@hopeplayer/core 1.0.17 → 1.0.18

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 (62) hide show
  1. package/dist/HopePlayerElement.d.ts +2 -0
  2. package/dist/HopePlayerElement.d.ts.map +1 -1
  3. package/dist/chunks/{adTriggers-4SueRFgK.js → adTriggers-DXmtF4t2.js} +112 -117
  4. package/dist/chunks/adTriggers-DXmtF4t2.js.map +1 -0
  5. package/dist/chunks/{ads-DPL7m9PV.js → ads-MCG5a6eK.js} +2 -2
  6. package/dist/chunks/{ads-DPL7m9PV.js.map → ads-MCG5a6eK.js.map} +1 -1
  7. package/dist/chunks/{cast-DCAT2agI.js → cast-bMrkGGuD.js} +70 -66
  8. package/dist/chunks/cast-bMrkGGuD.js.map +1 -0
  9. package/dist/chunks/{markers-DE4O8xbw.js → markers-BhMJLPqj.js} +2 -2
  10. package/dist/chunks/{markers-DE4O8xbw.js.map → markers-BhMJLPqj.js.map} +1 -1
  11. package/dist/chunks/{player-C886oKP-.js → player-DW5iWvPs.js} +260 -229
  12. package/dist/chunks/player-DW5iWvPs.js.map +1 -0
  13. package/dist/chunks/{playlist-CI3mRZjo.js → playlist-DYGbJ5wz.js} +24 -24
  14. package/dist/chunks/playlist-DYGbJ5wz.js.map +1 -0
  15. package/dist/chunks/{qrResume-BNy8XCp_.js → qrResume-DXwD3oSA.js} +29 -30
  16. package/dist/chunks/{qrResume-BNy8XCp_.js.map → qrResume-DXwD3oSA.js.map} +1 -1
  17. package/dist/chunks/{redirectScreen-CJ3q9OX4.js → redirectScreen-CSjrS8Kg.js} +2 -2
  18. package/dist/chunks/{redirectScreen-CJ3q9OX4.js.map → redirectScreen-CSjrS8Kg.js.map} +1 -1
  19. package/dist/chunks/{rewardedUnlock-EyGMB9PK.js → rewardedUnlock-DZ_qPcDG.js} +2 -2
  20. package/dist/chunks/{rewardedUnlock-EyGMB9PK.js.map → rewardedUnlock-DZ_qPcDG.js.map} +1 -1
  21. package/dist/chunks/seekWhenReady-Clzne3-S.js +32 -0
  22. package/dist/chunks/seekWhenReady-Clzne3-S.js.map +1 -0
  23. package/dist/chunks/{segments-C2HKU6XK.js → segments-LsZPlbYi.js} +2 -2
  24. package/dist/chunks/{segments-C2HKU6XK.js.map → segments-LsZPlbYi.js.map} +1 -1
  25. package/dist/chunks/{sponsorship-DyFwGmEb.js → sponsorship-BT21uwN5.js} +36 -41
  26. package/dist/chunks/sponsorship-BT21uwN5.js.map +1 -0
  27. package/dist/chunks/{spriteThumbnails-D0NQ5CCp.js → spriteThumbnails-BQkEBRu-.js} +2 -2
  28. package/dist/chunks/{spriteThumbnails-D0NQ5CCp.js.map → spriteThumbnails-BQkEBRu-.js.map} +1 -1
  29. package/dist/chunks/{story-D5Got6-6.js → story-H6f7gSoX.js} +27 -15
  30. package/dist/chunks/story-H6f7gSoX.js.map +1 -0
  31. package/dist/chunks/trackingPixel-D2wxdCEz.js +20 -0
  32. package/dist/chunks/trackingPixel-D2wxdCEz.js.map +1 -0
  33. package/dist/controls/SeekBar.d.ts.map +1 -1
  34. package/dist/hls/SourceManager.d.ts.map +1 -1
  35. package/dist/hope-player.js +1 -1
  36. package/dist/keyboard/KeyboardController.d.ts.map +1 -1
  37. package/dist/plugins/ad-triggers/AdTriggers.d.ts.map +1 -1
  38. package/dist/plugins/cast/CastController.d.ts.map +1 -1
  39. package/dist/plugins/playlist/PlaylistRunner.d.ts.map +1 -1
  40. package/dist/plugins/qr-resume/QrResume.d.ts.map +1 -1
  41. package/dist/plugins/shared/seekWhenReady.d.ts +22 -0
  42. package/dist/plugins/shared/seekWhenReady.d.ts.map +1 -0
  43. package/dist/plugins/shared/trackingPixel.d.ts +8 -0
  44. package/dist/plugins/shared/trackingPixel.d.ts.map +1 -0
  45. package/dist/plugins/sponsorship/SponsorshipLayer.d.ts.map +1 -1
  46. package/dist/plugins/story/HopeStory.d.ts +2 -0
  47. package/dist/plugins/story/HopeStory.d.ts.map +1 -1
  48. package/dist/screens/ErrorScreen.d.ts +7 -0
  49. package/dist/screens/ErrorScreen.d.ts.map +1 -1
  50. package/dist/types/index.d.ts +2 -0
  51. package/dist/types/index.d.ts.map +1 -1
  52. package/dist/utils/media-error.d.ts +10 -0
  53. package/dist/utils/media-error.d.ts.map +1 -0
  54. package/dist/utils/seek-by.d.ts +8 -0
  55. package/dist/utils/seek-by.d.ts.map +1 -1
  56. package/package.json +2 -1
  57. package/dist/chunks/adTriggers-4SueRFgK.js.map +0 -1
  58. package/dist/chunks/cast-DCAT2agI.js.map +0 -1
  59. package/dist/chunks/player-C886oKP-.js.map +0 -1
  60. package/dist/chunks/playlist-CI3mRZjo.js.map +0 -1
  61. package/dist/chunks/sponsorship-DyFwGmEb.js.map +0 -1
  62. package/dist/chunks/story-D5Got6-6.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"adTriggers-4SueRFgK.js","sources":["../../src/plugins/ad-triggers/AdTriggers.ts","../../src/plugins/ad-triggers/index.ts"],"sourcesContent":["import type { AdTrigger, AdTriggerLayout, AdTriggerRule, AdTriggersConfig, AdTriggersOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { loadGpt, type GoogleTag, type GptSlot, type GptSlotRenderEndedEvent } from '../pause-ad/loadGpt';\n\nexport interface AdTriggersContext {\n /** Light DOM sahibi: GPT reklam div'ini id ile bulabilsin diye div buraya eklenir (tam ekranda da görünür). */\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n /** Reklam kutusunun ekleneceği alan (video alanı). */\n overlayEl: HTMLElement;\n i18n: HopeLocaleStrings;\n log(entry: { message: string; fatal?: boolean; details?: Record<string, string | number | boolean | undefined> }): void;\n /** Video reklamı (IMA) oynuyor ya da giriş ekranı (geri sayım / geo) açık — bu sırada istenmez. */\n isBlocked(): boolean;\n isFullscreen(): boolean;\n /** iPhone'un kendi video tam ekranı — player katmanları orada görünmez, reklam istenmez. */\n isNativeFullscreen(): boolean;\n /** İçerik kimliği — kalite değişimi / yedek kaynak aynı içerik sayılır; değişince sayaçlar sıfırlanır. */\n contentKey(): string;\n}\n\nconst DEFAULT_TIMEOUT_MS = 5000;\nconst DEFAULT_RENDER_TIMEOUT_MS = 8000;\nconst DEFAULT_GLOBAL_GAP_S = 30;\nconst LAYOUTS: AdTriggerLayout[] = ['none', 'full', 'center', 'top', 'bottom', 'top-left', 'top-right', 'bottom-left', 'bottom-right'];\nconst TRIGGER_TYPES = ['time', 'interval', 'percent', 'fullscreen', 'fullscreenExit', 'start', 'pause', 'resume', 'ended'] as const;\n/** Doğal ilerleme sayılan en büyük timeupdate adımı (sn) — daha büyük sıçrama ileri sarmadır, aradaki anlar atlanır. */\nconst MAX_NATURAL_STEP_S = 1.5;\nlet instanceCount = 0;\n\nfunction safeUrl(value: unknown): string | null {\n if (typeof value !== 'string' || !value.trim()) return null;\n try {\n const u = new URL(value, document.baseURI);\n return u.protocol === 'https:' || u.protocol === 'http:' ? u.href : null;\n } catch {\n return null;\n }\n}\n\nconst num = (n: unknown, min: number, max: number): number | undefined =>\n typeof n === 'number' && Number.isFinite(n) ? Math.min(max, Math.max(min, n)) : undefined;\n\ntype KeyValues = Record<string, string | string[]>;\nconst prim = (v: unknown): string | null =>\n typeof v === 'string' ? v.slice(0, 200) : typeof v === 'number' && Number.isFinite(v) ? String(v) : typeof v === 'boolean' ? String(v) : null;\n\n/**\n * Ad Manager key-value'ları (GPT slot hedeflemesi = VAST tag'lerindeki `cust_params`): JSON nesnesi\n * `{ \"kategori\": \"spor\", \"etiket\": [\"mac\", \"ozet\"], \"sezon\": 2026 }` ya da `\"kategori=spor&etiket=mac,ozet\"` metni.\n * Sayı / boolean metne çevrilir; geçersiz anahtar ve değerler atılır.\n */\nexport function parseCustParams(raw: unknown): KeyValues | undefined {\n let entries: Array<[string, unknown]>;\n if (typeof raw === 'string') {\n if (!raw.trim()) return undefined;\n entries = [...new URLSearchParams(raw.trim().replace(/^\\?/, '')).entries()].map(([k, v]) => [k, v.includes(',') ? v.split(',') : v]);\n } else if (raw && typeof raw === 'object' && !Array.isArray(raw)) {\n entries = Object.entries(raw as Record<string, unknown>);\n } else {\n return undefined;\n }\n const out: KeyValues = {};\n for (const [k, v] of entries.slice(0, 50)) {\n if (!/^[\\w.-]{1,40}$/.test(k)) continue;\n if (Array.isArray(v)) {\n const list = v.map(prim).filter((x): x is string => x !== null && x !== '').slice(0, 30);\n if (list.length) out[k] = list;\n } else {\n const one = prim(v);\n if (one !== null && one !== '') out[k] = one;\n }\n }\n return Object.keys(out).length ? out : undefined;\n}\n\nfunction normalizeTrigger(raw: unknown): AdTrigger | null {\n if (!raw || typeof raw !== 'object') return null;\n const t = raw as Record<string, unknown>;\n const type = t.type as (typeof TRIGGER_TYPES)[number];\n if (!TRIGGER_TYPES.includes(type)) return null;\n const list = (v: unknown, min: number, max: number): number[] =>\n (Array.isArray(v) ? v : [v]).map((x) => num(x, min, max)).filter((x): x is number => x !== undefined).slice(0, 50);\n if (type === 'time') {\n const at = list(t.at, 0, 86_400);\n return at.length ? { type, at } : null;\n }\n if (type === 'percent') {\n const at = list(t.at, 1, 99);\n return at.length ? { type, at } : null;\n }\n if (type === 'interval') {\n const every = num(t.every, 10, 86_400);\n return every ? { type, every, startAfter: num(t.startAfter, 0, 86_400) } : null;\n }\n return { type, delay: num(t.delay, 0, 600) };\n}\n\n/** API yanıtını doğrular, geçersiz kural/tetikleyicileri atar; modül kapalıysa ya da geçerli kural yoksa null. */\nexport function normalizeAdTriggers(raw: unknown): AdTriggersConfig | null {\n if (!raw || typeof raw !== 'object') return null;\n const r = raw as Partial<AdTriggersConfig>;\n if (r.active !== true || !Array.isArray(r.rules)) return null;\n const now = Date.now();\n const from = r.validFrom ? Date.parse(r.validFrom) : NaN;\n const until = r.validUntil ? Date.parse(r.validUntil) : NaN;\n if ((Number.isFinite(from) && now < from) || (Number.isFinite(until) && now > until)) return null;\n const urls = (list: unknown): string[] => (Array.isArray(list) ? list.map(safeUrl).filter((u): u is string => !!u).slice(0, 10) : []);\n const rules: AdTriggerRule[] = [];\n for (const raw of r.rules.slice(0, 20)) {\n if (!raw || typeof raw !== 'object') continue;\n const x = raw as Partial<AdTriggerRule>;\n // Reklam birimi yolu: \"/ağ kodu/birim/...\" biçimi.\n if (typeof x.adUnitPath !== 'string' || !/^\\/\\d+(?:[,/][\\w.\\-/]*)?$/.test(x.adUnitPath)) continue;\n const triggers = (Array.isArray(x.triggers) ? x.triggers : []).map(normalizeTrigger).filter((t): t is AdTrigger => !!t).slice(0, 20);\n if (!triggers.length) continue;\n const size = Array.isArray(x.size) && x.size.length === 2 ? [num(x.size[0], 1, 4000), num(x.size[1], 1, 4000)] : null;\n const layout = LAYOUTS.includes(x.layout as AdTriggerLayout) ? x.layout! : 'none';\n rules.push({\n id: typeof x.id === 'string' ? x.id.slice(0, 80) : undefined,\n adUnitPath: x.adUnitPath,\n mode: x.mode === 'fullscreen' || x.mode === 'normal' ? x.mode : 'any',\n triggers,\n targeting: parseCustParams(x.targeting),\n // API'lerde yaygın `cust_params` yazımı da kabul edilir.\n custParams: parseCustParams(x.custParams ?? (x as { cust_params?: unknown }).cust_params),\n layout,\n size: size && size[0] && size[1] ? [size[0], size[1]] : undefined,\n backdrop: typeof x.backdrop === 'boolean' ? x.backdrop : layout === 'full',\n pauseContent: x.pauseContent === true,\n closeButton: x.closeButton !== false,\n closeDelay: num(x.closeDelay, 0, 120) ?? 0,\n duration: num(x.duration, 1, 3600),\n label: x.label === false ? false : typeof x.label === 'string' ? x.label.slice(0, 40) : undefined,\n maxShows: num(x.maxShows, 1, 1000),\n minGapSeconds: num(x.minGapSeconds, 0, 86_400),\n minPlayerWidth: num(x.minPlayerWidth, 0, 4000),\n tracking: { impression: urls(x.tracking?.impression), close: urls(x.tracking?.close), empty: urls(x.tracking?.empty) },\n });\n }\n if (!rules.length) return null;\n return {\n active: true,\n id: typeof r.id === 'string' ? r.id.slice(0, 120) : undefined,\n minGapSeconds: num(r.minGapSeconds, 0, 86_400) ?? DEFAULT_GLOBAL_GAP_S,\n rules,\n };\n}\n\nfunction fire(urls: string[] | undefined): void {\n for (const u of urls ?? []) {\n const img = new Image();\n img.referrerPolicy = 'no-referrer-when-downgrade';\n img.src = u;\n }\n}\n\ntype TriggerType = AdTrigger['type'];\ntype CloseReason = 'user' | 'timeout' | 'mode' | 'ad' | 'content' | 'replaced';\n\ninterface Showing {\n rule: AdTriggerRule;\n trigger: TriggerType;\n box: HTMLDivElement;\n adHost: HTMLDivElement;\n slot: GptSlot | null;\n filled: boolean;\n pausedContent: boolean;\n timers: Array<ReturnType<typeof setTimeout>>;\n /** İsteğe giden key-value'ların son hali (olayda bildirilir). */\n custParams?: KeyValues;\n}\n\n/**\n * Reklam tetikleyici: kurallara göre Ad Manager out-of-page reklamı ister ve player içinde (tam ekranda da) gösterir.\n * Kurallar API'den (`endpoint`) ya da `config`'ten gelir; API hatasında son geçerli kurallar korunur.\n * Aynı anda tek reklam; video reklamı (IMA) oynarken, sekme arka plandayken ve iPhone native tam ekranında istenmez.\n */\nexport class AdTriggers {\n private options: AdTriggersOptions;\n private config: AdTriggersConfig | null = null;\n private loaded = false;\n private googletag: GoogleTag | null = null;\n private showing: Showing | null = null;\n private readonly instance = ++instanceCount;\n private seq = 0;\n private requestSeq = 0;\n private destroyed = false;\n private refreshTimer: ReturnType<typeof setInterval> | null = null;\n private readonly tickTimer: ReturnType<typeof setInterval>;\n /** Olaydan `delay` sn sonra çalışacak tetiklemeler — koşul bozulunca iptal edilir. */\n private delayed: Array<{ type: TriggerType; timer: ReturnType<typeof setTimeout> }> = [];\n // ── içerik başına durum (kaynak değişince sıfırlanır) ──\n private contentKey = '';\n private fired = new Set<string>();\n private shows = new Map<number, number>();\n private lastShownAt = new Map<number, number>();\n private lastAnyAt = 0;\n private watchedMs = 0;\n private lastTick = performance.now();\n private lastPos = 0;\n private started = false;\n private userPaused = false;\n /** Player'ın kendi duraklatması (pauseContent) — pause/resume kuralı sayılmaz. */\n private selfPause = false;\n private wasFullscreen = false;\n\n constructor(\n private readonly ctx: AdTriggersContext,\n options: AdTriggersOptions\n ) {\n this.options = options;\n const v = ctx.videoEl;\n v.addEventListener('timeupdate', this.onTimeUpdate);\n v.addEventListener('seeked', this.onSeeked);\n v.addEventListener('playing', this.onPlaying);\n v.addEventListener('pause', this.onPause);\n v.addEventListener('ended', this.onEnded);\n v.addEventListener('loadstart', this.onLoadStart);\n v.addEventListener('webkitbeginfullscreen', this.onFullscreenChange);\n v.addEventListener('webkitendfullscreen', this.onFullscreenChange);\n document.addEventListener('fullscreenchange', this.onFullscreenChange);\n document.addEventListener('webkitfullscreenchange', this.onFullscreenChange);\n ctx.hostEl.addEventListener('hp:adstart', this.onVideoAdStart);\n this.wasFullscreen = ctx.isFullscreen();\n this.contentKey = ctx.contentKey();\n this.tickTimer = setInterval(this.tick, 1000);\n void this.load();\n this.scheduleRefresh();\n }\n\n update(options: AdTriggersOptions): void {\n const changed =\n options.endpoint !== this.options.endpoint ||\n JSON.stringify(options.params) !== JSON.stringify(this.options.params) ||\n JSON.stringify(options.config) !== JSON.stringify(this.options.config);\n const refreshChanged = options.refreshSeconds !== this.options.refreshSeconds;\n this.options = options;\n if (changed) void this.load();\n if (refreshChanged) this.scheduleRefresh();\n }\n\n get current(): AdTriggersConfig | null {\n return this.config;\n }\n\n /** Şu an bir reklam gösteriliyor mu. */\n get active(): boolean {\n return !!this.showing?.filled;\n }\n\n // ── kurallar ──\n\n private scheduleRefresh(): void {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n this.refreshTimer = null;\n const s = this.options.refreshSeconds;\n if (this.options.endpoint && typeof s === 'number' && s >= 10) this.refreshTimer = setInterval(() => void this.load(), s * 1000);\n }\n\n private async load(): Promise<void> {\n const seq = ++this.requestSeq;\n if (!this.options.endpoint) {\n this.apply(normalizeAdTriggers(this.options.config));\n return;\n }\n const ctrl = typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timer = setTimeout(() => ctrl?.abort(), this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n let url = '';\n try {\n const u = new URL(this.options.endpoint, document.baseURI);\n for (const [k, v] of Object.entries(this.options.params ?? {})) u.searchParams.set(k, v);\n url = u.href;\n const res = await fetch(url, { ...this.options.fetchInit, signal: ctrl?.signal });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const json: unknown = await res.json();\n if (this.destroyed || seq !== this.requestSeq) return;\n this.apply(normalizeAdTriggers(json));\n } catch (err) {\n if (this.destroyed || seq !== this.requestSeq) return;\n this.ctx.log({ message: `Ad triggers API failed: ${String(err)}`, details: { url } });\n // Hiç kural yoksa yerel varsayılan (config) kullanılır; varsa son geçerli kurallar korunur.\n if (!this.config && this.options.config) this.apply(normalizeAdTriggers(this.options.config));\n } finally {\n clearTimeout(timer);\n }\n }\n\n private apply(config: AdTriggersConfig | null): void {\n // İlk yanıt her zaman bildirilir (kapalı olsa da) — sonrakiler yalnızca değişince.\n const changed = !this.loaded || JSON.stringify(config) !== JSON.stringify(this.config);\n this.loaded = true;\n this.config = config;\n if (!changed) return;\n this.cancelDelayed();\n if (!config) this.close('content');\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:adtriggers', { detail: { config } }));\n }\n\n // ── olaylar → tetikleyiciler ──\n\n private readonly onLoadStart = (): void => {\n const key = this.ctx.contentKey();\n // Aynı içeriğin kalite değişimi de loadstart üretir — yalnızca gerçekten başka bir içerik gelince sıfırla.\n if (key === this.contentKey) return;\n this.contentKey = key;\n this.fired.clear();\n this.shows.clear();\n this.lastShownAt.clear();\n this.watchedMs = 0;\n this.lastPos = 0;\n this.started = false;\n this.userPaused = false;\n this.cancelDelayed();\n this.close('content');\n };\n\n private readonly onPlaying = (): void => {\n if (this.ctx.isBlocked()) return;\n if (!this.started) {\n this.started = true;\n this.trigger('start');\n } else if (this.userPaused) {\n this.trigger('resume');\n }\n this.userPaused = false;\n this.cancelDelayed('pause');\n };\n\n private readonly onPause = (): void => {\n const v = this.ctx.videoEl;\n if (this.selfPause) {\n this.selfPause = false;\n return;\n }\n if (v.ended || v.seeking || this.ctx.isBlocked()) return;\n this.userPaused = true;\n this.cancelDelayed('start', 'resume');\n this.trigger('pause');\n };\n\n private readonly onEnded = (): void => {\n if (!this.ctx.isBlocked()) this.trigger('ended');\n };\n\n private readonly onSeeked = (): void => {\n this.lastPos = this.ctx.videoEl.currentTime;\n };\n\n private readonly onFullscreenChange = (): void => {\n const fs = this.ctx.isFullscreen();\n if (fs === this.wasFullscreen) return;\n this.wasFullscreen = fs;\n this.cancelDelayed(fs ? 'fullscreenExit' : 'fullscreen');\n // Tam ekran durumu değişti: o duruma özel gösterilen reklam kapanır.\n const mode = this.showing?.rule.mode;\n if ((mode === 'fullscreen' && !fs) || (mode === 'normal' && fs)) this.close('mode');\n this.trigger(fs ? 'fullscreen' : 'fullscreenExit');\n };\n\n private readonly onVideoAdStart = (e: Event): void => {\n if ((e as CustomEvent<{ linear?: boolean }>).detail?.linear === false) return;\n this.cancelDelayed();\n this.close('ad');\n };\n\n private isLive(): boolean {\n return this.ctx.videoEl.duration === Infinity;\n }\n\n private readonly onTimeUpdate = (): void => {\n const v = this.ctx.videoEl;\n const pos = v.currentTime;\n const prev = this.lastPos;\n this.lastPos = pos;\n const c = this.config;\n if (!c || v.paused || v.seeking || this.isLive() || this.ctx.isBlocked()) return;\n // Yalnızca doğal ilerleme — ileri sarınca aradaki anlar tetiklenmez.\n if (pos <= prev || pos - prev > MAX_NATURAL_STEP_S) return;\n const dur = v.duration;\n c.rules.forEach((rule, ri) =>\n rule.triggers.forEach((t, ti) => {\n if (t.type !== 'time' && t.type !== 'percent') return;\n for (const mark of t.at) {\n const at = t.type === 'percent' ? (Number.isFinite(dur) && dur > 0 ? (dur * mark) / 100 : NaN) : mark;\n const key = `${ri}:${ti}:${mark}`;\n if (prev < at && at <= pos && !this.fired.has(key)) {\n this.fired.add(key);\n this.showRule(ri, t.type);\n }\n }\n })\n );\n };\n\n /** Gerçek izleme süresi: interval kuralları (ve canlıda time kuralları) bununla sayılır. */\n private readonly tick = (): void => {\n const now = performance.now();\n const delta = Math.min(2000, Math.max(0, now - this.lastTick));\n this.lastTick = now;\n const v = this.ctx.videoEl;\n const c = this.config;\n if (!c || v.paused || v.ended || document.hidden || this.ctx.isBlocked() || this.showing?.filled) return;\n const before = this.watchedMs / 1000;\n this.watchedMs += delta;\n const after = this.watchedMs / 1000;\n c.rules.forEach((rule, ri) =>\n rule.triggers.forEach((t, ti) => {\n if (t.type === 'interval') {\n const first = t.startAfter ?? t.every;\n // Bu adımda geçilen eşik: first, first + every, first + 2·every…\n const n = Math.floor((after - first) / t.every);\n if (after >= first && first + n * t.every > before) this.showRule(ri, 'interval');\n } else if (t.type === 'time' && this.isLive()) {\n for (const at of t.at) {\n const key = `${ri}:${ti}:${at}:live`;\n if (before < at && at <= after && !this.fired.has(key)) {\n this.fired.add(key);\n this.showRule(ri, 'time');\n }\n }\n }\n })\n );\n };\n\n /** Olay tipindeki tetikleyicisi olan her kural (gecikmeliyse zamanlanır). */\n private trigger(type: TriggerType): void {\n const c = this.config;\n if (!c) return;\n c.rules.forEach((rule, ri) => {\n const t = rule.triggers.find((x) => x.type === type) as { delay?: number } | undefined;\n if (!t) return;\n const delay = (t.delay ?? 0) * 1000;\n if (delay <= 0) {\n this.showRule(ri, type);\n return;\n }\n const timer = setTimeout(() => {\n this.delayed = this.delayed.filter((d) => d.timer !== timer);\n this.showRule(ri, type);\n }, delay);\n this.delayed.push({ type, timer });\n });\n }\n\n private cancelDelayed(...types: TriggerType[]): void {\n this.delayed = this.delayed.filter((d) => {\n if (types.length && !types.includes(d.type)) return true;\n clearTimeout(d.timer);\n return false;\n });\n }\n\n // ── gösterim ──\n\n /** Koşullar uygunsa kuralın reklamını ister. Uygun değilse sessizce atlanır (sebep kayda düşer). */\n private showRule(index: number, trigger: TriggerType): void {\n const rule = this.config?.rules[index];\n if (!rule || this.destroyed) return;\n const v = this.ctx.videoEl;\n const fs = this.ctx.isFullscreen();\n const skip = (why: string): void => this.ctx.log({ message: `Ad trigger skipped (${why})`, details: { rule: rule.id, trigger } });\n // layout 'none' reklamının kapanışı kreatifte — yeni tetikleme onu değiştirir; diğerleri (ya da süren istek) bekletir.\n if (this.showing && !(this.showing.filled && this.showing.rule.layout === 'none')) return skip('another ad is showing');\n if (this.ctx.isBlocked()) return skip('video ad / intro screen');\n if (document.hidden) return skip('tab hidden');\n if (this.ctx.isNativeFullscreen()) return skip('native iOS fullscreen');\n if (rule.mode === 'fullscreen' && !fs) return skip('not fullscreen');\n if (rule.mode === 'normal' && fs) return skip('fullscreen');\n // Olay anındaki durum hâlâ geçerli mi (gecikmeli tetiklemeler için).\n if (trigger === 'pause' && (!v.paused || v.ended)) return;\n if (trigger === 'ended' && !v.ended) return;\n if (['time', 'percent', 'interval', 'start', 'resume'].includes(trigger) && v.paused) return;\n if (rule.minPlayerWidth && this.ctx.overlayEl.getBoundingClientRect().width < rule.minPlayerWidth) return skip('player too narrow');\n const now = Date.now();\n if (rule.maxShows && (this.shows.get(index) ?? 0) >= rule.maxShows) return skip('maxShows');\n if (rule.minGapSeconds && now - (this.lastShownAt.get(index) ?? 0) < rule.minGapSeconds * 1000) return skip('rule minGapSeconds');\n if (now - this.lastAnyAt < (this.config?.minGapSeconds ?? DEFAULT_GLOBAL_GAP_S) * 1000) return skip('minGapSeconds');\n if (this.showing) this.close('replaced');\n // İstek anı aralığa sayılır: boş dönen birim her saniye yeniden istenmesin.\n this.lastAnyAt = now;\n this.lastShownAt.set(index, now);\n void this.request(index, rule, trigger, fs);\n }\n\n private async request(index: number, rule: AdTriggerRule, trigger: TriggerType, fullscreen: boolean): Promise<void> {\n const id = ++this.seq;\n const slotName = `hp-adtrigger-${this.instance}`;\n const box = this.buildBox(rule, slotName);\n const adHost = document.createElement('div');\n adHost.id = `hp-adtrigger-${this.instance}-${id}`;\n adHost.slot = slotName;\n const s: Showing = { rule, trigger, box, adHost, slot: null, filled: false, pausedContent: false, timers: [] };\n this.showing = s;\n this.ctx.overlayEl.appendChild(box);\n this.ctx.hostEl.appendChild(adHost);\n const detail = { rule: rule.id, trigger, adUnitPath: rule.adUnitPath };\n const empty = (why: string): void => {\n if (this.showing !== s) return;\n this.ctx.log({ message: `Ad trigger: no ad (${why})`, details: { ...detail } });\n fire(rule.tracking?.empty);\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:adtriggerempty', { detail }));\n this.teardown(s);\n };\n // GPT hiç yüklenemez / yanıt vermezse (engelleyici, ağ) kutu asılı kalmasın.\n s.timers.push(setTimeout(() => !s.filled && empty('timeout'), this.options.renderTimeoutMs ?? DEFAULT_RENDER_TIMEOUT_MS));\n try {\n this.googletag ??= await loadGpt();\n } catch (err) {\n empty(String(err));\n return;\n }\n if (this.showing !== s) return;\n const gt = this.googletag;\n gt.cmd.push(() => {\n if (this.showing !== s) return;\n const slot = gt.defineOutOfPageSlot(rule.adUnitPath, adHost.id);\n if (!slot) {\n empty('slot could not be defined');\n return;\n }\n s.slot = slot;\n slot.addService(gt.pubads());\n // Öncelik (sonraki ezer): sayfa targeting → sayfa custParams → kural targeting → kural custParams → hp_*.\n const targeting: Record<string, string | string[]> = {\n ...parseCustParams(this.options.targeting),\n ...parseCustParams(this.options.custParams),\n ...rule.targeting,\n ...parseCustParams(rule.custParams),\n hp_trigger: trigger,\n hp_mode: fullscreen ? 'fullscreen' : 'normal',\n };\n if (rule.id) targeting.hp_rule = rule.id;\n for (const [k, val] of Object.entries(targeting)) slot.setTargeting(k, val);\n s.custParams = targeting;\n const onRender = (e: GptSlotRenderEndedEvent): void => {\n if (e.slot !== slot) return;\n gt.pubads().removeEventListener?.('slotRenderEnded', onRender);\n if (e.isEmpty) empty('empty');\n else this.reveal(index, s, fullscreen);\n };\n gt.pubads().addEventListener('slotRenderEnded', onRender);\n gt.enableServices();\n gt.display(adHost.id);\n // Sayfa disableInitialLoad kullanıyorsa display istek atmaz — elle refresh.\n if (gt.pubads().isInitialLoadDisabled()) gt.pubads().refresh([slot]);\n });\n }\n\n private buildBox(rule: AdTriggerRule, slotName: string): HTMLDivElement {\n const box = document.createElement('div');\n box.className = 'hp-adtrigger';\n box.setAttribute('part', 'ad-trigger');\n const bare = rule.layout === 'none';\n box.setAttribute('data-layout', rule.layout ?? 'none');\n box.toggleAttribute('data-backdrop', !!rule.backdrop);\n const frame = document.createElement('div');\n frame.className = 'hp-adtrigger-frame';\n if (rule.size && rule.layout !== 'full') {\n frame.style.setProperty('--hp-adtrigger-w', `${rule.size[0]}px`);\n frame.style.setProperty('--hp-adtrigger-h', `${rule.size[1]}px`);\n frame.setAttribute('data-sized', '');\n }\n // 'none': player yalnızca isteği atar ve kreatifi yerleştirir — etiket, kapat butonu, boyut kreatifin işi.\n if (rule.label !== false && !bare) {\n const label = document.createElement('span');\n label.className = 'hp-adtrigger-label';\n label.textContent = rule.label || this.ctx.i18n.adTriggerLabel;\n frame.appendChild(label);\n }\n const slot = document.createElement('slot');\n slot.name = slotName;\n frame.appendChild(slot);\n if (rule.closeButton !== false && !bare) {\n const close = document.createElement('button');\n close.type = 'button';\n close.className = 'hp-adtrigger-close';\n close.setAttribute('part', 'ad-trigger-close');\n close.setAttribute('aria-label', this.ctx.i18n.pauseAdClose);\n close.hidden = true;\n close.innerHTML =\n '<svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" aria-hidden=\"true\"><path d=\"M6 6l12 12M18 6L6 18\"/></svg>';\n close.addEventListener('click', () => this.close('user'));\n frame.appendChild(close);\n }\n box.appendChild(frame);\n // Reklama tıklama / dokunma videoyu oynat-duraklat yapmasın, kontrolleri açmasın.\n for (const t of ['pointerdown', 'click', 'dblclick'] as const) box.addEventListener(t, (e) => e.stopPropagation());\n return box;\n }\n\n private reveal(index: number, s: Showing, fullscreen: boolean): void {\n if (this.showing !== s) return;\n const { rule } = s;\n s.filled = true;\n this.shows.set(index, (this.shows.get(index) ?? 0) + 1);\n this.lastAnyAt = Date.now();\n // Kutu boyutlu ya da tam alan ise reklam iframe'i kutuyu doldursun (out-of-page kreatifleri kendi boyutunu vermez).\n if (rule.layout === 'full' || (rule.size && rule.layout !== 'none')) {\n const iframe = s.adHost.querySelector('iframe');\n if (iframe) Object.assign(iframe.style, { width: '100%', height: '100%', border: '0' });\n Object.assign(s.adHost.style, { width: '100%', height: '100%' });\n }\n s.box.setAttribute('data-open', '');\n const close = s.box.querySelector<HTMLButtonElement>('.hp-adtrigger-close');\n if (close) s.timers.push(setTimeout(() => (close.hidden = false), (rule.closeDelay ?? 0) * 1000));\n if (rule.duration) s.timers.push(setTimeout(() => this.close('timeout'), rule.duration * 1000));\n const v = this.ctx.videoEl;\n if (rule.pauseContent && !v.paused) {\n s.pausedContent = true;\n this.selfPause = true;\n v.pause();\n }\n fire(rule.tracking?.impression);\n this.ctx.hostEl.dispatchEvent(\n new CustomEvent('hp:adtriggershow', { detail: { rule: rule.id, trigger: s.trigger, adUnitPath: rule.adUnitPath, fullscreen, custParams: s.custParams ?? {} } })\n );\n }\n\n /** Gösterilen reklamı kapat (bekleyen istek varsa iptal). */\n close(reason: CloseReason): void {\n const s = this.showing;\n if (!s) return;\n const wasFilled = s.filled;\n this.teardown(s);\n if (!wasFilled) return;\n fire(s.rule.tracking?.close);\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:adtriggerclose', { detail: { rule: s.rule.id, reason } }));\n // Duraklattığımız içerik kaldığı yerden devam etsin (içerik değişmediyse / video reklamı başlamadıysa).\n if (s.pausedContent && reason !== 'content' && reason !== 'ad') void this.ctx.videoEl.play().catch(() => {});\n }\n\n private teardown(s: Showing): void {\n if (this.showing === s) this.showing = null;\n for (const t of s.timers) clearTimeout(t);\n if (s.slot && this.googletag) {\n try {\n this.googletag.destroySlots([s.slot]);\n } catch {\n /* zaten yok edildi */\n }\n }\n s.box.remove();\n s.adHost.remove();\n }\n\n destroy(): void {\n this.destroyed = true;\n this.cancelDelayed();\n this.close('content');\n clearInterval(this.tickTimer);\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n const v = this.ctx.videoEl;\n v.removeEventListener('timeupdate', this.onTimeUpdate);\n v.removeEventListener('seeked', this.onSeeked);\n v.removeEventListener('playing', this.onPlaying);\n v.removeEventListener('pause', this.onPause);\n v.removeEventListener('ended', this.onEnded);\n v.removeEventListener('loadstart', this.onLoadStart);\n v.removeEventListener('webkitbeginfullscreen', this.onFullscreenChange);\n v.removeEventListener('webkitendfullscreen', this.onFullscreenChange);\n document.removeEventListener('fullscreenchange', this.onFullscreenChange);\n document.removeEventListener('webkitfullscreenchange', this.onFullscreenChange);\n this.ctx.hostEl.removeEventListener('hp:adstart', this.onVideoAdStart);\n }\n}\n","import { AdTriggers, normalizeAdTriggers, type AdTriggersContext } from './AdTriggers';\nimport type { AdTriggersOptions } from '../../types';\n\n/** Reklam tetikleyicisini kurar (kuralları `endpoint`'ten ya da `config`'ten alır). */\nexport function installAdTriggers(ctx: AdTriggersContext, options: AdTriggersOptions): AdTriggers {\n return new AdTriggers(ctx, options);\n}\n\nexport { AdTriggers, normalizeAdTriggers };\nexport type { AdTriggersContext };\n"],"names":["DEFAULT_TIMEOUT_MS","DEFAULT_RENDER_TIMEOUT_MS","DEFAULT_GLOBAL_GAP_S","LAYOUTS","TRIGGER_TYPES","MAX_NATURAL_STEP_S","instanceCount","safeUrl","value","u","num","n","min","max","prim","v","parseCustParams","raw","entries","k","out","list","x","one","normalizeTrigger","t","type","at","every","normalizeAdTriggers","r","now","from","until","urls","rules","triggers","size","layout","_a","_b","_c","fire","img","AdTriggers","ctx","options","__publicField","key","fs","mode","pos","prev","c","dur","rule","ri","ti","mark","delta","before","after","first","changed","refreshChanged","s","seq","ctrl","timer","url","res","json","err","config","delay","types","d","index","trigger","skip","why","fullscreen","id","slotName","box","adHost","detail","empty","loadGpt","gt","slot","targeting","val","onRender","e","bare","frame","label","close","iframe","reason","wasFilled","installAdTriggers"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"cast-DCAT2agI.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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"}