@tidal-music/player-web-components 0.2.0 → 0.2.2

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.
Files changed (31) hide show
  1. package/dist/active-device-changed-DKzZonX1--oMxdziu.js +7 -0
  2. package/dist/active-device-mode-changed-Dj16yzUX-BbRjSd-6.js +7 -0
  3. package/dist/audio-context-store-Ccv6WKna-C-yxIXdl.js +36 -0
  4. package/dist/basePlayer-CxowZx76-CfK9Qp4M.js +380 -0
  5. package/dist/browserPlayer-CJUIZMXc-Cwz_EqKS.js +170 -0
  6. package/dist/generate-guid-DMif1b6n-WXvDGKGF.js +1716 -0
  7. package/dist/index.js +363 -10
  8. package/dist/load-D2Tka_Qx-BNIMgt7e.js +29305 -0
  9. package/dist/media-element-error-circuit-breaker-fMDQ6k4B-B9oZKZUK.js +22 -0
  10. package/dist/nativePlayer-Bk8Y048r-S6bg9D6D.js +232 -0
  11. package/dist/output-devices-kF_iC6GM-CnAUEjc9.js +156 -0
  12. package/dist/pushkin-BJAKy5lP-BDJR20nC.js +117 -0
  13. package/dist/pushkin-CVLqA7Zj-DJu6_unL.js +2 -0
  14. package/dist/shakaPlayer-BvtoIIdC-CizBy6it.js +1448 -0
  15. package/dist/src/helpers.d.ts +18 -0
  16. package/dist/src/index.d.ts +7 -0
  17. package/dist/src/tidal-current-time.d.ts +9 -0
  18. package/dist/src/tidal-duration-time.d.ts +9 -0
  19. package/dist/src/tidal-play-trigger.d.ts +2 -0
  20. package/dist/src/tidal-progress-bar.d.ts +2 -0
  21. package/dist/src/tidal-video-view.d.ts +2 -0
  22. package/dist/state-B888KJag-C7pa4Xs7.js +210 -0
  23. package/package.json +15 -13
  24. package/dist/_commonjsHelpers-DaMA6jEr-DtILRGNx.js +0 -8
  25. package/dist/basePlayer-C5QIyqfj-Dxhlf4BZ.js +0 -528
  26. package/dist/browserPlayer-HE2uqs17-DJrIq6Jp.js +0 -259
  27. package/dist/index-vp_MoGvy.js +0 -3417
  28. package/dist/index.d.ts +0 -24
  29. package/dist/nativePlayer-B3eHKegV-DdXsvi0F.js +0 -323
  30. package/dist/output-devices-Jno8Kp5B-CAnEAv_Z.js +0 -224
  31. package/dist/shakaPlayer-CCJQsypf-DHT2kwDp.js +0 -24411
@@ -1,3417 +0,0 @@
1
- let A = Object.freeze({
2
- apiUrl: "https://api.tidal.com/v1",
3
- desiredVolumeLevel: 1,
4
- gatherEvents: !0,
5
- loudnessNormalizationMode: "ALBUM",
6
- outputDevicesEnabled: !1,
7
- streamingWifiAudioQuality: "LOW"
8
- });
9
- function _(r) {
10
- return A[r];
11
- }
12
- function B(r) {
13
- return A = Object.freeze({
14
- ...A,
15
- ...r
16
- }), Object.keys(r).forEach((e) => {
17
- const t = e;
18
- oe.dispatchEvent(new CustomEvent(t, { detail: r[t] }));
19
- }), A;
20
- }
21
- const oe = new EventTarget();
22
- class ce {
23
- #e;
24
- #r = !1;
25
- #s;
26
- #t;
27
- constructor(e) {
28
- this.#t = new URL(e), this.synchronize();
29
- }
30
- /**
31
- * Returns the current time adjusted to server-time.
32
- *
33
- * @param clientCurrentTime The current time on the client side. Defaults to Date.now().
34
- * @returns The current adjusted time (or the client time if not synced yet).
35
- */
36
- // eslint-disable-next-line no-restricted-syntax
37
- now(e = Date.now()) {
38
- return !this.#s || !this.#e ? (console.warn("TrueTime is not yet synchronized"), e) : this.#s + (e - this.#e);
39
- }
40
- /**
41
- * Synchronizes the client's time with the server's time.
42
- * If the client's time is already synchronized within an hour, this method does nothing.
43
- *
44
- * @returns {Promise<void>} A promise that resolves when the synchronization is complete.
45
- */
46
- async synchronize() {
47
- if (!(this.#e && // eslint-disable-next-line no-restricted-syntax
48
- Math.abs(Date.now() - this.#e) < 36e5 || this.#r)) {
49
- this.#r = !0;
50
- try {
51
- const e = await fetch(this.#t);
52
- e.ok && e.headers.has("date") && (this.#s = new Date(e.headers.get("date")).getTime(), this.#e = Date.now());
53
- } catch (e) {
54
- console.error(e);
55
- }
56
- this.#r = !1;
57
- }
58
- }
59
- /**
60
- * Returns the timestamp of a performance mark with the specified name and detail.
61
- * PS: `performance.mark` must be called with `startTime: trueTime.now()`.
62
- *
63
- * @param markName - The name of the performance mark.
64
- * @param detail - Optional. The detail of the performance mark.
65
- * @returns The timestamp of the performance mark, or undefined if not found.
66
- * @throws ReferenceError if the performance mark is not found.
67
- */
68
- timestamp(e, t) {
69
- let s;
70
- if (t) {
71
- if (s = performance.getEntriesByName(e).find((n) => "detail" in n && n.detail === t), !s)
72
- throw new ReferenceError(
73
- `There is no performance entry named "${e}" with detail "${t}"`
74
- );
75
- } else
76
- s = performance.getEntriesByName(e).pop();
77
- return s ? s.startTime : void 0;
78
- }
79
- }
80
- const y = new ce("https://api.tidal.com/v1/ping"), de = (r, e, t) => {
81
- for (const s of r) {
82
- const n = s.addedNodes[0];
83
- s.type === "childList" && n.id === e && t();
84
- }
85
- };
86
- function le() {
87
- const r = document.getElementById("tidal-player-root");
88
- if (!r)
89
- return Promise.reject("No player root");
90
- if ("video-one" in r.children)
91
- return Promise.resolve();
92
- const e = [];
93
- return "video-one" in r.children || e.push(
94
- new Promise((t) => {
95
- new MutationObserver(
96
- (s) => de(s, "video-one", t)
97
- ).observe(r, { childList: !0 });
98
- })
99
- ), Promise.all(e);
100
- }
101
- const E = document.createElement("video"), ue = (r) => {
102
- r.setAttribute("crossorigin", "anonymous"), r.setAttribute("playsinline", "playsinline");
103
- };
104
- ue(E);
105
- E.id = "video-one";
106
- const O = "tidal-player-root";
107
- function he() {
108
- let r = document.getElementById(O);
109
- if (!r) {
110
- const e = document.createElement("template");
111
- e.id = O, document.body.appendChild(e), r = document.getElementById(O);
112
- }
113
- return me();
114
- }
115
- function me() {
116
- const r = document.getElementById(
117
- O
118
- );
119
- return r && (E.id in r.children || r.appendChild(E)), le();
120
- }
121
- function pe() {
122
- return new Promise(
123
- (r) => document.addEventListener(
124
- "click",
125
- () => {
126
- E.readyState === HTMLMediaElement.HAVE_NOTHING && !E.src && E.load(), r();
127
- },
128
- { once: !0 }
129
- )
130
- );
131
- }
132
- function fe(r) {
133
- return new Promise((e) => setTimeout(() => e(), r));
134
- }
135
- function ge(r, e) {
136
- return new Promise((t) => {
137
- r.addEventListener(e, (s) => t(s), !1);
138
- });
139
- }
140
- class ye extends EventTarget {
141
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
142
- // @ts-ignore - Setter
143
- #e;
144
- hasEventSender() {
145
- return !!this.#e;
146
- }
147
- set eventSender(e) {
148
- this.#e = e;
149
- }
150
- get eventSender() {
151
- return this.#e;
152
- }
153
- }
154
- class we extends EventTarget {
155
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
156
- // @ts-ignore - Setter
157
- #e;
158
- async dispatchAuthorized() {
159
- const e = await this.#e.getCredentials();
160
- e?.token ? this.dispatchEvent(
161
- new CustomEvent("authorized", {
162
- detail: {
163
- credentials: e
164
- }
165
- })
166
- ) : this.dispatchEvent(
167
- new CustomEvent("unauthenticated", { detail: { credentials: e } })
168
- );
169
- }
170
- set credentialsProvider(e) {
171
- this.#e = e, this.dispatchAuthorized().catch(console.error), this.#e.bus((t) => {
172
- switch (t.detail.type) {
173
- case "CredentialsUpdatedMessage":
174
- this.dispatchAuthorized().catch(console.error);
175
- break;
176
- default:
177
- console.warn("Unhandled event from credentials provider: ", t);
178
- break;
179
- }
180
- });
181
- }
182
- get credentialsProvider() {
183
- return this.#e;
184
- }
185
- }
186
- class C extends Error {
187
- errorCode = null;
188
- errorId = null;
189
- referenceId;
190
- constructor(e, t, s) {
191
- super(`${e}: ${t} (${s})`), this.errorId = e, this.errorCode = t, this.referenceId = s;
192
- }
193
- toJSON() {
194
- return {
195
- errorCode: this.errorCode,
196
- errorId: this.errorId,
197
- referenceId: this.referenceId
198
- };
199
- }
200
- toString() {
201
- return JSON.stringify(this.toJSON());
202
- }
203
- }
204
- async function P() {
205
- if (v.credentialsProvider) {
206
- const r = await v.credentialsProvider.getCredentials();
207
- return !!(r.token && r.userId);
208
- }
209
- return await ge(v, "authorized"), P();
210
- }
211
- const v = new we(), D = new ye();
212
- async function be() {
213
- const r = await P(), e = async () => {
214
- const { Pushkin: t } = await Promise.resolve().then(() => gt);
215
- return t.refresh();
216
- };
217
- if (r) {
218
- B({
219
- gatherEvents: !0
220
- });
221
- try {
222
- await Promise.all([e()]);
223
- } catch (t) {
224
- console.error(t);
225
- }
226
- } else
227
- B({
228
- gatherEvents: !1
229
- });
230
- }
231
- function ve() {
232
- B({
233
- gatherEvents: !0
234
- });
235
- }
236
- v.addEventListener("authorized", () => {
237
- be().then().catch(console.error);
238
- });
239
- v.addEventListener("unauthenticated", () => {
240
- ve();
241
- });
242
- async function V() {
243
- return v.credentialsProvider ? (await v.credentialsProvider.getCredentials()).token ?? null : null;
244
- }
245
- class Se extends EventTarget {
246
- dispatchError(e) {
247
- this.dispatchEvent(
248
- new CustomEvent("error", {
249
- detail: e.toJSON()
250
- })
251
- );
252
- }
253
- }
254
- const m = new Se();
255
- class Me {
256
- #e = /* @__PURE__ */ new Map();
257
- #r = /* @__PURE__ */ new Map();
258
- #s = /* @__PURE__ */ new Map();
259
- #t = /* @__PURE__ */ new Map();
260
- /**
261
- * Clones a session to re-use the media product and playback content for a new session.
262
- *
263
- * @param from - streamingSessionId to clone
264
- * @param to - target streamingSessionId
265
- */
266
- clone(e, t) {
267
- const s = this.getMediaProductTransition(e), n = this.getStreamInfo(e), o = this.getPlaybackInfo(e);
268
- if (!s || !n || !o)
269
- throw new Error(
270
- `Cannot clone ${e}. Missing mediaProductTransition or streamInfo.`
271
- );
272
- this.saveMediaProductTransition(t, {
273
- ...s,
274
- playbackContext: {
275
- ...s.playbackContext,
276
- playbackSessionId: t
277
- }
278
- }), this.saveStreamInfo(t, {
279
- ...n,
280
- streamingSessionId: t
281
- }), this.savePlaybackInfo(t, {
282
- ...o,
283
- streamingSessionId: t
284
- });
285
- }
286
- deleteMediaProductTransition(e) {
287
- this.#e.delete(e);
288
- }
289
- /**
290
- * Removed cached playbackInfo, streamInfo and mediaProductTransition for session.
291
- * For re-using playbackInfo etc for other sessions make sure to run clone before deletion!
292
- *
293
- * @see {@link StreamingSessionStore.clone}
294
- */
295
- deleteSession(e) {
296
- this.deleteMediaProductTransition(e), this.#r.delete(e), this.#s.delete(e), this.deleteStreamInfo(e);
297
- }
298
- deleteStartedStreamInfo(e) {
299
- this.#s.delete(e);
300
- }
301
- deleteStreamInfo(e) {
302
- this.#t.delete(e);
303
- }
304
- getMediaProductTransition(e) {
305
- return e ? this.#e.get(e) : void 0;
306
- }
307
- getPlaybackInfo(e) {
308
- return e ? this.#r.get(e) : void 0;
309
- }
310
- getStreamInfo(e) {
311
- return e ? this.#t.get(e) : void 0;
312
- }
313
- hasMediaProductTransition(e) {
314
- return this.#e.has(e);
315
- }
316
- hasPlaybackInfo(e) {
317
- return this.#r.has(e);
318
- }
319
- hasStartedStreamInfo(e) {
320
- return this.#s.has(e);
321
- }
322
- hasStreamInfo(e) {
323
- return this.#t.has(e);
324
- }
325
- overwriteDuration(e, t) {
326
- const s = this.#e.get(e);
327
- s && (s.playbackContext = {
328
- ...s.playbackContext,
329
- actualDuration: t
330
- }, this.saveMediaProductTransition(e, s));
331
- }
332
- saveMediaProductTransition(e, t) {
333
- this.#e.set(
334
- e,
335
- t
336
- );
337
- }
338
- savePlaybackInfo(e, t) {
339
- this.#r.set(e, t);
340
- }
341
- saveStreamInfo(e, t) {
342
- this.#t.set(e, t);
343
- }
344
- setStartedStreamInfo(e) {
345
- return this.#s.set(e, !0);
346
- }
347
- }
348
- const H = new Me();
349
- class Ee {
350
- activePlayer;
351
- preloadPlayer;
352
- get preloadedMediaProduct() {
353
- return H.getMediaProductTransition(
354
- this.preloadedStreamingSessionId
355
- )?.mediaProduct ?? void 0;
356
- }
357
- get preloadedStreamingSessionId() {
358
- return this.preloadPlayer?.preloadedStreamingSessionId ?? void 0;
359
- }
360
- }
361
- const p = new Ee();
362
- let ke;
363
- const Pe = [
364
- {
365
- itemTypes: ["track", "video", "demo"],
366
- player: "shaka",
367
- qualities: ["HIGH", "LOSSLESS", "LOW", "HI_RES_LOSSLESS"]
368
- }
369
- ];
370
- let x = Pe;
371
- const w = {
372
- browser: void 0,
373
- native: void 0,
374
- shaka: void 0
375
- };
376
- async function Te() {
377
- await Promise.all(
378
- x.map((r) => {
379
- const e = w[r.player];
380
- return e ? e.reset() : Promise.resolve();
381
- })
382
- ), p.activePlayer = void 0, p.preloadPlayer = void 0;
383
- }
384
- function Ie(r) {
385
- r.name !== "nativePlayer" && w.native && w.native.abandon(), p.activePlayer = r;
386
- }
387
- function Le() {
388
- m.removeEventListener("ended", ke);
389
- }
390
- async function Ae() {
391
- const { default: r } = await import("./nativePlayer-B3eHKegV-DdXsvi0F.js");
392
- return w.native || (w.native = new r()), w.native;
393
- }
394
- async function Oe() {
395
- const { default: r } = await import("./browserPlayer-HE2uqs17-DJrIq6Jp.js");
396
- return w.browser || (w.browser = new r()), w.browser;
397
- }
398
- async function Ce() {
399
- const { default: r } = await import("./shakaPlayer-CCJQsypf-DHT2kwDp.js");
400
- return w.shaka || (w.shaka = new r()), w.shaka;
401
- }
402
- async function _e(r, e) {
403
- const t = x.filter((n) => n.itemTypes.includes(r)).filter(
404
- (n) => r === "track" && n.qualities && e ? n.qualities.includes(e) : !0
405
- );
406
- t.length === 0 && console.error(
407
- `No player found to handle audio quality "${String(
408
- e
409
- )}" for product type "${r}" in player config: `,
410
- x
411
- );
412
- const { player: s } = t[0];
413
- switch (s) {
414
- case "browser":
415
- return Oe();
416
- case "native":
417
- return Ae();
418
- case "shaka":
419
- return Ce();
420
- default:
421
- throw new Error("No player found.");
422
- }
423
- }
424
- function Fe() {
425
- return p.activePlayer?.getPosition() ?? 0;
426
- }
427
- function Ne() {
428
- return p.activePlayer?.currentMediaProduct ?? null;
429
- }
430
- function Be() {
431
- const r = p.activePlayer;
432
- if (r) {
433
- const e = H.getMediaProductTransition(
434
- r.currentStreamingSessionId
435
- );
436
- if (e)
437
- return e.playbackContext;
438
- }
439
- }
440
- function Q() {
441
- return p.activePlayer?.playbackState ?? "IDLE";
442
- }
443
- class xe {
444
- #e;
445
- constructor() {
446
- this.#e = /* @__PURE__ */ new Map();
447
- }
448
- async #r(e, t) {
449
- const s = new TextEncoder().encode(
450
- `${e}-${t}`
451
- ), n = await crypto.subtle.digest("SHA-1", s);
452
- return Array.from(new Uint8Array(n)).map((o) => o.toString(16).padStart(2, "0")).join("");
453
- }
454
- /**
455
- * Delete a logged event by name and streamingSessionId.
456
- */
457
- async delete({
458
- name: e,
459
- streamingSessionId: t
460
- }) {
461
- const s = await this.#r(
462
- t,
463
- e
464
- );
465
- this.#e.delete(s);
466
- }
467
- /**
468
- * Get a logged event by name and streamingSessionId.
469
- */
470
- async get({
471
- name: e,
472
- streamingSessionId: t
473
- }) {
474
- const s = await this.#r(
475
- t,
476
- e
477
- );
478
- return this.#e.get(s);
479
- }
480
- /**
481
- * Adds or updates an event.
482
- */
483
- async put(e) {
484
- const t = await this.#r(
485
- e.streamingSessionId,
486
- e.name
487
- );
488
- this.#e.set(t, e);
489
- }
490
- }
491
- const R = new xe();
492
- async function T(r, e) {
493
- return _("gatherEvents") ? async (t) => {
494
- try {
495
- const s = await R.get({
496
- name: r,
497
- streamingSessionId: t.streamingSessionId
498
- }), n = Object.assign(
499
- {},
500
- e,
501
- s ? s.payload : {},
502
- t
503
- );
504
- for (const o of Object.keys(t)) {
505
- const a = o;
506
- Array.isArray(t[a]) && (n[a] = [
507
- ...e[a] || [],
508
- ...s && s.payload[a] || [],
509
- ...t[a] || []
510
- ]);
511
- }
512
- return await R.put({
513
- name: r,
514
- payload: n,
515
- streamingSessionId: t.streamingSessionId
516
- }), {
517
- name: r,
518
- payload: n,
519
- streamingSessionId: t.streamingSessionId
520
- };
521
- } catch (s) {
522
- console.error(s);
523
- }
524
- } : (t) => Promise.resolve(void 0);
525
- }
526
- const Re = {
527
- endReason: "COMPLETE",
528
- endTimestamp: 0,
529
- errorCode: null,
530
- errorMessage: null,
531
- startTimestamp: 0,
532
- streamingSessionId: ""
533
- }, De = await T(
534
- "drm_license_fetch",
535
- Re
536
- );
537
- function Dt(r) {
538
- return De(r);
539
- }
540
- const He = {
541
- endReason: "COMPLETE",
542
- endTimestamp: 0,
543
- errorCode: null,
544
- errorMessage: null,
545
- startTimestamp: 0,
546
- streamingSessionId: ""
547
- }, Ue = await T(
548
- "playback_info_fetch",
549
- He
550
- );
551
- function N(r) {
552
- return Ue(r);
553
- }
554
- function Ht(r) {
555
- switch (r) {
556
- case "bluetooth":
557
- return "BLUETOOTH";
558
- case "builtIn":
559
- return "BUILT_IN";
560
- case "displayPort":
561
- return "DISPLAY_PORT";
562
- case "hdmi":
563
- return "HDMI";
564
- case "systemDefault":
565
- return "SYSTEM_DEFAULT";
566
- case "usb":
567
- return "USB";
568
- // Never happens (cannot be chose by user)
569
- case "airplay":
570
- case "windowsCommunication":
571
- default:
572
- return;
573
- }
574
- }
575
- const Ve = {
576
- actualAssetPresentation: "FULL",
577
- actualAudioMode: "STEREO",
578
- actualProductId: null,
579
- actualQuality: "LOSSLESS",
580
- actualStartTimestamp: 0,
581
- actualStreamType: "ON_DEMAND",
582
- adaptations: [],
583
- cdm: "WIDEVINE",
584
- cdmVersion: null,
585
- endReason: "COMPLETE",
586
- endTimestamp: 0,
587
- errorCode: null,
588
- errorMessage: null,
589
- hasAds: !1,
590
- idealStartTimestamp: 0,
591
- outputDevice: null,
592
- productType: "TRACK",
593
- stalls: [],
594
- streamingSessionId: ""
595
- }, ze = await T(
596
- "playback_statistics",
597
- Ve
598
- );
599
- function z(r) {
600
- return ze(r);
601
- }
602
- const We = {
603
- streamingSessionId: "",
604
- timestamp: 0
605
- }, $e = await T(
606
- "streaming_session_end",
607
- We
608
- );
609
- function Qe(r) {
610
- return $e(r);
611
- }
612
- const Ge = {
613
- "Amazon Silk": "amazon_silk",
614
- "Android Browser": "android",
615
- Bada: "bada",
616
- BlackBerry: "blackberry",
617
- Chrome: "chrome",
618
- Chromium: "chromium",
619
- Electron: "electron",
620
- Epiphany: "epiphany",
621
- Firefox: "firefox",
622
- Focus: "focus",
623
- Generic: "generic",
624
- "Google Search": "google_search",
625
- Googlebot: "googlebot",
626
- "Internet Explorer": "ie",
627
- "K-Meleon": "k_meleon",
628
- Maxthon: "maxthon",
629
- "Microsoft Edge": "edge",
630
- "MZ Browser": "mz",
631
- "NAVER Whale Browser": "naver",
632
- Opera: "opera",
633
- "Opera Coast": "opera_coast",
634
- "Pale Moon": "pale_moon",
635
- PhantomJS: "phantomjs",
636
- Puffin: "puffin",
637
- QupZilla: "qupzilla",
638
- QQ: "qq",
639
- QQLite: "qqlite",
640
- Safari: "safari",
641
- Sailfish: "sailfish",
642
- "Samsung Internet for Android": "samsung_internet",
643
- SeaMonkey: "seamonkey",
644
- Sleipnir: "sleipnir",
645
- Swing: "swing",
646
- Tizen: "tizen",
647
- "UC Browser": "uc",
648
- Vivaldi: "vivaldi",
649
- "WebOS Browser": "webos",
650
- WeChat: "wechat",
651
- "Yandex Browser": "yandex",
652
- Roku: "roku"
653
- }, G = {
654
- amazon_silk: "Amazon Silk",
655
- android: "Android Browser",
656
- bada: "Bada",
657
- blackberry: "BlackBerry",
658
- chrome: "Chrome",
659
- chromium: "Chromium",
660
- electron: "Electron",
661
- epiphany: "Epiphany",
662
- firefox: "Firefox",
663
- focus: "Focus",
664
- generic: "Generic",
665
- googlebot: "Googlebot",
666
- google_search: "Google Search",
667
- ie: "Internet Explorer",
668
- k_meleon: "K-Meleon",
669
- maxthon: "Maxthon",
670
- edge: "Microsoft Edge",
671
- mz: "MZ Browser",
672
- naver: "NAVER Whale Browser",
673
- opera: "Opera",
674
- opera_coast: "Opera Coast",
675
- pale_moon: "Pale Moon",
676
- phantomjs: "PhantomJS",
677
- puffin: "Puffin",
678
- qupzilla: "QupZilla",
679
- qq: "QQ Browser",
680
- qqlite: "QQ Browser Lite",
681
- safari: "Safari",
682
- sailfish: "Sailfish",
683
- samsung_internet: "Samsung Internet for Android",
684
- seamonkey: "SeaMonkey",
685
- sleipnir: "Sleipnir",
686
- swing: "Swing",
687
- tizen: "Tizen",
688
- uc: "UC Browser",
689
- vivaldi: "Vivaldi",
690
- webos: "WebOS Browser",
691
- wechat: "WeChat",
692
- yandex: "Yandex Browser"
693
- }, h = {
694
- tablet: "tablet",
695
- mobile: "mobile",
696
- desktop: "desktop",
697
- tv: "tv",
698
- bot: "bot"
699
- }, g = {
700
- WindowsPhone: "Windows Phone",
701
- Windows: "Windows",
702
- MacOS: "macOS",
703
- iOS: "iOS",
704
- Android: "Android",
705
- WebOS: "WebOS",
706
- BlackBerry: "BlackBerry",
707
- Bada: "Bada",
708
- Tizen: "Tizen",
709
- Linux: "Linux",
710
- ChromeOS: "Chrome OS",
711
- PlayStation4: "PlayStation 4",
712
- Roku: "Roku"
713
- }, S = {
714
- EdgeHTML: "EdgeHTML",
715
- Blink: "Blink",
716
- Trident: "Trident",
717
- Presto: "Presto",
718
- Gecko: "Gecko",
719
- WebKit: "WebKit"
720
- };
721
- class i {
722
- /**
723
- * Get first matched item for a string
724
- * @param {RegExp} regexp
725
- * @param {String} ua
726
- * @return {Array|{index: number, input: string}|*|boolean|string}
727
- */
728
- static getFirstMatch(e, t) {
729
- const s = t.match(e);
730
- return s && s.length > 0 && s[1] || "";
731
- }
732
- /**
733
- * Get second matched item for a string
734
- * @param regexp
735
- * @param {String} ua
736
- * @return {Array|{index: number, input: string}|*|boolean|string}
737
- */
738
- static getSecondMatch(e, t) {
739
- const s = t.match(e);
740
- return s && s.length > 1 && s[2] || "";
741
- }
742
- /**
743
- * Match a regexp and return a constant or undefined
744
- * @param {RegExp} regexp
745
- * @param {String} ua
746
- * @param {*} _const Any const that will be returned if regexp matches the string
747
- * @return {*}
748
- */
749
- static matchAndReturnConst(e, t, s) {
750
- if (e.test(t))
751
- return s;
752
- }
753
- static getWindowsVersionName(e) {
754
- switch (e) {
755
- case "NT":
756
- return "NT";
757
- case "XP":
758
- return "XP";
759
- case "NT 5.0":
760
- return "2000";
761
- case "NT 5.1":
762
- return "XP";
763
- case "NT 5.2":
764
- return "2003";
765
- case "NT 6.0":
766
- return "Vista";
767
- case "NT 6.1":
768
- return "7";
769
- case "NT 6.2":
770
- return "8";
771
- case "NT 6.3":
772
- return "8.1";
773
- case "NT 10.0":
774
- return "10";
775
- default:
776
- return;
777
- }
778
- }
779
- /**
780
- * Get macOS version name
781
- * 10.5 - Leopard
782
- * 10.6 - Snow Leopard
783
- * 10.7 - Lion
784
- * 10.8 - Mountain Lion
785
- * 10.9 - Mavericks
786
- * 10.10 - Yosemite
787
- * 10.11 - El Capitan
788
- * 10.12 - Sierra
789
- * 10.13 - High Sierra
790
- * 10.14 - Mojave
791
- * 10.15 - Catalina
792
- *
793
- * @example
794
- * getMacOSVersionName("10.14") // 'Mojave'
795
- *
796
- * @param {string} version
797
- * @return {string} versionName
798
- */
799
- static getMacOSVersionName(e) {
800
- const t = e.split(".").splice(0, 2).map((s) => parseInt(s, 10) || 0);
801
- if (t.push(0), t[0] === 10)
802
- switch (t[1]) {
803
- case 5:
804
- return "Leopard";
805
- case 6:
806
- return "Snow Leopard";
807
- case 7:
808
- return "Lion";
809
- case 8:
810
- return "Mountain Lion";
811
- case 9:
812
- return "Mavericks";
813
- case 10:
814
- return "Yosemite";
815
- case 11:
816
- return "El Capitan";
817
- case 12:
818
- return "Sierra";
819
- case 13:
820
- return "High Sierra";
821
- case 14:
822
- return "Mojave";
823
- case 15:
824
- return "Catalina";
825
- default:
826
- return;
827
- }
828
- }
829
- /**
830
- * Get Android version name
831
- * 1.5 - Cupcake
832
- * 1.6 - Donut
833
- * 2.0 - Eclair
834
- * 2.1 - Eclair
835
- * 2.2 - Froyo
836
- * 2.x - Gingerbread
837
- * 3.x - Honeycomb
838
- * 4.0 - Ice Cream Sandwich
839
- * 4.1 - Jelly Bean
840
- * 4.4 - KitKat
841
- * 5.x - Lollipop
842
- * 6.x - Marshmallow
843
- * 7.x - Nougat
844
- * 8.x - Oreo
845
- * 9.x - Pie
846
- *
847
- * @example
848
- * getAndroidVersionName("7.0") // 'Nougat'
849
- *
850
- * @param {string} version
851
- * @return {string} versionName
852
- */
853
- static getAndroidVersionName(e) {
854
- const t = e.split(".").splice(0, 2).map((s) => parseInt(s, 10) || 0);
855
- if (t.push(0), !(t[0] === 1 && t[1] < 5)) {
856
- if (t[0] === 1 && t[1] < 6) return "Cupcake";
857
- if (t[0] === 1 && t[1] >= 6) return "Donut";
858
- if (t[0] === 2 && t[1] < 2) return "Eclair";
859
- if (t[0] === 2 && t[1] === 2) return "Froyo";
860
- if (t[0] === 2 && t[1] > 2) return "Gingerbread";
861
- if (t[0] === 3) return "Honeycomb";
862
- if (t[0] === 4 && t[1] < 1) return "Ice Cream Sandwich";
863
- if (t[0] === 4 && t[1] < 4) return "Jelly Bean";
864
- if (t[0] === 4 && t[1] >= 4) return "KitKat";
865
- if (t[0] === 5) return "Lollipop";
866
- if (t[0] === 6) return "Marshmallow";
867
- if (t[0] === 7) return "Nougat";
868
- if (t[0] === 8) return "Oreo";
869
- if (t[0] === 9) return "Pie";
870
- }
871
- }
872
- /**
873
- * Get version precisions count
874
- *
875
- * @example
876
- * getVersionPrecision("1.10.3") // 3
877
- *
878
- * @param {string} version
879
- * @return {number}
880
- */
881
- static getVersionPrecision(e) {
882
- return e.split(".").length;
883
- }
884
- /**
885
- * Calculate browser version weight
886
- *
887
- * @example
888
- * compareVersions('1.10.2.1', '1.8.2.1.90') // 1
889
- * compareVersions('1.010.2.1', '1.09.2.1.90'); // 1
890
- * compareVersions('1.10.2.1', '1.10.2.1'); // 0
891
- * compareVersions('1.10.2.1', '1.0800.2'); // -1
892
- * compareVersions('1.10.2.1', '1.10', true); // 0
893
- *
894
- * @param {String} versionA versions versions to compare
895
- * @param {String} versionB versions versions to compare
896
- * @param {boolean} [isLoose] enable loose comparison
897
- * @return {Number} comparison result: -1 when versionA is lower,
898
- * 1 when versionA is bigger, 0 when both equal
899
- */
900
- /* eslint consistent-return: 1 */
901
- static compareVersions(e, t, s = !1) {
902
- const n = i.getVersionPrecision(e), o = i.getVersionPrecision(t);
903
- let a = Math.max(n, o), c = 0;
904
- const u = i.map([e, t], (d) => {
905
- const b = a - i.getVersionPrecision(d), M = d + new Array(b + 1).join(".0");
906
- return i.map(M.split("."), (f) => new Array(20 - f.length).join("0") + f).reverse();
907
- });
908
- for (s && (c = a - Math.min(n, o)), a -= 1; a >= c; ) {
909
- if (u[0][a] > u[1][a])
910
- return 1;
911
- if (u[0][a] === u[1][a]) {
912
- if (a === c)
913
- return 0;
914
- a -= 1;
915
- } else if (u[0][a] < u[1][a])
916
- return -1;
917
- }
918
- }
919
- /**
920
- * Array::map polyfill
921
- *
922
- * @param {Array} arr
923
- * @param {Function} iterator
924
- * @return {Array}
925
- */
926
- static map(e, t) {
927
- const s = [];
928
- let n;
929
- if (Array.prototype.map)
930
- return Array.prototype.map.call(e, t);
931
- for (n = 0; n < e.length; n += 1)
932
- s.push(t(e[n]));
933
- return s;
934
- }
935
- /**
936
- * Array::find polyfill
937
- *
938
- * @param {Array} arr
939
- * @param {Function} predicate
940
- * @return {Array}
941
- */
942
- static find(e, t) {
943
- let s, n;
944
- if (Array.prototype.find)
945
- return Array.prototype.find.call(e, t);
946
- for (s = 0, n = e.length; s < n; s += 1) {
947
- const o = e[s];
948
- if (t(o, s))
949
- return o;
950
- }
951
- }
952
- /**
953
- * Object::assign polyfill
954
- *
955
- * @param {Object} obj
956
- * @param {Object} ...objs
957
- * @return {Object}
958
- */
959
- static assign(e, ...t) {
960
- const s = e;
961
- let n, o;
962
- if (Object.assign)
963
- return Object.assign(e, ...t);
964
- for (n = 0, o = t.length; n < o; n += 1) {
965
- const a = t[n];
966
- typeof a == "object" && a !== null && Object.keys(a).forEach((c) => {
967
- s[c] = a[c];
968
- });
969
- }
970
- return e;
971
- }
972
- /**
973
- * Get short version/alias for a browser name
974
- *
975
- * @example
976
- * getBrowserAlias('Microsoft Edge') // edge
977
- *
978
- * @param {string} browserName
979
- * @return {string}
980
- */
981
- static getBrowserAlias(e) {
982
- return Ge[e];
983
- }
984
- /**
985
- * Get browser name for a short version/alias
986
- *
987
- * @example
988
- * getBrowserTypeByAlias('edge') // Microsoft Edge
989
- *
990
- * @param {string} browserAlias
991
- * @return {string}
992
- */
993
- static getBrowserTypeByAlias(e) {
994
- return G[e] || "";
995
- }
996
- }
997
- const l = /version\/(\d+(\.?_?\d+)+)/i, qe = [
998
- /* Googlebot */
999
- {
1000
- test: [/googlebot/i],
1001
- describe(r) {
1002
- const e = {
1003
- name: "Googlebot"
1004
- }, t = i.getFirstMatch(/googlebot\/(\d+(\.\d+))/i, r) || i.getFirstMatch(l, r);
1005
- return t && (e.version = t), e;
1006
- }
1007
- },
1008
- /* Opera < 13.0 */
1009
- {
1010
- test: [/opera/i],
1011
- describe(r) {
1012
- const e = {
1013
- name: "Opera"
1014
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:opera)[\s/](\d+(\.?_?\d+)+)/i, r);
1015
- return t && (e.version = t), e;
1016
- }
1017
- },
1018
- /* Opera > 13.0 */
1019
- {
1020
- test: [/opr\/|opios/i],
1021
- describe(r) {
1022
- const e = {
1023
- name: "Opera"
1024
- }, t = i.getFirstMatch(/(?:opr|opios)[\s/](\S+)/i, r) || i.getFirstMatch(l, r);
1025
- return t && (e.version = t), e;
1026
- }
1027
- },
1028
- {
1029
- test: [/SamsungBrowser/i],
1030
- describe(r) {
1031
- const e = {
1032
- name: "Samsung Internet for Android"
1033
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:SamsungBrowser)[\s/](\d+(\.?_?\d+)+)/i, r);
1034
- return t && (e.version = t), e;
1035
- }
1036
- },
1037
- {
1038
- test: [/Whale/i],
1039
- describe(r) {
1040
- const e = {
1041
- name: "NAVER Whale Browser"
1042
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:whale)[\s/](\d+(?:\.\d+)+)/i, r);
1043
- return t && (e.version = t), e;
1044
- }
1045
- },
1046
- {
1047
- test: [/PaleMoon/i],
1048
- describe(r) {
1049
- const e = {
1050
- name: "Pale Moon"
1051
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:PaleMoon)[\s/](\d+(?:\.\d+)+)/i, r);
1052
- return t && (e.version = t), e;
1053
- }
1054
- },
1055
- {
1056
- test: [/MZBrowser/i],
1057
- describe(r) {
1058
- const e = {
1059
- name: "MZ Browser"
1060
- }, t = i.getFirstMatch(/(?:MZBrowser)[\s/](\d+(?:\.\d+)+)/i, r) || i.getFirstMatch(l, r);
1061
- return t && (e.version = t), e;
1062
- }
1063
- },
1064
- {
1065
- test: [/focus/i],
1066
- describe(r) {
1067
- const e = {
1068
- name: "Focus"
1069
- }, t = i.getFirstMatch(/(?:focus)[\s/](\d+(?:\.\d+)+)/i, r) || i.getFirstMatch(l, r);
1070
- return t && (e.version = t), e;
1071
- }
1072
- },
1073
- {
1074
- test: [/swing/i],
1075
- describe(r) {
1076
- const e = {
1077
- name: "Swing"
1078
- }, t = i.getFirstMatch(/(?:swing)[\s/](\d+(?:\.\d+)+)/i, r) || i.getFirstMatch(l, r);
1079
- return t && (e.version = t), e;
1080
- }
1081
- },
1082
- {
1083
- test: [/coast/i],
1084
- describe(r) {
1085
- const e = {
1086
- name: "Opera Coast"
1087
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:coast)[\s/](\d+(\.?_?\d+)+)/i, r);
1088
- return t && (e.version = t), e;
1089
- }
1090
- },
1091
- {
1092
- test: [/opt\/\d+(?:.?_?\d+)+/i],
1093
- describe(r) {
1094
- const e = {
1095
- name: "Opera Touch"
1096
- }, t = i.getFirstMatch(/(?:opt)[\s/](\d+(\.?_?\d+)+)/i, r) || i.getFirstMatch(l, r);
1097
- return t && (e.version = t), e;
1098
- }
1099
- },
1100
- {
1101
- test: [/yabrowser/i],
1102
- describe(r) {
1103
- const e = {
1104
- name: "Yandex Browser"
1105
- }, t = i.getFirstMatch(/(?:yabrowser)[\s/](\d+(\.?_?\d+)+)/i, r) || i.getFirstMatch(l, r);
1106
- return t && (e.version = t), e;
1107
- }
1108
- },
1109
- {
1110
- test: [/ucbrowser/i],
1111
- describe(r) {
1112
- const e = {
1113
- name: "UC Browser"
1114
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:ucbrowser)[\s/](\d+(\.?_?\d+)+)/i, r);
1115
- return t && (e.version = t), e;
1116
- }
1117
- },
1118
- {
1119
- test: [/Maxthon|mxios/i],
1120
- describe(r) {
1121
- const e = {
1122
- name: "Maxthon"
1123
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:Maxthon|mxios)[\s/](\d+(\.?_?\d+)+)/i, r);
1124
- return t && (e.version = t), e;
1125
- }
1126
- },
1127
- {
1128
- test: [/epiphany/i],
1129
- describe(r) {
1130
- const e = {
1131
- name: "Epiphany"
1132
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:epiphany)[\s/](\d+(\.?_?\d+)+)/i, r);
1133
- return t && (e.version = t), e;
1134
- }
1135
- },
1136
- {
1137
- test: [/puffin/i],
1138
- describe(r) {
1139
- const e = {
1140
- name: "Puffin"
1141
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:puffin)[\s/](\d+(\.?_?\d+)+)/i, r);
1142
- return t && (e.version = t), e;
1143
- }
1144
- },
1145
- {
1146
- test: [/sleipnir/i],
1147
- describe(r) {
1148
- const e = {
1149
- name: "Sleipnir"
1150
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:sleipnir)[\s/](\d+(\.?_?\d+)+)/i, r);
1151
- return t && (e.version = t), e;
1152
- }
1153
- },
1154
- {
1155
- test: [/k-meleon/i],
1156
- describe(r) {
1157
- const e = {
1158
- name: "K-Meleon"
1159
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/(?:k-meleon)[\s/](\d+(\.?_?\d+)+)/i, r);
1160
- return t && (e.version = t), e;
1161
- }
1162
- },
1163
- {
1164
- test: [/micromessenger/i],
1165
- describe(r) {
1166
- const e = {
1167
- name: "WeChat"
1168
- }, t = i.getFirstMatch(/(?:micromessenger)[\s/](\d+(\.?_?\d+)+)/i, r) || i.getFirstMatch(l, r);
1169
- return t && (e.version = t), e;
1170
- }
1171
- },
1172
- {
1173
- test: [/qqbrowser/i],
1174
- describe(r) {
1175
- const e = {
1176
- name: /qqbrowserlite/i.test(r) ? "QQ Browser Lite" : "QQ Browser"
1177
- }, t = i.getFirstMatch(/(?:qqbrowserlite|qqbrowser)[/](\d+(\.?_?\d+)+)/i, r) || i.getFirstMatch(l, r);
1178
- return t && (e.version = t), e;
1179
- }
1180
- },
1181
- {
1182
- test: [/msie|trident/i],
1183
- describe(r) {
1184
- const e = {
1185
- name: "Internet Explorer"
1186
- }, t = i.getFirstMatch(/(?:msie |rv:)(\d+(\.?_?\d+)+)/i, r);
1187
- return t && (e.version = t), e;
1188
- }
1189
- },
1190
- {
1191
- test: [/\sedg\//i],
1192
- describe(r) {
1193
- const e = {
1194
- name: "Microsoft Edge"
1195
- }, t = i.getFirstMatch(/\sedg\/(\d+(\.?_?\d+)+)/i, r);
1196
- return t && (e.version = t), e;
1197
- }
1198
- },
1199
- {
1200
- test: [/edg([ea]|ios)/i],
1201
- describe(r) {
1202
- const e = {
1203
- name: "Microsoft Edge"
1204
- }, t = i.getSecondMatch(/edg([ea]|ios)\/(\d+(\.?_?\d+)+)/i, r);
1205
- return t && (e.version = t), e;
1206
- }
1207
- },
1208
- {
1209
- test: [/vivaldi/i],
1210
- describe(r) {
1211
- const e = {
1212
- name: "Vivaldi"
1213
- }, t = i.getFirstMatch(/vivaldi\/(\d+(\.?_?\d+)+)/i, r);
1214
- return t && (e.version = t), e;
1215
- }
1216
- },
1217
- {
1218
- test: [/seamonkey/i],
1219
- describe(r) {
1220
- const e = {
1221
- name: "SeaMonkey"
1222
- }, t = i.getFirstMatch(/seamonkey\/(\d+(\.?_?\d+)+)/i, r);
1223
- return t && (e.version = t), e;
1224
- }
1225
- },
1226
- {
1227
- test: [/sailfish/i],
1228
- describe(r) {
1229
- const e = {
1230
- name: "Sailfish"
1231
- }, t = i.getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i, r);
1232
- return t && (e.version = t), e;
1233
- }
1234
- },
1235
- {
1236
- test: [/silk/i],
1237
- describe(r) {
1238
- const e = {
1239
- name: "Amazon Silk"
1240
- }, t = i.getFirstMatch(/silk\/(\d+(\.?_?\d+)+)/i, r);
1241
- return t && (e.version = t), e;
1242
- }
1243
- },
1244
- {
1245
- test: [/phantom/i],
1246
- describe(r) {
1247
- const e = {
1248
- name: "PhantomJS"
1249
- }, t = i.getFirstMatch(/phantomjs\/(\d+(\.?_?\d+)+)/i, r);
1250
- return t && (e.version = t), e;
1251
- }
1252
- },
1253
- {
1254
- test: [/slimerjs/i],
1255
- describe(r) {
1256
- const e = {
1257
- name: "SlimerJS"
1258
- }, t = i.getFirstMatch(/slimerjs\/(\d+(\.?_?\d+)+)/i, r);
1259
- return t && (e.version = t), e;
1260
- }
1261
- },
1262
- {
1263
- test: [/blackberry|\bbb\d+/i, /rim\stablet/i],
1264
- describe(r) {
1265
- const e = {
1266
- name: "BlackBerry"
1267
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/blackberry[\d]+\/(\d+(\.?_?\d+)+)/i, r);
1268
- return t && (e.version = t), e;
1269
- }
1270
- },
1271
- {
1272
- test: [/(web|hpw)[o0]s/i],
1273
- describe(r) {
1274
- const e = {
1275
- name: "WebOS Browser"
1276
- }, t = i.getFirstMatch(l, r) || i.getFirstMatch(/w(?:eb)?[o0]sbrowser\/(\d+(\.?_?\d+)+)/i, r);
1277
- return t && (e.version = t), e;
1278
- }
1279
- },
1280
- {
1281
- test: [/bada/i],
1282
- describe(r) {
1283
- const e = {
1284
- name: "Bada"
1285
- }, t = i.getFirstMatch(/dolfin\/(\d+(\.?_?\d+)+)/i, r);
1286
- return t && (e.version = t), e;
1287
- }
1288
- },
1289
- {
1290
- test: [/tizen/i],
1291
- describe(r) {
1292
- const e = {
1293
- name: "Tizen"
1294
- }, t = i.getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.?_?\d+)+)/i, r) || i.getFirstMatch(l, r);
1295
- return t && (e.version = t), e;
1296
- }
1297
- },
1298
- {
1299
- test: [/qupzilla/i],
1300
- describe(r) {
1301
- const e = {
1302
- name: "QupZilla"
1303
- }, t = i.getFirstMatch(/(?:qupzilla)[\s/](\d+(\.?_?\d+)+)/i, r) || i.getFirstMatch(l, r);
1304
- return t && (e.version = t), e;
1305
- }
1306
- },
1307
- {
1308
- test: [/firefox|iceweasel|fxios/i],
1309
- describe(r) {
1310
- const e = {
1311
- name: "Firefox"
1312
- }, t = i.getFirstMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i, r);
1313
- return t && (e.version = t), e;
1314
- }
1315
- },
1316
- {
1317
- test: [/electron/i],
1318
- describe(r) {
1319
- const e = {
1320
- name: "Electron"
1321
- }, t = i.getFirstMatch(/(?:electron)\/(\d+(\.?_?\d+)+)/i, r);
1322
- return t && (e.version = t), e;
1323
- }
1324
- },
1325
- {
1326
- test: [/MiuiBrowser/i],
1327
- describe(r) {
1328
- const e = {
1329
- name: "Miui"
1330
- }, t = i.getFirstMatch(/(?:MiuiBrowser)[\s/](\d+(\.?_?\d+)+)/i, r);
1331
- return t && (e.version = t), e;
1332
- }
1333
- },
1334
- {
1335
- test: [/chromium/i],
1336
- describe(r) {
1337
- const e = {
1338
- name: "Chromium"
1339
- }, t = i.getFirstMatch(/(?:chromium)[\s/](\d+(\.?_?\d+)+)/i, r) || i.getFirstMatch(l, r);
1340
- return t && (e.version = t), e;
1341
- }
1342
- },
1343
- {
1344
- test: [/chrome|crios|crmo/i],
1345
- describe(r) {
1346
- const e = {
1347
- name: "Chrome"
1348
- }, t = i.getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i, r);
1349
- return t && (e.version = t), e;
1350
- }
1351
- },
1352
- {
1353
- test: [/GSA/i],
1354
- describe(r) {
1355
- const e = {
1356
- name: "Google Search"
1357
- }, t = i.getFirstMatch(/(?:GSA)\/(\d+(\.?_?\d+)+)/i, r);
1358
- return t && (e.version = t), e;
1359
- }
1360
- },
1361
- /* Android Browser */
1362
- {
1363
- test(r) {
1364
- const e = !r.test(/like android/i), t = r.test(/android/i);
1365
- return e && t;
1366
- },
1367
- describe(r) {
1368
- const e = {
1369
- name: "Android Browser"
1370
- }, t = i.getFirstMatch(l, r);
1371
- return t && (e.version = t), e;
1372
- }
1373
- },
1374
- /* PlayStation 4 */
1375
- {
1376
- test: [/playstation 4/i],
1377
- describe(r) {
1378
- const e = {
1379
- name: "PlayStation 4"
1380
- }, t = i.getFirstMatch(l, r);
1381
- return t && (e.version = t), e;
1382
- }
1383
- },
1384
- /* Safari */
1385
- {
1386
- test: [/safari|applewebkit/i],
1387
- describe(r) {
1388
- const e = {
1389
- name: "Safari"
1390
- }, t = i.getFirstMatch(l, r);
1391
- return t && (e.version = t), e;
1392
- }
1393
- },
1394
- /* Something else */
1395
- {
1396
- test: [/.*/i],
1397
- describe(r) {
1398
- const e = /^(.*)\/(.*) /, t = /^(.*)\/(.*)[ \t]\((.*)/, s = r.search("\\(") !== -1 ? t : e;
1399
- return {
1400
- name: i.getFirstMatch(s, r),
1401
- version: i.getSecondMatch(s, r)
1402
- };
1403
- }
1404
- }
1405
- ], je = [
1406
- /* Roku */
1407
- {
1408
- test: [/Roku\/DVP/],
1409
- describe(r) {
1410
- const e = i.getFirstMatch(/Roku\/DVP-(\d+\.\d+)/i, r);
1411
- return {
1412
- name: g.Roku,
1413
- version: e
1414
- };
1415
- }
1416
- },
1417
- /* Windows Phone */
1418
- {
1419
- test: [/windows phone/i],
1420
- describe(r) {
1421
- const e = i.getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i, r);
1422
- return {
1423
- name: g.WindowsPhone,
1424
- version: e
1425
- };
1426
- }
1427
- },
1428
- /* Windows */
1429
- {
1430
- test: [/windows /i],
1431
- describe(r) {
1432
- const e = i.getFirstMatch(/Windows ((NT|XP)( \d\d?.\d)?)/i, r), t = i.getWindowsVersionName(e);
1433
- return {
1434
- name: g.Windows,
1435
- version: e,
1436
- versionName: t
1437
- };
1438
- }
1439
- },
1440
- /* Firefox on iPad */
1441
- {
1442
- test: [/Macintosh(.*?) FxiOS(.*?)\//],
1443
- describe(r) {
1444
- const e = {
1445
- name: g.iOS
1446
- }, t = i.getSecondMatch(/(Version\/)(\d[\d.]+)/, r);
1447
- return t && (e.version = t), e;
1448
- }
1449
- },
1450
- /* macOS */
1451
- {
1452
- test: [/macintosh/i],
1453
- describe(r) {
1454
- const e = i.getFirstMatch(/mac os x (\d+(\.?_?\d+)+)/i, r).replace(/[_\s]/g, "."), t = i.getMacOSVersionName(e), s = {
1455
- name: g.MacOS,
1456
- version: e
1457
- };
1458
- return t && (s.versionName = t), s;
1459
- }
1460
- },
1461
- /* iOS */
1462
- {
1463
- test: [/(ipod|iphone|ipad)/i],
1464
- describe(r) {
1465
- const e = i.getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i, r).replace(/[_\s]/g, ".");
1466
- return {
1467
- name: g.iOS,
1468
- version: e
1469
- };
1470
- }
1471
- },
1472
- /* Android */
1473
- {
1474
- test(r) {
1475
- const e = !r.test(/like android/i), t = r.test(/android/i);
1476
- return e && t;
1477
- },
1478
- describe(r) {
1479
- const e = i.getFirstMatch(/android[\s/-](\d+(\.\d+)*)/i, r), t = i.getAndroidVersionName(e), s = {
1480
- name: g.Android,
1481
- version: e
1482
- };
1483
- return t && (s.versionName = t), s;
1484
- }
1485
- },
1486
- /* WebOS */
1487
- {
1488
- test: [/(web|hpw)[o0]s/i],
1489
- describe(r) {
1490
- const e = i.getFirstMatch(/(?:web|hpw)[o0]s\/(\d+(\.\d+)*)/i, r), t = {
1491
- name: g.WebOS
1492
- };
1493
- return e && e.length && (t.version = e), t;
1494
- }
1495
- },
1496
- /* BlackBerry */
1497
- {
1498
- test: [/blackberry|\bbb\d+/i, /rim\stablet/i],
1499
- describe(r) {
1500
- const e = i.getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i, r) || i.getFirstMatch(/blackberry\d+\/(\d+([_\s]\d+)*)/i, r) || i.getFirstMatch(/\bbb(\d+)/i, r);
1501
- return {
1502
- name: g.BlackBerry,
1503
- version: e
1504
- };
1505
- }
1506
- },
1507
- /* Bada */
1508
- {
1509
- test: [/bada/i],
1510
- describe(r) {
1511
- const e = i.getFirstMatch(/bada\/(\d+(\.\d+)*)/i, r);
1512
- return {
1513
- name: g.Bada,
1514
- version: e
1515
- };
1516
- }
1517
- },
1518
- /* Tizen */
1519
- {
1520
- test: [/tizen/i],
1521
- describe(r) {
1522
- const e = i.getFirstMatch(/tizen[/\s](\d+(\.\d+)*)/i, r);
1523
- return {
1524
- name: g.Tizen,
1525
- version: e
1526
- };
1527
- }
1528
- },
1529
- /* Linux */
1530
- {
1531
- test: [/linux/i],
1532
- describe() {
1533
- return {
1534
- name: g.Linux
1535
- };
1536
- }
1537
- },
1538
- /* Chrome OS */
1539
- {
1540
- test: [/CrOS/],
1541
- describe() {
1542
- return {
1543
- name: g.ChromeOS
1544
- };
1545
- }
1546
- },
1547
- /* Playstation 4 */
1548
- {
1549
- test: [/PlayStation 4/],
1550
- describe(r) {
1551
- const e = i.getFirstMatch(/PlayStation 4[/\s](\d+(\.\d+)*)/i, r);
1552
- return {
1553
- name: g.PlayStation4,
1554
- version: e
1555
- };
1556
- }
1557
- }
1558
- ], Ke = [
1559
- /* Googlebot */
1560
- {
1561
- test: [/googlebot/i],
1562
- describe() {
1563
- return {
1564
- type: h.bot,
1565
- vendor: "Google"
1566
- };
1567
- }
1568
- },
1569
- /* Huawei */
1570
- {
1571
- test: [/huawei/i],
1572
- describe(r) {
1573
- const e = i.getFirstMatch(/(can-l01)/i, r) && "Nova", t = {
1574
- type: h.mobile,
1575
- vendor: "Huawei"
1576
- };
1577
- return e && (t.model = e), t;
1578
- }
1579
- },
1580
- /* Nexus Tablet */
1581
- {
1582
- test: [/nexus\s*(?:7|8|9|10).*/i],
1583
- describe() {
1584
- return {
1585
- type: h.tablet,
1586
- vendor: "Nexus"
1587
- };
1588
- }
1589
- },
1590
- /* iPad */
1591
- {
1592
- test: [/ipad/i],
1593
- describe() {
1594
- return {
1595
- type: h.tablet,
1596
- vendor: "Apple",
1597
- model: "iPad"
1598
- };
1599
- }
1600
- },
1601
- /* Firefox on iPad */
1602
- {
1603
- test: [/Macintosh(.*?) FxiOS(.*?)\//],
1604
- describe() {
1605
- return {
1606
- type: h.tablet,
1607
- vendor: "Apple",
1608
- model: "iPad"
1609
- };
1610
- }
1611
- },
1612
- /* Amazon Kindle Fire */
1613
- {
1614
- test: [/kftt build/i],
1615
- describe() {
1616
- return {
1617
- type: h.tablet,
1618
- vendor: "Amazon",
1619
- model: "Kindle Fire HD 7"
1620
- };
1621
- }
1622
- },
1623
- /* Another Amazon Tablet with Silk */
1624
- {
1625
- test: [/silk/i],
1626
- describe() {
1627
- return {
1628
- type: h.tablet,
1629
- vendor: "Amazon"
1630
- };
1631
- }
1632
- },
1633
- /* Tablet */
1634
- {
1635
- test: [/tablet(?! pc)/i],
1636
- describe() {
1637
- return {
1638
- type: h.tablet
1639
- };
1640
- }
1641
- },
1642
- /* iPod/iPhone */
1643
- {
1644
- test(r) {
1645
- const e = r.test(/ipod|iphone/i), t = r.test(/like (ipod|iphone)/i);
1646
- return e && !t;
1647
- },
1648
- describe(r) {
1649
- const e = i.getFirstMatch(/(ipod|iphone)/i, r);
1650
- return {
1651
- type: h.mobile,
1652
- vendor: "Apple",
1653
- model: e
1654
- };
1655
- }
1656
- },
1657
- /* Nexus Mobile */
1658
- {
1659
- test: [/nexus\s*[0-6].*/i, /galaxy nexus/i],
1660
- describe() {
1661
- return {
1662
- type: h.mobile,
1663
- vendor: "Nexus"
1664
- };
1665
- }
1666
- },
1667
- /* Nokia */
1668
- {
1669
- test: [/Nokia/i],
1670
- describe(r) {
1671
- const e = i.getFirstMatch(/Nokia\s+([0-9]+(\.[0-9]+)?)/i, r), t = {
1672
- type: h.mobile,
1673
- vendor: "Nokia"
1674
- };
1675
- return e && (t.model = e), t;
1676
- }
1677
- },
1678
- /* Mobile */
1679
- {
1680
- test: [/[^-]mobi/i],
1681
- describe() {
1682
- return {
1683
- type: h.mobile
1684
- };
1685
- }
1686
- },
1687
- /* BlackBerry */
1688
- {
1689
- test(r) {
1690
- return r.getBrowserName(!0) === "blackberry";
1691
- },
1692
- describe() {
1693
- return {
1694
- type: h.mobile,
1695
- vendor: "BlackBerry"
1696
- };
1697
- }
1698
- },
1699
- /* Bada */
1700
- {
1701
- test(r) {
1702
- return r.getBrowserName(!0) === "bada";
1703
- },
1704
- describe() {
1705
- return {
1706
- type: h.mobile
1707
- };
1708
- }
1709
- },
1710
- /* Windows Phone */
1711
- {
1712
- test(r) {
1713
- return r.getBrowserName() === "windows phone";
1714
- },
1715
- describe() {
1716
- return {
1717
- type: h.mobile,
1718
- vendor: "Microsoft"
1719
- };
1720
- }
1721
- },
1722
- /* Android Tablet */
1723
- {
1724
- test(r) {
1725
- const e = Number(String(r.getOSVersion()).split(".")[0]);
1726
- return r.getOSName(!0) === "android" && e >= 3;
1727
- },
1728
- describe() {
1729
- return {
1730
- type: h.tablet
1731
- };
1732
- }
1733
- },
1734
- /* Android Mobile */
1735
- {
1736
- test(r) {
1737
- return r.getOSName(!0) === "android";
1738
- },
1739
- describe() {
1740
- return {
1741
- type: h.mobile
1742
- };
1743
- }
1744
- },
1745
- /* desktop */
1746
- {
1747
- test(r) {
1748
- return r.getOSName(!0) === "macos";
1749
- },
1750
- describe() {
1751
- return {
1752
- type: h.desktop,
1753
- vendor: "Apple"
1754
- };
1755
- }
1756
- },
1757
- /* Windows */
1758
- {
1759
- test(r) {
1760
- return r.getOSName(!0) === "windows";
1761
- },
1762
- describe() {
1763
- return {
1764
- type: h.desktop
1765
- };
1766
- }
1767
- },
1768
- /* Linux */
1769
- {
1770
- test(r) {
1771
- return r.getOSName(!0) === "linux";
1772
- },
1773
- describe() {
1774
- return {
1775
- type: h.desktop
1776
- };
1777
- }
1778
- },
1779
- /* PlayStation 4 */
1780
- {
1781
- test(r) {
1782
- return r.getOSName(!0) === "playstation 4";
1783
- },
1784
- describe() {
1785
- return {
1786
- type: h.tv
1787
- };
1788
- }
1789
- },
1790
- /* Roku */
1791
- {
1792
- test(r) {
1793
- return r.getOSName(!0) === "roku";
1794
- },
1795
- describe() {
1796
- return {
1797
- type: h.tv
1798
- };
1799
- }
1800
- }
1801
- ], Ye = [
1802
- /* EdgeHTML */
1803
- {
1804
- test(r) {
1805
- return r.getBrowserName(!0) === "microsoft edge";
1806
- },
1807
- describe(r) {
1808
- if (/\sedg\//i.test(r))
1809
- return {
1810
- name: S.Blink
1811
- };
1812
- const e = i.getFirstMatch(/edge\/(\d+(\.?_?\d+)+)/i, r);
1813
- return {
1814
- name: S.EdgeHTML,
1815
- version: e
1816
- };
1817
- }
1818
- },
1819
- /* Trident */
1820
- {
1821
- test: [/trident/i],
1822
- describe(r) {
1823
- const e = {
1824
- name: S.Trident
1825
- }, t = i.getFirstMatch(/trident\/(\d+(\.?_?\d+)+)/i, r);
1826
- return t && (e.version = t), e;
1827
- }
1828
- },
1829
- /* Presto */
1830
- {
1831
- test(r) {
1832
- return r.test(/presto/i);
1833
- },
1834
- describe(r) {
1835
- const e = {
1836
- name: S.Presto
1837
- }, t = i.getFirstMatch(/presto\/(\d+(\.?_?\d+)+)/i, r);
1838
- return t && (e.version = t), e;
1839
- }
1840
- },
1841
- /* Gecko */
1842
- {
1843
- test(r) {
1844
- const e = r.test(/gecko/i), t = r.test(/like gecko/i);
1845
- return e && !t;
1846
- },
1847
- describe(r) {
1848
- const e = {
1849
- name: S.Gecko
1850
- }, t = i.getFirstMatch(/gecko\/(\d+(\.?_?\d+)+)/i, r);
1851
- return t && (e.version = t), e;
1852
- }
1853
- },
1854
- /* Blink */
1855
- {
1856
- test: [/(apple)?webkit\/537\.36/i],
1857
- describe() {
1858
- return {
1859
- name: S.Blink
1860
- };
1861
- }
1862
- },
1863
- /* WebKit */
1864
- {
1865
- test: [/(apple)?webkit/i],
1866
- describe(r) {
1867
- const e = {
1868
- name: S.WebKit
1869
- }, t = i.getFirstMatch(/webkit\/(\d+(\.?_?\d+)+)/i, r);
1870
- return t && (e.version = t), e;
1871
- }
1872
- }
1873
- ];
1874
- class W {
1875
- /**
1876
- * Create instance of Parser
1877
- *
1878
- * @param {String} UA User-Agent string
1879
- * @param {Boolean} [skipParsing=false] parser can skip parsing in purpose of performance
1880
- * improvements if you need to make a more particular parsing
1881
- * like {@link Parser#parseBrowser} or {@link Parser#parsePlatform}
1882
- *
1883
- * @throw {Error} in case of empty UA String
1884
- *
1885
- * @constructor
1886
- */
1887
- constructor(e, t = !1) {
1888
- if (e == null || e === "")
1889
- throw new Error("UserAgent parameter can't be empty");
1890
- this._ua = e, this.parsedResult = {}, t !== !0 && this.parse();
1891
- }
1892
- /**
1893
- * Get UserAgent string of current Parser instance
1894
- * @return {String} User-Agent String of the current <Parser> object
1895
- *
1896
- * @public
1897
- */
1898
- getUA() {
1899
- return this._ua;
1900
- }
1901
- /**
1902
- * Test a UA string for a regexp
1903
- * @param {RegExp} regex
1904
- * @return {Boolean}
1905
- */
1906
- test(e) {
1907
- return e.test(this._ua);
1908
- }
1909
- /**
1910
- * Get parsed browser object
1911
- * @return {Object}
1912
- */
1913
- parseBrowser() {
1914
- this.parsedResult.browser = {};
1915
- const e = i.find(qe, (t) => {
1916
- if (typeof t.test == "function")
1917
- return t.test(this);
1918
- if (Array.isArray(t.test))
1919
- return t.test.some((s) => this.test(s));
1920
- throw new Error("Browser's test function is not valid");
1921
- });
1922
- return e && (this.parsedResult.browser = e.describe(this.getUA())), this.parsedResult.browser;
1923
- }
1924
- /**
1925
- * Get parsed browser object
1926
- * @return {Object}
1927
- *
1928
- * @public
1929
- */
1930
- getBrowser() {
1931
- return this.parsedResult.browser ? this.parsedResult.browser : this.parseBrowser();
1932
- }
1933
- /**
1934
- * Get browser's name
1935
- * @return {String} Browser's name or an empty string
1936
- *
1937
- * @public
1938
- */
1939
- getBrowserName(e) {
1940
- return e ? String(this.getBrowser().name).toLowerCase() || "" : this.getBrowser().name || "";
1941
- }
1942
- /**
1943
- * Get browser's version
1944
- * @return {String} version of browser
1945
- *
1946
- * @public
1947
- */
1948
- getBrowserVersion() {
1949
- return this.getBrowser().version;
1950
- }
1951
- /**
1952
- * Get OS
1953
- * @return {Object}
1954
- *
1955
- * @example
1956
- * this.getOS();
1957
- * {
1958
- * name: 'macOS',
1959
- * version: '10.11.12'
1960
- * }
1961
- */
1962
- getOS() {
1963
- return this.parsedResult.os ? this.parsedResult.os : this.parseOS();
1964
- }
1965
- /**
1966
- * Parse OS and save it to this.parsedResult.os
1967
- * @return {*|{}}
1968
- */
1969
- parseOS() {
1970
- this.parsedResult.os = {};
1971
- const e = i.find(je, (t) => {
1972
- if (typeof t.test == "function")
1973
- return t.test(this);
1974
- if (Array.isArray(t.test))
1975
- return t.test.some((s) => this.test(s));
1976
- throw new Error("Browser's test function is not valid");
1977
- });
1978
- return e && (this.parsedResult.os = e.describe(this.getUA())), this.parsedResult.os;
1979
- }
1980
- /**
1981
- * Get OS name
1982
- * @param {Boolean} [toLowerCase] return lower-cased value
1983
- * @return {String} name of the OS — macOS, Windows, Linux, etc.
1984
- */
1985
- getOSName(e) {
1986
- const { name: t } = this.getOS();
1987
- return e ? String(t).toLowerCase() || "" : t || "";
1988
- }
1989
- /**
1990
- * Get OS version
1991
- * @return {String} full version with dots ('10.11.12', '5.6', etc)
1992
- */
1993
- getOSVersion() {
1994
- return this.getOS().version;
1995
- }
1996
- /**
1997
- * Get parsed platform
1998
- * @return {{}}
1999
- */
2000
- getPlatform() {
2001
- return this.parsedResult.platform ? this.parsedResult.platform : this.parsePlatform();
2002
- }
2003
- /**
2004
- * Get platform name
2005
- * @param {Boolean} [toLowerCase=false]
2006
- * @return {*}
2007
- */
2008
- getPlatformType(e = !1) {
2009
- const { type: t } = this.getPlatform();
2010
- return e ? String(t).toLowerCase() || "" : t || "";
2011
- }
2012
- /**
2013
- * Get parsed platform
2014
- * @return {{}}
2015
- */
2016
- parsePlatform() {
2017
- this.parsedResult.platform = {};
2018
- const e = i.find(Ke, (t) => {
2019
- if (typeof t.test == "function")
2020
- return t.test(this);
2021
- if (Array.isArray(t.test))
2022
- return t.test.some((s) => this.test(s));
2023
- throw new Error("Browser's test function is not valid");
2024
- });
2025
- return e && (this.parsedResult.platform = e.describe(this.getUA())), this.parsedResult.platform;
2026
- }
2027
- /**
2028
- * Get parsed engine
2029
- * @return {{}}
2030
- */
2031
- getEngine() {
2032
- return this.parsedResult.engine ? this.parsedResult.engine : this.parseEngine();
2033
- }
2034
- /**
2035
- * Get engines's name
2036
- * @return {String} Engines's name or an empty string
2037
- *
2038
- * @public
2039
- */
2040
- getEngineName(e) {
2041
- return e ? String(this.getEngine().name).toLowerCase() || "" : this.getEngine().name || "";
2042
- }
2043
- /**
2044
- * Get parsed platform
2045
- * @return {{}}
2046
- */
2047
- parseEngine() {
2048
- this.parsedResult.engine = {};
2049
- const e = i.find(Ye, (t) => {
2050
- if (typeof t.test == "function")
2051
- return t.test(this);
2052
- if (Array.isArray(t.test))
2053
- return t.test.some((s) => this.test(s));
2054
- throw new Error("Browser's test function is not valid");
2055
- });
2056
- return e && (this.parsedResult.engine = e.describe(this.getUA())), this.parsedResult.engine;
2057
- }
2058
- /**
2059
- * Parse full information about the browser
2060
- * @returns {Parser}
2061
- */
2062
- parse() {
2063
- return this.parseBrowser(), this.parseOS(), this.parsePlatform(), this.parseEngine(), this;
2064
- }
2065
- /**
2066
- * Get parsed result
2067
- * @return {ParsedResult}
2068
- */
2069
- getResult() {
2070
- return i.assign({}, this.parsedResult);
2071
- }
2072
- /**
2073
- * Check if parsed browser matches certain conditions
2074
- *
2075
- * @param {Object} checkTree It's one or two layered object,
2076
- * which can include a platform or an OS on the first layer
2077
- * and should have browsers specs on the bottom-laying layer
2078
- *
2079
- * @returns {Boolean|undefined} Whether the browser satisfies the set conditions or not.
2080
- * Returns `undefined` when the browser is no described in the checkTree object.
2081
- *
2082
- * @example
2083
- * const browser = Bowser.getParser(window.navigator.userAgent);
2084
- * if (browser.satisfies({chrome: '>118.01.1322' }))
2085
- * // or with os
2086
- * if (browser.satisfies({windows: { chrome: '>118.01.1322' } }))
2087
- * // or with platforms
2088
- * if (browser.satisfies({desktop: { chrome: '>118.01.1322' } }))
2089
- */
2090
- satisfies(e) {
2091
- const t = {};
2092
- let s = 0;
2093
- const n = {};
2094
- let o = 0;
2095
- if (Object.keys(e).forEach((a) => {
2096
- const c = e[a];
2097
- typeof c == "string" ? (n[a] = c, o += 1) : typeof c == "object" && (t[a] = c, s += 1);
2098
- }), s > 0) {
2099
- const a = Object.keys(t), c = i.find(a, (d) => this.isOS(d));
2100
- if (c) {
2101
- const d = this.satisfies(t[c]);
2102
- if (d !== void 0)
2103
- return d;
2104
- }
2105
- const u = i.find(
2106
- a,
2107
- (d) => this.isPlatform(d)
2108
- );
2109
- if (u) {
2110
- const d = this.satisfies(t[u]);
2111
- if (d !== void 0)
2112
- return d;
2113
- }
2114
- }
2115
- if (o > 0) {
2116
- const a = Object.keys(n), c = i.find(a, (u) => this.isBrowser(u, !0));
2117
- if (c !== void 0)
2118
- return this.compareVersion(n[c]);
2119
- }
2120
- }
2121
- /**
2122
- * Check if the browser name equals the passed string
2123
- * @param {string} browserName The string to compare with the browser name
2124
- * @param [includingAlias=false] The flag showing whether alias will be included into comparison
2125
- * @returns {boolean}
2126
- */
2127
- isBrowser(e, t = !1) {
2128
- const s = this.getBrowserName().toLowerCase();
2129
- let n = e.toLowerCase();
2130
- const o = i.getBrowserTypeByAlias(n);
2131
- return t && o && (n = o.toLowerCase()), n === s;
2132
- }
2133
- compareVersion(e) {
2134
- let t = [0], s = e, n = !1;
2135
- const o = this.getBrowserVersion();
2136
- if (typeof o == "string")
2137
- return e[0] === ">" || e[0] === "<" ? (s = e.substr(1), e[1] === "=" ? (n = !0, s = e.substr(2)) : t = [], e[0] === ">" ? t.push(1) : t.push(-1)) : e[0] === "=" ? s = e.substr(1) : e[0] === "~" && (n = !0, s = e.substr(1)), t.indexOf(
2138
- i.compareVersions(o, s, n)
2139
- ) > -1;
2140
- }
2141
- /**
2142
- * Check if the OS name equals the passed string
2143
- * @param {string} osName The string to compare with the OS name
2144
- * @returns {boolean}
2145
- */
2146
- isOS(e) {
2147
- return this.getOSName(!0) === String(e).toLowerCase();
2148
- }
2149
- /**
2150
- * Check if the platform type equals the passed string
2151
- * @param {string} platformType The string to compare with the platform type
2152
- * @returns {boolean}
2153
- */
2154
- isPlatform(e) {
2155
- return this.getPlatformType(!0) === String(e).toLowerCase();
2156
- }
2157
- /**
2158
- * Check if the engine name equals the passed string
2159
- * @param {string} engineName The string to compare with the engine name
2160
- * @returns {boolean}
2161
- */
2162
- isEngine(e) {
2163
- return this.getEngineName(!0) === String(e).toLowerCase();
2164
- }
2165
- /**
2166
- * Is anything? Check if the browser is called "anything",
2167
- * the OS called "anything" or the platform called "anything"
2168
- * @param {String} anything
2169
- * @param [includingAlias=false] The flag showing whether alias will be included into comparison
2170
- * @returns {Boolean}
2171
- */
2172
- is(e, t = !1) {
2173
- return this.isBrowser(e, t) || this.isOS(e) || this.isPlatform(e);
2174
- }
2175
- /**
2176
- * Check if any of the given values satisfies this.is(anything)
2177
- * @param {String[]} anythings
2178
- * @returns {Boolean}
2179
- */
2180
- some(e = []) {
2181
- return e.some((t) => this.is(t));
2182
- }
2183
- }
2184
- /*!
2185
- * Bowser - a browser detector
2186
- * https://github.com/lancedikson/bowser
2187
- * MIT License | (c) Dustin Diaz 2012-2015
2188
- * MIT License | (c) Denis Demchenko 2015-2019
2189
- */
2190
- class Je {
2191
- /**
2192
- * Creates a {@link Parser} instance
2193
- *
2194
- * @param {String} UA UserAgent string
2195
- * @param {Boolean} [skipParsing=false] Will make the Parser postpone parsing until you ask it
2196
- * explicitly. Same as `skipParsing` for {@link Parser}.
2197
- * @returns {Parser}
2198
- * @throws {Error} when UA is not a String
2199
- *
2200
- * @example
2201
- * const parser = Bowser.getParser(window.navigator.userAgent);
2202
- * const result = parser.getResult();
2203
- */
2204
- static getParser(e, t = !1) {
2205
- if (typeof e != "string")
2206
- throw new Error("UserAgent should be a string");
2207
- return new W(e, t);
2208
- }
2209
- /**
2210
- * Creates a {@link Parser} instance and runs {@link Parser.getResult} immediately
2211
- *
2212
- * @param UA
2213
- * @return {ParsedResult}
2214
- *
2215
- * @example
2216
- * const result = Bowser.parse(window.navigator.userAgent);
2217
- */
2218
- static parse(e) {
2219
- return new W(e).getResult();
2220
- }
2221
- static get BROWSER_MAP() {
2222
- return G;
2223
- }
2224
- static get ENGINE_MAP() {
2225
- return S;
2226
- }
2227
- static get OS_MAP() {
2228
- return g;
2229
- }
2230
- static get PLATFORMS_MAP() {
2231
- return h;
2232
- }
2233
- }
2234
- const I = Je.parse(navigator.userAgent), Xe = {
2235
- abTestGroup: null,
2236
- abTestName: null,
2237
- browser: I.browser.name ?? null,
2238
- browserVersion: I.browser.version ?? null,
2239
- hardwarePlatform: I.browser.name === "Electron" ? "DESKTOP" : "WEB",
2240
- isOfflineModeStart: !1,
2241
- mobileNetworkType: null,
2242
- networkType: "WIFI",
2243
- operatingSystem: I.os.name ?? null,
2244
- operatingSystemVersion: I.os.version ?? null,
2245
- screenHeight: window.screen.height,
2246
- screenWidth: window.screen.width,
2247
- sessionProductId: "",
2248
- sessionProductType: "TRACK",
2249
- sessionTags: [],
2250
- sessionType: "PLAYBACK",
2251
- startReason: "IMPLICIT",
2252
- streamingSessionId: "",
2253
- timestamp: 0
2254
- }, Ze = await T(
2255
- "streaming_session_start",
2256
- Xe
2257
- );
2258
- function et(r) {
2259
- return Ze(r);
2260
- }
2261
- async function tt(r) {
2262
- if (await P())
2263
- return r();
2264
- }
2265
- async function q(r) {
2266
- const e = {
2267
- consentCategory: "NECESSARY",
2268
- ..."extras" in r && { extras: r.extras },
2269
- group: r.group,
2270
- name: r.name,
2271
- payload: r.payload,
2272
- version: r.version
2273
- }, t = e.payload.streamingSessionId;
2274
- e.name === "progress" && "streamingSessionId" in e.payload && delete e.payload.streamingSessionId, D.eventSender.sendEvent(e), t && await R.delete({
2275
- name: e.name,
2276
- streamingSessionId: t
2277
- });
2278
- }
2279
- async function j(r) {
2280
- return tt(async () => {
2281
- for (const e of r)
2282
- if (e) {
2283
- const t = await e;
2284
- t && await q({
2285
- group: "streaming_metrics",
2286
- name: t.name,
2287
- payload: t.payload,
2288
- version: 2
2289
- });
2290
- }
2291
- });
2292
- }
2293
- function rt(r = !0) {
2294
- const e = r && "crypto" in window && "getRandomValues" in crypto;
2295
- return ("10000000-1000-4000-8000" + -1e11).replace(/[018]/g, (t) => {
2296
- const s = e ? crypto.getRandomValues(new Uint8Array(1))[0] : Math.floor(256 * Math.random());
2297
- return (t ^ (s ?? 0) & 15 >> t / 4).toString(16);
2298
- });
2299
- }
2300
- const L = {
2301
- BTS: "application/vnd.tidal.bts",
2302
- DASH: "application/dash+xml",
2303
- EMU: "application/vnd.tidal.emu",
2304
- HLS: "application/vnd.apple.mpegurl"
2305
- };
2306
- function st(r) {
2307
- return JSON.parse(atob(r));
2308
- }
2309
- function it(r, e) {
2310
- if ("codecs" in r)
2311
- switch (r.codecs) {
2312
- case "aac":
2313
- return "aac";
2314
- case "aac+":
2315
- return "aac+";
2316
- case "flac":
2317
- return "flac";
2318
- case "mp3":
2319
- return "mp3";
2320
- case "mp4a.40.2":
2321
- return "mp4a.40.2";
2322
- case "mp4a.40.5":
2323
- return "mp4a.40.5";
2324
- }
2325
- else if (e)
2326
- switch (e) {
2327
- case "HI_RES":
2328
- case "HI_RES_LOSSLESS":
2329
- case "LOSSLESS":
2330
- return "flac";
2331
- case "HIGH":
2332
- return "mp4a.40.2";
2333
- case "LOW":
2334
- return "mp4a.40.5";
2335
- }
2336
- return "none";
2337
- }
2338
- function nt(r) {
2339
- switch (r) {
2340
- case "aac":
2341
- case "aac+":
2342
- case "mp4a.40.2":
2343
- case "mp4a.40.5":
2344
- return "aac";
2345
- case "flac":
2346
- return r;
2347
- case "mp3":
2348
- return "mp3";
2349
- default:
2350
- return;
2351
- }
2352
- }
2353
- function at(r) {
2354
- const e = /codecs=(["'])?((?:.(?!\1|>))*.?)\1?/.exec(r);
2355
- if (e === null)
2356
- return;
2357
- const t = e[2] ?? "";
2358
- if (t.includes("mp4a") || t.includes("aac"))
2359
- return "aac";
2360
- if (t === "flac")
2361
- return t;
2362
- }
2363
- function ot(r) {
2364
- const e = /PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?/.exec(r);
2365
- if (!e)
2366
- throw new Error("Invalid duration format");
2367
- const t = parseFloat(e[1] || "0"), s = parseFloat(e[2] || "0"), n = parseFloat(e[3] || "0");
2368
- return t * 3600 + s * 60 + n;
2369
- }
2370
- function ct(r) {
2371
- const e = /mediaPresentationDuration="([^"]+)"/.exec(r);
2372
- if (e) {
2373
- const t = e[1];
2374
- if (t)
2375
- return ot(t);
2376
- }
2377
- }
2378
- function dt(r) {
2379
- const { prefetched: e, streamingSessionId: t } = r, s = "albumReplayGain" in r ? {
2380
- albumPeakAmplitude: r.albumPeakAmplitude,
2381
- albumReplayGain: r.albumReplayGain,
2382
- trackPeakAmplitude: r.trackPeakAmplitude,
2383
- trackReplayGain: r.trackReplayGain
2384
- } : {}, n = "audioQuality" in r ? r.audioQuality : r.videoQuality, o = {
2385
- id: String(
2386
- "videoId" in r ? r.videoId : r.trackId
2387
- ),
2388
- type: "trackId" in r ? "track" : "video"
2389
- };
2390
- if (r.manifestMimeType === L.BTS || r.manifestMimeType === L.EMU) {
2391
- const a = st(r.manifest), c = a.urls[0], u = it(
2392
- a,
2393
- "audioQuality" in r ? r.audioQuality : null
2394
- );
2395
- let d;
2396
- return "keyId" in a && (d = a.keyId), "licenseSecurityToken" in r && (d = r.licenseSecurityToken), {
2397
- ...s,
2398
- bitDepth: "bitDepth" in r ? r.bitDepth ?? void 0 : void 0,
2399
- codec: nt(u),
2400
- prefetched: e,
2401
- quality: n,
2402
- sampleRate: "sampleRate" in r ? r.sampleRate ?? void 0 : void 0,
2403
- securityToken: d,
2404
- streamFormat: u,
2405
- streamUrl: c,
2406
- streamingSessionId: t,
2407
- ...o,
2408
- expires: r.expires
2409
- };
2410
- }
2411
- if (r.manifestMimeType === L.DASH) {
2412
- const a = `data:${r.manifestMimeType};base64,${r.manifest}`, c = atob(r.manifest);
2413
- return {
2414
- ...s,
2415
- bitDepth: "bitDepth" in r ? r.bitDepth ?? void 0 : void 0,
2416
- codec: at(c),
2417
- duration: ct(c),
2418
- prefetched: e,
2419
- quality: n,
2420
- sampleRate: "sampleRate" in r ? r.sampleRate ?? void 0 : void 0,
2421
- securityToken: r.licenseSecurityToken,
2422
- streamUrl: a,
2423
- streamingSessionId: t,
2424
- ...o,
2425
- expires: r.expires
2426
- };
2427
- }
2428
- throw new TypeError(
2429
- `${r.manifestMimeType} not supported as playback info manifest mime type.`
2430
- );
2431
- }
2432
- const K = async (r, e = {}, t = 3) => {
2433
- let s, n;
2434
- try {
2435
- s = await fetch(r, e);
2436
- } catch (c) {
2437
- if (t === 0)
2438
- throw c;
2439
- n = null;
2440
- }
2441
- if (s?.ok)
2442
- return s;
2443
- const o = s && s.status >= 500 && s.status <= 599, a = n === null || o || s?.status === 429;
2444
- if (t > 0 && a) {
2445
- const c = 500 * Math.abs(4 - t);
2446
- return console.debug(
2447
- `Retrying request for ${Math.abs(
2448
- 4 - t
2449
- )}th time in ${c}ms`
2450
- ), await fe(c), K(r, e, t - 1);
2451
- }
2452
- if (!s)
2453
- throw new Error("Retries exchaused. Cannot fetch playbackinfo.");
2454
- return s;
2455
- };
2456
- function lt(r, e) {
2457
- switch (e) {
2458
- case 4010:
2459
- return "PEMonthlyStreamQuotaExceeded";
2460
- case 4032:
2461
- case 4035:
2462
- return "PEContentNotAvailableInLocation";
2463
- case 4033:
2464
- return "PEContentNotAvailableForSubscription";
2465
- }
2466
- return r >= 500 && r < 600 || r === 429 ? "PERetryable" : r >= 400 && r < 500 ? "PENotAllowed" : "EUnexpected";
2467
- }
2468
- async function ut(r) {
2469
- const {
2470
- accessToken: e,
2471
- audioQuality: t,
2472
- clientId: s,
2473
- mediaProduct: n,
2474
- prefetch: o,
2475
- streamingSessionId: a
2476
- } = r, c = _("apiUrl"), u = new URL(
2477
- `${c}/${n.productType}s/${n.productId}/playbackinfo`
2478
- ), d = u.searchParams;
2479
- n.productType === "video" ? d.set("videoquality", "HIGH") : d.set("audioquality", t), d.set("playbackmode", "STREAM"), d.set("assetpresentation", "FULL");
2480
- const b = new Headers();
2481
- o && b.set("x-tidal-prefetch", "true"), s && b.set("x-tidal-token", s), e && b.set("authorization", "Bearer " + e), a && b.set("x-tidal-streamingsessionid", a);
2482
- let M;
2483
- try {
2484
- M = await K(
2485
- u.toString(),
2486
- {
2487
- headers: b,
2488
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2489
- // @ts-ignore - It is a thing.
2490
- importance: "high"
2491
- },
2492
- 3
2493
- );
2494
- } catch {
2495
- throw new C("PENetwork", "NPBI0");
2496
- }
2497
- const f = await M.json();
2498
- if ("status" in f) {
2499
- const ae = `A${f.subStatus}`;
2500
- throw new C(lt(f.status, f.subStatus), ae);
2501
- }
2502
- const ie = "trackId" in f, ne = "videoId" in f;
2503
- if (!ie && !ne)
2504
- throw new C("EUnexpected", "B9999");
2505
- return {
2506
- ...f,
2507
- // eslint-disable-next-line no-restricted-syntax
2508
- expires: Date.now() + 36e5,
2509
- prefetched: o
2510
- };
2511
- }
2512
- function ht(r) {
2513
- const { mediaProduct: e, streamingSessionId: t } = r;
2514
- return {
2515
- assetPresentation: "FULL",
2516
- audioMode: "STEREO",
2517
- audioQuality: "LOW",
2518
- // eslint-disable-next-line no-restricted-syntax
2519
- expires: Date.now() + 36e5,
2520
- manifest: btoa(
2521
- JSON.stringify({
2522
- mimeType: L.HLS,
2523
- urls: [
2524
- `https://fsu.fa.tidal.com/storage/${e.productId}.m3u8`
2525
- ]
2526
- })
2527
- ),
2528
- manifestMimeType: L.EMU,
2529
- prefetched: !1,
2530
- streamType: "ON_DEMAND",
2531
- streamingSessionId: t,
2532
- trackId: e.productId
2533
- };
2534
- }
2535
- async function mt(r) {
2536
- const { streamingSessionId: e } = r, t = [];
2537
- performance.mark("streaming_metrics:playback_info_fetch:startTimestamp", {
2538
- detail: e,
2539
- startTime: y.now()
2540
- });
2541
- try {
2542
- let s;
2543
- if (r.mediaProduct.productType === "demo" ? s = ht(r) : s = await ut(r), s === void 0)
2544
- throw new Error("Playback info was fetched, but undefined.");
2545
- N({
2546
- endReason: "COMPLETE",
2547
- streamingSessionId: e
2548
- }).catch(console.error);
2549
- const n = "adInfo" in s;
2550
- return "trackId" in s ? z({
2551
- actualAssetPresentation: s.assetPresentation,
2552
- actualAudioMode: s.audioMode,
2553
- actualProductId: String(s.trackId),
2554
- actualQuality: s.audioQuality,
2555
- actualStreamType: void 0,
2556
- hasAds: n,
2557
- productType: "TRACK",
2558
- streamingSessionId: e
2559
- }).catch(console.error) : z({
2560
- actualAssetPresentation: s.assetPresentation,
2561
- actualAudioMode: void 0,
2562
- actualProductId: String(s.videoId),
2563
- actualQuality: s.videoQuality,
2564
- actualStreamType: s.streamType,
2565
- hasAds: n,
2566
- productType: "VIDEO",
2567
- streamingSessionId: e
2568
- }).catch(console.error), performance.mark("streaming_metrics:playback_info_fetch:endTimestamp", {
2569
- detail: e,
2570
- startTime: y.now()
2571
- }), s;
2572
- } catch (s) {
2573
- throw performance.mark("streaming_metrics:playback_info_fetch:endTimestamp", {
2574
- detail: e,
2575
- startTime: y.now()
2576
- }), N({
2577
- endReason: "ERROR",
2578
- errorCode: s.message,
2579
- errorMessage: s.stack,
2580
- streamingSessionId: e
2581
- }).catch(console.error), t.push(
2582
- Qe({
2583
- streamingSessionId: e,
2584
- timestamp: y.timestamp(
2585
- "streaming_metrics:playback_info_fetch:endTimestamp"
2586
- )
2587
- })
2588
- ), s;
2589
- } finally {
2590
- t.push(
2591
- N({
2592
- endTimestamp: y.timestamp(
2593
- "streaming_metrics:playback_info_fetch:endTimestamp"
2594
- ),
2595
- startTimestamp: y.timestamp(
2596
- "streaming_metrics:playback_info_fetch:startTimestamp"
2597
- ),
2598
- streamingSessionId: e
2599
- })
2600
- ), j(t).catch(console.error), performance.clearMarks(
2601
- "streaming_metrics:playback_info_fetch:endTimestamp"
2602
- ), performance.clearMarks(
2603
- "streaming_metrics:playback_info_fetch:startTimestamp"
2604
- );
2605
- }
2606
- }
2607
- class Y {
2608
- /**
2609
- * The current time position to restore playback from when connection is back online.
2610
- */
2611
- static #e = 0;
2612
- static #r = !1;
2613
- /**
2614
- * The media product to restore when connection is back online.
2615
- */
2616
- static #s = null;
2617
- static #t;
2618
- static #i;
2619
- static #n;
2620
- static #a() {
2621
- const { activePlayer: e } = p;
2622
- e?.hasStarted() && (this.#s = e.currentMediaProduct, this.#n = this.#d.bind(this), m.addEventListener(
2623
- "playback-state-change",
2624
- this.#n
2625
- ));
2626
- }
2627
- static #o() {
2628
- const { activePlayer: e } = p;
2629
- e?.hasStarted() && (e.playbackState !== "PLAYING" && this.#s && (m.dispatchEvent(
2630
- new CustomEvent("load", {
2631
- detail: {
2632
- currentTime: this.#e,
2633
- mediaProduct: this.#s
2634
- }
2635
- })
2636
- ), this.#c()), m.removeEventListener(
2637
- "playback-state-change",
2638
- this.#n
2639
- ));
2640
- }
2641
- static #c() {
2642
- this.#s = null, this.#e = 0;
2643
- }
2644
- static #d() {
2645
- const { activePlayer: e } = p;
2646
- e && (this.#e = e.currentTime);
2647
- }
2648
- static disable() {
2649
- this.#r && (this.#t && window.removeEventListener("offline", this.#t, !1), this.#i && window.removeEventListener("online", this.#i, !1), this.#i = void 0, this.#t = void 0, this.#r = !1);
2650
- }
2651
- static enable() {
2652
- this.#r || (this.#i = () => this.#o(), this.#t = () => this.#a(), window.addEventListener("offline", this.#t, !1), window.addEventListener("online", this.#i, !1), this.#r = !0);
2653
- }
2654
- }
2655
- const pt = "streaming-privileges-revoked";
2656
- function ft(r) {
2657
- return new CustomEvent(pt, {
2658
- detail: r
2659
- });
2660
- }
2661
- let k;
2662
- async function J(r) {
2663
- const e = _("apiUrl"), t = await fetch(e + "/rt/connect", {
2664
- headers: new Headers({
2665
- Authorization: "Bearer " + r,
2666
- "Content-Type": "application/json"
2667
- }),
2668
- method: "POST"
2669
- }), { url: s } = await t.json();
2670
- return s;
2671
- }
2672
- function X(r) {
2673
- return new Promise((e) => {
2674
- r.addEventListener("open", () => e(), { once: !0 });
2675
- });
2676
- }
2677
- class F {
2678
- #e;
2679
- #r;
2680
- #s;
2681
- #t;
2682
- constructor() {
2683
- this.#t = void 0, this.#r = this.#i(), m.addEventListener("user-action", () => {
2684
- this.connected && this.userAction().then().catch(console.error);
2685
- });
2686
- }
2687
- /**
2688
- * Call this method to ensure pushkin is running.
2689
- */
2690
- static async ensure() {
2691
- await P() && (k ? k.connected || await k.reconnect() : k = new F());
2692
- }
2693
- /**
2694
- * Call this method when credentials changes to re-setup pushkin with the new credentials
2695
- */
2696
- static async refresh() {
2697
- if (!await P())
2698
- return;
2699
- const e = await V();
2700
- k && e && k.reconnect().catch(console.error);
2701
- }
2702
- async #i() {
2703
- const e = await V();
2704
- if (!e)
2705
- throw new Error("No access token to connect to Pushkin.");
2706
- const t = await J(e);
2707
- t && (this.#t = new WebSocket(t), await X(this.#t), this.#s = (s) => this.#o(s.data), this.#e = () => this.#a(), this.#t.addEventListener("message", this.#s, !1), this.#t.addEventListener("closed", this.#e, !1), window.addEventListener("online", () => this.#a(), {
2708
- once: !0
2709
- }));
2710
- }
2711
- async #n(e) {
2712
- if (!this.#t)
2713
- throw new Error(
2714
- "No socket connected. Did you forget to call connect method in Pushkin service first?"
2715
- );
2716
- this.#t.readyState !== WebSocket.OPEN && await this.#r, this.#t.send(JSON.stringify(e));
2717
- }
2718
- #a() {
2719
- this.#r = this.#i();
2720
- }
2721
- #o(e) {
2722
- const t = JSON.parse(e);
2723
- switch (t.type) {
2724
- case "PRIVILEGED_SESSION_NOTIFICATION": {
2725
- m.dispatchEvent(
2726
- ft(
2727
- String(t.payload.clientDisplayName)
2728
- )
2729
- ), p.activePlayer?.pause();
2730
- break;
2731
- }
2732
- case "RECONNECT":
2733
- this.reconnect().catch(console.error);
2734
- break;
2735
- default:
2736
- console.warn("Unhandled event from Pushkin: ", t);
2737
- break;
2738
- }
2739
- }
2740
- reconnect() {
2741
- return this.#t ? (this.#s && this.#t.removeEventListener("message", this.#s), this.#e && this.#t.removeEventListener("closed", this.#e), this.#t.close(), this.#r = this.#i(), this.#r) : Promise.resolve();
2742
- }
2743
- /**
2744
- * Call this method to tell Pushkin a user action happened, so it can
2745
- * make good qualified guesses if you're the session with allowed playback-
2746
- */
2747
- async userAction() {
2748
- this.connected || await this.reconnect();
2749
- try {
2750
- await this.#n({
2751
- payload: {
2752
- startedAt: y.now()
2753
- },
2754
- type: "USER_ACTION"
2755
- });
2756
- } catch (e) {
2757
- console.error(e);
2758
- }
2759
- }
2760
- get connected() {
2761
- return this.#t && this.#t.readyState === WebSocket.OPEN;
2762
- }
2763
- }
2764
- const gt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2765
- __proto__: null,
2766
- Pushkin: F,
2767
- fetchWebSocketURL: J,
2768
- socketOpen: X
2769
- }, Symbol.toStringTag, { value: "Module" }));
2770
- async function yt() {
2771
- Le(), Y.disable(), await Te();
2772
- }
2773
- function Ut(r, e) {
2774
- return r === "FULL" && e.sourceType !== "PRIVATE_LINK_SHARING";
2775
- }
2776
- const wt = {
2777
- actions: [],
2778
- actualAssetPresentation: "PREVIEW",
2779
- actualAudioMode: "STEREO",
2780
- actualProductId: "",
2781
- actualQuality: "LOW",
2782
- endAssetPosition: -1,
2783
- endTimestamp: -1,
2784
- isPostPaywall: !1,
2785
- playbackSessionId: "",
2786
- productType: "TRACK",
2787
- requestedProductId: "",
2788
- sourceId: "",
2789
- sourceType: "",
2790
- startAssetPosition: -1,
2791
- startTimestamp: -1
2792
- }, Z = await T(
2793
- "playback_session",
2794
- wt
2795
- );
2796
- async function Vt(r) {
2797
- const e = await Z(r);
2798
- if (!e) {
2799
- console.error("reducedData is undefined");
2800
- return;
2801
- }
2802
- const { name: t, streamingSessionId: s } = e, { extras: n, ...o } = e.payload;
2803
- return {
2804
- extras: n,
2805
- name: t,
2806
- payload: o,
2807
- streamingSessionId: s
2808
- };
2809
- }
2810
- function zt(r, e) {
2811
- return Z({
2812
- actions: [e],
2813
- streamingSessionId: r
2814
- });
2815
- }
2816
- function Wt(r) {
2817
- switch (r) {
2818
- case "demo":
2819
- return "UC";
2820
- case "video":
2821
- return "VIDEO";
2822
- case "track":
2823
- default:
2824
- return "TRACK";
2825
- }
2826
- }
2827
- async function $t(r) {
2828
- const e = await P();
2829
- for (const t of r)
2830
- if (t) {
2831
- const s = await t;
2832
- s && await q({
2833
- ..."extras" in s && { extras: s.extras },
2834
- group: e ? "play_log" : "play_log_open",
2835
- name: s.name,
2836
- payload: s.payload,
2837
- version: 2
2838
- });
2839
- }
2840
- }
2841
- async function ee(r, e = 0, t = !1) {
2842
- if (!D.hasEventSender())
2843
- throw new Error("Playback not allowed without an event sender.");
2844
- if (await y.synchronize(), F.ensure().catch(console.error), p.activePlayer?.nextItem && p.activePlayer.nextItem.mediaProduct.productId === r.productId) {
2845
- const f = p.activePlayer;
2846
- return performance.mark(
2847
- "streaming_metrics:playback_statistics:idealStartTimestamp",
2848
- {
2849
- detail: p.preloadedStreamingSessionId,
2850
- startTime: y.now()
2851
- }
2852
- ), await f.reset({ keepPreload: !0 }), r.referenceId && p.preloadedStreamingSessionId && f.overwriteMediaProduct(
2853
- p.preloadedStreamingSessionId,
2854
- r
2855
- ), f.skipToPreloadedMediaProduct();
2856
- }
2857
- const s = yt(), n = rt();
2858
- j([
2859
- et({
2860
- sessionProductId: r.productId,
2861
- sessionProductType: r.productType === "track" ? "TRACK" : "VIDEO",
2862
- sessionType: "PLAYBACK",
2863
- startReason: "EXPLICIT",
2864
- streamingSessionId: n,
2865
- timestamp: y.now()
2866
- })
2867
- ]).catch(console.error), performance.mark(
2868
- "streaming_metrics:playback_statistics:idealStartTimestamp",
2869
- {
2870
- detail: n,
2871
- startTime: y.now()
2872
- }
2873
- );
2874
- const { clientId: o, token: a } = await v.credentialsProvider.getCredentials(), c = _("streamingWifiAudioQuality");
2875
- let u = null;
2876
- try {
2877
- u = await mt({
2878
- accessToken: a,
2879
- audioQuality: c,
2880
- clientId: o,
2881
- mediaProduct: r,
2882
- prefetch: t,
2883
- streamingSessionId: n
2884
- });
2885
- } catch (f) {
2886
- f instanceof C && m.dispatchError(f), document.location.href.includes("localhost") && console.error(f);
2887
- }
2888
- if (!u)
2889
- return;
2890
- const d = dt(u);
2891
- H.saveStreamInfo(
2892
- d.streamingSessionId,
2893
- d
2894
- ), await s, Y.enable();
2895
- const b = "trackId" in u ? u.audioQuality : void 0, M = await _e(
2896
- r.productType,
2897
- b
2898
- );
2899
- return Ie(M), M.load(
2900
- {
2901
- assetPosition: e,
2902
- mediaProduct: r,
2903
- playbackInfo: u,
2904
- streamInfo: d
2905
- },
2906
- "explicit"
2907
- );
2908
- }
2909
- m.addEventListener("load", (r) => {
2910
- if (r instanceof CustomEvent) {
2911
- const { currentTime: e, mediaProduct: t } = r.detail;
2912
- ee(t, e).then().catch(console.error);
2913
- }
2914
- });
2915
- function bt() {
2916
- return p.activePlayer?.pause();
2917
- }
2918
- async function vt() {
2919
- await y.synchronize();
2920
- const { activePlayer: r } = p;
2921
- return r ? (m.dispatchEvent(new CustomEvent("user-action")), r.play()) : Promise.reject(new Error("No active player"));
2922
- }
2923
- async function St(r) {
2924
- const { activePlayer: e } = p;
2925
- return e?.seek(r);
2926
- }
2927
- function Qt(r) {
2928
- v.credentialsProvider = r;
2929
- }
2930
- function Gt(r) {
2931
- D.eventSender = r;
2932
- }
2933
- const Mt = "active-device-changed";
2934
- function qt(r) {
2935
- return new CustomEvent(Mt, {
2936
- detail: r
2937
- });
2938
- }
2939
- const Et = "active-device-mode-changed";
2940
- function jt(r) {
2941
- return new CustomEvent(Et, {
2942
- detail: r
2943
- });
2944
- }
2945
- y.synchronize().then().catch(console.error);
2946
- function te() {
2947
- const { activePlayer: r } = p;
2948
- if (!r)
2949
- return null;
2950
- switch (r.name) {
2951
- case "browserPlayer":
2952
- return r.mediaElement;
2953
- case "shakaPlayer":
2954
- return r.mediaElement;
2955
- default:
2956
- return null;
2957
- }
2958
- }
2959
- function kt() {
2960
- const r = localStorage.getItem("ssuid");
2961
- try {
2962
- r && indexedDB.deleteDatabase("streaming-sessions-" + r);
2963
- } catch (e) {
2964
- console.warn(`DB streaming-sessions-${r} could not be deleted`), console.error(e);
2965
- }
2966
- }
2967
- he().then().catch(console.error);
2968
- pe().then().catch(console.error);
2969
- kt();
2970
- const U = String.raw, Pt = String.raw;
2971
- function re(r) {
2972
- if (r === void 0)
2973
- return "0:00";
2974
- const e = parseInt(String(r), 10), t = Math.floor(e / 3600), s = Math.floor((e - t * 3600) / 60), n = e - t * 3600 - s * 60;
2975
- let o = "";
2976
- if (t !== 0) {
2977
- const a = s < 10 ? `0${s}` : String(s);
2978
- o = `${t}:${a}:`;
2979
- } else
2980
- o = `${s}:`;
2981
- return o += n < 10 ? `0${n}` : String(n), o;
2982
- }
2983
- function se(r = 0) {
2984
- const e = typeof r == "number" ? r : parseInt(r, 10), t = Math.floor(e / 3600) % 24, s = Math.floor(e / 60) % 60, n = e % 60, o = (c, u) => {
2985
- if (c === 0 && u !== 1)
2986
- return "";
2987
- let d;
2988
- switch (u) {
2989
- case 0:
2990
- d = "H";
2991
- break;
2992
- case 1:
2993
- d = "M";
2994
- break;
2995
- default:
2996
- d = "S";
2997
- break;
2998
- }
2999
- return `${d}${c}`;
3000
- };
3001
- return `P${[t, s, n].map(o).join("")}`;
3002
- }
3003
- const Tt = "tidal-current-time";
3004
- class It extends HTMLElement {
3005
- #e = void 0;
3006
- #r = /* @__PURE__ */ new Set();
3007
- #s;
3008
- #t;
3009
- #i;
3010
- constructor() {
3011
- super(), this.#i = (e) => this.renderTime(e.target.currentTime), this.#t = () => this.renderTime(0), this.#s = this.#n.bind(this);
3012
- }
3013
- #n() {
3014
- const e = te();
3015
- e && this.#e && !this.#r.has(e) && (e.addEventListener("timeupdate", this.#i, !1), this.#r.add(e));
3016
- }
3017
- connectedCallback() {
3018
- const e = this.attachShadow({ mode: "open" });
3019
- e.innerHTML = "<time></time>";
3020
- const t = e.querySelector("time");
3021
- this.#e === void 0 && t !== null && (this.#e = t), this.renderTime(Fe()), m.addEventListener(
3022
- "media-product-transition",
3023
- this.#s,
3024
- !1
3025
- ), m.addEventListener("ended", this.#t, !1);
3026
- }
3027
- disconnectedCallback() {
3028
- for (let e of this.#r)
3029
- e.removeEventListener(
3030
- "timeupdate",
3031
- this.#i,
3032
- !1
3033
- );
3034
- m.removeEventListener(
3035
- "media-product-transition",
3036
- this.#s,
3037
- !1
3038
- ), m.removeEventListener("ended", this.#t, !1);
3039
- }
3040
- renderTime(e) {
3041
- const t = Math.floor(e);
3042
- this.#e && (this.#e.textContent = re(t), this.#e.setAttribute("datetime", se(t)));
3043
- }
3044
- }
3045
- customElements.define(Tt, It);
3046
- const Lt = "tidal-duration-time";
3047
- class At extends HTMLElement {
3048
- #e;
3049
- #r = !1;
3050
- #s;
3051
- constructor() {
3052
- super(), this.#s = (e) => {
3053
- const t = e;
3054
- this.renderTime(t.detail.playbackContext.actualDuration);
3055
- }, this.#t();
3056
- }
3057
- #t() {
3058
- this.#r || (m.addEventListener(
3059
- "media-product-transition",
3060
- this.#s,
3061
- !1
3062
- ), this.#r = !0);
3063
- }
3064
- #i() {
3065
- const e = this.attachShadow({ mode: "open" });
3066
- this.#e = document.createElement("time"), e.appendChild(this.#e);
3067
- }
3068
- connectedCallback() {
3069
- this.#t(), this.#i();
3070
- const e = parseInt(String(this.textContent), 10), t = Number.isNaN(e) ? 0 : e;
3071
- this.renderTime(Be()?.actualDuration ?? t);
3072
- }
3073
- disconnectedCallback() {
3074
- m.removeEventListener(
3075
- "media-product-transition",
3076
- this.#s,
3077
- !1
3078
- ), this.#r = !1;
3079
- }
3080
- renderTime(e) {
3081
- const t = parseInt(e.toFixed(0), 10);
3082
- this.#e && (this.#e.textContent = re(t), this.#e.setAttribute("datetime", se(t)));
3083
- }
3084
- }
3085
- customElements.define(Lt, At);
3086
- const Ot = "tidal-play-trigger";
3087
- class Ct extends HTMLElement {
3088
- #e;
3089
- #r = !1;
3090
- constructor() {
3091
- super(), this.#e = () => {
3092
- this.#s().catch(console.error);
3093
- }, this.#i();
3094
- }
3095
- async #s() {
3096
- await this.#t(), Q() === "PLAYING" ? bt() : await vt();
3097
- }
3098
- #t() {
3099
- const e = Ne()?.productId ?? void 0;
3100
- if (this.mediaProduct && this.mediaProduct.productId !== e)
3101
- return ee(this.mediaProduct, 0);
3102
- }
3103
- #i() {
3104
- this.#r || this.addEventListener("click", this.#e, { passive: !0 });
3105
- }
3106
- #n() {
3107
- const e = this.attachShadow({ mode: "closed" }), t = document.createElement("style");
3108
- t.textContent = U`
3109
- :host {
3110
- display: contents;
3111
- }
3112
- `;
3113
- const s = document.createElement("slot");
3114
- e.appendChild(t), e.appendChild(s);
3115
- }
3116
- connectedCallback() {
3117
- this.#i(), this.#n();
3118
- }
3119
- disconnectedCallback() {
3120
- this.removeEventListener("click", this.#e, {
3121
- passive: !0
3122
- }), this.#r = !1;
3123
- }
3124
- get mediaProduct() {
3125
- const e = this.getAttribute("product-id");
3126
- if (!e)
3127
- return;
3128
- const t = this.getAttribute("product-type") === "video" ? "video" : "track";
3129
- return {
3130
- productId: e,
3131
- productType: t,
3132
- sourceId: "",
3133
- sourceType: ""
3134
- };
3135
- }
3136
- static get observedAttributes() {
3137
- return ["product-id", "product-type"];
3138
- }
3139
- }
3140
- customElements.define(Ot, Ct);
3141
- const _t = U`
3142
- :host {
3143
- display: inline-block;
3144
- }
3145
-
3146
- #wrapper {
3147
- width: 100%;
3148
- height: 100%;
3149
- contain: strict;
3150
- background-color: rgba(255, 255, 255, 0.2);
3151
- cursor: pointer;
3152
- }
3153
-
3154
- #indicator {
3155
- width: 100%;
3156
- height: 100%;
3157
- transform: none;
3158
- will-change: transform;
3159
- background-color: currentColor;
3160
- pointer-events: none;
3161
- }
3162
- `, $ = {
3163
- NO_DURATION: "You need to set duration before you can start/stop the progress bar."
3164
- };
3165
- class Ft extends HTMLElement {
3166
- #e;
3167
- #r = 1;
3168
- #s = null;
3169
- #t;
3170
- #i;
3171
- #n = /* @__PURE__ */ new Set();
3172
- #a = null;
3173
- #o;
3174
- constructor() {
3175
- super(), this.#t = (e) => {
3176
- const t = e;
3177
- if (this.duration = t.detail.playbackContext.actualDuration, Q() === "PLAYING")
3178
- try {
3179
- this.start();
3180
- } catch (s) {
3181
- console.warn(s);
3182
- }
3183
- }, this.#i = (e) => {
3184
- const t = e;
3185
- try {
3186
- t.detail.state === "PLAYING" ? this.start() : this.stop();
3187
- } catch (s) {
3188
- console.warn(s);
3189
- }
3190
- }, this.#o = (e) => {
3191
- (e instanceof MouseEvent || e instanceof PointerEvent) && this.handleClick(e);
3192
- }, this.#c();
3193
- }
3194
- #c() {
3195
- this.#n.has("media-product-transition") || (m.addEventListener(
3196
- "media-product-transition",
3197
- this.#t,
3198
- !1
3199
- ), this.#n.add("media-product-transition")), this.#n.has("playback-state-change") || (m.addEventListener(
3200
- "playback-state-change",
3201
- this.#i
3202
- ), this.#n.add("playback-state-change")), this.#a && !this.#n.has("wrapper-click") && (this.#a.addEventListener("click", this.#o, !1), this.#n.add("wrapper-click"));
3203
- }
3204
- #d() {
3205
- const e = this.attachShadow({ mode: "closed" });
3206
- e.innerHTML = Pt`
3207
- <style>
3208
- ${_t}
3209
- </style>
3210
- <div id="wrapper">
3211
- <div id="indicator"></div>
3212
- </div>
3213
- `, this.#a = e.querySelector("#wrapper"), this.#s = e.querySelector("#indicator");
3214
- }
3215
- /**
3216
- * Renders the progress bar to a shadow DOM, caches references to the wrapper
3217
- * && indicator elements and adds a click handler to the wrapper element for
3218
- * handling the seeking.
3219
- */
3220
- connectedCallback() {
3221
- this.#d(), this.#c();
3222
- }
3223
- disconnectedCallback() {
3224
- m.removeEventListener(
3225
- "media-product-transition",
3226
- this.#t,
3227
- !1
3228
- ), m.removeEventListener(
3229
- "playback-state-change",
3230
- this.#i
3231
- ), this.#a?.addEventListener("click", this.#o, !1), this.#n.clear();
3232
- }
3233
- /**
3234
- * Calculates where in the progress bar the person clicked
3235
- * in percent.
3236
- *
3237
- * @param {MouseEvent} mouse
3238
- */
3239
- getMousePositionAsPercent(e) {
3240
- if (this.#a) {
3241
- const t = this.#a.getBoundingClientRect(), s = {
3242
- left: Math.abs(t.left + window.pageXOffset - e.pageX),
3243
- width: Math.round(t.width)
3244
- };
3245
- return s.left / s.width;
3246
- }
3247
- return 0;
3248
- }
3249
- /**
3250
- * Handle clicking the progress bar wrapper. Calculate the percentate
3251
- * to seek to and emits a progress-bar:seek CustomEvent to be listened
3252
- * to outside this component to react to the click.
3253
- *
3254
- * @param {MouseEvent | PointerEvent} event
3255
- */
3256
- handleClick(e) {
3257
- const t = this.getMousePositionAsPercent(e), s = this.#r * t;
3258
- this.currentTime = s, St(s / 1e3);
3259
- }
3260
- /**
3261
- * Starts the animation if duration is defined.
3262
- *
3263
- * @throws Will throw an error if duration is not set.
3264
- */
3265
- start() {
3266
- if (!this.#e)
3267
- throw new Error($.NO_DURATION);
3268
- this.#e.play();
3269
- }
3270
- /**
3271
- * Stops the animation if duration is defined.
3272
- *
3273
- * @throws Will throw an error if duration is not set.
3274
- */
3275
- stop() {
3276
- if (!this.#e)
3277
- throw new Error($.NO_DURATION);
3278
- this.#e.pause();
3279
- }
3280
- /**
3281
- * Set current time with milliseconds.
3282
- *
3283
- * @memberof ProgressBar
3284
- */
3285
- set currentTime(e) {
3286
- this.#e && (this.#e.currentTime = e);
3287
- }
3288
- /**
3289
- * Setting this recrates the animation with the new duraton and pauses the animation.
3290
- */
3291
- set duration(e) {
3292
- this.#r = e * 1e3;
3293
- const t = [
3294
- {
3295
- transform: "translateX(-100%)"
3296
- },
3297
- {
3298
- transform: "translateX(0%)"
3299
- }
3300
- ];
3301
- this.#e = this.#s?.animate(t, {
3302
- duration: this.#r,
3303
- iterations: 1
3304
- }), this.#e?.pause();
3305
- }
3306
- /**
3307
- * Setting this stops the animations, updates the playback rate and plays it again.
3308
- */
3309
- set playbackRate(e) {
3310
- this.stop(), this.#e && (this.#e.playbackRate = e), this.start();
3311
- }
3312
- }
3313
- const Nt = "tidal-progress-bar";
3314
- customElements.define(Nt, Ft);
3315
- const Bt = U`
3316
- :host {
3317
- position: relative;
3318
- display: block;
3319
- width: 100%;
3320
- aspect-ratio: 16/9;
3321
- background-color: black;
3322
- }
3323
-
3324
- ::slotted(video) {
3325
- display: block;
3326
- width: 100%;
3327
- height: 100%;
3328
- z-index: 1;
3329
- position: relative;
3330
- background-color: black;
3331
- }
3332
- `, xt = "tidal-video-view";
3333
- class Rt extends HTMLElement {
3334
- #e = !1;
3335
- #r;
3336
- #s;
3337
- constructor() {
3338
- super(), this.#r = (e) => {
3339
- e.detail.mediaProduct.productType === "video" && this.mountPlayer();
3340
- }, this.#s = (e) => {
3341
- const t = e;
3342
- this.setAttribute(
3343
- "playback-state",
3344
- t.detail.state.toLocaleLowerCase()
3345
- );
3346
- }, this.#t();
3347
- }
3348
- #t() {
3349
- this.#e || (m.addEventListener(
3350
- "media-product-transition",
3351
- this.#r,
3352
- !1
3353
- ), m.addEventListener(
3354
- "playback-state-change",
3355
- this.#s,
3356
- !1
3357
- ));
3358
- }
3359
- connectedCallback() {
3360
- this.#t();
3361
- const e = this.attachShadow({ mode: "closed" }), t = document.createElement("style");
3362
- t.textContent = Bt;
3363
- const s = document.createElement("slot");
3364
- e.appendChild(t), e.appendChild(s);
3365
- }
3366
- disconnectedCallback() {
3367
- m.removeEventListener(
3368
- "media-product-transition",
3369
- this.#r,
3370
- !1
3371
- ), m.removeEventListener(
3372
- "playback-state-change",
3373
- this.#s,
3374
- !1
3375
- ), this.#e = !0;
3376
- }
3377
- mountPlayer() {
3378
- const e = te();
3379
- e && (this.innerHTML = "", this.appendChild(e));
3380
- }
3381
- }
3382
- customElements.define(xt, Rt);
3383
- export {
3384
- Ht as C,
3385
- qt as G,
3386
- Qt as H,
3387
- E as I,
3388
- Dt as L,
3389
- H as P,
3390
- Gt as Q,
3391
- zt as R,
3392
- v as S,
3393
- j as W,
3394
- me as a,
3395
- m as b,
3396
- fe as c,
3397
- $t as d,
3398
- Qe as e,
3399
- oe as f,
3400
- Wt as g,
3401
- Ut as h,
3402
- ee as i,
3403
- jt as j,
3404
- _ as k,
3405
- p as l,
3406
- Je as m,
3407
- rt as n,
3408
- Tt as o,
3409
- Lt as p,
3410
- z as q,
3411
- Ot as r,
3412
- Nt as s,
3413
- xt as t,
3414
- Vt as w,
3415
- C as x,
3416
- y
3417
- };