@hopeplayer/core 1.0.15 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/HopePlayerElement.d.ts +36 -0
- package/dist/HopePlayerElement.d.ts.map +1 -1
- package/dist/chunks/{index-BvoB2O1p.js → index-BXSND_xN.js} +2 -2
- package/dist/chunks/{index-BvoB2O1p.js.map → index-BXSND_xN.js.map} +1 -1
- package/dist/chunks/index-BbRYOSvk.js +261 -0
- package/dist/chunks/index-BbRYOSvk.js.map +1 -0
- package/dist/chunks/{index-ClQg_X1N.js → index-C3BQGcT3.js} +2 -2
- package/dist/chunks/{index-ClQg_X1N.js.map → index-C3BQGcT3.js.map} +1 -1
- package/dist/chunks/{index-BOoNcKeR.js → index-CBX7bn-G.js} +2 -2
- package/dist/chunks/{index-BOoNcKeR.js.map → index-CBX7bn-G.js.map} +1 -1
- package/dist/chunks/{index-CaMVTgh0.js → index-CDPrkLq0.js} +55 -68
- package/dist/chunks/index-CDPrkLq0.js.map +1 -0
- package/dist/chunks/index-CWLyz1fp.js +415 -0
- package/dist/chunks/index-CWLyz1fp.js.map +1 -0
- package/dist/chunks/{index-D5P-LWbg.js → index-Ch3ep-eJ.js} +20 -20
- package/dist/chunks/index-Ch3ep-eJ.js.map +1 -0
- package/dist/chunks/{index-DpUZXNJS.js → index-D3Z7ZDLJ.js} +2 -2
- package/dist/chunks/{index-DpUZXNJS.js.map → index-D3Z7ZDLJ.js.map} +1 -1
- package/dist/chunks/{index-w7pACyTw.js → index-DEv3YqLg.js} +1152 -845
- package/dist/chunks/index-DEv3YqLg.js.map +1 -0
- package/dist/chunks/{index-BCMVXNL0.js → index-DITXYcHx.js} +68 -96
- package/dist/chunks/index-DITXYcHx.js.map +1 -0
- package/dist/chunks/index-Miba3PD_.js +387 -0
- package/dist/chunks/index-Miba3PD_.js.map +1 -0
- package/dist/chunks/{index-DRlQC-ev.js → index-e00_M05B.js} +2 -2
- package/dist/chunks/{index-DRlQC-ev.js.map → index-e00_M05B.js.map} +1 -1
- package/dist/chunks/loadGpt-CmiAy366.js +18 -0
- package/dist/chunks/loadGpt-CmiAy366.js.map +1 -0
- package/dist/hls/SourceManager.d.ts +8 -0
- package/dist/hls/SourceManager.d.ts.map +1 -1
- package/dist/hls/sourceGroups.d.ts +19 -0
- package/dist/hls/sourceGroups.d.ts.map +1 -0
- package/dist/hope-player.js +1 -1
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/types.d.ts +9 -0
- package/dist/i18n/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/plugins/ad-triggers/AdTriggers.d.ts +99 -0
- package/dist/plugins/ad-triggers/AdTriggers.d.ts.map +1 -0
- package/dist/plugins/ad-triggers/index.d.ts +7 -0
- package/dist/plugins/ad-triggers/index.d.ts.map +1 -0
- package/dist/plugins/ads/AdsController.d.ts +8 -0
- package/dist/plugins/ads/AdsController.d.ts.map +1 -1
- package/dist/plugins/cast/CastController.d.ts +107 -0
- package/dist/plugins/cast/CastController.d.ts.map +1 -0
- package/dist/plugins/cast/RemoteMediaProxy.d.ts +41 -0
- package/dist/plugins/cast/RemoteMediaProxy.d.ts.map +1 -0
- package/dist/plugins/cast/castSdk.d.ts +160 -0
- package/dist/plugins/cast/castSdk.d.ts.map +1 -0
- package/dist/plugins/cast/index.d.ts +7 -0
- package/dist/plugins/cast/index.d.ts.map +1 -0
- package/dist/plugins/pause-ad/loadGpt.d.ts +2 -0
- package/dist/plugins/pause-ad/loadGpt.d.ts.map +1 -1
- package/dist/plugins/rewarded/RewardedUnlock.d.ts +2 -0
- package/dist/plugins/rewarded/RewardedUnlock.d.ts.map +1 -1
- package/dist/plugins/rewarded/gpt.d.ts +6 -2
- package/dist/plugins/rewarded/gpt.d.ts.map +1 -1
- package/dist/plugins/sponsorship/SponsorshipLayer.d.ts.map +1 -1
- package/dist/types/index.d.ts +262 -3
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/index-BCMVXNL0.js.map +0 -1
- package/dist/chunks/index-CaMVTgh0.js.map +0 -1
- package/dist/chunks/index-D5P-LWbg.js.map +0 -1
- package/dist/chunks/index-TkG8IO6q.js +0 -239
- package/dist/chunks/index-TkG8IO6q.js.map +0 -1
- package/dist/chunks/index-w7pACyTw.js.map +0 -1
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
var k = Object.defineProperty;
|
|
2
|
+
var x = (l, t, e) => t in l ? k(l, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : l[t] = e;
|
|
3
|
+
var r = (l, t, e) => x(l, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import { s as E } from "./index-DEv3YqLg.js";
|
|
5
|
+
const T = "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1", C = 1e4;
|
|
6
|
+
let g = null;
|
|
7
|
+
function b() {
|
|
8
|
+
var t, e;
|
|
9
|
+
const l = window;
|
|
10
|
+
return (t = l.cast) != null && t.framework && ((e = l.chrome) != null && e.cast) ? { framework: l.cast.framework, chrome: l.chrome.cast } : null;
|
|
11
|
+
}
|
|
12
|
+
function w() {
|
|
13
|
+
if (g) return g;
|
|
14
|
+
const l = window;
|
|
15
|
+
return b() ? g = Promise.resolve(b()) : !l.chrome || !window.isSecureContext ? g = Promise.resolve(null) : (g = new Promise((t) => {
|
|
16
|
+
const e = l.__onGCastApiAvailable, s = setTimeout(() => t(null), C);
|
|
17
|
+
if (l.__onGCastApiAvailable = (i, a) => {
|
|
18
|
+
e == null || e(i, a), clearTimeout(s), t(i ? b() : null);
|
|
19
|
+
}, !document.querySelector('script[src*="cast_sender.js"]')) {
|
|
20
|
+
const i = document.createElement("script");
|
|
21
|
+
i.async = !0, i.src = T, i.onerror = () => {
|
|
22
|
+
clearTimeout(s), g = null, t(null);
|
|
23
|
+
}, document.head.appendChild(i);
|
|
24
|
+
}
|
|
25
|
+
}), g);
|
|
26
|
+
}
|
|
27
|
+
const I = ["paused", "currentTime", "duration", "ended", "volume", "muted", "readyState", "seeking", "buffered", "play", "pause"], M = {
|
|
28
|
+
length: 0,
|
|
29
|
+
start: () => {
|
|
30
|
+
throw new DOMException("Index out of range", "IndexSizeError");
|
|
31
|
+
},
|
|
32
|
+
end: () => {
|
|
33
|
+
throw new DOMException("Index out of range", "IndexSizeError");
|
|
34
|
+
}
|
|
35
|
+
}, P = 150;
|
|
36
|
+
function A(l, t) {
|
|
37
|
+
return Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, t).get.call(l);
|
|
38
|
+
}
|
|
39
|
+
class N {
|
|
40
|
+
constructor(t, e, s) {
|
|
41
|
+
r(this, "state");
|
|
42
|
+
r(this, "pendingSeek", null);
|
|
43
|
+
r(this, "seekTimer", null);
|
|
44
|
+
r(this, "installed", !1);
|
|
45
|
+
this.video = t, this.commands = e, this.state = { ...s };
|
|
46
|
+
}
|
|
47
|
+
get current() {
|
|
48
|
+
return this.state;
|
|
49
|
+
}
|
|
50
|
+
install() {
|
|
51
|
+
if (this.installed) return;
|
|
52
|
+
this.installed = !0;
|
|
53
|
+
const t = this.video, e = () => this.state, s = (i, a) => {
|
|
54
|
+
Object.defineProperty(t, i, { configurable: !0, enumerable: !1, ...a });
|
|
55
|
+
};
|
|
56
|
+
s("paused", { get: () => e().paused }), s("ended", { get: () => e().ended }), s("duration", { get: () => e().duration }), s("readyState", { get: () => 4 }), s("seeking", { get: () => this.pendingSeek !== null }), s("buffered", { get: () => M }), s("currentTime", {
|
|
57
|
+
get: () => this.pendingSeek ?? e().currentTime,
|
|
58
|
+
set: (i) => this.seek(i)
|
|
59
|
+
}), s("volume", {
|
|
60
|
+
get: () => e().volume,
|
|
61
|
+
set: (i) => {
|
|
62
|
+
const a = Math.min(1, Math.max(0, Number(i) || 0));
|
|
63
|
+
this.state.volume = a, this.commands.setVolume(a), this.fire("volumechange");
|
|
64
|
+
}
|
|
65
|
+
}), s("muted", {
|
|
66
|
+
get: () => e().muted,
|
|
67
|
+
set: (i) => {
|
|
68
|
+
this.state.muted = !!i, this.commands.setMuted(!!i), this.fire("volumechange");
|
|
69
|
+
}
|
|
70
|
+
}), s("play", {
|
|
71
|
+
value: () => (this.state.ended && this.seek(0), this.commands.play(), Promise.resolve())
|
|
72
|
+
}), s("pause", { value: () => this.commands.pause() });
|
|
73
|
+
}
|
|
74
|
+
uninstall() {
|
|
75
|
+
if (this.installed) {
|
|
76
|
+
this.installed = !1, this.seekTimer && clearTimeout(this.seekTimer), this.seekTimer = null, this.pendingSeek = null;
|
|
77
|
+
for (const t of I) delete this.video[t];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** TV'den gelen durum — değişen alanlar için olay yayar. */
|
|
81
|
+
update(t) {
|
|
82
|
+
const e = this.state;
|
|
83
|
+
this.state = { ...e, ...t };
|
|
84
|
+
const s = this.state;
|
|
85
|
+
t.duration !== void 0 && t.duration !== e.duration && this.fire("durationchange"), t.currentTime !== void 0 && t.currentTime !== e.currentTime && this.pendingSeek === null && this.fire("timeupdate"), (t.volume !== void 0 || t.muted !== void 0) && (s.volume !== e.volume || s.muted !== e.muted) && this.fire("volumechange"), t.paused !== void 0 && t.paused !== e.paused && (s.paused ? this.fire("pause") : (this.fire("play"), this.fire("playing"))), t.ended && !e.ended && this.fire("ended");
|
|
86
|
+
}
|
|
87
|
+
seek(t) {
|
|
88
|
+
const e = Math.max(0, Number(t) || 0), s = this.pendingSeek === null;
|
|
89
|
+
this.pendingSeek = e, s && this.fire("seeking"), this.fire("timeupdate"), this.seekTimer && clearTimeout(this.seekTimer), this.seekTimer = setTimeout(() => {
|
|
90
|
+
this.seekTimer = null;
|
|
91
|
+
const i = this.pendingSeek ?? e;
|
|
92
|
+
this.commands.seek(i), this.state = { ...this.state, currentTime: i, ended: !1 }, this.pendingSeek = null, this.fire("seeked"), this.fire("timeupdate");
|
|
93
|
+
}, P);
|
|
94
|
+
}
|
|
95
|
+
fire(t) {
|
|
96
|
+
this.video.dispatchEvent(new Event(t));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
let y = null, m = null;
|
|
100
|
+
const B = 20, _ = 5;
|
|
101
|
+
class L {
|
|
102
|
+
constructor(t, e) {
|
|
103
|
+
r(this, "options");
|
|
104
|
+
r(this, "api", null);
|
|
105
|
+
r(this, "context", null);
|
|
106
|
+
r(this, "session", null);
|
|
107
|
+
r(this, "player", null);
|
|
108
|
+
r(this, "controller", null);
|
|
109
|
+
r(this, "proxy", null);
|
|
110
|
+
r(this, "castBtn", null);
|
|
111
|
+
r(this, "castIcon", null);
|
|
112
|
+
r(this, "airplayBtn", null);
|
|
113
|
+
r(this, "remoteBtn", null);
|
|
114
|
+
r(this, "overlay", null);
|
|
115
|
+
r(this, "loadedSrc", "");
|
|
116
|
+
r(this, "loadedContent", "");
|
|
117
|
+
r(this, "savedAutoplay", !1);
|
|
118
|
+
r(this, "airplayActive", !1);
|
|
119
|
+
r(this, "destroyed", !1);
|
|
120
|
+
r(this, "remoteWatchId", null);
|
|
121
|
+
r(this, "onCastState", (t) => {
|
|
122
|
+
var s;
|
|
123
|
+
const e = t.castState ?? "NO_DEVICES_AVAILABLE";
|
|
124
|
+
this.castBtn && (this.castBtn.hidden = e === "NO_DEVICES_AVAILABLE"), (s = this.castBtn) == null || s.toggleAttribute("data-connecting", e === "CONNECTING"), this.proxy || this.emit(e === "NO_DEVICES_AVAILABLE" ? "unavailable" : e === "CONNECTING" ? "connecting" : "available", "chromecast");
|
|
125
|
+
});
|
|
126
|
+
r(this, "onSessionState", (t) => {
|
|
127
|
+
const e = t.sessionState;
|
|
128
|
+
(e === "SESSION_STARTED" || e === "SESSION_RESUMED") && t.session ? y === this ? (y = null, this.attach(t.session, !0)) : e === "SESSION_RESUMED" && !m && this.tryResume(t.session) : (e === "SESSION_ENDED" || e === "SESSION_START_FAILED") && (y === this && (y = null), m === this && this.detach());
|
|
129
|
+
});
|
|
130
|
+
r(this, "onRemoteChange", (t) => {
|
|
131
|
+
var i;
|
|
132
|
+
const e = this.player, s = this.proxy;
|
|
133
|
+
if (!(!e || !s))
|
|
134
|
+
switch (t.field) {
|
|
135
|
+
case "isPaused":
|
|
136
|
+
s.update({ paused: !!t.value });
|
|
137
|
+
break;
|
|
138
|
+
case "currentTime":
|
|
139
|
+
s.update({ currentTime: Number(t.value) || 0 });
|
|
140
|
+
break;
|
|
141
|
+
case "duration":
|
|
142
|
+
s.update({ duration: Number(t.value) > 0 ? Number(t.value) : s.current.duration });
|
|
143
|
+
break;
|
|
144
|
+
case "volumeLevel":
|
|
145
|
+
s.update({ volume: Number(t.value) });
|
|
146
|
+
break;
|
|
147
|
+
case "isMuted":
|
|
148
|
+
s.update({ muted: !!t.value });
|
|
149
|
+
break;
|
|
150
|
+
case "playerState":
|
|
151
|
+
t.value === "IDLE" && e.isMediaLoaded === !1 && s.current.currentTime > 0 ? s.update({ ended: !0, paused: !0 }) : t.value === "PLAYING" && s.update({ ended: !1, paused: !1 });
|
|
152
|
+
break;
|
|
153
|
+
case "isPlayingBreak":
|
|
154
|
+
(i = this.overlay) == null || i.toggleAttribute("data-break", !!t.value);
|
|
155
|
+
break;
|
|
156
|
+
case "isConnected":
|
|
157
|
+
!t.value && m === this && this.detach();
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
/** Cast sırasında player başka bir kaynağa geçti (playlist sonraki öğe, kalite, yedek kaynak) → TV'ye de gönder. */
|
|
162
|
+
r(this, "onLocalSourceChange", () => {
|
|
163
|
+
if (!this.proxy) return;
|
|
164
|
+
HTMLMediaElement.prototype.pause.call(this.ctx.videoEl);
|
|
165
|
+
const t = this.ctx.getMedia();
|
|
166
|
+
if (!t || t.src === this.loadedSrc) return;
|
|
167
|
+
const e = this.ctx.contentKey() === this.loadedContent;
|
|
168
|
+
this.loadMedia(e ? this.proxy.current.currentTime : 0, !0);
|
|
169
|
+
});
|
|
170
|
+
this.ctx = t, this.options = e, e.chromecast && this.initChromecast(), e.airplay && this.initAirPlay(), e.remotePlayback && this.initRemotePlayback();
|
|
171
|
+
}
|
|
172
|
+
update(t) {
|
|
173
|
+
const e = this.options;
|
|
174
|
+
this.options = t, t.chromecast && !e.chromecast && this.initChromecast(), t.airplay && !e.airplay && this.initAirPlay(), t.remotePlayback && !e.remotePlayback && this.initRemotePlayback(), this.castBtn && (this.castBtn.hidden = !t.chromecast || this.castBtn.hidden), this.airplayBtn && !t.airplay && (this.airplayBtn.hidden = !0), this.remoteBtn && !t.remotePlayback && (this.remoteBtn.hidden = !0);
|
|
175
|
+
}
|
|
176
|
+
/** İçerik şu an TV'de mi (herhangi bir yoldan). */
|
|
177
|
+
get casting() {
|
|
178
|
+
var t;
|
|
179
|
+
return !!this.proxy || this.airplayActive || ((t = this.ctx.videoEl.remote) == null ? void 0 : t.state) === "connected";
|
|
180
|
+
}
|
|
181
|
+
emit(t, e, s) {
|
|
182
|
+
this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:cast", { detail: { state: t, via: e, device: s } }));
|
|
183
|
+
}
|
|
184
|
+
button(t, e, s) {
|
|
185
|
+
const i = this.ctx.addButton(t, e, s);
|
|
186
|
+
return i.btn.hidden = !0, i;
|
|
187
|
+
}
|
|
188
|
+
// ── Google Cast ─────────────────────────────────────────────────────────
|
|
189
|
+
async initChromecast() {
|
|
190
|
+
if (this.castBtn) return;
|
|
191
|
+
const { btn: t, icon: e } = this.button(this.ctx.i18n.castButton, "cast", () => this.requestCast());
|
|
192
|
+
t.setAttribute("part", "cast-button"), this.castBtn = t, this.castIcon = e;
|
|
193
|
+
const s = await w();
|
|
194
|
+
if (!s || this.destroyed) {
|
|
195
|
+
s || this.ctx.log({ message: "Google Cast is not available in this browser (Chrome / Edge over HTTPS needed)" });
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
this.api = s;
|
|
199
|
+
const i = s.framework.CastContext.getInstance();
|
|
200
|
+
this.context = i, i.setOptions({
|
|
201
|
+
receiverApplicationId: this.options.receiverAppId || s.chrome.media.DEFAULT_MEDIA_RECEIVER_APP_ID,
|
|
202
|
+
autoJoinPolicy: s.chrome.AutoJoinPolicy.ORIGIN_SCOPED
|
|
203
|
+
});
|
|
204
|
+
const a = s.framework.CastContextEventType;
|
|
205
|
+
i.addEventListener(a.CAST_STATE_CHANGED, this.onCastState), i.addEventListener(a.SESSION_STATE_CHANGED, this.onSessionState), this.onCastState({ castState: i.getCastState() });
|
|
206
|
+
const n = i.getCurrentSession();
|
|
207
|
+
n && !m && this.tryResume(n);
|
|
208
|
+
}
|
|
209
|
+
requestCast() {
|
|
210
|
+
if (this.context) {
|
|
211
|
+
if (this.ctx.isAdPlaying()) {
|
|
212
|
+
this.ctx.log({ message: "Cast: wait for the ad to finish" });
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
y = this, this.context.requestSession().catch((t) => {
|
|
216
|
+
y === this && (y = null), String(t) !== "cancel" && this.ctx.log({ message: `Cast session failed: ${String(t)}` });
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
tryResume(t) {
|
|
221
|
+
var i, a;
|
|
222
|
+
const e = this.ctx.getMedia(), s = (a = (i = t.getMediaSession()) == null ? void 0 : i.media) == null ? void 0 : a.contentId;
|
|
223
|
+
e && s && s === e.src && this.attach(t, !1);
|
|
224
|
+
}
|
|
225
|
+
async attach(t, e) {
|
|
226
|
+
var p, c, h, u;
|
|
227
|
+
const s = this.api;
|
|
228
|
+
if (!s || this.destroyed) return;
|
|
229
|
+
m && m !== this && m.detach(), m = this, this.session = t;
|
|
230
|
+
const i = this.ctx.videoEl, a = A(i, "currentTime"), n = A(i, "duration");
|
|
231
|
+
HTMLMediaElement.prototype.pause.call(i), this.savedAutoplay = i.autoplay, i.autoplay = !1;
|
|
232
|
+
const o = new s.framework.RemotePlayer(), d = new s.framework.RemotePlayerController(o);
|
|
233
|
+
this.player = o, this.controller = d, this.proxy = new N(
|
|
234
|
+
i,
|
|
235
|
+
{
|
|
236
|
+
play: () => o.isPaused && d.playOrPause(),
|
|
237
|
+
pause: () => !o.isPaused && d.playOrPause(),
|
|
238
|
+
seek: (f) => {
|
|
239
|
+
o.currentTime = f, d.seek();
|
|
240
|
+
},
|
|
241
|
+
setVolume: (f) => {
|
|
242
|
+
o.volumeLevel = f, d.setVolumeLevel();
|
|
243
|
+
},
|
|
244
|
+
setMuted: (f) => o.isMuted !== f && d.muteOrUnmute()
|
|
245
|
+
},
|
|
246
|
+
{ paused: !1, currentTime: a, duration: n, volume: i.volume, muted: i.muted, ended: !1 }
|
|
247
|
+
), this.proxy.install(), d.addEventListener(s.framework.RemotePlayerEventType.ANY_CHANGE, this.onRemoteChange), i.addEventListener("loadstart", this.onLocalSourceChange), this.ctx.onRemoteChange(!0);
|
|
248
|
+
const v = ((p = t.getCastDevice()) == null ? void 0 : p.friendlyName) || this.ctx.i18n.castDeviceFallback;
|
|
249
|
+
this.showOverlay(this.ctx.i18n.castPlayingOn.replace("{device}", v)), (c = this.castBtn) == null || c.setAttribute("aria-pressed", "true"), this.castIcon && E(this.castIcon, "cast-connected"), this.emit("connected", "chromecast", v), e ? await this.loadMedia(a, !0) : (this.loadedSrc = ((u = (h = t.getMediaSession()) == null ? void 0 : h.media) == null ? void 0 : u.contentId) ?? "", this.loadedContent = this.ctx.contentKey());
|
|
250
|
+
}
|
|
251
|
+
/** O an çalan içeriği TV'ye yükler (reklam araları ve altyazılarla). */
|
|
252
|
+
async loadMedia(t, e) {
|
|
253
|
+
const s = this.api, i = this.session, a = this.ctx.getMedia();
|
|
254
|
+
if (!s || !i || !a) {
|
|
255
|
+
this.ctx.log({ message: "Cast: nothing to send (no playable source)" });
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const n = s.chrome.media, o = new n.MediaInfo(a.src, a.contentType);
|
|
259
|
+
o.streamType = a.live ? n.StreamType.LIVE : n.StreamType.BUFFERED;
|
|
260
|
+
const d = a.music ? new n.MusicTrackMediaMetadata() : new n.GenericMediaMetadata();
|
|
261
|
+
d.title = a.title, a.music ? d.artist = a.subtitle : d.subtitle = a.subtitle, a.image && (d.images = [new s.chrome.Image(a.image)]), o.metadata = d, /mpegurl/i.test(a.contentType) && this.options.hlsSegmentFormat === "fmp4" && (n.HlsSegmentFormat && (o.hlsSegmentFormat = n.HlsSegmentFormat.FMP4), n.HlsVideoSegmentFormat && (o.hlsVideoSegmentFormat = n.HlsVideoSegmentFormat.FMP4));
|
|
262
|
+
const v = [];
|
|
263
|
+
o.tracks = a.subtitles.map((c, h) => {
|
|
264
|
+
const u = new n.Track(h + 1, n.TrackType.TEXT);
|
|
265
|
+
return u.trackContentId = c.src, u.trackContentType = "text/vtt", u.subtype = n.TextTrackType.SUBTITLES, u.name = c.label, u.language = c.lang, c.default && v.push(h + 1), u;
|
|
266
|
+
}), this.applyAds(o, a);
|
|
267
|
+
const p = new n.LoadRequest(o);
|
|
268
|
+
p.currentTime = a.live ? void 0 : t, p.autoplay = e, v.length && (p.activeTrackIds = v), this.loadedSrc = a.src, this.loadedContent = this.ctx.contentKey();
|
|
269
|
+
try {
|
|
270
|
+
await i.loadMedia(p), this.ctx.log({ message: "Cast: media loaded on the TV", details: { src: a.src, ads: a.ads ? a.ads.vmap ? "vmap" : "vast" : "none" } });
|
|
271
|
+
} catch (c) {
|
|
272
|
+
this.ctx.log({ message: `Cast: the TV could not load the media: ${String(c)}`, fatal: !0, details: { src: a.src } });
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Reklamlar TV'de: VMAP verilmişse receiver tüm araları kendisi planlar (vmapAdsRequest); yoksa VAST tag'leri
|
|
277
|
+
* ara olarak eklenir — preroll (0), aralıklı midroll'lar, postroll (-1). Reklamları receiver oynatır ve sayar.
|
|
278
|
+
*/
|
|
279
|
+
applyAds(t, e) {
|
|
280
|
+
var p;
|
|
281
|
+
const s = e.ads, i = this.api.chrome.media;
|
|
282
|
+
if (!s) return;
|
|
283
|
+
if (s.vmap) {
|
|
284
|
+
const c = new i.VastAdsRequest();
|
|
285
|
+
c.adTagUrl = s.vmap, t.vmapAdsRequest = c;
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const a = [], n = [], o = (c, h, u) => {
|
|
289
|
+
const f = new i.BreakClip(`clip-${c}`), S = new i.VastAdsRequest();
|
|
290
|
+
S.adTagUrl = h, f.vastAdsRequest = S, a.push(f), n.push(new i.Break(`break-${c}`, [`clip-${c}`], u));
|
|
291
|
+
};
|
|
292
|
+
s.preroll && o("pre", s.preroll, 0);
|
|
293
|
+
const d = s.midrollIntervalSeconds ?? 0, v = ((p = this.proxy) == null ? void 0 : p.current.duration) ?? NaN;
|
|
294
|
+
if (s.midroll && d > 0 && !e.live && Number.isFinite(v))
|
|
295
|
+
for (let c = d, h = 1; c < v - _ && h <= B; c += d, h++) o(`mid-${h}`, s.midroll, c);
|
|
296
|
+
s.postroll && !e.live && o("post", s.postroll, -1), a.length && (t.breakClips = a, t.breaks = n);
|
|
297
|
+
}
|
|
298
|
+
detach() {
|
|
299
|
+
var n, o;
|
|
300
|
+
const t = this.proxy;
|
|
301
|
+
if (!t) return;
|
|
302
|
+
m === this && (m = null);
|
|
303
|
+
const { currentTime: e, paused: s, ended: i } = t.current, a = this.ctx.videoEl;
|
|
304
|
+
(n = this.controller) == null || n.removeEventListener(this.api.framework.RemotePlayerEventType.ANY_CHANGE, this.onRemoteChange), a.removeEventListener("loadstart", this.onLocalSourceChange), t.uninstall(), this.proxy = null, this.player = null, this.controller = null, this.session = null, this.loadedSrc = "", a.autoplay = this.savedAutoplay, this.ctx.onRemoteChange(!1), this.hideOverlay(), (o = this.castBtn) == null || o.setAttribute("aria-pressed", "false"), this.castIcon && E(this.castIcon, "cast"), Number.isFinite(e) && e > 0 && !i && (a.currentTime = e), !s && !i && a.play().catch(() => {
|
|
305
|
+
}), this.emit("disconnected", "chromecast");
|
|
306
|
+
}
|
|
307
|
+
// ── AirPlay (Safari) ────────────────────────────────────────────────────
|
|
308
|
+
initAirPlay() {
|
|
309
|
+
if (this.airplayBtn || !("WebKitPlaybackTargetAvailabilityEvent" in window)) return;
|
|
310
|
+
const t = this.ctx.videoEl;
|
|
311
|
+
t.setAttribute("x-webkit-airplay", "allow");
|
|
312
|
+
const { btn: e } = this.button(this.ctx.i18n.airplayButton, "airplay", () => {
|
|
313
|
+
var s;
|
|
314
|
+
if (this.ctx.isMse()) {
|
|
315
|
+
this.ctx.log({ message: 'AirPlay: this source plays through hls.js (MSE) — use hls.engine: "auto" / "native" on Safari for AirPlay' });
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
(s = t.webkitShowPlaybackTargetPicker) == null || s.call(t);
|
|
319
|
+
});
|
|
320
|
+
e.setAttribute("part", "airplay-button"), this.airplayBtn = e, t.addEventListener("webkitplaybacktargetavailabilitychanged", ((s) => {
|
|
321
|
+
const i = s.availability === "available";
|
|
322
|
+
e.hidden = !i || !this.options.airplay, this.airplayActive || this.emit(i ? "available" : "unavailable", "airplay");
|
|
323
|
+
})), t.addEventListener("webkitcurrentplaybacktargetiswirelesschanged", () => {
|
|
324
|
+
const s = !!t.webkitCurrentPlaybackTargetIsWireless;
|
|
325
|
+
s !== this.airplayActive && (this.airplayActive = s, e.setAttribute("aria-pressed", String(s)), s ? this.showOverlay(this.ctx.i18n.airplayPlaying) : this.hideOverlay(), this.emit(s ? "connected" : "disconnected", "airplay"));
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
// ── Remote Playback API ─────────────────────────────────────────────────
|
|
329
|
+
initRemotePlayback() {
|
|
330
|
+
const t = this.ctx.videoEl, e = t.remote;
|
|
331
|
+
if (this.remoteBtn || !e) return;
|
|
332
|
+
t.disableRemotePlayback = !1;
|
|
333
|
+
const { btn: s } = this.button(this.ctx.i18n.castButton, "cast", () => {
|
|
334
|
+
if (this.ctx.isMse()) {
|
|
335
|
+
this.ctx.log({ message: "Remote playback: hls.js (MSE) sources cannot be sent to the device" });
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
e.prompt().catch((i) => this.ctx.log({ message: `Remote playback: ${String(i)}` }));
|
|
339
|
+
});
|
|
340
|
+
s.setAttribute("part", "remote-playback-button"), this.remoteBtn = s, e.watchAvailability((i) => {
|
|
341
|
+
s.hidden = !i || this.ctx.isMse() || !!(this.castBtn && !this.castBtn.hidden), e.state === "disconnected" && this.emit(i ? "available" : "unavailable", "remote");
|
|
342
|
+
}).then((i) => this.remoteWatchId = i).catch(() => s.hidden = !0), e.addEventListener("connecting", () => this.emit("connecting", "remote")), e.addEventListener("connect", () => {
|
|
343
|
+
s.setAttribute("aria-pressed", "true"), this.showOverlay(this.ctx.i18n.castPlayingOn.replace("{device}", this.ctx.i18n.castDeviceFallback)), this.emit("connected", "remote");
|
|
344
|
+
}), e.addEventListener("disconnect", () => {
|
|
345
|
+
s.setAttribute("aria-pressed", "false"), this.hideOverlay(), this.emit("disconnected", "remote");
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
// ── "TV'de oynatılıyor" katmanı ─────────────────────────────────────────
|
|
349
|
+
showOverlay(t) {
|
|
350
|
+
if (!this.overlay) {
|
|
351
|
+
const e = document.createElement("div");
|
|
352
|
+
e.className = "hp-cast-overlay", e.setAttribute("part", "cast-overlay"), e.setAttribute("role", "status");
|
|
353
|
+
const s = document.createElement("i");
|
|
354
|
+
s.className = "hp-icon hp-icon-cast-connected", s.setAttribute("aria-hidden", "true");
|
|
355
|
+
const i = document.createElement("span");
|
|
356
|
+
i.className = "hp-cast-overlay-text";
|
|
357
|
+
const a = document.createElement("span");
|
|
358
|
+
a.className = "hp-cast-overlay-ad", e.append(s, i, a), this.ctx.overlayEl.appendChild(e), this.overlay = e;
|
|
359
|
+
}
|
|
360
|
+
this.overlay.querySelector(".hp-cast-overlay-text").textContent = t, this.overlay.querySelector(".hp-cast-overlay-ad").textContent = this.ctx.i18n.castAdOnTv, this.overlay.removeAttribute("data-break"), this.overlay.setAttribute("data-open", ""), this.ctx.overlayEl.setAttribute("data-casting", "");
|
|
361
|
+
}
|
|
362
|
+
hideOverlay() {
|
|
363
|
+
var t;
|
|
364
|
+
(t = this.overlay) == null || t.removeAttribute("data-open"), this.ctx.overlayEl.removeAttribute("data-casting");
|
|
365
|
+
}
|
|
366
|
+
refreshLabels() {
|
|
367
|
+
var t, e, s;
|
|
368
|
+
(t = this.castBtn) == null || t.setAttribute("aria-label", this.ctx.i18n.castButton), (e = this.airplayBtn) == null || e.setAttribute("aria-label", this.ctx.i18n.airplayButton), (s = this.remoteBtn) == null || s.setAttribute("aria-label", this.ctx.i18n.castButton);
|
|
369
|
+
}
|
|
370
|
+
destroy() {
|
|
371
|
+
var t, e, s, i, a;
|
|
372
|
+
if (this.destroyed = !0, m === this && this.detach(), y === this && (y = null), this.context && this.api) {
|
|
373
|
+
const n = this.api.framework.CastContextEventType;
|
|
374
|
+
this.context.removeEventListener(n.CAST_STATE_CHANGED, this.onCastState), this.context.removeEventListener(n.SESSION_STATE_CHANGED, this.onSessionState);
|
|
375
|
+
}
|
|
376
|
+
this.remoteWatchId !== null && ((t = this.ctx.videoEl.remote) == null || t.cancelWatchAvailability(this.remoteWatchId).catch(() => {
|
|
377
|
+
})), (e = this.castBtn) == null || e.remove(), (s = this.airplayBtn) == null || s.remove(), (i = this.remoteBtn) == null || i.remove(), (a = this.overlay) == null || a.remove();
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
function D(l, t) {
|
|
381
|
+
return new L(l, t);
|
|
382
|
+
}
|
|
383
|
+
export {
|
|
384
|
+
L as CastController,
|
|
385
|
+
D as installCast
|
|
386
|
+
};
|
|
387
|
+
//# sourceMappingURL=index-Miba3PD_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-Miba3PD_.js","sources":["../../src/plugins/cast/castSdk.ts","../../src/plugins/cast/RemoteMediaProxy.ts","../../src/plugins/cast/CastController.ts","../../src/plugins/cast/index.ts"],"sourcesContent":["/**\n * Google Cast Web Sender SDK (CAF) — kullanılan yüzeyin minimal tipleri ve yükleyicisi.\n * https://developers.google.com/cast/docs/web_sender\n */\n\nexport interface CastImage {\n url: string;\n}\n\nexport interface CastMediaMetadata {\n metadataType?: number;\n title?: string;\n subtitle?: string;\n artist?: string;\n albumName?: string;\n images?: CastImage[];\n}\n\nexport interface CastTrack {\n trackContentId?: string;\n trackContentType?: string;\n subtype?: string;\n name?: string;\n language?: string;\n}\n\nexport interface CastVastAdsRequest {\n adTagUrl?: string;\n}\n\nexport interface CastBreakClip {\n vastAdsRequest?: CastVastAdsRequest;\n}\n\nexport interface CastMediaInfo {\n contentId: string;\n contentType: string;\n streamType?: string;\n metadata?: CastMediaMetadata;\n tracks?: CastTrack[];\n hlsSegmentFormat?: string;\n hlsVideoSegmentFormat?: string;\n vmapAdsRequest?: CastVastAdsRequest;\n breakClips?: CastBreakClip[];\n breaks?: unknown[];\n}\n\nexport interface CastLoadRequest {\n currentTime?: number;\n autoplay?: boolean;\n activeTrackIds?: number[];\n}\n\nexport interface CastSessionLike {\n loadMedia(request: CastLoadRequest): Promise<unknown>;\n getCastDevice(): { friendlyName?: string };\n getMediaSession(): { media?: { contentId?: string } } | null;\n}\n\nexport interface RemotePlayerLike {\n isConnected: boolean;\n isMediaLoaded: boolean;\n isPaused: boolean;\n currentTime: number;\n duration: number;\n volumeLevel: number;\n isMuted: boolean;\n playerState: string | null;\n isPlayingBreak: boolean;\n}\n\nexport interface RemotePlayerControllerLike {\n addEventListener(type: string, fn: (e: { field: string; value: unknown }) => void): void;\n removeEventListener(type: string, fn: (e: { field: string; value: unknown }) => void): void;\n playOrPause(): void;\n seek(): void;\n setVolumeLevel(): void;\n muteOrUnmute(): void;\n stop(): void;\n}\n\nexport interface CastContextLike {\n setOptions(options: Record<string, unknown>): void;\n addEventListener(type: string, fn: (e: { castState?: string; sessionState?: string; session?: CastSessionLike }) => void): void;\n removeEventListener(type: string, fn: (e: { castState?: string; sessionState?: string; session?: CastSessionLike }) => void): void;\n requestSession(): Promise<unknown>;\n getCurrentSession(): CastSessionLike | null;\n getCastState(): string;\n endCurrentSession(stopCasting: boolean): void;\n}\n\ntype Ctor<T> = new (...args: never[]) => T;\n\n/** `window.cast.framework` + `window.chrome.cast` — yalnızca kullandıklarımız. */\nexport interface CastApi {\n framework: {\n CastContext: { getInstance(): CastContextLike };\n CastContextEventType: { CAST_STATE_CHANGED: string; SESSION_STATE_CHANGED: string };\n RemotePlayer: Ctor<RemotePlayerLike>;\n RemotePlayerController: new (player: RemotePlayerLike) => RemotePlayerControllerLike;\n RemotePlayerEventType: { ANY_CHANGE: string };\n };\n chrome: {\n AutoJoinPolicy: { ORIGIN_SCOPED: string };\n media: {\n DEFAULT_MEDIA_RECEIVER_APP_ID: string;\n MediaInfo: new (contentId: string, contentType: string) => CastMediaInfo;\n GenericMediaMetadata: Ctor<CastMediaMetadata>;\n MusicTrackMediaMetadata: Ctor<CastMediaMetadata>;\n LoadRequest: new (media: CastMediaInfo) => CastLoadRequest;\n Track: new (trackId: number, type: string) => CastTrack;\n TrackType: { TEXT: string };\n TextTrackType: { SUBTITLES: string };\n StreamType: { BUFFERED: string; LIVE: string };\n VastAdsRequest: Ctor<CastVastAdsRequest>;\n BreakClip: new (id: string) => CastBreakClip;\n Break: new (id: string, breakClipIds: string[], position: number) => unknown;\n HlsSegmentFormat?: { TS: string; FMP4: string; AAC: string };\n HlsVideoSegmentFormat?: { MPEG2_TS: string; FMP4: string };\n };\n Image: new (url: string) => CastImage;\n };\n}\n\nconst CAST_SDK_SRC = 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1';\nconst LOAD_TIMEOUT_MS = 10_000;\nlet loading: Promise<CastApi | null> | null = null;\n\nfunction current(): CastApi | null {\n const w = window as unknown as { cast?: { framework?: CastApi['framework'] }; chrome?: { cast?: CastApi['chrome'] } };\n return w.cast?.framework && w.chrome?.cast ? { framework: w.cast.framework, chrome: w.chrome.cast } : null;\n}\n\n/**\n * Cast SDK'yı bir kez yükler. Yalnızca Chromium tarayıcılarda (Chrome / Edge) ve güvenli bağlamda (HTTPS) denenir;\n * diğerlerinde ya da SDK \"Cast yok\" derse null — buton hiç görünmez.\n */\nexport function loadCastSdk(): Promise<CastApi | null> {\n if (loading) return loading;\n const w = window as unknown as { chrome?: unknown; __onGCastApiAvailable?: (available: boolean, reason?: string) => void };\n if (current()) return (loading = Promise.resolve(current()));\n if (!w.chrome || !window.isSecureContext) return (loading = Promise.resolve(null));\n loading = new Promise<CastApi | null>((resolve) => {\n const previous = w.__onGCastApiAvailable;\n const timer = setTimeout(() => resolve(null), LOAD_TIMEOUT_MS);\n // SDK hazır olunca bu global geri çağrıyı çağırır — sayfa kendi kurduysa onu da çağır.\n w.__onGCastApiAvailable = (available, reason) => {\n previous?.(available, reason);\n clearTimeout(timer);\n resolve(available ? current() : null);\n };\n if (!document.querySelector('script[src*=\"cast_sender.js\"]')) {\n const s = document.createElement('script');\n s.async = true;\n s.src = CAST_SDK_SRC;\n s.onerror = () => {\n clearTimeout(timer);\n loading = null;\n resolve(null);\n };\n document.head.appendChild(s);\n }\n });\n return loading;\n}\n","/** Uzak oynatıcıya (TV) giden komutlar. */\nexport interface RemoteCommands {\n play(): void;\n pause(): void;\n seek(time: number): void;\n setVolume(volume: number): void;\n setMuted(muted: boolean): void;\n}\n\nexport interface RemoteState {\n paused: boolean;\n currentTime: number;\n duration: number;\n volume: number;\n muted: boolean;\n ended: boolean;\n}\n\nconst PROXIED = ['paused', 'currentTime', 'duration', 'ended', 'volume', 'muted', 'readyState', 'seeking', 'buffered', 'play', 'pause'] as const;\nconst EMPTY_RANGES: TimeRanges = {\n length: 0,\n start: () => {\n throw new DOMException('Index out of range', 'IndexSizeError');\n },\n end: () => {\n throw new DOMException('Index out of range', 'IndexSizeError');\n },\n};\n/** Seek bar sürüklenirken her harekette TV'ye istek gitmesin. */\nconst SEEK_DEBOUNCE_MS = 150;\n\n/** <video>'nun gerçek (prototip) değeri — vekil kuruluyken de. */\nexport function nativeGet<K extends 'currentTime' | 'duration' | 'paused' | 'ended'>(video: HTMLVideoElement, key: K): HTMLMediaElement[K] {\n const d = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, key);\n return d!.get!.call(video) as HTMLMediaElement[K];\n}\n\n/**\n * Cast sırasında `<video>` örneğinin oynatma yüzeyini (paused, currentTime, play(), volume…) TV'ye bağlar ve TV'den\n * gelen durumu olay olarak (play / pause / timeupdate / volumechange…) yayar. Böylece kontrol çubuğu, seek bar,\n * klavye kısayolları ve eklentiler hiç değişmeden TV'yi yönetir. Kaldırılınca örnek özellikleri silinir, prototip\n * (gerçek video) geri gelir.\n */\nexport class RemoteMediaProxy {\n private state: RemoteState;\n private pendingSeek: number | null = null;\n private seekTimer: ReturnType<typeof setTimeout> | null = null;\n private installed = false;\n\n constructor(\n private readonly video: HTMLVideoElement,\n private readonly commands: RemoteCommands,\n initial: RemoteState\n ) {\n this.state = { ...initial };\n }\n\n get current(): Readonly<RemoteState> {\n return this.state;\n }\n\n install(): void {\n if (this.installed) return;\n this.installed = true;\n const v = this.video;\n const s = (): RemoteState => this.state;\n const define = (key: string, desc: PropertyDescriptor): void => {\n Object.defineProperty(v, key, { configurable: true, enumerable: false, ...desc });\n };\n define('paused', { get: () => s().paused });\n define('ended', { get: () => s().ended });\n define('duration', { get: () => s().duration });\n define('readyState', { get: () => 4 });\n define('seeking', { get: () => this.pendingSeek !== null });\n define('buffered', { get: () => EMPTY_RANGES });\n define('currentTime', {\n get: () => this.pendingSeek ?? s().currentTime,\n set: (t: number) => this.seek(t),\n });\n define('volume', {\n get: () => s().volume,\n set: (vol: number) => {\n const clamped = Math.min(1, Math.max(0, Number(vol) || 0));\n this.state.volume = clamped;\n this.commands.setVolume(clamped);\n this.fire('volumechange');\n },\n });\n define('muted', {\n get: () => s().muted,\n set: (m: boolean) => {\n this.state.muted = !!m;\n this.commands.setMuted(!!m);\n this.fire('volumechange');\n },\n });\n define('play', {\n value: () => {\n if (this.state.ended) this.seek(0);\n this.commands.play();\n return Promise.resolve();\n },\n });\n define('pause', { value: () => this.commands.pause() });\n }\n\n uninstall(): void {\n if (!this.installed) return;\n this.installed = false;\n if (this.seekTimer) clearTimeout(this.seekTimer);\n this.seekTimer = null;\n this.pendingSeek = null;\n for (const key of PROXIED) delete (this.video as unknown as Record<string, unknown>)[key];\n }\n\n /** TV'den gelen durum — değişen alanlar için olay yayar. */\n update(patch: Partial<RemoteState>): void {\n const prev = this.state;\n this.state = { ...prev, ...patch };\n const next = this.state;\n if (patch.duration !== undefined && patch.duration !== prev.duration) this.fire('durationchange');\n if (patch.currentTime !== undefined && patch.currentTime !== prev.currentTime && this.pendingSeek === null) this.fire('timeupdate');\n if (patch.volume !== undefined || patch.muted !== undefined) {\n if (next.volume !== prev.volume || next.muted !== prev.muted) this.fire('volumechange');\n }\n if (patch.paused !== undefined && patch.paused !== prev.paused) {\n if (next.paused) this.fire('pause');\n else {\n this.fire('play');\n this.fire('playing');\n }\n }\n if (patch.ended && !prev.ended) this.fire('ended');\n }\n\n private seek(t: number): void {\n const target = Math.max(0, Number(t) || 0);\n const first = this.pendingSeek === null;\n this.pendingSeek = target;\n if (first) this.fire('seeking');\n this.fire('timeupdate');\n if (this.seekTimer) clearTimeout(this.seekTimer);\n this.seekTimer = setTimeout(() => {\n this.seekTimer = null;\n const to = this.pendingSeek ?? target;\n this.commands.seek(to);\n this.state = { ...this.state, currentTime: to, ended: false };\n this.pendingSeek = null;\n this.fire('seeked');\n this.fire('timeupdate');\n }, SEEK_DEBOUNCE_MS);\n }\n\n private fire(type: string): void {\n this.video.dispatchEvent(new Event(type));\n }\n}\n","import type { CastOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { setIconName } from '../../icons/Icon';\nimport { loadCastSdk, type CastApi, type CastContextLike, type CastMediaInfo, type CastSessionLike, type RemotePlayerControllerLike, type RemotePlayerLike } from './castSdk';\nimport { RemoteMediaProxy, nativeGet } from './RemoteMediaProxy';\n\n/** TV'ye gönderilecek içerik — player o anki duruma göre hazırlar. */\nexport interface CastMedia {\n src: string;\n contentType: string;\n live: boolean;\n title?: string;\n subtitle?: string;\n image?: string;\n /** Ses modu: TV'de müzik parçası olarak (kapak, sanatçı). */\n music: boolean;\n subtitles: Array<{ src: string; label: string; lang: string; default?: boolean }>;\n /** TV'de oynatılacak reklamlar (makroları doldurulmuş tag'ler); null = reklamsız. */\n ads: { vmap?: string; preroll?: string; midroll?: string; midrollIntervalSeconds?: number; postroll?: string } | null;\n}\n\nexport interface CastPlayerContext {\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n overlayEl: HTMLElement;\n i18n: HopeLocaleStrings;\n log(entry: { message: string; fatal?: boolean; details?: Record<string, string | number | boolean | undefined> }): void;\n addButton(label: string, icon: string, onClick: () => void): { btn: HTMLButtonElement; icon: HTMLElement };\n getMedia(): CastMedia | null;\n /** Yerelde video reklamı oynuyor — bu sırada yayın başlatılmaz. */\n isAdPlaying(): boolean;\n /** hls.js (MSE) ile oynatılıyor — AirPlay / Remote Playback bu kaynağı TV'ye veremez. */\n isMse(): boolean;\n /** İçerik kimliği — kalite / yedek kaynak değişimi aynı içerik sayılır (TV'de konum korunur). */\n contentKey(): string;\n /** İçerik TV'de mi (Chromecast) — player yerel reklamları askıya alır, otomatik oynatmayı keser. */\n onRemoteChange(remote: boolean): void;\n}\n\ntype Via = 'chromecast' | 'airplay' | 'remote';\ntype CastState = 'available' | 'unavailable' | 'connecting' | 'connected' | 'disconnected';\n\n/** Aynı sayfada birden çok player: Cast oturumu, butonuna basılan player'ındır. */\nlet requester: CastController | null = null;\nlet owner: CastController | null = null;\n/** Midroll aralığından üretilecek en fazla ara. */\nconst MAX_INTERVAL_BREAKS = 20;\nconst MIDROLL_END_MARGIN_S = 5;\n\n/**\n * TV'ye yayın: Google Cast (Chromecast / Google TV), AirPlay ve Remote Playback API. Her biri ayrı ayrı açılır;\n * butonlar yalnızca uygun cihaz varken görünür. Chromecast'te içerik TV'de oynar, player kumandaya dönüşür\n * (RemoteMediaProxy); bağlantı bitince yerelde TV'deki saniyeden devam eder.\n */\nexport class CastController {\n private options: CastOptions;\n private api: CastApi | null = null;\n private context: CastContextLike | null = null;\n private session: CastSessionLike | null = null;\n private player: RemotePlayerLike | null = null;\n private controller: RemotePlayerControllerLike | null = null;\n private proxy: RemoteMediaProxy | null = null;\n private castBtn: HTMLButtonElement | null = null;\n private castIcon: HTMLElement | null = null;\n private airplayBtn: HTMLButtonElement | null = null;\n private remoteBtn: HTMLButtonElement | null = null;\n private overlay: HTMLDivElement | null = null;\n private loadedSrc = '';\n private loadedContent = '';\n private savedAutoplay = false;\n private airplayActive = false;\n private destroyed = false;\n private remoteWatchId: number | null = null;\n\n constructor(\n private readonly ctx: CastPlayerContext,\n options: CastOptions\n ) {\n this.options = options;\n if (options.chromecast) void this.initChromecast();\n if (options.airplay) this.initAirPlay();\n if (options.remotePlayback) this.initRemotePlayback();\n }\n\n update(options: CastOptions): void {\n const prev = this.options;\n this.options = options;\n if (options.chromecast && !prev.chromecast) void this.initChromecast();\n if (options.airplay && !prev.airplay) this.initAirPlay();\n if (options.remotePlayback && !prev.remotePlayback) this.initRemotePlayback();\n if (this.castBtn) this.castBtn.hidden = !options.chromecast || this.castBtn.hidden;\n if (this.airplayBtn && !options.airplay) this.airplayBtn.hidden = true;\n if (this.remoteBtn && !options.remotePlayback) this.remoteBtn.hidden = true;\n }\n\n /** İçerik şu an TV'de mi (herhangi bir yoldan). */\n get casting(): boolean {\n return !!this.proxy || this.airplayActive || this.ctx.videoEl.remote?.state === 'connected';\n }\n\n private emit(state: CastState, via: Via, device?: string): void {\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:cast', { detail: { state, via, device } }));\n }\n\n private button(label: string, icon: string, onClick: () => void): { btn: HTMLButtonElement; icon: HTMLElement } {\n const b = this.ctx.addButton(label, icon, onClick);\n b.btn.hidden = true;\n return b;\n }\n\n // ── Google Cast ─────────────────────────────────────────────────────────\n\n private async initChromecast(): Promise<void> {\n if (this.castBtn) return;\n const { btn, icon } = this.button(this.ctx.i18n.castButton, 'cast', () => this.requestCast());\n btn.setAttribute('part', 'cast-button');\n this.castBtn = btn;\n this.castIcon = icon;\n const api = await loadCastSdk();\n if (!api || this.destroyed) {\n if (!api) this.ctx.log({ message: 'Google Cast is not available in this browser (Chrome / Edge over HTTPS needed)' });\n return;\n }\n this.api = api;\n const context = api.framework.CastContext.getInstance();\n this.context = context;\n context.setOptions({\n receiverApplicationId: this.options.receiverAppId || api.chrome.media.DEFAULT_MEDIA_RECEIVER_APP_ID,\n autoJoinPolicy: api.chrome.AutoJoinPolicy.ORIGIN_SCOPED,\n });\n const types = api.framework.CastContextEventType;\n context.addEventListener(types.CAST_STATE_CHANGED, this.onCastState);\n context.addEventListener(types.SESSION_STATE_CHANGED, this.onSessionState);\n this.onCastState({ castState: context.getCastState() });\n // Sayfa yenilendi ve oturum sürüyor (TV aynı içeriği oynatıyor) → kumandayı yeniden bağla.\n const existing = context.getCurrentSession();\n if (existing && !owner) this.tryResume(existing);\n }\n\n private readonly onCastState = (e: { castState?: string }): void => {\n const state = e.castState ?? 'NO_DEVICES_AVAILABLE';\n if (this.castBtn) this.castBtn.hidden = state === 'NO_DEVICES_AVAILABLE';\n this.castBtn?.toggleAttribute('data-connecting', state === 'CONNECTING');\n if (!this.proxy) this.emit(state === 'NO_DEVICES_AVAILABLE' ? 'unavailable' : state === 'CONNECTING' ? 'connecting' : 'available', 'chromecast');\n };\n\n private readonly onSessionState = (e: { sessionState?: string; session?: CastSessionLike }): void => {\n const s = e.sessionState;\n if ((s === 'SESSION_STARTED' || s === 'SESSION_RESUMED') && e.session) {\n if (requester === this) {\n requester = null;\n void this.attach(e.session, true);\n } else if (s === 'SESSION_RESUMED' && !owner) {\n this.tryResume(e.session);\n }\n } else if (s === 'SESSION_ENDED' || s === 'SESSION_START_FAILED') {\n if (requester === this) requester = null;\n if (owner === this) this.detach();\n }\n };\n\n private requestCast(): void {\n if (!this.context) return;\n if (this.ctx.isAdPlaying()) {\n this.ctx.log({ message: 'Cast: wait for the ad to finish' });\n return;\n }\n requester = this;\n // Bağlıyken Chrome'un seçicisi \"yayını durdur\"u da sunar.\n this.context.requestSession().catch((err: unknown) => {\n if (requester === this) requester = null;\n // Kullanıcı seçiciyi kapattı ('cancel') — hata değil.\n if (String(err) !== 'cancel') this.ctx.log({ message: `Cast session failed: ${String(err)}` });\n });\n }\n\n private tryResume(session: CastSessionLike): void {\n const media = this.ctx.getMedia();\n const remoteId = session.getMediaSession()?.media?.contentId;\n if (media && remoteId && remoteId === media.src) void this.attach(session, false);\n }\n\n private async attach(session: CastSessionLike, load: boolean): Promise<void> {\n const api = this.api;\n if (!api || this.destroyed) return;\n if (owner && owner !== this) owner.detach();\n owner = this;\n this.session = session;\n const v = this.ctx.videoEl;\n const startAt = nativeGet(v, 'currentTime');\n const duration = nativeGet(v, 'duration');\n HTMLMediaElement.prototype.pause.call(v);\n // Cast sırasında kaynak değişirse (playlist / kalite) yerel video kendiliğinden çalmasın.\n this.savedAutoplay = v.autoplay;\n v.autoplay = false;\n\n const player = new api.framework.RemotePlayer();\n const controller = new api.framework.RemotePlayerController(player);\n this.player = player;\n this.controller = controller;\n this.proxy = new RemoteMediaProxy(\n v,\n {\n play: () => player.isPaused && controller.playOrPause(),\n pause: () => !player.isPaused && controller.playOrPause(),\n seek: (t) => {\n player.currentTime = t;\n controller.seek();\n },\n setVolume: (vol) => {\n player.volumeLevel = vol;\n controller.setVolumeLevel();\n },\n setMuted: (m) => player.isMuted !== m && controller.muteOrUnmute(),\n },\n { paused: false, currentTime: startAt, duration, volume: v.volume, muted: v.muted, ended: false }\n );\n this.proxy.install();\n controller.addEventListener(api.framework.RemotePlayerEventType.ANY_CHANGE, this.onRemoteChange);\n v.addEventListener('loadstart', this.onLocalSourceChange);\n this.ctx.onRemoteChange(true);\n const device = session.getCastDevice()?.friendlyName || this.ctx.i18n.castDeviceFallback;\n this.showOverlay(this.ctx.i18n.castPlayingOn.replace('{device}', device));\n this.castBtn?.setAttribute('aria-pressed', 'true');\n if (this.castIcon) setIconName(this.castIcon, 'cast-connected');\n this.emit('connected', 'chromecast', device);\n if (load) await this.loadMedia(startAt, true);\n else {\n this.loadedSrc = session.getMediaSession()?.media?.contentId ?? '';\n this.loadedContent = this.ctx.contentKey();\n }\n }\n\n /** O an çalan içeriği TV'ye yükler (reklam araları ve altyazılarla). */\n private async loadMedia(currentTime: number, autoplay: boolean): Promise<void> {\n const api = this.api;\n const session = this.session;\n const media = this.ctx.getMedia();\n if (!api || !session || !media) {\n this.ctx.log({ message: 'Cast: nothing to send (no playable source)' });\n return;\n }\n const m = api.chrome.media;\n const info: CastMediaInfo = new m.MediaInfo(media.src, media.contentType);\n info.streamType = media.live ? m.StreamType.LIVE : m.StreamType.BUFFERED;\n const md = media.music ? new m.MusicTrackMediaMetadata() : new m.GenericMediaMetadata();\n md.title = media.title;\n if (media.music) md.artist = media.subtitle;\n else md.subtitle = media.subtitle;\n if (media.image) md.images = [new api.chrome.Image(media.image)];\n info.metadata = md;\n if (/mpegurl/i.test(media.contentType) && this.options.hlsSegmentFormat === 'fmp4') {\n if (m.HlsSegmentFormat) info.hlsSegmentFormat = m.HlsSegmentFormat.FMP4;\n if (m.HlsVideoSegmentFormat) info.hlsVideoSegmentFormat = m.HlsVideoSegmentFormat.FMP4;\n }\n const activeTrackIds: number[] = [];\n info.tracks = media.subtitles.map((s, i) => {\n const t = new m.Track(i + 1, m.TrackType.TEXT);\n t.trackContentId = s.src;\n t.trackContentType = 'text/vtt';\n t.subtype = m.TextTrackType.SUBTITLES;\n t.name = s.label;\n t.language = s.lang;\n if (s.default) activeTrackIds.push(i + 1);\n return t;\n });\n this.applyAds(info, media);\n const req = new m.LoadRequest(info);\n req.currentTime = media.live ? undefined : currentTime;\n req.autoplay = autoplay;\n if (activeTrackIds.length) req.activeTrackIds = activeTrackIds;\n this.loadedSrc = media.src;\n this.loadedContent = this.ctx.contentKey();\n try {\n await session.loadMedia(req);\n this.ctx.log({ message: 'Cast: media loaded on the TV', details: { src: media.src, ads: media.ads ? (media.ads.vmap ? 'vmap' : 'vast') : 'none' } });\n } catch (err) {\n this.ctx.log({ message: `Cast: the TV could not load the media: ${String(err)}`, fatal: true, details: { src: media.src } });\n }\n }\n\n /**\n * Reklamlar TV'de: VMAP verilmişse receiver tüm araları kendisi planlar (vmapAdsRequest); yoksa VAST tag'leri\n * ara olarak eklenir — preroll (0), aralıklı midroll'lar, postroll (-1). Reklamları receiver oynatır ve sayar.\n */\n private applyAds(info: CastMediaInfo, media: CastMedia): void {\n const ads = media.ads;\n const m = this.api!.chrome.media;\n if (!ads) return;\n if (ads.vmap) {\n const req = new m.VastAdsRequest();\n req.adTagUrl = ads.vmap;\n info.vmapAdsRequest = req;\n return;\n }\n const clips: unknown[] = [];\n const breaks: unknown[] = [];\n const add = (id: string, tag: string, position: number): void => {\n const clip = new m.BreakClip(`clip-${id}`);\n const req = new m.VastAdsRequest();\n req.adTagUrl = tag;\n clip.vastAdsRequest = req;\n clips.push(clip);\n breaks.push(new m.Break(`break-${id}`, [`clip-${id}`], position));\n };\n if (ads.preroll) add('pre', ads.preroll, 0);\n const every = ads.midrollIntervalSeconds ?? 0;\n const duration = this.proxy?.current.duration ?? NaN;\n if (ads.midroll && every > 0 && !media.live && Number.isFinite(duration)) {\n // Bitişe çok yakın midroll olmasın (orada postroll var).\n for (let t = every, i = 1; t < duration - MIDROLL_END_MARGIN_S && i <= MAX_INTERVAL_BREAKS; t += every, i++) add(`mid-${i}`, ads.midroll, t);\n }\n if (ads.postroll && !media.live) add('post', ads.postroll, -1);\n if (clips.length) {\n info.breakClips = clips as CastMediaInfo['breakClips'];\n info.breaks = breaks;\n }\n }\n\n private readonly onRemoteChange = (e: { field: string; value: unknown }): void => {\n const p = this.player;\n const proxy = this.proxy;\n if (!p || !proxy) return;\n switch (e.field) {\n case 'isPaused':\n proxy.update({ paused: !!e.value });\n break;\n case 'currentTime':\n proxy.update({ currentTime: Number(e.value) || 0 });\n break;\n case 'duration':\n proxy.update({ duration: Number(e.value) > 0 ? Number(e.value) : proxy.current.duration });\n break;\n case 'volumeLevel':\n proxy.update({ volume: Number(e.value) });\n break;\n case 'isMuted':\n proxy.update({ muted: !!e.value });\n break;\n case 'playerState':\n // İçerik TV'de bitti (IDLE + daha önce oynuyordu) → ended.\n if (e.value === 'IDLE' && p.isMediaLoaded === false && proxy.current.currentTime > 0) proxy.update({ ended: true, paused: true });\n else if (e.value === 'PLAYING') proxy.update({ ended: false, paused: false });\n break;\n case 'isPlayingBreak':\n this.overlay?.toggleAttribute('data-break', !!e.value);\n break;\n case 'isConnected':\n if (!e.value && owner === this) this.detach();\n break;\n }\n };\n\n /** Cast sırasında player başka bir kaynağa geçti (playlist sonraki öğe, kalite, yedek kaynak) → TV'ye de gönder. */\n private readonly onLocalSourceChange = (): void => {\n if (!this.proxy) return;\n HTMLMediaElement.prototype.pause.call(this.ctx.videoEl);\n const media = this.ctx.getMedia();\n if (!media || media.src === this.loadedSrc) return;\n // Aynı içeriğin başka kalitesi / yedeği ise kaldığı yerden, yeni bir içerikse (playlist) baştan.\n const same = this.ctx.contentKey() === this.loadedContent;\n void this.loadMedia(same ? this.proxy.current.currentTime : 0, true);\n };\n\n private detach(): void {\n const proxy = this.proxy;\n if (!proxy) return;\n if (owner === this) owner = null;\n const { currentTime, paused, ended } = proxy.current;\n const v = this.ctx.videoEl;\n this.controller?.removeEventListener(this.api!.framework.RemotePlayerEventType.ANY_CHANGE, this.onRemoteChange);\n v.removeEventListener('loadstart', this.onLocalSourceChange);\n proxy.uninstall();\n this.proxy = null;\n this.player = null;\n this.controller = null;\n this.session = null;\n this.loadedSrc = '';\n v.autoplay = this.savedAutoplay;\n this.ctx.onRemoteChange(false);\n this.hideOverlay();\n this.castBtn?.setAttribute('aria-pressed', 'false');\n if (this.castIcon) setIconName(this.castIcon, 'cast');\n // TV'deki saniyeden yerelde devam (bittiyse olduğu yerde kalır).\n if (Number.isFinite(currentTime) && currentTime > 0 && !ended) v.currentTime = currentTime;\n if (!paused && !ended) void v.play().catch(() => {});\n this.emit('disconnected', 'chromecast');\n }\n\n // ── AirPlay (Safari) ────────────────────────────────────────────────────\n\n private initAirPlay(): void {\n if (this.airplayBtn || !('WebKitPlaybackTargetAvailabilityEvent' in window)) return;\n const v = this.ctx.videoEl as HTMLVideoElement & { webkitShowPlaybackTargetPicker?: () => void; webkitCurrentPlaybackTargetIsWireless?: boolean };\n v.setAttribute('x-webkit-airplay', 'allow');\n const { btn } = this.button(this.ctx.i18n.airplayButton, 'airplay', () => {\n if (this.ctx.isMse()) {\n this.ctx.log({ message: 'AirPlay: this source plays through hls.js (MSE) — use hls.engine: \"auto\" / \"native\" on Safari for AirPlay' });\n return;\n }\n v.webkitShowPlaybackTargetPicker?.();\n });\n btn.setAttribute('part', 'airplay-button');\n this.airplayBtn = btn;\n v.addEventListener('webkitplaybacktargetavailabilitychanged', ((e: Event & { availability?: string }) => {\n const available = e.availability === 'available';\n btn.hidden = !available || !this.options.airplay;\n if (!this.airplayActive) this.emit(available ? 'available' : 'unavailable', 'airplay');\n }) as EventListener);\n v.addEventListener('webkitcurrentplaybacktargetiswirelesschanged', () => {\n const on = !!v.webkitCurrentPlaybackTargetIsWireless;\n if (on === this.airplayActive) return;\n this.airplayActive = on;\n btn.setAttribute('aria-pressed', String(on));\n if (on) this.showOverlay(this.ctx.i18n.airplayPlaying);\n else this.hideOverlay();\n this.emit(on ? 'connected' : 'disconnected', 'airplay');\n });\n }\n\n // ── Remote Playback API ─────────────────────────────────────────────────\n\n private initRemotePlayback(): void {\n const v = this.ctx.videoEl;\n const remote = v.remote;\n if (this.remoteBtn || !remote) return;\n v.disableRemotePlayback = false;\n const { btn } = this.button(this.ctx.i18n.castButton, 'cast', () => {\n if (this.ctx.isMse()) {\n this.ctx.log({ message: 'Remote playback: hls.js (MSE) sources cannot be sent to the device' });\n return;\n }\n remote.prompt().catch((err: unknown) => this.ctx.log({ message: `Remote playback: ${String(err)}` }));\n });\n btn.setAttribute('part', 'remote-playback-button');\n this.remoteBtn = btn;\n remote\n .watchAvailability((available) => {\n // Google Cast butonu görünüyorsa aynı işi yapan ikinci butonu gösterme.\n btn.hidden = !available || this.ctx.isMse() || !!(this.castBtn && !this.castBtn.hidden);\n if (remote.state === 'disconnected') this.emit(available ? 'available' : 'unavailable', 'remote');\n })\n .then((id) => (this.remoteWatchId = id))\n .catch(() => (btn.hidden = true));\n remote.addEventListener('connecting', () => this.emit('connecting', 'remote'));\n remote.addEventListener('connect', () => {\n btn.setAttribute('aria-pressed', 'true');\n this.showOverlay(this.ctx.i18n.castPlayingOn.replace('{device}', this.ctx.i18n.castDeviceFallback));\n this.emit('connected', 'remote');\n });\n remote.addEventListener('disconnect', () => {\n btn.setAttribute('aria-pressed', 'false');\n this.hideOverlay();\n this.emit('disconnected', 'remote');\n });\n }\n\n // ── \"TV'de oynatılıyor\" katmanı ─────────────────────────────────────────\n\n private showOverlay(text: string): void {\n if (!this.overlay) {\n const el = document.createElement('div');\n el.className = 'hp-cast-overlay';\n el.setAttribute('part', 'cast-overlay');\n el.setAttribute('role', 'status');\n const icon = document.createElement('i');\n icon.className = 'hp-icon hp-icon-cast-connected';\n icon.setAttribute('aria-hidden', 'true');\n const label = document.createElement('span');\n label.className = 'hp-cast-overlay-text';\n const ad = document.createElement('span');\n ad.className = 'hp-cast-overlay-ad';\n el.append(icon, label, ad);\n this.ctx.overlayEl.appendChild(el);\n this.overlay = el;\n }\n this.overlay.querySelector('.hp-cast-overlay-text')!.textContent = text;\n this.overlay.querySelector('.hp-cast-overlay-ad')!.textContent = this.ctx.i18n.castAdOnTv;\n this.overlay.removeAttribute('data-break');\n this.overlay.setAttribute('data-open', '');\n this.ctx.overlayEl.setAttribute('data-casting', '');\n }\n\n private hideOverlay(): void {\n this.overlay?.removeAttribute('data-open');\n this.ctx.overlayEl.removeAttribute('data-casting');\n }\n\n refreshLabels(): void {\n this.castBtn?.setAttribute('aria-label', this.ctx.i18n.castButton);\n this.airplayBtn?.setAttribute('aria-label', this.ctx.i18n.airplayButton);\n this.remoteBtn?.setAttribute('aria-label', this.ctx.i18n.castButton);\n }\n\n destroy(): void {\n this.destroyed = true;\n if (owner === this) {\n // Player sayfadan kalkıyor: TV'deki yayın sürsün (Cast'in olağan davranışı), kumanda bağı kopsun.\n this.detach();\n }\n if (requester === this) requester = null;\n if (this.context && this.api) {\n const types = this.api.framework.CastContextEventType;\n this.context.removeEventListener(types.CAST_STATE_CHANGED, this.onCastState);\n this.context.removeEventListener(types.SESSION_STATE_CHANGED, this.onSessionState);\n }\n if (this.remoteWatchId !== null) void this.ctx.videoEl.remote?.cancelWatchAvailability(this.remoteWatchId).catch(() => {});\n this.castBtn?.remove();\n this.airplayBtn?.remove();\n this.remoteBtn?.remove();\n this.overlay?.remove();\n }\n}\n","import { CastController, type CastMedia, type CastPlayerContext } from './CastController';\nimport type { CastOptions } from '../../types';\n\n/** TV'ye yayını kurar (Google Cast / AirPlay / Remote Playback — her biri seçenekle açılır). */\nexport function installCast(ctx: CastPlayerContext, options: CastOptions): CastController {\n return new CastController(ctx, options);\n}\n\nexport { CastController };\nexport type { CastMedia, CastPlayerContext };\n"],"names":["CAST_SDK_SRC","LOAD_TIMEOUT_MS","loading","current","w","_a","_b","loadCastSdk","resolve","previous","timer","available","reason","s","PROXIED","EMPTY_RANGES","SEEK_DEBOUNCE_MS","nativeGet","video","key","RemoteMediaProxy","commands","initial","__publicField","v","define","desc","t","vol","clamped","m","patch","prev","next","target","first","to","type","requester","owner","MAX_INTERVAL_BREAKS","MIDROLL_END_MARGIN_S","CastController","ctx","options","e","state","p","proxy","media","same","via","device","label","icon","onClick","b","btn","api","context","types","existing","err","session","remoteId","load","startAt","duration","player","controller","setIconName","_d","_c","currentTime","autoplay","info","md","activeTrackIds","i","req","ads","clips","breaks","add","id","tag","position","clip","every","paused","ended","on","remote","text","el","ad","_e","installCast"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var u = Object.defineProperty;
|
|
2
2
|
var m = (p, e, t) => e in p ? u(p, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[e] = t;
|
|
3
3
|
var o = (p, e, t) => m(p, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import { c as b } from "./index-
|
|
4
|
+
import { c as b } from "./index-DEv3YqLg.js";
|
|
5
5
|
const f = {
|
|
6
6
|
enabled: !1,
|
|
7
7
|
mode: "rich",
|
|
@@ -202,4 +202,4 @@ export {
|
|
|
202
202
|
v as MarkProgress,
|
|
203
203
|
y as installMarkers
|
|
204
204
|
};
|
|
205
|
-
//# sourceMappingURL=index-
|
|
205
|
+
//# sourceMappingURL=index-e00_M05B.js.map
|