itube-modern-player 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -1
- package/dist/core.cjs +3 -3
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +516 -356
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/itube-modern-player.iife.js +3 -3
- package/dist/itube-modern-player.iife.js.map +1 -1
- package/dist/{labels-C3gAZEm-.js → labels-DZFT0XMa.js} +5 -1
- package/dist/labels-DZFT0XMa.js.map +1 -0
- package/dist/labels-y0IHe3i9.cjs +2 -0
- package/dist/labels-y0IHe3i9.cjs.map +1 -0
- package/dist/locales.cjs +1 -1
- package/dist/locales.cjs.map +1 -1
- package/dist/locales.js +44 -4
- package/dist/locales.js.map +1 -1
- package/dist/player.d.ts +18 -1
- package/dist/style.css +1 -1
- package/dist/types.d.ts +55 -1
- package/dist/ui/controls.d.ts +16 -1
- package/dist/ui/menu.d.ts +15 -5
- package/dist/ui/overlays.d.ts +12 -0
- package/package.json +1 -1
- package/dist/labels-C3gAZEm-.js.map +0 -1
- package/dist/labels-DTgTxMuq.cjs +0 -2
- package/dist/labels-DTgTxMuq.cjs.map +0 -1
package/dist/core.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import { d as
|
|
2
|
-
function
|
|
3
|
-
const i = document.createElement(
|
|
1
|
+
import { d as q } from "./labels-DZFT0XMa.js";
|
|
2
|
+
function o(l, t, e) {
|
|
3
|
+
const i = document.createElement(l);
|
|
4
4
|
if (t && (i.className = t), e)
|
|
5
5
|
for (const [s, n] of Object.entries(e)) i.setAttribute(s, n);
|
|
6
6
|
return i;
|
|
7
7
|
}
|
|
8
|
-
function f(
|
|
9
|
-
const i =
|
|
8
|
+
function f(l, t, e) {
|
|
9
|
+
const i = o("button", `imp-btn ${l}`, { type: "button", "aria-label": t, title: t });
|
|
10
10
|
return i.innerHTML = e, i;
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
|
|
12
|
+
function E(l, t, e) {
|
|
13
|
+
l.innerHTML = t, e !== void 0 && (l.setAttribute("aria-label", e), l.setAttribute("title", e));
|
|
14
14
|
}
|
|
15
|
-
function w(
|
|
16
|
-
return Math.min(e, Math.max(t,
|
|
15
|
+
function w(l, t, e) {
|
|
16
|
+
return Math.min(e, Math.max(t, l));
|
|
17
17
|
}
|
|
18
|
-
function x(
|
|
19
|
-
if (!Number.isFinite(
|
|
20
|
-
const t = Math.floor(
|
|
18
|
+
function x(l) {
|
|
19
|
+
if (!Number.isFinite(l) || l < 0) return "0:00";
|
|
20
|
+
const t = Math.floor(l % 60), e = Math.floor(l / 60 % 60), i = Math.floor(l / 3600), s = i > 0 ? String(e).padStart(2, "0") : String(e), n = String(t).padStart(2, "0");
|
|
21
21
|
return i > 0 ? `${i}:${s}:${n}` : `${s}:${n}`;
|
|
22
22
|
}
|
|
23
|
-
function
|
|
24
|
-
const t =
|
|
23
|
+
function I(l) {
|
|
24
|
+
const t = l.trim().match(/^(?:(\d+):)?(\d{1,2}):(\d{2})(?:[.,](\d{1,3}))?$/);
|
|
25
25
|
if (!t) return null;
|
|
26
26
|
const e = t[1] ? Number(t[1]) : 0, i = Number(t[2]), s = Number(t[3]), n = t[4] ? Number(t[4].padEnd(3, "0")) : 0;
|
|
27
27
|
return e * 3600 + i * 60 + s + n / 1e3;
|
|
28
28
|
}
|
|
29
|
-
function Q(
|
|
30
|
-
const t = [], e =
|
|
29
|
+
function Q(l) {
|
|
30
|
+
const t = [], e = l.replace(/\r\n?/g, `
|
|
31
31
|
`).split(/\n\n+/);
|
|
32
32
|
for (const i of e) {
|
|
33
33
|
const s = i.split(`
|
|
@@ -35,7 +35,7 @@ function Q(o) {
|
|
|
35
35
|
if (s.length === 0) continue;
|
|
36
36
|
let n = s.findIndex((p) => p.includes("-->"));
|
|
37
37
|
if (n === -1) continue;
|
|
38
|
-
const [r,
|
|
38
|
+
const [r, a] = s[n].split("-->"), h = I(r), c = I((a ?? "").split(" ")[1] ?? a ?? "") ?? I(a ?? "");
|
|
39
39
|
if (h === null || c === null) continue;
|
|
40
40
|
const u = s.slice(n + 1).join(`
|
|
41
41
|
`).trim();
|
|
@@ -43,14 +43,14 @@ function Q(o) {
|
|
|
43
43
|
}
|
|
44
44
|
return t;
|
|
45
45
|
}
|
|
46
|
-
function
|
|
46
|
+
function X(l, t) {
|
|
47
47
|
try {
|
|
48
|
-
return new URL(
|
|
48
|
+
return new URL(l, new URL(t, window.location.href)).toString();
|
|
49
49
|
} catch {
|
|
50
|
-
return
|
|
50
|
+
return l;
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
class
|
|
53
|
+
class K {
|
|
54
54
|
constructor() {
|
|
55
55
|
this.listeners = /* @__PURE__ */ new Map();
|
|
56
56
|
}
|
|
@@ -82,7 +82,7 @@ class X {
|
|
|
82
82
|
this.listeners.clear();
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
const v = (
|
|
85
|
+
const v = (l, t = "0 0 24 24") => `<svg viewBox="${t}" fill="currentColor" aria-hidden="true" focusable="false">${l}</svg>`, J = {
|
|
86
86
|
play: v('<path d="M8 5.14v13.72c0 .8.87 1.3 1.56.88l10.54-6.86a1.05 1.05 0 0 0 0-1.76L9.56 4.26C8.87 3.84 8 4.34 8 5.14Z"/>'),
|
|
87
87
|
pause: v('<rect x="6" y="5" width="4" height="14" rx="1"/><rect x="14" y="5" width="4" height="14" rx="1"/>'),
|
|
88
88
|
replay: v('<path d="M12 5V2.5L7.5 6 12 9.5V7a5 5 0 1 1-5 5H5a7 7 0 1 0 7-7Z"/>'),
|
|
@@ -113,25 +113,25 @@ const v = (o, t = "0 0 24 24") => `<svg viewBox="${t}" fill="currentColor" aria-
|
|
|
113
113
|
report: v('<path d="M5 3h2v18H5V3Zm4 1h10l-2.5 4L19 12H9V4Z"/>'),
|
|
114
114
|
more: v('<circle cx="12" cy="5" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="12" cy="19" r="2"/>'),
|
|
115
115
|
close: v('<path d="m6.4 5 5.6 5.6L17.6 5 19 6.4 13.4 12l5.6 5.6-1.4 1.4-5.6-5.6L6.4 19 5 17.6 10.6 12 5 6.4 6.4 5Z"/>')
|
|
116
|
-
}, P = { en:
|
|
117
|
-
function
|
|
118
|
-
P[
|
|
116
|
+
}, P = { en: q };
|
|
117
|
+
function _t(l, t) {
|
|
118
|
+
P[l] = t;
|
|
119
119
|
}
|
|
120
|
-
function
|
|
121
|
-
for (const [t, e] of Object.entries(
|
|
120
|
+
function Lt(l) {
|
|
121
|
+
for (const [t, e] of Object.entries(l))
|
|
122
122
|
e && (P[t] = e);
|
|
123
123
|
}
|
|
124
|
-
function
|
|
125
|
-
return
|
|
124
|
+
function Y(l) {
|
|
125
|
+
return l && P[l] || q;
|
|
126
126
|
}
|
|
127
|
-
function
|
|
127
|
+
function Bt() {
|
|
128
128
|
return Object.keys(P);
|
|
129
129
|
}
|
|
130
|
-
function
|
|
131
|
-
if (
|
|
130
|
+
function tt(l, t, e = 100) {
|
|
131
|
+
if (l.length === 0 || !Number.isFinite(t) || t <= 0) return [];
|
|
132
132
|
const i = new Array(e).fill(0);
|
|
133
133
|
let s = !1;
|
|
134
|
-
for (const c of
|
|
134
|
+
for (const c of l) {
|
|
135
135
|
if (!Number.isFinite(c.time) || c.time < 0 || c.time > t) continue;
|
|
136
136
|
const u = Math.max(0, c.value);
|
|
137
137
|
if (u === 0) continue;
|
|
@@ -140,93 +140,93 @@ function Y(o, t, e = 100) {
|
|
|
140
140
|
}
|
|
141
141
|
if (!s) return [];
|
|
142
142
|
const n = [0.06, 0.24, 0.4, 0.24, 0.06], r = i.map(
|
|
143
|
-
(c, u) => n.reduce((p, m,
|
|
144
|
-
),
|
|
145
|
-
if (
|
|
143
|
+
(c, u) => n.reduce((p, m, y) => p + m * (i[u + y - 2] ?? 0), 0)
|
|
144
|
+
), a = Math.max(...r);
|
|
145
|
+
if (a <= 0) return [];
|
|
146
146
|
const h = 0.08;
|
|
147
|
-
return r.map((c) => h + (1 - h) * (c /
|
|
147
|
+
return r.map((c) => h + (1 - h) * (c / a));
|
|
148
148
|
}
|
|
149
|
-
function
|
|
150
|
-
if (
|
|
151
|
-
const i = t / (
|
|
149
|
+
function et(l, t = 1e3, e = 100) {
|
|
150
|
+
if (l.length === 0) return "";
|
|
151
|
+
const i = t / (l.length - 1 || 1);
|
|
152
152
|
let s = `M 0 ${e}`;
|
|
153
|
-
return
|
|
153
|
+
return l.forEach((n, r) => {
|
|
154
154
|
s += ` L ${(r * i).toFixed(1)} ${(e - n * e).toFixed(1)}`;
|
|
155
155
|
}), s += ` L ${t} ${e} Z`, s;
|
|
156
156
|
}
|
|
157
|
-
async function
|
|
158
|
-
if (
|
|
157
|
+
async function it(l, t) {
|
|
158
|
+
if (l.src)
|
|
159
159
|
return {
|
|
160
|
-
roll:
|
|
161
|
-
mediaUrl:
|
|
162
|
-
clickThrough:
|
|
160
|
+
roll: l.roll,
|
|
161
|
+
mediaUrl: l.src,
|
|
162
|
+
clickThrough: l.clickUrl,
|
|
163
163
|
impressions: [],
|
|
164
164
|
tracking: {}
|
|
165
165
|
};
|
|
166
|
-
if (!
|
|
167
|
-
return z(
|
|
166
|
+
if (!l.vastTag) throw new Error('Ad roll has neither "vastTag" nor "src"');
|
|
167
|
+
return z(l, l.vastTag, t, 0, { impressions: [], tracking: {} });
|
|
168
168
|
}
|
|
169
|
-
async function z(
|
|
169
|
+
async function z(l, t, e, i, s) {
|
|
170
170
|
if (i > e.maxWrapperDepth) throw new Error("VAST wrapper depth limit exceeded");
|
|
171
171
|
const n = new AbortController(), r = setTimeout(() => n.abort(), e.requestTimeout);
|
|
172
|
-
let
|
|
172
|
+
let a;
|
|
173
173
|
try {
|
|
174
174
|
const g = await fetch(t, { signal: n.signal, credentials: "omit" });
|
|
175
175
|
if (!g.ok) throw new Error(`VAST request failed (${g.status})`);
|
|
176
|
-
|
|
176
|
+
a = await g.text();
|
|
177
177
|
} finally {
|
|
178
178
|
clearTimeout(r);
|
|
179
179
|
}
|
|
180
|
-
const h = new DOMParser().parseFromString(
|
|
180
|
+
const h = new DOMParser().parseFromString(a, "text/xml");
|
|
181
181
|
if (h.querySelector("parsererror")) throw new Error("VAST response is not valid XML");
|
|
182
182
|
const c = h.querySelector("VAST > Ad");
|
|
183
183
|
if (!c) throw new Error("VAST response contains no ads");
|
|
184
|
-
|
|
184
|
+
st(c, s);
|
|
185
185
|
const u = c.querySelector(":scope > Wrapper");
|
|
186
186
|
if (u) {
|
|
187
|
-
const g =
|
|
187
|
+
const g = S(u.querySelector("VASTAdTagURI"));
|
|
188
188
|
if (!g) throw new Error("VAST wrapper without VASTAdTagURI");
|
|
189
|
-
return z(
|
|
189
|
+
return z(l, g, e, i + 1, s);
|
|
190
190
|
}
|
|
191
191
|
const p = c.querySelector(":scope > InLine");
|
|
192
192
|
if (!p) throw new Error("VAST ad has neither InLine nor Wrapper");
|
|
193
193
|
const m = p.querySelector("Creatives > Creative > Linear");
|
|
194
194
|
if (!m) throw new Error("VAST ad has no Linear creative");
|
|
195
|
-
const
|
|
196
|
-
if (!
|
|
195
|
+
const y = nt(m);
|
|
196
|
+
if (!y) throw new Error("VAST ad has no playable MediaFile");
|
|
197
197
|
return {
|
|
198
|
-
roll:
|
|
199
|
-
mediaUrl:
|
|
200
|
-
mediaType:
|
|
201
|
-
clickThrough:
|
|
202
|
-
duration: N(
|
|
203
|
-
skipOffset:
|
|
198
|
+
roll: l.roll,
|
|
199
|
+
mediaUrl: y.url,
|
|
200
|
+
mediaType: y.type,
|
|
201
|
+
clickThrough: S(m.querySelector("VideoClicks > ClickThrough")) ?? l.clickUrl,
|
|
202
|
+
duration: N(S(m.querySelector(":scope > Duration"))),
|
|
203
|
+
skipOffset: rt(
|
|
204
204
|
m.getAttribute("skipoffset"),
|
|
205
|
-
N(
|
|
205
|
+
N(S(m.querySelector(":scope > Duration")))
|
|
206
206
|
),
|
|
207
207
|
impressions: s.impressions,
|
|
208
208
|
tracking: s.tracking,
|
|
209
|
-
adTitle:
|
|
209
|
+
adTitle: S(p.querySelector(":scope > AdTitle")) ?? void 0
|
|
210
210
|
};
|
|
211
211
|
}
|
|
212
|
-
function
|
|
212
|
+
function st(l, t) {
|
|
213
213
|
var e, i;
|
|
214
|
-
for (const s of
|
|
215
|
-
const n =
|
|
214
|
+
for (const s of l.querySelectorAll("Impression")) {
|
|
215
|
+
const n = S(s);
|
|
216
216
|
n && t.impressions.push(n);
|
|
217
217
|
}
|
|
218
|
-
for (const s of
|
|
219
|
-
const n = s.getAttribute("event"), r =
|
|
218
|
+
for (const s of l.querySelectorAll("Linear > TrackingEvents > Tracking")) {
|
|
219
|
+
const n = s.getAttribute("event"), r = S(s);
|
|
220
220
|
!n || !r || ["start", "firstQuartile", "midpoint", "thirdQuartile", "complete", "skip", "pause", "resume"].includes(n) && ((e = t.tracking)[n] ?? (e[n] = [])).push(r);
|
|
221
221
|
}
|
|
222
|
-
for (const s of
|
|
223
|
-
const n =
|
|
222
|
+
for (const s of l.querySelectorAll("Linear > VideoClicks > ClickTracking")) {
|
|
223
|
+
const n = S(s);
|
|
224
224
|
n && ((i = t.tracking).click ?? (i.click = [])).push(n);
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
|
-
function
|
|
228
|
-
const e = [...
|
|
229
|
-
url:
|
|
227
|
+
function nt(l) {
|
|
228
|
+
const e = [...l.querySelectorAll("MediaFiles > MediaFile")].map((r) => ({
|
|
229
|
+
url: S(r) ?? "",
|
|
230
230
|
type: r.getAttribute("type") ?? void 0,
|
|
231
231
|
delivery: r.getAttribute("delivery") ?? "",
|
|
232
232
|
bitrate: Number(r.getAttribute("bitrate") ?? 0),
|
|
@@ -235,33 +235,33 @@ function st(o) {
|
|
|
235
235
|
(r) => !r.type || /(video\/(mp4|webm|ogg)|application\/(x-mpegurl|vnd\.apple\.mpegurl))/i.test(r.type)
|
|
236
236
|
);
|
|
237
237
|
if (e.length === 0) return null;
|
|
238
|
-
e.sort((r,
|
|
238
|
+
e.sort((r, a) => r.bitrate - a.bitrate);
|
|
239
239
|
const i = e.filter((r) => r.delivery !== "streaming"), s = i.length > 0 ? i : e, n = s[Math.floor(s.length / 2)];
|
|
240
240
|
return { url: n.url, type: n.type };
|
|
241
241
|
}
|
|
242
|
-
function N(
|
|
243
|
-
if (!
|
|
244
|
-
const t =
|
|
242
|
+
function N(l) {
|
|
243
|
+
if (!l) return;
|
|
244
|
+
const t = l.trim().match(/^(?:(\d+):)?(\d{1,2}):(\d{2})(?:\.(\d{1,3}))?$/);
|
|
245
245
|
if (t)
|
|
246
246
|
return (t[1] ? Number(t[1]) * 3600 : 0) + Number(t[2]) * 60 + Number(t[3]) + (t[4] ? Number(t[4].padEnd(3, "0")) / 1e3 : 0);
|
|
247
247
|
}
|
|
248
|
-
function
|
|
249
|
-
if (!
|
|
250
|
-
const e =
|
|
251
|
-
return e ? t !== void 0 ? Number(e[1]) / 100 * t : void 0 : N(
|
|
248
|
+
function rt(l, t) {
|
|
249
|
+
if (!l) return;
|
|
250
|
+
const e = l.trim().match(/^(\d+(?:\.\d+)?)%$/);
|
|
251
|
+
return e ? t !== void 0 ? Number(e[1]) / 100 * t : void 0 : N(l);
|
|
252
252
|
}
|
|
253
|
-
function
|
|
254
|
-
if (
|
|
255
|
-
for (const t of
|
|
253
|
+
function M(l) {
|
|
254
|
+
if (l)
|
|
255
|
+
for (const t of l)
|
|
256
256
|
try {
|
|
257
257
|
new Image().src = t;
|
|
258
258
|
} catch {
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
|
-
function
|
|
262
|
-
return
|
|
261
|
+
function S(l) {
|
|
262
|
+
return l?.textContent?.trim().replace(/^<!\[CDATA\[|\]\]>$/g, "").trim() || null;
|
|
263
263
|
}
|
|
264
|
-
class
|
|
264
|
+
class ot {
|
|
265
265
|
constructor(t, e) {
|
|
266
266
|
this.host = t, this.playedRolls = /* @__PURE__ */ new Set(), this.sourcesSeen = 0, this.activeBreak = null, this.layer = null, this.adVideo = null, this.destroyed = !1, this.opts = {
|
|
267
267
|
skipDelay: 5,
|
|
@@ -280,7 +280,7 @@ class rt {
|
|
|
280
280
|
*/
|
|
281
281
|
ensureAdVideo() {
|
|
282
282
|
if (!this.adVideo) {
|
|
283
|
-
this.adVideo =
|
|
283
|
+
this.adVideo = o("video", "imp-ad__video", { playsinline: "" });
|
|
284
284
|
try {
|
|
285
285
|
this.adVideo.load();
|
|
286
286
|
} catch {
|
|
@@ -328,11 +328,11 @@ class rt {
|
|
|
328
328
|
for (const n of t) {
|
|
329
329
|
this.playedRolls.add(n);
|
|
330
330
|
try {
|
|
331
|
-
const r = await
|
|
331
|
+
const r = await it(n, this.opts);
|
|
332
332
|
await this.playAd(r);
|
|
333
333
|
} catch (r) {
|
|
334
|
-
const
|
|
335
|
-
this.host.emitter.emit("aderror", { roll: n, error:
|
|
334
|
+
const a = r instanceof Error ? r : new Error(String(r));
|
|
335
|
+
this.host.emitter.emit("aderror", { roll: n, error: a });
|
|
336
336
|
}
|
|
337
337
|
if (this.destroyed) return;
|
|
338
338
|
}
|
|
@@ -345,28 +345,28 @@ class rt {
|
|
|
345
345
|
}
|
|
346
346
|
playAd(t) {
|
|
347
347
|
return new Promise((e) => {
|
|
348
|
-
const { labels: i } = this.host, s =
|
|
348
|
+
const { labels: i } = this.host, s = o("div", "imp-ad"), n = this.ensureAdVideo(), r = new AbortController(), a = r.signal;
|
|
349
349
|
n.src = t.mediaUrl, n.muted = this.host.contentVideo.muted, n.volume = this.host.contentVideo.volume;
|
|
350
|
-
const h =
|
|
350
|
+
const h = o("div", "imp-spinner imp-ad__spinner"), c = o("div", "imp-ad__hud"), u = o("span", "imp-ad__badge");
|
|
351
351
|
u.textContent = t.adTitle ? `${i.adLabel} · ${t.adTitle}` : i.adLabel;
|
|
352
|
-
const p =
|
|
352
|
+
const p = o("span", "imp-ad__countdown");
|
|
353
353
|
c.append(u, p);
|
|
354
|
-
const m =
|
|
355
|
-
let
|
|
356
|
-
t.clickThrough && (
|
|
357
|
-
const g =
|
|
354
|
+
const m = o("div", "imp-ad__actions");
|
|
355
|
+
let y = null;
|
|
356
|
+
t.clickThrough && (y = o("button", "imp-ad__visit", { type: "button" }), y.textContent = i.visitAdvertiser, m.append(y));
|
|
357
|
+
const g = o("button", "imp-ad__skip", { type: "button" });
|
|
358
358
|
g.hidden = !0, m.append(g), s.append(n, h, c, m), this.host.container.append(s), this.layer = s;
|
|
359
|
-
const
|
|
360
|
-
d.has(k) || (d.add(k),
|
|
359
|
+
const T = t.skipOffset ?? this.opts.skipDelay, d = /* @__PURE__ */ new Set(), b = (k) => {
|
|
360
|
+
d.has(k) || (d.add(k), M(t.tracking[k]));
|
|
361
361
|
};
|
|
362
|
-
let A = Date.now(),
|
|
362
|
+
let A = Date.now(), V = -1;
|
|
363
363
|
const j = setInterval(() => {
|
|
364
364
|
if (n.paused) {
|
|
365
365
|
A = Date.now();
|
|
366
366
|
return;
|
|
367
367
|
}
|
|
368
|
-
if (n.currentTime !==
|
|
369
|
-
|
|
368
|
+
if (n.currentTime !== V) {
|
|
369
|
+
V = n.currentTime, A = Date.now();
|
|
370
370
|
return;
|
|
371
371
|
}
|
|
372
372
|
Date.now() - A >= this.opts.mediaTimeout && (this.host.emitter.emit("aderror", {
|
|
@@ -376,38 +376,38 @@ class rt {
|
|
|
376
376
|
}, 500), R = () => {
|
|
377
377
|
clearInterval(j), r.abort(), n.pause(), n.removeAttribute("src"), n.load(), s.remove(), this.layer = null, e();
|
|
378
378
|
}, H = (k) => {
|
|
379
|
-
k ? (
|
|
379
|
+
k ? (b("skip"), this.host.emitter.emit("adskip", { ad: t })) : b("complete"), this.host.emitter.emit("adend", { ad: t }), R();
|
|
380
380
|
};
|
|
381
381
|
n.addEventListener("playing", () => {
|
|
382
|
-
|
|
383
|
-
}, { once: !0, signal:
|
|
382
|
+
M(t.impressions), b("start"), this.host.emitter.emit("adstart", { ad: t });
|
|
383
|
+
}, { once: !0, signal: a }), n.addEventListener("playing", () => {
|
|
384
384
|
h.hidden = !0;
|
|
385
|
-
}, { signal:
|
|
385
|
+
}, { signal: a }), n.addEventListener("waiting", () => {
|
|
386
386
|
h.hidden = !1;
|
|
387
|
-
}, { signal:
|
|
388
|
-
const k = n.currentTime,
|
|
389
|
-
if (Number.isFinite(
|
|
390
|
-
const D = Math.ceil(
|
|
387
|
+
}, { signal: a }), n.addEventListener("timeupdate", () => {
|
|
388
|
+
const k = n.currentTime, L = n.duration;
|
|
389
|
+
if (Number.isFinite(L) && L > 0 && (p.textContent = x(Math.max(0, L - k)), k / L >= 0.25 && b("firstQuartile"), k / L >= 0.5 && b("midpoint"), k / L >= 0.75 && b("thirdQuartile")), T >= 0) {
|
|
390
|
+
const D = Math.ceil(T - k);
|
|
391
391
|
D > 0 ? (g.hidden = !1, g.disabled = !0, g.textContent = `${i.skipAdIn} ${D}`) : (g.hidden = !1, g.disabled = !1, g.textContent = i.skipAd);
|
|
392
392
|
}
|
|
393
|
-
}, { signal:
|
|
393
|
+
}, { signal: a }), n.addEventListener("ended", () => H(!1), { signal: a }), n.addEventListener("error", () => {
|
|
394
394
|
this.host.emitter.emit("aderror", {
|
|
395
395
|
roll: { roll: t.roll },
|
|
396
396
|
error: new Error("Ad media failed to play")
|
|
397
397
|
}), R();
|
|
398
|
-
}, { signal:
|
|
398
|
+
}, { signal: a }), g.addEventListener("click", () => H(!0));
|
|
399
399
|
const O = () => {
|
|
400
|
-
t.clickThrough && (
|
|
400
|
+
t.clickThrough && (b("click"), this.host.emitter.emit("adclick", { ad: t }), window.open(t.clickThrough, "_blank", "noopener"), n.pause());
|
|
401
401
|
};
|
|
402
|
-
n.addEventListener("click", O, { signal:
|
|
402
|
+
n.addEventListener("click", O, { signal: a }), y?.addEventListener("click", O);
|
|
403
403
|
let Z = !1, C = !1;
|
|
404
404
|
n.addEventListener("playing", () => {
|
|
405
405
|
Z = !0;
|
|
406
|
-
}, { once: !0, signal:
|
|
407
|
-
n.ended || !s.isConnected || (s.classList.add("imp-ad--paused"), Z && !C && (C = !0,
|
|
408
|
-
}, { signal:
|
|
409
|
-
s.classList.remove("imp-ad--paused"), C && (C = !1,
|
|
410
|
-
}, { signal:
|
|
406
|
+
}, { once: !0, signal: a }), n.addEventListener("pause", () => {
|
|
407
|
+
n.ended || !s.isConnected || (s.classList.add("imp-ad--paused"), Z && !C && (C = !0, M(t.tracking.pause), this.host.emitter.emit("adpause", { ad: t })));
|
|
408
|
+
}, { signal: a }), n.addEventListener("play", () => {
|
|
409
|
+
s.classList.remove("imp-ad--paused"), C && (C = !1, M(t.tracking.resume), this.host.emitter.emit("adresume", { ad: t }));
|
|
410
|
+
}, { signal: a }), s.addEventListener("click", (k) => {
|
|
411
411
|
(k.target === s || s.classList.contains("imp-ad--paused")) && n.paused && n.play().catch(() => {
|
|
412
412
|
});
|
|
413
413
|
}), n.play().catch(() => {
|
|
@@ -423,8 +423,8 @@ class rt {
|
|
|
423
423
|
this.destroyed = !0, this.adVideo?.pause(), this.layer?.remove(), this.layer = null, this.adVideo = null;
|
|
424
424
|
}
|
|
425
425
|
}
|
|
426
|
-
function
|
|
427
|
-
const e = [...
|
|
426
|
+
function W(l, t) {
|
|
427
|
+
const e = [...l].sort((s, n) => s.start - n.start), i = [];
|
|
428
428
|
for (let s = 0; s < e.length; s++) {
|
|
429
429
|
const n = Math.max(0, e[s].start);
|
|
430
430
|
if (Number.isFinite(t) && n >= t) continue;
|
|
@@ -433,41 +433,41 @@ function ot(o, t) {
|
|
|
433
433
|
}
|
|
434
434
|
return i;
|
|
435
435
|
}
|
|
436
|
-
async function lt(
|
|
437
|
-
const t = await fetch(
|
|
436
|
+
async function lt(l) {
|
|
437
|
+
const t = await fetch(l);
|
|
438
438
|
if (!t.ok) throw new Error(`Failed to load chapters VTT (${t.status})`);
|
|
439
439
|
const e = await t.text();
|
|
440
440
|
return Q(e).map((i) => ({ start: i.start, end: i.end, title: i.text }));
|
|
441
441
|
}
|
|
442
|
-
function U(
|
|
443
|
-
for (const e of
|
|
442
|
+
function U(l, t) {
|
|
443
|
+
for (const e of l)
|
|
444
444
|
if (t >= e.start && t < e.end) return e;
|
|
445
445
|
return null;
|
|
446
446
|
}
|
|
447
|
-
function at(
|
|
448
|
-
return t ? /application\/(x-mpegurl|vnd\.apple\.mpegurl)/i.test(t) : /\.m3u8(\?|#|$)/i.test(
|
|
447
|
+
function at(l, t) {
|
|
448
|
+
return t ? /application\/(x-mpegurl|vnd\.apple\.mpegurl)/i.test(t) : /\.m3u8(\?|#|$)/i.test(l);
|
|
449
449
|
}
|
|
450
|
-
let
|
|
450
|
+
let _;
|
|
451
451
|
async function ht() {
|
|
452
|
-
if (
|
|
453
|
-
const
|
|
454
|
-
if (
|
|
455
|
-
return
|
|
452
|
+
if (_ !== void 0) return _;
|
|
453
|
+
const l = globalThis.Hls;
|
|
454
|
+
if (l)
|
|
455
|
+
return _ = l, _;
|
|
456
456
|
try {
|
|
457
|
-
|
|
457
|
+
_ = (await import("hls.js/light")).default;
|
|
458
458
|
} catch {
|
|
459
|
-
|
|
459
|
+
_ = null;
|
|
460
460
|
}
|
|
461
|
-
return
|
|
461
|
+
return _;
|
|
462
462
|
}
|
|
463
|
-
async function ct(
|
|
463
|
+
async function ct(l, t, e, i) {
|
|
464
464
|
if (at(t, e)) {
|
|
465
|
-
const s =
|
|
466
|
-
return n && n.isSupported() ? dt(n,
|
|
465
|
+
const s = l.canPlayType("application/vnd.apple.mpegurl"), n = s ? null : await ht();
|
|
466
|
+
return n && n.isSupported() ? dt(n, l, t, i) : s ? (l.src = t, $(l)) : (i.onError("HLS is not supported in this browser and hls.js could not be loaded."), $(l));
|
|
467
467
|
}
|
|
468
|
-
return
|
|
468
|
+
return l.src = t, $(l);
|
|
469
469
|
}
|
|
470
|
-
function
|
|
470
|
+
function $(l) {
|
|
471
471
|
return {
|
|
472
472
|
kind: "native",
|
|
473
473
|
levels: [],
|
|
@@ -475,12 +475,12 @@ function q(o) {
|
|
|
475
475
|
setLevel() {
|
|
476
476
|
},
|
|
477
477
|
destroy() {
|
|
478
|
-
|
|
478
|
+
l.removeAttribute("src"), l.load();
|
|
479
479
|
}
|
|
480
480
|
};
|
|
481
481
|
}
|
|
482
|
-
function dt(
|
|
483
|
-
const s = new
|
|
482
|
+
function dt(l, t, e, i) {
|
|
483
|
+
const s = new l({ enableWorker: !0 }), n = {
|
|
484
484
|
kind: "hls",
|
|
485
485
|
levels: [],
|
|
486
486
|
selected: -1,
|
|
@@ -491,30 +491,30 @@ function dt(o, t, e, i) {
|
|
|
491
491
|
s.destroy(), t.removeAttribute("src"), t.load();
|
|
492
492
|
}
|
|
493
493
|
};
|
|
494
|
-
s.on(
|
|
494
|
+
s.on(l.Events.MANIFEST_PARSED, () => {
|
|
495
495
|
n.levels = s.levels.map((h, c) => ({
|
|
496
496
|
index: c,
|
|
497
497
|
label: h.height ? `${h.height}p` : `${Math.round(h.bitrate / 1e3)} kbps`
|
|
498
498
|
})).reverse(), i.onLevels(n.levels);
|
|
499
|
-
}), s.on(
|
|
499
|
+
}), s.on(l.Events.LEVEL_SWITCHED, (h, c) => {
|
|
500
500
|
const u = s.levels[c.level];
|
|
501
501
|
u && i.onLevelSwitch(u.height ? `${u.height}p` : `${Math.round(u.bitrate / 1e3)} kbps`);
|
|
502
502
|
});
|
|
503
|
-
let r = 0,
|
|
504
|
-
return s.on(
|
|
503
|
+
let r = 0, a = !1;
|
|
504
|
+
return s.on(l.Events.ERROR, (h, c) => {
|
|
505
505
|
if (c.fatal)
|
|
506
506
|
switch (c.type) {
|
|
507
|
-
case
|
|
507
|
+
case l.ErrorTypes.NETWORK_ERROR:
|
|
508
508
|
s.startLoad();
|
|
509
509
|
break;
|
|
510
|
-
case
|
|
510
|
+
case l.ErrorTypes.MEDIA_ERROR:
|
|
511
511
|
r < 3 ? (r++, s.recoverMediaError()) : (i.onError(`HLS media error: ${c.details}`, c), s.destroy());
|
|
512
512
|
break;
|
|
513
513
|
default:
|
|
514
|
-
if (
|
|
514
|
+
if (a)
|
|
515
515
|
i.onError(`HLS fatal error: ${c.details}`, c), s.destroy();
|
|
516
516
|
else {
|
|
517
|
-
|
|
517
|
+
a = !0;
|
|
518
518
|
try {
|
|
519
519
|
s.loadSource(e), s.startLoad();
|
|
520
520
|
} catch {
|
|
@@ -524,7 +524,7 @@ function dt(o, t, e, i) {
|
|
|
524
524
|
}
|
|
525
525
|
}), s.loadSource(e), s.attachMedia(t), n;
|
|
526
526
|
}
|
|
527
|
-
class
|
|
527
|
+
class F {
|
|
528
528
|
constructor(t) {
|
|
529
529
|
this.cues = t;
|
|
530
530
|
}
|
|
@@ -533,16 +533,16 @@ class I {
|
|
|
533
533
|
if (!e.ok) throw new Error(`Failed to load thumbnails VTT (${e.status})`);
|
|
534
534
|
const i = await e.text(), s = [];
|
|
535
535
|
for (const n of Q(i)) {
|
|
536
|
-
const [r,
|
|
536
|
+
const [r, a] = n.text.trim().split("#");
|
|
537
537
|
if (!r) continue;
|
|
538
538
|
const h = {
|
|
539
539
|
start: n.start,
|
|
540
540
|
end: n.end,
|
|
541
|
-
src:
|
|
542
|
-
}, c =
|
|
541
|
+
src: X(r, t)
|
|
542
|
+
}, c = a?.match(/xywh=(\d+),(\d+),(\d+),(\d+)/);
|
|
543
543
|
c && (h.xywh = { x: Number(c[1]), y: Number(c[2]), w: Number(c[3]), h: Number(c[4]) }), s.push(h);
|
|
544
544
|
}
|
|
545
|
-
return s.sort((n, r) => n.start - r.start), new
|
|
545
|
+
return s.sort((n, r) => n.start - r.start), new F(s);
|
|
546
546
|
}
|
|
547
547
|
cueAt(t) {
|
|
548
548
|
let e = 0, i = this.cues.length - 1;
|
|
@@ -556,9 +556,9 @@ class I {
|
|
|
556
556
|
}
|
|
557
557
|
}
|
|
558
558
|
const ut = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 6 6 6-6 6"/></svg>', pt = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 6-6 6 6 6"/></svg>';
|
|
559
|
-
class
|
|
559
|
+
class B {
|
|
560
560
|
constructor(t) {
|
|
561
|
-
this.anchor = t, this.outsideListener = null, this.root =
|
|
561
|
+
this.anchor = t, this.outsideListener = null, this.root = o("div", "imp-menu"), this.root.hidden = !0, this.backdrop = o("div", "imp-menu__backdrop"), this.backdrop.hidden = !0, this.backdrop.addEventListener("pointerdown", (e) => {
|
|
562
562
|
e.preventDefault(), this.close();
|
|
563
563
|
}), t.append(this.backdrop);
|
|
564
564
|
}
|
|
@@ -583,38 +583,57 @@ class E {
|
|
|
583
583
|
}
|
|
584
584
|
renderSettingsRoot(t) {
|
|
585
585
|
this.root.textContent = "";
|
|
586
|
-
const e =
|
|
586
|
+
const e = o("div", "imp-menu__section");
|
|
587
587
|
for (const i of t) {
|
|
588
|
-
|
|
588
|
+
if (i.toggle) {
|
|
589
|
+
e.append(this.buildToggleRow(i, i.toggle));
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const s = o("button", "imp-menu__item imp-menu__row", { type: "button" }), n = o("span", "imp-menu__label");
|
|
589
593
|
n.textContent = i.label;
|
|
590
|
-
const r =
|
|
591
|
-
r.textContent = i.value;
|
|
592
|
-
const
|
|
593
|
-
|
|
594
|
+
const r = o("span", "imp-menu__value");
|
|
595
|
+
r.textContent = i.value ?? "";
|
|
596
|
+
const a = o("span", "imp-menu__chevron");
|
|
597
|
+
a.innerHTML = ut, s.append(n, r, a), s.addEventListener("click", () => this.renderSettingsDetail(t, i)), e.append(s);
|
|
594
598
|
}
|
|
595
599
|
this.root.append(e);
|
|
596
600
|
}
|
|
601
|
+
/** Toggle row: label + an on/off switch. Stays in the menu (no close). */
|
|
602
|
+
buildToggleRow(t, e) {
|
|
603
|
+
const i = o("button", "imp-menu__item imp-menu__row imp-menu__toggle", {
|
|
604
|
+
type: "button",
|
|
605
|
+
role: "switch",
|
|
606
|
+
"aria-checked": String(e.value)
|
|
607
|
+
}), s = o("span", "imp-menu__label");
|
|
608
|
+
s.textContent = t.label;
|
|
609
|
+
const n = o("span", "imp-switch");
|
|
610
|
+
return n.append(o("span", "imp-switch__knob")), i.classList.toggle("imp-menu__toggle--on", e.value), i.append(s, n), i.addEventListener("click", () => {
|
|
611
|
+
const r = i.getAttribute("aria-checked") !== "true";
|
|
612
|
+
i.setAttribute("aria-checked", String(r)), i.classList.toggle("imp-menu__toggle--on", r), e.onChange(r);
|
|
613
|
+
}), i;
|
|
614
|
+
}
|
|
597
615
|
renderSettingsDetail(t, e) {
|
|
616
|
+
if (!e.section) return;
|
|
598
617
|
this.root.textContent = "";
|
|
599
|
-
const i =
|
|
618
|
+
const i = o("button", "imp-menu__item imp-menu__back", { type: "button" }), s = o("span", "imp-menu__chevron");
|
|
600
619
|
s.innerHTML = pt;
|
|
601
|
-
const n =
|
|
620
|
+
const n = o("span", "imp-menu__label");
|
|
602
621
|
n.textContent = e.label, i.append(s, n), i.addEventListener("click", () => this.renderSettingsRoot(t)), this.root.append(i), this.root.append(this.renderSection(e.section())), this.root.scrollTop = 0;
|
|
603
622
|
}
|
|
604
623
|
/** Build one option block (radio items) from a section. */
|
|
605
624
|
renderSection(t) {
|
|
606
|
-
const e =
|
|
625
|
+
const e = o("div", "imp-menu__section");
|
|
607
626
|
if (t.title) {
|
|
608
|
-
const i =
|
|
627
|
+
const i = o("div", "imp-menu__title");
|
|
609
628
|
i.textContent = t.title, e.append(i);
|
|
610
629
|
}
|
|
611
630
|
for (const i of t.items) {
|
|
612
|
-
const s =
|
|
631
|
+
const s = o("button", "imp-menu__item", { type: "button", role: "menuitemradio" });
|
|
613
632
|
if (s.setAttribute("aria-checked", String(i.active)), i.active && s.classList.add("imp-menu__item--active"), i.icon) {
|
|
614
|
-
const r =
|
|
615
|
-
i.icon.trimStart().startsWith("<svg") ? r.innerHTML = i.icon : r.append(
|
|
633
|
+
const r = o("span", "imp-menu__icon");
|
|
634
|
+
i.icon.trimStart().startsWith("<svg") ? r.innerHTML = i.icon : r.append(o("img", "", { src: i.icon, alt: "" })), s.append(r);
|
|
616
635
|
}
|
|
617
|
-
const n =
|
|
636
|
+
const n = o("span", "imp-menu__label");
|
|
618
637
|
n.textContent = i.label, s.append(n), s.addEventListener("click", () => {
|
|
619
638
|
t.onSelect(i.value), this.close();
|
|
620
639
|
}), e.append(s);
|
|
@@ -639,7 +658,7 @@ class E {
|
|
|
639
658
|
}
|
|
640
659
|
class mt {
|
|
641
660
|
constructor(t) {
|
|
642
|
-
this.cb = t, this.segments = [], this.duration = 0, this.chapters = [], this.thumbnails = null, this.scrubbing = !1, this.root =
|
|
661
|
+
this.cb = t, this.segments = [], this.duration = 0, this.chapters = [], this.thumbnails = null, this.scrubbing = !1, this.root = o("div", "imp-progress", { role: "slider", "aria-label": "Seek", tabindex: "-1" }), this.buffered = o("div", "imp-progress__buffered"), this.track = o("div", "imp-progress__track"), this.handle = o("div", "imp-progress__handle"), this.tooltipThumb = o("div", "imp-progress__thumb"), this.tooltipChapter = o("div", "imp-progress__tooltip-chapter"), this.tooltipTime = o("div", "imp-progress__tooltip-time"), this.tooltip = o("div", "imp-progress__tooltip"), this.tooltip.append(this.tooltipThumb, this.tooltipChapter, this.tooltipTime), this.heatmap = o("div", "imp-progress__heatmap"), this.heatmap.hidden = !0, this.root.append(this.heatmap, this.buffered, this.track, this.handle, this.tooltip), this.setChapters([]), this.bindPointer();
|
|
643
662
|
}
|
|
644
663
|
/** Render the popularity curve (empty array hides it). */
|
|
645
664
|
setHeatmap(t) {
|
|
@@ -647,7 +666,7 @@ class mt {
|
|
|
647
666
|
this.heatmap.hidden = !0, this.heatmap.textContent = "";
|
|
648
667
|
return;
|
|
649
668
|
}
|
|
650
|
-
this.heatmap.innerHTML = `<svg viewBox="0 0 1000 100" preserveAspectRatio="none" aria-hidden="true"><path d="${
|
|
669
|
+
this.heatmap.innerHTML = `<svg viewBox="0 0 1000 100" preserveAspectRatio="none" aria-hidden="true"><path d="${et(t)}"/></svg>`, this.heatmap.hidden = !1;
|
|
651
670
|
}
|
|
652
671
|
setDuration(t) {
|
|
653
672
|
this.duration = Number.isFinite(t) ? t : 0, this.root.classList.toggle("imp-progress--live", !Number.isFinite(t)), this.chapters.length === 0 && this.setChapters([]);
|
|
@@ -660,10 +679,10 @@ class mt {
|
|
|
660
679
|
n.start > s && i.push({ start: s, end: n.start, title: "" }), i.push(n), s = n.end;
|
|
661
680
|
this.duration > 0 && s < this.duration && i.push({ start: s, end: this.duration, title: "" });
|
|
662
681
|
for (const n of i) {
|
|
663
|
-
const r =
|
|
682
|
+
const r = o("div", "imp-progress__segment");
|
|
664
683
|
r.style.flexGrow = String(Math.max(n.end - n.start, 0.01));
|
|
665
|
-
const
|
|
666
|
-
r.append(
|
|
684
|
+
const a = o("div", "imp-progress__fill");
|
|
685
|
+
r.append(a), this.track.append(r), this.segments.push({ chapter: n, root: r, fill: a });
|
|
667
686
|
}
|
|
668
687
|
}
|
|
669
688
|
setThumbnails(t) {
|
|
@@ -705,8 +724,8 @@ class mt {
|
|
|
705
724
|
this.tooltipChapter.textContent = i?.title ?? "", this.tooltipChapter.hidden = !i?.title;
|
|
706
725
|
const s = this.thumbnails?.cueAt(e) ?? null;
|
|
707
726
|
s ? (this.tooltipThumb.hidden = !1, this.tooltipThumb.style.backgroundImage = `url("${s.src}")`, s.xywh ? (this.tooltipThumb.style.width = `${s.xywh.w}px`, this.tooltipThumb.style.height = `${s.xywh.h}px`, this.tooltipThumb.style.backgroundPosition = `-${s.xywh.x}px -${s.xywh.y}px`, this.tooltipThumb.style.backgroundSize = "auto") : (this.tooltipThumb.style.width = "160px", this.tooltipThumb.style.height = "90px", this.tooltipThumb.style.backgroundPosition = "center", this.tooltipThumb.style.backgroundSize = "cover")) : this.tooltipThumb.hidden = !0, this.tooltip.classList.add("imp-progress__tooltip--visible");
|
|
708
|
-
const n = this.root.getBoundingClientRect(), r = w(t.clientX - n.left, 0, n.width),
|
|
709
|
-
this.tooltip.style.left = `${w(r,
|
|
727
|
+
const n = this.root.getBoundingClientRect(), r = w(t.clientX - n.left, 0, n.width), a = this.tooltip.offsetWidth / 2;
|
|
728
|
+
this.tooltip.style.left = `${w(r, a, Math.max(a, n.width - a))}px`;
|
|
710
729
|
}
|
|
711
730
|
hideTooltip() {
|
|
712
731
|
this.tooltip.classList.remove("imp-progress__tooltip--visible");
|
|
@@ -714,9 +733,9 @@ class mt {
|
|
|
714
733
|
}
|
|
715
734
|
class vt {
|
|
716
735
|
constructor(t) {
|
|
717
|
-
this.player = t, this.subtitlesBtn = null, this.settingsBtn = null, this.settingsMenu = null, this.subtitlesMenu = null, this.moreMenu = null, this.moreWrap = null, this.qualityBtn = null, this.qualityMenu = null, this.gearBtn = null, this.gearMenu = null, this.gear = { speed: !1, quality: !1, subtitles: !1 }, this.nextPreviewEl = null, this.nextPreviewOpts = null, this.scenesBtn = null, this.likeBtn = null, this.dislikeBtn = null, this.likeCountEl = null, this.dislikeCountEl = null, this.prevBtn = null, this.nextBtn = null, this.seekBackBtn = null, this.seekFwdBtn = null, this.centerPlayBtn = null, this.centerPrevBtn = null, this.centerNextBtn = null, this.collapsibles = [], this.overflowed = /* @__PURE__ */ new Set(), this.resizeObserver = null, this.reflowScheduled = !1, this.actionItems = [], this.wasPlayingBeforeScrub = !1, this.disposers = [], this.onWindowResize = null;
|
|
736
|
+
this.player = t, this.rightItems = /* @__PURE__ */ new Map(), this.subtitlesBtn = null, this.settingsBtn = null, this.settingsMenu = null, this.subtitlesMenu = null, this.moreMenu = null, this.moreWrap = null, this.qualityBtn = null, this.qualityMenu = null, this.gearBtn = null, this.gearMenu = null, this.gear = { speed: !1, quality: !1, subtitles: !1 }, this.nextPreviewEl = null, this.nextPreviewOpts = null, this.scenesBtn = null, this.sceneTypeBtn = null, this.sceneTypeMenu = null, this.likeBtn = null, this.dislikeBtn = null, this.likeCountEl = null, this.dislikeCountEl = null, this.prevBtn = null, this.nextBtn = null, this.seekBackBtn = null, this.seekFwdBtn = null, this.centerPlayBtn = null, this.centerPrevBtn = null, this.centerNextBtn = null, this.collapsibles = [], this.overflowed = /* @__PURE__ */ new Set(), this.resizeObserver = null, this.reflowScheduled = !1, this.actionItems = [], this.wasPlayingBeforeScrub = !1, this.disposers = [], this.onWindowResize = null;
|
|
718
737
|
const { labels: e, icons: i } = t, s = t.controlsOptions;
|
|
719
|
-
this.root =
|
|
738
|
+
this.root = o("div", "imp-controls"), this.progress = new mt({
|
|
720
739
|
onSeek: (d) => t.seek(d),
|
|
721
740
|
onScrubStart: () => {
|
|
722
741
|
this.wasPlayingBeforeScrub = !t.paused, t.pause();
|
|
@@ -725,16 +744,16 @@ class vt {
|
|
|
725
744
|
this.wasPlayingBeforeScrub && t.play();
|
|
726
745
|
}
|
|
727
746
|
}), s.progress && this.root.append(this.progress.root);
|
|
728
|
-
const n =
|
|
747
|
+
const n = o("div", "imp-controls__row");
|
|
729
748
|
this.row = n, this.root.append(n);
|
|
730
|
-
const r =
|
|
731
|
-
this.rightGroup =
|
|
732
|
-
const h =
|
|
733
|
-
this.chapterLabel =
|
|
749
|
+
const r = o("div", "imp-controls__group"), a = o("div", "imp-controls__group");
|
|
750
|
+
this.rightGroup = a;
|
|
751
|
+
const h = o("div", "imp-controls__spacer");
|
|
752
|
+
this.chapterLabel = o("div", "imp-controls__chapter"), n.append(r, h, a), h.append(this.chapterLabel);
|
|
734
753
|
const c = typeof s.seekButtons == "object" ? s.seekButtons : {}, u = c.back ?? t.seekStep, p = c.forward ?? t.seekStep;
|
|
735
|
-
if (s.playlist && t.hasPlaylist && !s.hidePrev && (this.prevBtn = f("imp-btn--prev", e.previous, i.previous), this.prevBtn.addEventListener("click", () => t.previous()), r.append(this.prevBtn)), s.seekButtons && (this.seekBackBtn = f("imp-btn--seek-back", `${e.seekBack} ${u}s`, i.seekBack), this.addStepBadge(this.seekBackBtn, u), this.seekBackBtn.addEventListener("click", () => t.skip(-u)), r.append(this.seekBackBtn)), s.play && (this.playBtn = f("imp-btn--play", e.play, i.play), this.playBtn.addEventListener("click", () => t.togglePlay()), r.append(this.playBtn)), s.seekButtons && (this.seekFwdBtn = f("imp-btn--seek-forward", `${e.seekForward} ${p}s`, i.seekForward), this.addStepBadge(this.seekFwdBtn, p), this.seekFwdBtn.addEventListener("click", () => t.skip(p)), r.append(this.seekFwdBtn)), s.playlist && t.hasPlaylist && (this.nextBtn = f("imp-btn--next", e.next, i.next), this.nextBtn.addEventListener("click", () => t.next()), r.append(this.nextBtn)), s.volume) {
|
|
736
|
-
const d =
|
|
737
|
-
this.muteBtn = f("imp-btn--mute", e.mute, i.volumeHigh), this.muteBtn.addEventListener("click", () => t.toggleMute()), this.volumeSlider =
|
|
754
|
+
if (this.seekLabelFn = c.label, s.playlist && t.hasPlaylist && !s.hidePrev && (this.prevBtn = f("imp-btn--prev", e.previous, i.previous), this.prevBtn.addEventListener("click", () => t.previous()), r.append(this.prevBtn)), s.seekButtons && (this.seekBackBtn = f("imp-btn--seek-back", `${e.seekBack} ${u}s`, i.seekBack), this.addStepBadge(this.seekBackBtn, u, "back"), this.seekBackBtn.addEventListener("click", () => t.skip(-u)), r.append(this.seekBackBtn)), s.play && (this.playBtn = f("imp-btn--play", e.play, i.play), this.playBtn.addEventListener("click", () => t.togglePlay()), r.append(this.playBtn)), s.seekButtons && (this.seekFwdBtn = f("imp-btn--seek-forward", `${e.seekForward} ${p}s`, i.seekForward), this.addStepBadge(this.seekFwdBtn, p, "forward"), this.seekFwdBtn.addEventListener("click", () => t.skip(p)), r.append(this.seekFwdBtn)), s.playlist && t.hasPlaylist && (this.nextBtn = f("imp-btn--next", e.next, i.next), this.nextBtn.addEventListener("click", () => t.next()), r.append(this.nextBtn)), s.volume) {
|
|
755
|
+
const d = o("div", "imp-volume");
|
|
756
|
+
this.muteBtn = f("imp-btn--mute", e.mute, i.volumeHigh), this.muteBtn.addEventListener("click", () => t.toggleMute()), this.volumeSlider = o("input", "imp-volume__slider", {
|
|
738
757
|
type: "range",
|
|
739
758
|
min: "0",
|
|
740
759
|
max: "1",
|
|
@@ -744,22 +763,22 @@ class vt {
|
|
|
744
763
|
t.setVolume(Number(this.volumeSlider.value));
|
|
745
764
|
}), d.append(this.muteBtn, this.volumeSlider), r.append(d);
|
|
746
765
|
}
|
|
747
|
-
s.time && (this.timeLabel =
|
|
748
|
-
for (const d of (t.actionsOptions.custom ?? []).filter((
|
|
749
|
-
const
|
|
750
|
-
|
|
766
|
+
s.time && (this.timeLabel = o("div", "imp-controls__time"), this.liveBadge = o("span", "imp-controls__live"), this.liveBadge.textContent = e.live, this.liveBadge.hidden = !0, r.append(this.timeLabel, this.liveBadge)), this.buildLikeDislike();
|
|
767
|
+
for (const d of (t.actionsOptions.custom ?? []).filter((b) => b.placement === "bar")) {
|
|
768
|
+
const b = f(`imp-btn--custom imp-btn--custom-${d.id}`, d.title, d.icon ?? i.more);
|
|
769
|
+
b.addEventListener("click", () => t.emit("customaction", { id: d.id })), this.rightItems.set(`custom:${d.id}`, b), this.registerCollapsible({
|
|
751
770
|
key: `custom:${d.id}`,
|
|
752
|
-
el:
|
|
771
|
+
el: b,
|
|
753
772
|
priority: 55,
|
|
754
773
|
available: () => !0,
|
|
755
774
|
section: () => this.simpleSection(`custom:${d.id}`, d.title, d.icon ?? i.more, () => t.emit("customaction", { id: d.id }))
|
|
756
775
|
});
|
|
757
776
|
}
|
|
758
|
-
const m = (d) => d === !1 ? "off" : d === "bar" ? "bar" : "gear",
|
|
759
|
-
if (this.gear = { speed:
|
|
760
|
-
this.subtitlesBtn = f("imp-btn--subtitles", e.subtitles, i.subtitles), this.subtitlesMenu = new
|
|
761
|
-
const d =
|
|
762
|
-
d.append(this.subtitlesBtn, this.subtitlesMenu.root), this.subtitlesBtn.addEventListener("click", () => this.toggleSubtitlesMenu()),
|
|
777
|
+
const m = (d) => d === !1 ? "off" : d === "bar" ? "bar" : "gear", y = m(s.subtitles), g = m(s.quality), T = m(s.speed);
|
|
778
|
+
if (this.gear = { speed: T === "gear", quality: g === "gear", subtitles: y === "gear" }, y === "bar") {
|
|
779
|
+
this.subtitlesBtn = f("imp-btn--subtitles", e.subtitles, i.subtitles), this.subtitlesMenu = new B(this.subtitlesBtn);
|
|
780
|
+
const d = o("div", "imp-controls__menu-anchor");
|
|
781
|
+
d.append(this.subtitlesBtn, this.subtitlesMenu.root), this.subtitlesBtn.addEventListener("click", () => this.toggleSubtitlesMenu()), this.rightItems.set("subtitles", d), this.registerCollapsible({
|
|
763
782
|
key: "subtitles",
|
|
764
783
|
el: d,
|
|
765
784
|
priority: 30,
|
|
@@ -768,9 +787,9 @@ class vt {
|
|
|
768
787
|
});
|
|
769
788
|
}
|
|
770
789
|
if (g === "bar") {
|
|
771
|
-
this.qualityBtn = f("imp-btn--quality", e.quality, i.settings), this.qualityMenu = new
|
|
772
|
-
const d =
|
|
773
|
-
d.append(this.qualityBtn, this.qualityMenu.root), this.qualityBtn.addEventListener("click", () => this.toggleQualityMenu()),
|
|
790
|
+
this.qualityBtn = f("imp-btn--quality", e.quality, i.settings), this.qualityMenu = new B(this.qualityBtn);
|
|
791
|
+
const d = o("div", "imp-controls__menu-anchor");
|
|
792
|
+
d.append(this.qualityBtn, this.qualityMenu.root), this.qualityBtn.addEventListener("click", () => this.toggleQualityMenu()), this.rightItems.set("quality", d), this.registerCollapsible({
|
|
774
793
|
key: "quality",
|
|
775
794
|
el: d,
|
|
776
795
|
priority: 10,
|
|
@@ -778,10 +797,10 @@ class vt {
|
|
|
778
797
|
section: () => this.qualitySection()
|
|
779
798
|
});
|
|
780
799
|
}
|
|
781
|
-
if (
|
|
782
|
-
this.settingsBtn = f("imp-btn--speed", e.speed, i.speed), this.settingsMenu = new
|
|
783
|
-
const d =
|
|
784
|
-
d.append(this.settingsBtn, this.settingsMenu.root), this.settingsBtn.addEventListener("click", () => this.toggleSettingsMenu()),
|
|
800
|
+
if (T === "bar") {
|
|
801
|
+
this.settingsBtn = f("imp-btn--speed", e.speed, i.speed), this.settingsMenu = new B(this.settingsBtn);
|
|
802
|
+
const d = o("div", "imp-controls__menu-anchor");
|
|
803
|
+
d.append(this.settingsBtn, this.settingsMenu.root), this.settingsBtn.addEventListener("click", () => this.toggleSettingsMenu()), this.rightItems.set("speed", d), this.registerCollapsible({
|
|
785
804
|
key: "speed",
|
|
786
805
|
el: d,
|
|
787
806
|
priority: 40,
|
|
@@ -789,15 +808,26 @@ class vt {
|
|
|
789
808
|
section: () => this.speedSection()
|
|
790
809
|
});
|
|
791
810
|
}
|
|
792
|
-
if (s.scenes && (this.scenesBtn = f("imp-btn--scenes", e.scenes, i.scenes), this.scenesBtn.addEventListener("click", () => t.toggleScenesPanel()),
|
|
811
|
+
if (s.scenes && (this.scenesBtn = f("imp-btn--scenes", e.scenes, i.scenes), this.scenesBtn.addEventListener("click", () => t.toggleScenesPanel()), this.rightItems.set("scenes", this.scenesBtn), this.registerCollapsible({
|
|
793
812
|
key: "scenes",
|
|
794
813
|
el: this.scenesBtn,
|
|
795
814
|
priority: 25,
|
|
796
815
|
available: () => t.chapterList.length > 0,
|
|
797
816
|
section: () => this.simpleSection("scenes", e.scenes, i.scenes, () => t.toggleScenesPanel())
|
|
798
|
-
})), s.
|
|
817
|
+
})), s.sceneTypes !== !1) {
|
|
818
|
+
this.sceneTypeBtn = o("button", "imp-btn imp-btn--scene-types", { type: "button" }), this.sceneTypeMenu = new B(this.sceneTypeBtn);
|
|
819
|
+
const d = o("div", "imp-controls__menu-anchor");
|
|
820
|
+
d.append(this.sceneTypeBtn, this.sceneTypeMenu.root), this.sceneTypeBtn.addEventListener("click", () => this.toggleSceneTypeMenu()), this.rightItems.set("sceneTypes", d), this.refreshSceneTypeButton(), this.registerCollapsible({
|
|
821
|
+
key: "sceneTypes",
|
|
822
|
+
el: d,
|
|
823
|
+
priority: 26,
|
|
824
|
+
available: () => t.sceneTypes.length > 0,
|
|
825
|
+
section: () => this.sceneTypeSection()
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
if (s.playlist && t.hasPlaylist) {
|
|
799
829
|
const d = f("imp-btn--list", e.playlist, i.list);
|
|
800
|
-
d.addEventListener("click", () => t.togglePlaylistPanel()),
|
|
830
|
+
d.addEventListener("click", () => t.togglePlaylistPanel()), this.rightItems.set("playlist", d), this.registerCollapsible({
|
|
801
831
|
key: "list",
|
|
802
832
|
el: d,
|
|
803
833
|
priority: 50,
|
|
@@ -807,7 +837,7 @@ class vt {
|
|
|
807
837
|
}
|
|
808
838
|
if (s.pip && "requestPictureInPicture" in HTMLVideoElement.prototype) {
|
|
809
839
|
const d = f("imp-btn--pip", e.pip, i.pip);
|
|
810
|
-
d.addEventListener("click", () => void t.togglePip()),
|
|
840
|
+
d.addEventListener("click", () => void t.togglePip()), this.rightItems.set("pip", d), this.registerCollapsible({
|
|
811
841
|
key: "pip",
|
|
812
842
|
el: d,
|
|
813
843
|
priority: 20,
|
|
@@ -815,7 +845,7 @@ class vt {
|
|
|
815
845
|
section: () => this.simpleSection("pip", e.pip, i.pip, () => void t.togglePip())
|
|
816
846
|
});
|
|
817
847
|
}
|
|
818
|
-
if (s.fullscreen && (this.fullscreenBtn = f("imp-btn--fullscreen", e.fullscreen, i.fullscreen), this.fullscreenBtn.addEventListener("click", () => void t.toggleFullscreen()),
|
|
848
|
+
if (s.fullscreen && (this.fullscreenBtn = f("imp-btn--fullscreen", e.fullscreen, i.fullscreen), this.fullscreenBtn.addEventListener("click", () => void t.toggleFullscreen()), this.rightItems.set("fullscreen", this.fullscreenBtn)), this.prevBtn && this.registerCollapsible({
|
|
819
849
|
key: "prev",
|
|
820
850
|
el: this.prevBtn,
|
|
821
851
|
priority: 70,
|
|
@@ -847,18 +877,18 @@ class vt {
|
|
|
847
877
|
section: () => this.simpleSection("seekFwd", `${e.seekForward} ${p}s`, i.seekForward, () => t.skip(p))
|
|
848
878
|
});
|
|
849
879
|
}
|
|
850
|
-
if (this.center =
|
|
880
|
+
if (this.center = o("div", "imp-center-controls"), s.playlist && t.hasPlaylist && (this.centerPrevBtn = this.makeCenterButton("prev", e.previous, i.previous), this.centerPrevBtn.addEventListener("click", () => t.previous()), this.center.append(this.centerPrevBtn)), s.seekButtons) {
|
|
851
881
|
const d = this.makeCenterButton("seek-back", `${e.seekBack} ${u}s`, i.seekBack);
|
|
852
|
-
this.addStepBadge(d, u), d.addEventListener("click", () => t.skip(-u)), this.center.append(d);
|
|
882
|
+
this.addStepBadge(d, u, "back"), d.addEventListener("click", () => t.skip(-u)), this.center.append(d);
|
|
853
883
|
}
|
|
854
884
|
if (s.play && (this.centerPlayBtn = this.makeCenterButton("play", e.play, i.play), this.centerPlayBtn.addEventListener("click", () => t.togglePlay()), this.center.append(this.centerPlayBtn)), s.seekButtons) {
|
|
855
885
|
const d = this.makeCenterButton("seek-forward", `${e.seekForward} ${p}s`, i.seekForward);
|
|
856
|
-
this.addStepBadge(d, p), d.addEventListener("click", () => t.skip(p)), this.center.append(d);
|
|
886
|
+
this.addStepBadge(d, p, "forward"), d.addEventListener("click", () => t.skip(p)), this.center.append(d);
|
|
857
887
|
}
|
|
858
888
|
if (s.playlist && t.hasPlaylist && (this.centerNextBtn = this.makeCenterButton("next", e.next, i.next), this.centerNextBtn.addEventListener("click", () => t.next()), this.center.append(this.centerNextBtn)), this.center.style.display = "none", this.setupNextPreview(), this.gear.speed || this.gear.quality || this.gear.subtitles) {
|
|
859
|
-
this.gearBtn = f("imp-btn--settings", e.settings, i.settings), this.gearMenu = new
|
|
860
|
-
const d =
|
|
861
|
-
d.append(this.gearBtn, this.gearMenu.root), this.gearBtn.addEventListener("click", () => this.toggleGearMenu()),
|
|
889
|
+
this.gearBtn = f("imp-btn--settings", e.settings, i.settings), this.gearMenu = new B(this.gearBtn);
|
|
890
|
+
const d = o("div", "imp-controls__menu-anchor");
|
|
891
|
+
d.append(this.gearBtn, this.gearMenu.root), this.gearBtn.addEventListener("click", () => this.toggleGearMenu()), this.rightItems.set("gear", d), this.registerCollapsible({
|
|
862
892
|
key: "gear",
|
|
863
893
|
el: d,
|
|
864
894
|
priority: 40,
|
|
@@ -866,20 +896,40 @@ class vt {
|
|
|
866
896
|
section: () => this.gearSections()
|
|
867
897
|
});
|
|
868
898
|
}
|
|
869
|
-
this.buildMoreDropdown(
|
|
899
|
+
this.layoutRightCluster(a), this.buildMoreDropdown(a), this.bind(), this.syncVolume(), this.syncPlayState(), this.setLikeState(t.actionsOptions.likeState ?? null), typeof ResizeObserver < "u" && (this.resizeObserver = new ResizeObserver(() => this.scheduleReflow()), this.resizeObserver.observe(t.container)), this.onWindowResize = () => this.scheduleReflow(), window.addEventListener("resize", this.onWindowResize);
|
|
870
900
|
}
|
|
871
901
|
registerCollapsible(t) {
|
|
872
902
|
this.collapsibles.push(t);
|
|
873
903
|
}
|
|
904
|
+
/**
|
|
905
|
+
* Append the right-cluster controls. Built-in order = creation order; if
|
|
906
|
+
* `controls.order` is set, its keys go first (in that order), then any
|
|
907
|
+
* unlisted controls keep their default position. (⋯ is appended separately.)
|
|
908
|
+
*/
|
|
909
|
+
layoutRightCluster(t) {
|
|
910
|
+
const e = [...this.rightItems.keys()], i = this.player.controlsOptions.order;
|
|
911
|
+
let s = e;
|
|
912
|
+
if (i.length > 0) {
|
|
913
|
+
const n = /* @__PURE__ */ new Set();
|
|
914
|
+
s = [];
|
|
915
|
+
for (const r of i)
|
|
916
|
+
this.rightItems.has(r) && !n.has(r) && (s.push(r), n.add(r));
|
|
917
|
+
for (const r of e) n.has(r) || s.push(r);
|
|
918
|
+
}
|
|
919
|
+
for (const n of s) {
|
|
920
|
+
const r = this.rightItems.get(n);
|
|
921
|
+
r && t.append(r);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
874
924
|
/** Center-cluster button — deliberately NOT `.imp-btn` (own sizing/look). */
|
|
875
925
|
makeCenterButton(t, e, i) {
|
|
876
|
-
const s =
|
|
926
|
+
const s = o("button", `imp-center-btn imp-center-btn--${t}`, { type: "button", "aria-label": e, title: e });
|
|
877
927
|
return s.innerHTML = i, s;
|
|
878
928
|
}
|
|
879
|
-
/**
|
|
880
|
-
addStepBadge(t, e) {
|
|
881
|
-
const
|
|
882
|
-
|
|
929
|
+
/** Caption under the seek arrow. Default "−15s"/"+15s"; overridable via `controls.seekButtons.label`. */
|
|
930
|
+
addStepBadge(t, e, i) {
|
|
931
|
+
const s = o("span", "imp-seek-num");
|
|
932
|
+
s.textContent = this.seekLabelFn ? this.seekLabelFn(e, i) : `${i === "back" ? "−" : "+"}${e}${this.player.labels.secondsShort}`, t.append(s);
|
|
883
933
|
}
|
|
884
934
|
// === gear (unified settings) ==========================================
|
|
885
935
|
/** Sections for the gear when overflowed into ⋯ (expanded, no drill-down). */
|
|
@@ -890,7 +940,11 @@ class vt {
|
|
|
890
940
|
/** Gear drill-down rows: one per setting, each showing its current value. */
|
|
891
941
|
gearEntries() {
|
|
892
942
|
const t = this.player, e = [];
|
|
893
|
-
if (
|
|
943
|
+
if (t.hasPlaylist && e.push({
|
|
944
|
+
key: "autoplay",
|
|
945
|
+
label: t.labels.autoplay,
|
|
946
|
+
toggle: { value: t.autoAdvance, onChange: (i) => t.setAutoAdvance(i) }
|
|
947
|
+
}), this.gear.quality && t.qualityLevels.length > 0) {
|
|
894
948
|
const i = t.currentQuality === -1 ? t.labels.qualityAuto : t.qualityLevels.find((s) => s.index === t.currentQuality)?.label ?? t.labels.qualityAuto;
|
|
895
949
|
e.push({ key: "quality", label: t.labels.quality, value: i, section: () => this.qualitySection() });
|
|
896
950
|
}
|
|
@@ -904,6 +958,38 @@ class vt {
|
|
|
904
958
|
}
|
|
905
959
|
return e;
|
|
906
960
|
}
|
|
961
|
+
// === scene types ======================================================
|
|
962
|
+
/** Update the scene-type button to the active group's icon + title. */
|
|
963
|
+
refreshSceneTypeButton() {
|
|
964
|
+
const t = this.sceneTypeBtn;
|
|
965
|
+
if (!t) return;
|
|
966
|
+
const e = this.player.activeSceneType;
|
|
967
|
+
if (t.textContent = "", !e) return;
|
|
968
|
+
if (e.icon) {
|
|
969
|
+
const s = o("span", "imp-scene-type__icon");
|
|
970
|
+
e.icon.trimStart().startsWith("<svg") ? s.innerHTML = e.icon : s.append(o("img", "", { src: e.icon, alt: "" })), t.append(s);
|
|
971
|
+
}
|
|
972
|
+
const i = o("span", "imp-scene-type__label");
|
|
973
|
+
i.textContent = e.title, t.append(i), t.setAttribute("aria-label", `${this.player.labels.sceneTypes}: ${e.title}`), t.title = e.title;
|
|
974
|
+
}
|
|
975
|
+
sceneTypeSection() {
|
|
976
|
+
const t = this.player;
|
|
977
|
+
return {
|
|
978
|
+
title: t.labels.sceneTypes,
|
|
979
|
+
items: t.sceneTypes.map((e) => ({
|
|
980
|
+
label: e.title,
|
|
981
|
+
value: e.id,
|
|
982
|
+
icon: e.icon,
|
|
983
|
+
active: e.id === (t.activeSceneType?.id ?? "")
|
|
984
|
+
})),
|
|
985
|
+
onSelect: (e) => {
|
|
986
|
+
t.setSceneGroup(e), this.refreshSceneTypeButton();
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
toggleSceneTypeMenu() {
|
|
991
|
+
!this.sceneTypeMenu || this.player.sceneTypes.length === 0 || (this.closeMenus(this.sceneTypeMenu), this.sceneTypeMenu.toggle([this.sceneTypeSection()]));
|
|
992
|
+
}
|
|
907
993
|
toggleGearMenu() {
|
|
908
994
|
if (!this.gearMenu) return;
|
|
909
995
|
const t = this.gearEntries();
|
|
@@ -919,7 +1005,7 @@ class vt {
|
|
|
919
1005
|
title: i.title ?? !0,
|
|
920
1006
|
duration: i.duration ?? !0,
|
|
921
1007
|
meta: i.meta ?? !0
|
|
922
|
-
}, this.nextPreviewEl =
|
|
1008
|
+
}, this.nextPreviewEl = o("div", "imp-next-preview"), this.nextPreviewEl.hidden = !0, t.container.append(this.nextPreviewEl), this.nextBtn && this.bindNextPreview(this.nextBtn), this.centerNextBtn && this.bindNextPreview(this.centerNextBtn);
|
|
923
1009
|
}
|
|
924
1010
|
bindNextPreview(t) {
|
|
925
1011
|
t.addEventListener("pointerenter", (e) => {
|
|
@@ -932,62 +1018,62 @@ class vt {
|
|
|
932
1018
|
const s = this.player.nextSource;
|
|
933
1019
|
if (!s) return;
|
|
934
1020
|
e.textContent = "";
|
|
935
|
-
const n =
|
|
1021
|
+
const n = o("div", "imp-next-preview__kicker");
|
|
936
1022
|
if (n.textContent = this.player.labels.next, e.append(n), i.thumbnail && s.poster) {
|
|
937
|
-
const m =
|
|
1023
|
+
const m = o("div", "imp-next-preview__thumb");
|
|
938
1024
|
if (m.style.backgroundImage = `url("${s.poster}")`, i.duration && s.duration) {
|
|
939
|
-
const
|
|
940
|
-
|
|
1025
|
+
const y = o("span", "imp-next-preview__duration");
|
|
1026
|
+
y.textContent = x(s.duration), m.append(y);
|
|
941
1027
|
}
|
|
942
1028
|
e.append(m);
|
|
943
1029
|
}
|
|
944
1030
|
if (i.title && s.title) {
|
|
945
|
-
const m =
|
|
1031
|
+
const m = o("div", "imp-next-preview__title");
|
|
946
1032
|
m.textContent = s.title, e.append(m);
|
|
947
1033
|
}
|
|
948
1034
|
if (i.meta && s.previewMeta?.length) {
|
|
949
|
-
const m =
|
|
1035
|
+
const m = o("div", "imp-next-preview__meta");
|
|
950
1036
|
m.textContent = s.previewMeta.join(" · "), e.append(m);
|
|
951
1037
|
}
|
|
952
1038
|
e.hidden = !1;
|
|
953
|
-
const r = this.player.container.getBoundingClientRect(),
|
|
954
|
-
e.style.left = `${p}px`, e.style.bottom = `${r.height - (
|
|
1039
|
+
const r = this.player.container.getBoundingClientRect(), a = t.getBoundingClientRect(), h = 8, c = e.offsetWidth, u = a.left - r.left + a.width / 2 - c / 2, p = Math.max(h, Math.min(u, r.width - c - h));
|
|
1040
|
+
e.style.left = `${p}px`, e.style.bottom = `${r.height - (a.top - r.top) + 10}px`;
|
|
955
1041
|
}
|
|
956
1042
|
hideNextPreview() {
|
|
957
1043
|
this.nextPreviewEl && (this.nextPreviewEl.hidden = !0);
|
|
958
1044
|
}
|
|
959
1045
|
/** like/dislike — visible buttons (collapsible), highlightable via `setLikeState`. */
|
|
960
|
-
buildLikeDislike(
|
|
961
|
-
const
|
|
962
|
-
if (
|
|
963
|
-
this.likeBtn = f("imp-btn--like",
|
|
964
|
-
const
|
|
965
|
-
|
|
1046
|
+
buildLikeDislike() {
|
|
1047
|
+
const t = this.player, e = t.actionsOptions, { labels: i, icons: s } = t;
|
|
1048
|
+
if (e.like) {
|
|
1049
|
+
this.likeBtn = f("imp-btn--like", i.like, s.like), this.likeBtn.addEventListener("click", () => t.emit("action", { id: "like" })), this.likeCountEl = this.attachCountTooltip(this.likeBtn, e.likeCount);
|
|
1050
|
+
const n = this.wrapWithTooltip(this.likeBtn, this.likeCountEl);
|
|
1051
|
+
this.rightItems.set("like", n), this.registerCollapsible({
|
|
966
1052
|
key: "like",
|
|
967
|
-
el:
|
|
1053
|
+
el: n,
|
|
968
1054
|
priority: 62,
|
|
969
1055
|
available: () => !0,
|
|
970
|
-
section: () => this.simpleSection("like",
|
|
1056
|
+
section: () => this.simpleSection("like", i.like, s.like, () => t.emit("action", { id: "like" }))
|
|
971
1057
|
});
|
|
972
1058
|
}
|
|
973
|
-
if (
|
|
974
|
-
this.dislikeBtn = f("imp-btn--dislike",
|
|
975
|
-
const
|
|
976
|
-
|
|
1059
|
+
if (e.dislike) {
|
|
1060
|
+
this.dislikeBtn = f("imp-btn--dislike", i.dislike, s.dislike), this.dislikeBtn.addEventListener("click", () => t.emit("action", { id: "dislike" })), this.dislikeCountEl = this.attachCountTooltip(this.dislikeBtn, e.dislikeCount);
|
|
1061
|
+
const n = this.wrapWithTooltip(this.dislikeBtn, this.dislikeCountEl);
|
|
1062
|
+
this.rightItems.set("dislike", n), this.registerCollapsible({
|
|
977
1063
|
key: "dislike",
|
|
978
|
-
el:
|
|
1064
|
+
el: n,
|
|
979
1065
|
priority: 60,
|
|
980
1066
|
available: () => !0,
|
|
981
|
-
section: () => this.simpleSection("dislike",
|
|
1067
|
+
section: () => this.simpleSection("dislike", i.dislike, s.dislike, () => t.emit("action", { id: "dislike" }))
|
|
982
1068
|
});
|
|
983
1069
|
}
|
|
984
1070
|
}
|
|
985
1071
|
attachCountTooltip(t, e) {
|
|
986
|
-
const i =
|
|
1072
|
+
const i = o("span", "imp-count-tooltip");
|
|
987
1073
|
return this.setCountText(i, e), i;
|
|
988
1074
|
}
|
|
989
1075
|
wrapWithTooltip(t, e) {
|
|
990
|
-
const i =
|
|
1076
|
+
const i = o("div", "imp-action");
|
|
991
1077
|
return i.append(t, e), i;
|
|
992
1078
|
}
|
|
993
1079
|
setCountText(t, e) {
|
|
@@ -1007,20 +1093,20 @@ class vt {
|
|
|
1007
1093
|
for (const h of (i.custom ?? []).filter((c) => c.placement !== "bar"))
|
|
1008
1094
|
this.actionItems.push({ value: `custom:${h.id}`, label: h.title, icon: h.icon, run: () => e.emit("customaction", { id: h.id }) });
|
|
1009
1095
|
const r = f("imp-btn--more", s.more, n.more);
|
|
1010
|
-
this.moreMenu = new
|
|
1011
|
-
const
|
|
1012
|
-
|
|
1096
|
+
this.moreMenu = new B(r);
|
|
1097
|
+
const a = o("div", "imp-controls__menu-anchor imp-controls__more");
|
|
1098
|
+
a.append(r, this.moreMenu.root), r.addEventListener("click", () => {
|
|
1013
1099
|
this.closeMenus(this.moreMenu), this.moreMenu?.toggle(this.buildMoreSections());
|
|
1014
|
-
}), t.append(
|
|
1100
|
+
}), t.append(a), this.moreWrap = a;
|
|
1015
1101
|
}
|
|
1016
1102
|
/** ⋯ menu = overflowed controls (in display order) + consumer actions. */
|
|
1017
1103
|
buildMoreSections() {
|
|
1018
|
-
const t = [], e = /* @__PURE__ */ new Map(), i = [], s = ["prev", "next", "seekBack", "seekFwd", "like", "dislike", "scenes", "pip", "list", "subtitles", "speed", "quality", "gear"], n = (
|
|
1019
|
-
const h = s.indexOf(
|
|
1104
|
+
const t = [], e = /* @__PURE__ */ new Map(), i = [], s = ["prev", "next", "seekBack", "seekFwd", "like", "dislike", "scenes", "sceneTypes", "pip", "list", "subtitles", "speed", "quality", "gear"], n = (a) => {
|
|
1105
|
+
const h = s.indexOf(a);
|
|
1020
1106
|
return h === -1 ? s.length : h;
|
|
1021
|
-
}, r = this.collapsibles.filter((
|
|
1022
|
-
for (const
|
|
1023
|
-
const h =
|
|
1107
|
+
}, r = this.collapsibles.filter((a) => this.overflowed.has(a.key) && a.available()).sort((a, h) => n(a.key) - n(h.key));
|
|
1108
|
+
for (const a of r) {
|
|
1109
|
+
const h = a.section();
|
|
1024
1110
|
if (h)
|
|
1025
1111
|
for (const c of Array.isArray(h) ? h : [h])
|
|
1026
1112
|
if (!c.title && c.items.length === 1) {
|
|
@@ -1029,12 +1115,12 @@ class vt {
|
|
|
1029
1115
|
} else
|
|
1030
1116
|
t.push(c);
|
|
1031
1117
|
}
|
|
1032
|
-
if (i.length > 0 && t.unshift({ title: "", items: i, onSelect: (
|
|
1033
|
-
const
|
|
1118
|
+
if (i.length > 0 && t.unshift({ title: "", items: i, onSelect: (a) => e.get(a)?.() }), this.actionItems.length > 0) {
|
|
1119
|
+
const a = new Map(this.actionItems.map((h) => [h.value, h.run]));
|
|
1034
1120
|
t.push({
|
|
1035
1121
|
title: "",
|
|
1036
1122
|
items: this.actionItems.map(({ value: h, label: c, icon: u }) => ({ value: h, label: c, icon: u, active: !1 })),
|
|
1037
|
-
onSelect: (h) =>
|
|
1123
|
+
onSelect: (h) => a.get(h)?.()
|
|
1038
1124
|
});
|
|
1039
1125
|
}
|
|
1040
1126
|
return t;
|
|
@@ -1089,26 +1175,26 @@ class vt {
|
|
|
1089
1175
|
reflow() {
|
|
1090
1176
|
const t = window.innerWidth <= 767, i = this.player.controlsOptions.seekPlacement !== "bar" || t;
|
|
1091
1177
|
this.center.style.display = i ? "flex" : "none", this.centerPrevBtn && (this.centerPrevBtn.style.display = t ? "" : "none"), this.centerNextBtn && (this.centerNextBtn.style.display = t ? "" : "none"), this.playBtn && (this.playBtn.style.display = t ? "none" : "");
|
|
1092
|
-
const s = (
|
|
1178
|
+
const s = (a) => a === "seekBack" || a === "seekFwd" ? i : a === "prev" || a === "next" ? t : !1;
|
|
1093
1179
|
this.overflowed.clear();
|
|
1094
|
-
for (const
|
|
1095
|
-
if (s(
|
|
1096
|
-
|
|
1180
|
+
for (const a of this.collapsibles) {
|
|
1181
|
+
if (s(a.key)) {
|
|
1182
|
+
a.el.style.display = "none";
|
|
1097
1183
|
continue;
|
|
1098
1184
|
}
|
|
1099
|
-
const h =
|
|
1100
|
-
|
|
1185
|
+
const h = a.available();
|
|
1186
|
+
a.el.style.display = h ? "" : "none", a.el.classList.remove("imp-collapsed");
|
|
1101
1187
|
}
|
|
1102
|
-
const n = this.collapsibles.filter((
|
|
1188
|
+
const n = this.collapsibles.filter((a) => a.available() && !s(a.key)).sort((a, h) => a.priority - h.priority);
|
|
1103
1189
|
let r = n.length;
|
|
1104
1190
|
for (; r-- > 0 && this.overflowsRow(); ) {
|
|
1105
|
-
const
|
|
1106
|
-
if (!
|
|
1107
|
-
|
|
1191
|
+
const a = n.find((h) => !this.overflowed.has(h.key));
|
|
1192
|
+
if (!a) break;
|
|
1193
|
+
a.el.style.display = "none", a.el.classList.add("imp-collapsed"), this.overflowed.add(a.key);
|
|
1108
1194
|
}
|
|
1109
1195
|
if (this.moreWrap) {
|
|
1110
|
-
const
|
|
1111
|
-
this.moreWrap.style.display =
|
|
1196
|
+
const a = this.actionItems.length > 0 || this.overflowed.size > 0;
|
|
1197
|
+
this.moreWrap.style.display = a ? "" : "none";
|
|
1112
1198
|
}
|
|
1113
1199
|
}
|
|
1114
1200
|
overflowsRow() {
|
|
@@ -1129,7 +1215,7 @@ class vt {
|
|
|
1129
1215
|
this.chapterLabel.textContent = e?.title ?? "";
|
|
1130
1216
|
}),
|
|
1131
1217
|
t.on("fullscreenchange", ({ active: e }) => {
|
|
1132
|
-
this.fullscreenBtn &&
|
|
1218
|
+
this.fullscreenBtn && E(this.fullscreenBtn, e ? t.icons.fullscreenExit : t.icons.fullscreen, e ? t.labels.exitFullscreen : t.labels.fullscreen), this.scheduleReflow();
|
|
1133
1219
|
}),
|
|
1134
1220
|
t.on("playlistitemchange", () => {
|
|
1135
1221
|
this.syncPlaylistButtons(), this.scheduleReflow();
|
|
@@ -1141,23 +1227,23 @@ class vt {
|
|
|
1141
1227
|
}
|
|
1142
1228
|
syncPlayState() {
|
|
1143
1229
|
const t = this.player, [e, i] = t.ended ? [t.icons.replay, t.labels.replay] : t.paused ? [t.icons.play, t.labels.play] : [t.icons.pause, t.labels.pause];
|
|
1144
|
-
this.playBtn &&
|
|
1230
|
+
this.playBtn && E(this.playBtn, e, i), this.centerPlayBtn && E(this.centerPlayBtn, e, i);
|
|
1145
1231
|
}
|
|
1146
1232
|
syncVolume() {
|
|
1147
1233
|
if (!this.muteBtn) return;
|
|
1148
1234
|
const t = this.player, e = t.muted ? 0 : t.volume, i = e === 0 ? t.icons.volumeMute : e < 0.5 ? t.icons.volumeLow : t.icons.volumeHigh;
|
|
1149
|
-
|
|
1235
|
+
E(this.muteBtn, i, t.muted ? t.labels.unmute : t.labels.mute), this.volumeSlider.value = String(e), this.volumeSlider.style.setProperty("--imp-volume-fill", `${e * 100}%`);
|
|
1150
1236
|
}
|
|
1151
1237
|
/** Called by the player when per-source data (chapters/quality/subtitles) changes. */
|
|
1152
1238
|
syncFeatureButtons() {
|
|
1153
|
-
this.scheduleReflow();
|
|
1239
|
+
this.refreshSceneTypeButton(), this.scheduleReflow();
|
|
1154
1240
|
}
|
|
1155
1241
|
syncPlaylistButtons() {
|
|
1156
1242
|
const t = this.player;
|
|
1157
1243
|
this.prevBtn && (this.prevBtn.disabled = !t.hasPrevious), this.nextBtn && (this.nextBtn.disabled = !t.hasNext), this.centerPrevBtn && (this.centerPrevBtn.disabled = !t.hasPrevious), this.centerNextBtn && (this.centerNextBtn.disabled = !t.hasNext);
|
|
1158
1244
|
}
|
|
1159
1245
|
closeMenus(t) {
|
|
1160
|
-
for (const e of [this.gearMenu, this.settingsMenu, this.subtitlesMenu, this.qualityMenu, this.moreMenu])
|
|
1246
|
+
for (const e of [this.gearMenu, this.settingsMenu, this.subtitlesMenu, this.qualityMenu, this.sceneTypeMenu, this.moreMenu])
|
|
1161
1247
|
e && e !== t && e.close();
|
|
1162
1248
|
}
|
|
1163
1249
|
toggleSettingsMenu() {
|
|
@@ -1171,12 +1257,12 @@ class vt {
|
|
|
1171
1257
|
}
|
|
1172
1258
|
destroy() {
|
|
1173
1259
|
for (const t of this.disposers) t();
|
|
1174
|
-
this.disposers = [], this.resizeObserver?.disconnect(), this.onWindowResize && window.removeEventListener("resize", this.onWindowResize), this.gearMenu?.destroy(), this.settingsMenu?.destroy(), this.subtitlesMenu?.destroy(), this.qualityMenu?.destroy(), this.moreMenu?.destroy(), this.nextPreviewEl?.remove(), this.root.remove();
|
|
1260
|
+
this.disposers = [], this.resizeObserver?.disconnect(), this.onWindowResize && window.removeEventListener("resize", this.onWindowResize), this.gearMenu?.destroy(), this.sceneTypeMenu?.destroy(), this.settingsMenu?.destroy(), this.subtitlesMenu?.destroy(), this.qualityMenu?.destroy(), this.moreMenu?.destroy(), this.nextPreviewEl?.remove(), this.root.remove();
|
|
1175
1261
|
}
|
|
1176
1262
|
}
|
|
1177
1263
|
class ft {
|
|
1178
1264
|
constructor(t) {
|
|
1179
|
-
this.root =
|
|
1265
|
+
this.root = o("div", "imp-poster"), this.image = o("img", "imp-poster__image", { alt: "", decoding: "async" }), this.image.hidden = !0;
|
|
1180
1266
|
const e = f("imp-poster__play", t.labels.play, t.icons.bigPlay);
|
|
1181
1267
|
e.addEventListener("click", () => void t.play()), this.root.append(this.image, e), this.root.addEventListener("click", (i) => {
|
|
1182
1268
|
(i.target === this.root || i.target === this.image) && t.play();
|
|
@@ -1194,11 +1280,11 @@ class ft {
|
|
|
1194
1280
|
}
|
|
1195
1281
|
class gt {
|
|
1196
1282
|
constructor(t) {
|
|
1197
|
-
this.labels = t, this.channelUrl = null, this.custom = null, this.visible = { title: !0, description: !0, sponsor: !0 }, this.root =
|
|
1283
|
+
this.labels = t, this.channelUrl = null, this.custom = null, this.visible = { title: !0, description: !0, sponsor: !0 }, this.root = o("div", "imp-pause-screen"), this.root.hidden = !0, this.defaultContent = o("div", "imp-pause-screen__default"), this.channel = o("button", "imp-channel", { type: "button" }), this.channel.hidden = !0, this.channelAvatar = o("div", "imp-channel__avatar"), this.channelName = o("div", "imp-channel__name"), this.channel.append(this.channelName, this.channelAvatar), this.channel.addEventListener("click", () => {
|
|
1198
1284
|
this.channelUrl && window.open(this.channelUrl, "_blank", "noopener");
|
|
1199
1285
|
});
|
|
1200
|
-
const e =
|
|
1201
|
-
this.title =
|
|
1286
|
+
const e = o("div", "imp-pause-screen__heading");
|
|
1287
|
+
this.title = o("div", "imp-pause-screen__title"), this.description = o("div", "imp-pause-screen__description"), this.sponsor = o("a", "imp-sponsor", { target: "_blank", rel: "nofollow noopener" }), this.sponsor.hidden = !0, this.sponsorLabel = o("span", "imp-sponsor__label"), this.sponsorText = o("span", "imp-sponsor__text"), this.sponsor.append(this.sponsorLabel, this.sponsorText), this.sponsor.addEventListener("click", (i) => i.stopPropagation()), e.append(this.sponsor, this.title, this.description), this.defaultContent.append(e, this.channel), this.root.append(this.defaultContent);
|
|
1202
1288
|
}
|
|
1203
1289
|
setCustomContent(t) {
|
|
1204
1290
|
this.custom?.remove(), this.custom = t, t && (t.classList.add("imp-pause-screen__custom"), this.root.append(t)), this.defaultContent.hidden = t !== null, this.root.classList.toggle("imp-pause-screen--custom", t !== null);
|
|
@@ -1229,9 +1315,9 @@ class gt {
|
|
|
1229
1315
|
this.root.hidden = !0;
|
|
1230
1316
|
}
|
|
1231
1317
|
}
|
|
1232
|
-
class
|
|
1318
|
+
class yt {
|
|
1233
1319
|
constructor(t) {
|
|
1234
|
-
this.player = t, this.clickBehavior = "player", this.root =
|
|
1320
|
+
this.player = t, this.clickBehavior = "player", this.root = o("div", "imp-related"), this.root.hidden = !0, this.heading = o("div", "imp-related__title"), this.grid = o("div", "imp-related__grid");
|
|
1235
1321
|
const e = f("imp-related__close", "Close", t.icons.close);
|
|
1236
1322
|
e.addEventListener("click", () => this.hide()), this.root.append(e, this.heading, this.grid);
|
|
1237
1323
|
}
|
|
@@ -1243,12 +1329,12 @@ class bt {
|
|
|
1243
1329
|
}
|
|
1244
1330
|
}
|
|
1245
1331
|
buildCard(t) {
|
|
1246
|
-
const e =
|
|
1332
|
+
const e = o("button", "imp-related__card", { type: "button" }), i = o("div", "imp-related__thumb");
|
|
1247
1333
|
if (t.poster && (i.style.backgroundImage = `url("${t.poster}")`), t.duration) {
|
|
1248
|
-
const n =
|
|
1334
|
+
const n = o("span", "imp-related__duration");
|
|
1249
1335
|
n.textContent = t.duration, i.append(n);
|
|
1250
1336
|
}
|
|
1251
|
-
const s =
|
|
1337
|
+
const s = o("div", "imp-related__card-title");
|
|
1252
1338
|
return s.textContent = t.title, e.append(i, s), e.addEventListener("click", () => {
|
|
1253
1339
|
this.player.emit("relatedclick", { item: t }), this.hide(), this.activate(t);
|
|
1254
1340
|
}), e;
|
|
@@ -1278,39 +1364,76 @@ class bt {
|
|
|
1278
1364
|
this.root.hidden = !0;
|
|
1279
1365
|
}
|
|
1280
1366
|
}
|
|
1281
|
-
class
|
|
1367
|
+
class bt {
|
|
1368
|
+
constructor(t) {
|
|
1369
|
+
this.player = t, this.root = o("div", "imp-upnext"), this.root.hidden = !0;
|
|
1370
|
+
}
|
|
1371
|
+
get visible() {
|
|
1372
|
+
return !this.root.hidden;
|
|
1373
|
+
}
|
|
1374
|
+
show() {
|
|
1375
|
+
const t = this.player.nextSource;
|
|
1376
|
+
if (!t) return;
|
|
1377
|
+
const { labels: e } = this.player;
|
|
1378
|
+
this.root.textContent = "";
|
|
1379
|
+
const i = o("div", "imp-upnext__card"), s = o("div", "imp-upnext__kicker");
|
|
1380
|
+
if (s.textContent = e.next, i.append(s), t.poster) {
|
|
1381
|
+
const r = o("button", "imp-upnext__thumb", { type: "button", "aria-label": e.playNext });
|
|
1382
|
+
if (r.style.backgroundImage = `url("${t.poster}")`, t.duration) {
|
|
1383
|
+
const h = o("span", "imp-upnext__duration");
|
|
1384
|
+
h.textContent = x(t.duration), r.append(h);
|
|
1385
|
+
}
|
|
1386
|
+
const a = o("span", "imp-upnext__thumb-play");
|
|
1387
|
+
a.innerHTML = this.player.icons.bigPlay, r.append(a), r.addEventListener("click", () => this.player.next()), i.append(r);
|
|
1388
|
+
}
|
|
1389
|
+
if (t.title) {
|
|
1390
|
+
const r = o("div", "imp-upnext__title");
|
|
1391
|
+
r.textContent = t.title, i.append(r);
|
|
1392
|
+
}
|
|
1393
|
+
if (t.previewMeta?.length) {
|
|
1394
|
+
const r = o("div", "imp-upnext__meta");
|
|
1395
|
+
r.textContent = t.previewMeta.join(" · "), i.append(r);
|
|
1396
|
+
}
|
|
1397
|
+
const n = o("button", "imp-upnext__btn", { type: "button" });
|
|
1398
|
+
n.textContent = e.playNext, n.addEventListener("click", () => this.player.next()), i.append(n), this.root.append(i), this.root.hidden = !1;
|
|
1399
|
+
}
|
|
1400
|
+
hide() {
|
|
1401
|
+
this.root.hidden = !0;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
class kt {
|
|
1282
1405
|
constructor(t, e = "sidebar", i) {
|
|
1283
|
-
this.player = t, this.root =
|
|
1284
|
-
const s =
|
|
1406
|
+
this.player = t, this.root = o("div", `imp-playlist imp-playlist--${e}`), this.root.hidden = !0;
|
|
1407
|
+
const s = o("div", "imp-playlist__header"), n = o("div", "imp-playlist__heading");
|
|
1285
1408
|
if (i) {
|
|
1286
|
-
const h =
|
|
1409
|
+
const h = o("div", "imp-playlist__kicker");
|
|
1287
1410
|
h.textContent = t.labels.playlist;
|
|
1288
|
-
const c =
|
|
1411
|
+
const c = o("div", "imp-playlist__name");
|
|
1289
1412
|
c.textContent = i, n.append(h, c);
|
|
1290
1413
|
} else
|
|
1291
1414
|
n.textContent = t.labels.playlist;
|
|
1292
|
-
const r =
|
|
1415
|
+
const r = o("div", "imp-playlist__tools");
|
|
1293
1416
|
this.shuffleBtn = f("imp-playlist__shuffle", t.labels.shuffle, t.icons.shuffle), this.shuffleBtn.addEventListener("click", () => {
|
|
1294
1417
|
t.setShuffle(!t.shuffle), this.syncModes();
|
|
1295
1418
|
}), this.repeatBtn = f("imp-playlist__repeat", t.labels.repeat, t.icons.repeat), this.repeatBtn.addEventListener("click", () => {
|
|
1296
1419
|
t.setRepeat(!t.repeat), this.syncModes();
|
|
1297
1420
|
});
|
|
1298
|
-
const
|
|
1299
|
-
|
|
1421
|
+
const a = f("imp-playlist__close", "Close", t.icons.close);
|
|
1422
|
+
a.addEventListener("click", () => this.hide()), r.append(this.shuffleBtn, this.repeatBtn, a), s.append(n, r), this.list = o("div", "imp-playlist__list"), this.root.append(s, this.list), this.rebuild(), this.syncModes();
|
|
1300
1423
|
}
|
|
1301
1424
|
syncModes() {
|
|
1302
1425
|
this.shuffleBtn.classList.toggle("imp-btn--active", this.player.shuffle), this.repeatBtn.classList.toggle("imp-btn--active", this.player.repeat);
|
|
1303
1426
|
}
|
|
1304
1427
|
rebuild() {
|
|
1305
1428
|
this.list.textContent = "", this.player.playlist.forEach((t, e) => {
|
|
1306
|
-
const i =
|
|
1429
|
+
const i = o("button", "imp-playlist__item", { type: "button" });
|
|
1307
1430
|
e === this.player.index && i.classList.add("imp-playlist__item--active");
|
|
1308
|
-
const s =
|
|
1431
|
+
const s = o("div", "imp-playlist__thumb");
|
|
1309
1432
|
t.poster && (s.style.backgroundImage = `url("${t.poster}")`);
|
|
1310
|
-
const n =
|
|
1433
|
+
const n = o("div", "imp-playlist__meta"), r = o("div", "imp-playlist__title");
|
|
1311
1434
|
if (r.textContent = t.title ?? `#${e + 1}`, n.append(r), t.duration) {
|
|
1312
|
-
const
|
|
1313
|
-
|
|
1435
|
+
const a = o("div", "imp-playlist__duration");
|
|
1436
|
+
a.textContent = x(t.duration), n.append(a);
|
|
1314
1437
|
}
|
|
1315
1438
|
i.append(s, n), i.addEventListener("click", () => {
|
|
1316
1439
|
this.player.playItem(e), window.innerWidth <= 767 && this.hide();
|
|
@@ -1330,28 +1453,28 @@ class yt {
|
|
|
1330
1453
|
this.visible ? this.hide() : this.show();
|
|
1331
1454
|
}
|
|
1332
1455
|
}
|
|
1333
|
-
class
|
|
1456
|
+
class wt {
|
|
1334
1457
|
constructor(t, e = "bottom") {
|
|
1335
|
-
this.player = t, this.items = [], this.root =
|
|
1336
|
-
const i =
|
|
1458
|
+
this.player = t, this.items = [], this.root = o("div", `imp-playlist imp-scenes imp-playlist--${e}`), this.root.hidden = !0;
|
|
1459
|
+
const i = o("div", "imp-playlist__header"), s = o("span");
|
|
1337
1460
|
s.textContent = t.labels.scenes;
|
|
1338
1461
|
const n = f("imp-playlist__close", "Close", t.icons.close);
|
|
1339
|
-
n.addEventListener("click", () => this.hide()), i.append(s, n), this.list =
|
|
1462
|
+
n.addEventListener("click", () => this.hide()), i.append(s, n), this.list = o("div", "imp-playlist__list"), this.root.append(i, this.list), t.on("chapterchange", () => this.syncActive());
|
|
1340
1463
|
}
|
|
1341
1464
|
/** Re-render from the player's current chapters + thumbnail track. */
|
|
1342
1465
|
rebuild() {
|
|
1343
1466
|
this.list.textContent = "", this.items = [];
|
|
1344
1467
|
const t = this.player.thumbnails;
|
|
1345
1468
|
for (const e of this.player.chapterList) {
|
|
1346
|
-
const i =
|
|
1469
|
+
const i = o("button", "imp-playlist__item", { type: "button" }), s = o("div", "imp-playlist__thumb"), n = t?.cueAt(e.start + 0.01) ?? null;
|
|
1347
1470
|
if (n?.xywh) {
|
|
1348
|
-
const c =
|
|
1471
|
+
const c = o("div", "imp-scenes__sprite");
|
|
1349
1472
|
c.style.width = `${n.xywh.w}px`, c.style.height = `${n.xywh.h}px`, c.style.backgroundImage = `url("${n.src}")`, c.style.backgroundPosition = `-${n.xywh.x}px -${n.xywh.y}px`, c.style.setProperty("--imp-sprite-w", String(n.xywh.w)), s.append(c);
|
|
1350
1473
|
} else n && (s.style.backgroundImage = `url("${n.src}")`);
|
|
1351
|
-
const r =
|
|
1352
|
-
|
|
1353
|
-
const h =
|
|
1354
|
-
h.textContent = x(e.start), r.append(
|
|
1474
|
+
const r = o("div", "imp-playlist__meta"), a = o("div", "imp-playlist__title");
|
|
1475
|
+
a.textContent = e.title || x(e.start);
|
|
1476
|
+
const h = o("div", "imp-playlist__duration");
|
|
1477
|
+
h.textContent = x(e.start), r.append(a, h), i.append(s, r), i.addEventListener("click", () => {
|
|
1355
1478
|
this.player.seek(e.start), this.player.play(), window.innerWidth <= 767 && this.hide();
|
|
1356
1479
|
}), this.list.append(i), this.items.push(i);
|
|
1357
1480
|
}
|
|
@@ -1376,10 +1499,10 @@ class kt {
|
|
|
1376
1499
|
this.visible ? this.hide() : this.show();
|
|
1377
1500
|
}
|
|
1378
1501
|
}
|
|
1379
|
-
function
|
|
1380
|
-
return
|
|
1502
|
+
function G(l) {
|
|
1503
|
+
return l ? typeof l == "string" ? [{ src: l, label: "Subtitles" }] : Array.isArray(l) ? l : [l] : [];
|
|
1381
1504
|
}
|
|
1382
|
-
const
|
|
1505
|
+
const xt = {
|
|
1383
1506
|
play: !0,
|
|
1384
1507
|
progress: !0,
|
|
1385
1508
|
time: !0,
|
|
@@ -1392,38 +1515,41 @@ const wt = {
|
|
|
1392
1515
|
// legacy alias for `speed`; resolved in the constructor
|
|
1393
1516
|
quality: "gear",
|
|
1394
1517
|
scenes: !0,
|
|
1518
|
+
sceneTypes: !0,
|
|
1395
1519
|
heatmap: !0,
|
|
1396
1520
|
subtitles: "gear",
|
|
1397
1521
|
seekButtons: !0,
|
|
1398
1522
|
// Prev/seek/play/next as a centered overlay on every viewport.
|
|
1399
1523
|
seekPlacement: "overlay",
|
|
1524
|
+
order: [],
|
|
1525
|
+
// empty → built-in right-cluster order
|
|
1400
1526
|
playlist: !0,
|
|
1401
1527
|
hidePrev: !0,
|
|
1402
1528
|
nextPreview: !0,
|
|
1403
1529
|
hideDelay: 2500
|
|
1404
1530
|
};
|
|
1405
|
-
class
|
|
1531
|
+
class Tt {
|
|
1406
1532
|
constructor(t, e = {}) {
|
|
1407
|
-
this.scrubbing = !1, this.emitter = new
|
|
1533
|
+
this.scrubbing = !1, this.emitter = new K(), this.abort = new AbortController(), this.sources = [], this.currentIndex = -1, this.sourceController = null, this.loadToken = 0, this.chapters = [], this.currentChapter = null, this.sceneGroupList = [], this.activeSceneGroupId = "", this.progressiveQuality = -1, this.thumbTrack = null, this.shuffleMode = !1, this.autoAdvanceEnabled = !0, this.decodeRecoveries = 0, this.adManager = null, this.playedOnce = !1, this.idleTimer = null, this.destroyed = !1;
|
|
1408
1534
|
const i = typeof t == "string" ? document.querySelector(t) : t;
|
|
1409
1535
|
if (!i) throw new Error(`[itube-player] mount target not found: ${String(t)}`);
|
|
1410
|
-
this.mount = i, this.options = e, this.labels = { ...
|
|
1536
|
+
this.mount = i, this.options = e, this.labels = { ...q, ...Y(e.language), ...e.labels }, this.icons = { ...J, ...e.icons };
|
|
1411
1537
|
const s = e.controls ?? {}, n = s.speed ?? s.settings ?? "gear";
|
|
1412
|
-
this.controlsOptions = { ...
|
|
1538
|
+
this.controlsOptions = { ...xt, ...s, speed: n, settings: n }, this.actionsOptions = e.actions ?? {}, this.playbackRates = e.playbackRates ?? [0.5, 0.75, 1, 1.25, 1.5, 2], this.seekStep = e.seekStep ?? 15, this.playlistOptions = { title: "", autoAdvance: !0, loop: !1, shuffle: !1, startIndex: 0, layout: "sidebar", ...e.playlist }, this.shuffleMode = this.playlistOptions.shuffle, this.autoAdvanceEnabled = this.playlistOptions.autoAdvance, this.sources = e.source ? Array.isArray(e.source) ? [...e.source] : [e.source] : [], this.container = o("div", "imp-player", { tabindex: "0" }), e.className && this.container.classList.add(e.className);
|
|
1413
1539
|
const r = e.styling;
|
|
1414
1540
|
if (r?.themeColor && this.container.style.setProperty("--imp-accent", r.themeColor), r?.likeColor && this.container.style.setProperty("--imp-like", r.likeColor), r?.dislikeColor && this.container.style.setProperty("--imp-dislike", r.dislikeColor), r?.borderRadius !== void 0) {
|
|
1415
1541
|
const p = typeof r.borderRadius == "number" ? `${r.borderRadius}px` : r.borderRadius;
|
|
1416
1542
|
this.container.style.setProperty("--imp-radius", p);
|
|
1417
1543
|
}
|
|
1418
|
-
r?.playButtonStyle === "inverted" && this.container.classList.add("imp-player--play-inverted"), this.video =
|
|
1419
|
-
const
|
|
1420
|
-
this.spinner =
|
|
1421
|
-
const h =
|
|
1544
|
+
r?.playButtonStyle === "inverted" && this.container.classList.add("imp-player--play-inverted"), this.video = o("video", "imp-video"), e.playsInline !== !1 && this.video.setAttribute("playsinline", ""), e.crossOrigin !== void 0 && (this.video.crossOrigin = e.crossOrigin), this.video.preload = "metadata", e.loop && (this.video.loop = !0), e.muted && (this.video.muted = !0), this.video.volume = w(e.volume ?? 1, 0, 1);
|
|
1545
|
+
const a = o("div", "imp-layer");
|
|
1546
|
+
this.spinner = o("div", "imp-spinner"), this.spinner.hidden = !0, this.errorBox = o("div", "imp-error"), this.errorBox.hidden = !0, this.pauseScreen = new gt(this.labels), this.poster = new ft(this), this.related = new yt(this), this.related.setOptions(e.related), this.upNext = new bt(this), this.controls = new vt(this), this.playlistPanel = new kt(this, this.playlistOptions.layout, this.playlistOptions.title || void 0), this.scenesPanel = new wt(this, e.scenes?.layout ?? "bottom");
|
|
1547
|
+
const h = o("div", "imp-layer__middle");
|
|
1422
1548
|
h.append(this.spinner, this.errorBox, this.controls.center);
|
|
1423
|
-
const c =
|
|
1424
|
-
c.append(this.controls.root),
|
|
1549
|
+
const c = o("div", "imp-layer__bottom");
|
|
1550
|
+
c.append(this.controls.root), a.append(this.pauseScreen.root, this.related.root, this.upNext.root, h, c), this.container.append(this.video, a, this.poster.root, this.playlistPanel.root, this.scenesPanel.root), this.mount.append(this.container), e.pauseScreen instanceof HTMLElement ? this.pauseScreen.setCustomContent(e.pauseScreen) : typeof e.pauseScreen == "function" ? this.pauseScreen.setCustomContent(e.pauseScreen(this)) : e.pauseScreen && typeof e.pauseScreen == "object" && this.pauseScreen.setVisibility(e.pauseScreen);
|
|
1425
1551
|
const u = e.adConfig ?? e.ads;
|
|
1426
|
-
u && u.adList.length > 0 && (this.adManager = new
|
|
1552
|
+
u && u.adList.length > 0 && (this.adManager = new ot(
|
|
1427
1553
|
{ container: this.container, contentVideo: this.video, emitter: this.emitter, labels: this.labels, closeIcon: this.icons.close },
|
|
1428
1554
|
u
|
|
1429
1555
|
)), this.emitter.on("error", ({ message: p }) => {
|
|
@@ -1542,7 +1668,7 @@ class Bt {
|
|
|
1542
1668
|
}
|
|
1543
1669
|
// === subtitles ========================================================
|
|
1544
1670
|
get subtitleTracks() {
|
|
1545
|
-
return
|
|
1671
|
+
return G(this.source?.subtitles);
|
|
1546
1672
|
}
|
|
1547
1673
|
get activeSubtitle() {
|
|
1548
1674
|
const t = this.video.textTracks;
|
|
@@ -1653,6 +1779,23 @@ class Bt {
|
|
|
1653
1779
|
get chapter() {
|
|
1654
1780
|
return this.currentChapter;
|
|
1655
1781
|
}
|
|
1782
|
+
// === scene types (groups) =============================================
|
|
1783
|
+
/** Typed scene breakdowns attached to the current source (may be empty). */
|
|
1784
|
+
get sceneTypes() {
|
|
1785
|
+
return this.sceneGroupList;
|
|
1786
|
+
}
|
|
1787
|
+
/** Currently selected scene type, or null when there are no groups. */
|
|
1788
|
+
get activeSceneType() {
|
|
1789
|
+
return this.sceneGroupList.find((t) => t.id === this.activeSceneGroupId) ?? null;
|
|
1790
|
+
}
|
|
1791
|
+
/** Switch the active scene type — rebuilds the timeline segments + scenes panel. */
|
|
1792
|
+
setSceneGroup(t) {
|
|
1793
|
+
t === this.activeSceneGroupId || !this.sceneGroupList.some((e) => e.id === t) || (this.activeSceneGroupId = t, this.applyActiveSceneGroup(), this.emitter.emit("scenetypechange", { group: this.activeSceneType }));
|
|
1794
|
+
}
|
|
1795
|
+
/** Normalize the active group's scenes into `chapters` and refresh the UI. */
|
|
1796
|
+
applyActiveSceneGroup() {
|
|
1797
|
+
this.chapters = W(this.activeSceneType?.scenes ?? [], this.video.duration), this.currentChapter = null, this.controls.progress.setChapters(this.chapters), this.controls.syncFeatureButtons(), this.scenesPanel.visible && this.scenesPanel.rebuild();
|
|
1798
|
+
}
|
|
1656
1799
|
// === actions ==========================================================
|
|
1657
1800
|
/**
|
|
1658
1801
|
* Share the current video: native share sheet when the device has one,
|
|
@@ -1694,11 +1837,11 @@ class Bt {
|
|
|
1694
1837
|
async loadItem(t, e) {
|
|
1695
1838
|
const i = ++this.loadToken, s = this.sources[t];
|
|
1696
1839
|
if (!s) return;
|
|
1697
|
-
this.currentIndex = t, this.sourceController?.destroy(), this.sourceController = null, this.chapters = [], this.currentChapter = null, this.progressiveQuality = -1, this.playedOnce = !1;
|
|
1840
|
+
this.currentIndex = t, this.sourceController?.destroy(), this.sourceController = null, this.chapters = [], this.currentChapter = null, this.sceneGroupList = [], this.activeSceneGroupId = "", this.progressiveQuality = -1, this.playedOnce = !1;
|
|
1698
1841
|
for (const h of [...this.video.querySelectorAll("track")]) h.remove();
|
|
1699
|
-
this.adManager?.resetForNewSource(), this.related.hide(), this.pauseScreen.hide(), this.scenesPanel.hide(), this.thumbTrack = null, this.errorBox.hidden = !0, this.decodeRecoveries = 0, this.video.poster = s.poster ?? "", this.poster.setSource(s), this.pauseScreen.setSource(s), this.controls.progress.setChapters([]), this.controls.progress.setThumbnails(null), this.controls.progress.setHeatmap([]), e ? this.poster.hide() : this.poster.show(), this.playlistPanel.rebuild();
|
|
1700
|
-
for (const h of
|
|
1701
|
-
const c =
|
|
1842
|
+
this.adManager?.resetForNewSource(), this.related.hide(), this.upNext.hide(), this.pauseScreen.hide(), this.scenesPanel.hide(), this.thumbTrack = null, this.errorBox.hidden = !0, this.decodeRecoveries = 0, this.video.poster = s.poster ?? "", this.poster.setSource(s), this.pauseScreen.setSource(s), this.controls.progress.setChapters([]), this.controls.progress.setThumbnails(null), this.controls.progress.setHeatmap([]), e ? this.poster.hide() : this.poster.show(), this.playlistPanel.rebuild();
|
|
1843
|
+
for (const h of G(s.subtitles)) {
|
|
1844
|
+
const c = o("track", "", {
|
|
1702
1845
|
kind: "subtitles",
|
|
1703
1846
|
src: h.src,
|
|
1704
1847
|
label: h.label,
|
|
@@ -1712,7 +1855,7 @@ class Bt {
|
|
|
1712
1855
|
this.progressiveQuality = h, n = s.qualities[h].src, r = s.qualities[h].type ?? r;
|
|
1713
1856
|
}
|
|
1714
1857
|
this.video.preload = this.adManager?.hasPendingPreRoll ? "auto" : "metadata";
|
|
1715
|
-
const
|
|
1858
|
+
const a = await ct(this.video, n, r, {
|
|
1716
1859
|
onLevels: () => {
|
|
1717
1860
|
i === this.loadToken && this.controls.syncFeatureButtons();
|
|
1718
1861
|
},
|
|
@@ -1720,15 +1863,21 @@ class Bt {
|
|
|
1720
1863
|
onError: (h, c) => this.emitter.emit("error", { message: h, cause: c })
|
|
1721
1864
|
});
|
|
1722
1865
|
if (i !== this.loadToken) {
|
|
1723
|
-
|
|
1866
|
+
a.destroy();
|
|
1724
1867
|
return;
|
|
1725
1868
|
}
|
|
1726
|
-
if (this.sourceController =
|
|
1869
|
+
if (this.sourceController = a, this.emitter.emit("sourcechange", { source: s, index: t }), s.thumbnails && F.load(s.thumbnails).then((h) => {
|
|
1727
1870
|
i === this.loadToken && (this.thumbTrack = h, this.controls.progress.setThumbnails(h), this.scenesPanel.visible && this.scenesPanel.rebuild());
|
|
1728
|
-
}).catch((h) => this.emitter.emit("error", { message: "Failed to load thumbnails track", cause: h })), s.
|
|
1871
|
+
}).catch((h) => this.emitter.emit("error", { message: "Failed to load thumbnails track", cause: h })), s.sceneGroups && s.sceneGroups.length > 0) {
|
|
1872
|
+
this.sceneGroupList = s.sceneGroups, this.activeSceneGroupId = s.sceneGroups[0].id;
|
|
1873
|
+
const h = () => {
|
|
1874
|
+
i === this.loadToken && this.applyActiveSceneGroup();
|
|
1875
|
+
};
|
|
1876
|
+
Number.isFinite(this.video.duration) && this.video.duration > 0 ? h() : this.video.addEventListener("loadedmetadata", h, { once: !0, signal: this.abort.signal });
|
|
1877
|
+
} else if (s.chapters) {
|
|
1729
1878
|
const h = (c) => {
|
|
1730
1879
|
const u = () => {
|
|
1731
|
-
i === this.loadToken && (this.chapters =
|
|
1880
|
+
i === this.loadToken && (this.chapters = W(c, this.video.duration), this.controls.progress.setChapters(this.chapters), this.controls.syncFeatureButtons(), this.scenesPanel.visible && this.scenesPanel.rebuild());
|
|
1732
1881
|
};
|
|
1733
1882
|
Number.isFinite(this.video.duration) && this.video.duration > 0 ? u() : this.video.addEventListener("loadedmetadata", u, { once: !0, signal: this.abort.signal });
|
|
1734
1883
|
};
|
|
@@ -1736,7 +1885,7 @@ class Bt {
|
|
|
1736
1885
|
}
|
|
1737
1886
|
if (s.heatmap && s.heatmap.length > 0 && this.controlsOptions.heatmap) {
|
|
1738
1887
|
const h = s.heatmap, c = () => {
|
|
1739
|
-
i === this.loadToken && this.controls.progress.setHeatmap(
|
|
1888
|
+
i === this.loadToken && this.controls.progress.setHeatmap(tt(h, this.video.duration));
|
|
1740
1889
|
};
|
|
1741
1890
|
Number.isFinite(this.video.duration) && this.video.duration > 0 ? c() : this.video.addEventListener("loadedmetadata", c, { once: !0, signal: this.abort.signal });
|
|
1742
1891
|
}
|
|
@@ -1747,7 +1896,7 @@ class Bt {
|
|
|
1747
1896
|
bindVideoEvents() {
|
|
1748
1897
|
const { signal: t } = this.abort, e = this.video;
|
|
1749
1898
|
e.addEventListener("play", () => {
|
|
1750
|
-
this.playedOnce = !0, this.poster.hide(), this.pauseScreen.hide(), this.related.visible || this.related.hide(), this.related.hide(), e.readyState < 3 && (this.spinner.hidden = !1), this.emitter.emit("play", void 0), this.scheduleIdle();
|
|
1899
|
+
this.playedOnce = !0, this.poster.hide(), this.pauseScreen.hide(), this.related.visible || this.related.hide(), this.related.hide(), this.upNext.hide(), e.readyState < 3 && (this.spinner.hidden = !1), this.emitter.emit("play", void 0), this.scheduleIdle();
|
|
1751
1900
|
}, { signal: t }), e.addEventListener("pause", () => {
|
|
1752
1901
|
this.spinner.hidden = !0, this.emitter.emit("pause", void 0), this.showControlsNow(), !(this.video.ended || this.scrubbing || this.adPlaying || !this.playedOnce) && (this.options.pauseScreen !== !1 && this.pauseScreen.show(), this.options.related?.showOn?.includes("pause") && this.related.show());
|
|
1753
1902
|
}, { signal: t }), e.addEventListener("ended", () => {
|
|
@@ -1774,7 +1923,7 @@ class Bt {
|
|
|
1774
1923
|
this.decodeRecoveries++;
|
|
1775
1924
|
const n = e.currentTime, r = !e.paused;
|
|
1776
1925
|
e.load();
|
|
1777
|
-
const
|
|
1926
|
+
const a = () => {
|
|
1778
1927
|
try {
|
|
1779
1928
|
e.currentTime = n;
|
|
1780
1929
|
} catch {
|
|
@@ -1782,7 +1931,7 @@ class Bt {
|
|
|
1782
1931
|
r && e.play().catch(() => {
|
|
1783
1932
|
});
|
|
1784
1933
|
};
|
|
1785
|
-
e.readyState >= 1 ?
|
|
1934
|
+
e.readyState >= 1 ? a() : e.addEventListener("loadedmetadata", a, { once: !0, signal: this.abort.signal });
|
|
1786
1935
|
return;
|
|
1787
1936
|
}
|
|
1788
1937
|
this.emitter.emit("error", { message: i.message || `Media error (code ${i.code})`, cause: i });
|
|
@@ -1792,13 +1941,24 @@ class Bt {
|
|
|
1792
1941
|
}
|
|
1793
1942
|
async handleEnded() {
|
|
1794
1943
|
if (this.emitter.emit("ended", void 0), this.showControlsNow(), !(this.adManager && (await this.adManager.playPostRoll(), this.destroyed))) {
|
|
1795
|
-
if (this.
|
|
1944
|
+
if (this.autoAdvanceEnabled && this.hasNext) {
|
|
1796
1945
|
this.next();
|
|
1797
1946
|
return;
|
|
1798
1947
|
}
|
|
1948
|
+
if (!this.autoAdvanceEnabled && this.hasNext) {
|
|
1949
|
+
this.upNext.show();
|
|
1950
|
+
return;
|
|
1951
|
+
}
|
|
1799
1952
|
(this.options.related?.showOn?.includes("ended") ?? !!this.options.related) && this.related.show();
|
|
1800
1953
|
}
|
|
1801
1954
|
}
|
|
1955
|
+
/** Autoplay-next state (gear switch). Off → show the up-next card on end. */
|
|
1956
|
+
get autoAdvance() {
|
|
1957
|
+
return this.autoAdvanceEnabled;
|
|
1958
|
+
}
|
|
1959
|
+
setAutoAdvance(t) {
|
|
1960
|
+
this.autoAdvanceEnabled = t, t && this.upNext.hide();
|
|
1961
|
+
}
|
|
1802
1962
|
// === controls visibility ==============================================
|
|
1803
1963
|
bindIdleHide() {
|
|
1804
1964
|
const { signal: t } = this.abort, e = () => {
|
|
@@ -1863,22 +2023,22 @@ class Bt {
|
|
|
1863
2023
|
}
|
|
1864
2024
|
}
|
|
1865
2025
|
export {
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
2026
|
+
K as Emitter,
|
|
2027
|
+
Tt as Player,
|
|
2028
|
+
F as ThumbnailTrack,
|
|
2029
|
+
tt as buildHeatmapValues,
|
|
1870
2030
|
U as chapterAt,
|
|
1871
|
-
|
|
1872
|
-
|
|
2031
|
+
J as defaultIcons,
|
|
2032
|
+
q as defaultLabels,
|
|
1873
2033
|
x as formatTime,
|
|
1874
|
-
|
|
1875
|
-
|
|
2034
|
+
Y as getLocale,
|
|
2035
|
+
et as heatmapPath,
|
|
1876
2036
|
at as isHlsSource,
|
|
1877
2037
|
lt as loadChaptersVtt,
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
2038
|
+
W as normalizeChapters,
|
|
2039
|
+
_t as registerLocale,
|
|
2040
|
+
Lt as registerLocales,
|
|
2041
|
+
Bt as registeredLanguages,
|
|
2042
|
+
it as resolveVast
|
|
1883
2043
|
};
|
|
1884
2044
|
//# sourceMappingURL=core.js.map
|