(function () { 'use strict'; var nn = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}; function hr(s) { return s && s.__esModule && Object.prototype.hasOwnProperty.call(s, "default") ? s.default : s; } function sm(s) { if (Object.prototype.hasOwnProperty.call(s, "__esModule")) return s; var e = s.default; if (typeof e == "function") { var t = function i() { var r = false; try { r = this instanceof i; } catch { } return r ? Reflect.construct(e, arguments, this.constructor) : e.apply(this, arguments); }; t.prototype = e.prototype; } else t = {}; return Object.defineProperty(t, "__esModule", { value: true }), Object.keys(s).forEach(function(i) { var r = Object.getOwnPropertyDescriptor(s, i); Object.defineProperty(t, i, r.get ? r : { enumerable: true, get: function() { return s[i]; } }); }), t; } var ha, Gu; function In() { if (Gu) return ha; Gu = 1; var s; return typeof window < "u" ? s = window : typeof nn < "u" ? s = nn : typeof self < "u" ? s = self : s = {}, ha = s, ha; } var rm = /* @__PURE__ */ In(); const D = /* @__PURE__ */ hr(rm), nm = {}, am = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: nm }, Symbol.toStringTag, { value: "Module" })), om = /* @__PURE__ */ sm(am); var fa, Wu; function Sc() { if (Wu) return fa; Wu = 1; var s = typeof nn < "u" ? nn : typeof window < "u" ? window : {}, e = om, t; return typeof document < "u" ? t = document : (t = s["__GLOBAL_DOCUMENT_CACHE@4"], t || (t = s["__GLOBAL_DOCUMENT_CACHE@4"] = e)), fa = t, fa; } var um = /* @__PURE__ */ Sc(); const se = /* @__PURE__ */ hr(um); var Gr = { exports: {} }, pa = { exports: {} }, Xu; function lm() { return Xu || (Xu = 1, function(s) { function e() { return s.exports = e = Object.assign ? Object.assign.bind() : function(t) { for (var i = 1; i < arguments.length; i++) { var r = arguments[i]; for (var n in r) ({}).hasOwnProperty.call(r, n) && (t[n] = r[n]); } return t; }, s.exports.__esModule = true, s.exports.default = s.exports, e.apply(null, arguments); } s.exports = e, s.exports.__esModule = true, s.exports.default = s.exports; }(pa)), pa.exports; } var ma, Ku; function cm() { if (Ku) return ma; Ku = 1, ma = e; var s = Object.prototype.toString; function e(t) { if (!t) return false; var i = s.call(t); return i === "[object Function]" || typeof t == "function" && i !== "[object RegExp]" || typeof window < "u" && // IE8 and below (t === window.setTimeout || t === window.alert || t === window.confirm || t === window.prompt); } return ma; } var ga, Qu; function dm() { if (Qu) return ga; Qu = 1; function s(r, n) { var a = typeof Symbol < "u" && r[Symbol.iterator] || r["@@iterator"]; if (a) return (a = a.call(r)).next.bind(a); if (Array.isArray(r) || (a = e(r)) || n) { a && (r = a); var u = 0; return function() { return u >= r.length ? { done: true } : { done: false, value: r[u++] }; }; } throw new TypeError(`Invalid attempt to iterate non-iterable instance. In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`); } function e(r, n) { if (r) { if (typeof r == "string") return t(r, n); var a = Object.prototype.toString.call(r).slice(8, -1); if (a === "Object" && r.constructor && (a = r.constructor.name), a === "Map" || a === "Set") return Array.from(r); if (a === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)) return t(r, n); } } function t(r, n) { (n == null || n > r.length) && (n = r.length); for (var a = 0, u = new Array(n); a < n; a++) u[a] = r[a]; return u; } var i = /* @__PURE__ */ function() { function r() { this.typeToInterceptorsMap_ = /* @__PURE__ */ new Map(), this.enabled_ = false; } var n = r.prototype; return n.getIsEnabled = function() { return this.enabled_; }, n.enable = function() { this.enabled_ = true; }, n.disable = function() { this.enabled_ = false; }, n.reset = function() { this.typeToInterceptorsMap_ = /* @__PURE__ */ new Map(), this.enabled_ = false; }, n.addInterceptor = function(u, c) { this.typeToInterceptorsMap_.has(u) || this.typeToInterceptorsMap_.set(u, /* @__PURE__ */ new Set()); var f = this.typeToInterceptorsMap_.get(u); return f.has(c) ? false : (f.add(c), true); }, n.removeInterceptor = function(u, c) { var f = this.typeToInterceptorsMap_.get(u); return f && f.has(c) ? (f.delete(c), true) : false; }, n.clearInterceptorsByType = function(u) { var c = this.typeToInterceptorsMap_.get(u); return c ? (this.typeToInterceptorsMap_.delete(u), this.typeToInterceptorsMap_.set(u, /* @__PURE__ */ new Set()), true) : false; }, n.clear = function() { return this.typeToInterceptorsMap_.size ? (this.typeToInterceptorsMap_ = /* @__PURE__ */ new Map(), true) : false; }, n.getForType = function(u) { return this.typeToInterceptorsMap_.get(u) || /* @__PURE__ */ new Set(); }, n.execute = function(u, c) { for (var f = this.getForType(u), g = s(f), y; !(y = g()).done; ) { var I = y.value; try { c = I(c); } catch { } } return c; }, r; }(); return ga = i, ga; } var _a, Yu; function hm() { if (Yu) return _a; Yu = 1; var s = /* @__PURE__ */ function() { function t() { this.maxAttempts_ = 1, this.delayFactor_ = 0.1, this.fuzzFactor_ = 0.1, this.initialDelay_ = 1e3, this.enabled_ = false; } var i = t.prototype; return i.getIsEnabled = function() { return this.enabled_; }, i.enable = function() { this.enabled_ = true; }, i.disable = function() { this.enabled_ = false; }, i.reset = function() { this.maxAttempts_ = 1, this.delayFactor_ = 0.1, this.fuzzFactor_ = 0.1, this.initialDelay_ = 1e3, this.enabled_ = false; }, i.getMaxAttempts = function() { return this.maxAttempts_; }, i.setMaxAttempts = function(n) { this.maxAttempts_ = n; }, i.getDelayFactor = function() { return this.delayFactor_; }, i.setDelayFactor = function(n) { this.delayFactor_ = n; }, i.getFuzzFactor = function() { return this.fuzzFactor_; }, i.setFuzzFactor = function(n) { this.fuzzFactor_ = n; }, i.getInitialDelay = function() { return this.initialDelay_; }, i.setInitialDelay = function(n) { this.initialDelay_ = n; }, i.createRetry = function(n) { var a = n === void 0 ? {} : n, u = a.maxAttempts, c = a.delayFactor, f = a.fuzzFactor, g = a.initialDelay; return new e({ maxAttempts: u || this.maxAttempts_, delayFactor: c || this.delayFactor_, fuzzFactor: f || this.fuzzFactor_, initialDelay: g || this.initialDelay_ }); }, t; }(), e = /* @__PURE__ */ function() { function t(r) { this.maxAttempts_ = r.maxAttempts, this.delayFactor_ = r.delayFactor, this.fuzzFactor_ = r.fuzzFactor, this.currentDelay_ = r.initialDelay, this.currentAttempt_ = 1; } var i = t.prototype; return i.moveToNextAttempt = function() { this.currentAttempt_++; var n = this.currentDelay_ * this.delayFactor_; this.currentDelay_ = this.currentDelay_ + n; }, i.shouldRetry = function() { return this.currentAttempt_ < this.maxAttempts_; }, i.getCurrentDelay = function() { return this.currentDelay_; }, i.getCurrentMinPossibleDelay = function() { return (1 - this.fuzzFactor_) * this.currentDelay_; }, i.getCurrentMaxPossibleDelay = function() { return (1 + this.fuzzFactor_) * this.currentDelay_; }, i.getCurrentFuzzedDelay = function() { var n = this.getCurrentMinPossibleDelay(), a = this.getCurrentMaxPossibleDelay(); return n + Math.random() * (a - n); }, t; }(); return _a = s, _a; } var ya, Ju; function fm() { if (Ju) return ya; Ju = 1; var s = /* @__PURE__ */ In(), e = function(r, n) { return n === void 0 && (n = false), function(a, u, c) { if (a) { r(a); return; } if (u.statusCode >= 400 && u.statusCode <= 599) { var f = c; if (n) if (s.TextDecoder) { var g = t(u.headers && u.headers["content-type"]); try { f = new TextDecoder(g).decode(c); } catch { } } else f = String.fromCharCode.apply(null, new Uint8Array(c)); r({ cause: f }); return; } r(null, c); }; }; function t(i) { return i === void 0 && (i = ""), i.toLowerCase().split(";").reduce(function(r, n) { var a = n.split("="), u = a[0], c = a[1]; return u.trim() === "charset" ? c.trim() : r; }, "utf-8"); } return ya = e, ya; } var Zu; function pm() { if (Zu) return Gr.exports; Zu = 1; var s = /* @__PURE__ */ In(), e = /* @__PURE__ */ lm(), t = /* @__PURE__ */ cm(), i = /* @__PURE__ */ dm(), r = /* @__PURE__ */ hm(); f.httpHandler = /* @__PURE__ */ fm(), f.requestInterceptorsStorage = new i(), f.responseInterceptorsStorage = new i(), f.retryManager = new r(); /** * @license * slighly modified parse-headers 2.0.2 * Copyright (c) 2014 David Björklund * Available under the MIT license * */ var n = function(R) { var T = {}; return R && R.trim().split(` `).forEach(function(P) { var B = P.indexOf(":"), N = P.slice(0, B).trim().toLowerCase(), L = P.slice(B + 1).trim(); typeof T[N] > "u" ? T[N] = L : Array.isArray(T[N]) ? T[N].push(L) : T[N] = [T[N], L]; }), T; }; Gr.exports = f, Gr.exports.default = f, f.XMLHttpRequest = s.XMLHttpRequest || I, f.XDomainRequest = "withCredentials" in new f.XMLHttpRequest() ? f.XMLHttpRequest : s.XDomainRequest, a(["get", "put", "post", "patch", "head", "delete"], function(C) { f[C === "delete" ? "del" : C] = function(R, T, P) { return T = c(R, T, P), T.method = C.toUpperCase(), g(T); }; }); function a(C, R) { for (var T = 0; T < C.length; T++) R(C[T]); } function u(C) { for (var R in C) if (C.hasOwnProperty(R)) return false; return true; } function c(C, R, T) { var P = C; return t(R) ? (T = R, typeof C == "string" && (P = { uri: C })) : P = e({}, R, { uri: C }), P.callback = T, P; } function f(C, R, T) { return R = c(C, R, T), g(R); } function g(C) { if (typeof C.callback > "u") throw new Error("callback argument missing"); if (C.requestType && f.requestInterceptorsStorage.getIsEnabled()) { var R = { uri: C.uri || C.url, headers: C.headers || {}, body: C.body, metadata: C.metadata || {}, retry: C.retry, timeout: C.timeout }, T = f.requestInterceptorsStorage.execute(C.requestType, R); C.uri = T.uri, C.headers = T.headers, C.body = T.body, C.metadata = T.metadata, C.retry = T.retry, C.timeout = T.timeout; } var P = false, B = function(Z, J, te) { P || (P = true, C.callback(Z, J, te)); }; function N() { U.readyState === 4 && !f.responseInterceptorsStorage.getIsEnabled() && setTimeout(O, 0); } function L() { var W = void 0; if (U.response ? W = U.response : W = U.responseText || y(U), Y) try { W = JSON.parse(W); } catch { } return W; } function z(W) { if (clearTimeout(ie), clearTimeout(C.retryTimeout), W instanceof Error || (W = new Error("" + (W || "Unknown XMLHttpRequest Error"))), W.statusCode = 0, !Q && f.retryManager.getIsEnabled() && C.retry && C.retry.shouldRetry()) { C.retryTimeout = setTimeout(function() { C.retry.moveToNextAttempt(), C.xhr = U, g(C); }, C.retry.getCurrentFuzzedDelay()); return; } if (C.requestType && f.responseInterceptorsStorage.getIsEnabled()) { var Z = { headers: re.headers || {}, body: re.body, responseUrl: U.responseURL, responseType: U.responseType }, J = f.responseInterceptorsStorage.execute(C.requestType, Z); re.body = J.body, re.headers = J.headers; } return B(W, re); } function O() { if (!Q) { var W; clearTimeout(ie), clearTimeout(C.retryTimeout), C.useXDR && U.status === void 0 ? W = 200 : W = U.status === 1223 ? 204 : U.status; var Z = re, J = null; if (W !== 0 ? (Z = { body: L(), statusCode: W, method: E, headers: {}, url: v, rawRequest: U }, U.getAllResponseHeaders && (Z.headers = n(U.getAllResponseHeaders()))) : J = new Error("Internal XMLHttpRequest Error"), C.requestType && f.responseInterceptorsStorage.getIsEnabled()) { var te = { headers: Z.headers || {}, body: Z.body, responseUrl: U.responseURL, responseType: U.responseType }, ee = f.responseInterceptorsStorage.execute(C.requestType, te); Z.body = ee.body, Z.headers = ee.headers; } return B(J, Z, Z.body); } } var U = C.xhr || null; U || (C.cors || C.useXDR ? U = new f.XDomainRequest() : U = new f.XMLHttpRequest()); var V, Q, v = U.url = C.uri || C.url, E = U.method = C.method || "GET", q = C.body || C.data, j = U.headers = C.headers || {}, H = !!C.sync, Y = false, ie, re = { body: void 0, headers: {}, statusCode: 0, method: E, url: v, rawRequest: U }; if ("json" in C && C.json !== false && (Y = true, j.accept || j.Accept || (j.Accept = "application/json"), E !== "GET" && E !== "HEAD" && (j["content-type"] || j["Content-Type"] || (j["Content-Type"] = "application/json"), q = JSON.stringify(C.json === true ? q : C.json))), U.onreadystatechange = N, U.onload = O, U.onerror = z, U.onprogress = function() { }, U.onabort = function() { Q = true, clearTimeout(C.retryTimeout); }, U.ontimeout = z, U.open(E, v, !H, C.username, C.password), H || (U.withCredentials = !!C.withCredentials), !H && C.timeout > 0 && (ie = setTimeout(function() { if (!Q) { Q = true, U.abort("timeout"); var W = new Error("XMLHttpRequest timeout"); W.code = "ETIMEDOUT", z(W); } }, C.timeout)), U.setRequestHeader) for (V in j) j.hasOwnProperty(V) && U.setRequestHeader(V, j[V]); else if (C.headers && !u(C.headers)) throw new Error("Headers cannot be set on an XDomainRequest object"); return "responseType" in C && (U.responseType = C.responseType), "beforeSend" in C && typeof C.beforeSend == "function" && C.beforeSend(U), U.send(q || null), U; } function y(C) { try { if (C.responseType === "document") return C.responseXML; var R = C.responseXML && C.responseXML.documentElement.nodeName === "parsererror"; if (C.responseType === "" && !R) return C.responseXML; } catch { } return null; } function I() { } return Gr.exports; } var mm = /* @__PURE__ */ pm(); const Ec = /* @__PURE__ */ hr(mm); var Ta = { exports: {} }, va, el; function gm() { if (el) return va; el = 1; var s = /* @__PURE__ */ Sc(), e = Object.create || /* @__PURE__ */ function() { function v() { } return function(E) { if (arguments.length !== 1) throw new Error("Object.create shim only accepts one parameter."); return v.prototype = E, new v(); }; }(); function t(v, E) { this.name = "ParsingError", this.code = v.code, this.message = E || v.message; } t.prototype = e(Error.prototype), t.prototype.constructor = t, t.Errors = { BadSignature: { code: 0, message: "Malformed WebVTT signature." }, BadTimeStamp: { code: 1, message: "Malformed time stamp." } }; function i(v) { function E(j, H, Y, ie) { return (j | 0) * 3600 + (H | 0) * 60 + (Y | 0) + (ie | 0) / 1e3; } var q = v.match(/^(\d+):(\d{1,2})(:\d{1,2})?\.(\d{3})/); return q ? q[3] ? E(q[1], q[2], q[3].replace(":", ""), q[4]) : q[1] > 59 ? E(q[1], q[2], 0, q[4]) : E(0, q[1], q[2], q[4]) : null; } function r() { this.values = e(null); } r.prototype = { // Only accept the first assignment to any key. set: function(v, E) { !this.get(v) && E !== "" && (this.values[v] = E); }, // Return the value for a key, or a default value. // If 'defaultKey' is passed then 'dflt' is assumed to be an object with // a number of possible default values as properties where 'defaultKey' is // the key of the property that will be chosen; otherwise it's assumed to be // a single value. get: function(v, E, q) { return q ? this.has(v) ? this.values[v] : E[q] : this.has(v) ? this.values[v] : E; }, // Check whether we have a value for a key. has: function(v) { return v in this.values; }, // Accept a setting if its one of the given alternatives. alt: function(v, E, q) { for (var j = 0; j < q.length; ++j) if (E === q[j]) { this.set(v, E); break; } }, // Accept a setting if its a valid (signed) integer. integer: function(v, E) { /^-?\d+$/.test(E) && this.set(v, parseInt(E, 10)); }, // Accept a setting if its a valid percentage. percent: function(v, E) { return E.match(/^([\d]{1,3})(\.[\d]*)?%$/) && (E = parseFloat(E), E >= 0 && E <= 100) ? (this.set(v, E), true) : false; } }; function n(v, E, q, j) { var H = j ? v.split(j) : [v]; for (var Y in H) if (typeof H[Y] == "string") { var ie = H[Y].split(q); if (ie.length === 2) { var re = ie[0].trim(), W = ie[1].trim(); E(re, W); } } } function a(v, E, q) { var j = v; function H() { var re = i(v); if (re === null) throw new t( t.Errors.BadTimeStamp, "Malformed timestamp: " + j ); return v = v.replace(/^[^\sa-zA-Z-]+/, ""), re; } function Y(re, W) { var Z = new r(); n(re, function(J, te) { switch (J) { case "region": for (var ee = q.length - 1; ee >= 0; ee--) if (q[ee].id === te) { Z.set(J, q[ee].region); break; } break; case "vertical": Z.alt(J, te, ["rl", "lr"]); break; case "line": var fe = te.split(","), me = fe[0]; Z.integer(J, me), Z.percent(J, me) && Z.set("snapToLines", false), Z.alt(J, me, ["auto"]), fe.length === 2 && Z.alt("lineAlign", fe[1], ["start", "center", "end"]); break; case "position": fe = te.split(","), Z.percent(J, fe[0]), fe.length === 2 && Z.alt("positionAlign", fe[1], ["start", "center", "end"]); break; case "size": Z.percent(J, te); break; case "align": Z.alt(J, te, ["start", "center", "end", "left", "right"]); break; } }, /:/, /\s/), W.region = Z.get("region", null), W.vertical = Z.get("vertical", ""); try { W.line = Z.get("line", "auto"); } catch { } W.lineAlign = Z.get("lineAlign", "start"), W.snapToLines = Z.get("snapToLines", true), W.size = Z.get("size", 100); try { W.align = Z.get("align", "center"); } catch { W.align = Z.get("align", "middle"); } try { W.position = Z.get("position", "auto"); } catch { W.position = Z.get("position", { start: 0, left: 0, center: 50, middle: 50, end: 100, right: 100 }, W.align); } W.positionAlign = Z.get("positionAlign", { start: "start", left: "start", center: "center", middle: "center", end: "end", right: "end" }, W.align); } function ie() { v = v.replace(/^\s+/, ""); } if (ie(), E.startTime = H(), ie(), v.substr(0, 3) !== "-->") throw new t( t.Errors.BadTimeStamp, "Malformed time stamp (time stamps must be separated by '-->'): " + j ); v = v.substr(3), ie(), E.endTime = H(), ie(), Y(v, E); } var u = s.createElement && s.createElement("textarea"), c = { c: "span", i: "i", b: "b", u: "u", ruby: "ruby", rt: "rt", v: "span", lang: "span" }, f = { white: "rgba(255,255,255,1)", lime: "rgba(0,255,0,1)", cyan: "rgba(0,255,255,1)", red: "rgba(255,0,0,1)", yellow: "rgba(255,255,0,1)", magenta: "rgba(255,0,255,1)", blue: "rgba(0,0,255,1)", black: "rgba(0,0,0,1)" }, g = { v: "title", lang: "lang" }, y = { rt: "ruby" }; function I(v, E) { function q() { if (!E) return null; function me(he) { return E = E.substr(he.length), he; } var _e = E.match(/^([^<]*)(<[^>]*>?)?/); return me(_e[1] ? _e[1] : _e[2]); } function j(me) { return u.innerHTML = me, me = u.textContent, u.textContent = "", me; } function H(me, _e) { return !y[_e.localName] || y[_e.localName] === me.localName; } function Y(me, _e) { var he = c[me]; if (!he) return null; var Ke = v.document.createElement(he), Je = g[me]; return Je && _e && (Ke[Je] = _e.trim()), Ke; } for (var ie = v.document.createElement("div"), re = ie, W, Z = []; (W = q()) !== null; ) { if (W[0] === "<") { if (W[1] === "/") { Z.length && Z[Z.length - 1] === W.substr(2).replace(">", "") && (Z.pop(), re = re.parentNode); continue; } var J = i(W.substr(1, W.length - 2)), te; if (J) { te = v.document.createProcessingInstruction("timestamp", J), re.appendChild(te); continue; } var ee = W.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/); if (!ee || (te = Y(ee[1], ee[3]), !te) || !H(re, te)) continue; if (ee[2]) { var fe = ee[2].split("."); fe.forEach(function(me) { var _e = /^bg_/.test(me), he = _e ? me.slice(3) : me; if (f.hasOwnProperty(he)) { var Ke = _e ? "background-color" : "color", Je = f[he]; te.style[Ke] = Je; } }), te.className = fe.join(" "); } Z.push(ee[1]), re.appendChild(te), re = te; continue; } re.appendChild(v.document.createTextNode(j(W))); } return ie; } var C = [ [1470, 1470], [1472, 1472], [1475, 1475], [1478, 1478], [1488, 1514], [1520, 1524], [1544, 1544], [1547, 1547], [1549, 1549], [1563, 1563], [1566, 1610], [1645, 1647], [1649, 1749], [1765, 1766], [1774, 1775], [1786, 1805], [1807, 1808], [1810, 1839], [1869, 1957], [1969, 1969], [1984, 2026], [2036, 2037], [2042, 2042], [2048, 2069], [2074, 2074], [2084, 2084], [2088, 2088], [2096, 2110], [2112, 2136], [2142, 2142], [2208, 2208], [2210, 2220], [8207, 8207], [64285, 64285], [64287, 64296], [64298, 64310], [64312, 64316], [64318, 64318], [64320, 64321], [64323, 64324], [64326, 64449], [64467, 64829], [64848, 64911], [64914, 64967], [65008, 65020], [65136, 65140], [65142, 65276], [67584, 67589], [67592, 67592], [67594, 67637], [67639, 67640], [67644, 67644], [67647, 67669], [67671, 67679], [67840, 67867], [67872, 67897], [67903, 67903], [67968, 68023], [68030, 68031], [68096, 68096], [68112, 68115], [68117, 68119], [68121, 68147], [68160, 68167], [68176, 68184], [68192, 68223], [68352, 68405], [68416, 68437], [68440, 68466], [68472, 68479], [68608, 68680], [126464, 126467], [126469, 126495], [126497, 126498], [126500, 126500], [126503, 126503], [126505, 126514], [126516, 126519], [126521, 126521], [126523, 126523], [126530, 126530], [126535, 126535], [126537, 126537], [126539, 126539], [126541, 126543], [126545, 126546], [126548, 126548], [126551, 126551], [126553, 126553], [126555, 126555], [126557, 126557], [126559, 126559], [126561, 126562], [126564, 126564], [126567, 126570], [126572, 126578], [126580, 126583], [126585, 126588], [126590, 126590], [126592, 126601], [126603, 126619], [126625, 126627], [126629, 126633], [126635, 126651], [1114109, 1114109] ]; function R(v) { for (var E = 0; E < C.length; E++) { var q = C[E]; if (v >= q[0] && v <= q[1]) return true; } return false; } function T(v) { var E = [], q = "", j; if (!v || !v.childNodes) return "ltr"; function H(re, W) { for (var Z = W.childNodes.length - 1; Z >= 0; Z--) re.push(W.childNodes[Z]); } function Y(re) { if (!re || !re.length) return null; var W = re.pop(), Z = W.textContent || W.innerText; if (Z) { var J = Z.match(/^.*(\n|\r)/); return J ? (re.length = 0, J[0]) : Z; } if (W.tagName === "ruby") return Y(re); if (W.childNodes) return H(re, W), Y(re); } for (H(E, v); q = Y(E); ) for (var ie = 0; ie < q.length; ie++) if (j = q.charCodeAt(ie), R(j)) return "rtl"; return "ltr"; } function P(v) { if (typeof v.line == "number" && (v.snapToLines || v.line >= 0 && v.line <= 100)) return v.line; if (!v.track || !v.track.textTrackList || !v.track.textTrackList.mediaElement) return -1; for (var E = v.track, q = E.textTrackList, j = 0, H = 0; H < q.length && q[H] !== E; H++) q[H].mode === "showing" && j++; return ++j * -1; } function B() { } B.prototype.applyStyles = function(v, E) { E = E || this.div; for (var q in v) v.hasOwnProperty(q) && (E.style[q] = v[q]); }, B.prototype.formatStyle = function(v, E) { return v === 0 ? 0 : v + E; }; function N(v, E, q) { B.call(this), this.cue = E, this.cueDiv = I(v, E.text); var j = { color: "rgba(255, 255, 255, 1)", backgroundColor: "rgba(0, 0, 0, 0.8)", position: "relative", left: 0, right: 0, top: 0, bottom: 0, display: "inline", writingMode: E.vertical === "" ? "horizontal-tb" : E.vertical === "lr" ? "vertical-lr" : "vertical-rl", unicodeBidi: "plaintext" }; this.applyStyles(j, this.cueDiv), this.div = v.document.createElement("div"), j = { direction: T(this.cueDiv), writingMode: E.vertical === "" ? "horizontal-tb" : E.vertical === "lr" ? "vertical-lr" : "vertical-rl", unicodeBidi: "plaintext", textAlign: E.align === "middle" ? "center" : E.align, font: q.font, whiteSpace: "pre-line", position: "absolute" }, this.applyStyles(j), this.div.appendChild(this.cueDiv); var H = 0; switch (E.positionAlign) { case "start": case "line-left": H = E.position; break; case "center": H = E.position - E.size / 2; break; case "end": case "line-right": H = E.position - E.size; break; } E.vertical === "" ? this.applyStyles({ left: this.formatStyle(H, "%"), width: this.formatStyle(E.size, "%") }) : this.applyStyles({ top: this.formatStyle(H, "%"), height: this.formatStyle(E.size, "%") }), this.move = function(Y) { this.applyStyles({ top: this.formatStyle(Y.top, "px"), bottom: this.formatStyle(Y.bottom, "px"), left: this.formatStyle(Y.left, "px"), right: this.formatStyle(Y.right, "px"), height: this.formatStyle(Y.height, "px"), width: this.formatStyle(Y.width, "px") }); }; } N.prototype = e(B.prototype), N.prototype.constructor = N; function L(v) { var E, q, j, H; if (v.div) { q = v.div.offsetHeight, j = v.div.offsetWidth, H = v.div.offsetTop; var Y = (Y = v.div.childNodes) && (Y = Y[0]) && Y.getClientRects && Y.getClientRects(); v = v.div.getBoundingClientRect(), E = Y ? Math.max(Y[0] && Y[0].height || 0, v.height / Y.length) : 0; } this.left = v.left, this.right = v.right, this.top = v.top || H, this.height = v.height || q, this.bottom = v.bottom || H + (v.height || q), this.width = v.width || j, this.lineHeight = E !== void 0 ? E : v.lineHeight; } L.prototype.move = function(v, E) { switch (E = E !== void 0 ? E : this.lineHeight, v) { case "+x": this.left += E, this.right += E; break; case "-x": this.left -= E, this.right -= E; break; case "+y": this.top += E, this.bottom += E; break; case "-y": this.top -= E, this.bottom -= E; break; } }, L.prototype.overlaps = function(v) { return this.left < v.right && this.right > v.left && this.top < v.bottom && this.bottom > v.top; }, L.prototype.overlapsAny = function(v) { for (var E = 0; E < v.length; E++) if (this.overlaps(v[E])) return true; return false; }, L.prototype.within = function(v) { return this.top >= v.top && this.bottom <= v.bottom && this.left >= v.left && this.right <= v.right; }, L.prototype.overlapsOppositeAxis = function(v, E) { switch (E) { case "+x": return this.left < v.left; case "-x": return this.right > v.right; case "+y": return this.top < v.top; case "-y": return this.bottom > v.bottom; } }, L.prototype.intersectPercentage = function(v) { var E = Math.max(0, Math.min(this.right, v.right) - Math.max(this.left, v.left)), q = Math.max(0, Math.min(this.bottom, v.bottom) - Math.max(this.top, v.top)), j = E * q; return j / (this.height * this.width); }, L.prototype.toCSSCompatValues = function(v) { return { top: this.top - v.top, bottom: v.bottom - this.bottom, left: this.left - v.left, right: v.right - this.right, height: this.height, width: this.width }; }, L.getSimpleBoxPosition = function(v) { var E = v.div ? v.div.offsetHeight : v.tagName ? v.offsetHeight : 0, q = v.div ? v.div.offsetWidth : v.tagName ? v.offsetWidth : 0, j = v.div ? v.div.offsetTop : v.tagName ? v.offsetTop : 0; v = v.div ? v.div.getBoundingClientRect() : v.tagName ? v.getBoundingClientRect() : v; var H = { left: v.left, right: v.right, top: v.top || j, height: v.height || E, bottom: v.bottom || j + (v.height || E), width: v.width || q }; return H; }; function z(v, E, q, j) { function H(he, Ke) { for (var Je, $e = new L(he), Ze = 1, vt = 0; vt < Ke.length; vt++) { for (; he.overlapsOppositeAxis(q, Ke[vt]) || he.within(q) && he.overlapsAny(j); ) he.move(Ke[vt]); if (he.within(q)) return he; var Qe = he.intersectPercentage(q); Ze > Qe && (Je = new L(he), Ze = Qe), he = new L($e); } return Je || $e; } var Y = new L(E), ie = E.cue, re = P(ie), W = []; if (ie.snapToLines) { var Z; switch (ie.vertical) { case "": W = ["+y", "-y"], Z = "height"; break; case "rl": W = ["+x", "-x"], Z = "width"; break; case "lr": W = ["-x", "+x"], Z = "width"; break; } var J = Y.lineHeight, te = J * Math.round(re), ee = q[Z] + J, fe = W[0]; Math.abs(te) > ee && (te = te < 0 ? -1 : 1, te *= Math.ceil(ee / J) * J), re < 0 && (te += ie.vertical === "" ? q.height : q.width, W = W.reverse()), Y.move(fe, te); } else { var me = Y.lineHeight / q.height * 100; switch (ie.lineAlign) { case "center": re -= me / 2; break; case "end": re -= me; break; } switch (ie.vertical) { case "": E.applyStyles({ top: E.formatStyle(re, "%") }); break; case "rl": E.applyStyles({ left: E.formatStyle(re, "%") }); break; case "lr": E.applyStyles({ right: E.formatStyle(re, "%") }); break; } W = ["+y", "-x", "+x", "-y"], Y = new L(E); } var _e = H(Y, W); E.move(_e.toCSSCompatValues(q)); } function O() { } O.StringDecoder = function() { return { decode: function(v) { if (!v) return ""; if (typeof v != "string") throw new Error("Error - expected string data."); return decodeURIComponent(encodeURIComponent(v)); } }; }, O.convertCueToDOMTree = function(v, E) { return !v || !E ? null : I(v, E); }; var U = 0.05, V = "sans-serif", Q = "1.5%"; return O.processCues = function(v, E, q) { if (!v || !E || !q) return null; for (; q.firstChild; ) q.removeChild(q.firstChild); var j = v.document.createElement("div"); j.style.position = "absolute", j.style.left = "0", j.style.right = "0", j.style.top = "0", j.style.bottom = "0", j.style.margin = Q, q.appendChild(j); function H(J) { for (var te = 0; te < J.length; te++) if (J[te].hasBeenReset || !J[te].displayState) return true; return false; } if (!H(E)) { for (var Y = 0; Y < E.length; Y++) j.appendChild(E[Y].displayState); return; } var ie = [], re = L.getSimpleBoxPosition(j), W = Math.round(re.height * U * 100) / 100, Z = { font: W + "px " + V }; (function() { for (var J, te, ee = 0; ee < E.length; ee++) te = E[ee], J = new N(v, te, Z), j.appendChild(J.div), z(v, J, re, ie), te.displayState = J.div, ie.push(L.getSimpleBoxPosition(J)); })(); }, O.Parser = function(v, E, q) { q || (q = E, E = {}), E || (E = {}), this.window = v, this.vttjs = E, this.state = "INITIAL", this.buffer = "", this.decoder = q || new TextDecoder("utf8"), this.regionList = []; }, O.Parser.prototype = { // If the error is a ParsingError then report it to the consumer if // possible. If it's not a ParsingError then throw it like normal. reportOrThrowError: function(v) { if (v instanceof t) this.onparsingerror && this.onparsingerror(v); else throw v; }, parse: function(v) { var E = this; v && (E.buffer += E.decoder.decode(v, { stream: true })); function q() { for (var J = E.buffer, te = 0; te < J.length && J[te] !== "\r" && J[te] !== ` `; ) ++te; var ee = J.substr(0, te); return J[te] === "\r" && ++te, J[te] === ` ` && ++te, E.buffer = J.substr(te), ee; } function j(J) { var te = new r(); if (n(J, function(fe, me) { switch (fe) { case "id": te.set(fe, me); break; case "width": te.percent(fe, me); break; case "lines": te.integer(fe, me); break; case "regionanchor": case "viewportanchor": var _e = me.split(","); if (_e.length !== 2) break; var he = new r(); if (he.percent("x", _e[0]), he.percent("y", _e[1]), !he.has("x") || !he.has("y")) break; te.set(fe + "X", he.get("x")), te.set(fe + "Y", he.get("y")); break; case "scroll": te.alt(fe, me, ["up"]); break; } }, /=/, /\s/), te.has("id")) { var ee = new (E.vttjs.VTTRegion || E.window.VTTRegion)(); ee.width = te.get("width", 100), ee.lines = te.get("lines", 3), ee.regionAnchorX = te.get("regionanchorX", 0), ee.regionAnchorY = te.get("regionanchorY", 100), ee.viewportAnchorX = te.get("viewportanchorX", 0), ee.viewportAnchorY = te.get("viewportanchorY", 100), ee.scroll = te.get("scroll", ""), E.onregion && E.onregion(ee), E.regionList.push({ id: te.get("id"), region: ee }); } } function H(J) { var te = new r(); n(J, function(ee, fe) { switch (ee) { case "MPEGT": te.integer(ee + "S", fe); break; case "LOCA": te.set(ee + "L", i(fe)); break; } }, /[^\d]:/, /,/), E.ontimestampmap && E.ontimestampmap({ MPEGTS: te.get("MPEGTS"), LOCAL: te.get("LOCAL") }); } function Y(J) { J.match(/X-TIMESTAMP-MAP/) ? n(J, function(te, ee) { switch (te) { case "X-TIMESTAMP-MAP": H(ee); break; } }, /=/) : n(J, function(te, ee) { switch (te) { case "Region": j(ee); break; } }, /:/); } try { var ie; if (E.state === "INITIAL") { if (!/\r\n|\n/.test(E.buffer)) return this; ie = q(); var re = ie.match(/^WEBVTT([ \t].*)?$/); if (!re || !re[0]) throw new t(t.Errors.BadSignature); E.state = "HEADER"; } for (var W = !1; E.buffer; ) { if (!/\r\n|\n/.test(E.buffer)) return this; switch (W ? W = !1 : ie = q(), E.state) { case "HEADER": /:/.test(ie) ? Y(ie) : ie || (E.state = "ID"); continue; case "NOTE": ie || (E.state = "ID"); continue; case "ID": if (/^NOTE($|[ \t])/.test(ie)) { E.state = "NOTE"; break; } if (!ie) continue; E.cue = new (E.vttjs.VTTCue || E.window.VTTCue)(0, 0, ""); try { E.cue.align = "center"; } catch { E.cue.align = "middle"; } if (E.state = "CUE", ie.indexOf("-->") === -1) { E.cue.id = ie; continue; } // Process line as start of a cue. /*falls through*/ case "CUE": try { a(ie, E.cue, E.regionList); } catch (J) { E.reportOrThrowError(J), E.cue = null, E.state = "BADCUE"; continue; } E.state = "CUETEXT"; continue; case "CUETEXT": var Z = ie.indexOf("-->") !== -1; if (!ie || Z && (W = !0)) { E.oncue && E.oncue(E.cue), E.cue = null, E.state = "ID"; continue; } E.cue.text && (E.cue.text += ` `), E.cue.text += ie.replace(/\u2028/g, ` `).replace(/u2029/g, ` `); continue; case "BADCUE": ie || (E.state = "ID"); continue; } } } catch (J) { E.reportOrThrowError(J), E.state === "CUETEXT" && E.cue && E.oncue && E.oncue(E.cue), E.cue = null, E.state = E.state === "INITIAL" ? "BADWEBVTT" : "BADCUE"; } return this; }, flush: function() { var v = this; try { if (v.buffer += v.decoder.decode(), (v.cue || v.state === "HEADER") && (v.buffer += ` `, v.parse()), v.state === "INITIAL") throw new t(t.Errors.BadSignature); } catch (E) { v.reportOrThrowError(E); } return v.onflush && v.onflush(), this; } }, va = O, va; } var ba, tl; function _m() { if (tl) return ba; tl = 1; var s = "auto", e = { "": 1, lr: 1, rl: 1 }, t = { start: 1, center: 1, end: 1, left: 1, right: 1, auto: 1, "line-left": 1, "line-right": 1 }; function i(a) { if (typeof a != "string") return false; var u = e[a.toLowerCase()]; return u ? a.toLowerCase() : false; } function r(a) { if (typeof a != "string") return false; var u = t[a.toLowerCase()]; return u ? a.toLowerCase() : false; } function n(a, u, c) { this.hasBeenReset = false; var f = "", g = false, y = a, I = u, C = c, R = null, T = "", P = true, B = "auto", N = "start", L = "auto", z = "auto", O = 100, U = "center"; Object.defineProperties(this, { id: { enumerable: true, get: function() { return f; }, set: function(V) { f = "" + V; } }, pauseOnExit: { enumerable: true, get: function() { return g; }, set: function(V) { g = !!V; } }, startTime: { enumerable: true, get: function() { return y; }, set: function(V) { if (typeof V != "number") throw new TypeError("Start time must be set to a number."); y = V, this.hasBeenReset = true; } }, endTime: { enumerable: true, get: function() { return I; }, set: function(V) { if (typeof V != "number") throw new TypeError("End time must be set to a number."); I = V, this.hasBeenReset = true; } }, text: { enumerable: true, get: function() { return C; }, set: function(V) { C = "" + V, this.hasBeenReset = true; } }, region: { enumerable: true, get: function() { return R; }, set: function(V) { R = V, this.hasBeenReset = true; } }, vertical: { enumerable: true, get: function() { return T; }, set: function(V) { var Q = i(V); if (Q === false) throw new SyntaxError("Vertical: an invalid or illegal direction string was specified."); T = Q, this.hasBeenReset = true; } }, snapToLines: { enumerable: true, get: function() { return P; }, set: function(V) { P = !!V, this.hasBeenReset = true; } }, line: { enumerable: true, get: function() { return B; }, set: function(V) { if (typeof V != "number" && V !== s) throw new SyntaxError("Line: an invalid number or illegal string was specified."); B = V, this.hasBeenReset = true; } }, lineAlign: { enumerable: true, get: function() { return N; }, set: function(V) { var Q = r(V); Q ? (N = Q, this.hasBeenReset = true) : console.warn("lineAlign: an invalid or illegal string was specified."); } }, position: { enumerable: true, get: function() { return L; }, set: function(V) { if (V < 0 || V > 100) throw new Error("Position must be between 0 and 100."); L = V, this.hasBeenReset = true; } }, positionAlign: { enumerable: true, get: function() { return z; }, set: function(V) { var Q = r(V); Q ? (z = Q, this.hasBeenReset = true) : console.warn("positionAlign: an invalid or illegal string was specified."); } }, size: { enumerable: true, get: function() { return O; }, set: function(V) { if (V < 0 || V > 100) throw new Error("Size must be between 0 and 100."); O = V, this.hasBeenReset = true; } }, align: { enumerable: true, get: function() { return U; }, set: function(V) { var Q = r(V); if (!Q) throw new SyntaxError("align: an invalid or illegal alignment string was specified."); U = Q, this.hasBeenReset = true; } } }), this.displayState = void 0; } return n.prototype.getCueAsHTML = function() { return WebVTT.convertCueToDOMTree(window, this.text); }, ba = n, ba; } var xa, il; function ym() { if (il) return xa; il = 1; var s = { "": true, up: true }; function e(r) { if (typeof r != "string") return false; var n = s[r.toLowerCase()]; return n ? r.toLowerCase() : false; } function t(r) { return typeof r == "number" && r >= 0 && r <= 100; } function i() { var r = 100, n = 3, a = 0, u = 100, c = 0, f = 100, g = ""; Object.defineProperties(this, { width: { enumerable: true, get: function() { return r; }, set: function(y) { if (!t(y)) throw new Error("Width must be between 0 and 100."); r = y; } }, lines: { enumerable: true, get: function() { return n; }, set: function(y) { if (typeof y != "number") throw new TypeError("Lines must be set to a number."); n = y; } }, regionAnchorY: { enumerable: true, get: function() { return u; }, set: function(y) { if (!t(y)) throw new Error("RegionAnchorX must be between 0 and 100."); u = y; } }, regionAnchorX: { enumerable: true, get: function() { return a; }, set: function(y) { if (!t(y)) throw new Error("RegionAnchorY must be between 0 and 100."); a = y; } }, viewportAnchorY: { enumerable: true, get: function() { return f; }, set: function(y) { if (!t(y)) throw new Error("ViewportAnchorY must be between 0 and 100."); f = y; } }, viewportAnchorX: { enumerable: true, get: function() { return c; }, set: function(y) { if (!t(y)) throw new Error("ViewportAnchorX must be between 0 and 100."); c = y; } }, scroll: { enumerable: true, get: function() { return g; }, set: function(y) { var I = e(y); I === false ? console.warn("Scroll: an invalid or illegal string was specified.") : g = I; } } }); } return xa = i, xa; } var sl; function Tm() { if (sl) return Ta.exports; sl = 1; var s = /* @__PURE__ */ In(), e = Ta.exports = { WebVTT: /* @__PURE__ */ gm(), VTTCue: /* @__PURE__ */ _m(), VTTRegion: /* @__PURE__ */ ym() }; s.vttjs = e, s.WebVTT = e.WebVTT; var t = e.VTTCue, i = e.VTTRegion, r = s.VTTCue, n = s.VTTRegion; return e.shim = function() { s.VTTCue = t, s.VTTRegion = i; }, e.restore = function() { s.VTTCue = r, s.VTTRegion = n; }, s.VTTCue || e.shim(), Ta.exports; } var vm = /* @__PURE__ */ Tm(); const rl = /* @__PURE__ */ hr(vm); function qe() { return qe = Object.assign ? Object.assign.bind() : function(s) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var i in t) ({}).hasOwnProperty.call(t, i) && (s[i] = t[i]); } return s; }, qe.apply(null, arguments); } var nl = "https://example.com", kn = function(e, t) { if (/^[a-z]+:/i.test(t)) return t; /^data:/.test(e) && (e = D.location && D.location.href || ""); var i = /^\/\//.test(e), r = !D.location && !/\/\//i.test(e); e = new D.URL(e, D.location || nl); var n = new URL(t, e); return r ? n.href.slice(nl.length) : i ? n.href.slice(n.protocol.length) : n.href; }, vo = /* @__PURE__ */ function() { function s() { this.listeners = {}; } var e = s.prototype; return e.on = function(i, r) { this.listeners[i] || (this.listeners[i] = []), this.listeners[i].push(r); }, e.off = function(i, r) { if (!this.listeners[i]) return false; var n = this.listeners[i].indexOf(r); return this.listeners[i] = this.listeners[i].slice(0), this.listeners[i].splice(n, 1), n > -1; }, e.trigger = function(i) { var r = this.listeners[i]; if (r) if (arguments.length === 2) for (var n = r.length, a = 0; a < n; ++a) r[a].call(this, arguments[1]); else for (var u = Array.prototype.slice.call(arguments, 1), c = r.length, f = 0; f < c; ++f) r[f].apply(this, u); }, e.dispose = function() { this.listeners = {}; }, e.pipe = function(i) { this.on("data", function(r) { i.push(r); }); }, s; }(), bm = function(e) { return D.atob ? D.atob(e) : Buffer.from(e, "base64").toString("binary"); }; function Cc(s) { for (var e = bm(s), t = new Uint8Array(e.length), i = 0; i < e.length; i++) t[i] = e.charCodeAt(i); return t; } /*! @name m3u8-parser @version 7.2.0 @license Apache-2.0 */ class xm extends vo { constructor() { super(), this.buffer = ""; } /** * Add new data to be parsed. * * @param {string} data the text to process */ push(e) { let t; for (this.buffer += e, t = this.buffer.indexOf(` `); t > -1; t = this.buffer.indexOf(` `)) this.trigger("data", this.buffer.substring(0, t)), this.buffer = this.buffer.substring(t + 1); } } const Sm = " ", Sa = function(s) { const e = /([0-9.]*)?@?([0-9.]*)?/.exec(s || ""), t = {}; return e[1] && (t.length = parseInt(e[1], 10)), e[2] && (t.offset = parseInt(e[2], 10)), t; }, Em = function() { const t = "(?:" + "[^=]*" + ")=(?:" + '"[^"]*"|[^,]*' + ")"; return new RegExp("(?:^|,)(" + t + ")"); }, at = function(s) { const e = {}; if (!s) return e; const t = s.split(Em()); let i = t.length, r; for (; i--; ) t[i] !== "" && (r = /([^=]*)=(.*)/.exec(t[i]).slice(1), r[0] = r[0].replace(/^\s+|\s+$/g, ""), r[1] = r[1].replace(/^\s+|\s+$/g, ""), r[1] = r[1].replace(/^['"](.*)['"]$/g, "$1"), e[r[0]] = r[1]); return e; }, al = (s) => { const e = s.split("x"), t = {}; return e[0] && (t.width = parseInt(e[0], 10)), e[1] && (t.height = parseInt(e[1], 10)), t; }; class Cm extends vo { constructor() { super(), this.customParsers = [], this.tagMappers = []; } /** * Parses an additional line of input. * * @param {string} line a single line of an M3U8 file to parse */ push(e) { let t, i; if (e = e.trim(), e.length === 0) return; if (e[0] !== "#") { this.trigger("data", { type: "uri", uri: e }); return; } this.tagMappers.reduce((n, a) => { const u = a(e); return u === e ? n : n.concat([u]); }, [e]).forEach((n) => { for (let a = 0; a < this.customParsers.length; a++) if (this.customParsers[a].call(this, n)) return; if (n.indexOf("#EXT") !== 0) { this.trigger("data", { type: "comment", text: n.slice(1) }); return; } if (n = n.replace("\r", ""), t = /^#EXTM3U/.exec(n), t) { this.trigger("data", { type: "tag", tagType: "m3u" }); return; } if (t = /^#EXTINF:([0-9\.]*)?,?(.*)?$/.exec(n), t) { i = { type: "tag", tagType: "inf" }, t[1] && (i.duration = parseFloat(t[1])), t[2] && (i.title = t[2]), this.trigger("data", i); return; } if (t = /^#EXT-X-TARGETDURATION:([0-9.]*)?/.exec(n), t) { i = { type: "tag", tagType: "targetduration" }, t[1] && (i.duration = parseInt(t[1], 10)), this.trigger("data", i); return; } if (t = /^#EXT-X-VERSION:([0-9.]*)?/.exec(n), t) { i = { type: "tag", tagType: "version" }, t[1] && (i.version = parseInt(t[1], 10)), this.trigger("data", i); return; } if (t = /^#EXT-X-MEDIA-SEQUENCE:(\-?[0-9.]*)?/.exec(n), t) { i = { type: "tag", tagType: "media-sequence" }, t[1] && (i.number = parseInt(t[1], 10)), this.trigger("data", i); return; } if (t = /^#EXT-X-DISCONTINUITY-SEQUENCE:(\-?[0-9.]*)?/.exec(n), t) { i = { type: "tag", tagType: "discontinuity-sequence" }, t[1] && (i.number = parseInt(t[1], 10)), this.trigger("data", i); return; } if (t = /^#EXT-X-PLAYLIST-TYPE:(.*)?$/.exec(n), t) { i = { type: "tag", tagType: "playlist-type" }, t[1] && (i.playlistType = t[1]), this.trigger("data", i); return; } if (t = /^#EXT-X-BYTERANGE:(.*)?$/.exec(n), t) { i = qe(Sa(t[1]), { type: "tag", tagType: "byterange" }), this.trigger("data", i); return; } if (t = /^#EXT-X-ALLOW-CACHE:(YES|NO)?/.exec(n), t) { i = { type: "tag", tagType: "allow-cache" }, t[1] && (i.allowed = !/NO/.test(t[1])), this.trigger("data", i); return; } if (t = /^#EXT-X-MAP:(.*)$/.exec(n), t) { if (i = { type: "tag", tagType: "map" }, t[1]) { const a = at(t[1]); a.URI && (i.uri = a.URI), a.BYTERANGE && (i.byterange = Sa(a.BYTERANGE)); } this.trigger("data", i); return; } if (t = /^#EXT-X-STREAM-INF:(.*)$/.exec(n), t) { i = { type: "tag", tagType: "stream-inf" }, t[1] && (i.attributes = at(t[1]), i.attributes.RESOLUTION && (i.attributes.RESOLUTION = al(i.attributes.RESOLUTION)), i.attributes.BANDWIDTH && (i.attributes.BANDWIDTH = parseInt(i.attributes.BANDWIDTH, 10)), i.attributes["FRAME-RATE"] && (i.attributes["FRAME-RATE"] = parseFloat(i.attributes["FRAME-RATE"])), i.attributes["PROGRAM-ID"] && (i.attributes["PROGRAM-ID"] = parseInt(i.attributes["PROGRAM-ID"], 10))), this.trigger("data", i); return; } if (t = /^#EXT-X-MEDIA:(.*)$/.exec(n), t) { i = { type: "tag", tagType: "media" }, t[1] && (i.attributes = at(t[1])), this.trigger("data", i); return; } if (t = /^#EXT-X-ENDLIST/.exec(n), t) { this.trigger("data", { type: "tag", tagType: "endlist" }); return; } if (t = /^#EXT-X-DISCONTINUITY/.exec(n), t) { this.trigger("data", { type: "tag", tagType: "discontinuity" }); return; } if (t = /^#EXT-X-PROGRAM-DATE-TIME:(.*)$/.exec(n), t) { i = { type: "tag", tagType: "program-date-time" }, t[1] && (i.dateTimeString = t[1], i.dateTimeObject = new Date(t[1])), this.trigger("data", i); return; } if (t = /^#EXT-X-KEY:(.*)$/.exec(n), t) { i = { type: "tag", tagType: "key" }, t[1] && (i.attributes = at(t[1]), i.attributes.IV && (i.attributes.IV.substring(0, 2).toLowerCase() === "0x" && (i.attributes.IV = i.attributes.IV.substring(2)), i.attributes.IV = i.attributes.IV.match(/.{8}/g), i.attributes.IV[0] = parseInt(i.attributes.IV[0], 16), i.attributes.IV[1] = parseInt(i.attributes.IV[1], 16), i.attributes.IV[2] = parseInt(i.attributes.IV[2], 16), i.attributes.IV[3] = parseInt(i.attributes.IV[3], 16), i.attributes.IV = new Uint32Array(i.attributes.IV))), this.trigger("data", i); return; } if (t = /^#EXT-X-START:(.*)$/.exec(n), t) { i = { type: "tag", tagType: "start" }, t[1] && (i.attributes = at(t[1]), i.attributes["TIME-OFFSET"] = parseFloat(i.attributes["TIME-OFFSET"]), i.attributes.PRECISE = /YES/.test(i.attributes.PRECISE)), this.trigger("data", i); return; } if (t = /^#EXT-X-CUE-OUT-CONT:(.*)?$/.exec(n), t) { i = { type: "tag", tagType: "cue-out-cont" }, t[1] ? i.data = t[1] : i.data = "", this.trigger("data", i); return; } if (t = /^#EXT-X-CUE-OUT:(.*)?$/.exec(n), t) { i = { type: "tag", tagType: "cue-out" }, t[1] ? i.data = t[1] : i.data = "", this.trigger("data", i); return; } if (t = /^#EXT-X-CUE-IN:?(.*)?$/.exec(n), t) { i = { type: "tag", tagType: "cue-in" }, t[1] ? i.data = t[1] : i.data = "", this.trigger("data", i); return; } if (t = /^#EXT-X-SKIP:(.*)$/.exec(n), t && t[1]) { i = { type: "tag", tagType: "skip" }, i.attributes = at(t[1]), i.attributes.hasOwnProperty("SKIPPED-SEGMENTS") && (i.attributes["SKIPPED-SEGMENTS"] = parseInt(i.attributes["SKIPPED-SEGMENTS"], 10)), i.attributes.hasOwnProperty("RECENTLY-REMOVED-DATERANGES") && (i.attributes["RECENTLY-REMOVED-DATERANGES"] = i.attributes["RECENTLY-REMOVED-DATERANGES"].split(Sm)), this.trigger("data", i); return; } if (t = /^#EXT-X-PART:(.*)$/.exec(n), t && t[1]) { i = { type: "tag", tagType: "part" }, i.attributes = at(t[1]), ["DURATION"].forEach(function(a) { i.attributes.hasOwnProperty(a) && (i.attributes[a] = parseFloat(i.attributes[a])); }), ["INDEPENDENT", "GAP"].forEach(function(a) { i.attributes.hasOwnProperty(a) && (i.attributes[a] = /YES/.test(i.attributes[a])); }), i.attributes.hasOwnProperty("BYTERANGE") && (i.attributes.byterange = Sa(i.attributes.BYTERANGE)), this.trigger("data", i); return; } if (t = /^#EXT-X-SERVER-CONTROL:(.*)$/.exec(n), t && t[1]) { i = { type: "tag", tagType: "server-control" }, i.attributes = at(t[1]), ["CAN-SKIP-UNTIL", "PART-HOLD-BACK", "HOLD-BACK"].forEach(function(a) { i.attributes.hasOwnProperty(a) && (i.attributes[a] = parseFloat(i.attributes[a])); }), ["CAN-SKIP-DATERANGES", "CAN-BLOCK-RELOAD"].forEach(function(a) { i.attributes.hasOwnProperty(a) && (i.attributes[a] = /YES/.test(i.attributes[a])); }), this.trigger("data", i); return; } if (t = /^#EXT-X-PART-INF:(.*)$/.exec(n), t && t[1]) { i = { type: "tag", tagType: "part-inf" }, i.attributes = at(t[1]), ["PART-TARGET"].forEach(function(a) { i.attributes.hasOwnProperty(a) && (i.attributes[a] = parseFloat(i.attributes[a])); }), this.trigger("data", i); return; } if (t = /^#EXT-X-PRELOAD-HINT:(.*)$/.exec(n), t && t[1]) { i = { type: "tag", tagType: "preload-hint" }, i.attributes = at(t[1]), ["BYTERANGE-START", "BYTERANGE-LENGTH"].forEach(function(a) { if (i.attributes.hasOwnProperty(a)) { i.attributes[a] = parseInt(i.attributes[a], 10); const u = a === "BYTERANGE-LENGTH" ? "length" : "offset"; i.attributes.byterange = i.attributes.byterange || {}, i.attributes.byterange[u] = i.attributes[a], delete i.attributes[a]; } }), this.trigger("data", i); return; } if (t = /^#EXT-X-RENDITION-REPORT:(.*)$/.exec(n), t && t[1]) { i = { type: "tag", tagType: "rendition-report" }, i.attributes = at(t[1]), ["LAST-MSN", "LAST-PART"].forEach(function(a) { i.attributes.hasOwnProperty(a) && (i.attributes[a] = parseInt(i.attributes[a], 10)); }), this.trigger("data", i); return; } if (t = /^#EXT-X-DATERANGE:(.*)$/.exec(n), t && t[1]) { i = { type: "tag", tagType: "daterange" }, i.attributes = at(t[1]), ["ID", "CLASS"].forEach(function(u) { i.attributes.hasOwnProperty(u) && (i.attributes[u] = String(i.attributes[u])); }), ["START-DATE", "END-DATE"].forEach(function(u) { i.attributes.hasOwnProperty(u) && (i.attributes[u] = new Date(i.attributes[u])); }), ["DURATION", "PLANNED-DURATION"].forEach(function(u) { i.attributes.hasOwnProperty(u) && (i.attributes[u] = parseFloat(i.attributes[u])); }), ["END-ON-NEXT"].forEach(function(u) { i.attributes.hasOwnProperty(u) && (i.attributes[u] = /YES/i.test(i.attributes[u])); }), ["SCTE35-CMD", " SCTE35-OUT", "SCTE35-IN"].forEach(function(u) { i.attributes.hasOwnProperty(u) && (i.attributes[u] = i.attributes[u].toString(16)); }); const a = /^X-([A-Z]+-)+[A-Z]+$/; for (const u in i.attributes) { if (!a.test(u)) continue; const c = /[0-9A-Fa-f]{6}/g.test(i.attributes[u]), f = /^\d+(\.\d+)?$/.test(i.attributes[u]); i.attributes[u] = c ? i.attributes[u].toString(16) : f ? parseFloat(i.attributes[u]) : String(i.attributes[u]); } this.trigger("data", i); return; } if (t = /^#EXT-X-INDEPENDENT-SEGMENTS/.exec(n), t) { this.trigger("data", { type: "tag", tagType: "independent-segments" }); return; } if (t = /^#EXT-X-I-FRAMES-ONLY/.exec(n), t) { this.trigger("data", { type: "tag", tagType: "i-frames-only" }); return; } if (t = /^#EXT-X-CONTENT-STEERING:(.*)$/.exec(n), t) { i = { type: "tag", tagType: "content-steering" }, i.attributes = at(t[1]), this.trigger("data", i); return; } if (t = /^#EXT-X-I-FRAME-STREAM-INF:(.*)$/.exec(n), t) { i = { type: "tag", tagType: "i-frame-playlist" }, i.attributes = at(t[1]), i.attributes.URI && (i.uri = i.attributes.URI), i.attributes.BANDWIDTH && (i.attributes.BANDWIDTH = parseInt(i.attributes.BANDWIDTH, 10)), i.attributes.RESOLUTION && (i.attributes.RESOLUTION = al(i.attributes.RESOLUTION)), i.attributes["AVERAGE-BANDWIDTH"] && (i.attributes["AVERAGE-BANDWIDTH"] = parseInt(i.attributes["AVERAGE-BANDWIDTH"], 10)), i.attributes["FRAME-RATE"] && (i.attributes["FRAME-RATE"] = parseFloat(i.attributes["FRAME-RATE"])), this.trigger("data", i); return; } if (t = /^#EXT-X-DEFINE:(.*)$/.exec(n), t) { i = { type: "tag", tagType: "define" }, i.attributes = at(t[1]), this.trigger("data", i); return; } this.trigger("data", { type: "tag", data: n.slice(4) }); }); } /** * Add a parser for custom headers * * @param {Object} options a map of options for the added parser * @param {RegExp} options.expression a regular expression to match the custom header * @param {string} options.customType the custom type to register to the output * @param {Function} [options.dataParser] function to parse the line into an object * @param {boolean} [options.segment] should tag data be attached to the segment object */ addParser({ expression: e, customType: t, dataParser: i, segment: r }) { typeof i != "function" && (i = (n) => n), this.customParsers.push((n) => { if (e.exec(n)) return this.trigger("data", { type: "custom", data: i(n), customType: t, segment: r }), true; }); } /** * Add a custom header mapper * * @param {Object} options * @param {RegExp} options.expression a regular expression to match the custom header * @param {Function} options.map function to translate tag into a different tag */ addTagMapper({ expression: e, map: t }) { const i = (r) => e.test(r) ? t(r) : r; this.tagMappers.push(i); } } const Am = (s) => s.toLowerCase().replace(/-(\w)/g, (e) => e[1].toUpperCase()), mi = function(s) { const e = {}; return Object.keys(s).forEach(function(t) { e[Am(t)] = s[t]; }), e; }, Ea = function(s) { const { serverControl: e, targetDuration: t, partTargetDuration: i } = s; if (!e) return; const r = "#EXT-X-SERVER-CONTROL", n = "holdBack", a = "partHoldBack", u = t && t * 3, c = i && i * 2; t && !e.hasOwnProperty(n) && (e[n] = u, this.trigger("info", { message: `${r} defaulting HOLD-BACK to targetDuration * 3 (${u}).` })), u && e[n] < u && (this.trigger("warn", { message: `${r} clamping HOLD-BACK (${e[n]}) to targetDuration * 3 (${u})` }), e[n] = u), i && !e.hasOwnProperty(a) && (e[a] = i * 3, this.trigger("info", { message: `${r} defaulting PART-HOLD-BACK to partTargetDuration * 3 (${e[a]}).` })), i && e[a] < c && (this.trigger("warn", { message: `${r} clamping PART-HOLD-BACK (${e[a]}) to partTargetDuration * 2 (${c}).` }), e[a] = c); }; class Dm extends vo { constructor(e = {}) { super(), this.lineStream = new xm(), this.parseStream = new Cm(), this.lineStream.pipe(this.parseStream), this.mainDefinitions = e.mainDefinitions || {}, this.params = new URL(e.uri, "https://a.com").searchParams, this.lastProgramDateTime = null; const t = this, i = []; let r = {}, n, a, u = false; const c = function() { }, f = { AUDIO: {}, VIDEO: {}, "CLOSED-CAPTIONS": {}, SUBTITLES: {} }, g = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"; let y = 0; this.manifest = { allowCache: true, discontinuityStarts: [], dateRanges: [], iFramePlaylists: [], segments: [] }; let I = 0, C = 0; const R = {}; this.on("end", () => { r.uri || !r.parts && !r.preloadHints || (!r.map && n && (r.map = n), !r.key && a && (r.key = a), !r.timeline && typeof y == "number" && (r.timeline = y), this.manifest.preloadSegment = r); }), this.parseStream.on("data", function(T) { let P, B; if (t.manifest.definitions) { for (const N in t.manifest.definitions) if (T.uri && (T.uri = T.uri.replace(`{$${N}}`, t.manifest.definitions[N])), T.attributes) for (const L in T.attributes) typeof T.attributes[L] == "string" && (T.attributes[L] = T.attributes[L].replace(`{$${N}}`, t.manifest.definitions[N])); } ({ tag() { ({ version() { T.version && (this.manifest.version = T.version); }, "allow-cache"() { this.manifest.allowCache = T.allowed, "allowed" in T || (this.trigger("info", { message: "defaulting allowCache to YES" }), this.manifest.allowCache = true); }, byterange() { const N = {}; "length" in T && (r.byterange = N, N.length = T.length, "offset" in T || (T.offset = I)), "offset" in T && (r.byterange = N, N.offset = T.offset), I = N.offset + N.length; }, endlist() { this.manifest.endList = true; }, inf() { "mediaSequence" in this.manifest || (this.manifest.mediaSequence = 0, this.trigger("info", { message: "defaulting media sequence to zero" })), "discontinuitySequence" in this.manifest || (this.manifest.discontinuitySequence = 0, this.trigger("info", { message: "defaulting discontinuity sequence to zero" })), T.title && (r.title = T.title), T.duration > 0 && (r.duration = T.duration), T.duration === 0 && (r.duration = 0.01, this.trigger("info", { message: "updating zero segment duration to a small value" })), this.manifest.segments = i; }, key() { if (!T.attributes) { this.trigger("warn", { message: "ignoring key declaration without attribute list" }); return; } if (T.attributes.METHOD === "NONE") { a = null; return; } if (!T.attributes.URI) { this.trigger("warn", { message: "ignoring key declaration without URI" }); return; } if (T.attributes.KEYFORMAT === "com.apple.streamingkeydelivery") { this.manifest.contentProtection = this.manifest.contentProtection || {}, this.manifest.contentProtection["com.apple.fps.1_0"] = { attributes: T.attributes }; return; } if (T.attributes.KEYFORMAT === "com.microsoft.playready") { this.manifest.contentProtection = this.manifest.contentProtection || {}, this.manifest.contentProtection["com.microsoft.playready"] = { uri: T.attributes.URI }; return; } if (T.attributes.KEYFORMAT === g) { if (["SAMPLE-AES", "SAMPLE-AES-CTR", "SAMPLE-AES-CENC"].indexOf(T.attributes.METHOD) === -1) { this.trigger("warn", { message: "invalid key method provided for Widevine" }); return; } if (T.attributes.METHOD === "SAMPLE-AES-CENC" && this.trigger("warn", { message: "SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead" }), T.attributes.URI.substring(0, 23) !== "data:text/plain;base64,") { this.trigger("warn", { message: "invalid key URI provided for Widevine" }); return; } if (!(T.attributes.KEYID && T.attributes.KEYID.substring(0, 2) === "0x")) { this.trigger("warn", { message: "invalid key ID provided for Widevine" }); return; } this.manifest.contentProtection = this.manifest.contentProtection || {}, this.manifest.contentProtection["com.widevine.alpha"] = { attributes: { schemeIdUri: T.attributes.KEYFORMAT, // remove '0x' from the key id string keyId: T.attributes.KEYID.substring(2) }, // decode the base64-encoded PSSH box pssh: Cc(T.attributes.URI.split(",")[1]) }; return; } T.attributes.METHOD || this.trigger("warn", { message: "defaulting key method to AES-128" }), a = { method: T.attributes.METHOD || "AES-128", uri: T.attributes.URI }, typeof T.attributes.IV < "u" && (a.iv = T.attributes.IV); }, "media-sequence"() { if (!isFinite(T.number)) { this.trigger("warn", { message: "ignoring invalid media sequence: " + T.number }); return; } this.manifest.mediaSequence = T.number; }, "discontinuity-sequence"() { if (!isFinite(T.number)) { this.trigger("warn", { message: "ignoring invalid discontinuity sequence: " + T.number }); return; } this.manifest.discontinuitySequence = T.number, y = T.number; }, "playlist-type"() { if (!/VOD|EVENT/.test(T.playlistType)) { this.trigger("warn", { message: "ignoring unknown playlist type: " + T.playlist }); return; } this.manifest.playlistType = T.playlistType; }, map() { n = {}, T.uri && (n.uri = T.uri), T.byterange && (n.byterange = T.byterange), a && (n.key = a); }, "stream-inf"() { if (this.manifest.playlists = i, this.manifest.mediaGroups = this.manifest.mediaGroups || f, !T.attributes) { this.trigger("warn", { message: "ignoring empty stream-inf attributes" }); return; } r.attributes || (r.attributes = {}), qe(r.attributes, T.attributes); }, media() { if (this.manifest.mediaGroups = this.manifest.mediaGroups || f, !(T.attributes && T.attributes.TYPE && T.attributes["GROUP-ID"] && T.attributes.NAME)) { this.trigger("warn", { message: "ignoring incomplete or missing media group" }); return; } const N = this.manifest.mediaGroups[T.attributes.TYPE]; N[T.attributes["GROUP-ID"]] = N[T.attributes["GROUP-ID"]] || {}, P = N[T.attributes["GROUP-ID"]], B = { default: /yes/i.test(T.attributes.DEFAULT) }, B.default ? B.autoselect = true : B.autoselect = /yes/i.test(T.attributes.AUTOSELECT), T.attributes.LANGUAGE && (B.language = T.attributes.LANGUAGE), T.attributes.URI && (B.uri = T.attributes.URI), T.attributes["INSTREAM-ID"] && (B.instreamId = T.attributes["INSTREAM-ID"]), T.attributes.CHARACTERISTICS && (B.characteristics = T.attributes.CHARACTERISTICS), T.attributes.FORCED && (B.forced = /yes/i.test(T.attributes.FORCED)), P[T.attributes.NAME] = B; }, discontinuity() { y += 1, r.discontinuity = true, this.manifest.discontinuityStarts.push(i.length); }, "program-date-time"() { typeof this.manifest.dateTimeString > "u" && (this.manifest.dateTimeString = T.dateTimeString, this.manifest.dateTimeObject = T.dateTimeObject), r.dateTimeString = T.dateTimeString, r.dateTimeObject = T.dateTimeObject; const { lastProgramDateTime: N } = this; this.lastProgramDateTime = new Date(T.dateTimeString).getTime(), N === null && this.manifest.segments.reduceRight((L, z) => (z.programDateTime = L - z.duration * 1e3, z.programDateTime), this.lastProgramDateTime); }, targetduration() { if (!isFinite(T.duration) || T.duration < 0) { this.trigger("warn", { message: "ignoring invalid target duration: " + T.duration }); return; } this.manifest.targetDuration = T.duration, Ea.call(this, this.manifest); }, start() { if (!T.attributes || isNaN(T.attributes["TIME-OFFSET"])) { this.trigger("warn", { message: "ignoring start declaration without appropriate attribute list" }); return; } this.manifest.start = { timeOffset: T.attributes["TIME-OFFSET"], precise: T.attributes.PRECISE }; }, "cue-out"() { r.cueOut = T.data; }, "cue-out-cont"() { r.cueOutCont = T.data; }, "cue-in"() { r.cueIn = T.data; }, skip() { this.manifest.skip = mi(T.attributes), this.warnOnMissingAttributes_("#EXT-X-SKIP", T.attributes, ["SKIPPED-SEGMENTS"]); }, part() { u = true; const N = this.manifest.segments.length, L = mi(T.attributes); r.parts = r.parts || [], r.parts.push(L), L.byterange && (L.byterange.hasOwnProperty("offset") || (L.byterange.offset = C), C = L.byterange.offset + L.byterange.length); const z = r.parts.length - 1; this.warnOnMissingAttributes_(`#EXT-X-PART #${z} for segment #${N}`, T.attributes, ["URI", "DURATION"]), this.manifest.renditionReports && this.manifest.renditionReports.forEach((O, U) => { O.hasOwnProperty("lastPart") || this.trigger("warn", { message: `#EXT-X-RENDITION-REPORT #${U} lacks required attribute(s): LAST-PART` }); }); }, "server-control"() { const N = this.manifest.serverControl = mi(T.attributes); N.hasOwnProperty("canBlockReload") || (N.canBlockReload = false, this.trigger("info", { message: "#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false" })), Ea.call(this, this.manifest), N.canSkipDateranges && !N.hasOwnProperty("canSkipUntil") && this.trigger("warn", { message: "#EXT-X-SERVER-CONTROL lacks required attribute CAN-SKIP-UNTIL which is required when CAN-SKIP-DATERANGES is set" }); }, "preload-hint"() { const N = this.manifest.segments.length, L = mi(T.attributes), z = L.type && L.type === "PART"; r.preloadHints = r.preloadHints || [], r.preloadHints.push(L), L.byterange && (L.byterange.hasOwnProperty("offset") || (L.byterange.offset = z ? C : 0, z && (C = L.byterange.offset + L.byterange.length))); const O = r.preloadHints.length - 1; if (this.warnOnMissingAttributes_(`#EXT-X-PRELOAD-HINT #${O} for segment #${N}`, T.attributes, ["TYPE", "URI"]), !!L.type) for (let U = 0; U < r.preloadHints.length - 1; U++) { const V = r.preloadHints[U]; V.type && V.type === L.type && this.trigger("warn", { message: `#EXT-X-PRELOAD-HINT #${O} for segment #${N} has the same TYPE ${L.type} as preload hint #${U}` }); } }, "rendition-report"() { const N = mi(T.attributes); this.manifest.renditionReports = this.manifest.renditionReports || [], this.manifest.renditionReports.push(N); const L = this.manifest.renditionReports.length - 1, z = ["LAST-MSN", "URI"]; u && z.push("LAST-PART"), this.warnOnMissingAttributes_(`#EXT-X-RENDITION-REPORT #${L}`, T.attributes, z); }, "part-inf"() { this.manifest.partInf = mi(T.attributes), this.warnOnMissingAttributes_("#EXT-X-PART-INF", T.attributes, ["PART-TARGET"]), this.manifest.partInf.partTarget && (this.manifest.partTargetDuration = this.manifest.partInf.partTarget), Ea.call(this, this.manifest); }, daterange() { this.manifest.dateRanges.push(mi(T.attributes)); const N = this.manifest.dateRanges.length - 1; this.warnOnMissingAttributes_(`#EXT-X-DATERANGE #${N}`, T.attributes, ["ID", "START-DATE"]); const L = this.manifest.dateRanges[N]; L.endDate && L.startDate && new Date(L.endDate) < new Date(L.startDate) && this.trigger("warn", { message: "EXT-X-DATERANGE END-DATE must be equal to or later than the value of the START-DATE" }), L.duration && L.duration < 0 && this.trigger("warn", { message: "EXT-X-DATERANGE DURATION must not be negative" }), L.plannedDuration && L.plannedDuration < 0 && this.trigger("warn", { message: "EXT-X-DATERANGE PLANNED-DURATION must not be negative" }); const z = !!L.endOnNext; if (z && !L.class && this.trigger("warn", { message: "EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must have a CLASS attribute" }), z && (L.duration || L.endDate) && this.trigger("warn", { message: "EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must not contain DURATION or END-DATE attributes" }), L.duration && L.endDate) { const U = L.startDate.getTime() + L.duration * 1e3; this.manifest.dateRanges[N].endDate = new Date(U); } if (!R[L.id]) R[L.id] = L; else { for (const U in R[L.id]) if (L[U] && JSON.stringify(R[L.id][U]) !== JSON.stringify(L[U])) { this.trigger("warn", { message: "EXT-X-DATERANGE tags with the same ID in a playlist must have the same attributes values" }); break; } const O = this.manifest.dateRanges.findIndex((U) => U.id === L.id); this.manifest.dateRanges[O] = qe(this.manifest.dateRanges[O], L), R[L.id] = qe(R[L.id], L), this.manifest.dateRanges.pop(); } }, "independent-segments"() { this.manifest.independentSegments = true; }, "i-frames-only"() { this.manifest.iFramesOnly = true, this.requiredCompatibilityversion(this.manifest.version, 4); }, "content-steering"() { this.manifest.contentSteering = mi(T.attributes), this.warnOnMissingAttributes_("#EXT-X-CONTENT-STEERING", T.attributes, ["SERVER-URI"]); }, /** @this {Parser} */ define() { this.manifest.definitions = this.manifest.definitions || {}; const N = (L, z) => { if (L in this.manifest.definitions) { this.trigger("error", { message: `EXT-X-DEFINE: Duplicate name ${L}` }); return; } this.manifest.definitions[L] = z; }; if ("QUERYPARAM" in T.attributes) { if ("NAME" in T.attributes || "IMPORT" in T.attributes) { this.trigger("error", { message: "EXT-X-DEFINE: Invalid attributes" }); return; } const L = this.params.get(T.attributes.QUERYPARAM); if (!L) { this.trigger("error", { message: `EXT-X-DEFINE: No query param ${T.attributes.QUERYPARAM}` }); return; } N(T.attributes.QUERYPARAM, decodeURIComponent(L)); return; } if ("NAME" in T.attributes) { if ("IMPORT" in T.attributes) { this.trigger("error", { message: "EXT-X-DEFINE: Invalid attributes" }); return; } if (!("VALUE" in T.attributes) || typeof T.attributes.VALUE != "string") { this.trigger("error", { message: `EXT-X-DEFINE: No value for ${T.attributes.NAME}` }); return; } N(T.attributes.NAME, T.attributes.VALUE); return; } if ("IMPORT" in T.attributes) { if (!this.mainDefinitions[T.attributes.IMPORT]) { this.trigger("error", { message: `EXT-X-DEFINE: No value ${T.attributes.IMPORT} to import, or IMPORT used on main playlist` }); return; } N(T.attributes.IMPORT, this.mainDefinitions[T.attributes.IMPORT]); return; } this.trigger("error", { message: "EXT-X-DEFINE: No attribute" }); }, "i-frame-playlist"() { this.manifest.iFramePlaylists.push({ attributes: T.attributes, uri: T.uri, timeline: y }), this.warnOnMissingAttributes_("#EXT-X-I-FRAME-STREAM-INF", T.attributes, ["BANDWIDTH", "URI"]); } }[T.tagType] || c).call(t); }, uri() { r.uri = T.uri, i.push(r), this.manifest.targetDuration && !("duration" in r) && (this.trigger("warn", { message: "defaulting segment duration to the target duration" }), r.duration = this.manifest.targetDuration), a && (r.key = a), r.timeline = y, n && (r.map = n), C = 0, this.lastProgramDateTime !== null && (r.programDateTime = this.lastProgramDateTime, this.lastProgramDateTime += r.duration * 1e3), r = {}; }, comment() { }, custom() { T.segment ? (r.custom = r.custom || {}, r.custom[T.customType] = T.data) : (this.manifest.custom = this.manifest.custom || {}, this.manifest.custom[T.customType] = T.data); } })[T.type].call(t); }); } requiredCompatibilityversion(e, t) { (e < t || !e) && this.trigger("warn", { message: `manifest must be at least version ${t}` }); } warnOnMissingAttributes_(e, t, i) { const r = []; i.forEach(function(n) { t.hasOwnProperty(n) || r.push(n); }), r.length && this.trigger("warn", { message: `${e} lacks required attribute(s): ${r.join(", ")}` }); } /** * Parse the input string and update the manifest object. * * @param {string} chunk a potentially incomplete portion of the manifest */ push(e) { this.lineStream.push(e); } /** * Flush any remaining input. This can be handy if the last line of an M3U8 * manifest did not contain a trailing newline but the file has been * completely received. */ end() { this.lineStream.push(` `), this.manifest.dateRanges.length && this.lastProgramDateTime === null && this.trigger("warn", { message: "A playlist with EXT-X-DATERANGE tag must contain atleast one EXT-X-PROGRAM-DATE-TIME tag" }), this.lastProgramDateTime = null, this.trigger("end"); } /** * Add an additional parser for non-standard tags * * @param {Object} options a map of options for the added parser * @param {RegExp} options.expression a regular expression to match the custom header * @param {string} options.customType the custom type to register to the output * @param {Function} [options.dataParser] function to parse the line into an object * @param {boolean} [options.segment] should tag data be attached to the segment object */ addParser(e) { this.parseStream.addParser(e); } /** * Add a custom header mapper * * @param {Object} options * @param {RegExp} options.expression a regular expression to match the custom header * @param {Function} options.map function to translate tag into a different tag */ addTagMapper(e) { this.parseStream.addTagMapper(e); } } var qi = { // to determine mime types mp4: /^(av0?1|avc0?[1234]|vp0?9|flac|opus|mp3|mp4a|mp4v|stpp.ttml.im1t)/, webm: /^(vp0?[89]|av0?1|opus|vorbis)/, ogg: /^(vp0?[89]|theora|flac|opus|vorbis)/, // to determine if a codec is audio or video video: /^(av0?1|avc0?[1234]|vp0?[89]|hvc1|hev1|theora|mp4v)/, audio: /^(mp4a|flac|vorbis|opus|ac-[34]|ec-3|alac|mp3|speex|aac)/, text: /^(stpp.ttml.im1t)/, // mux.js support regex muxerVideo: /^(avc0?1)/, muxerAudio: /^(mp4a)/, // match nothing as muxer does not support text right now. // there cannot never be a character before the start of a string // so this matches nothing. muxerText: /a^/ }, wm = ["video", "audio", "text"], ol = ["Video", "Audio", "Text"], Ac = function(e) { return e && e.replace(/avc1\.(\d+)\.(\d+)/i, function(t, i, r) { var n = ("00" + Number(i).toString(16)).slice(-2), a = ("00" + Number(r).toString(16)).slice(-2); return "avc1." + n + "00" + a; }); }, Ht = function(e) { e === void 0 && (e = ""); var t = e.split(","), i = []; return t.forEach(function(r) { r = r.trim(); var n; wm.forEach(function(a) { var u = qi[a].exec(r.toLowerCase()); if (!(!u || u.length <= 1)) { n = a; var c = r.substring(0, u[1].length), f = r.replace(c, ""); i.push({ type: c, details: f, mediaType: a }); } }), n || i.push({ type: r, details: "", mediaType: "unknown" }); }), i; }, Im = function(e, t) { if (!e.mediaGroups.AUDIO || !t) return null; var i = e.mediaGroups.AUDIO[t]; if (!i) return null; for (var r in i) { var n = i[r]; if (n.default && n.playlists) return Ht(n.playlists[0].attributes.CODECS); } return null; }, Dc = function(e) { return e === void 0 && (e = ""), qi.audio.test(e.trim().toLowerCase()); }, km = function(e) { return e === void 0 && (e = ""), qi.text.test(e.trim().toLowerCase()); }, hs = function(e) { if (!(!e || typeof e != "string")) { var t = e.toLowerCase().split(",").map(function(n) { return Ac(n.trim()); }), i = "video"; t.length === 1 && Dc(t[0]) ? i = "audio" : t.length === 1 && km(t[0]) && (i = "application"); var r = "mp4"; return t.every(function(n) { return qi.mp4.test(n); }) ? r = "mp4" : t.every(function(n) { return qi.webm.test(n); }) ? r = "webm" : t.every(function(n) { return qi.ogg.test(n); }) && (r = "ogg"), i + "/" + r + ';codecs="' + e + '"'; } }, ir = function(e, t) { return e === void 0 && (e = ""), t === void 0 && (t = false), D.MediaSource && D.MediaSource.isTypeSupported && D.MediaSource.isTypeSupported(hs(e)) || t && D.ManagedMediaSource && D.ManagedMediaSource.isTypeSupported && D.ManagedMediaSource.isTypeSupported(hs(e)) || false; }, Ca = function(e) { return e === void 0 && (e = ""), e.toLowerCase().split(",").every(function(t) { t = t.trim(); for (var i = 0; i < ol.length; i++) { var r = ol[i]; if (qi["muxer" + r].test(t)) return true; } return false; }); }, ul = "mp4a.40.2", Pm = "avc1.4d400d", Om = /^(audio|video|application)\/(x-|vnd\.apple\.)?mpegurl/i, Lm = /^application\/dash\+xml/i, wc = function(e) { return Om.test(e) ? "hls" : Lm.test(e) ? "dash" : e === "application/vnd.videojs.vhs+json" ? "vhs-json" : null; }, Rm = function(e) { return e.toString(2).length; }, Mm = function(e) { return Math.ceil(Rm(e) / 8); }, Ic = function(e) { return ArrayBuffer.isView === "function" ? ArrayBuffer.isView(e) : e && e.buffer instanceof ArrayBuffer; }, Nm = function(e) { return Ic(e); }, le = function(e) { return e instanceof Uint8Array ? e : (!Array.isArray(e) && !Nm(e) && !(e instanceof ArrayBuffer) && (typeof e != "number" || typeof e == "number" && e !== e ? e = 0 : e = [e]), new Uint8Array(e && e.buffer || e, e && e.byteOffset || 0, e && e.byteLength || 0)); }, Ye = D.BigInt || Number, Ga = [Ye("0x1"), Ye("0x100"), Ye("0x10000"), Ye("0x1000000"), Ye("0x100000000"), Ye("0x10000000000"), Ye("0x1000000000000"), Ye("0x100000000000000"), Ye("0x10000000000000000")], Bm = function(e, t) { var i = t === void 0 ? {} : t, r = i.signed, n = r === void 0 ? false : r, a = i.le, u = a === void 0 ? false : a; e = le(e); var c = u ? "reduce" : "reduceRight", f = e[c] ? e[c] : Array.prototype[c], g = f.call(e, function(I, C, R) { var T = u ? R : Math.abs(R + 1 - e.length); return I + Ye(C) * Ga[T]; }, Ye(0)); if (n) { var y = Ga[e.length] / Ye(2) - Ye(1); g = Ye(g), g > y && (g -= y, g -= y, g -= Ye(2)); } return Number(g); }, Fm = function(e, t) { var i = {}, r = i.le, n = r === void 0 ? false : r; (typeof e != "bigint" && typeof e != "number" || typeof e == "number" && e !== e) && (e = 0), e = Ye(e); for (var a = Mm(e), u = new Uint8Array(new ArrayBuffer(a)), c = 0; c < a; c++) { var f = n ? c : Math.abs(c + 1 - u.length); u[f] = Number(e / Ga[c] & Ye(255)), e < 0 && (u[f] = Math.abs(~u[f]), u[f] -= c === 0 ? 1 : 2); } return u; }, kc = function(e, t) { if (typeof e != "string" && e && typeof e.toString == "function" && (e = e.toString()), typeof e != "string") return new Uint8Array(); t || (e = unescape(encodeURIComponent(e))); for (var i = new Uint8Array(e.length), r = 0; r < e.length; r++) i[r] = e.charCodeAt(r); return i; }, Um = function() { for (var e = arguments.length, t = new Array(e), i = 0; i < e; i++) t[i] = arguments[i]; if (t = t.filter(function(u) { return u && (u.byteLength || u.length) && typeof u != "string"; }), t.length <= 1) return le(t[0]); var r = t.reduce(function(u, c, f) { return u + (c.byteLength || c.length); }, 0), n = new Uint8Array(r), a = 0; return t.forEach(function(u) { u = le(u), n.set(u, a), a += u.byteLength; }), n; }, Pe = function(e, t, i) { var r = i === void 0 ? {} : i, n = r.offset, a = n === void 0 ? 0 : n, u = r.mask, c = u === void 0 ? [] : u; e = le(e), t = le(t); var f = t.every ? t.every : Array.prototype.every; return t.length && e.length - a >= t.length && // ie 11 doesn't support every on uin8 f.call(t, function(g, y) { var I = c[y] ? c[y] & e[a + y] : e[a + y]; return g === I; }); }, qm = function(e, t, i) { t.forEach(function(r) { for (var n in e.mediaGroups[r]) for (var a in e.mediaGroups[r][n]) { var u = e.mediaGroups[r][n][a]; i(u, r, n, a); } }); }, Xs = {}, si = {}, Li = {}, ll; function Pn() { if (ll) return Li; ll = 1; function s(n, a, u) { if (u === void 0 && (u = Array.prototype), n && typeof u.find == "function") return u.find.call(n, a); for (var c = 0; c < n.length; c++) if (Object.prototype.hasOwnProperty.call(n, c)) { var f = n[c]; if (a.call(void 0, f, c, n)) return f; } } function e(n, a) { return a === void 0 && (a = Object), a && typeof a.freeze == "function" ? a.freeze(n) : n; } function t(n, a) { if (n === null || typeof n != "object") throw new TypeError("target is not an object"); for (var u in a) Object.prototype.hasOwnProperty.call(a, u) && (n[u] = a[u]); return n; } var i = e({ /** * `text/html`, the only mime type that triggers treating an XML document as HTML. * * @see DOMParser.SupportedType.isHTML * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration * @see https://en.wikipedia.org/wiki/HTML Wikipedia * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring WHATWG HTML Spec */ HTML: "text/html", /** * Helper method to check a mime type if it indicates an HTML document * * @param {string} [value] * @returns {boolean} * * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration * @see https://en.wikipedia.org/wiki/HTML Wikipedia * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring */ isHTML: function(n) { return n === i.HTML; }, /** * `application/xml`, the standard mime type for XML documents. * * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType registration * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303 * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia */ XML_APPLICATION: "application/xml", /** * `text/html`, an alias for `application/xml`. * * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303 * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia */ XML_TEXT: "text/xml", /** * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace, * but is parsed as an XML document. * * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType registration * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec * @see https://en.wikipedia.org/wiki/XHTML Wikipedia */ XML_XHTML_APPLICATION: "application/xhtml+xml", /** * `image/svg+xml`, * * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1 * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia */ XML_SVG_IMAGE: "image/svg+xml" }), r = e({ /** * The XHTML namespace. * * @see http://www.w3.org/1999/xhtml */ HTML: "http://www.w3.org/1999/xhtml", /** * Checks if `uri` equals `NAMESPACE.HTML`. * * @param {string} [uri] * * @see NAMESPACE.HTML */ isHTML: function(n) { return n === r.HTML; }, /** * The SVG namespace. * * @see http://www.w3.org/2000/svg */ SVG: "http://www.w3.org/2000/svg", /** * The `xml:` namespace. * * @see http://www.w3.org/XML/1998/namespace */ XML: "http://www.w3.org/XML/1998/namespace", /** * The `xmlns:` namespace * * @see https://www.w3.org/2000/xmlns/ */ XMLNS: "http://www.w3.org/2000/xmlns/" }); return Li.assign = t, Li.find = s, Li.freeze = e, Li.MIME_TYPE = i, Li.NAMESPACE = r, Li; } var cl; function Pc() { if (cl) return si; cl = 1; var s = /* @__PURE__ */ Pn(), e = s.find, t = s.NAMESPACE; function i(_) { return _ !== ""; } function r(_) { return _ ? _.split(/[\t\n\f\r ]+/).filter(i) : []; } function n(_, b) { return _.hasOwnProperty(b) || (_[b] = true), _; } function a(_) { if (!_) return []; var b = r(_); return Object.keys(b.reduce(n, {})); } function u(_) { return function(b) { return _ && _.indexOf(b) !== -1; }; } function c(_, b) { for (var k in _) Object.prototype.hasOwnProperty.call(_, k) && (b[k] = _[k]); } function f(_, b) { var k = _.prototype; if (!(k instanceof b)) { let $ = function() { }; $.prototype = b.prototype, $ = new $(), c(k, $), _.prototype = k = $; } k.constructor != _ && (typeof _ != "function" && console.error("unknown Class:" + _), k.constructor = _); } var g = {}, y = g.ELEMENT_NODE = 1, I = g.ATTRIBUTE_NODE = 2, C = g.TEXT_NODE = 3, R = g.CDATA_SECTION_NODE = 4, T = g.ENTITY_REFERENCE_NODE = 5, P = g.ENTITY_NODE = 6, B = g.PROCESSING_INSTRUCTION_NODE = 7, N = g.COMMENT_NODE = 8, L = g.DOCUMENT_NODE = 9, z = g.DOCUMENT_TYPE_NODE = 10, O = g.DOCUMENT_FRAGMENT_NODE = 11, U = g.NOTATION_NODE = 12, V = {}, Q = {}; V.INDEX_SIZE_ERR = (Q[1] = "Index size error", 1), V.DOMSTRING_SIZE_ERR = (Q[2] = "DOMString size error", 2); var v = V.HIERARCHY_REQUEST_ERR = (Q[3] = "Hierarchy request error", 3); V.WRONG_DOCUMENT_ERR = (Q[4] = "Wrong document", 4), V.INVALID_CHARACTER_ERR = (Q[5] = "Invalid character", 5), V.NO_DATA_ALLOWED_ERR = (Q[6] = "No data allowed", 6), V.NO_MODIFICATION_ALLOWED_ERR = (Q[7] = "No modification allowed", 7); var E = V.NOT_FOUND_ERR = (Q[8] = "Not found", 8); V.NOT_SUPPORTED_ERR = (Q[9] = "Not supported", 9); var q = V.INUSE_ATTRIBUTE_ERR = (Q[10] = "Attribute in use", 10); V.INVALID_STATE_ERR = (Q[11] = "Invalid state", 11), V.SYNTAX_ERR = (Q[12] = "Syntax error", 12), V.INVALID_MODIFICATION_ERR = (Q[13] = "Invalid modification", 13), V.NAMESPACE_ERR = (Q[14] = "Invalid namespace", 14), V.INVALID_ACCESS_ERR = (Q[15] = "Invalid access", 15); function j(_, b) { if (b instanceof Error) var k = b; else k = this, Error.call(this, Q[_]), this.message = Q[_], Error.captureStackTrace && Error.captureStackTrace(this, j); return k.code = _, b && (this.message = this.message + ": " + b), k; } j.prototype = Error.prototype, c(V, j); function H() { } H.prototype = { /** * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive. * @standard level1 */ length: 0, /** * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null. * @standard level1 * @param index unsigned long * Index into the collection. * @return Node * The node at the indexth position in the NodeList, or null if that is not a valid index. */ item: function(_) { return _ >= 0 && _ < this.length ? this[_] : null; }, toString: function(_, b) { for (var k = [], $ = 0; $ < this.length; $++) di(this[$], k, _, b); return k.join(""); }, /** * @private * @param {function (Node):boolean} predicate * @returns {Node[]} */ filter: function(_) { return Array.prototype.filter.call(this, _); }, /** * @private * @param {Node} item * @returns {number} */ indexOf: function(_) { return Array.prototype.indexOf.call(this, _); } }; function Y(_, b) { this._node = _, this._refresh = b, ie(this); } function ie(_) { var b = _._node._inc || _._node.ownerDocument._inc; if (_._inc !== b) { var k = _._refresh(_._node); if (xr(_, "length", k.length), !_.$$length || k.length < _.$$length) for (var $ = k.length; $ in _; $++) Object.prototype.hasOwnProperty.call(_, $) && delete _[$]; c(k, _), _._inc = b; } } Y.prototype.item = function(_) { return ie(this), this[_] || null; }, f(Y, H); function re() { } function W(_, b) { for (var k = _.length; k--; ) if (_[k] === b) return k; } function Z(_, b, k, $) { if ($ ? b[W(b, $)] = k : b[b.length++] = k, _) { k.ownerElement = _; var ne = _.ownerDocument; ne && ($ && Ke(ne, _, $), he(ne, _, k)); } } function J(_, b, k) { var $ = W(b, k); if ($ >= 0) { for (var ne = b.length - 1; $ < ne; ) b[$] = b[++$]; if (b.length = ne, _) { var de = _.ownerDocument; de && (Ke(de, _, k), k.ownerElement = null); } } else throw new j(E, new Error(_.tagName + "@" + k)); } re.prototype = { length: 0, item: H.prototype.item, getNamedItem: function(_) { for (var b = this.length; b--; ) { var k = this[b]; if (k.nodeName == _) return k; } }, setNamedItem: function(_) { var b = _.ownerElement; if (b && b != this._ownerElement) throw new j(q); var k = this.getNamedItem(_.nodeName); return Z(this._ownerElement, this, _, k), k; }, /* returns Node */ setNamedItemNS: function(_) { var b = _.ownerElement, k; if (b && b != this._ownerElement) throw new j(q); return k = this.getNamedItemNS(_.namespaceURI, _.localName), Z(this._ownerElement, this, _, k), k; }, /* returns Node */ removeNamedItem: function(_) { var b = this.getNamedItem(_); return J(this._ownerElement, this, b), b; }, // raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR //for level2 removeNamedItemNS: function(_, b) { var k = this.getNamedItemNS(_, b); return J(this._ownerElement, this, k), k; }, getNamedItemNS: function(_, b) { for (var k = this.length; k--; ) { var $ = this[k]; if ($.localName == b && $.namespaceURI == _) return $; } return null; } }; function te() { } te.prototype = { /** * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given feature is supported. * The different implementations fairly diverged in what kind of features were reported. * The latest version of the spec settled to force this method to always return true, where the functionality was accurate and in use. * * @deprecated It is deprecated and modern browsers return true in all cases. * * @param {string} feature * @param {string} [version] * @returns {boolean} always true * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard */ hasFeature: function(_, b) { return true; }, /** * Creates an XML Document object of the specified type with its document element. * * __It behaves slightly different from the description in the living standard__: * - There is no interface/class `XMLDocument`, it returns a `Document` instance. * - `contentType`, `encoding`, `mode`, `origin`, `url` fields are currently not declared. * - this implementation is not validating names or qualified names * (when parsing XML strings, the SAX parser takes care of that) * * @param {string|null} namespaceURI * @param {string} qualifiedName * @param {DocumentType=null} doctype * @returns {Document} * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM Level 2 Core (initial) * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core * * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names */ createDocument: function(_, b, k) { var $ = new _e(); if ($.implementation = this, $.childNodes = new H(), $.doctype = k || null, k && $.appendChild(k), b) { var ne = $.createElementNS(_, b); $.appendChild(ne); } return $; }, /** * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`. * * __This behavior is slightly different from the in the specs__: * - this implementation is not validating names or qualified names * (when parsing XML strings, the SAX parser takes care of that) * * @param {string} qualifiedName * @param {string} [publicId] * @param {string} [systemId] * @returns {DocumentType} which can either be used with `DOMImplementation.createDocument` upon document creation * or can be put into the document via methods like `Node.insertBefore()` or `Node.replaceChild()` * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType MDN * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM Level 2 Core * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living Standard * * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names */ createDocumentType: function(_, b, k) { var $ = new ei(); return $.name = _, $.nodeName = _, $.publicId = b || "", $.systemId = k || "", $; } }; function ee() { } ee.prototype = { firstChild: null, lastChild: null, previousSibling: null, nextSibling: null, attributes: null, parentNode: null, childNodes: null, ownerDocument: null, nodeValue: null, namespaceURI: null, prefix: null, localName: null, // Modified in DOM Level 2: insertBefore: function(_, b) { return bt(this, _, b); }, replaceChild: function(_, b) { bt(this, _, b, pt), b && this.removeChild(b); }, removeChild: function(_) { return $e(this, _); }, appendChild: function(_) { return this.insertBefore(_, null); }, hasChildNodes: function() { return this.firstChild != null; }, cloneNode: function(_) { return Ps(this.ownerDocument || this, this, _); }, // Modified in DOM Level 2: normalize: function() { for (var _ = this.firstChild; _; ) { var b = _.nextSibling; b && b.nodeType == C && _.nodeType == C ? (this.removeChild(b), _.appendData(b.data)) : (_.normalize(), _ = b); } }, // Introduced in DOM Level 2: isSupported: function(_, b) { return this.ownerDocument.implementation.hasFeature(_, b); }, // Introduced in DOM Level 2: hasAttributes: function() { return this.attributes.length > 0; }, /** * Look up the prefix associated to the given namespace URI, starting from this node. * **The default namespace declarations are ignored by this method.** * See Namespace Prefix Lookup for details on the algorithm used by this method. * * _Note: The implementation seems to be incomplete when compared to the algorithm described in the specs._ * * @param {string | null} namespaceURI * @returns {string | null} * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix * @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo * @see https://dom.spec.whatwg.org/#dom-node-lookupprefix * @see https://github.com/xmldom/xmldom/issues/322 */ lookupPrefix: function(_) { for (var b = this; b; ) { var k = b._nsMap; if (k) { for (var $ in k) if (Object.prototype.hasOwnProperty.call(k, $) && k[$] === _) return $; } b = b.nodeType == I ? b.ownerDocument : b.parentNode; } return null; }, // Introduced in DOM Level 3: lookupNamespaceURI: function(_) { for (var b = this; b; ) { var k = b._nsMap; if (k && Object.prototype.hasOwnProperty.call(k, _)) return k[_]; b = b.nodeType == I ? b.ownerDocument : b.parentNode; } return null; }, // Introduced in DOM Level 3: isDefaultNamespace: function(_) { var b = this.lookupPrefix(_); return b == null; } }; function fe(_) { return _ == "<" && "<" || _ == ">" && ">" || _ == "&" && "&" || _ == '"' && """ || "&#" + _.charCodeAt() + ";"; } c(g, ee), c(g, ee.prototype); function me(_, b) { if (b(_)) return true; if (_ = _.firstChild) do if (me(_, b)) return true; while (_ = _.nextSibling); } function _e() { this.ownerDocument = this; } function he(_, b, k) { _ && _._inc++; var $ = k.namespaceURI; $ === t.XMLNS && (b._nsMap[k.prefix ? k.localName : ""] = k.value); } function Ke(_, b, k, $) { _ && _._inc++; var ne = k.namespaceURI; ne === t.XMLNS && delete b._nsMap[k.prefix ? k.localName : ""]; } function Je(_, b, k) { if (_ && _._inc) { _._inc++; var $ = b.childNodes; if (k) $[$.length++] = k; else { for (var ne = b.firstChild, de = 0; ne; ) $[de++] = ne, ne = ne.nextSibling; $.length = de, delete $[$.length]; } } } function $e(_, b) { var k = b.previousSibling, $ = b.nextSibling; return k ? k.nextSibling = $ : _.firstChild = $, $ ? $.previousSibling = k : _.lastChild = k, b.parentNode = null, b.previousSibling = null, b.nextSibling = null, Je(_.ownerDocument, _), b; } function Ze(_) { return _ && (_.nodeType === ee.DOCUMENT_NODE || _.nodeType === ee.DOCUMENT_FRAGMENT_NODE || _.nodeType === ee.ELEMENT_NODE); } function vt(_) { return _ && (rt(_) || li(_) || Qe(_) || _.nodeType === ee.DOCUMENT_FRAGMENT_NODE || _.nodeType === ee.COMMENT_NODE || _.nodeType === ee.PROCESSING_INSTRUCTION_NODE); } function Qe(_) { return _ && _.nodeType === ee.DOCUMENT_TYPE_NODE; } function rt(_) { return _ && _.nodeType === ee.ELEMENT_NODE; } function li(_) { return _ && _.nodeType === ee.TEXT_NODE; } function Ve(_, b) { var k = _.childNodes || []; if (e(k, rt) || Qe(b)) return false; var $ = e(k, Qe); return !(b && $ && k.indexOf($) > k.indexOf(b)); } function ci(_, b) { var k = _.childNodes || []; function $(de) { return rt(de) && de !== b; } if (e(k, $)) return false; var ne = e(k, Qe); return !(b && ne && k.indexOf(ne) > k.indexOf(b)); } function He(_, b, k) { if (!Ze(_)) throw new j(v, "Unexpected parent node type " + _.nodeType); if (k && k.parentNode !== _) throw new j(E, "child not in parent"); if ( // 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException. !vt(b) || // 5. If either `node` is a Text node and `parent` is a document, // the sax parser currently adds top level text nodes, this will be fixed in 0.9.0 // || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE) // or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException. Qe(b) && _.nodeType !== ee.DOCUMENT_NODE ) throw new j( v, "Unexpected node type " + b.nodeType + " for parent node type " + _.nodeType ); } function Gi(_, b, k) { var $ = _.childNodes || [], ne = b.childNodes || []; if (b.nodeType === ee.DOCUMENT_FRAGMENT_NODE) { var de = ne.filter(rt); if (de.length > 1 || e(ne, li)) throw new j(v, "More than one element or text in fragment"); if (de.length === 1 && !Ve(_, k)) throw new j(v, "Element in fragment can not be inserted before doctype"); } if (rt(b) && !Ve(_, k)) throw new j(v, "Only one element can be added and only after doctype"); if (Qe(b)) { if (e($, Qe)) throw new j(v, "Only one doctype is allowed"); var Ae = e($, rt); if (k && $.indexOf(Ae) < $.indexOf(k)) throw new j(v, "Doctype can only be inserted before an element"); if (!k && Ae) throw new j(v, "Doctype can not be appended since element is present"); } } function pt(_, b, k) { var $ = _.childNodes || [], ne = b.childNodes || []; if (b.nodeType === ee.DOCUMENT_FRAGMENT_NODE) { var de = ne.filter(rt); if (de.length > 1 || e(ne, li)) throw new j(v, "More than one element or text in fragment"); if (de.length === 1 && !ci(_, k)) throw new j(v, "Element in fragment can not be inserted before doctype"); } if (rt(b) && !ci(_, k)) throw new j(v, "Only one element can be added and only after doctype"); if (Qe(b)) { if (e($, function(It) { return Qe(It) && It !== k; })) throw new j(v, "Only one doctype is allowed"); var Ae = e($, rt); if (k && $.indexOf(Ae) < $.indexOf(k)) throw new j(v, "Doctype can only be inserted before an element"); } } function bt(_, b, k, $) { He(_, b, k), _.nodeType === ee.DOCUMENT_NODE && ($ || Gi)(_, b, k); var ne = b.parentNode; if (ne && ne.removeChild(b), b.nodeType === O) { var de = b.firstChild; if (de == null) return b; var Ae = b.lastChild; } else de = Ae = b; var et = k ? k.previousSibling : _.lastChild; de.previousSibling = et, Ae.nextSibling = k, et ? et.nextSibling = de : _.firstChild = de, k == null ? _.lastChild = Ae : k.previousSibling = Ae; do de.parentNode = _; while (de !== Ae && (de = de.nextSibling)); return Je(_.ownerDocument || _, _), b.nodeType == O && (b.firstChild = b.lastChild = null), b; } function Te(_, b) { return b.parentNode && b.parentNode.removeChild(b), b.parentNode = _, b.previousSibling = _.lastChild, b.nextSibling = null, b.previousSibling ? b.previousSibling.nextSibling = b : _.firstChild = b, _.lastChild = b, Je(_.ownerDocument, _, b), b; } _e.prototype = { //implementation : null, nodeName: "#document", nodeType: L, /** * The DocumentType node of the document. * * @readonly * @type DocumentType */ doctype: null, documentElement: null, _inc: 1, insertBefore: function(_, b) { if (_.nodeType == O) { for (var k = _.firstChild; k; ) { var $ = k.nextSibling; this.insertBefore(k, b), k = $; } return _; } return bt(this, _, b), _.ownerDocument = this, this.documentElement === null && _.nodeType === y && (this.documentElement = _), _; }, removeChild: function(_) { return this.documentElement == _ && (this.documentElement = null), $e(this, _); }, replaceChild: function(_, b) { bt(this, _, b, pt), _.ownerDocument = this, b && this.removeChild(b), rt(_) && (this.documentElement = _); }, // Introduced in DOM Level 2: importNode: function(_, b) { return br(this, _, b); }, // Introduced in DOM Level 2: getElementById: function(_) { var b = null; return me(this.documentElement, function(k) { if (k.nodeType == y && k.getAttribute("id") == _) return b = k, true; }), b; }, /** * The `getElementsByClassName` method of `Document` interface returns an array-like object * of all child elements which have **all** of the given class name(s). * * Returns an empty list if `classeNames` is an empty string or only contains HTML white space characters. * * * Warning: This is a live LiveNodeList. * Changes in the DOM will reflect in the array as the changes occur. * If an element selected by this array no longer qualifies for the selector, * it will automatically be removed. Be aware of this for iteration purposes. * * @param {string} classNames is a string representing the class name(s) to match; multiple class names are separated by (ASCII-)whitespace * * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname */ getElementsByClassName: function(_) { var b = a(_); return new Y(this, function(k) { var $ = []; return b.length > 0 && me(k.documentElement, function(ne) { if (ne !== k && ne.nodeType === y) { var de = ne.getAttribute("class"); if (de) { var Ae = _ === de; if (!Ae) { var et = a(de); Ae = b.every(u(et)); } Ae && $.push(ne); } } }), $; }); }, //document factory method: createElement: function(_) { var b = new ve(); b.ownerDocument = this, b.nodeName = _, b.tagName = _, b.localName = _, b.childNodes = new H(); var k = b.attributes = new re(); return k._ownerElement = b, b; }, createDocumentFragment: function() { var _ = new Di(); return _.ownerDocument = this, _.childNodes = new H(), _; }, createTextNode: function(_) { var b = new Ei(); return b.ownerDocument = this, b.appendData(_), b; }, createComment: function(_) { var b = new Ci(); return b.ownerDocument = this, b.appendData(_), b; }, createCDATASection: function(_) { var b = new Ai(); return b.ownerDocument = this, b.appendData(_), b; }, createProcessingInstruction: function(_, b) { var k = new Se(); return k.ownerDocument = this, k.tagName = k.nodeName = k.target = _, k.nodeValue = k.data = b, k; }, createAttribute: function(_) { var b = new Be(); return b.ownerDocument = this, b.name = _, b.nodeName = _, b.localName = _, b.specified = true, b; }, createEntityReference: function(_) { var b = new Xi(); return b.ownerDocument = this, b.nodeName = _, b; }, // Introduced in DOM Level 2: createElementNS: function(_, b) { var k = new ve(), $ = b.split(":"), ne = k.attributes = new re(); return k.childNodes = new H(), k.ownerDocument = this, k.nodeName = b, k.tagName = b, k.namespaceURI = _, $.length == 2 ? (k.prefix = $[0], k.localName = $[1]) : k.localName = b, ne._ownerElement = k, k; }, // Introduced in DOM Level 2: createAttributeNS: function(_, b) { var k = new Be(), $ = b.split(":"); return k.ownerDocument = this, k.nodeName = b, k.name = b, k.namespaceURI = _, k.specified = true, $.length == 2 ? (k.prefix = $[0], k.localName = $[1]) : k.localName = b, k; } }, f(_e, ee); function ve() { this._nsMap = {}; } ve.prototype = { nodeType: y, hasAttribute: function(_) { return this.getAttributeNode(_) != null; }, getAttribute: function(_) { var b = this.getAttributeNode(_); return b && b.value || ""; }, getAttributeNode: function(_) { return this.attributes.getNamedItem(_); }, setAttribute: function(_, b) { var k = this.ownerDocument.createAttribute(_); k.value = k.nodeValue = "" + b, this.setAttributeNode(k); }, removeAttribute: function(_) { var b = this.getAttributeNode(_); b && this.removeAttributeNode(b); }, //four real opeartion method appendChild: function(_) { return _.nodeType === O ? this.insertBefore(_, null) : Te(this, _); }, setAttributeNode: function(_) { return this.attributes.setNamedItem(_); }, setAttributeNodeNS: function(_) { return this.attributes.setNamedItemNS(_); }, removeAttributeNode: function(_) { return this.attributes.removeNamedItem(_.nodeName); }, //get real attribute name,and remove it by removeAttributeNode removeAttributeNS: function(_, b) { var k = this.getAttributeNodeNS(_, b); k && this.removeAttributeNode(k); }, hasAttributeNS: function(_, b) { return this.getAttributeNodeNS(_, b) != null; }, getAttributeNS: function(_, b) { var k = this.getAttributeNodeNS(_, b); return k && k.value || ""; }, setAttributeNS: function(_, b, k) { var $ = this.ownerDocument.createAttributeNS(_, b); $.value = $.nodeValue = "" + k, this.setAttributeNode($); }, getAttributeNodeNS: function(_, b) { return this.attributes.getNamedItemNS(_, b); }, getElementsByTagName: function(_) { return new Y(this, function(b) { var k = []; return me(b, function($) { $ !== b && $.nodeType == y && (_ === "*" || $.tagName == _) && k.push($); }), k; }); }, getElementsByTagNameNS: function(_, b) { return new Y(this, function(k) { var $ = []; return me(k, function(ne) { ne !== k && ne.nodeType === y && (_ === "*" || ne.namespaceURI === _) && (b === "*" || ne.localName == b) && $.push(ne); }), $; }); } }, _e.prototype.getElementsByTagName = ve.prototype.getElementsByTagName, _e.prototype.getElementsByTagNameNS = ve.prototype.getElementsByTagNameNS, f(ve, ee); function Be() { } Be.prototype.nodeType = I, f(Be, ee); function Zt() { } Zt.prototype = { data: "", substringData: function(_, b) { return this.data.substring(_, _ + b); }, appendData: function(_) { _ = this.data + _, this.nodeValue = this.data = _, this.length = _.length; }, insertData: function(_, b) { this.replaceData(_, 0, b); }, appendChild: function(_) { throw new Error(Q[v]); }, deleteData: function(_, b) { this.replaceData(_, b, ""); }, replaceData: function(_, b, k) { var $ = this.data.substring(0, _), ne = this.data.substring(_ + b); k = $ + k + ne, this.nodeValue = this.data = k, this.length = k.length; } }, f(Zt, ee); function Ei() { } Ei.prototype = { nodeName: "#text", nodeType: C, splitText: function(_) { var b = this.data, k = b.substring(_); b = b.substring(0, _), this.data = this.nodeValue = b, this.length = b.length; var $ = this.ownerDocument.createTextNode(k); return this.parentNode && this.parentNode.insertBefore($, this.nextSibling), $; } }, f(Ei, Zt); function Ci() { } Ci.prototype = { nodeName: "#comment", nodeType: N }, f(Ci, Zt); function Ai() { } Ai.prototype = { nodeName: "#cdata-section", nodeType: R }, f(Ai, Zt); function ei() { } ei.prototype.nodeType = z, f(ei, ee); function Wi() { } Wi.prototype.nodeType = U, f(Wi, ee); function Is() { } Is.prototype.nodeType = P, f(Is, ee); function Xi() { } Xi.prototype.nodeType = T, f(Xi, ee); function Di() { } Di.prototype.nodeName = "#document-fragment", Di.prototype.nodeType = O, f(Di, ee); function Se() { } Se.prototype.nodeType = B, f(Se, ee); function Tr() { } Tr.prototype.serializeToString = function(_, b, k) { return wi.call(_, b, k); }, ee.prototype.toString = wi; function wi(_, b) { var k = [], $ = this.nodeType == 9 && this.documentElement || this, ne = $.prefix, de = $.namespaceURI; if (de && ne == null) { var ne = $.lookupPrefix(de); if (ne == null) var Ae = [ { namespace: de, prefix: null } //{namespace:uri,prefix:''} ]; } return di(this, k, _, b, Ae), k.join(""); } function vr(_, b, k) { var $ = _.prefix || "", ne = _.namespaceURI; if (!ne || $ === "xml" && ne === t.XML || ne === t.XMLNS) return false; for (var de = k.length; de--; ) { var Ae = k[de]; if (Ae.prefix === $) return Ae.namespace !== ne; } return true; } function ks(_, b, k) { _.push(" ", b, '="', k.replace(/[<>&"\t\n\r]/g, fe), '"'); } function di(_, b, k, $, ne) { if (ne || (ne = []), $) if (_ = $(_), _) { if (typeof _ == "string") { b.push(_); return; } } else return; switch (_.nodeType) { case y: var de = _.attributes, Ae = de.length, Fe = _.firstChild, et = _.tagName; k = t.isHTML(_.namespaceURI) || k; var It = et; if (!k && !_.prefix && _.namespaceURI) { for (var Ut, kt = 0; kt < de.length; kt++) if (de.item(kt).name === "xmlns") { Ut = de.item(kt).value; break; } if (!Ut) for (var qt = ne.length - 1; qt >= 0; qt--) { var Pt = ne[qt]; if (Pt.prefix === "" && Pt.namespace === _.namespaceURI) { Ut = Pt.namespace; break; } } if (Ut !== _.namespaceURI) for (var qt = ne.length - 1; qt >= 0; qt--) { var Pt = ne[qt]; if (Pt.namespace === _.namespaceURI) { Pt.prefix && (It = Pt.prefix + ":" + et); break; } } } b.push("<", It); for (var xt = 0; xt < Ae; xt++) { var we = de.item(xt); we.prefix == "xmlns" ? ne.push({ prefix: we.localName, namespace: we.value }) : we.nodeName == "xmlns" && ne.push({ prefix: "", namespace: we.value }); } for (var xt = 0; xt < Ae; xt++) { var we = de.item(xt); if (vr(we, k, ne)) { var ti = we.prefix || "", Ii = we.namespaceURI; ks(b, ti ? "xmlns:" + ti : "xmlns", Ii), ne.push({ prefix: ti, namespace: Ii }); } di(we, b, k, $, ne); } if (et === It && vr(_, k, ne)) { var ti = _.prefix || "", Ii = _.namespaceURI; ks(b, ti ? "xmlns:" + ti : "xmlns", Ii), ne.push({ prefix: ti, namespace: Ii }); } if (Fe || k && !/^(?:meta|link|img|br|hr|input)$/i.test(et)) { if (b.push(">"), k && /^script$/i.test(et)) for (; Fe; ) Fe.data ? b.push(Fe.data) : di(Fe, b, k, $, ne.slice()), Fe = Fe.nextSibling; else for (; Fe; ) di(Fe, b, k, $, ne.slice()), Fe = Fe.nextSibling; b.push(""); } else b.push("/>"); return; case L: case O: for (var Fe = _.firstChild; Fe; ) di(Fe, b, k, $, ne.slice()), Fe = Fe.nextSibling; return; case I: return ks(b, _.name, _.value); case C: return b.push( _.data.replace(/[<&>]/g, fe) ); case R: return b.push(""); case N: return b.push(""); case z: var St = _.publicId, Ot = _.systemId; if (b.push(""); else if (Ot && Ot != ".") b.push(" SYSTEM ", Ot, ">"); else { var be = _.internalSubset; be && b.push(" [", be, "]"), b.push(">"); } return; case B: return b.push(""); case T: return b.push("&", _.nodeName, ";"); //case ENTITY_NODE: //case NOTATION_NODE: default: b.push("??", _.nodeName); } } function br(_, b, k) { var $; switch (b.nodeType) { case y: $ = b.cloneNode(false), $.ownerDocument = _; //var attrs = node2.attributes; //var len = attrs.length; //for(var i=0;i", lt: "<", quot: '"' }), s.HTML_ENTITIES = e({ Aacute: "Á", aacute: "á", Abreve: "Ă", abreve: "ă", ac: "∾", acd: "∿", acE: "∾̳", Acirc: "Â", acirc: "â", acute: "´", Acy: "А", acy: "а", AElig: "Æ", aelig: "æ", af: "⁡", Afr: "𝔄", afr: "𝔞", Agrave: "À", agrave: "à", alefsym: "ℵ", aleph: "ℵ", Alpha: "Α", alpha: "α", Amacr: "Ā", amacr: "ā", amalg: "⨿", AMP: "&", amp: "&", And: "⩓", and: "∧", andand: "⩕", andd: "⩜", andslope: "⩘", andv: "⩚", ang: "∠", ange: "⦤", angle: "∠", angmsd: "∡", angmsdaa: "⦨", angmsdab: "⦩", angmsdac: "⦪", angmsdad: "⦫", angmsdae: "⦬", angmsdaf: "⦭", angmsdag: "⦮", angmsdah: "⦯", angrt: "∟", angrtvb: "⊾", angrtvbd: "⦝", angsph: "∢", angst: "Å", angzarr: "⍼", Aogon: "Ą", aogon: "ą", Aopf: "𝔸", aopf: "𝕒", ap: "≈", apacir: "⩯", apE: "⩰", ape: "≊", apid: "≋", apos: "'", ApplyFunction: "⁡", approx: "≈", approxeq: "≊", Aring: "Å", aring: "å", Ascr: "𝒜", ascr: "𝒶", Assign: "≔", ast: "*", asymp: "≈", asympeq: "≍", Atilde: "Ã", atilde: "ã", Auml: "Ä", auml: "ä", awconint: "∳", awint: "⨑", backcong: "≌", backepsilon: "϶", backprime: "‵", backsim: "∽", backsimeq: "⋍", Backslash: "∖", Barv: "⫧", barvee: "⊽", Barwed: "⌆", barwed: "⌅", barwedge: "⌅", bbrk: "⎵", bbrktbrk: "⎶", bcong: "≌", Bcy: "Б", bcy: "б", bdquo: "„", becaus: "∵", Because: "∵", because: "∵", bemptyv: "⦰", bepsi: "϶", bernou: "ℬ", Bernoullis: "ℬ", Beta: "Β", beta: "β", beth: "ℶ", between: "≬", Bfr: "𝔅", bfr: "𝔟", bigcap: "⋂", bigcirc: "◯", bigcup: "⋃", bigodot: "⨀", bigoplus: "⨁", bigotimes: "⨂", bigsqcup: "⨆", bigstar: "★", bigtriangledown: "▽", bigtriangleup: "△", biguplus: "⨄", bigvee: "⋁", bigwedge: "⋀", bkarow: "⤍", blacklozenge: "⧫", blacksquare: "▪", blacktriangle: "▴", blacktriangledown: "▾", blacktriangleleft: "◂", blacktriangleright: "▸", blank: "␣", blk12: "▒", blk14: "░", blk34: "▓", block: "█", bne: "=⃥", bnequiv: "≡⃥", bNot: "⫭", bnot: "⌐", Bopf: "𝔹", bopf: "𝕓", bot: "⊥", bottom: "⊥", bowtie: "⋈", boxbox: "⧉", boxDL: "╗", boxDl: "╖", boxdL: "╕", boxdl: "┐", boxDR: "╔", boxDr: "╓", boxdR: "╒", boxdr: "┌", boxH: "═", boxh: "─", boxHD: "╦", boxHd: "╤", boxhD: "╥", boxhd: "┬", boxHU: "╩", boxHu: "╧", boxhU: "╨", boxhu: "┴", boxminus: "⊟", boxplus: "⊞", boxtimes: "⊠", boxUL: "╝", boxUl: "╜", boxuL: "╛", boxul: "┘", boxUR: "╚", boxUr: "╙", boxuR: "╘", boxur: "└", boxV: "║", boxv: "│", boxVH: "╬", boxVh: "╫", boxvH: "╪", boxvh: "┼", boxVL: "╣", boxVl: "╢", boxvL: "╡", boxvl: "┤", boxVR: "╠", boxVr: "╟", boxvR: "╞", boxvr: "├", bprime: "‵", Breve: "˘", breve: "˘", brvbar: "¦", Bscr: "ℬ", bscr: "𝒷", bsemi: "⁏", bsim: "∽", bsime: "⋍", bsol: "\\", bsolb: "⧅", bsolhsub: "⟈", bull: "•", bullet: "•", bump: "≎", bumpE: "⪮", bumpe: "≏", Bumpeq: "≎", bumpeq: "≏", Cacute: "Ć", cacute: "ć", Cap: "⋒", cap: "∩", capand: "⩄", capbrcup: "⩉", capcap: "⩋", capcup: "⩇", capdot: "⩀", CapitalDifferentialD: "ⅅ", caps: "∩︀", caret: "⁁", caron: "ˇ", Cayleys: "ℭ", ccaps: "⩍", Ccaron: "Č", ccaron: "č", Ccedil: "Ç", ccedil: "ç", Ccirc: "Ĉ", ccirc: "ĉ", Cconint: "∰", ccups: "⩌", ccupssm: "⩐", Cdot: "Ċ", cdot: "ċ", cedil: "¸", Cedilla: "¸", cemptyv: "⦲", cent: "¢", CenterDot: "·", centerdot: "·", Cfr: "ℭ", cfr: "𝔠", CHcy: "Ч", chcy: "ч", check: "✓", checkmark: "✓", Chi: "Χ", chi: "χ", cir: "○", circ: "ˆ", circeq: "≗", circlearrowleft: "↺", circlearrowright: "↻", circledast: "⊛", circledcirc: "⊚", circleddash: "⊝", CircleDot: "⊙", circledR: "®", circledS: "Ⓢ", CircleMinus: "⊖", CirclePlus: "⊕", CircleTimes: "⊗", cirE: "⧃", cire: "≗", cirfnint: "⨐", cirmid: "⫯", cirscir: "⧂", ClockwiseContourIntegral: "∲", CloseCurlyDoubleQuote: "”", CloseCurlyQuote: "’", clubs: "♣", clubsuit: "♣", Colon: "∷", colon: ":", Colone: "⩴", colone: "≔", coloneq: "≔", comma: ",", commat: "@", comp: "∁", compfn: "∘", complement: "∁", complexes: "ℂ", cong: "≅", congdot: "⩭", Congruent: "≡", Conint: "∯", conint: "∮", ContourIntegral: "∮", Copf: "ℂ", copf: "𝕔", coprod: "∐", Coproduct: "∐", COPY: "©", copy: "©", copysr: "℗", CounterClockwiseContourIntegral: "∳", crarr: "↵", Cross: "⨯", cross: "✗", Cscr: "𝒞", cscr: "𝒸", csub: "⫏", csube: "⫑", csup: "⫐", csupe: "⫒", ctdot: "⋯", cudarrl: "⤸", cudarrr: "⤵", cuepr: "⋞", cuesc: "⋟", cularr: "↶", cularrp: "⤽", Cup: "⋓", cup: "∪", cupbrcap: "⩈", CupCap: "≍", cupcap: "⩆", cupcup: "⩊", cupdot: "⊍", cupor: "⩅", cups: "∪︀", curarr: "↷", curarrm: "⤼", curlyeqprec: "⋞", curlyeqsucc: "⋟", curlyvee: "⋎", curlywedge: "⋏", curren: "¤", curvearrowleft: "↶", curvearrowright: "↷", cuvee: "⋎", cuwed: "⋏", cwconint: "∲", cwint: "∱", cylcty: "⌭", Dagger: "‡", dagger: "†", daleth: "ℸ", Darr: "↡", dArr: "⇓", darr: "↓", dash: "‐", Dashv: "⫤", dashv: "⊣", dbkarow: "⤏", dblac: "˝", Dcaron: "Ď", dcaron: "ď", Dcy: "Д", dcy: "д", DD: "ⅅ", dd: "ⅆ", ddagger: "‡", ddarr: "⇊", DDotrahd: "⤑", ddotseq: "⩷", deg: "°", Del: "∇", Delta: "Δ", delta: "δ", demptyv: "⦱", dfisht: "⥿", Dfr: "𝔇", dfr: "𝔡", dHar: "⥥", dharl: "⇃", dharr: "⇂", DiacriticalAcute: "´", DiacriticalDot: "˙", DiacriticalDoubleAcute: "˝", DiacriticalGrave: "`", DiacriticalTilde: "˜", diam: "⋄", Diamond: "⋄", diamond: "⋄", diamondsuit: "♦", diams: "♦", die: "¨", DifferentialD: "ⅆ", digamma: "ϝ", disin: "⋲", div: "÷", divide: "÷", divideontimes: "⋇", divonx: "⋇", DJcy: "Ђ", djcy: "ђ", dlcorn: "⌞", dlcrop: "⌍", dollar: "$", Dopf: "𝔻", dopf: "𝕕", Dot: "¨", dot: "˙", DotDot: "⃜", doteq: "≐", doteqdot: "≑", DotEqual: "≐", dotminus: "∸", dotplus: "∔", dotsquare: "⊡", doublebarwedge: "⌆", DoubleContourIntegral: "∯", DoubleDot: "¨", DoubleDownArrow: "⇓", DoubleLeftArrow: "⇐", DoubleLeftRightArrow: "⇔", DoubleLeftTee: "⫤", DoubleLongLeftArrow: "⟸", DoubleLongLeftRightArrow: "⟺", DoubleLongRightArrow: "⟹", DoubleRightArrow: "⇒", DoubleRightTee: "⊨", DoubleUpArrow: "⇑", DoubleUpDownArrow: "⇕", DoubleVerticalBar: "∥", DownArrow: "↓", Downarrow: "⇓", downarrow: "↓", DownArrowBar: "⤓", DownArrowUpArrow: "⇵", DownBreve: "̑", downdownarrows: "⇊", downharpoonleft: "⇃", downharpoonright: "⇂", DownLeftRightVector: "⥐", DownLeftTeeVector: "⥞", DownLeftVector: "↽", DownLeftVectorBar: "⥖", DownRightTeeVector: "⥟", DownRightVector: "⇁", DownRightVectorBar: "⥗", DownTee: "⊤", DownTeeArrow: "↧", drbkarow: "⤐", drcorn: "⌟", drcrop: "⌌", Dscr: "𝒟", dscr: "𝒹", DScy: "Ѕ", dscy: "ѕ", dsol: "⧶", Dstrok: "Đ", dstrok: "đ", dtdot: "⋱", dtri: "▿", dtrif: "▾", duarr: "⇵", duhar: "⥯", dwangle: "⦦", DZcy: "Џ", dzcy: "џ", dzigrarr: "⟿", Eacute: "É", eacute: "é", easter: "⩮", Ecaron: "Ě", ecaron: "ě", ecir: "≖", Ecirc: "Ê", ecirc: "ê", ecolon: "≕", Ecy: "Э", ecy: "э", eDDot: "⩷", Edot: "Ė", eDot: "≑", edot: "ė", ee: "ⅇ", efDot: "≒", Efr: "𝔈", efr: "𝔢", eg: "⪚", Egrave: "È", egrave: "è", egs: "⪖", egsdot: "⪘", el: "⪙", Element: "∈", elinters: "⏧", ell: "ℓ", els: "⪕", elsdot: "⪗", Emacr: "Ē", emacr: "ē", empty: "∅", emptyset: "∅", EmptySmallSquare: "◻", emptyv: "∅", EmptyVerySmallSquare: "▫", emsp: " ", emsp13: " ", emsp14: " ", ENG: "Ŋ", eng: "ŋ", ensp: " ", Eogon: "Ę", eogon: "ę", Eopf: "𝔼", eopf: "𝕖", epar: "⋕", eparsl: "⧣", eplus: "⩱", epsi: "ε", Epsilon: "Ε", epsilon: "ε", epsiv: "ϵ", eqcirc: "≖", eqcolon: "≕", eqsim: "≂", eqslantgtr: "⪖", eqslantless: "⪕", Equal: "⩵", equals: "=", EqualTilde: "≂", equest: "≟", Equilibrium: "⇌", equiv: "≡", equivDD: "⩸", eqvparsl: "⧥", erarr: "⥱", erDot: "≓", Escr: "ℰ", escr: "ℯ", esdot: "≐", Esim: "⩳", esim: "≂", Eta: "Η", eta: "η", ETH: "Ð", eth: "ð", Euml: "Ë", euml: "ë", euro: "€", excl: "!", exist: "∃", Exists: "∃", expectation: "ℰ", ExponentialE: "ⅇ", exponentiale: "ⅇ", fallingdotseq: "≒", Fcy: "Ф", fcy: "ф", female: "♀", ffilig: "ffi", fflig: "ff", ffllig: "ffl", Ffr: "𝔉", ffr: "𝔣", filig: "fi", FilledSmallSquare: "◼", FilledVerySmallSquare: "▪", fjlig: "fj", flat: "♭", fllig: "fl", fltns: "▱", fnof: "ƒ", Fopf: "𝔽", fopf: "𝕗", ForAll: "∀", forall: "∀", fork: "⋔", forkv: "⫙", Fouriertrf: "ℱ", fpartint: "⨍", frac12: "½", frac13: "⅓", frac14: "¼", frac15: "⅕", frac16: "⅙", frac18: "⅛", frac23: "⅔", frac25: "⅖", frac34: "¾", frac35: "⅗", frac38: "⅜", frac45: "⅘", frac56: "⅚", frac58: "⅝", frac78: "⅞", frasl: "⁄", frown: "⌢", Fscr: "ℱ", fscr: "𝒻", gacute: "ǵ", Gamma: "Γ", gamma: "γ", Gammad: "Ϝ", gammad: "ϝ", gap: "⪆", Gbreve: "Ğ", gbreve: "ğ", Gcedil: "Ģ", Gcirc: "Ĝ", gcirc: "ĝ", Gcy: "Г", gcy: "г", Gdot: "Ġ", gdot: "ġ", gE: "≧", ge: "≥", gEl: "⪌", gel: "⋛", geq: "≥", geqq: "≧", geqslant: "⩾", ges: "⩾", gescc: "⪩", gesdot: "⪀", gesdoto: "⪂", gesdotol: "⪄", gesl: "⋛︀", gesles: "⪔", Gfr: "𝔊", gfr: "𝔤", Gg: "⋙", gg: "≫", ggg: "⋙", gimel: "ℷ", GJcy: "Ѓ", gjcy: "ѓ", gl: "≷", gla: "⪥", glE: "⪒", glj: "⪤", gnap: "⪊", gnapprox: "⪊", gnE: "≩", gne: "⪈", gneq: "⪈", gneqq: "≩", gnsim: "⋧", Gopf: "𝔾", gopf: "𝕘", grave: "`", GreaterEqual: "≥", GreaterEqualLess: "⋛", GreaterFullEqual: "≧", GreaterGreater: "⪢", GreaterLess: "≷", GreaterSlantEqual: "⩾", GreaterTilde: "≳", Gscr: "𝒢", gscr: "ℊ", gsim: "≳", gsime: "⪎", gsiml: "⪐", Gt: "≫", GT: ">", gt: ">", gtcc: "⪧", gtcir: "⩺", gtdot: "⋗", gtlPar: "⦕", gtquest: "⩼", gtrapprox: "⪆", gtrarr: "⥸", gtrdot: "⋗", gtreqless: "⋛", gtreqqless: "⪌", gtrless: "≷", gtrsim: "≳", gvertneqq: "≩︀", gvnE: "≩︀", Hacek: "ˇ", hairsp: " ", half: "½", hamilt: "ℋ", HARDcy: "Ъ", hardcy: "ъ", hArr: "⇔", harr: "↔", harrcir: "⥈", harrw: "↭", Hat: "^", hbar: "ℏ", Hcirc: "Ĥ", hcirc: "ĥ", hearts: "♥", heartsuit: "♥", hellip: "…", hercon: "⊹", Hfr: "ℌ", hfr: "𝔥", HilbertSpace: "ℋ", hksearow: "⤥", hkswarow: "⤦", hoarr: "⇿", homtht: "∻", hookleftarrow: "↩", hookrightarrow: "↪", Hopf: "ℍ", hopf: "𝕙", horbar: "―", HorizontalLine: "─", Hscr: "ℋ", hscr: "𝒽", hslash: "ℏ", Hstrok: "Ħ", hstrok: "ħ", HumpDownHump: "≎", HumpEqual: "≏", hybull: "⁃", hyphen: "‐", Iacute: "Í", iacute: "í", ic: "⁣", Icirc: "Î", icirc: "î", Icy: "И", icy: "и", Idot: "İ", IEcy: "Е", iecy: "е", iexcl: "¡", iff: "⇔", Ifr: "ℑ", ifr: "𝔦", Igrave: "Ì", igrave: "ì", ii: "ⅈ", iiiint: "⨌", iiint: "∭", iinfin: "⧜", iiota: "℩", IJlig: "IJ", ijlig: "ij", Im: "ℑ", Imacr: "Ī", imacr: "ī", image: "ℑ", ImaginaryI: "ⅈ", imagline: "ℐ", imagpart: "ℑ", imath: "ı", imof: "⊷", imped: "Ƶ", Implies: "⇒", in: "∈", incare: "℅", infin: "∞", infintie: "⧝", inodot: "ı", Int: "∬", int: "∫", intcal: "⊺", integers: "ℤ", Integral: "∫", intercal: "⊺", Intersection: "⋂", intlarhk: "⨗", intprod: "⨼", InvisibleComma: "⁣", InvisibleTimes: "⁢", IOcy: "Ё", iocy: "ё", Iogon: "Į", iogon: "į", Iopf: "𝕀", iopf: "𝕚", Iota: "Ι", iota: "ι", iprod: "⨼", iquest: "¿", Iscr: "ℐ", iscr: "𝒾", isin: "∈", isindot: "⋵", isinE: "⋹", isins: "⋴", isinsv: "⋳", isinv: "∈", it: "⁢", Itilde: "Ĩ", itilde: "ĩ", Iukcy: "І", iukcy: "і", Iuml: "Ï", iuml: "ï", Jcirc: "Ĵ", jcirc: "ĵ", Jcy: "Й", jcy: "й", Jfr: "𝔍", jfr: "𝔧", jmath: "ȷ", Jopf: "𝕁", jopf: "𝕛", Jscr: "𝒥", jscr: "𝒿", Jsercy: "Ј", jsercy: "ј", Jukcy: "Є", jukcy: "є", Kappa: "Κ", kappa: "κ", kappav: "ϰ", Kcedil: "Ķ", kcedil: "ķ", Kcy: "К", kcy: "к", Kfr: "𝔎", kfr: "𝔨", kgreen: "ĸ", KHcy: "Х", khcy: "х", KJcy: "Ќ", kjcy: "ќ", Kopf: "𝕂", kopf: "𝕜", Kscr: "𝒦", kscr: "𝓀", lAarr: "⇚", Lacute: "Ĺ", lacute: "ĺ", laemptyv: "⦴", lagran: "ℒ", Lambda: "Λ", lambda: "λ", Lang: "⟪", lang: "⟨", langd: "⦑", langle: "⟨", lap: "⪅", Laplacetrf: "ℒ", laquo: "«", Larr: "↞", lArr: "⇐", larr: "←", larrb: "⇤", larrbfs: "⤟", larrfs: "⤝", larrhk: "↩", larrlp: "↫", larrpl: "⤹", larrsim: "⥳", larrtl: "↢", lat: "⪫", lAtail: "⤛", latail: "⤙", late: "⪭", lates: "⪭︀", lBarr: "⤎", lbarr: "⤌", lbbrk: "❲", lbrace: "{", lbrack: "[", lbrke: "⦋", lbrksld: "⦏", lbrkslu: "⦍", Lcaron: "Ľ", lcaron: "ľ", Lcedil: "Ļ", lcedil: "ļ", lceil: "⌈", lcub: "{", Lcy: "Л", lcy: "л", ldca: "⤶", ldquo: "“", ldquor: "„", ldrdhar: "⥧", ldrushar: "⥋", ldsh: "↲", lE: "≦", le: "≤", LeftAngleBracket: "⟨", LeftArrow: "←", Leftarrow: "⇐", leftarrow: "←", LeftArrowBar: "⇤", LeftArrowRightArrow: "⇆", leftarrowtail: "↢", LeftCeiling: "⌈", LeftDoubleBracket: "⟦", LeftDownTeeVector: "⥡", LeftDownVector: "⇃", LeftDownVectorBar: "⥙", LeftFloor: "⌊", leftharpoondown: "↽", leftharpoonup: "↼", leftleftarrows: "⇇", LeftRightArrow: "↔", Leftrightarrow: "⇔", leftrightarrow: "↔", leftrightarrows: "⇆", leftrightharpoons: "⇋", leftrightsquigarrow: "↭", LeftRightVector: "⥎", LeftTee: "⊣", LeftTeeArrow: "↤", LeftTeeVector: "⥚", leftthreetimes: "⋋", LeftTriangle: "⊲", LeftTriangleBar: "⧏", LeftTriangleEqual: "⊴", LeftUpDownVector: "⥑", LeftUpTeeVector: "⥠", LeftUpVector: "↿", LeftUpVectorBar: "⥘", LeftVector: "↼", LeftVectorBar: "⥒", lEg: "⪋", leg: "⋚", leq: "≤", leqq: "≦", leqslant: "⩽", les: "⩽", lescc: "⪨", lesdot: "⩿", lesdoto: "⪁", lesdotor: "⪃", lesg: "⋚︀", lesges: "⪓", lessapprox: "⪅", lessdot: "⋖", lesseqgtr: "⋚", lesseqqgtr: "⪋", LessEqualGreater: "⋚", LessFullEqual: "≦", LessGreater: "≶", lessgtr: "≶", LessLess: "⪡", lesssim: "≲", LessSlantEqual: "⩽", LessTilde: "≲", lfisht: "⥼", lfloor: "⌊", Lfr: "𝔏", lfr: "𝔩", lg: "≶", lgE: "⪑", lHar: "⥢", lhard: "↽", lharu: "↼", lharul: "⥪", lhblk: "▄", LJcy: "Љ", ljcy: "љ", Ll: "⋘", ll: "≪", llarr: "⇇", llcorner: "⌞", Lleftarrow: "⇚", llhard: "⥫", lltri: "◺", Lmidot: "Ŀ", lmidot: "ŀ", lmoust: "⎰", lmoustache: "⎰", lnap: "⪉", lnapprox: "⪉", lnE: "≨", lne: "⪇", lneq: "⪇", lneqq: "≨", lnsim: "⋦", loang: "⟬", loarr: "⇽", lobrk: "⟦", LongLeftArrow: "⟵", Longleftarrow: "⟸", longleftarrow: "⟵", LongLeftRightArrow: "⟷", Longleftrightarrow: "⟺", longleftrightarrow: "⟷", longmapsto: "⟼", LongRightArrow: "⟶", Longrightarrow: "⟹", longrightarrow: "⟶", looparrowleft: "↫", looparrowright: "↬", lopar: "⦅", Lopf: "𝕃", lopf: "𝕝", loplus: "⨭", lotimes: "⨴", lowast: "∗", lowbar: "_", LowerLeftArrow: "↙", LowerRightArrow: "↘", loz: "◊", lozenge: "◊", lozf: "⧫", lpar: "(", lparlt: "⦓", lrarr: "⇆", lrcorner: "⌟", lrhar: "⇋", lrhard: "⥭", lrm: "‎", lrtri: "⊿", lsaquo: "‹", Lscr: "ℒ", lscr: "𝓁", Lsh: "↰", lsh: "↰", lsim: "≲", lsime: "⪍", lsimg: "⪏", lsqb: "[", lsquo: "‘", lsquor: "‚", Lstrok: "Ł", lstrok: "ł", Lt: "≪", LT: "<", lt: "<", ltcc: "⪦", ltcir: "⩹", ltdot: "⋖", lthree: "⋋", ltimes: "⋉", ltlarr: "⥶", ltquest: "⩻", ltri: "◃", ltrie: "⊴", ltrif: "◂", ltrPar: "⦖", lurdshar: "⥊", luruhar: "⥦", lvertneqq: "≨︀", lvnE: "≨︀", macr: "¯", male: "♂", malt: "✠", maltese: "✠", Map: "⤅", map: "↦", mapsto: "↦", mapstodown: "↧", mapstoleft: "↤", mapstoup: "↥", marker: "▮", mcomma: "⨩", Mcy: "М", mcy: "м", mdash: "—", mDDot: "∺", measuredangle: "∡", MediumSpace: " ", Mellintrf: "ℳ", Mfr: "𝔐", mfr: "𝔪", mho: "℧", micro: "µ", mid: "∣", midast: "*", midcir: "⫰", middot: "·", minus: "−", minusb: "⊟", minusd: "∸", minusdu: "⨪", MinusPlus: "∓", mlcp: "⫛", mldr: "…", mnplus: "∓", models: "⊧", Mopf: "𝕄", mopf: "𝕞", mp: "∓", Mscr: "ℳ", mscr: "𝓂", mstpos: "∾", Mu: "Μ", mu: "μ", multimap: "⊸", mumap: "⊸", nabla: "∇", Nacute: "Ń", nacute: "ń", nang: "∠⃒", nap: "≉", napE: "⩰̸", napid: "≋̸", napos: "ʼn", napprox: "≉", natur: "♮", natural: "♮", naturals: "ℕ", nbsp: " ", nbump: "≎̸", nbumpe: "≏̸", ncap: "⩃", Ncaron: "Ň", ncaron: "ň", Ncedil: "Ņ", ncedil: "ņ", ncong: "≇", ncongdot: "⩭̸", ncup: "⩂", Ncy: "Н", ncy: "н", ndash: "–", ne: "≠", nearhk: "⤤", neArr: "⇗", nearr: "↗", nearrow: "↗", nedot: "≐̸", NegativeMediumSpace: "​", NegativeThickSpace: "​", NegativeThinSpace: "​", NegativeVeryThinSpace: "​", nequiv: "≢", nesear: "⤨", nesim: "≂̸", NestedGreaterGreater: "≫", NestedLessLess: "≪", NewLine: ` `, nexist: "∄", nexists: "∄", Nfr: "𝔑", nfr: "𝔫", ngE: "≧̸", nge: "≱", ngeq: "≱", ngeqq: "≧̸", ngeqslant: "⩾̸", nges: "⩾̸", nGg: "⋙̸", ngsim: "≵", nGt: "≫⃒", ngt: "≯", ngtr: "≯", nGtv: "≫̸", nhArr: "⇎", nharr: "↮", nhpar: "⫲", ni: "∋", nis: "⋼", nisd: "⋺", niv: "∋", NJcy: "Њ", njcy: "њ", nlArr: "⇍", nlarr: "↚", nldr: "‥", nlE: "≦̸", nle: "≰", nLeftarrow: "⇍", nleftarrow: "↚", nLeftrightarrow: "⇎", nleftrightarrow: "↮", nleq: "≰", nleqq: "≦̸", nleqslant: "⩽̸", nles: "⩽̸", nless: "≮", nLl: "⋘̸", nlsim: "≴", nLt: "≪⃒", nlt: "≮", nltri: "⋪", nltrie: "⋬", nLtv: "≪̸", nmid: "∤", NoBreak: "⁠", NonBreakingSpace: " ", Nopf: "ℕ", nopf: "𝕟", Not: "⫬", not: "¬", NotCongruent: "≢", NotCupCap: "≭", NotDoubleVerticalBar: "∦", NotElement: "∉", NotEqual: "≠", NotEqualTilde: "≂̸", NotExists: "∄", NotGreater: "≯", NotGreaterEqual: "≱", NotGreaterFullEqual: "≧̸", NotGreaterGreater: "≫̸", NotGreaterLess: "≹", NotGreaterSlantEqual: "⩾̸", NotGreaterTilde: "≵", NotHumpDownHump: "≎̸", NotHumpEqual: "≏̸", notin: "∉", notindot: "⋵̸", notinE: "⋹̸", notinva: "∉", notinvb: "⋷", notinvc: "⋶", NotLeftTriangle: "⋪", NotLeftTriangleBar: "⧏̸", NotLeftTriangleEqual: "⋬", NotLess: "≮", NotLessEqual: "≰", NotLessGreater: "≸", NotLessLess: "≪̸", NotLessSlantEqual: "⩽̸", NotLessTilde: "≴", NotNestedGreaterGreater: "⪢̸", NotNestedLessLess: "⪡̸", notni: "∌", notniva: "∌", notnivb: "⋾", notnivc: "⋽", NotPrecedes: "⊀", NotPrecedesEqual: "⪯̸", NotPrecedesSlantEqual: "⋠", NotReverseElement: "∌", NotRightTriangle: "⋫", NotRightTriangleBar: "⧐̸", NotRightTriangleEqual: "⋭", NotSquareSubset: "⊏̸", NotSquareSubsetEqual: "⋢", NotSquareSuperset: "⊐̸", NotSquareSupersetEqual: "⋣", NotSubset: "⊂⃒", NotSubsetEqual: "⊈", NotSucceeds: "⊁", NotSucceedsEqual: "⪰̸", NotSucceedsSlantEqual: "⋡", NotSucceedsTilde: "≿̸", NotSuperset: "⊃⃒", NotSupersetEqual: "⊉", NotTilde: "≁", NotTildeEqual: "≄", NotTildeFullEqual: "≇", NotTildeTilde: "≉", NotVerticalBar: "∤", npar: "∦", nparallel: "∦", nparsl: "⫽⃥", npart: "∂̸", npolint: "⨔", npr: "⊀", nprcue: "⋠", npre: "⪯̸", nprec: "⊀", npreceq: "⪯̸", nrArr: "⇏", nrarr: "↛", nrarrc: "⤳̸", nrarrw: "↝̸", nRightarrow: "⇏", nrightarrow: "↛", nrtri: "⋫", nrtrie: "⋭", nsc: "⊁", nsccue: "⋡", nsce: "⪰̸", Nscr: "𝒩", nscr: "𝓃", nshortmid: "∤", nshortparallel: "∦", nsim: "≁", nsime: "≄", nsimeq: "≄", nsmid: "∤", nspar: "∦", nsqsube: "⋢", nsqsupe: "⋣", nsub: "⊄", nsubE: "⫅̸", nsube: "⊈", nsubset: "⊂⃒", nsubseteq: "⊈", nsubseteqq: "⫅̸", nsucc: "⊁", nsucceq: "⪰̸", nsup: "⊅", nsupE: "⫆̸", nsupe: "⊉", nsupset: "⊃⃒", nsupseteq: "⊉", nsupseteqq: "⫆̸", ntgl: "≹", Ntilde: "Ñ", ntilde: "ñ", ntlg: "≸", ntriangleleft: "⋪", ntrianglelefteq: "⋬", ntriangleright: "⋫", ntrianglerighteq: "⋭", Nu: "Ν", nu: "ν", num: "#", numero: "№", numsp: " ", nvap: "≍⃒", nVDash: "⊯", nVdash: "⊮", nvDash: "⊭", nvdash: "⊬", nvge: "≥⃒", nvgt: ">⃒", nvHarr: "⤄", nvinfin: "⧞", nvlArr: "⤂", nvle: "≤⃒", nvlt: "<⃒", nvltrie: "⊴⃒", nvrArr: "⤃", nvrtrie: "⊵⃒", nvsim: "∼⃒", nwarhk: "⤣", nwArr: "⇖", nwarr: "↖", nwarrow: "↖", nwnear: "⤧", Oacute: "Ó", oacute: "ó", oast: "⊛", ocir: "⊚", Ocirc: "Ô", ocirc: "ô", Ocy: "О", ocy: "о", odash: "⊝", Odblac: "Ő", odblac: "ő", odiv: "⨸", odot: "⊙", odsold: "⦼", OElig: "Œ", oelig: "œ", ofcir: "⦿", Ofr: "𝔒", ofr: "𝔬", ogon: "˛", Ograve: "Ò", ograve: "ò", ogt: "⧁", ohbar: "⦵", ohm: "Ω", oint: "∮", olarr: "↺", olcir: "⦾", olcross: "⦻", oline: "‾", olt: "⧀", Omacr: "Ō", omacr: "ō", Omega: "Ω", omega: "ω", Omicron: "Ο", omicron: "ο", omid: "⦶", ominus: "⊖", Oopf: "𝕆", oopf: "𝕠", opar: "⦷", OpenCurlyDoubleQuote: "“", OpenCurlyQuote: "‘", operp: "⦹", oplus: "⊕", Or: "⩔", or: "∨", orarr: "↻", ord: "⩝", order: "ℴ", orderof: "ℴ", ordf: "ª", ordm: "º", origof: "⊶", oror: "⩖", orslope: "⩗", orv: "⩛", oS: "Ⓢ", Oscr: "𝒪", oscr: "ℴ", Oslash: "Ø", oslash: "ø", osol: "⊘", Otilde: "Õ", otilde: "õ", Otimes: "⨷", otimes: "⊗", otimesas: "⨶", Ouml: "Ö", ouml: "ö", ovbar: "⌽", OverBar: "‾", OverBrace: "⏞", OverBracket: "⎴", OverParenthesis: "⏜", par: "∥", para: "¶", parallel: "∥", parsim: "⫳", parsl: "⫽", part: "∂", PartialD: "∂", Pcy: "П", pcy: "п", percnt: "%", period: ".", permil: "‰", perp: "⊥", pertenk: "‱", Pfr: "𝔓", pfr: "𝔭", Phi: "Φ", phi: "φ", phiv: "ϕ", phmmat: "ℳ", phone: "☎", Pi: "Π", pi: "π", pitchfork: "⋔", piv: "ϖ", planck: "ℏ", planckh: "ℎ", plankv: "ℏ", plus: "+", plusacir: "⨣", plusb: "⊞", pluscir: "⨢", plusdo: "∔", plusdu: "⨥", pluse: "⩲", PlusMinus: "±", plusmn: "±", plussim: "⨦", plustwo: "⨧", pm: "±", Poincareplane: "ℌ", pointint: "⨕", Popf: "ℙ", popf: "𝕡", pound: "£", Pr: "⪻", pr: "≺", prap: "⪷", prcue: "≼", prE: "⪳", pre: "⪯", prec: "≺", precapprox: "⪷", preccurlyeq: "≼", Precedes: "≺", PrecedesEqual: "⪯", PrecedesSlantEqual: "≼", PrecedesTilde: "≾", preceq: "⪯", precnapprox: "⪹", precneqq: "⪵", precnsim: "⋨", precsim: "≾", Prime: "″", prime: "′", primes: "ℙ", prnap: "⪹", prnE: "⪵", prnsim: "⋨", prod: "∏", Product: "∏", profalar: "⌮", profline: "⌒", profsurf: "⌓", prop: "∝", Proportion: "∷", Proportional: "∝", propto: "∝", prsim: "≾", prurel: "⊰", Pscr: "𝒫", pscr: "𝓅", Psi: "Ψ", psi: "ψ", puncsp: " ", Qfr: "𝔔", qfr: "𝔮", qint: "⨌", Qopf: "ℚ", qopf: "𝕢", qprime: "⁗", Qscr: "𝒬", qscr: "𝓆", quaternions: "ℍ", quatint: "⨖", quest: "?", questeq: "≟", QUOT: '"', quot: '"', rAarr: "⇛", race: "∽̱", Racute: "Ŕ", racute: "ŕ", radic: "√", raemptyv: "⦳", Rang: "⟫", rang: "⟩", rangd: "⦒", range: "⦥", rangle: "⟩", raquo: "»", Rarr: "↠", rArr: "⇒", rarr: "→", rarrap: "⥵", rarrb: "⇥", rarrbfs: "⤠", rarrc: "⤳", rarrfs: "⤞", rarrhk: "↪", rarrlp: "↬", rarrpl: "⥅", rarrsim: "⥴", Rarrtl: "⤖", rarrtl: "↣", rarrw: "↝", rAtail: "⤜", ratail: "⤚", ratio: "∶", rationals: "ℚ", RBarr: "⤐", rBarr: "⤏", rbarr: "⤍", rbbrk: "❳", rbrace: "}", rbrack: "]", rbrke: "⦌", rbrksld: "⦎", rbrkslu: "⦐", Rcaron: "Ř", rcaron: "ř", Rcedil: "Ŗ", rcedil: "ŗ", rceil: "⌉", rcub: "}", Rcy: "Р", rcy: "р", rdca: "⤷", rdldhar: "⥩", rdquo: "”", rdquor: "”", rdsh: "↳", Re: "ℜ", real: "ℜ", realine: "ℛ", realpart: "ℜ", reals: "ℝ", rect: "▭", REG: "®", reg: "®", ReverseElement: "∋", ReverseEquilibrium: "⇋", ReverseUpEquilibrium: "⥯", rfisht: "⥽", rfloor: "⌋", Rfr: "ℜ", rfr: "𝔯", rHar: "⥤", rhard: "⇁", rharu: "⇀", rharul: "⥬", Rho: "Ρ", rho: "ρ", rhov: "ϱ", RightAngleBracket: "⟩", RightArrow: "→", Rightarrow: "⇒", rightarrow: "→", RightArrowBar: "⇥", RightArrowLeftArrow: "⇄", rightarrowtail: "↣", RightCeiling: "⌉", RightDoubleBracket: "⟧", RightDownTeeVector: "⥝", RightDownVector: "⇂", RightDownVectorBar: "⥕", RightFloor: "⌋", rightharpoondown: "⇁", rightharpoonup: "⇀", rightleftarrows: "⇄", rightleftharpoons: "⇌", rightrightarrows: "⇉", rightsquigarrow: "↝", RightTee: "⊢", RightTeeArrow: "↦", RightTeeVector: "⥛", rightthreetimes: "⋌", RightTriangle: "⊳", RightTriangleBar: "⧐", RightTriangleEqual: "⊵", RightUpDownVector: "⥏", RightUpTeeVector: "⥜", RightUpVector: "↾", RightUpVectorBar: "⥔", RightVector: "⇀", RightVectorBar: "⥓", ring: "˚", risingdotseq: "≓", rlarr: "⇄", rlhar: "⇌", rlm: "‏", rmoust: "⎱", rmoustache: "⎱", rnmid: "⫮", roang: "⟭", roarr: "⇾", robrk: "⟧", ropar: "⦆", Ropf: "ℝ", ropf: "𝕣", roplus: "⨮", rotimes: "⨵", RoundImplies: "⥰", rpar: ")", rpargt: "⦔", rppolint: "⨒", rrarr: "⇉", Rrightarrow: "⇛", rsaquo: "›", Rscr: "ℛ", rscr: "𝓇", Rsh: "↱", rsh: "↱", rsqb: "]", rsquo: "’", rsquor: "’", rthree: "⋌", rtimes: "⋊", rtri: "▹", rtrie: "⊵", rtrif: "▸", rtriltri: "⧎", RuleDelayed: "⧴", ruluhar: "⥨", rx: "℞", Sacute: "Ś", sacute: "ś", sbquo: "‚", Sc: "⪼", sc: "≻", scap: "⪸", Scaron: "Š", scaron: "š", sccue: "≽", scE: "⪴", sce: "⪰", Scedil: "Ş", scedil: "ş", Scirc: "Ŝ", scirc: "ŝ", scnap: "⪺", scnE: "⪶", scnsim: "⋩", scpolint: "⨓", scsim: "≿", Scy: "С", scy: "с", sdot: "⋅", sdotb: "⊡", sdote: "⩦", searhk: "⤥", seArr: "⇘", searr: "↘", searrow: "↘", sect: "§", semi: ";", seswar: "⤩", setminus: "∖", setmn: "∖", sext: "✶", Sfr: "𝔖", sfr: "𝔰", sfrown: "⌢", sharp: "♯", SHCHcy: "Щ", shchcy: "щ", SHcy: "Ш", shcy: "ш", ShortDownArrow: "↓", ShortLeftArrow: "←", shortmid: "∣", shortparallel: "∥", ShortRightArrow: "→", ShortUpArrow: "↑", shy: "­", Sigma: "Σ", sigma: "σ", sigmaf: "ς", sigmav: "ς", sim: "∼", simdot: "⩪", sime: "≃", simeq: "≃", simg: "⪞", simgE: "⪠", siml: "⪝", simlE: "⪟", simne: "≆", simplus: "⨤", simrarr: "⥲", slarr: "←", SmallCircle: "∘", smallsetminus: "∖", smashp: "⨳", smeparsl: "⧤", smid: "∣", smile: "⌣", smt: "⪪", smte: "⪬", smtes: "⪬︀", SOFTcy: "Ь", softcy: "ь", sol: "/", solb: "⧄", solbar: "⌿", Sopf: "𝕊", sopf: "𝕤", spades: "♠", spadesuit: "♠", spar: "∥", sqcap: "⊓", sqcaps: "⊓︀", sqcup: "⊔", sqcups: "⊔︀", Sqrt: "√", sqsub: "⊏", sqsube: "⊑", sqsubset: "⊏", sqsubseteq: "⊑", sqsup: "⊐", sqsupe: "⊒", sqsupset: "⊐", sqsupseteq: "⊒", squ: "□", Square: "□", square: "□", SquareIntersection: "⊓", SquareSubset: "⊏", SquareSubsetEqual: "⊑", SquareSuperset: "⊐", SquareSupersetEqual: "⊒", SquareUnion: "⊔", squarf: "▪", squf: "▪", srarr: "→", Sscr: "𝒮", sscr: "𝓈", ssetmn: "∖", ssmile: "⌣", sstarf: "⋆", Star: "⋆", star: "☆", starf: "★", straightepsilon: "ϵ", straightphi: "ϕ", strns: "¯", Sub: "⋐", sub: "⊂", subdot: "⪽", subE: "⫅", sube: "⊆", subedot: "⫃", submult: "⫁", subnE: "⫋", subne: "⊊", subplus: "⪿", subrarr: "⥹", Subset: "⋐", subset: "⊂", subseteq: "⊆", subseteqq: "⫅", SubsetEqual: "⊆", subsetneq: "⊊", subsetneqq: "⫋", subsim: "⫇", subsub: "⫕", subsup: "⫓", succ: "≻", succapprox: "⪸", succcurlyeq: "≽", Succeeds: "≻", SucceedsEqual: "⪰", SucceedsSlantEqual: "≽", SucceedsTilde: "≿", succeq: "⪰", succnapprox: "⪺", succneqq: "⪶", succnsim: "⋩", succsim: "≿", SuchThat: "∋", Sum: "∑", sum: "∑", sung: "♪", Sup: "⋑", sup: "⊃", sup1: "¹", sup2: "²", sup3: "³", supdot: "⪾", supdsub: "⫘", supE: "⫆", supe: "⊇", supedot: "⫄", Superset: "⊃", SupersetEqual: "⊇", suphsol: "⟉", suphsub: "⫗", suplarr: "⥻", supmult: "⫂", supnE: "⫌", supne: "⊋", supplus: "⫀", Supset: "⋑", supset: "⊃", supseteq: "⊇", supseteqq: "⫆", supsetneq: "⊋", supsetneqq: "⫌", supsim: "⫈", supsub: "⫔", supsup: "⫖", swarhk: "⤦", swArr: "⇙", swarr: "↙", swarrow: "↙", swnwar: "⤪", szlig: "ß", Tab: " ", target: "⌖", Tau: "Τ", tau: "τ", tbrk: "⎴", Tcaron: "Ť", tcaron: "ť", Tcedil: "Ţ", tcedil: "ţ", Tcy: "Т", tcy: "т", tdot: "⃛", telrec: "⌕", Tfr: "𝔗", tfr: "𝔱", there4: "∴", Therefore: "∴", therefore: "∴", Theta: "Θ", theta: "θ", thetasym: "ϑ", thetav: "ϑ", thickapprox: "≈", thicksim: "∼", ThickSpace: "  ", thinsp: " ", ThinSpace: " ", thkap: "≈", thksim: "∼", THORN: "Þ", thorn: "þ", Tilde: "∼", tilde: "˜", TildeEqual: "≃", TildeFullEqual: "≅", TildeTilde: "≈", times: "×", timesb: "⊠", timesbar: "⨱", timesd: "⨰", tint: "∭", toea: "⤨", top: "⊤", topbot: "⌶", topcir: "⫱", Topf: "𝕋", topf: "𝕥", topfork: "⫚", tosa: "⤩", tprime: "‴", TRADE: "™", trade: "™", triangle: "▵", triangledown: "▿", triangleleft: "◃", trianglelefteq: "⊴", triangleq: "≜", triangleright: "▹", trianglerighteq: "⊵", tridot: "◬", trie: "≜", triminus: "⨺", TripleDot: "⃛", triplus: "⨹", trisb: "⧍", tritime: "⨻", trpezium: "⏢", Tscr: "𝒯", tscr: "𝓉", TScy: "Ц", tscy: "ц", TSHcy: "Ћ", tshcy: "ћ", Tstrok: "Ŧ", tstrok: "ŧ", twixt: "≬", twoheadleftarrow: "↞", twoheadrightarrow: "↠", Uacute: "Ú", uacute: "ú", Uarr: "↟", uArr: "⇑", uarr: "↑", Uarrocir: "⥉", Ubrcy: "Ў", ubrcy: "ў", Ubreve: "Ŭ", ubreve: "ŭ", Ucirc: "Û", ucirc: "û", Ucy: "У", ucy: "у", udarr: "⇅", Udblac: "Ű", udblac: "ű", udhar: "⥮", ufisht: "⥾", Ufr: "𝔘", ufr: "𝔲", Ugrave: "Ù", ugrave: "ù", uHar: "⥣", uharl: "↿", uharr: "↾", uhblk: "▀", ulcorn: "⌜", ulcorner: "⌜", ulcrop: "⌏", ultri: "◸", Umacr: "Ū", umacr: "ū", uml: "¨", UnderBar: "_", UnderBrace: "⏟", UnderBracket: "⎵", UnderParenthesis: "⏝", Union: "⋃", UnionPlus: "⊎", Uogon: "Ų", uogon: "ų", Uopf: "𝕌", uopf: "𝕦", UpArrow: "↑", Uparrow: "⇑", uparrow: "↑", UpArrowBar: "⤒", UpArrowDownArrow: "⇅", UpDownArrow: "↕", Updownarrow: "⇕", updownarrow: "↕", UpEquilibrium: "⥮", upharpoonleft: "↿", upharpoonright: "↾", uplus: "⊎", UpperLeftArrow: "↖", UpperRightArrow: "↗", Upsi: "ϒ", upsi: "υ", upsih: "ϒ", Upsilon: "Υ", upsilon: "υ", UpTee: "⊥", UpTeeArrow: "↥", upuparrows: "⇈", urcorn: "⌝", urcorner: "⌝", urcrop: "⌎", Uring: "Ů", uring: "ů", urtri: "◹", Uscr: "𝒰", uscr: "𝓊", utdot: "⋰", Utilde: "Ũ", utilde: "ũ", utri: "▵", utrif: "▴", uuarr: "⇈", Uuml: "Ü", uuml: "ü", uwangle: "⦧", vangrt: "⦜", varepsilon: "ϵ", varkappa: "ϰ", varnothing: "∅", varphi: "ϕ", varpi: "ϖ", varpropto: "∝", vArr: "⇕", varr: "↕", varrho: "ϱ", varsigma: "ς", varsubsetneq: "⊊︀", varsubsetneqq: "⫋︀", varsupsetneq: "⊋︀", varsupsetneqq: "⫌︀", vartheta: "ϑ", vartriangleleft: "⊲", vartriangleright: "⊳", Vbar: "⫫", vBar: "⫨", vBarv: "⫩", Vcy: "В", vcy: "в", VDash: "⊫", Vdash: "⊩", vDash: "⊨", vdash: "⊢", Vdashl: "⫦", Vee: "⋁", vee: "∨", veebar: "⊻", veeeq: "≚", vellip: "⋮", Verbar: "‖", verbar: "|", Vert: "‖", vert: "|", VerticalBar: "∣", VerticalLine: "|", VerticalSeparator: "❘", VerticalTilde: "≀", VeryThinSpace: " ", Vfr: "𝔙", vfr: "𝔳", vltri: "⊲", vnsub: "⊂⃒", vnsup: "⊃⃒", Vopf: "𝕍", vopf: "𝕧", vprop: "∝", vrtri: "⊳", Vscr: "𝒱", vscr: "𝓋", vsubnE: "⫋︀", vsubne: "⊊︀", vsupnE: "⫌︀", vsupne: "⊋︀", Vvdash: "⊪", vzigzag: "⦚", Wcirc: "Ŵ", wcirc: "ŵ", wedbar: "⩟", Wedge: "⋀", wedge: "∧", wedgeq: "≙", weierp: "℘", Wfr: "𝔚", wfr: "𝔴", Wopf: "𝕎", wopf: "𝕨", wp: "℘", wr: "≀", wreath: "≀", Wscr: "𝒲", wscr: "𝓌", xcap: "⋂", xcirc: "◯", xcup: "⋃", xdtri: "▽", Xfr: "𝔛", xfr: "𝔵", xhArr: "⟺", xharr: "⟷", Xi: "Ξ", xi: "ξ", xlArr: "⟸", xlarr: "⟵", xmap: "⟼", xnis: "⋻", xodot: "⨀", Xopf: "𝕏", xopf: "𝕩", xoplus: "⨁", xotime: "⨂", xrArr: "⟹", xrarr: "⟶", Xscr: "𝒳", xscr: "𝓍", xsqcup: "⨆", xuplus: "⨄", xutri: "△", xvee: "⋁", xwedge: "⋀", Yacute: "Ý", yacute: "ý", YAcy: "Я", yacy: "я", Ycirc: "Ŷ", ycirc: "ŷ", Ycy: "Ы", ycy: "ы", yen: "¥", Yfr: "𝔜", yfr: "𝔶", YIcy: "Ї", yicy: "ї", Yopf: "𝕐", yopf: "𝕪", Yscr: "𝒴", yscr: "𝓎", YUcy: "Ю", yucy: "ю", Yuml: "Ÿ", yuml: "ÿ", Zacute: "Ź", zacute: "ź", Zcaron: "Ž", zcaron: "ž", Zcy: "З", zcy: "з", Zdot: "Ż", zdot: "ż", zeetrf: "ℨ", ZeroWidthSpace: "​", Zeta: "Ζ", zeta: "ζ", Zfr: "ℨ", zfr: "𝔷", ZHcy: "Ж", zhcy: "ж", zigrarr: "⇝", Zopf: "ℤ", zopf: "𝕫", Zscr: "𝒵", zscr: "𝓏", zwj: "‍", zwnj: "‌" }), s.entityMap = s.HTML_ENTITIES; }(Aa)), Aa; } var Wr = {}, hl; function jm() { if (hl) return Wr; hl = 1; var s = Pn().NAMESPACE, e = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/, t = new RegExp("[\\-\\.0-9" + e.source.slice(1, -1) + "\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"), i = new RegExp("^" + e.source + t.source + "*(?::" + e.source + t.source + "*)?$"), r = 0, n = 1, a = 2, u = 3, c = 4, f = 5, g = 6, y = 7; function I(v, E) { this.message = v, this.locator = E, Error.captureStackTrace && Error.captureStackTrace(this, I); } I.prototype = new Error(), I.prototype.name = I.name; function C() { } C.prototype = { parse: function(v, E, q) { var j = this.domBuilder; j.startDocument(), z(E, E = {}), R( v, E, q, j, this.errorHandler ), j.endDocument(); } }; function R(v, E, q, j, H) { function Y(ve) { if (ve > 65535) { ve -= 65536; var Be = 55296 + (ve >> 10), Zt = 56320 + (ve & 1023); return String.fromCharCode(Be, Zt); } else return String.fromCharCode(ve); } function ie(ve) { var Be = ve.slice(1, -1); return Object.hasOwnProperty.call(q, Be) ? q[Be] : Be.charAt(0) === "#" ? Y(parseInt(Be.substr(1).replace("x", "0x"))) : (H.error("entity not found:" + ve), ve); } function re(ve) { if (ve > _e) { var Be = v.substring(_e, ve).replace(/&#?\w+;/g, ie); ee && W(_e), j.characters(Be, 0, ve - _e), _e = ve; } } function W(ve, Be) { for (; ve >= J && (Be = te.exec(v)); ) Z = Be.index, J = Z + Be[0].length, ee.lineNumber++; ee.columnNumber = ve - Z + 1; } for (var Z = 0, J = 0, te = /.*(?:\r\n?|\n)|.*$/g, ee = j.locator, fe = [{ currentNSMap: E }], me = {}, _e = 0; ; ) { try { var he = v.indexOf("<", _e); if (he < 0) { if (!v.substr(_e).match(/^\s*$/)) { var Ke = j.doc, Je = Ke.createTextNode(v.substr(_e)); Ke.appendChild(Je), j.currentElement = Je; } return; } switch (he > _e && re(he), v.charAt(he + 1)) { case "/": var He = v.indexOf(">", he + 3), $e = v.substring(he + 2, He).replace(/[ \t\n\r]+$/g, ""), Ze = fe.pop(); He < 0 ? ($e = v.substring(he + 2).replace(/[\s<].*/, ""), H.error("end tag name: " + $e + " is not complete:" + Ze.tagName), He = he + 1 + $e.length) : $e.match(/\s _e ? _e = He : re(Math.max(he, _e) + 1); } } function T(v, E) { return E.lineNumber = v.lineNumber, E.columnNumber = v.columnNumber, E; } function P(v, E, q, j, H, Y) { function ie(ee, fe, me) { q.attributeNames.hasOwnProperty(ee) && Y.fatalError("Attribute " + ee + " redefined"), q.addValue( ee, // @see https://www.w3.org/TR/xml/#AVNormalize // since the xmldom sax parser does not "interpret" DTD the following is not implemented: // - recursive replacement of (DTD) entity references // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA fe.replace(/[\t\n\r]/g, " ").replace(/&#?\w+;/g, H), me ); } for (var re, W, Z = ++E, J = r; ; ) { var te = v.charAt(Z); switch (te) { case "=": if (J === n) re = v.slice(E, Z), J = u; else if (J === a) J = u; else throw new Error("attribute equal must after attrName"); break; case "'": case '"': if (J === u || J === n) if (J === n && (Y.warning('attribute value must after "="'), re = v.slice(E, Z)), E = Z + 1, Z = v.indexOf(te, E), Z > 0) W = v.slice(E, Z), ie(re, W, E - 1), J = f; else throw new Error("attribute value no end '" + te + "' match"); else if (J == c) W = v.slice(E, Z), ie(re, W, E), Y.warning('attribute "' + re + '" missed start quot(' + te + ")!!"), E = Z + 1, J = f; else throw new Error('attribute value must after "="'); break; case "/": switch (J) { case r: q.setTagName(v.slice(E, Z)); case f: case g: case y: J = y, q.closed = true; case c: case n: break; case a: q.closed = true; break; //case S_EQ: default: throw new Error("attribute invalid close char('/')"); } break; case "": return Y.error("unexpected end of input"), J == r && q.setTagName(v.slice(E, Z)), Z; case ">": switch (J) { case r: q.setTagName(v.slice(E, Z)); case f: case g: case y: break; //normal case c: //Compatible state case n: W = v.slice(E, Z), W.slice(-1) === "/" && (q.closed = true, W = W.slice(0, -1)); case a: J === a && (W = re), J == c ? (Y.warning('attribute "' + W + '" missed quot(")!'), ie(re, W, E)) : ((!s.isHTML(j[""]) || !W.match(/^(?:disabled|checked|selected)$/i)) && Y.warning('attribute "' + W + '" missed value!! "' + W + '" instead!!'), ie(W, W, E)); break; case u: throw new Error("attribute value missed!!"); } return Z; /*xml space '\x20' | #x9 | #xD | #xA; */ case "€": te = " "; default: if (te <= " ") switch (J) { case r: q.setTagName(v.slice(E, Z)), J = g; break; case n: re = v.slice(E, Z), J = a; break; case c: var W = v.slice(E, Z); Y.warning('attribute "' + W + '" missed quot(")!!'), ie(re, W, E); case f: J = g; break; } else switch (J) { //case S_TAG:void();break; //case S_ATTR:void();break; //case S_ATTR_NOQUOT_VALUE:void();break; case a: (!s.isHTML(j[""]) || !re.match(/^(?:disabled|checked|selected)$/i)) && Y.warning('attribute "' + re + '" missed value!! "' + re + '" instead2!!'), ie(re, re, E), E = Z, J = n; break; case f: Y.warning('attribute space is required"' + re + '"!!'); case g: J = n, E = Z; break; case u: J = c, E = Z; break; case y: throw new Error("elements closed character '/' and '>' must be connected to"); } } Z++; } } function B(v, E, q) { for (var j = v.tagName, H = null, te = v.length; te--; ) { var Y = v[te], ie = Y.qName, re = Y.value, ee = ie.indexOf(":"); if (ee > 0) var W = Y.prefix = ie.slice(0, ee), Z = ie.slice(ee + 1), J = W === "xmlns" && Z; else Z = ie, W = null, J = ie === "xmlns" && ""; Y.localName = Z, J !== false && (H == null && (H = {}, z(q, q = {})), q[J] = H[J] = re, Y.uri = s.XMLNS, E.startPrefixMapping(J, re)); } for (var te = v.length; te--; ) { Y = v[te]; var W = Y.prefix; W && (W === "xml" && (Y.uri = s.XML), W !== "xmlns" && (Y.uri = q[W || ""])); } var ee = j.indexOf(":"); ee > 0 ? (W = v.prefix = j.slice(0, ee), Z = v.localName = j.slice(ee + 1)) : (W = null, Z = v.localName = j); var fe = v.uri = q[W || ""]; if (E.startElement(fe, Z, j, v), v.closed) { if (E.endElement(fe, Z, j), H) for (W in H) Object.prototype.hasOwnProperty.call(H, W) && E.endPrefixMapping(W); } else return v.currentNSMap = q, v.localNSMap = H, true; } function N(v, E, q, j, H) { if (/^(?:script|textarea)$/i.test(q)) { var Y = v.indexOf("", E), ie = v.substring(E + 1, Y); if (/[&<]/.test(ie)) return /^script$/i.test(q) ? (H.characters(ie, 0, ie.length), Y) : (ie = ie.replace(/&#?\w+;/g, j), H.characters(ie, 0, ie.length), Y); } return E + 1; } function L(v, E, q, j) { var H = j[q]; return H == null && (H = v.lastIndexOf(""), H < E && (H = v.lastIndexOf("", E + 4); return Y > E ? (q.comment(v, E + 4, Y - E - 4), Y + 3) : (j.error("Unclosed comment"), -1); } else return -1; default: if (v.substr(E + 3, 6) == "CDATA[") { var Y = v.indexOf("]]>", E + 9); return q.startCDATA(), q.characters(v, E + 9, Y - E - 9), q.endCDATA(), Y + 3; } var ie = Q(v, E), re = ie.length; if (re > 1 && /!doctype/i.test(ie[0][0])) { var W = ie[1][0], Z = false, J = false; re > 3 && (/^public$/i.test(ie[2][0]) ? (Z = ie[3][0], J = re > 4 && ie[4][0]) : /^system$/i.test(ie[2][0]) && (J = ie[3][0])); var te = ie[re - 1]; return q.startDTD(W, Z, J), q.endDTD(), te.index + te[0].length; } } return -1; } function U(v, E, q) { var j = v.indexOf("?>", E); if (j) { var H = v.substring(E, j).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/); return H ? (q.processingInstruction(H[1], H[2]), j + 2) : -1; } return -1; } function V() { this.attributeNames = {}; } V.prototype = { setTagName: function(v) { if (!i.test(v)) throw new Error("invalid tagName:" + v); this.tagName = v; }, addValue: function(v, E, q) { if (!i.test(v)) throw new Error("invalid attribute:" + v); this.attributeNames[v] = this.length, this[this.length++] = { qName: v, value: E, offset: q }; }, length: 0, getLocalName: function(v) { return this[v].localName; }, getLocator: function(v) { return this[v].locator; }, getQName: function(v) { return this[v].qName; }, getURI: function(v) { return this[v].uri; }, getValue: function(v) { return this[v].value; } // ,getIndex:function(uri, localName)){ // if(localName){ // // }else{ // var qName = uri // } // }, // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))}, // getType:function(uri,localName){} // getType:function(i){}, }; function Q(v, E) { var q, j = [], H = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g; for (H.lastIndex = E, H.exec(v); q = H.exec(v); ) if (j.push(q), q[1]) return j; } return Wr.XMLReader = C, Wr.ParseError = I, Wr; } var fl; function Hm() { if (fl) return Ks; fl = 1; var s = /* @__PURE__ */ Pn(), e = /* @__PURE__ */ Pc(), t = /* @__PURE__ */ $m(), i = /* @__PURE__ */ jm(), r = e.DOMImplementation, n = s.NAMESPACE, a = i.ParseError, u = i.XMLReader; function c(P) { return P.replace(/\r[\n\u0085]/g, ` `).replace(/[\r\u0085\u2028]/g, ` `); } function f(P) { this.options = P || { locator: {} }; } f.prototype.parseFromString = function(P, B) { var N = this.options, L = new u(), z = N.domBuilder || new y(), O = N.errorHandler, U = N.locator, V = N.xmlns || {}, Q = /\/x?html?$/.test(B), v = Q ? t.HTML_ENTITIES : t.XML_ENTITIES; U && z.setDocumentLocator(U), L.errorHandler = g(O, z, U), L.domBuilder = N.domBuilder || z, Q && (V[""] = n.HTML), V.xml = V.xml || n.XML; var E = N.normalizeLineEndings || c; return P && typeof P == "string" ? L.parse( E(P), V, v ) : L.errorHandler.error("invalid doc source"), z.doc; }; function g(P, B, N) { if (!P) { if (B instanceof y) return B; P = B; } var L = {}, z = P instanceof Function; N = N || {}; function O(U) { var V = P[U]; !V && z && (V = P.length == 2 ? function(Q) { P(U, Q); } : P), L[U] = V && function(Q) { V("[xmldom " + U + "] " + Q + C(N)); } || function() { }; } return O("warning"), O("error"), O("fatalError"), L; } function y() { this.cdata = false; } function I(P, B) { B.lineNumber = P.lineNumber, B.columnNumber = P.columnNumber; } y.prototype = { startDocument: function() { this.doc = new r().createDocument(null, null, null), this.locator && (this.doc.documentURI = this.locator.systemId); }, startElement: function(P, B, N, L) { var z = this.doc, O = z.createElementNS(P, N || B), U = L.length; T(this, O), this.currentElement = O, this.locator && I(this.locator, O); for (var V = 0; V < U; V++) { var P = L.getURI(V), Q = L.getValue(V), N = L.getQName(V), v = z.createAttributeNS(P, N); this.locator && I(L.getLocator(V), v), v.value = v.nodeValue = Q, O.setAttributeNode(v); } }, endElement: function(P, B, N) { var L = this.currentElement; this.currentElement = L.parentNode; }, startPrefixMapping: function(P, B) { }, endPrefixMapping: function(P) { }, processingInstruction: function(P, B) { var N = this.doc.createProcessingInstruction(P, B); this.locator && I(this.locator, N), T(this, N); }, ignorableWhitespace: function(P, B, N) { }, characters: function(P, B, N) { if (P = R.apply(this, arguments), P) { if (this.cdata) var L = this.doc.createCDATASection(P); else var L = this.doc.createTextNode(P); this.currentElement ? this.currentElement.appendChild(L) : /^\s*$/.test(P) && this.doc.appendChild(L), this.locator && I(this.locator, L); } }, skippedEntity: function(P) { }, endDocument: function() { this.doc.normalize(); }, setDocumentLocator: function(P) { (this.locator = P) && (P.lineNumber = 0); }, //LexicalHandler comment: function(P, B, N) { P = R.apply(this, arguments); var L = this.doc.createComment(P); this.locator && I(this.locator, L), T(this, L); }, startCDATA: function() { this.cdata = true; }, endCDATA: function() { this.cdata = false; }, startDTD: function(P, B, N) { var L = this.doc.implementation; if (L && L.createDocumentType) { var z = L.createDocumentType(P, B, N); this.locator && I(this.locator, z), T(this, z), this.doc.doctype = z; } }, /** * @see org.xml.sax.ErrorHandler * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html */ warning: function(P) { console.warn("[xmldom warning] " + P, C(this.locator)); }, error: function(P) { console.error("[xmldom error] " + P, C(this.locator)); }, fatalError: function(P) { throw new a(P, this.locator); } }; function C(P) { if (P) return ` @` + (P.systemId || "") + "#[line:" + P.lineNumber + ",col:" + P.columnNumber + "]"; } function R(P, B, N) { return typeof P == "string" ? P.substr(B, N) : P.length >= B + N || B ? new java.lang.String(P, B, N) + "" : P; } "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g, function(P) { y.prototype[P] = function() { return null; }; }); function T(P, B) { P.currentElement ? P.currentElement.appendChild(B) : P.doc.appendChild(B); } return Ks.__DOMHandler = y, Ks.normalizeLineEndings = c, Ks.DOMParser = f, Ks; } var pl; function Vm() { if (pl) return Xs; pl = 1; var s = /* @__PURE__ */ Pc(); return Xs.DOMImplementation = s.DOMImplementation, Xs.XMLSerializer = s.XMLSerializer, Xs.DOMParser = Hm().DOMParser, Xs; } var zm = /* @__PURE__ */ Vm(); /*! @name mpd-parser @version 1.3.1 @license Apache-2.0 */ const ml = (s) => !!s && typeof s == "object", We = (...s) => s.reduce((e, t) => (typeof t != "object" || Object.keys(t).forEach((i) => { Array.isArray(e[i]) && Array.isArray(t[i]) ? e[i] = e[i].concat(t[i]) : ml(e[i]) && ml(t[i]) ? e[i] = We(e[i], t[i]) : e[i] = t[i]; }), e), {}), Oc = (s) => Object.keys(s).map((e) => s[e]), Gm = (s, e) => { const t = []; for (let i = s; i < e; i++) t.push(i); return t; }, fs = (s) => s.reduce((e, t) => e.concat(t), []), Lc = (s) => { if (!s.length) return []; const e = []; for (let t = 0; t < s.length; t++) e.push(s[t]); return e; }, Wm = (s, e) => s.reduce((t, i, r) => (i[e] && t.push(r), t), []), Xm = (s, e) => Oc(s.reduce((t, i) => (i.forEach((r) => { t[e(r)] = r; }), t), {})); var ps = { INVALID_NUMBER_OF_PERIOD: "INVALID_NUMBER_OF_PERIOD", DASH_EMPTY_MANIFEST: "DASH_EMPTY_MANIFEST", DASH_INVALID_XML: "DASH_INVALID_XML", NO_BASE_URL: "NO_BASE_URL", SEGMENT_TIME_UNSPECIFIED: "SEGMENT_TIME_UNSPECIFIED", UNSUPPORTED_UTC_TIMING_SCHEME: "UNSUPPORTED_UTC_TIMING_SCHEME" }; const ur = ({ baseUrl: s = "", source: e = "", range: t = "", indexRange: i = "" }) => { const r = { uri: e, resolvedUri: kn(s || "", e) }; if (t || i) { const a = (t || i).split("-"); let u = D.BigInt ? D.BigInt(a[0]) : parseInt(a[0], 10), c = D.BigInt ? D.BigInt(a[1]) : parseInt(a[1], 10); u < Number.MAX_SAFE_INTEGER && typeof u == "bigint" && (u = Number(u)), c < Number.MAX_SAFE_INTEGER && typeof c == "bigint" && (c = Number(c)); let f; typeof c == "bigint" || typeof u == "bigint" ? f = D.BigInt(c) - D.BigInt(u) + D.BigInt(1) : f = c - u + 1, typeof f == "bigint" && f < Number.MAX_SAFE_INTEGER && (f = Number(f)), r.byterange = { length: f, offset: u }; } return r; }, Km = (s) => { let e; return typeof s.offset == "bigint" || typeof s.length == "bigint" ? e = D.BigInt(s.offset) + D.BigInt(s.length) - D.BigInt(1) : e = s.offset + s.length - 1, `${s.offset}-${e}`; }, gl = (s) => (s && typeof s != "number" && (s = parseInt(s, 10)), isNaN(s) ? null : s), Qm = { /** * Returns the entire range of available segments for a static MPD * * @param {Object} attributes * Inheritied MPD attributes * @return {{ start: number, end: number }} * The start and end numbers for available segments */ static(s) { const { duration: e, timescale: t = 1, sourceDuration: i, periodDuration: r } = s, n = gl(s.endNumber), a = e / t; return typeof n == "number" ? { start: 0, end: n } : typeof r == "number" ? { start: 0, end: r / a } : { start: 0, end: i / a }; }, /** * Returns the current live window range of available segments for a dynamic MPD * * @param {Object} attributes * Inheritied MPD attributes * @return {{ start: number, end: number }} * The start and end numbers for available segments */ dynamic(s) { const { NOW: e, clientOffset: t, availabilityStartTime: i, timescale: r = 1, duration: n, periodStart: a = 0, minimumUpdatePeriod: u = 0, timeShiftBufferDepth: c = 1 / 0 } = s, f = gl(s.endNumber), g = (e + t) / 1e3, y = i + a, C = g + u - y, R = Math.ceil(C * r / n), T = Math.floor((g - y - c) * r / n), P = Math.floor((g - y) * r / n); return { start: Math.max(0, T), end: typeof f == "number" ? f : Math.min(R, P) }; } }, Ym = (s) => (e) => { const { duration: t, timescale: i = 1, periodStart: r, startNumber: n = 1 } = s; return { number: n + e, duration: t / i, timeline: r, time: e * t }; }, bo = (s) => { const { type: e, duration: t, timescale: i = 1, periodDuration: r, sourceDuration: n } = s, { start: a, end: u } = Qm[e](s), c = Gm(a, u).map(Ym(s)); if (e === "static") { const f = c.length - 1, g = typeof r == "number" ? r : n; c[f].duration = g - t / i * f; } return c; }, Rc = (s) => { const { baseUrl: e, initialization: t = {}, sourceDuration: i, indexRange: r = "", periodStart: n, presentationTime: a, number: u = 0, duration: c } = s; if (!e) throw new Error(ps.NO_BASE_URL); const f = ur({ baseUrl: e, source: t.sourceURL, range: t.range }), g = ur({ baseUrl: e, source: e, indexRange: r }); if (g.map = f, c) { const y = bo(s); y.length && (g.duration = y[0].duration, g.timeline = y[0].timeline); } else i && (g.duration = i, g.timeline = n); return g.presentationTime = a || n, g.number = u, [g]; }, xo = (s, e, t) => { const i = s.sidx.map ? s.sidx.map : null, r = s.sidx.duration, n = s.timeline || 0, a = s.sidx.byterange, u = a.offset + a.length, c = e.timescale, f = e.references.filter((P) => P.referenceType !== 1), g = [], y = s.endList ? "static" : "dynamic", I = s.sidx.timeline; let C = I, R = s.mediaSequence || 0, T; typeof e.firstOffset == "bigint" ? T = D.BigInt(u) + e.firstOffset : T = u + e.firstOffset; for (let P = 0; P < f.length; P++) { const B = e.references[P], N = B.referencedSize, L = B.subsegmentDuration; let z; typeof T == "bigint" ? z = T + D.BigInt(N) - D.BigInt(1) : z = T + N - 1; const O = `${T}-${z}`, V = Rc({ baseUrl: t, timescale: c, timeline: n, periodStart: I, presentationTime: C, number: R, duration: L, sourceDuration: r, indexRange: O, type: y })[0]; i && (V.map = i), g.push(V), typeof T == "bigint" ? T += D.BigInt(N) : T += N, C += L / c, R++; } return s.segments = g, s; }, Jm = ["AUDIO", "SUBTITLES"], Zm = 1 / 60, Mc = (s) => Xm(s, ({ timeline: e }) => e).sort((e, t) => e.timeline > t.timeline ? 1 : -1), eg = (s, e) => { for (let t = 0; t < s.length; t++) if (s[t].attributes.NAME === e) return s[t]; return null; }, _l = (s) => { let e = []; return qm(s, Jm, (t, i, r, n) => { e = e.concat(t.playlists || []); }), e; }, yl = ({ playlist: s, mediaSequence: e }) => { s.mediaSequence = e, s.segments.forEach((t, i) => { t.number = s.mediaSequence + i; }); }, tg = ({ oldPlaylists: s, newPlaylists: e, timelineStarts: t }) => { e.forEach((i) => { i.discontinuitySequence = t.findIndex(function({ timeline: c }) { return c === i.timeline; }); const r = eg(s, i.attributes.NAME); if (!r || i.sidx) return; const n = i.segments[0], a = r.segments.findIndex(function(c) { return Math.abs(c.presentationTime - n.presentationTime) < Zm; }); if (a === -1) { yl({ playlist: i, mediaSequence: r.mediaSequence + r.segments.length }), i.segments[0].discontinuity = true, i.discontinuityStarts.unshift(0), (!r.segments.length && i.timeline > r.timeline || r.segments.length && i.timeline > r.segments[r.segments.length - 1].timeline) && i.discontinuitySequence--; return; } r.segments[a].discontinuity && !n.discontinuity && (n.discontinuity = true, i.discontinuityStarts.unshift(0), i.discontinuitySequence--), yl({ playlist: i, mediaSequence: r.segments[a].number }); }); }, ig = ({ oldManifest: s, newManifest: e }) => { const t = s.playlists.concat(_l(s)), i = e.playlists.concat(_l(e)); return e.timelineStarts = Mc([s.timelineStarts, e.timelineStarts]), tg({ oldPlaylists: t, newPlaylists: i, timelineStarts: e.timelineStarts }), e; }, On = (s) => s && s.uri + "-" + Km(s.byterange), Da = (s) => { const e = s.reduce(function(i, r) { return i[r.attributes.baseUrl] || (i[r.attributes.baseUrl] = []), i[r.attributes.baseUrl].push(r), i; }, {}); let t = []; return Object.values(e).forEach((i) => { const r = Oc(i.reduce((n, a) => { const u = a.attributes.id + (a.attributes.lang || ""); return n[u] ? (a.segments && (a.segments[0] && (a.segments[0].discontinuity = true), n[u].segments.push(...a.segments)), a.attributes.contentProtection && (n[u].attributes.contentProtection = a.attributes.contentProtection)) : (n[u] = a, n[u].attributes.timelineStarts = []), n[u].attributes.timelineStarts.push({ // Although they represent the same number, it's important to have both to make it // compatible with HLS potentially having a similar attribute. start: a.attributes.periodStart, timeline: a.attributes.periodStart }), n; }, {})); t = t.concat(r); }), t.map((i) => (i.discontinuityStarts = Wm(i.segments || [], "discontinuity"), i)); }, So = (s, e) => { const t = On(s.sidx), i = t && e[t] && e[t].sidx; return i && xo(s, i, s.sidx.resolvedUri), s; }, sg = (s, e = {}) => { if (!Object.keys(e).length) return s; for (const t in s) s[t] = So(s[t], e); return s; }, rg = ({ attributes: s, segments: e, sidx: t, mediaSequence: i, discontinuitySequence: r, discontinuityStarts: n }, a) => { const u = { attributes: { NAME: s.id, BANDWIDTH: s.bandwidth, CODECS: s.codecs, "PROGRAM-ID": 1 }, uri: "", endList: s.type === "static", timeline: s.periodStart, resolvedUri: s.baseUrl || "", targetDuration: s.duration, discontinuitySequence: r, discontinuityStarts: n, timelineStarts: s.timelineStarts, mediaSequence: i, segments: e }; return s.contentProtection && (u.contentProtection = s.contentProtection), s.serviceLocation && (u.attributes.serviceLocation = s.serviceLocation), t && (u.sidx = t), a && (u.attributes.AUDIO = "audio", u.attributes.SUBTITLES = "subs"), u; }, ng = ({ attributes: s, segments: e, mediaSequence: t, discontinuityStarts: i, discontinuitySequence: r }) => { typeof e > "u" && (e = [{ uri: s.baseUrl, timeline: s.periodStart, resolvedUri: s.baseUrl || "", duration: s.sourceDuration, number: 0 }], s.duration = s.sourceDuration); const n = { NAME: s.id, BANDWIDTH: s.bandwidth, "PROGRAM-ID": 1 }; s.codecs && (n.CODECS = s.codecs); const a = { attributes: n, uri: "", endList: s.type === "static", timeline: s.periodStart, resolvedUri: s.baseUrl || "", targetDuration: s.duration, timelineStarts: s.timelineStarts, discontinuityStarts: i, discontinuitySequence: r, mediaSequence: t, segments: e }; return s.serviceLocation && (a.attributes.serviceLocation = s.serviceLocation), a; }, ag = (s, e = {}, t = false) => { let i; const r = s.reduce((n, a) => { const u = a.attributes.role && a.attributes.role.value || "", c = a.attributes.lang || ""; let f = a.attributes.label || "main"; if (c && !a.attributes.label) { const y = u ? ` (${u})` : ""; f = `${a.attributes.lang}${y}`; } n[f] || (n[f] = { language: c, autoselect: true, default: u === "main", playlists: [], uri: "" }); const g = So(rg(a, t), e); return n[f].playlists.push(g), typeof i > "u" && u === "main" && (i = a, i.default = true), n; }, {}); if (!i) { const n = Object.keys(r)[0]; r[n].default = true; } return r; }, og = (s, e = {}) => s.reduce((t, i) => { const r = i.attributes.label || i.attributes.lang || "text", n = i.attributes.lang || "und"; return t[r] || (t[r] = { language: n, default: false, autoselect: false, playlists: [], uri: "" }), t[r].playlists.push(So(ng(i), e)), t; }, {}), ug = (s) => s.reduce((e, t) => (t && t.forEach((i) => { const { channel: r, language: n } = i; e[n] = { autoselect: false, default: false, instreamId: r, language: n }, i.hasOwnProperty("aspectRatio") && (e[n].aspectRatio = i.aspectRatio), i.hasOwnProperty("easyReader") && (e[n].easyReader = i.easyReader), i.hasOwnProperty("3D") && (e[n]["3D"] = i["3D"]); }), e), {}), lg = ({ attributes: s, segments: e, sidx: t, discontinuityStarts: i }) => { const r = { attributes: { NAME: s.id, AUDIO: "audio", SUBTITLES: "subs", RESOLUTION: { width: s.width, height: s.height }, CODECS: s.codecs, BANDWIDTH: s.bandwidth, "PROGRAM-ID": 1 }, uri: "", endList: s.type === "static", timeline: s.periodStart, resolvedUri: s.baseUrl || "", targetDuration: s.duration, discontinuityStarts: i, timelineStarts: s.timelineStarts, segments: e }; return s.frameRate && (r.attributes["FRAME-RATE"] = s.frameRate), s.contentProtection && (r.contentProtection = s.contentProtection), s.serviceLocation && (r.attributes.serviceLocation = s.serviceLocation), t && (r.sidx = t), r; }, cg = ({ attributes: s }) => s.mimeType === "video/mp4" || s.mimeType === "video/webm" || s.contentType === "video", dg = ({ attributes: s }) => s.mimeType === "audio/mp4" || s.mimeType === "audio/webm" || s.contentType === "audio", hg = ({ attributes: s }) => s.mimeType === "text/vtt" || s.contentType === "text", fg = (s, e) => { s.forEach((t) => { t.mediaSequence = 0, t.discontinuitySequence = e.findIndex(function({ timeline: i }) { return i === t.timeline; }), t.segments && t.segments.forEach((i, r) => { i.number = r; }); }); }, Tl = (s) => s ? Object.keys(s).reduce((e, t) => { const i = s[t]; return e.concat(i.playlists); }, []) : [], pg = ({ dashPlaylists: s, locations: e, contentSteering: t, sidxMapping: i = {}, previousManifest: r, eventStream: n }) => { if (!s.length) return {}; const { sourceDuration: a, type: u, suggestedPresentationDelay: c, minimumUpdatePeriod: f } = s[0].attributes, g = Da(s.filter(cg)).map(lg), y = Da(s.filter(dg)), I = Da(s.filter(hg)), C = s.map((z) => z.attributes.captionServices).filter(Boolean), R = { allowCache: true, discontinuityStarts: [], segments: [], endList: true, mediaGroups: { AUDIO: {}, VIDEO: {}, "CLOSED-CAPTIONS": {}, SUBTITLES: {} }, uri: "", duration: a, playlists: sg(g, i) }; f >= 0 && (R.minimumUpdatePeriod = f * 1e3), e && (R.locations = e), t && (R.contentSteering = t), u === "dynamic" && (R.suggestedPresentationDelay = c), n && n.length > 0 && (R.eventStream = n); const T = R.playlists.length === 0, P = y.length ? ag(y, i, T) : null, B = I.length ? og(I, i) : null, N = g.concat(Tl(P), Tl(B)), L = N.map(({ timelineStarts: z }) => z); return R.timelineStarts = Mc(L), fg(N, R.timelineStarts), P && (R.mediaGroups.AUDIO.audio = P), B && (R.mediaGroups.SUBTITLES.subs = B), C.length && (R.mediaGroups["CLOSED-CAPTIONS"].cc = ug(C)), r ? ig({ oldManifest: r, newManifest: R }) : R; }, mg = (s, e, t) => { const { NOW: i, clientOffset: r, availabilityStartTime: n, timescale: a = 1, periodStart: u = 0, minimumUpdatePeriod: c = 0 } = s, f = (i + r) / 1e3, g = n + u, I = f + c - g; return Math.ceil((I * a - e) / t); }, Nc = (s, e) => { const { type: t, minimumUpdatePeriod: i = 0, media: r = "", sourceDuration: n, timescale: a = 1, startNumber: u = 1, periodStart: c } = s, f = []; let g = -1; for (let y = 0; y < e.length; y++) { const I = e[y], C = I.d, R = I.r || 0, T = I.t || 0; g < 0 && (g = T), T && T > g && (g = T); let P; if (R < 0) { const L = y + 1; L === e.length ? t === "dynamic" && i > 0 && r.indexOf("$Number$") > 0 ? P = mg(s, g, C) : P = (n * a - g) / C : P = (e[L].t - g) / C; } else P = R + 1; const B = u + f.length + P; let N = u + f.length; for (; N < B; ) f.push({ number: N, duration: C / a, time: g, timeline: c }), g += C, N++; } return f; }, gg = /\$([A-z]*)(?:(%0)([0-9]+)d)?\$/g, _g = (s) => (e, t, i, r) => { if (e === "$$") return "$"; if (typeof s[t] > "u") return e; const n = "" + s[t]; return t === "RepresentationID" || (i ? r = parseInt(r, 10) : r = 1, n.length >= r) ? n : `${new Array(r - n.length + 1).join("0")}${n}`; }, vl = (s, e) => s.replace(gg, _g(e)), yg = (s, e) => !s.duration && !e ? [{ number: s.startNumber || 1, duration: s.sourceDuration, time: 0, timeline: s.periodStart }] : s.duration ? bo(s) : Nc(s, e), Tg = (s, e) => { const t = { RepresentationID: s.id, Bandwidth: s.bandwidth || 0 }, { initialization: i = { sourceURL: "", range: "" } } = s, r = ur({ baseUrl: s.baseUrl, source: vl(i.sourceURL, t), range: i.range }); return yg(s, e).map((a) => { t.Number = a.number, t.Time = a.time; const u = vl(s.media || "", t), c = s.timescale || 1, f = s.presentationTimeOffset || 0, g = ( // Even if the @t attribute is not specified for the segment, segment.time is // calculated in mpd-parser prior to this, so it's assumed to be available. s.periodStart + (a.time - f) / c ); return { uri: u, timeline: a.timeline, duration: a.duration, resolvedUri: kn(s.baseUrl || "", u), map: r, number: a.number, presentationTime: g }; }); }, vg = (s, e) => { const { baseUrl: t, initialization: i = {} } = s, r = ur({ baseUrl: t, source: i.sourceURL, range: i.range }), n = ur({ baseUrl: t, source: e.media, range: e.mediaRange }); return n.map = r, n; }, bg = (s, e) => { const { duration: t, segmentUrls: i = [], periodStart: r } = s; if (!t && !e || t && e) throw new Error(ps.SEGMENT_TIME_UNSPECIFIED); const n = i.map((c) => vg(s, c)); let a; return t && (a = bo(s)), e && (a = Nc(s, e)), a.map((c, f) => { if (n[f]) { const g = n[f], y = s.timescale || 1, I = s.presentationTimeOffset || 0; return g.timeline = c.timeline, g.duration = c.duration, g.number = c.number, g.presentationTime = r + (c.time - I) / y, g; } }).filter((c) => c); }, xg = ({ attributes: s, segmentInfo: e }) => { let t, i; e.template ? (i = Tg, t = We(s, e.template)) : e.base ? (i = Rc, t = We(s, e.base)) : e.list && (i = bg, t = We(s, e.list)); const r = { attributes: s }; if (!i) return r; const n = i(t, e.segmentTimeline); if (t.duration) { const { duration: a, timescale: u = 1 } = t; t.duration = a / u; } else n.length ? t.duration = n.reduce((a, u) => Math.max(a, Math.ceil(u.duration)), 0) : t.duration = 0; return r.attributes = t, r.segments = n, e.base && t.indexRange && (r.sidx = n[0], r.segments = []), r; }, Sg = (s) => s.map(xg), Oe = (s, e) => Lc(s.childNodes).filter(({ tagName: t }) => t === e), fr = (s) => s.textContent.trim(), Eg = (s) => parseFloat(s.split("/").reduce((e, t) => e / t)), Ji = (s) => { const u = /P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)D)?(?:T(?:(\d*)H)?(?:(\d*)M)?(?:([\d.]*)S)?)?/.exec(s); if (!u) return 0; const [c, f, g, y, I, C] = u.slice(1); return parseFloat(c || 0) * 31536e3 + parseFloat(f || 0) * 2592e3 + parseFloat(g || 0) * 86400 + parseFloat(y || 0) * 3600 + parseFloat(I || 0) * 60 + parseFloat(C || 0); }, Cg = (s) => (/^\d+-\d+-\d+T\d+:\d+:\d+(\.\d+)?$/.test(s) && (s += "Z"), Date.parse(s)), bl = { /** * Specifies the duration of the entire Media Presentation. Format is a duration string * as specified in ISO 8601 * * @param {string} value * value of attribute as a string * @return {number} * The duration in seconds */ mediaPresentationDuration(s) { return Ji(s); }, /** * Specifies the Segment availability start time for all Segments referred to in this * MPD. For a dynamic manifest, it specifies the anchor for the earliest availability * time. Format is a date string as specified in ISO 8601 * * @param {string} value * value of attribute as a string * @return {number} * The date as seconds from unix epoch */ availabilityStartTime(s) { return Cg(s) / 1e3; }, /** * Specifies the smallest period between potential changes to the MPD. Format is a * duration string as specified in ISO 8601 * * @param {string} value * value of attribute as a string * @return {number} * The duration in seconds */ minimumUpdatePeriod(s) { return Ji(s); }, /** * Specifies the suggested presentation delay. Format is a * duration string as specified in ISO 8601 * * @param {string} value * value of attribute as a string * @return {number} * The duration in seconds */ suggestedPresentationDelay(s) { return Ji(s); }, /** * specifices the type of mpd. Can be either "static" or "dynamic" * * @param {string} value * value of attribute as a string * * @return {string} * The type as a string */ type(s) { return s; }, /** * Specifies the duration of the smallest time shifting buffer for any Representation * in the MPD. Format is a duration string as specified in ISO 8601 * * @param {string} value * value of attribute as a string * @return {number} * The duration in seconds */ timeShiftBufferDepth(s) { return Ji(s); }, /** * Specifies the PeriodStart time of the Period relative to the availabilityStarttime. * Format is a duration string as specified in ISO 8601 * * @param {string} value * value of attribute as a string * @return {number} * The duration in seconds */ start(s) { return Ji(s); }, /** * Specifies the width of the visual presentation * * @param {string} value * value of attribute as a string * @return {number} * The parsed width */ width(s) { return parseInt(s, 10); }, /** * Specifies the height of the visual presentation * * @param {string} value * value of attribute as a string * @return {number} * The parsed height */ height(s) { return parseInt(s, 10); }, /** * Specifies the bitrate of the representation * * @param {string} value * value of attribute as a string * @return {number} * The parsed bandwidth */ bandwidth(s) { return parseInt(s, 10); }, /** * Specifies the frame rate of the representation * * @param {string} value * value of attribute as a string * @return {number} * The parsed frame rate */ frameRate(s) { return Eg(s); }, /** * Specifies the number of the first Media Segment in this Representation in the Period * * @param {string} value * value of attribute as a string * @return {number} * The parsed number */ startNumber(s) { return parseInt(s, 10); }, /** * Specifies the timescale in units per seconds * * @param {string} value * value of attribute as a string * @return {number} * The parsed timescale */ timescale(s) { return parseInt(s, 10); }, /** * Specifies the presentationTimeOffset. * * @param {string} value * value of the attribute as a string * * @return {number} * The parsed presentationTimeOffset */ presentationTimeOffset(s) { return parseInt(s, 10); }, /** * Specifies the constant approximate Segment duration * NOTE: The element also contains an @duration attribute. This duration * specifies the duration of the Period. This attribute is currently not * supported by the rest of the parser, however we still check for it to prevent * errors. * * @param {string} value * value of attribute as a string * @return {number} * The parsed duration */ duration(s) { const e = parseInt(s, 10); return isNaN(e) ? Ji(s) : e; }, /** * Specifies the Segment duration, in units of the value of the @timescale. * * @param {string} value * value of attribute as a string * @return {number} * The parsed duration */ d(s) { return parseInt(s, 10); }, /** * Specifies the MPD start time, in @timescale units, the first Segment in the series * starts relative to the beginning of the Period * * @param {string} value * value of attribute as a string * @return {number} * The parsed time */ t(s) { return parseInt(s, 10); }, /** * Specifies the repeat count of the number of following contiguous Segments with the * same duration expressed by the value of @d * * @param {string} value * value of attribute as a string * @return {number} * The parsed number */ r(s) { return parseInt(s, 10); }, /** * Specifies the presentationTime. * * @param {string} value * value of the attribute as a string * * @return {number} * The parsed presentationTime */ presentationTime(s) { return parseInt(s, 10); }, /** * Default parser for all other attributes. Acts as a no-op and just returns the value * as a string * * @param {string} value * value of attribute as a string * @return {string} * Unparsed value */ DEFAULT(s) { return s; } }, je = (s) => s && s.attributes ? Lc(s.attributes).reduce((e, t) => { const i = bl[t.name] || bl.DEFAULT; return e[t.name] = i(t.value), e; }, {}) : {}, Ag = { "urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b": "org.w3.clearkey", "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed": "com.widevine.alpha", "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95": "com.microsoft.playready", "urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb": "com.adobe.primetime", // ISO_IEC 23009-1_2022 5.8.5.2.2 The mp4 Protection Scheme "urn:mpeg:dash:mp4protection:2011": "mp4protection" }, Ln = (s, e) => e.length ? fs(s.map(function(t) { return e.map(function(i) { const r = fr(i), n = kn(t.baseUrl, r), a = We(je(i), { baseUrl: n }); return n !== r && !a.serviceLocation && t.serviceLocation && (a.serviceLocation = t.serviceLocation), a; }); })) : s, Eo = (s) => { const e = Oe(s, "SegmentTemplate")[0], t = Oe(s, "SegmentList")[0], i = t && Oe(t, "SegmentURL").map((y) => We({ tag: "SegmentURL" }, je(y))), r = Oe(s, "SegmentBase")[0], n = t || e, a = n && Oe(n, "SegmentTimeline")[0], u = t || r || e, c = u && Oe(u, "Initialization")[0], f = e && je(e); f && c ? f.initialization = c && je(c) : f && f.initialization && (f.initialization = { sourceURL: f.initialization }); const g = { template: f, segmentTimeline: a && Oe(a, "S").map((y) => je(y)), list: t && We(je(t), { segmentUrls: i, initialization: je(c) }), base: r && We(je(r), { initialization: je(c) }) }; return Object.keys(g).forEach((y) => { g[y] || delete g[y]; }), g; }, Dg = (s, e, t) => (i) => { const r = Oe(i, "BaseURL"), n = Ln(e, r), a = We(s, je(i)), u = Eo(i); return n.map((c) => ({ segmentInfo: We(t, u), attributes: We(a, c) })); }, wg = (s) => s.reduce((e, t) => { const i = je(t); i.schemeIdUri && (i.schemeIdUri = i.schemeIdUri.toLowerCase()); const r = Ag[i.schemeIdUri]; if (r) { e[r] = { attributes: i }; const n = Oe(t, "cenc:pssh")[0]; if (n) { const a = fr(n); e[r].pssh = a && Cc(a); } } return e; }, {}), Ig = (s) => { if (s.schemeIdUri === "urn:scte:dash:cc:cea-608:2015") return (typeof s.value != "string" ? [] : s.value.split(";")).map((t) => { let i, r; return r = t, /^CC\d=/.test(t) ? [i, r] = t.split("=") : /^CC\d$/.test(t) && (i = t), { channel: i, language: r }; }); if (s.schemeIdUri === "urn:scte:dash:cc:cea-708:2015") return (typeof s.value != "string" ? [] : s.value.split(";")).map((t) => { const i = { // service or channel number 1-63 channel: void 0, // language is a 3ALPHA per ISO 639.2/B // field is required language: void 0, // BIT 1/0 or ? // default value is 1, meaning 16:9 aspect ratio, 0 is 4:3, ? is unknown aspectRatio: 1, // BIT 1/0 // easy reader flag indicated the text is tailed to the needs of beginning readers // default 0, or off easyReader: 0, // BIT 1/0 // If 3d metadata is present (CEA-708.1) then 1 // default 0 "3D": 0 }; if (/=/.test(t)) { const [r, n = ""] = t.split("="); i.channel = r, i.language = t, n.split(",").forEach((a) => { const [u, c] = a.split(":"); u === "lang" ? i.language = c : u === "er" ? i.easyReader = Number(c) : u === "war" ? i.aspectRatio = Number(c) : u === "3D" && (i["3D"] = Number(c)); }); } else i.language = t; return i.channel && (i.channel = "SERVICE" + i.channel), i; }); }, kg = (s) => fs(Oe(s.node, "EventStream").map((e) => { const t = je(e), i = t.schemeIdUri; return Oe(e, "Event").map((r) => { const n = je(r), a = n.presentationTime || 0, u = t.timescale || 1, c = n.duration || 0, f = a / u + s.attributes.start; return { schemeIdUri: i, value: t.value, id: n.id, start: f, end: f + c / u, messageData: fr(r) || n.messageData, contentEncoding: t.contentEncoding, presentationTimeOffset: t.presentationTimeOffset || 0 }; }); })), Pg = (s, e, t) => (i) => { const r = je(i), n = Ln(e, Oe(i, "BaseURL")), a = Oe(i, "Role")[0], u = { role: je(a) }; let c = We(s, r, u); const f = Oe(i, "Accessibility")[0], g = Ig(je(f)); g && (c = We(c, { captionServices: g })); const y = Oe(i, "Label")[0]; if (y && y.childNodes.length) { const P = y.childNodes[0].nodeValue.trim(); c = We(c, { label: P }); } const I = wg(Oe(i, "ContentProtection")); Object.keys(I).length && (c = We(c, { contentProtection: I })); const C = Eo(i), R = Oe(i, "Representation"), T = We(t, C); return fs(R.map(Dg(c, n, T))); }, Og = (s, e) => (t, i) => { const r = Ln(e, Oe(t.node, "BaseURL")), n = We(s, { periodStart: t.attributes.start }); typeof t.attributes.duration == "number" && (n.periodDuration = t.attributes.duration); const a = Oe(t.node, "AdaptationSet"), u = Eo(t.node); return fs(a.map(Pg(n, r, u))); }, Lg = (s, e) => { if (s.length > 1 && e({ type: "warn", message: "The MPD manifest should contain no more than one ContentSteering tag" }), !s.length) return null; const t = We({ serverURL: fr(s[0]) }, je(s[0])); return t.queryBeforeStart = t.queryBeforeStart === "true", t; }, Rg = ({ attributes: s, priorPeriodAttributes: e, mpdType: t }) => typeof s.start == "number" ? s.start : e && typeof e.start == "number" && typeof e.duration == "number" ? e.start + e.duration : !e && t === "static" ? 0 : null, Mg = (s, e = {}) => { const { manifestUri: t = "", NOW: i = Date.now(), clientOffset: r = 0, // TODO: For now, we are expecting an eventHandler callback function // to be passed into the mpd parser as an option. // In the future, we should enable stream parsing by using the Stream class from vhs-utils. // This will support new features including a standardized event handler. // See the m3u8 parser for examples of how stream parsing is currently used for HLS parsing. // https://github.com/videojs/vhs-utils/blob/88d6e10c631e57a5af02c5a62bc7376cd456b4f5/src/stream.js#L9 eventHandler: n = function() { } } = e, a = Oe(s, "Period"); if (!a.length) throw new Error(ps.INVALID_NUMBER_OF_PERIOD); const u = Oe(s, "Location"), c = je(s), f = Ln([{ baseUrl: t }], Oe(s, "BaseURL")), g = Oe(s, "ContentSteering"); c.type = c.type || "static", c.sourceDuration = c.mediaPresentationDuration || 0, c.NOW = i, c.clientOffset = r, u.length && (c.locations = u.map(fr)); const y = []; return a.forEach((I, C) => { const R = je(I), T = y[C - 1]; R.start = Rg({ attributes: R, priorPeriodAttributes: T ? T.attributes : null, mpdType: c.type }), y.push({ node: I, attributes: R }); }), { locations: c.locations, contentSteeringInfo: Lg(g, n), // TODO: There are occurences where this `representationInfo` array contains undesired // duplicates. This generally occurs when there are multiple BaseURL nodes that are // direct children of the MPD node. When we attempt to resolve URLs from a combination of the // parent BaseURL and a child BaseURL, and the value does not resolve, // we end up returning the child BaseURL multiple times. // We need to determine a way to remove these duplicates in a safe way. // See: https://github.com/videojs/mpd-parser/pull/17#discussion_r162750527 representationInfo: fs(y.map(Og(c, f))), eventStream: fs(y.map(kg)) }; }, Bc = (s) => { if (s === "") throw new Error(ps.DASH_EMPTY_MANIFEST); const e = new zm.DOMParser(); let t, i; try { t = e.parseFromString(s, "application/xml"), i = t && t.documentElement.tagName === "MPD" ? t.documentElement : null; } catch { } if (!i || i && i.getElementsByTagName("parsererror").length > 0) throw new Error(ps.DASH_INVALID_XML); return i; }, Ng = (s) => { const e = Oe(s, "UTCTiming")[0]; if (!e) return null; const t = je(e); switch (t.schemeIdUri) { case "urn:mpeg:dash:utc:http-head:2014": case "urn:mpeg:dash:utc:http-head:2012": t.method = "HEAD"; break; case "urn:mpeg:dash:utc:http-xsdate:2014": case "urn:mpeg:dash:utc:http-iso:2014": case "urn:mpeg:dash:utc:http-xsdate:2012": case "urn:mpeg:dash:utc:http-iso:2012": t.method = "GET"; break; case "urn:mpeg:dash:utc:direct:2014": case "urn:mpeg:dash:utc:direct:2012": t.method = "DIRECT", t.value = Date.parse(t.value); break; case "urn:mpeg:dash:utc:http-ntp:2014": case "urn:mpeg:dash:utc:ntp:2014": case "urn:mpeg:dash:utc:sntp:2014": default: throw new Error(ps.UNSUPPORTED_UTC_TIMING_SCHEME); } return t; }, Bg = (s, e = {}) => { const t = Mg(Bc(s), e), i = Sg(t.representationInfo); return pg({ dashPlaylists: i, locations: t.locations, contentSteering: t.contentSteeringInfo, sidxMapping: e.sidxMapping, previousManifest: e.previousManifest, eventStream: t.eventStream }); }, Fg = (s) => Ng(Bc(s)); var wa, xl; function Ug() { if (xl) return wa; xl = 1; var s = Math.pow(2, 32), e = function(t) { var i = new DataView(t.buffer, t.byteOffset, t.byteLength), r; return i.getBigUint64 ? (r = i.getBigUint64(0), r < Number.MAX_SAFE_INTEGER ? Number(r) : r) : i.getUint32(0) * s + i.getUint32(4); }; return wa = { getUint64: e, MAX_UINT32: s }, wa; } var Ia, Sl; function qg() { if (Sl) return Ia; Sl = 1; var s = Ug().getUint64, e = function(t) { var i = new DataView(t.buffer, t.byteOffset, t.byteLength), r = { version: t[0], flags: new Uint8Array(t.subarray(1, 4)), references: [], referenceId: i.getUint32(4), timescale: i.getUint32(8) }, n = 12; r.version === 0 ? (r.earliestPresentationTime = i.getUint32(n), r.firstOffset = i.getUint32(n + 4), n += 8) : (r.earliestPresentationTime = s(t.subarray(n)), r.firstOffset = s(t.subarray(n + 8)), n += 16), n += 2; var a = i.getUint16(n); for (n += 2; a > 0; n += 12, a--) r.references.push({ referenceType: (t[n] & 128) >>> 7, referencedSize: i.getUint32(n) & 2147483647, subsegmentDuration: i.getUint32(n + 4), startsWithSap: !!(t[n + 8] & 128), sapType: (t[n + 8] & 112) >>> 4, sapDeltaTime: i.getUint32(n + 8) & 268435455 }); return r; }; return Ia = e, Ia; } var $g = /* @__PURE__ */ qg(); const jg = /* @__PURE__ */ hr($g); var Hg = le([73, 68, 51]), Vg = function(e, t) { t === void 0 && (t = 0), e = le(e); var i = e[t + 5], r = e[t + 6] << 21 | e[t + 7] << 14 | e[t + 8] << 7 | e[t + 9], n = (i & 16) >> 4; return n ? r + 20 : r + 10; }, Zs = function s(e, t) { return t === void 0 && (t = 0), e = le(e), e.length - t < 10 || !Pe(e, Hg, { offset: t }) ? t : (t += Vg(e, t), s(e, t)); }, El = function(e) { return typeof e == "string" ? kc(e) : e; }, zg = function(e) { return Array.isArray(e) ? e.map(function(t) { return El(t); }) : [El(e)]; }, Gg = function s(e, t, i) { i === void 0 && (i = false), t = zg(t), e = le(e); var r = []; if (!t.length) return r; for (var n = 0; n < e.length; ) { var a = (e[n] << 24 | e[n + 1] << 16 | e[n + 2] << 8 | e[n + 3]) >>> 0, u = e.subarray(n + 4, n + 8); if (a === 0) break; var c = n + a; if (c > e.length) { if (i) break; c = e.length; } var f = e.subarray(n + 8, c); Pe(u, t[0]) && (t.length === 1 ? r.push(f) : r.push.apply(r, s(f, t.slice(1), i))), n = c; } return r; }, Xr = { EBML: le([26, 69, 223, 163]), DocType: le([66, 130]), Segment: le([24, 83, 128, 103]), SegmentInfo: le([21, 73, 169, 102]), Tracks: le([22, 84, 174, 107]), Track: le([174]), TrackNumber: le([215]), DefaultDuration: le([35, 227, 131]), TrackEntry: le([174]), TrackType: le([131]), FlagDefault: le([136]), CodecID: le([134]), CodecPrivate: le([99, 162]), VideoTrack: le([224]), AudioTrack: le([225]), // Not used yet, but will be used for live webm/mkv // see https://www.matroska.org/technical/basics.html#block-structure // see https://www.matroska.org/technical/basics.html#simpleblock-structure Cluster: le([31, 67, 182, 117]), Timestamp: le([231]), TimestampScale: le([42, 215, 177]), BlockGroup: le([160]), BlockDuration: le([155]), Block: le([161]), SimpleBlock: le([163]) }, Wa = [128, 64, 32, 16, 8, 4, 2, 1], Wg = function(e) { for (var t = 1, i = 0; i < Wa.length && !(e & Wa[i]); i++) t++; return t; }, an = function(e, t, i, r) { i === void 0 && (i = true), r === void 0 && (r = false); var n = Wg(e[t]), a = e.subarray(t, t + n); return i && (a = Array.prototype.slice.call(e, t, t + n), a[0] ^= Wa[n - 1]), { length: n, value: Bm(a, { signed: r }), bytes: a }; }, Cl = function s(e) { return typeof e == "string" ? e.match(/.{1,2}/g).map(function(t) { return s(t); }) : typeof e == "number" ? Fm(e) : e; }, Xg = function(e) { return Array.isArray(e) ? e.map(function(t) { return Cl(t); }) : [Cl(e)]; }, Kg = function s(e, t, i) { if (i >= t.length) return t.length; var r = an(t, i, false); if (Pe(e.bytes, r.bytes)) return i; var n = an(t, i + r.length); return s(e, t, i + n.length + n.value + r.length); }, Al = function s(e, t) { t = Xg(t), e = le(e); var i = []; if (!t.length) return i; for (var r = 0; r < e.length; ) { var n = an(e, r, false), a = an(e, r + n.length), u = r + n.length + a.length; a.value === 127 && (a.value = Kg(n, e, u), a.value !== e.length && (a.value -= u)); var c = u + a.value > e.length ? e.length : u + a.value, f = e.subarray(u, c); Pe(t[0], n.bytes) && (t.length === 1 ? i.push(f) : i = i.concat(s(f, t.slice(1)))); var g = n.length + a.length + f.length; r += g; } return i; }, Qg = le([0, 0, 0, 1]), Yg = le([0, 0, 1]), Jg = le([0, 0, 3]), Zg = function(e) { for (var t = [], i = 1; i < e.length - 2; ) Pe(e.subarray(i, i + 3), Jg) && (t.push(i + 2), i++), i++; if (t.length === 0) return e; var r = e.length - t.length, n = new Uint8Array(r), a = 0; for (i = 0; i < r; a++, i++) a === t[0] && (a++, t.shift()), n[i] = e[a]; return n; }, Fc = function(e, t, i, r) { e = le(e), i = [].concat(i); for (var n = 0, a, u = 0; n < e.length && (u < r || a); ) { var c = void 0; if (Pe(e.subarray(n), Qg) ? c = 4 : Pe(e.subarray(n), Yg) && (c = 3), !c) { n++; continue; } if (u++, a) return Zg(e.subarray(a, n)); var f = void 0; t === "h264" ? f = e[n + c] & 31 : t === "h265" && (f = e[n + c] >> 1 & 63), i.indexOf(f) !== -1 && (a = n + c), n += c + (t === "h264" ? 1 : 2); } return e.subarray(0, 0); }, e0 = function(e, t, i) { return Fc(e, "h264", t, i); }, t0 = function(e, t, i) { return Fc(e, "h265", t, i); }, ot = { // "webm" string literal in hex webm: le([119, 101, 98, 109]), // "matroska" string literal in hex matroska: le([109, 97, 116, 114, 111, 115, 107, 97]), // "fLaC" string literal in hex flac: le([102, 76, 97, 67]), // "OggS" string literal in hex ogg: le([79, 103, 103, 83]), // ac-3 sync byte, also works for ec-3 as that is simply a codec // of ac-3 ac3: le([11, 119]), // "RIFF" string literal in hex used for wav and avi riff: le([82, 73, 70, 70]), // "AVI" string literal in hex avi: le([65, 86, 73]), // "WAVE" string literal in hex wav: le([87, 65, 86, 69]), // "ftyp3g" string literal in hex "3gp": le([102, 116, 121, 112, 51, 103]), // "ftyp" string literal in hex mp4: le([102, 116, 121, 112]), // "styp" string literal in hex fmp4: le([115, 116, 121, 112]), // "ftypqt" string literal in hex mov: le([102, 116, 121, 112, 113, 116]), // moov string literal in hex moov: le([109, 111, 111, 118]), // moof string literal in hex moof: le([109, 111, 111, 102]) }, ms = { aac: function(e) { var t = Zs(e); return Pe(e, [255, 16], { offset: t, mask: [255, 22] }); }, mp3: function(e) { var t = Zs(e); return Pe(e, [255, 2], { offset: t, mask: [255, 6] }); }, webm: function(e) { var t = Al(e, [Xr.EBML, Xr.DocType])[0]; return Pe(t, ot.webm); }, mkv: function(e) { var t = Al(e, [Xr.EBML, Xr.DocType])[0]; return Pe(t, ot.matroska); }, mp4: function(e) { if (ms["3gp"](e) || ms.mov(e)) return false; if (Pe(e, ot.mp4, { offset: 4 }) || Pe(e, ot.fmp4, { offset: 4 }) || Pe(e, ot.moof, { offset: 4 }) || Pe(e, ot.moov, { offset: 4 })) return true; }, mov: function(e) { return Pe(e, ot.mov, { offset: 4 }); }, "3gp": function(e) { return Pe(e, ot["3gp"], { offset: 4 }); }, ac3: function(e) { var t = Zs(e); return Pe(e, ot.ac3, { offset: t }); }, ts: function(e) { if (e.length < 189 && e.length >= 1) return e[0] === 71; for (var t = 0; t + 188 < e.length && t < 188; ) { if (e[t] === 71 && e[t + 188] === 71) return true; t += 1; } return false; }, flac: function(e) { var t = Zs(e); return Pe(e, ot.flac, { offset: t }); }, ogg: function(e) { return Pe(e, ot.ogg); }, avi: function(e) { return Pe(e, ot.riff) && Pe(e, ot.avi, { offset: 8 }); }, wav: function(e) { return Pe(e, ot.riff) && Pe(e, ot.wav, { offset: 8 }); }, h264: function(e) { return e0(e, 7, 3).length; }, h265: function(e) { return t0(e, [32, 33], 3).length; } }, Xa = Object.keys(ms).filter(function(s) { return s !== "ts" && s !== "h264" && s !== "h265"; }).concat(["ts", "h264", "h265"]); Xa.forEach(function(s) { var e = ms[s]; ms[s] = function(t) { return e(le(t)); }; }); var i0 = ms, Co = function(e) { e = le(e); for (var t = 0; t < Xa.length; t++) { var i = Xa[t]; if (i0[i](e)) return i; } return ""; }, s0 = function(e) { return Gg(e, ["moof"]).length > 0; }, ka, Dl; function r0() { if (Dl) return ka; Dl = 1; var s = 9e4, e, t, i, r, n, a, u; return e = function(c) { return c * s; }, t = function(c, f) { return c * f; }, i = function(c) { return c / s; }, r = function(c, f) { return c / f; }, n = function(c, f) { return e(r(c, f)); }, a = function(c, f) { return t(i(c), f); }, u = function(c, f, g) { return i(g ? c : c - f); }, ka = { ONE_SECOND_IN_TS: s, secondsToVideoTs: e, secondsToAudioTs: t, videoTsToSeconds: i, audioTsToSeconds: r, audioTsToVideoTs: n, videoTsToAudioTs: a, metadataTsToSeconds: u }, ka; } var Bi = /* @__PURE__ */ r0(); /** * @license * Video.js 8.21.0 * Copyright Brightcove, Inc. * Available under Apache License Version 2.0 * * * Includes vtt.js * Available under Apache License Version 2.0 * */ var Ka = "8.21.0"; const ri = {}, bi = function(s, e) { return ri[s] = ri[s] || [], e && (ri[s] = ri[s].concat(e)), ri[s]; }, n0 = function(s, e) { bi(s, e); }, Uc = function(s, e) { const t = bi(s).indexOf(e); return t <= -1 ? false : (ri[s] = ri[s].slice(), ri[s].splice(t, 1), true); }, a0 = function(s, e) { bi(s, [].concat(e).map((t) => { const i = (...r) => (Uc(s, i), t(...r)); return i; })); }, on = { prefixed: true }, en = [ ["requestFullscreen", "exitFullscreen", "fullscreenElement", "fullscreenEnabled", "fullscreenchange", "fullscreenerror", "fullscreen"], // WebKit ["webkitRequestFullscreen", "webkitExitFullscreen", "webkitFullscreenElement", "webkitFullscreenEnabled", "webkitfullscreenchange", "webkitfullscreenerror", "-webkit-full-screen"] ], wl = en[0]; let er; for (let s = 0; s < en.length; s++) if (en[s][1] in se) { er = en[s]; break; } if (er) { for (let s = 0; s < er.length; s++) on[wl[s]] = er[s]; on.prefixed = er[0] !== wl[0]; } let dt = []; const o0 = (s, e, t) => (i, r, n) => { const a = e.levels[r], u = new RegExp(`^(${a})$`); let c = s; if (i !== "log" && n.unshift(i.toUpperCase() + ":"), t && (c = `%c${s}`, n.unshift(t)), n.unshift(c + ":"), dt) { dt.push([].concat(n)); const g = dt.length - 1e3; dt.splice(0, g > 0 ? g : 0); } if (!D.console) return; let f = D.console[i]; !f && i === "debug" && (f = D.console.info || D.console.log), !(!f || !a || !u.test(i)) && f[Array.isArray(n) ? "apply" : "call"](D.console, n); }; function Qa(s, e = ":", t = "") { let i = "info", r; function n(...a) { r("log", i, a); } return r = o0(s, n, t), n.createLogger = (a, u, c) => { const f = u !== void 0 ? u : e, g = c !== void 0 ? c : t, y = `${s} ${f} ${a}`; return Qa(y, f, g); }, n.createNewLogger = (a, u, c) => Qa(a, u, c), n.levels = { all: "debug|log|warn|error", off: "", debug: "debug|log|warn|error", info: "log|warn|error", warn: "warn|error", error: "error", DEFAULT: i }, n.level = (a) => { if (typeof a == "string") { if (!n.levels.hasOwnProperty(a)) throw new Error(`"${a}" in not a valid log level`); i = a; } return i; }, n.history = () => dt ? [].concat(dt) : [], n.history.filter = (a) => (dt || []).filter((u) => new RegExp(`.*${a}.*`).test(u[0])), n.history.clear = () => { dt && (dt.length = 0); }, n.history.disable = () => { dt !== null && (dt.length = 0, dt = null); }, n.history.enable = () => { dt === null && (dt = []); }, n.error = (...a) => r("error", i, a), n.warn = (...a) => r("warn", i, a), n.debug = (...a) => r("debug", i, a), n; } const ye = Qa("VIDEOJS"), qc = ye.createLogger, u0 = Object.prototype.toString, $c = function(s) { return Kt(s) ? Object.keys(s) : []; }; function rs(s, e) { $c(s).forEach((t) => e(s[t], t)); } function jc(s, e, t = 0) { return $c(s).reduce((i, r) => e(i, s[r], r), t); } function Kt(s) { return !!s && typeof s == "object"; } function gs(s) { return Kt(s) && u0.call(s) === "[object Object]" && s.constructor === Object; } function Ce(...s) { const e = {}; return s.forEach((t) => { t && rs(t, (i, r) => { if (!gs(i)) { e[r] = i; return; } gs(e[r]) || (e[r] = {}), e[r] = Ce(e[r], i); }); }), e; } function Hc(s = {}) { const e = []; for (const t in s) if (s.hasOwnProperty(t)) { const i = s[t]; e.push(i); } return e; } function Rn(s, e, t, i = true) { const r = (a) => Object.defineProperty(s, e, { value: a, enumerable: true, writable: true }), n = { configurable: true, enumerable: true, get() { const a = t(); return r(a), a; } }; return i && (n.set = r), Object.defineProperty(s, e, n); } var l0 = /* @__PURE__ */ Object.freeze({ __proto__: null, each: rs, reduce: jc, isObject: Kt, isPlain: gs, merge: Ce, values: Hc, defineLazyProperty: Rn }); let Ao = false, Vc = null, Bt = false, zc, Gc = false, ns = false, as = false, Qt = false, Do = null, Mn = null; const c0 = !!(D.cast && D.cast.framework && D.cast.framework.CastReceiverContext); let Wc = null, un = false, Nn = false, ln = false, Bn = false, cn = false, dn = false, hn = false; const lr = !!(xs() && ("ontouchstart" in D || D.navigator.maxTouchPoints || D.DocumentTouch && D.document instanceof D.DocumentTouch)), gi = D.navigator && D.navigator.userAgentData; gi && gi.platform && gi.brands && (Bt = gi.platform === "Android", ns = !!gi.brands.find((s) => s.brand === "Microsoft Edge"), as = !!gi.brands.find((s) => s.brand === "Chromium"), Qt = !ns && as, Do = Mn = (gi.brands.find((s) => s.brand === "Chromium") || {}).version || null, Nn = gi.platform === "Windows"); if (!as) { const s = D.navigator && D.navigator.userAgent || ""; Ao = /iPod/i.test(s), Vc = function() { const e = s.match(/OS (\d+)_/i); return e && e[1] ? e[1] : null; }(), Bt = /Android/i.test(s), zc = function() { const e = s.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i); if (!e) return null; const t = e[1] && parseFloat(e[1]), i = e[2] && parseFloat(e[2]); return t && i ? parseFloat(e[1] + "." + e[2]) : t || null; }(), Gc = /Firefox/i.test(s), ns = /Edg/i.test(s), as = /Chrome/i.test(s) || /CriOS/i.test(s), Qt = !ns && as, Do = Mn = function() { const e = s.match(/(Chrome|CriOS)\/(\d+)/); return e && e[2] ? parseFloat(e[2]) : null; }(), Wc = function() { const e = /MSIE\s(\d+)\.\d/.exec(s); let t = e && parseFloat(e[1]); return !t && /Trident\/7.0/i.test(s) && /rv:11.0/.test(s) && (t = 11), t; }(), cn = /Tizen/i.test(s), dn = /Web0S/i.test(s), hn = cn || dn, un = /Safari/i.test(s) && !Qt && !Bt && !ns && !hn, Nn = /Windows/i.test(s), ln = /iPad/i.test(s) || un && lr && !/iPhone/i.test(s), Bn = /iPhone/i.test(s) && !ln; } const tt = Bn || ln || Ao, Fn = (un || tt) && !Qt; var Xc = /* @__PURE__ */ Object.freeze({ __proto__: null, get IS_IPOD() { return Ao; }, get IOS_VERSION() { return Vc; }, get IS_ANDROID() { return Bt; }, get ANDROID_VERSION() { return zc; }, get IS_FIREFOX() { return Gc; }, get IS_EDGE() { return ns; }, get IS_CHROMIUM() { return as; }, get IS_CHROME() { return Qt; }, get CHROMIUM_VERSION() { return Do; }, get CHROME_VERSION() { return Mn; }, IS_CHROMECAST_RECEIVER: c0, get IE_VERSION() { return Wc; }, get IS_SAFARI() { return un; }, get IS_WINDOWS() { return Nn; }, get IS_IPAD() { return ln; }, get IS_IPHONE() { return Bn; }, get IS_TIZEN() { return cn; }, get IS_WEBOS() { return dn; }, get IS_SMART_TV() { return hn; }, TOUCH_ENABLED: lr, IS_IOS: tt, IS_ANY_SAFARI: Fn }); function Il(s) { return typeof s == "string" && !!s.trim(); } function d0(s) { if (s.indexOf(" ") >= 0) throw new Error("class has illegal whitespace characters"); } function xs() { return se === D.document; } function Ss(s) { return Kt(s) && s.nodeType === 1; } function Kc() { try { return D.parent !== D.self; } catch { return true; } } function Qc(s) { return function(e, t) { if (!Il(e)) return se[s](null); Il(t) && (t = se.querySelector(t)); const i = Ss(t) ? t : se; return i[s] && i[s](e); }; } function ce(s = "div", e = {}, t = {}, i) { const r = se.createElement(s); return Object.getOwnPropertyNames(e).forEach(function(n) { const a = e[n]; n === "textContent" ? Si(r, a) : (r[n] !== a || n === "tabIndex") && (r[n] = a); }), Object.getOwnPropertyNames(t).forEach(function(n) { r.setAttribute(n, t[n]); }), i && wo(r, i), r; } function Si(s, e) { return typeof s.textContent > "u" ? s.innerText = e : s.textContent = e, s; } function Ya(s, e) { e.firstChild ? e.insertBefore(s, e.firstChild) : e.appendChild(s); } function sr(s, e) { return d0(e), s.classList.contains(e); } function $i(s, ...e) { return s.classList.add(...e.reduce((t, i) => t.concat(i.split(/\s+/)), [])), s; } function Un(s, ...e) { return s ? (s.classList.remove(...e.reduce((t, i) => t.concat(i.split(/\s+/)), [])), s) : (ye.warn("removeClass was called with an element that doesn't exist"), null); } function Yc(s, e, t) { return typeof t == "function" && (t = t(s, e)), typeof t != "boolean" && (t = void 0), e.split(/\s+/).forEach((i) => s.classList.toggle(i, t)), s; } function Jc(s, e) { Object.getOwnPropertyNames(e).forEach(function(t) { const i = e[t]; i === null || typeof i > "u" || i === false ? s.removeAttribute(t) : s.setAttribute(t, i === true ? "" : i); }); } function Ti(s) { const e = {}, t = ["autoplay", "controls", "playsinline", "loop", "muted", "default", "defaultMuted"]; if (s && s.attributes && s.attributes.length > 0) { const i = s.attributes; for (let r = i.length - 1; r >= 0; r--) { const n = i[r].name; let a = i[r].value; t.includes(n) && (a = a !== null), e[n] = a; } } return e; } function Zc(s, e) { return s.getAttribute(e); } function _s(s, e, t) { s.setAttribute(e, t); } function qn(s, e) { s.removeAttribute(e); } function ed() { se.body.focus(), se.onselectstart = function() { return false; }; } function td() { se.onselectstart = function() { return true; }; } function ys(s) { if (s && s.getBoundingClientRect && s.parentNode) { const e = s.getBoundingClientRect(), t = {}; return ["bottom", "height", "left", "right", "top", "width"].forEach((i) => { e[i] !== void 0 && (t[i] = e[i]); }), t.height || (t.height = parseFloat(Ts(s, "height"))), t.width || (t.width = parseFloat(Ts(s, "width"))), t; } } function cr(s) { if (!s || s && !s.offsetParent) return { left: 0, top: 0, width: 0, height: 0 }; const e = s.offsetWidth, t = s.offsetHeight; let i = 0, r = 0; for (; s.offsetParent && s !== se[on.fullscreenElement]; ) i += s.offsetLeft, r += s.offsetTop, s = s.offsetParent; return { left: i, top: r, width: e, height: t }; } function $n(s, e) { const t = { x: 0, y: 0 }; if (tt) { let g = s; for (; g && g.nodeName.toLowerCase() !== "html"; ) { const y = Ts(g, "transform"); if (/^matrix/.test(y)) { const I = y.slice(7, -1).split(/,\s/).map(Number); t.x += I[4], t.y += I[5]; } else if (/^matrix3d/.test(y)) { const I = y.slice(9, -1).split(/,\s/).map(Number); t.x += I[12], t.y += I[13]; } if (g.assignedSlot && g.assignedSlot.parentElement && D.WebKitCSSMatrix) { const I = D.getComputedStyle(g.assignedSlot.parentElement).transform, C = new D.WebKitCSSMatrix(I); t.x += C.m41, t.y += C.m42; } g = g.parentNode || g.host; } } const i = {}, r = cr(e.target), n = cr(s), a = n.width, u = n.height; let c = e.offsetY - (n.top - r.top), f = e.offsetX - (n.left - r.left); return e.changedTouches && (f = e.changedTouches[0].pageX - n.left, c = e.changedTouches[0].pageY + n.top, tt && (f -= t.x, c -= t.y)), i.y = 1 - Math.max(0, Math.min(1, c / u)), i.x = Math.max(0, Math.min(1, f / a)), i; } function id(s) { return Kt(s) && s.nodeType === 3; } function jn(s) { for (; s.firstChild; ) s.removeChild(s.firstChild); return s; } function sd(s) { return typeof s == "function" && (s = s()), (Array.isArray(s) ? s : [s]).map((e) => { if (typeof e == "function" && (e = e()), Ss(e) || id(e)) return e; if (typeof e == "string" && /\S/.test(e)) return se.createTextNode(e); }).filter((e) => e); } function wo(s, e) { return sd(e).forEach((t) => s.appendChild(t)), s; } function rd(s, e) { return wo(jn(s), e); } function dr(s) { return s.button === void 0 && s.buttons === void 0 || s.button === 0 && s.buttons === void 0 || s.type === "mouseup" && s.button === 0 && s.buttons === 0 || s.type === "mousedown" && s.button === 0 && s.buttons === 0 ? true : !(s.button !== 0 || s.buttons !== 1); } const xi = Qc("querySelector"), nd = Qc("querySelectorAll"); function Ts(s, e) { if (!s || !e) return ""; if (typeof D.getComputedStyle == "function") { let t; try { t = D.getComputedStyle(s); } catch { return ""; } return t ? t.getPropertyValue(e) || t[e] : ""; } return ""; } function ad(s) { [...se.styleSheets].forEach((e) => { try { const t = [...e.cssRules].map((r) => r.cssText).join(""), i = se.createElement("style"); i.textContent = t, s.document.head.appendChild(i); } catch { const i = se.createElement("link"); i.rel = "stylesheet", i.type = e.type, i.media = e.media.mediaText, i.href = e.href, s.document.head.appendChild(i); } }); } var od = /* @__PURE__ */ Object.freeze({ __proto__: null, isReal: xs, isEl: Ss, isInFrame: Kc, createEl: ce, textContent: Si, prependTo: Ya, hasClass: sr, addClass: $i, removeClass: Un, toggleClass: Yc, setAttributes: Jc, getAttributes: Ti, getAttribute: Zc, setAttribute: _s, removeAttribute: qn, blockTextSelection: ed, unblockTextSelection: td, getBoundingClientRect: ys, findPosition: cr, getPointerPosition: $n, isTextNode: id, emptyEl: jn, normalizeContent: sd, appendContent: wo, insertContent: rd, isSingleLeftClick: dr, $: xi, $$: nd, computedStyle: Ts, copyStyleSheetsToWindow: ad }); let ud = false, Ja; const h0 = function() { if (Ja.options.autoSetup === false) return; const s = Array.prototype.slice.call(se.getElementsByTagName("video")), e = Array.prototype.slice.call(se.getElementsByTagName("audio")), t = Array.prototype.slice.call(se.getElementsByTagName("video-js")), i = s.concat(e, t); if (i && i.length > 0) for (let r = 0, n = i.length; r < n; r++) { const a = i[r]; if (a && a.getAttribute) a.player === void 0 && a.getAttribute("data-setup") !== null && Ja(a); else { Za(1); break; } } else ud || Za(1); }; function Za(s, e) { xs() && (e && (Ja = e), D.setTimeout(h0, s)); } function eo() { ud = true, D.removeEventListener("load", eo); } xs() && (se.readyState === "complete" ? eo() : D.addEventListener("load", eo)); const ld = function(s) { const e = se.createElement("style"); return e.className = s, e; }, cd = function(s, e) { s.styleSheet ? s.styleSheet.cssText = e : s.textContent = e; }; var lt = /* @__PURE__ */ new WeakMap(); const f0 = 3; let p0 = f0; function At() { return p0++; } function kl(s, e) { if (!lt.has(s)) return; const t = lt.get(s); t.handlers[e].length === 0 && (delete t.handlers[e], s.removeEventListener ? s.removeEventListener(e, t.dispatcher, false) : s.detachEvent && s.detachEvent("on" + e, t.dispatcher)), Object.getOwnPropertyNames(t.handlers).length <= 0 && (delete t.handlers, delete t.dispatcher, delete t.disabled), Object.getOwnPropertyNames(t).length === 0 && lt.delete(s); } function Io(s, e, t, i) { t.forEach(function(r) { s(e, r, i); }); } function Hn(s) { if (s.fixed_) return s; function e() { return true; } function t() { return false; } if (!s || !s.isPropagationStopped || !s.isImmediatePropagationStopped) { const i = s || D.event; s = {}; const r = ["layerX", "layerY", "keyLocation", "path", "webkitMovementX", "webkitMovementY", "mozPressure", "mozInputSource"]; for (const n in i) r.includes(n) || n === "returnValue" && i.preventDefault || (s[n] = i[n]); if (s.target || (s.target = s.srcElement || se), s.relatedTarget || (s.relatedTarget = s.fromElement === s.target ? s.toElement : s.fromElement), s.preventDefault = function() { i.preventDefault && i.preventDefault(), s.returnValue = false, i.returnValue = false, s.defaultPrevented = true; }, s.defaultPrevented = false, s.stopPropagation = function() { i.stopPropagation && i.stopPropagation(), s.cancelBubble = true, i.cancelBubble = true, s.isPropagationStopped = e; }, s.isPropagationStopped = t, s.stopImmediatePropagation = function() { i.stopImmediatePropagation && i.stopImmediatePropagation(), s.isImmediatePropagationStopped = e, s.stopPropagation(); }, s.isImmediatePropagationStopped = t, s.clientX !== null && s.clientX !== void 0) { const n = se.documentElement, a = se.body; s.pageX = s.clientX + (n && n.scrollLeft || a && a.scrollLeft || 0) - (n && n.clientLeft || a && a.clientLeft || 0), s.pageY = s.clientY + (n && n.scrollTop || a && a.scrollTop || 0) - (n && n.clientTop || a && a.clientTop || 0); } s.which = s.charCode || s.keyCode, s.button !== null && s.button !== void 0 && (s.button = s.button & 1 ? 0 : s.button & 4 ? 1 : s.button & 2 ? 2 : 0); } return s.fixed_ = true, s; } let Kr; const m0 = function() { if (typeof Kr != "boolean") { Kr = false; try { const s = Object.defineProperty({}, "passive", { get() { Kr = !0; } }); D.addEventListener("test", null, s), D.removeEventListener("test", null, s); } catch { } } return Kr; }, g0 = ["touchstart", "touchmove"]; function yt(s, e, t) { if (Array.isArray(e)) return Io(yt, s, e, t); lt.has(s) || lt.set(s, {}); const i = lt.get(s); if (i.handlers || (i.handlers = {}), i.handlers[e] || (i.handlers[e] = []), t.guid || (t.guid = At()), i.handlers[e].push(t), i.dispatcher || (i.disabled = false, i.dispatcher = function(r, n) { if (i.disabled) return; r = Hn(r); const a = i.handlers[r.type]; if (a) { const u = a.slice(0); for (let c = 0, f = u.length; c < f && !r.isImmediatePropagationStopped(); c++) try { u[c].call(s, r, n); } catch (g) { ye.error(g); } } }), i.handlers[e].length === 1) if (s.addEventListener) { let r = false; m0() && g0.indexOf(e) > -1 && (r = { passive: true }), s.addEventListener(e, i.dispatcher, r); } else s.attachEvent && s.attachEvent("on" + e, i.dispatcher); } function it(s, e, t) { if (!lt.has(s)) return; const i = lt.get(s); if (!i.handlers) return; if (Array.isArray(e)) return Io(it, s, e, t); const r = function(a, u) { i.handlers[u] = [], kl(a, u); }; if (e === void 0) { for (const a in i.handlers) Object.prototype.hasOwnProperty.call(i.handlers || {}, a) && r(s, a); return; } const n = i.handlers[e]; if (n) { if (!t) { r(s, e); return; } if (t.guid) for (let a = 0; a < n.length; a++) n[a].guid === t.guid && n.splice(a--, 1); kl(s, e); } } function Es(s, e, t) { const i = lt.has(s) ? lt.get(s) : {}, r = s.parentNode || s.ownerDocument; if (typeof e == "string" ? e = { type: e, target: s } : e.target || (e.target = s), e = Hn(e), i.dispatcher && i.dispatcher.call(s, e, t), r && !e.isPropagationStopped() && e.bubbles === true) Es.call(null, r, e, t); else if (!r && !e.defaultPrevented && e.target && e.target[e.type]) { lt.has(e.target) || lt.set(e.target, {}); const n = lt.get(e.target); e.target[e.type] && (n.disabled = true, typeof e.target[e.type] == "function" && e.target[e.type](), n.disabled = false); } return !e.defaultPrevented; } function Vn(s, e, t) { if (Array.isArray(e)) return Io(Vn, s, e, t); const i = function() { it(s, e, i), t.apply(this, arguments); }; i.guid = t.guid = t.guid || At(), yt(s, e, i); } function ko(s, e, t) { const i = function() { it(s, e, i), t.apply(this, arguments); }; i.guid = t.guid = t.guid || At(), yt(s, e, i); } var _0 = /* @__PURE__ */ Object.freeze({ __proto__: null, fixEvent: Hn, on: yt, off: it, trigger: Es, one: Vn, any: ko }); const Dt = 30, De = function(s, e, t) { e.guid || (e.guid = At()); const i = e.bind(s); return i.guid = t ? t + "_" + e.guid : e.guid, i; }, Yt = function(s, e) { let t = D.performance.now(); return function(...r) { const n = D.performance.now(); n - t >= e && (s(...r), t = n); }; }, dd = function(s, e, t, i = D) { let r; const n = () => { i.clearTimeout(r), r = null; }, a = function() { const u = this, c = arguments; let f = function() { r = null, f = null, t || s.apply(u, c); }; !r && t && s.apply(u, c), i.clearTimeout(r), r = i.setTimeout(f, e); }; return a.cancel = n, a; }; var y0 = /* @__PURE__ */ Object.freeze({ __proto__: null, UPDATE_REFRESH_INTERVAL: Dt, bind_: De, throttle: Yt, debounce: dd }); let Qs; class Tt { /** * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a * function that will get called when an event with a certain name gets triggered. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to call with `EventTarget`s */ on(e, t) { const i = this.addEventListener; this.addEventListener = () => { }, yt(this, e, t), this.addEventListener = i; } /** * Removes an `event listener` for a specific event from an instance of `EventTarget`. * This makes it so that the `event listener` will no longer get called when the * named event happens. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to remove. */ off(e, t) { it(this, e, t); } /** * This function will add an `event listener` that gets triggered only once. After the * first trigger it will get removed. This is like adding an `event listener` * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to be called once for each event name. */ one(e, t) { const i = this.addEventListener; this.addEventListener = () => { }, Vn(this, e, t), this.addEventListener = i; } /** * This function will add an `event listener` that gets triggered only once and is * removed from all events. This is like adding an array of `event listener`s * with {@link EventTarget#on} that calls {@link EventTarget#off} on all events the * first time it is triggered. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to be called once for each event name. */ any(e, t) { const i = this.addEventListener; this.addEventListener = () => { }, ko(this, e, t), this.addEventListener = i; } /** * This function causes an event to happen. This will then cause any `event listeners` * that are waiting for that event, to get called. If there are no `event listeners` * for an event then nothing will happen. * * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`. * Trigger will also call the `on` + `uppercaseEventName` function. * * Example: * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call * `onClick` if it exists. * * @param {string|EventTarget~Event|Object} event * The name of the event, an `Event`, or an object with a key of type set to * an event name. */ trigger(e) { const t = e.type || e; typeof e == "string" && (e = { type: t }), e = Hn(e), this.allowedEvents_[t] && this["on" + t] && this["on" + t](e), Es(this, e); } queueTrigger(e) { Qs || (Qs = /* @__PURE__ */ new Map()); const t = e.type || e; let i = Qs.get(this); i || (i = /* @__PURE__ */ new Map(), Qs.set(this, i)); const r = i.get(t); i.delete(t), D.clearTimeout(r); const n = D.setTimeout(() => { i.delete(t), i.size === 0 && (i = null, Qs.delete(this)), this.trigger(e); }, 0); i.set(t, n); } } Tt.prototype.allowedEvents_ = {}; Tt.prototype.addEventListener = Tt.prototype.on; Tt.prototype.removeEventListener = Tt.prototype.off; Tt.prototype.dispatchEvent = Tt.prototype.trigger; const zn = (s) => typeof s.name == "function" ? s.name() : typeof s.name == "string" ? s.name : s.name_ ? s.name_ : s.constructor && s.constructor.name ? s.constructor.name : typeof s, oi = (s) => s instanceof Tt || !!s.eventBusEl_ && ["on", "one", "off", "trigger"].every((e) => typeof s[e] == "function"), T0 = (s, e) => { oi(s) ? e() : (s.eventedCallbacks || (s.eventedCallbacks = []), s.eventedCallbacks.push(e)); }, to = (s) => ( // The regex here verifies that the `type` contains at least one non- // whitespace character. typeof s == "string" && /\S/.test(s) || Array.isArray(s) && !!s.length ), fn = (s, e, t) => { if (!s || !s.nodeName && !oi(s)) throw new Error(`Invalid target for ${zn(e)}#${t}; must be a DOM node or evented object.`); }, hd = (s, e, t) => { if (!to(s)) throw new Error(`Invalid event type for ${zn(e)}#${t}; must be a non-empty string or array.`); }, fd = (s, e, t) => { if (typeof s != "function") throw new Error(`Invalid listener for ${zn(e)}#${t}; must be a function.`); }, Pa = (s, e, t) => { const i = e.length < 3 || e[0] === s || e[0] === s.eventBusEl_; let r, n, a; return i ? (r = s.eventBusEl_, e.length >= 3 && e.shift(), [n, a] = e) : (r = e[0], n = e[1], a = e[2]), fn(r, s, t), hd(n, s, t), fd(a, s, t), a = De(s, a), { isTargetingSelf: i, target: r, type: n, listener: a }; }, Ri = (s, e, t, i) => { fn(s, s, e), s.nodeName ? _0[e](s, t, i) : s[e](t, i); }, v0 = { /** * Add a listener to an event (or events) on this object or another evented * object. * * @param {string|Array|Element|Object} targetOrType * If this is a string or array, it represents the event type(s) * that will trigger the listener. * * Another evented object can be passed here instead, which will * cause the listener to listen for events on _that_ object. * * In either case, the listener's `this` value will be bound to * this object. * * @param {string|Array|Function} typeOrListener * If the first argument was a string or array, this should be the * listener function. Otherwise, this is a string or array of event * type(s). * * @param {Function} [listener] * If the first argument was another evented object, this will be * the listener function. */ on(...s) { const { isTargetingSelf: e, target: t, type: i, listener: r } = Pa(this, s, "on"); if (Ri(t, "on", i, r), !e) { const n = () => this.off(t, i, r); n.guid = r.guid; const a = () => this.off("dispose", n); a.guid = r.guid, Ri(this, "on", "dispose", n), Ri(t, "on", "dispose", a); } }, /** * Add a listener to an event (or events) on this object or another evented * object. The listener will be called once per event and then removed. * * @param {string|Array|Element|Object} targetOrType * If this is a string or array, it represents the event type(s) * that will trigger the listener. * * Another evented object can be passed here instead, which will * cause the listener to listen for events on _that_ object. * * In either case, the listener's `this` value will be bound to * this object. * * @param {string|Array|Function} typeOrListener * If the first argument was a string or array, this should be the * listener function. Otherwise, this is a string or array of event * type(s). * * @param {Function} [listener] * If the first argument was another evented object, this will be * the listener function. */ one(...s) { const { isTargetingSelf: e, target: t, type: i, listener: r } = Pa(this, s, "one"); if (e) Ri(t, "one", i, r); else { const n = (...a) => { this.off(t, i, n), r.apply(null, a); }; n.guid = r.guid, Ri(t, "one", i, n); } }, /** * Add a listener to an event (or events) on this object or another evented * object. The listener will only be called once for the first event that is triggered * then removed. * * @param {string|Array|Element|Object} targetOrType * If this is a string or array, it represents the event type(s) * that will trigger the listener. * * Another evented object can be passed here instead, which will * cause the listener to listen for events on _that_ object. * * In either case, the listener's `this` value will be bound to * this object. * * @param {string|Array|Function} typeOrListener * If the first argument was a string or array, this should be the * listener function. Otherwise, this is a string or array of event * type(s). * * @param {Function} [listener] * If the first argument was another evented object, this will be * the listener function. */ any(...s) { const { isTargetingSelf: e, target: t, type: i, listener: r } = Pa(this, s, "any"); if (e) Ri(t, "any", i, r); else { const n = (...a) => { this.off(t, i, n), r.apply(null, a); }; n.guid = r.guid, Ri(t, "any", i, n); } }, /** * Removes listener(s) from event(s) on an evented object. * * @param {string|Array|Element|Object} [targetOrType] * If this is a string or array, it represents the event type(s). * * Another evented object can be passed here instead, in which case * ALL 3 arguments are _required_. * * @param {string|Array|Function} [typeOrListener] * If the first argument was a string or array, this may be the * listener function. Otherwise, this is a string or array of event * type(s). * * @param {Function} [listener] * If the first argument was another evented object, this will be * the listener function; otherwise, _all_ listeners bound to the * event type(s) will be removed. */ off(s, e, t) { if (!s || to(s)) it(this.eventBusEl_, s, e); else { const i = s, r = e; fn(i, this, "off"), hd(r, this, "off"), fd(t, this, "off"), t = De(this, t), this.off("dispose", t), i.nodeName ? (it(i, r, t), it(i, "dispose", t)) : oi(i) && (i.off(r, t), i.off("dispose", t)); } }, /** * Fire an event on this evented object, causing its listeners to be called. * * @param {string|Object} event * An event type or an object with a type property. * * @param {Object} [hash] * An additional object to pass along to listeners. * * @return {boolean} * Whether or not the default behavior was prevented. */ trigger(s, e) { fn(this.eventBusEl_, this, "trigger"); const t = s && typeof s != "string" ? s.type : s; if (!to(t)) throw new Error(`Invalid event type for ${zn(this)}#trigger; must be a non-empty string or object with a type key that has a non-empty value.`); return Es(this.eventBusEl_, s, e); } }; function Po(s, e = {}) { const { eventBusKey: t } = e; if (t) { if (!s[t].nodeName) throw new Error(`The eventBusKey "${t}" does not refer to an element.`); s.eventBusEl_ = s[t]; } else s.eventBusEl_ = ce("span", { className: "vjs-event-bus" }); return Object.assign(s, v0), s.eventedCallbacks && s.eventedCallbacks.forEach((i) => { i(); }), s.on("dispose", () => { s.off(), [s, s.el_, s.eventBusEl_].forEach(function(i) { i && lt.has(i) && lt.delete(i); }), D.setTimeout(() => { s.eventBusEl_ = null; }, 0); }), s; } const b0 = { /** * A hash containing arbitrary keys and values representing the state of * the object. * * @type {Object} */ state: {}, /** * Set the state of an object by mutating its * {@link module:stateful~StatefulMixin.state|state} object in place. * * @fires module:stateful~StatefulMixin#statechanged * @param {Object|Function} stateUpdates * A new set of properties to shallow-merge into the plugin state. * Can be a plain object or a function returning a plain object. * * @return {Object|undefined} * An object containing changes that occurred. If no changes * occurred, returns `undefined`. */ setState(s) { typeof s == "function" && (s = s()); let e; return rs(s, (t, i) => { this.state[i] !== t && (e = e || {}, e[i] = { from: this.state[i], to: t }), this.state[i] = t; }), e && oi(this) && this.trigger({ changes: e, type: "statechanged" }), e; } }; function pd(s, e) { return Object.assign(s, b0), s.state = Object.assign({}, s.state, e), typeof s.handleStateChanged == "function" && oi(s) && s.on("statechanged", s.handleStateChanged), s; } const rr = function(s) { return typeof s != "string" ? s : s.replace(/./, (e) => e.toLowerCase()); }, Ne = function(s) { return typeof s != "string" ? s : s.replace(/./, (e) => e.toUpperCase()); }, md = function(s, e) { return Ne(s) === Ne(e); }; var x0 = /* @__PURE__ */ Object.freeze({ __proto__: null, toLowerCase: rr, toTitleCase: Ne, titleCaseEquals: md }); let K = class ct { /** * Creates an instance of this class. * * @param {Player} player * The `Player` that this class should be attached to. * * @param {Object} [options] * The key/value store of component options. * * @param {Object[]} [options.children] * An array of children objects to initialize this component with. Children objects have * a name property that will be used if more than one component of the same type needs to be * added. * * @param {string} [options.className] * A class or space separated list of classes to add the component * * @param {ReadyCallback} [ready] * Function that gets called when the `Component` is ready. */ constructor(e, t, i) { if (!e && this.play ? this.player_ = e = this : this.player_ = e, this.isDisposed_ = false, this.parentComponent_ = null, this.options_ = Ce({}, this.options_), t = this.options_ = Ce(this.options_, t), this.id_ = t.id || t.el && t.el.id, !this.id_) { const r = e && e.id && e.id() || "no_player"; this.id_ = `${r}_component_${At()}`; } this.name_ = t.name || null, t.el ? this.el_ = t.el : t.createEl !== false && (this.el_ = this.createEl()), t.className && this.el_ && t.className.split(" ").forEach((r) => this.addClass(r)), ["on", "off", "one", "any", "trigger"].forEach((r) => { this[r] = void 0; }), t.evented !== false && (Po(this, { eventBusKey: this.el_ ? "el_" : null }), this.handleLanguagechange = this.handleLanguagechange.bind(this), this.on(this.player_, "languagechange", this.handleLanguagechange)), pd(this, this.constructor.defaultState), this.children_ = [], this.childIndex_ = {}, this.childNameIndex_ = {}, this.setTimeoutIds_ = /* @__PURE__ */ new Set(), this.setIntervalIds_ = /* @__PURE__ */ new Set(), this.rafIds_ = /* @__PURE__ */ new Set(), this.namedRafs_ = /* @__PURE__ */ new Map(), this.clearingTimersOnDispose_ = false, t.initChildren !== false && this.initChildren(), this.ready(i), t.reportTouchActivity !== false && this.enableTouchActivity(); } // `on`, `off`, `one`, `any` and `trigger` are here so tsc includes them in definitions. // They are replaced or removed in the constructor /** * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a * function that will get called when an event with a certain name gets triggered. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to call with `EventTarget`s */ /** * Removes an `event listener` for a specific event from an instance of `EventTarget`. * This makes it so that the `event listener` will no longer get called when the * named event happens. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} [fn] * The function to remove. If not specified, all listeners managed by Video.js will be removed. */ /** * This function will add an `event listener` that gets triggered only once. After the * first trigger it will get removed. This is like adding an `event listener` * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to be called once for each event name. */ /** * This function will add an `event listener` that gets triggered only once and is * removed from all events. This is like adding an array of `event listener`s * with {@link EventTarget#on} that calls {@link EventTarget#off} on all events the * first time it is triggered. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to be called once for each event name. */ /** * This function causes an event to happen. This will then cause any `event listeners` * that are waiting for that event, to get called. If there are no `event listeners` * for an event then nothing will happen. * * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`. * Trigger will also call the `on` + `uppercaseEventName` function. * * Example: * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call * `onClick` if it exists. * * @param {string|Event|Object} event * The name of the event, an `Event`, or an object with a key of type set to * an event name. * * @param {Object} [hash] * Optionally extra argument to pass through to an event listener */ /** * Dispose of the `Component` and all child components. * * @fires Component#dispose * * @param {Object} options * @param {Element} options.originalEl element with which to replace player element */ dispose(e = {}) { if (!this.isDisposed_) { if (this.readyQueue_ && (this.readyQueue_.length = 0), this.trigger({ type: "dispose", bubbles: false }), this.isDisposed_ = true, this.children_) for (let t = this.children_.length - 1; t >= 0; t--) this.children_[t].dispose && this.children_[t].dispose(); this.children_ = null, this.childIndex_ = null, this.childNameIndex_ = null, this.parentComponent_ = null, this.el_ && (this.el_.parentNode && (e.restoreEl ? this.el_.parentNode.replaceChild(e.restoreEl, this.el_) : this.el_.parentNode.removeChild(this.el_)), this.el_ = null), this.player_ = null; } } /** * Determine whether or not this component has been disposed. * * @return {boolean} * If the component has been disposed, will be `true`. Otherwise, `false`. */ isDisposed() { return !!this.isDisposed_; } /** * Return the {@link Player} that the `Component` has attached to. * * @return {Player} * The player that this `Component` has attached to. */ player() { return this.player_; } /** * Deep merge of options objects with new options. * > Note: When both `obj` and `options` contain properties whose values are objects. * The two properties get merged using {@link module:obj.merge} * * @param {Object} obj * The object that contains new options. * * @return {Object} * A new object of `this.options_` and `obj` merged together. */ options(e) { return e ? (this.options_ = Ce(this.options_, e), this.options_) : this.options_; } /** * Get the `Component`s DOM element * * @return {Element} * The DOM element for this `Component`. */ el() { return this.el_; } /** * Create the `Component`s DOM element. * * @param {string} [tagName] * Element's DOM node type. e.g. 'div' * * @param {Object} [properties] * An object of properties that should be set. * * @param {Object} [attributes] * An object of attributes that should be set. * * @return {Element} * The element that gets created. */ createEl(e, t, i) { return ce(e, t, i); } /** * Localize a string given the string in english. * * If tokens are provided, it'll try and run a simple token replacement on the provided string. * The tokens it looks for look like `{1}` with the index being 1-indexed into the tokens array. * * If a `defaultValue` is provided, it'll use that over `string`, * if a value isn't found in provided language files. * This is useful if you want to have a descriptive key for token replacement * but have a succinct localized string and not require `en.json` to be included. * * Currently, it is used for the progress bar timing. * ```js * { * "progress bar timing: currentTime={1} duration={2}": "{1} of {2}" * } * ``` * It is then used like so: * ```js * this.localize('progress bar timing: currentTime={1} duration{2}', * [this.player_.currentTime(), this.player_.duration()], * '{1} of {2}'); * ``` * * Which outputs something like: `01:23 of 24:56`. * * * @param {string} string * The string to localize and the key to lookup in the language files. * @param {string[]} [tokens] * If the current item has token replacements, provide the tokens here. * @param {string} [defaultValue] * Defaults to `string`. Can be a default value to use for token replacement * if the lookup key is needed to be separate. * * @return {string} * The localized string or if no localization exists the english string. */ localize(e, t, i = e) { const r = this.player_.language && this.player_.language(), n = this.player_.languages && this.player_.languages(), a = n && n[r], u = r && r.split("-")[0], c = n && n[u]; let f = i; return a && a[e] ? f = a[e] : c && c[e] && (f = c[e]), t && (f = f.replace(/\{(\d+)\}/g, function(g, y) { const I = t[y - 1]; let C = I; return typeof I > "u" && (C = g), C; })), f; } /** * Handles language change for the player in components. Should be overridden by sub-components. * * @abstract */ handleLanguagechange() { } /** * Return the `Component`s DOM element. This is where children get inserted. * This will usually be the the same as the element returned in {@link Component#el}. * * @return {Element} * The content element for this `Component`. */ contentEl() { return this.contentEl_ || this.el_; } /** * Get this `Component`s ID * * @return {string} * The id of this `Component` */ id() { return this.id_; } /** * Get the `Component`s name. The name gets used to reference the `Component` * and is set during registration. * * @return {string} * The name of this `Component`. */ name() { return this.name_; } /** * Get an array of all child components * * @return {Array} * The children */ children() { return this.children_; } /** * Returns the child `Component` with the given `id`. * * @param {string} id * The id of the child `Component` to get. * * @return {Component|undefined} * The child `Component` with the given `id` or undefined. */ getChildById(e) { return this.childIndex_[e]; } /** * Returns the child `Component` with the given `name`. * * @param {string} name * The name of the child `Component` to get. * * @return {Component|undefined} * The child `Component` with the given `name` or undefined. */ getChild(e) { if (e) return this.childNameIndex_[e]; } /** * Returns the descendant `Component` following the givent * descendant `names`. For instance ['foo', 'bar', 'baz'] would * try to get 'foo' on the current component, 'bar' on the 'foo' * component and 'baz' on the 'bar' component and return undefined * if any of those don't exist. * * @param {...string[]|...string} names * The name of the child `Component` to get. * * @return {Component|undefined} * The descendant `Component` following the given descendant * `names` or undefined. */ getDescendant(...e) { e = e.reduce((i, r) => i.concat(r), []); let t = this; for (let i = 0; i < e.length; i++) if (t = t.getChild(e[i]), !t || !t.getChild) return; return t; } /** * Adds an SVG icon element to another element or component. * * @param {string} iconName * The name of icon. A list of all the icon names can be found at 'sandbox/svg-icons.html' * * @param {Element} [el=this.el()] * Element to set the title on. Defaults to the current Component's element. * * @return {Element} * The newly created icon element. */ setIcon(e, t = this.el()) { if (!this.player_.options_.experimentalSvgIcons) return; const i = "http://www.w3.org/2000/svg", r = ce("span", { className: "vjs-icon-placeholder vjs-svg-icon" }, { "aria-hidden": "true" }), n = se.createElementNS(i, "svg"); n.setAttributeNS(null, "viewBox", "0 0 512 512"); const a = se.createElementNS(i, "use"); return n.appendChild(a), a.setAttributeNS(null, "href", `#vjs-icon-${e}`), r.appendChild(n), this.iconIsSet_ ? t.replaceChild(r, t.querySelector(".vjs-icon-placeholder")) : t.appendChild(r), this.iconIsSet_ = true, r; } /** * Add a child `Component` inside the current `Component`. * * @param {string|Component} child * The name or instance of a child to add. * * @param {Object} [options={}] * The key/value store of options that will get passed to children of * the child. * * @param {number} [index=this.children_.length] * The index to attempt to add a child into. * * * @return {Component} * The `Component` that gets added as a child. When using a string the * `Component` will get created by this process. */ addChild(e, t = {}, i = this.children_.length) { let r, n; if (typeof e == "string") { n = Ne(e); const a = t.componentClass || n; t.name = n; const u = ct.getComponent(a); if (!u) throw new Error(`Component ${a} does not exist`); if (typeof u != "function") return null; r = new u(this.player_ || this, t); } else r = e; if (r.parentComponent_ && r.parentComponent_.removeChild(r), this.children_.splice(i, 0, r), r.parentComponent_ = this, typeof r.id == "function" && (this.childIndex_[r.id()] = r), n = n || r.name && Ne(r.name()), n && (this.childNameIndex_[n] = r, this.childNameIndex_[rr(n)] = r), typeof r.el == "function" && r.el()) { let a = null; this.children_[i + 1] && (this.children_[i + 1].el_ ? a = this.children_[i + 1].el_ : Ss(this.children_[i + 1]) && (a = this.children_[i + 1])), this.contentEl().insertBefore(r.el(), a); } return r; } /** * Remove a child `Component` from this `Component`s list of children. Also removes * the child `Component`s element from this `Component`s element. * * @param {Component} component * The child `Component` to remove. */ removeChild(e) { if (typeof e == "string" && (e = this.getChild(e)), !e || !this.children_) return; let t = false; for (let r = this.children_.length - 1; r >= 0; r--) if (this.children_[r] === e) { t = true, this.children_.splice(r, 1); break; } if (!t) return; e.parentComponent_ = null, this.childIndex_[e.id()] = null, this.childNameIndex_[Ne(e.name())] = null, this.childNameIndex_[rr(e.name())] = null; const i = e.el(); i && i.parentNode === this.contentEl() && this.contentEl().removeChild(e.el()); } /** * Add and initialize default child `Component`s based upon options. */ initChildren() { const e = this.options_.children; if (e) { const t = this.options_, i = (a) => { const u = a.name; let c = a.opts; if (t[u] !== void 0 && (c = t[u]), c === false) return; c === true && (c = {}), c.playerOptions = this.options_.playerOptions; const f = this.addChild(u, c); f && (this[u] = f); }; let r; const n = ct.getComponent("Tech"); Array.isArray(e) ? r = e : r = Object.keys(e), r.concat(Object.keys(this.options_).filter(function(a) { return !r.some(function(u) { return typeof u == "string" ? a === u : a === u.name; }); })).map((a) => { let u, c; return typeof a == "string" ? (u = a, c = e[u] || this.options_[u] || {}) : (u = a.name, c = a), { name: u, opts: c }; }).filter((a) => { const u = ct.getComponent(a.opts.componentClass || Ne(a.name)); return u && !n.isTech(u); }).forEach(i); } } /** * Builds the default DOM class name. Should be overridden by sub-components. * * @return {string} * The DOM class name for this object. * * @abstract */ buildCSSClass() { return ""; } /** * Bind a listener to the component's ready state. * Different from event listeners in that if the ready event has already happened * it will trigger the function immediately. * * @param {ReadyCallback} fn * Function that gets called when the `Component` is ready. */ ready(e, t = false) { if (e) { if (!this.isReady_) { this.readyQueue_ = this.readyQueue_ || [], this.readyQueue_.push(e); return; } t ? e.call(this) : this.setTimeout(e, 1); } } /** * Trigger all the ready listeners for this `Component`. * * @fires Component#ready */ triggerReady() { this.isReady_ = true, this.setTimeout(function() { const e = this.readyQueue_; this.readyQueue_ = [], e && e.length > 0 && e.forEach(function(t) { t.call(this); }, this), this.trigger("ready"); }, 1); } /** * Find a single DOM element matching a `selector`. This can be within the `Component`s * `contentEl()` or another custom context. * * @param {string} selector * A valid CSS selector, which will be passed to `querySelector`. * * @param {Element|string} [context=this.contentEl()] * A DOM element within which to query. Can also be a selector string in * which case the first matching element will get used as context. If * missing `this.contentEl()` gets used. If `this.contentEl()` returns * nothing it falls back to `document`. * * @return {Element|null} * the dom element that was found, or null * * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) */ $(e, t) { return xi(e, t || this.contentEl()); } /** * Finds all DOM element matching a `selector`. This can be within the `Component`s * `contentEl()` or another custom context. * * @param {string} selector * A valid CSS selector, which will be passed to `querySelectorAll`. * * @param {Element|string} [context=this.contentEl()] * A DOM element within which to query. Can also be a selector string in * which case the first matching element will get used as context. If * missing `this.contentEl()` gets used. If `this.contentEl()` returns * nothing it falls back to `document`. * * @return {NodeList} * a list of dom elements that were found * * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) */ $$(e, t) { return nd(e, t || this.contentEl()); } /** * Check if a component's element has a CSS class name. * * @param {string} classToCheck * CSS class name to check. * * @return {boolean} * - True if the `Component` has the class. * - False if the `Component` does not have the class` */ hasClass(e) { return sr(this.el_, e); } /** * Add a CSS class name to the `Component`s element. * * @param {...string} classesToAdd * One or more CSS class name to add. */ addClass(...e) { $i(this.el_, ...e); } /** * Remove a CSS class name from the `Component`s element. * * @param {...string} classesToRemove * One or more CSS class name to remove. */ removeClass(...e) { Un(this.el_, ...e); } /** * Add or remove a CSS class name from the component's element. * - `classToToggle` gets added when {@link Component#hasClass} would return false. * - `classToToggle` gets removed when {@link Component#hasClass} would return true. * * @param {string} classToToggle * The class to add or remove. Passed to DOMTokenList's toggle() * * @param {boolean|Dom.PredicateCallback} [predicate] * A boolean or function that returns a boolean. Passed to DOMTokenList's toggle(). */ toggleClass(e, t) { Yc(this.el_, e, t); } /** * Show the `Component`s element if it is hidden by removing the * 'vjs-hidden' class name from it. */ show() { this.removeClass("vjs-hidden"); } /** * Hide the `Component`s element if it is currently showing by adding the * 'vjs-hidden` class name to it. */ hide() { this.addClass("vjs-hidden"); } /** * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing' * class name to it. Used during fadeIn/fadeOut. * * @private */ lockShowing() { this.addClass("vjs-lock-showing"); } /** * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing' * class name from it. Used during fadeIn/fadeOut. * * @private */ unlockShowing() { this.removeClass("vjs-lock-showing"); } /** * Get the value of an attribute on the `Component`s element. * * @param {string} attribute * Name of the attribute to get the value from. * * @return {string|null} * - The value of the attribute that was asked for. * - Can be an empty string on some browsers if the attribute does not exist * or has no value * - Most browsers will return null if the attribute does not exist or has * no value. * * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute} */ getAttribute(e) { return Zc(this.el_, e); } /** * Set the value of an attribute on the `Component`'s element * * @param {string} attribute * Name of the attribute to set. * * @param {string} value * Value to set the attribute to. * * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute} */ setAttribute(e, t) { _s(this.el_, e, t); } /** * Remove an attribute from the `Component`s element. * * @param {string} attribute * Name of the attribute to remove. * * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute} */ removeAttribute(e) { qn(this.el_, e); } /** * Get or set the width of the component based upon the CSS styles. * See {@link Component#dimension} for more detailed information. * * @param {number|string} [num] * The width that you want to set postfixed with '%', 'px' or nothing. * * @param {boolean} [skipListeners] * Skip the componentresize event trigger * * @return {number|undefined} * The width when getting, zero if there is no width */ width(e, t) { return this.dimension("width", e, t); } /** * Get or set the height of the component based upon the CSS styles. * See {@link Component#dimension} for more detailed information. * * @param {number|string} [num] * The height that you want to set postfixed with '%', 'px' or nothing. * * @param {boolean} [skipListeners] * Skip the componentresize event trigger * * @return {number|undefined} * The height when getting, zero if there is no height */ height(e, t) { return this.dimension("height", e, t); } /** * Set both the width and height of the `Component` element at the same time. * * @param {number|string} width * Width to set the `Component`s element to. * * @param {number|string} height * Height to set the `Component`s element to. */ dimensions(e, t) { this.width(e, true), this.height(t); } /** * Get or set width or height of the `Component` element. This is the shared code * for the {@link Component#width} and {@link Component#height}. * * Things to know: * - If the width or height in an number this will return the number postfixed with 'px'. * - If the width/height is a percent this will return the percent postfixed with '%' * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`. * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/} * for more information * - If you want the computed style of the component, use {@link Component#currentWidth} * and {@link {Component#currentHeight} * * @fires Component#componentresize * * @param {string} widthOrHeight 8 'width' or 'height' * * @param {number|string} [num] 8 New dimension * * @param {boolean} [skipListeners] * Skip componentresize event trigger * * @return {number|undefined} * The dimension when getting or 0 if unset */ dimension(e, t, i) { if (t !== void 0) { (t === null || t !== t) && (t = 0), ("" + t).indexOf("%") !== -1 || ("" + t).indexOf("px") !== -1 ? this.el_.style[e] = t : t === "auto" ? this.el_.style[e] = "" : this.el_.style[e] = t + "px", i || this.trigger("componentresize"); return; } if (!this.el_) return 0; const r = this.el_.style[e], n = r.indexOf("px"); return parseInt(n !== -1 ? r.slice(0, n) : this.el_["offset" + Ne(e)], 10); } /** * Get the computed width or the height of the component's element. * * Uses `window.getComputedStyle`. * * @param {string} widthOrHeight * A string containing 'width' or 'height'. Whichever one you want to get. * * @return {number} * The dimension that gets asked for or 0 if nothing was set * for that dimension. */ currentDimension(e) { let t = 0; if (e !== "width" && e !== "height") throw new Error("currentDimension only accepts width or height value"); if (t = Ts(this.el_, e), t = parseFloat(t), t === 0 || isNaN(t)) { const i = `offset${Ne(e)}`; t = this.el_[i]; } return t; } /** * An object that contains width and height values of the `Component`s * computed style. Uses `window.getComputedStyle`. * * @typedef {Object} Component~DimensionObject * * @property {number} width * The width of the `Component`s computed style. * * @property {number} height * The height of the `Component`s computed style. */ /** * Get an object that contains computed width and height values of the * component's element. * * Uses `window.getComputedStyle`. * * @return {Component~DimensionObject} * The computed dimensions of the component's element. */ currentDimensions() { return { width: this.currentDimension("width"), height: this.currentDimension("height") }; } /** * Get the computed width of the component's element. * * Uses `window.getComputedStyle`. * * @return {number} * The computed width of the component's element. */ currentWidth() { return this.currentDimension("width"); } /** * Get the computed height of the component's element. * * Uses `window.getComputedStyle`. * * @return {number} * The computed height of the component's element. */ currentHeight() { return this.currentDimension("height"); } /** * Retrieves the position and size information of the component's element. * * @return {Object} An object with `boundingClientRect` and `center` properties. * - `boundingClientRect`: An object with properties `x`, `y`, `width`, * `height`, `top`, `right`, `bottom`, and `left`, representing * the bounding rectangle of the element. * - `center`: An object with properties `x` and `y`, representing * the center point of the element. `width` and `height` are set to 0. */ getPositions() { const e = this.el_.getBoundingClientRect(), t = { x: e.x, y: e.y, width: e.width, height: e.height, top: e.top, right: e.right, bottom: e.bottom, left: e.left }, i = { x: e.left + e.width / 2, y: e.top + e.height / 2, width: 0, height: 0, top: e.top + e.height / 2, right: e.left + e.width / 2, bottom: e.top + e.height / 2, left: e.left + e.width / 2 }; return { boundingClientRect: t, center: i }; } /** * Set the focus to this component */ focus() { this.el_.focus(); } /** * Remove the focus from this component */ blur() { this.el_.blur(); } /** * When this Component receives a `keydown` event which it does not process, * it passes the event to the Player for handling. * * @param {KeyboardEvent} event * The `keydown` event that caused this function to be called. */ handleKeyDown(e) { this.player_ && (e.key !== "Tab" && !(this.player_.options_.playerOptions.spatialNavigation && this.player_.options_.playerOptions.spatialNavigation.enabled) && e.stopPropagation(), this.player_.handleKeyDown(e)); } /** * Many components used to have a `handleKeyPress` method, which was poorly * named because it listened to a `keydown` event. This method name now * delegates to `handleKeyDown`. This means anyone calling `handleKeyPress` * will not see their method calls stop working. * * @param {KeyboardEvent} event * The event that caused this function to be called. */ handleKeyPress(e) { this.handleKeyDown(e); } /** * Emit a 'tap' events when touch event support gets detected. This gets used to * support toggling the controls through a tap on the video. They get enabled * because every sub-component would have extra overhead otherwise. * * @protected * @fires Component#tap * @listens Component#touchstart * @listens Component#touchmove * @listens Component#touchleave * @listens Component#touchcancel * @listens Component#touchend */ emitTapEvents() { let e = 0, t = null; const i = 10, r = 200; let n; this.on("touchstart", function(u) { u.touches.length === 1 && (t = { pageX: u.touches[0].pageX, pageY: u.touches[0].pageY }, e = D.performance.now(), n = true); }), this.on("touchmove", function(u) { if (u.touches.length > 1) n = false; else if (t) { const c = u.touches[0].pageX - t.pageX, f = u.touches[0].pageY - t.pageY; Math.sqrt(c * c + f * f) > i && (n = false); } }); const a = function() { n = false; }; this.on("touchleave", a), this.on("touchcancel", a), this.on("touchend", function(u) { t = null, n === true && D.performance.now() - e < r && (u.preventDefault(), this.trigger("tap")); }); } /** * This function reports user activity whenever touch events happen. This can get * turned off by any sub-components that wants touch events to act another way. * * Report user touch activity when touch events occur. User activity gets used to * determine when controls should show/hide. It is simple when it comes to mouse * events, because any mouse event should show the controls. So we capture mouse * events that bubble up to the player and report activity when that happens. * With touch events it isn't as easy as `touchstart` and `touchend` toggle player * controls. So touch events can't help us at the player level either. * * User activity gets checked asynchronously. So what could happen is a tap event * on the video turns the controls off. Then the `touchend` event bubbles up to * the player. Which, if it reported user activity, would turn the controls right * back on. We also don't want to completely block touch events from bubbling up. * Furthermore a `touchmove` event and anything other than a tap, should not turn * controls back on. * * @listens Component#touchstart * @listens Component#touchmove * @listens Component#touchend * @listens Component#touchcancel */ enableTouchActivity() { if (!this.player() || !this.player().reportUserActivity) return; const e = De(this.player(), this.player().reportUserActivity); let t; this.on("touchstart", function() { e(), this.clearInterval(t), t = this.setInterval(e, 250); }); const i = function(r) { e(), this.clearInterval(t); }; this.on("touchmove", e), this.on("touchend", i), this.on("touchcancel", i); } /** * A callback that has no parameters and is bound into `Component`s context. * * @callback Component~GenericCallback * @this Component */ /** * Creates a function that runs after an `x` millisecond timeout. This function is a * wrapper around `window.setTimeout`. There are a few reasons to use this one * instead though: * 1. It gets cleared via {@link Component#clearTimeout} when * {@link Component#dispose} gets called. * 2. The function callback will gets turned into a {@link Component~GenericCallback} * * > Note: You can't use `window.clearTimeout` on the id returned by this function. This * will cause its dispose listener not to get cleaned up! Please use * {@link Component#clearTimeout} or {@link Component#dispose} instead. * * @param {Component~GenericCallback} fn * The function that will be run after `timeout`. * * @param {number} timeout * Timeout in milliseconds to delay before executing the specified function. * * @return {number} * Returns a timeout ID that gets used to identify the timeout. It can also * get used in {@link Component#clearTimeout} to clear the timeout that * was set. * * @listens Component#dispose * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout} */ setTimeout(e, t) { var i; return e = De(this, e), this.clearTimersOnDispose_(), i = D.setTimeout(() => { this.setTimeoutIds_.has(i) && this.setTimeoutIds_.delete(i), e(); }, t), this.setTimeoutIds_.add(i), i; } /** * Clears a timeout that gets created via `window.setTimeout` or * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout} * use this function instead of `window.clearTimout`. If you don't your dispose * listener will not get cleaned up until {@link Component#dispose}! * * @param {number} timeoutId * The id of the timeout to clear. The return value of * {@link Component#setTimeout} or `window.setTimeout`. * * @return {number} * Returns the timeout id that was cleared. * * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout} */ clearTimeout(e) { return this.setTimeoutIds_.has(e) && (this.setTimeoutIds_.delete(e), D.clearTimeout(e)), e; } /** * Creates a function that gets run every `x` milliseconds. This function is a wrapper * around `window.setInterval`. There are a few reasons to use this one instead though. * 1. It gets cleared via {@link Component#clearInterval} when * {@link Component#dispose} gets called. * 2. The function callback will be a {@link Component~GenericCallback} * * @param {Component~GenericCallback} fn * The function to run every `x` seconds. * * @param {number} interval * Execute the specified function every `x` milliseconds. * * @return {number} * Returns an id that can be used to identify the interval. It can also be be used in * {@link Component#clearInterval} to clear the interval. * * @listens Component#dispose * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval} */ setInterval(e, t) { e = De(this, e), this.clearTimersOnDispose_(); const i = D.setInterval(e, t); return this.setIntervalIds_.add(i), i; } /** * Clears an interval that gets created via `window.setInterval` or * {@link Component#setInterval}. If you set an interval via {@link Component#setInterval} * use this function instead of `window.clearInterval`. If you don't your dispose * listener will not get cleaned up until {@link Component#dispose}! * * @param {number} intervalId * The id of the interval to clear. The return value of * {@link Component#setInterval} or `window.setInterval`. * * @return {number} * Returns the interval id that was cleared. * * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval} */ clearInterval(e) { return this.setIntervalIds_.has(e) && (this.setIntervalIds_.delete(e), D.clearInterval(e)), e; } /** * Queues up a callback to be passed to requestAnimationFrame (rAF), but * with a few extra bonuses: * * - Supports browsers that do not support rAF by falling back to * {@link Component#setTimeout}. * * - The callback is turned into a {@link Component~GenericCallback} (i.e. * bound to the component). * * - Automatic cancellation of the rAF callback is handled if the component * is disposed before it is called. * * @param {Component~GenericCallback} fn * A function that will be bound to this component and executed just * before the browser's next repaint. * * @return {number} * Returns an rAF ID that gets used to identify the timeout. It can * also be used in {@link Component#cancelAnimationFrame} to cancel * the animation frame callback. * * @listens Component#dispose * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame} */ requestAnimationFrame(e) { this.clearTimersOnDispose_(); var t; return e = De(this, e), t = D.requestAnimationFrame(() => { this.rafIds_.has(t) && this.rafIds_.delete(t), e(); }), this.rafIds_.add(t), t; } /** * Request an animation frame, but only one named animation * frame will be queued. Another will never be added until * the previous one finishes. * * @param {string} name * The name to give this requestAnimationFrame * * @param {Component~GenericCallback} fn * A function that will be bound to this component and executed just * before the browser's next repaint. */ requestNamedAnimationFrame(e, t) { this.namedRafs_.has(e) && this.cancelNamedAnimationFrame(e), this.clearTimersOnDispose_(), t = De(this, t); const i = this.requestAnimationFrame(() => { t(), this.namedRafs_.has(e) && this.namedRafs_.delete(e); }); return this.namedRafs_.set(e, i), e; } /** * Cancels a current named animation frame if it exists. * * @param {string} name * The name of the requestAnimationFrame to cancel. */ cancelNamedAnimationFrame(e) { this.namedRafs_.has(e) && (this.cancelAnimationFrame(this.namedRafs_.get(e)), this.namedRafs_.delete(e)); } /** * Cancels a queued callback passed to {@link Component#requestAnimationFrame} * (rAF). * * If you queue an rAF callback via {@link Component#requestAnimationFrame}, * use this function instead of `window.cancelAnimationFrame`. If you don't, * your dispose listener will not get cleaned up until {@link Component#dispose}! * * @param {number} id * The rAF ID to clear. The return value of {@link Component#requestAnimationFrame}. * * @return {number} * Returns the rAF ID that was cleared. * * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/cancelAnimationFrame} */ cancelAnimationFrame(e) { return this.rafIds_.has(e) && (this.rafIds_.delete(e), D.cancelAnimationFrame(e)), e; } /** * A function to setup `requestAnimationFrame`, `setTimeout`, * and `setInterval`, clearing on dispose. * * > Previously each timer added and removed dispose listeners on it's own. * For better performance it was decided to batch them all, and use `Set`s * to track outstanding timer ids. * * @private */ clearTimersOnDispose_() { this.clearingTimersOnDispose_ || (this.clearingTimersOnDispose_ = true, this.one("dispose", () => { [["namedRafs_", "cancelNamedAnimationFrame"], ["rafIds_", "cancelAnimationFrame"], ["setTimeoutIds_", "clearTimeout"], ["setIntervalIds_", "clearInterval"]].forEach(([e, t]) => { this[e].forEach((i, r) => this[t](r)); }), this.clearingTimersOnDispose_ = false; })); } /** * Decide whether an element is actually disabled or not. * * @function isActuallyDisabled * @param element {Node} * @return {boolean} * * @see {@link https://html.spec.whatwg.org/multipage/semantics-other.html#concept-element-disabled} */ getIsDisabled() { return !!this.el_.disabled; } /** * Decide whether the element is expressly inert or not. * * @see {@link https://html.spec.whatwg.org/multipage/interaction.html#expressly-inert} * @function isExpresslyInert * @param element {Node} * @return {boolean} */ getIsExpresslyInert() { return this.el_.inert && !this.el_.ownerDocument.documentElement.inert; } /** * Determine whether or not this component can be considered as focusable component. * * @param {HTMLElement} el - The HTML element representing the component. * @return {boolean} * If the component can be focused, will be `true`. Otherwise, `false`. */ getIsFocusable(e) { return (e || this.el_).tabIndex >= 0 && !(this.getIsDisabled() || this.getIsExpresslyInert()); } /** * Determine whether or not this component is currently visible/enabled/etc... * * @param {HTMLElement} el - The HTML element representing the component. * @return {boolean} * If the component can is currently visible & enabled, will be `true`. Otherwise, `false`. */ getIsAvailableToBeFocused(e) { function t(n) { const a = D.getComputedStyle(n, null), u = a.getPropertyValue("visibility"); return a.getPropertyValue("display") !== "none" && !["hidden", "collapse"].includes(u); } function i(n) { return !(!t(n.parentElement) || !t(n) || n.style.opacity === "0" || D.getComputedStyle(n).height === "0px" || D.getComputedStyle(n).width === "0px"); } function r(n) { if (n.offsetWidth + n.offsetHeight + n.getBoundingClientRect().height + n.getBoundingClientRect().width === 0) return false; const a = { x: n.getBoundingClientRect().left + n.offsetWidth / 2, y: n.getBoundingClientRect().top + n.offsetHeight / 2 }; if (a.x < 0 || a.x > (se.documentElement.clientWidth || D.innerWidth) || a.y < 0 || a.y > (se.documentElement.clientHeight || D.innerHeight)) return false; let u = se.elementFromPoint(a.x, a.y); for (; u; ) { if (u === n) return true; if (u.parentNode) u = u.parentNode; else return false; } } return e || (e = this.el()), !!(r(e) && i(e) && (!e.parentElement || e.tabIndex >= 0)); } /** * Register a `Component` with `videojs` given the name and the component. * * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s * should be registered using {@link Tech.registerTech} or * {@link videojs:videojs.registerTech}. * * > NOTE: This function can also be seen on videojs as * {@link videojs:videojs.registerComponent}. * * @param {string} name * The name of the `Component` to register. * * @param {Component} ComponentToRegister * The `Component` class to register. * * @return {Component} * The `Component` that was registered. */ static registerComponent(e, t) { if (typeof e != "string" || !e) throw new Error(`Illegal component name, "${e}"; must be a non-empty string.`); const i = ct.getComponent("Tech"), r = i && i.isTech(t), n = ct === t || ct.prototype.isPrototypeOf(t.prototype); if (r || !n) { let u; throw r ? u = "techs must be registered using Tech.registerTech()" : u = "must be a Component subclass", new Error(`Illegal component, "${e}"; ${u}.`); } e = Ne(e), ct.components_ || (ct.components_ = {}); const a = ct.getComponent("Player"); if (e === "Player" && a && a.players) { const u = a.players, c = Object.keys(u); if (u && c.length > 0 && c.map((f) => u[f]).every(Boolean)) throw new Error("Can not register Player component after player has been created."); } return ct.components_[e] = t, ct.components_[rr(e)] = t, t; } /** * Get a `Component` based on the name it was registered with. * * @param {string} name * The Name of the component to get. * * @return {typeof Component} * The `Component` that got registered under the given name. */ static getComponent(e) { if (!(!e || !ct.components_)) return ct.components_[e]; } }; K.registerComponent("Component", K); function S0(s, e, t) { if (typeof e != "number" || e < 0 || e > t) throw new Error(`Failed to execute '${s}' on 'TimeRanges': The index provided (${e}) is non-numeric or out of bounds (0-${t}).`); } function Pl(s, e, t, i) { return S0(s, i, t.length - 1), t[i][e]; } function Oa(s) { let e; return s === void 0 || s.length === 0 ? e = { length: 0, start() { throw new Error("This TimeRanges object is empty"); }, end() { throw new Error("This TimeRanges object is empty"); } } : e = { length: s.length, start: Pl.bind(null, "start", 0, s), end: Pl.bind(null, "end", 1, s) }, D.Symbol && D.Symbol.iterator && (e[D.Symbol.iterator] = () => (s || []).values()), e; } function Nt(s, e) { return Array.isArray(s) ? Oa(s) : s === void 0 || e === void 0 ? Oa() : Oa([[s, e]]); } const gd = function(s, e) { s = s < 0 ? 0 : s; let t = Math.floor(s % 60), i = Math.floor(s / 60 % 60), r = Math.floor(s / 3600); const n = Math.floor(e / 60 % 60), a = Math.floor(e / 3600); return (isNaN(s) || s === 1 / 0) && (r = i = t = "-"), r = r > 0 || a > 0 ? r + ":" : "", i = ((r || n >= 10) && i < 10 ? "0" + i : i) + ":", t = t < 10 ? "0" + t : t, r + i + t; }; let Oo = gd; function _d(s) { Oo = s; } function yd() { Oo = gd; } function zi(s, e = s) { return Oo(s, e); } var E0 = /* @__PURE__ */ Object.freeze({ __proto__: null, createTimeRanges: Nt, createTimeRange: Nt, setFormatTime: _d, resetFormatTime: yd, formatTime: zi }); function Td(s, e) { let t = 0, i, r; if (!e) return 0; (!s || !s.length) && (s = Nt(0, 0)); for (let n = 0; n < s.length; n++) i = s.start(n), r = s.end(n), r > e && (r = e), t += r - i; return t / e; } function Re(s) { if (s instanceof Re) return s; typeof s == "number" ? this.code = s : typeof s == "string" ? this.message = s : Kt(s) && (typeof s.code == "number" && (this.code = s.code), Object.assign(this, s)), this.message || (this.message = Re.defaultMessages[this.code] || ""); } Re.prototype.code = 0; Re.prototype.message = ""; Re.prototype.status = null; Re.prototype.metadata = null; Re.errorTypes = ["MEDIA_ERR_CUSTOM", "MEDIA_ERR_ABORTED", "MEDIA_ERR_NETWORK", "MEDIA_ERR_DECODE", "MEDIA_ERR_SRC_NOT_SUPPORTED", "MEDIA_ERR_ENCRYPTED"]; Re.defaultMessages = { 1: "You aborted the media playback", 2: "A network error caused the media download to fail part-way.", 3: "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.", 4: "The media could not be loaded, either because the server or network failed or because the format is not supported.", 5: "The media is encrypted and we do not have the keys to decrypt it." }; Re.MEDIA_ERR_CUSTOM = 0; Re.prototype.MEDIA_ERR_CUSTOM = 0; Re.MEDIA_ERR_ABORTED = 1; Re.prototype.MEDIA_ERR_ABORTED = 1; Re.MEDIA_ERR_NETWORK = 2; Re.prototype.MEDIA_ERR_NETWORK = 2; Re.MEDIA_ERR_DECODE = 3; Re.prototype.MEDIA_ERR_DECODE = 3; Re.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; Re.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; Re.MEDIA_ERR_ENCRYPTED = 5; Re.prototype.MEDIA_ERR_ENCRYPTED = 5; function nr(s) { return s != null && typeof s.then == "function"; } function zt(s) { nr(s) && s.then(null, (e) => { }); } const io = function(s) { return ["kind", "label", "language", "id", "inBandMetadataTrackDispatchType", "mode", "src"].reduce((t, i, r) => (s[i] && (t[i] = s[i]), t), { cues: s.cues && Array.prototype.map.call(s.cues, function(t) { return { startTime: t.startTime, endTime: t.endTime, text: t.text, id: t.id }; }) }); }, C0 = function(s) { const e = s.$$("track"), t = Array.prototype.map.call(e, (r) => r.track); return Array.prototype.map.call(e, function(r) { const n = io(r.track); return r.src && (n.src = r.src), n; }).concat(Array.prototype.filter.call(s.textTracks(), function(r) { return t.indexOf(r) === -1; }).map(io)); }, A0 = function(s, e) { return s.forEach(function(t) { const i = e.addRemoteTextTrack(t).track; !t.src && t.cues && t.cues.forEach((r) => i.addCue(r)); }), e.textTracks(); }; var Ol = { textTracksToJson: C0, jsonToTextTracks: A0, trackToJson_: io }; const La = "vjs-modal-dialog"; class Cs extends K { /** * Creates an instance of this class. * * @param {Player} player * The `Player` that this class should be attached to. * * @param {Object} [options] * The key/value store of player options. * * @param {ContentDescriptor} [options.content=undefined] * Provide customized content for this modal. * * @param {string} [options.description] * A text description for the modal, primarily for accessibility. * * @param {boolean} [options.fillAlways=false] * Normally, modals are automatically filled only the first time * they open. This tells the modal to refresh its content * every time it opens. * * @param {string} [options.label] * A text label for the modal, primarily for accessibility. * * @param {boolean} [options.pauseOnOpen=true] * If `true`, playback will will be paused if playing when * the modal opens, and resumed when it closes. * * @param {boolean} [options.temporary=true] * If `true`, the modal can only be opened once; it will be * disposed as soon as it's closed. * * @param {boolean} [options.uncloseable=false] * If `true`, the user will not be able to close the modal * through the UI in the normal ways. Programmatic closing is * still possible. */ constructor(e, t) { super(e, t), this.handleKeyDown_ = (i) => this.handleKeyDown(i), this.close_ = (i) => this.close(i), this.opened_ = this.hasBeenOpened_ = this.hasBeenFilled_ = false, this.closeable(!this.options_.uncloseable), this.content(this.options_.content), this.contentEl_ = ce("div", { className: `${La}-content` }, { role: "document" }), this.descEl_ = ce("p", { className: `${La}-description vjs-control-text`, id: this.el().getAttribute("aria-describedby") }), Si(this.descEl_, this.description()), this.el_.appendChild(this.descEl_), this.el_.appendChild(this.contentEl_); } /** * Create the `ModalDialog`'s DOM element * * @return {Element} * The DOM element that gets created. */ createEl() { return super.createEl("div", { className: this.buildCSSClass(), tabIndex: -1 }, { "aria-describedby": `${this.id()}_description`, "aria-hidden": "true", "aria-label": this.label(), role: "dialog", "aria-live": "polite" }); } dispose() { this.contentEl_ = null, this.descEl_ = null, this.previouslyActiveEl_ = null, super.dispose(); } /** * Builds the default DOM `className`. * * @return {string} * The DOM `className` for this object. */ buildCSSClass() { return `${La} vjs-hidden ${super.buildCSSClass()}`; } /** * Returns the label string for this modal. Primarily used for accessibility. * * @return {string} * the localized or raw label of this modal. */ label() { return this.localize(this.options_.label || "Modal Window"); } /** * Returns the description string for this modal. Primarily used for * accessibility. * * @return {string} * The localized or raw description of this modal. */ description() { let e = this.options_.description || this.localize("This is a modal window."); return this.closeable() && (e += " " + this.localize("This modal can be closed by pressing the Escape key or activating the close button.")), e; } /** * Opens the modal. * * @fires ModalDialog#beforemodalopen * @fires ModalDialog#modalopen */ open() { if (this.opened_) { this.options_.fillAlways && this.fill(); return; } const e = this.player(); this.trigger("beforemodalopen"), this.opened_ = true, (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) && this.fill(), this.wasPlaying_ = !e.paused(), this.options_.pauseOnOpen && this.wasPlaying_ && e.pause(), this.on("keydown", this.handleKeyDown_), this.hadControls_ = e.controls(), e.controls(false), this.show(), this.conditionalFocus_(), this.el().setAttribute("aria-hidden", "false"), this.trigger("modalopen"), this.hasBeenOpened_ = true; } /** * If the `ModalDialog` is currently open or closed. * * @param {boolean} [value] * If given, it will open (`true`) or close (`false`) the modal. * * @return {boolean} * the current open state of the modaldialog */ opened(e) { return typeof e == "boolean" && this[e ? "open" : "close"](), this.opened_; } /** * Closes the modal, does nothing if the `ModalDialog` is * not open. * * @fires ModalDialog#beforemodalclose * @fires ModalDialog#modalclose */ close() { if (!this.opened_) return; const e = this.player(); this.trigger("beforemodalclose"), this.opened_ = false, this.wasPlaying_ && this.options_.pauseOnOpen && e.play(), this.off("keydown", this.handleKeyDown_), this.hadControls_ && e.controls(true), this.hide(), this.el().setAttribute("aria-hidden", "true"), this.trigger({ type: "modalclose", bubbles: true }), this.conditionalBlur_(), this.options_.temporary && this.dispose(); } /** * Check to see if the `ModalDialog` is closeable via the UI. * * @param {boolean} [value] * If given as a boolean, it will set the `closeable` option. * * @return {boolean} * Returns the final value of the closable option. */ closeable(e) { if (typeof e == "boolean") { const t = this.closeable_ = !!e; let i = this.getChild("closeButton"); if (t && !i) { const r = this.contentEl_; this.contentEl_ = this.el_, i = this.addChild("closeButton", { controlText: "Close Modal Dialog" }), this.contentEl_ = r, this.on(i, "close", this.close_); } !t && i && (this.off(i, "close", this.close_), this.removeChild(i), i.dispose()); } return this.closeable_; } /** * Fill the modal's content element with the modal's "content" option. * The content element will be emptied before this change takes place. */ fill() { this.fillWith(this.content()); } /** * Fill the modal's content element with arbitrary content. * The content element will be emptied before this change takes place. * * @fires ModalDialog#beforemodalfill * @fires ModalDialog#modalfill * * @param {ContentDescriptor} [content] * The same rules apply to this as apply to the `content` option. */ fillWith(e) { const t = this.contentEl(), i = t.parentNode, r = t.nextSibling; this.trigger("beforemodalfill"), this.hasBeenFilled_ = true, i.removeChild(t), this.empty(), rd(t, e), this.trigger("modalfill"), r ? i.insertBefore(t, r) : i.appendChild(t); const n = this.getChild("closeButton"); n && i.appendChild(n.el_), this.trigger("aftermodalfill"); } /** * Empties the content element. This happens anytime the modal is filled. * * @fires ModalDialog#beforemodalempty * @fires ModalDialog#modalempty */ empty() { this.trigger("beforemodalempty"), jn(this.contentEl()), this.trigger("modalempty"); } /** * Gets or sets the modal content, which gets normalized before being * rendered into the DOM. * * This does not update the DOM or fill the modal, but it is called during * that process. * * @param {ContentDescriptor} [value] * If defined, sets the internal content value to be used on the * next call(s) to `fill`. This value is normalized before being * inserted. To "clear" the internal content value, pass `null`. * * @return {ContentDescriptor} * The current content of the modal dialog */ content(e) { return typeof e < "u" && (this.content_ = e), this.content_; } /** * conditionally focus the modal dialog if focus was previously on the player. * * @private */ conditionalFocus_() { const e = se.activeElement, t = this.player_.el_; this.previouslyActiveEl_ = null, (t.contains(e) || t === e) && (this.previouslyActiveEl_ = e, this.focus()); } /** * conditionally blur the element and refocus the last focused element * * @private */ conditionalBlur_() { this.previouslyActiveEl_ && (this.previouslyActiveEl_.focus(), this.previouslyActiveEl_ = null); } /** * Keydown handler. Attached when modal is focused. * * @listens keydown */ handleKeyDown(e) { if (this.trigger({ type: "modalKeydown", originalEvent: e, target: this, bubbles: true }), e.stopPropagation(), e.key === "Escape" && this.closeable()) { e.preventDefault(), this.close(); return; } if (e.key !== "Tab") return; const t = this.focusableEls_(), i = this.el_.querySelector(":focus"); let r; for (let n = 0; n < t.length; n++) if (i === t[n]) { r = n; break; } se.activeElement === this.el_ && (r = 0), e.shiftKey && r === 0 ? (t[t.length - 1].focus(), e.preventDefault()) : !e.shiftKey && r === t.length - 1 && (t[0].focus(), e.preventDefault()); } /** * get all focusable elements * * @private */ focusableEls_() { const e = this.el_.querySelectorAll("*"); return Array.prototype.filter.call(e, (t) => (t instanceof D.HTMLAnchorElement || t instanceof D.HTMLAreaElement) && t.hasAttribute("href") || (t instanceof D.HTMLInputElement || t instanceof D.HTMLSelectElement || t instanceof D.HTMLTextAreaElement || t instanceof D.HTMLButtonElement) && !t.hasAttribute("disabled") || t instanceof D.HTMLIFrameElement || t instanceof D.HTMLObjectElement || t instanceof D.HTMLEmbedElement || t.hasAttribute("tabindex") && t.getAttribute("tabindex") !== -1 || t.hasAttribute("contenteditable")); } } Cs.prototype.options_ = { pauseOnOpen: true, temporary: true }; K.registerComponent("ModalDialog", Cs); class vs extends Tt { /** * Create an instance of this class * * @param { Track[] } tracks * A list of tracks to initialize the list with. * * @abstract */ constructor(e = []) { super(), this.tracks_ = [], Object.defineProperty(this, "length", { get() { return this.tracks_.length; } }); for (let t = 0; t < e.length; t++) this.addTrack(e[t]); } /** * Add a {@link Track} to the `TrackList` * * @param {Track} track * The audio, video, or text track to add to the list. * * @fires TrackList#addtrack */ addTrack(e) { const t = this.tracks_.length; "" + t in this || Object.defineProperty(this, t, { get() { return this.tracks_[t]; } }), this.tracks_.indexOf(e) === -1 && (this.tracks_.push(e), this.trigger({ track: e, type: "addtrack", target: this })), e.labelchange_ = () => { this.trigger({ track: e, type: "labelchange", target: this }); }, oi(e) && e.addEventListener("labelchange", e.labelchange_); } /** * Remove a {@link Track} from the `TrackList` * * @param {Track} rtrack * The audio, video, or text track to remove from the list. * * @fires TrackList#removetrack */ removeTrack(e) { let t; for (let i = 0, r = this.length; i < r; i++) if (this[i] === e) { t = this[i], t.off && t.off(), this.tracks_.splice(i, 1); break; } t && this.trigger({ track: t, type: "removetrack", target: this }); } /** * Get a Track from the TrackList by a tracks id * * @param {string} id - the id of the track to get * @method getTrackById * @return {Track} * @private */ getTrackById(e) { let t = null; for (let i = 0, r = this.length; i < r; i++) { const n = this[i]; if (n.id === e) { t = n; break; } } return t; } } vs.prototype.allowedEvents_ = { change: "change", addtrack: "addtrack", removetrack: "removetrack", labelchange: "labelchange" }; for (const s in vs.prototype.allowedEvents_) vs.prototype["on" + s] = null; const Ra = function(s, e) { for (let t = 0; t < s.length; t++) !Object.keys(s[t]).length || e.id === s[t].id || (s[t].enabled = false); }; class D0 extends vs { /** * Create an instance of this class. * * @param {AudioTrack[]} [tracks=[]] * A list of `AudioTrack` to instantiate the list with. */ constructor(e = []) { for (let t = e.length - 1; t >= 0; t--) if (e[t].enabled) { Ra(e, e[t]); break; } super(e), this.changing_ = false; } /** * Add an {@link AudioTrack} to the `AudioTrackList`. * * @param {AudioTrack} track * The AudioTrack to add to the list * * @fires TrackList#addtrack */ addTrack(e) { e.enabled && Ra(this, e), super.addTrack(e), e.addEventListener && (e.enabledChange_ = () => { this.changing_ || (this.changing_ = true, Ra(this, e), this.changing_ = false, this.trigger("change")); }, e.addEventListener("enabledchange", e.enabledChange_)); } removeTrack(e) { super.removeTrack(e), e.removeEventListener && e.enabledChange_ && (e.removeEventListener("enabledchange", e.enabledChange_), e.enabledChange_ = null); } } const Ma = function(s, e) { for (let t = 0; t < s.length; t++) !Object.keys(s[t]).length || e.id === s[t].id || (s[t].selected = false); }; class w0 extends vs { /** * Create an instance of this class. * * @param {VideoTrack[]} [tracks=[]] * A list of `VideoTrack` to instantiate the list with. */ constructor(e = []) { for (let t = e.length - 1; t >= 0; t--) if (e[t].selected) { Ma(e, e[t]); break; } super(e), this.changing_ = false, Object.defineProperty(this, "selectedIndex", { get() { for (let t = 0; t < this.length; t++) if (this[t].selected) return t; return -1; }, set() { } }); } /** * Add a {@link VideoTrack} to the `VideoTrackList`. * * @param {VideoTrack} track * The VideoTrack to add to the list * * @fires TrackList#addtrack */ addTrack(e) { e.selected && Ma(this, e), super.addTrack(e), e.addEventListener && (e.selectedChange_ = () => { this.changing_ || (this.changing_ = true, Ma(this, e), this.changing_ = false, this.trigger("change")); }, e.addEventListener("selectedchange", e.selectedChange_)); } removeTrack(e) { super.removeTrack(e), e.removeEventListener && e.selectedChange_ && (e.removeEventListener("selectedchange", e.selectedChange_), e.selectedChange_ = null); } } class vd extends vs { /** * Add a {@link TextTrack} to the `TextTrackList` * * @param {TextTrack} track * The text track to add to the list. * * @fires TrackList#addtrack */ addTrack(e) { super.addTrack(e), this.queueChange_ || (this.queueChange_ = () => this.queueTrigger("change")), this.triggerSelectedlanguagechange || (this.triggerSelectedlanguagechange_ = () => this.trigger("selectedlanguagechange")), e.addEventListener("modechange", this.queueChange_), ["metadata", "chapters"].indexOf(e.kind) === -1 && e.addEventListener("modechange", this.triggerSelectedlanguagechange_); } removeTrack(e) { super.removeTrack(e), e.removeEventListener && (this.queueChange_ && e.removeEventListener("modechange", this.queueChange_), this.selectedlanguagechange_ && e.removeEventListener("modechange", this.triggerSelectedlanguagechange_)); } } class I0 { /** * Create an instance of this class. * * @param {HtmlTrackElement[]} [tracks=[]] * A list of `HtmlTrackElement` to instantiate the list with. */ constructor(e = []) { this.trackElements_ = [], Object.defineProperty(this, "length", { get() { return this.trackElements_.length; } }); for (let t = 0, i = e.length; t < i; t++) this.addTrackElement_(e[t]); } /** * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList` * * @param {HtmlTrackElement} trackElement * The track element to add to the list. * * @private */ addTrackElement_(e) { const t = this.trackElements_.length; "" + t in this || Object.defineProperty(this, t, { get() { return this.trackElements_[t]; } }), this.trackElements_.indexOf(e) === -1 && this.trackElements_.push(e); } /** * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an * {@link TextTrack}. * * @param {TextTrack} track * The track associated with a track element. * * @return {HtmlTrackElement|undefined} * The track element that was found or undefined. * * @private */ getTrackElementByTrack_(e) { let t; for (let i = 0, r = this.trackElements_.length; i < r; i++) if (e === this.trackElements_[i].track) { t = this.trackElements_[i]; break; } return t; } /** * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList` * * @param {HtmlTrackElement} trackElement * The track element to remove from the list. * * @private */ removeTrackElement_(e) { for (let t = 0, i = this.trackElements_.length; t < i; t++) if (e === this.trackElements_[t]) { this.trackElements_[t].track && typeof this.trackElements_[t].track.off == "function" && this.trackElements_[t].track.off(), typeof this.trackElements_[t].off == "function" && this.trackElements_[t].off(), this.trackElements_.splice(t, 1); break; } } } class pn { /** * Create an instance of this class.. * * @param {Array} cues * A list of cues to be initialized with */ constructor(e) { pn.prototype.setCues_.call(this, e), Object.defineProperty(this, "length", { get() { return this.length_; } }); } /** * A setter for cues in this list. Creates getters * an an index for the cues. * * @param {Array} cues * An array of cues to set * * @private */ setCues_(e) { const t = this.length || 0; let i = 0; const r = e.length; this.cues_ = e, this.length_ = e.length; const n = function(a) { "" + a in this || Object.defineProperty(this, "" + a, { get() { return this.cues_[a]; } }); }; if (t < r) for (i = t; i < r; i++) n.call(this, i); } /** * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id. * * @param {string} id * The id of the cue that should be searched for. * * @return {TextTrackCueList~TextTrackCue|null} * A single cue or null if none was found. */ getCueById(e) { let t = null; for (let i = 0, r = this.length; i < r; i++) { const n = this[i]; if (n.id === e) { t = n; break; } } return t; } } const k0 = { alternative: "alternative", captions: "captions", main: "main", sign: "sign", subtitles: "subtitles", commentary: "commentary" }, P0 = { alternative: "alternative", descriptions: "descriptions", main: "main", "main-desc": "main-desc", translation: "translation", commentary: "commentary" }, O0 = { subtitles: "subtitles", captions: "captions", descriptions: "descriptions", chapters: "chapters", metadata: "metadata" }, Ll = { disabled: "disabled", hidden: "hidden", showing: "showing" }; class Lo extends Tt { /** * Create an instance of this class. * * @param {Object} [options={}] * Object of option names and values * * @param {string} [options.kind=''] * A valid kind for the track type you are creating. * * @param {string} [options.id='vjs_track_' + Guid.newGUID()] * A unique id for this AudioTrack. * * @param {string} [options.label=''] * The menu label for this track. * * @param {string} [options.language=''] * A valid two character language code. * * @abstract */ constructor(e = {}) { super(); const t = { id: e.id || "vjs_track_" + At(), kind: e.kind || "", language: e.language || "" }; let i = e.label || ""; for (const r in t) Object.defineProperty(this, r, { get() { return t[r]; }, set() { } }); Object.defineProperty(this, "label", { get() { return i; }, set(r) { r !== i && (i = r, this.trigger("labelchange")); } }); } } const Ro = function(s) { return new URL(s, se.baseURI); }, bd = function(s) { return new URL(s, se.baseURI).href; }, Mo = function(s) { if (typeof s == "string") { const t = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/.exec(s); if (t) return t.pop().toLowerCase(); } return ""; }, Gn = function(s, e = D.location) { return Ro(s).origin !== e.origin; }; var L0 = /* @__PURE__ */ Object.freeze({ __proto__: null, parseUrl: Ro, getAbsoluteURL: bd, getFileExtension: Mo, isCrossOrigin: Gn }); const Rl = function(s, e) { const t = new D.WebVTT.Parser(D, D.vttjs, D.WebVTT.StringDecoder()), i = []; t.oncue = function(r) { e.addCue(r); }, t.onparsingerror = function(r) { i.push(r); }, t.onflush = function() { e.trigger({ type: "loadeddata", target: e }); }, t.parse(s), i.length > 0 && (D.console && D.console.groupCollapsed && D.console.groupCollapsed(`Text Track parsing errors for ${e.src}`), i.forEach((r) => ye.error(r)), D.console && D.console.groupEnd && D.console.groupEnd()), t.flush(); }, Ml = function(s, e) { const t = { uri: s }, i = Gn(s); i && (t.cors = i); const r = e.tech_.crossOrigin() === "use-credentials"; r && (t.withCredentials = r), Ec(t, De(this, function(n, a, u) { if (n) return ye.error(n, a); e.loaded_ = true, typeof D.WebVTT != "function" ? e.tech_ && e.tech_.any(["vttjsloaded", "vttjserror"], (c) => { if (c.type === "vttjserror") { ye.error(`vttjs failed to load, stopping trying to process ${e.src}`); return; } return Rl(u, e); }) : Rl(u, e); })); }; class pr extends Lo { /** * Create an instance of this class. * * @param {Object} options={} * Object of option names and values * * @param {Tech} options.tech * A reference to the tech that owns this TextTrack. * * @param {TextTrack~Kind} [options.kind='subtitles'] * A valid text track kind. * * @param {TextTrack~Mode} [options.mode='disabled'] * A valid text track mode. * * @param {string} [options.id='vjs_track_' + Guid.newGUID()] * A unique id for this TextTrack. * * @param {string} [options.label=''] * The menu label for this track. * * @param {string} [options.language=''] * A valid two character language code. * * @param {string} [options.srclang=''] * A valid two character language code. An alternative, but deprioritized * version of `options.language` * * @param {string} [options.src] * A url to TextTrack cues. * * @param {boolean} [options.default] * If this track should default to on or off. */ constructor(e = {}) { if (!e.tech) throw new Error("A tech was not provided."); const t = Ce(e, { kind: O0[e.kind] || "subtitles", language: e.language || e.srclang || "" }); let i = Ll[t.mode] || "disabled"; const r = t.default; (t.kind === "metadata" || t.kind === "chapters") && (i = "hidden"), super(t), this.tech_ = t.tech, this.cues_ = [], this.activeCues_ = [], this.preload_ = this.tech_.preloadTextTracks !== false; const n = new pn(this.cues_), a = new pn(this.activeCues_); let u = false; this.timeupdateHandler = De(this, function(f = {}) { if (!this.tech_.isDisposed()) { if (!this.tech_.isReady_) { f.type !== "timeupdate" && (this.rvf_ = this.tech_.requestVideoFrameCallback(this.timeupdateHandler)); return; } this.activeCues = this.activeCues, u && (this.trigger("cuechange"), u = false), f.type !== "timeupdate" && (this.rvf_ = this.tech_.requestVideoFrameCallback(this.timeupdateHandler)); } }); const c = () => { this.stopTracking(); }; this.tech_.one("dispose", c), i !== "disabled" && this.startTracking(), Object.defineProperties(this, { /** * @memberof TextTrack * @member {boolean} default * If this track was set to be on or off by default. Cannot be changed after * creation. * @instance * * @readonly */ default: { get() { return r; }, set() { } }, /** * @memberof TextTrack * @member {string} mode * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will * not be set if setting to an invalid mode. * @instance * * @fires TextTrack#modechange */ mode: { get() { return i; }, set(f) { Ll[f] && i !== f && (i = f, !this.preload_ && i !== "disabled" && this.cues.length === 0 && Ml(this.src, this), this.stopTracking(), i !== "disabled" && this.startTracking(), this.trigger("modechange")); } }, /** * @memberof TextTrack * @member {TextTrackCueList} cues * The text track cue list for this TextTrack. * @instance */ cues: { get() { return this.loaded_ ? n : null; }, set() { } }, /** * @memberof TextTrack * @member {TextTrackCueList} activeCues * The list text track cues that are currently active for this TextTrack. * @instance */ activeCues: { get() { if (!this.loaded_) return null; if (this.cues.length === 0) return a; const f = this.tech_.currentTime(), g = []; for (let y = 0, I = this.cues.length; y < I; y++) { const C = this.cues[y]; C.startTime <= f && C.endTime >= f && g.push(C); } if (u = false, g.length !== this.activeCues_.length) u = true; else for (let y = 0; y < g.length; y++) this.activeCues_.indexOf(g[y]) === -1 && (u = true); return this.activeCues_ = g, a.setCues_(this.activeCues_), a; }, // /!\ Keep this setter empty (see the timeupdate handler above) set() { } } }), t.src ? (this.src = t.src, this.preload_ || (this.loaded_ = true), (this.preload_ || t.kind !== "subtitles" && t.kind !== "captions") && Ml(this.src, this)) : this.loaded_ = true; } startTracking() { this.rvf_ = this.tech_.requestVideoFrameCallback(this.timeupdateHandler), this.tech_.on("timeupdate", this.timeupdateHandler); } stopTracking() { this.rvf_ && (this.tech_.cancelVideoFrameCallback(this.rvf_), this.rvf_ = void 0), this.tech_.off("timeupdate", this.timeupdateHandler); } /** * Add a cue to the internal list of cues. * * @param {TextTrack~Cue} cue * The cue to add to our internal list */ addCue(e) { let t = e; if (!("getCueAsHTML" in t)) { t = new D.vttjs.VTTCue(e.startTime, e.endTime, e.text); for (const r in e) r in t || (t[r] = e[r]); t.id = e.id, t.originalCue_ = e; } const i = this.tech_.textTracks(); for (let r = 0; r < i.length; r++) i[r] !== this && i[r].removeCue(t); this.cues_.push(t), this.cues.setCues_(this.cues_); } /** * Remove a cue from our internal list * * @param {TextTrack~Cue} removeCue * The cue to remove from our internal list */ removeCue(e) { let t = this.cues_.length; for (; t--; ) { const i = this.cues_[t]; if (i === e || i.originalCue_ && i.originalCue_ === e) { this.cues_.splice(t, 1), this.cues.setCues_(this.cues_); break; } } } } pr.prototype.allowedEvents_ = { cuechange: "cuechange" }; class xd extends Lo { /** * Create an instance of this class. * * @param {Object} [options={}] * Object of option names and values * * @param {AudioTrack~Kind} [options.kind=''] * A valid audio track kind * * @param {string} [options.id='vjs_track_' + Guid.newGUID()] * A unique id for this AudioTrack. * * @param {string} [options.label=''] * The menu label for this track. * * @param {string} [options.language=''] * A valid two character language code. * * @param {boolean} [options.enabled] * If this track is the one that is currently playing. If this track is part of * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled. */ constructor(e = {}) { const t = Ce(e, { kind: P0[e.kind] || "" }); super(t); let i = false; Object.defineProperty(this, "enabled", { get() { return i; }, set(r) { typeof r != "boolean" || r === i || (i = r, this.trigger("enabledchange")); } }), t.enabled && (this.enabled = t.enabled), this.loaded_ = true; } } class Sd extends Lo { /** * Create an instance of this class. * * @param {Object} [options={}] * Object of option names and values * * @param {string} [options.kind=''] * A valid {@link VideoTrack~Kind} * * @param {string} [options.id='vjs_track_' + Guid.newGUID()] * A unique id for this AudioTrack. * * @param {string} [options.label=''] * The menu label for this track. * * @param {string} [options.language=''] * A valid two character language code. * * @param {boolean} [options.selected] * If this track is the one that is currently playing. */ constructor(e = {}) { const t = Ce(e, { kind: k0[e.kind] || "" }); super(t); let i = false; Object.defineProperty(this, "selected", { get() { return i; }, set(r) { typeof r != "boolean" || r === i || (i = r, this.trigger("selectedchange")); } }), t.selected && (this.selected = t.selected); } } class ui extends Tt { /** * Create an instance of this class. * * @param {Object} options={} * Object of option names and values * * @param {Tech} options.tech * A reference to the tech that owns this HTMLTrackElement. * * @param {TextTrack~Kind} [options.kind='subtitles'] * A valid text track kind. * * @param {TextTrack~Mode} [options.mode='disabled'] * A valid text track mode. * * @param {string} [options.id='vjs_track_' + Guid.newGUID()] * A unique id for this TextTrack. * * @param {string} [options.label=''] * The menu label for this track. * * @param {string} [options.language=''] * A valid two character language code. * * @param {string} [options.srclang=''] * A valid two character language code. An alternative, but deprioritized * version of `options.language` * * @param {string} [options.src] * A url to TextTrack cues. * * @param {boolean} [options.default] * If this track should default to on or off. */ constructor(e = {}) { super(); let t; const i = new pr(e); this.kind = i.kind, this.src = i.src, this.srclang = i.language, this.label = i.label, this.default = i.default, Object.defineProperties(this, { /** * @memberof HTMLTrackElement * @member {HTMLTrackElement~ReadyState} readyState * The current ready state of the track element. * @instance */ readyState: { get() { return t; } }, /** * @memberof HTMLTrackElement * @member {TextTrack} track * The underlying TextTrack object. * @instance * */ track: { get() { return i; } } }), t = ui.NONE, i.addEventListener("loadeddata", () => { t = ui.LOADED, this.trigger({ type: "load", target: this }); }); } } ui.prototype.allowedEvents_ = { load: "load" }; ui.NONE = 0; ui.LOADING = 1; ui.LOADED = 2; ui.ERROR = 3; const Ct = { audio: { ListClass: D0, TrackClass: xd, capitalName: "Audio" }, video: { ListClass: w0, TrackClass: Sd, capitalName: "Video" }, text: { ListClass: vd, TrackClass: pr, capitalName: "Text" } }; Object.keys(Ct).forEach(function(s) { Ct[s].getterName = `${s}Tracks`, Ct[s].privateName = `${s}Tracks_`; }); const bs = { remoteText: { ListClass: vd, TrackClass: pr, capitalName: "RemoteText", getterName: "remoteTextTracks", privateName: "remoteTextTracks_" }, remoteTextEl: { ListClass: I0, TrackClass: ui, capitalName: "RemoteTextTrackEls", getterName: "remoteTextTrackEls", privateName: "remoteTextTrackEls_" } }, ut = Object.assign({}, Ct, bs); bs.names = Object.keys(bs); Ct.names = Object.keys(Ct); ut.names = [].concat(bs.names).concat(Ct.names); function R0(s, e, t, i, r = {}) { const n = s.textTracks(); r.kind = e, t && (r.label = t), i && (r.language = i), r.tech = s; const a = new ut.text.TrackClass(r); return n.addTrack(a), a; } class pe extends K { /** * Create an instance of this Tech. * * @param {Object} [options] * The key/value store of player options. * * @param {Function} [ready] * Callback function to call when the `HTML5` Tech is ready. */ constructor(e = {}, t = function() { }) { e.reportTouchActivity = false, super(null, e, t), this.onDurationChange_ = (i) => this.onDurationChange(i), this.trackProgress_ = (i) => this.trackProgress(i), this.trackCurrentTime_ = (i) => this.trackCurrentTime(i), this.stopTrackingCurrentTime_ = (i) => this.stopTrackingCurrentTime(i), this.disposeSourceHandler_ = (i) => this.disposeSourceHandler(i), this.queuedHanders_ = /* @__PURE__ */ new Set(), this.hasStarted_ = false, this.on("playing", function() { this.hasStarted_ = true; }), this.on("loadstart", function() { this.hasStarted_ = false; }), ut.names.forEach((i) => { const r = ut[i]; e && e[r.getterName] && (this[r.privateName] = e[r.getterName]); }), this.featuresProgressEvents || this.manualProgressOn(), this.featuresTimeupdateEvents || this.manualTimeUpdatesOn(), ["Text", "Audio", "Video"].forEach((i) => { e[`native${i}Tracks`] === false && (this[`featuresNative${i}Tracks`] = false); }), e.nativeCaptions === false || e.nativeTextTracks === false ? this.featuresNativeTextTracks = false : (e.nativeCaptions === true || e.nativeTextTracks === true) && (this.featuresNativeTextTracks = true), this.featuresNativeTextTracks || this.emulateTextTracks(), this.preloadTextTracks = e.preloadTextTracks !== false, this.autoRemoteTextTracks_ = new ut.text.ListClass(), this.initTrackListeners(), e.nativeControlsForTouch || this.emitTapEvents(), this.constructor && (this.name_ = this.constructor.name || "Unknown Tech"); } /** * A special function to trigger source set in a way that will allow player * to re-trigger if the player or tech are not ready yet. * * @fires Tech#sourceset * @param {string} src The source string at the time of the source changing. */ triggerSourceset(e) { this.isReady_ || this.one("ready", () => this.setTimeout(() => this.triggerSourceset(e), 1)), this.trigger({ src: e, type: "sourceset" }); } /* Fallbacks for unsupported event types ================================================================================ */ /** * Polyfill the `progress` event for browsers that don't support it natively. * * @see {@link Tech#trackProgress} */ manualProgressOn() { this.on("durationchange", this.onDurationChange_), this.manualProgress = true, this.one("ready", this.trackProgress_); } /** * Turn off the polyfill for `progress` events that was created in * {@link Tech#manualProgressOn} */ manualProgressOff() { this.manualProgress = false, this.stopTrackingProgress(), this.off("durationchange", this.onDurationChange_); } /** * This is used to trigger a `progress` event when the buffered percent changes. It * sets an interval function that will be called every 500 milliseconds to check if the * buffer end percent has changed. * * > This function is called by {@link Tech#manualProgressOn} * * @param {Event} event * The `ready` event that caused this to run. * * @listens Tech#ready * @fires Tech#progress */ trackProgress(e) { this.stopTrackingProgress(), this.progressInterval = this.setInterval(De(this, function() { const t = this.bufferedPercent(); this.bufferedPercent_ !== t && this.trigger("progress"), this.bufferedPercent_ = t, t === 1 && this.stopTrackingProgress(); }), 500); } /** * Update our internal duration on a `durationchange` event by calling * {@link Tech#duration}. * * @param {Event} event * The `durationchange` event that caused this to run. * * @listens Tech#durationchange */ onDurationChange(e) { this.duration_ = this.duration(); } /** * Get and create a `TimeRange` object for buffering. * * @return {TimeRange} * The time range object that was created. */ buffered() { return Nt(0, 0); } /** * Get the percentage of the current video that is currently buffered. * * @return {number} * A number from 0 to 1 that represents the decimal percentage of the * video that is buffered. * */ bufferedPercent() { return Td(this.buffered(), this.duration_); } /** * Turn off the polyfill for `progress` events that was created in * {@link Tech#manualProgressOn} * Stop manually tracking progress events by clearing the interval that was set in * {@link Tech#trackProgress}. */ stopTrackingProgress() { this.clearInterval(this.progressInterval); } /** * Polyfill the `timeupdate` event for browsers that don't support it. * * @see {@link Tech#trackCurrentTime} */ manualTimeUpdatesOn() { this.manualTimeUpdates = true, this.on("play", this.trackCurrentTime_), this.on("pause", this.stopTrackingCurrentTime_); } /** * Turn off the polyfill for `timeupdate` events that was created in * {@link Tech#manualTimeUpdatesOn} */ manualTimeUpdatesOff() { this.manualTimeUpdates = false, this.stopTrackingCurrentTime(), this.off("play", this.trackCurrentTime_), this.off("pause", this.stopTrackingCurrentTime_); } /** * Sets up an interval function to track current time and trigger `timeupdate` every * 250 milliseconds. * * @listens Tech#play * @triggers Tech#timeupdate */ trackCurrentTime() { this.currentTimeInterval && this.stopTrackingCurrentTime(), this.currentTimeInterval = this.setInterval(function() { this.trigger({ type: "timeupdate", target: this, manuallyTriggered: true }); }, 250); } /** * Stop the interval function created in {@link Tech#trackCurrentTime} so that the * `timeupdate` event is no longer triggered. * * @listens {Tech#pause} */ stopTrackingCurrentTime() { this.clearInterval(this.currentTimeInterval), this.trigger({ type: "timeupdate", target: this, manuallyTriggered: true }); } /** * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList}, * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech. * * @fires Component#dispose */ dispose() { this.clearTracks(Ct.names), this.manualProgress && this.manualProgressOff(), this.manualTimeUpdates && this.manualTimeUpdatesOff(), super.dispose(); } /** * Clear out a single `TrackList` or an array of `TrackLists` given their names. * * > Note: Techs without source handlers should call this between sources for `video` * & `audio` tracks. You don't want to use them between tracks! * * @param {string[]|string} types * TrackList names to clear, valid names are `video`, `audio`, and * `text`. */ clearTracks(e) { e = [].concat(e), e.forEach((t) => { const i = this[`${t}Tracks`]() || []; let r = i.length; for (; r--; ) { const n = i[r]; t === "text" && this.removeRemoteTextTrack(n), i.removeTrack(n); } }); } /** * Remove any TextTracks added via addRemoteTextTrack that are * flagged for automatic garbage collection */ cleanupAutoTextTracks() { const e = this.autoRemoteTextTracks_ || []; let t = e.length; for (; t--; ) { const i = e[t]; this.removeRemoteTextTrack(i); } } /** * Reset the tech, which will removes all sources and reset the internal readyState. * * @abstract */ reset() { } /** * Get the value of `crossOrigin` from the tech. * * @abstract * * @see {Html5#crossOrigin} */ crossOrigin() { } /** * Set the value of `crossOrigin` on the tech. * * @abstract * * @param {string} crossOrigin the crossOrigin value * @see {Html5#setCrossOrigin} */ setCrossOrigin() { } /** * Get or set an error on the Tech. * * @param {MediaError} [err] * Error to set on the Tech * * @return {MediaError|null} * The current error object on the tech, or null if there isn't one. */ error(e) { return e !== void 0 && (this.error_ = new Re(e), this.trigger("error")), this.error_; } /** * Returns the `TimeRange`s that have been played through for the current source. * * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`. * It only checks whether the source has played at all or not. * * @return {TimeRange} * - A single time range if this video has played * - An empty set of ranges if not. */ played() { return this.hasStarted_ ? Nt(0, 0) : Nt(); } /** * Start playback * * @abstract * * @see {Html5#play} */ play() { } /** * Set whether we are scrubbing or not * * @abstract * @param {boolean} _isScrubbing * - true for we are currently scrubbing * - false for we are no longer scrubbing * * @see {Html5#setScrubbing} */ setScrubbing(e) { } /** * Get whether we are scrubbing or not * * @abstract * * @see {Html5#scrubbing} */ scrubbing() { } /** * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was * previously called. * * @param {number} _seconds * Set the current time of the media to this. * @fires Tech#timeupdate */ setCurrentTime(e) { this.manualTimeUpdates && this.trigger({ type: "timeupdate", target: this, manuallyTriggered: true }); } /** * Turn on listeners for {@link VideoTrackList}, {@link {AudioTrackList}, and * {@link TextTrackList} events. * * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`. * * @fires Tech#audiotrackchange * @fires Tech#videotrackchange * @fires Tech#texttrackchange */ initTrackListeners() { Ct.names.forEach((e) => { const t = Ct[e], i = () => { this.trigger(`${e}trackchange`); }, r = this[t.getterName](); r.addEventListener("removetrack", i), r.addEventListener("addtrack", i), this.on("dispose", () => { r.removeEventListener("removetrack", i), r.removeEventListener("addtrack", i); }); }); } /** * Emulate TextTracks using vtt.js if necessary * * @fires Tech#vttjsloaded * @fires Tech#vttjserror */ addWebVttScript_() { if (!D.WebVTT) if (se.body.contains(this.el())) { if (!this.options_["vtt.js"] && gs(rl) && Object.keys(rl).length > 0) { this.trigger("vttjsloaded"); return; } const e = se.createElement("script"); e.src = this.options_["vtt.js"] || "https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js", e.onload = () => { this.trigger("vttjsloaded"); }, e.onerror = () => { this.trigger("vttjserror"); }, this.on("dispose", () => { e.onload = null, e.onerror = null; }), D.WebVTT = true, this.el().parentNode.appendChild(e); } else this.ready(this.addWebVttScript_); } /** * Emulate texttracks * */ emulateTextTracks() { const e = this.textTracks(), t = this.remoteTextTracks(), i = (u) => e.addTrack(u.track), r = (u) => e.removeTrack(u.track); t.on("addtrack", i), t.on("removetrack", r), this.addWebVttScript_(); const n = () => this.trigger("texttrackchange"), a = () => { n(); for (let u = 0; u < e.length; u++) { const c = e[u]; c.removeEventListener("cuechange", n), c.mode === "showing" && c.addEventListener("cuechange", n); } }; a(), e.addEventListener("change", a), e.addEventListener("addtrack", a), e.addEventListener("removetrack", a), this.on("dispose", function() { t.off("addtrack", i), t.off("removetrack", r), e.removeEventListener("change", a), e.removeEventListener("addtrack", a), e.removeEventListener("removetrack", a); for (let u = 0; u < e.length; u++) e[u].removeEventListener("cuechange", n); }); } /** * Create and returns a remote {@link TextTrack} object. * * @param {string} kind * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) * * @param {string} [label] * Label to identify the text track * * @param {string} [language] * Two letter language abbreviation * * @return {TextTrack} * The TextTrack that gets created. */ addTextTrack(e, t, i) { if (!e) throw new Error("TextTrack kind is required but was not provided"); return R0(this, e, t, i); } /** * Create an emulated TextTrack for use by addRemoteTextTrack * * This is intended to be overridden by classes that inherit from * Tech in order to create native or custom TextTracks. * * @param {Object} options * The object should contain the options to initialize the TextTrack with. * * @param {string} [options.kind] * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata). * * @param {string} [options.label]. * Label to identify the text track * * @param {string} [options.language] * Two letter language abbreviation. * * @return {HTMLTrackElement} * The track element that gets created. */ createRemoteTextTrack(e) { const t = Ce(e, { tech: this }); return new bs.remoteTextEl.TrackClass(t); } /** * Creates a remote text track object and returns an html track element. * * > Note: This can be an emulated {@link HTMLTrackElement} or a native one. * * @param {Object} options * See {@link Tech#createRemoteTextTrack} for more detailed properties. * * @param {boolean} [manualCleanup=false] * - When false: the TextTrack will be automatically removed from the video * element whenever the source changes * - When True: The TextTrack will have to be cleaned up manually * * @return {HTMLTrackElement} * An Html Track Element. * */ addRemoteTextTrack(e = {}, t) { const i = this.createRemoteTextTrack(e); return typeof t != "boolean" && (t = false), this.remoteTextTrackEls().addTrackElement_(i), this.remoteTextTracks().addTrack(i.track), t === false && this.ready(() => this.autoRemoteTextTracks_.addTrack(i.track)), i; } /** * Remove a remote text track from the remote `TextTrackList`. * * @param {TextTrack} track * `TextTrack` to remove from the `TextTrackList` */ removeRemoteTextTrack(e) { const t = this.remoteTextTrackEls().getTrackElementByTrack_(e); this.remoteTextTrackEls().removeTrackElement_(t), this.remoteTextTracks().removeTrack(e), this.autoRemoteTextTracks_.removeTrack(e); } /** * Gets available media playback quality metrics as specified by the W3C's Media * Playback Quality API. * * @see [Spec]{@link https://wicg.github.io/media-playback-quality} * * @return {Object} * An object with supported media playback quality metrics * * @abstract */ getVideoPlaybackQuality() { return {}; } /** * Attempt to create a floating video window always on top of other windows * so that users may continue consuming media while they interact with other * content sites, or applications on their device. * * @see [Spec]{@link https://wicg.github.io/picture-in-picture} * * @return {Promise|undefined} * A promise with a Picture-in-Picture window if the browser supports * Promises (or one was passed in as an option). It returns undefined * otherwise. * * @abstract */ requestPictureInPicture() { return Promise.reject(); } /** * A method to check for the value of the 'disablePictureInPicture'