@hopeplayer/core 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{index-q5DsrT-Q.js → index-BR31cEYA.js} +2 -2
- package/dist/chunks/{index-q5DsrT-Q.js.map → index-BR31cEYA.js.map} +1 -1
- package/dist/chunks/{index-DiCkShCE.js → index-BjmWoP4E.js} +80 -70
- package/dist/chunks/index-BjmWoP4E.js.map +1 -0
- package/dist/chunks/{index-B4ujPVcl.js → index-CEmsL1uT.js} +2 -2
- package/dist/chunks/{index-B4ujPVcl.js.map → index-CEmsL1uT.js.map} +1 -1
- package/dist/chunks/{index-CQqGn9as.js → index-CZK3TwzR.js} +2 -2
- package/dist/chunks/{index-CQqGn9as.js.map → index-CZK3TwzR.js.map} +1 -1
- package/dist/chunks/{index-BFgqg05L.js → index-DadIEuQc.js} +2 -2
- package/dist/chunks/{index-BFgqg05L.js.map → index-DadIEuQc.js.map} +1 -1
- package/dist/chunks/{index-DXf2Al1x.js → index-lrAXde76.js} +2 -2
- package/dist/chunks/{index-DXf2Al1x.js.map → index-lrAXde76.js.map} +1 -1
- package/dist/hls/SourceManager.d.ts +5 -2
- package/dist/hls/SourceManager.d.ts.map +1 -1
- package/dist/hope-player.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/index-DiCkShCE.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-BjmWoP4E.js","sources":["../../src/hls/SourceManager.ts","../../src/utils/format-time.ts","../../src/controls/SeekBar.ts","../../src/icons/Icon.ts","../../src/controls/VolumePanel.ts","../../src/controls/SettingsMenu.ts","../../src/controls/ControlBar.ts","../../src/controls/Tooltip.ts","../../src/keyboard/KeyboardController.ts","../../src/screens/LoadingSpinner.ts","../../src/screens/ErrorScreen.ts","../../src/subtitles/attachTracks.ts","../../src/subtitles/CaptionRenderer.ts","../../src/controls/MiniProgress.ts","../../src/icons/injectIconFont.ts","../../src/i18n/locales/tr.ts","../../src/i18n/locales/en.ts","../../src/i18n/index.ts","../../src/HopePlayerElement.ts","../../src/index.ts"],"sourcesContent":["\n/**\n * MP4: HTML5 video üzerinden doğrudan oynatılır.\n * M3U8: Safari/iOS'ta native HLS; diğer tarayıcılarda gerektiğinde hls.js.\n */\nexport interface HlsQualityLevel {\n index: number;\n height: number;\n bitrate: number;\n}\n\ntype HlsModule = typeof import('hls.js');\ntype HlsInstance = InstanceType<HlsModule['default']>;\n\ntype MediaSourceType = 'hls' | 'mp4' | 'unknown';\n\n/**\n * Kaynak türünü MIME type veya URL uzantısından belirler.\n * URL'deki query string ve fragment değerlerini de destekler.\n */\nfunction detectSourceType(src: string, type?: string): MediaSourceType {\n const normalizedType = type\n ?.split(';')[0]\n ?.trim()\n .toLowerCase();\n\n // HLS / M3U8\n if (\n normalizedType === 'application/vnd.apple.mpegurl' ||\n normalizedType === 'application/x-mpegurl' ||\n /\\.m3u8(?:$|[?#])/i.test(src)\n ) {\n return 'hls';\n }\n\n // MP4\n if (\n normalizedType === 'video/mp4' ||\n /\\.mp4(?:$|[?#])/i.test(src)\n ) {\n return 'mp4';\n }\n\n return 'unknown';\n}\n\nexport class SourceManager {\n private hls: HlsInstance | null = null;\n\n private readonly video: HTMLVideoElement;\n\n private readonly onLevelsChanged: (\n levels: HlsQualityLevel[],\n activeIndex: number\n ) => void;\n\n constructor(\n video: HTMLVideoElement,\n onLevelsChanged: (\n levels: HlsQualityLevel[],\n activeIndex: number\n ) => void\n ) {\n this.video = video;\n this.onLevelsChanged = onLevelsChanged;\n }\n\n async load(src: string, type?: string): Promise<void> {\n // Önce önceki HLS instance'ını kapat.\n this.destroy();\n\n // Önceki kaynağın video elementinde kalmasını önle.\n this.video.pause();\n this.video.removeAttribute('src');\n this.video.load();\n\n const sourceType = detectSourceType(src, type);\n\n // MP4 veya uzantısı belirlenemeyen doğrudan video kaynağı.\n if (sourceType !== 'hls') {\n this.video.src = src;\n this.video.load();\n return;\n }\n\n // Safari / iOS: native HLS desteği varsa hls.js kullanma.\n if (\n this.video.canPlayType('application/vnd.apple.mpegurl') !== ''\n ) {\n this.video.src = src;\n this.video.load();\n return;\n }\n\n // Diğer tarayıcılar: hls.js'i yalnızca gerektiğinde yükle.\n const { default: Hls } = await import('hls.js');\n\n // hls.js desteklenmiyorsa native oynatmayı dene.\n if (!Hls.isSupported()) {\n this.video.src = src;\n this.video.load();\n return;\n }\n\n const hls = new Hls({\n enableWorker: true,\n });\n\n this.hls = hls;\n\n hls.on(Hls.Events.MANIFEST_PARSED, () => {\n const levels: HlsQualityLevel[] = hls.levels.map(\n (level, index) => ({\n index,\n height: level.height,\n bitrate: level.bitrate,\n })\n );\n\n this.onLevelsChanged(levels, hls.currentLevel);\n });\n\n hls.on(Hls.Events.LEVEL_SWITCHED, (_event, data) => {\n const levels: HlsQualityLevel[] = hls.levels.map(\n (level, index) => ({\n index,\n height: level.height,\n bitrate: level.bitrate,\n })\n );\n\n this.onLevelsChanged(levels, data.level);\n });\n\n hls.attachMedia(this.video);\n hls.loadSource(src);\n }\n\n /** -1 = otomatik kalite (ABR). */\n setLevel(index: number): void {\n if (this.hls) {\n this.hls.currentLevel = index;\n }\n }\n\n destroy(): void {\n if (this.hls) {\n this.hls.destroy();\n this.hls = null;\n }\n }\n}\n","/** 83 → \"1:23\", 3661 → \"1:01:01\". NaN/Infinity (henüz metadata yoksa) → \"0:00\". */\nexport function formatTime(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return '0:00';\n\n const totalSeconds = Math.floor(seconds);\n const h = Math.floor(totalSeconds / 3600);\n const m = Math.floor((totalSeconds % 3600) / 60);\n const s = totalSeconds % 60;\n\n const mm = h > 0 ? String(m).padStart(2, '0') : String(m);\n const ss = String(s).padStart(2, '0');\n\n return h > 0 ? `${h}:${mm}:${ss}` : `${mm}:${ss}`;\n}\n","import type { HopeLocaleStrings } from '../i18n/types';\nimport { formatTime } from '../utils/format-time';\n\n/**\n * Div tabanlı scrubber (role=\"slider\"). Çizim transform ile (layout tetiklemez), oynarken rAF döngüsü.\n * Chapter modunda zaman ↔ piksel eşlemesi parçaların ölçülmüş geometrisinden.\n */\nexport interface SeekBarChapterRange {\n /** 0–1 arası oran. */\n start: number;\n end: number;\n /** Bu bölümün oynatılmış dolgusunun rengi — verilmezse tema accent'i. */\n color?: string;\n}\n\ninterface ChapterState extends SeekBarChapterRange {\n el: HTMLDivElement;\n bufferedEl: HTMLDivElement;\n playedEl: HTMLDivElement;\n /** seek bar'ın sol kenarına göre px — measureChapters() dolduruyor. */\n left: number;\n width: number;\n}\n\nexport class SeekBar {\n readonly el: HTMLDivElement;\n private readonly trackEl: HTMLDivElement;\n private chaptersEl: HTMLDivElement | null = null;\n private chapters: ChapterState[] = [];\n /** İmlecin üstündeki zaman (varsayılan, plugin gerektirmez) — kendi zamanını gösteren plugin'ler `suppressHoverTime` ile gizler. */\n private readonly hoverTimeEl: HTMLDivElement;\n private readonly hoverTimeSuppressors = new Set<string>();\n private readonly playedEl: HTMLDivElement;\n private readonly bufferedEl: HTMLDivElement;\n private readonly thumbEl: HTMLDivElement;\n private readonly hoverDotEl: HTMLDivElement;\n private readonly video: HTMLVideoElement;\n private readonly labels: HopeLocaleStrings;\n private dragging = false;\n private readonly markerEls: HTMLDivElement[] = [];\n private trackWidth = 0;\n private readonly resizeObserver: ResizeObserver;\n private rafId: number | null = null;\n\n constructor(video: HTMLVideoElement, labels: HopeLocaleStrings) {\n this.video = video;\n this.labels = labels;\n\n this.el = document.createElement('div');\n this.el.setAttribute('part', 'seek-bar');\n // Tıklama alanı (--hp-seek-hit-h) görünür track'ten büyük.\n this.el.className =\n 'hp-seekbar hp:relative hp:h-[var(--hp-seek-hit-h)] hp:flex hp:items-center hp:cursor-pointer hp:group hp:touch-none';\n this.el.setAttribute('role', 'slider');\n this.el.setAttribute('tabindex', '0');\n this.el.setAttribute('aria-label', labels.seekBar);\n this.el.setAttribute('aria-valuemin', '0');\n\n const track = document.createElement('div');\n track.className =\n 'hp:absolute hp:inset-x-0 hp:h-[var(--hp-seek-track-h)] hp:rounded-full hp:bg-on-surface/25 ' +\n 'hp:group-hover:h-[var(--hp-seek-track-h-hover)] hp:transition-[height] hp:duration-150';\n this.el.appendChild(track);\n this.trackEl = track;\n\n this.bufferedEl = document.createElement('div');\n this.bufferedEl.className = 'hp:absolute hp:inset-0 hp:rounded-full hp:bg-on-surface/40';\n this.bufferedEl.style.transformOrigin = 'left';\n this.bufferedEl.style.willChange = 'transform';\n track.appendChild(this.bufferedEl);\n\n this.playedEl = document.createElement('div');\n this.playedEl.className = 'hp:absolute hp:inset-0 hp:rounded-full hp:bg-accent';\n this.playedEl.style.transformOrigin = 'left';\n this.playedEl.style.willChange = 'transform';\n track.appendChild(this.playedEl);\n\n // Boyut/ölçek tailwind.css'te (.hp-seek-thumb): her zaman görünür ve küçük, seek bar hover'ında büyür.\n this.thumbEl = document.createElement('div');\n this.thumbEl.className = 'hp-seek-thumb';\n this.thumbEl.setAttribute('part', 'seek-thumb');\n this.el.appendChild(this.thumbEl);\n\n // İmlecin altındaki küçük nokta — nereye tıklanacağını gösterir.\n this.hoverDotEl = document.createElement('div');\n this.hoverDotEl.className = 'hp-seek-hover-dot';\n this.hoverDotEl.setAttribute('part', 'seek-hover-dot');\n this.el.appendChild(this.hoverDotEl);\n\n this.hoverTimeEl = document.createElement('div');\n this.hoverTimeEl.className = 'hp-seek-time';\n this.hoverTimeEl.setAttribute('part', 'seek-time');\n this.el.appendChild(this.hoverTimeEl);\n\n this.el.addEventListener('pointerdown', this.onPointerDown);\n this.el.addEventListener('pointermove', this.onHoverMove);\n this.el.addEventListener('pointerleave', this.onHoverLeave);\n this.el.addEventListener('keydown', this.onKeyDown);\n video.addEventListener('play', this.startLoop);\n video.addEventListener('pause', this.stopLoop);\n video.addEventListener('ended', this.stopLoop);\n // rAF döngüsü yalnızca OYNARKEN çalışır — duraklıyken/scrub ederken\n // (ör. seek sonrası henüz play tetiklenmeden) konum hâlâ güncel\n // kalsın diye timeupdate/progress/loadedmetadata da dinleniyor.\n video.addEventListener('timeupdate', this.render);\n video.addEventListener('progress', this.render);\n video.addEventListener('loadedmetadata', this.render);\n if (!video.paused) this.startLoop();\n\n this.resizeObserver = new ResizeObserver(() => {\n this.trackWidth = this.el.getBoundingClientRect().width;\n this.measureChapters();\n this.render();\n });\n this.resizeObserver.observe(this.el);\n this.trackWidth = this.el.getBoundingClientRect().width;\n }\n\n /** Kendi zamanını gösteren plugin'ler (sprite/segments) varsayılan hover zamanını gizler — keyed set. */\n suppressHoverTime(key: string, suppressed: boolean): void {\n if (suppressed) this.hoverTimeSuppressors.add(key);\n else this.hoverTimeSuppressors.delete(key);\n if (suppressed) this.hoverTimeEl.removeAttribute('data-visible');\n }\n\n private readonly onHoverMove = (e: PointerEvent): void => {\n const duration = this.video.duration;\n const hasDuration = Number.isFinite(duration) && duration > 0;\n const ratio = this.ratioAtClientX(e.clientX);\n\n // Hover noktası: sürüklerken gösterilmez (thumb zaten imlecin altında); canlıda sarılacak konum yok.\n if (hasDuration && !this.dragging) {\n this.hoverDotEl.style.transform = `translate(${this.xAtRatio(ratio)}px, -50%) translateX(-50%)`;\n this.hoverDotEl.setAttribute('data-visible', '');\n } else {\n this.hoverDotEl.removeAttribute('data-visible');\n }\n\n // Canlı yayında (Infinity) süre yok — live-wall-clock'un kendi tooltip'i var.\n if (this.hoverTimeSuppressors.size || !hasDuration) {\n this.hoverTimeEl.removeAttribute('data-visible');\n return;\n }\n this.hoverTimeEl.textContent = formatTime(ratio * duration);\n this.hoverTimeEl.setAttribute('data-visible', '');\n // İmleci ortala, seek bar kenarlarından taşma.\n const rect = this.el.getBoundingClientRect();\n const w = this.hoverTimeEl.offsetWidth;\n const x = Math.min(Math.max(e.clientX - rect.left - w / 2, 0), Math.max(rect.width - w, 0));\n this.hoverTimeEl.style.transform = `translateX(${x}px)`;\n };\n\n private readonly onHoverLeave = (): void => {\n this.hoverTimeEl.removeAttribute('data-visible');\n this.hoverDotEl.removeAttribute('data-visible');\n };\n\n private ratioFromEvent(e: PointerEvent): number {\n return this.ratioAtClientX(e.clientX);\n }\n\n /** Ekran x koordinatını 0–1 zaman oranına çevirir — chapter modunda parça boşluklarını hesaba katar (segments plugin'inin hover popup'ı da bunu kullanıyor). */\n ratioAtClientX(clientX: number): number {\n const rect = this.el.getBoundingClientRect();\n const x = clientX - rect.left;\n if (!this.chapters.length) return Math.min(1, Math.max(0, x / rect.width));\n\n for (let i = 0; i < this.chapters.length; i++) {\n const c = this.chapters[i]!;\n const next = this.chapters[i + 1];\n // Parçanın kendisi + ardından gelen boşluk bu parçaya ait sayılıyor.\n const zoneEnd = next ? next.left : Infinity;\n if (x < zoneEnd || !next) {\n const local = c.width > 0 ? Math.min(1, Math.max(0, (x - c.left) / c.width)) : 0;\n return c.start + local * (c.end - c.start);\n }\n }\n return 1;\n }\n\n /** 0–1 zaman oranının seek bar üzerindeki px konumu (thumb için). */\n private xAtRatio(ratio: number): number {\n if (!this.chapters.length) return ratio * this.trackWidth;\n const c = this.chapters.find((ch) => ratio < ch.end) ?? this.chapters[this.chapters.length - 1]!;\n const span = c.end - c.start;\n const local = span > 0 ? Math.min(1, Math.max(0, (ratio - c.start) / span)) : 0;\n return c.left + local * c.width;\n }\n\n /** Track'i sıralı, 0→1'i kesintisiz kapsayan oran aralıklarına göre ayrı parçalara böler. */\n setChapters(ranges: SeekBarChapterRange[]): HTMLDivElement[] {\n this.clearChapters();\n if (!ranges.length) return [];\n\n const container = document.createElement('div');\n container.className = 'hp-chapters';\n this.chapters = ranges.map((r) => {\n const el = document.createElement('div');\n el.className = 'hp-chapter';\n el.setAttribute('part', 'segment-band');\n el.style.flex = `${Math.max(r.end - r.start, 0)} 1 0px`;\n\n const bufferedEl = document.createElement('div');\n bufferedEl.className = 'hp-chapter-fill hp-chapter-buffered';\n const playedEl = document.createElement('div');\n playedEl.className = 'hp-chapter-fill hp-chapter-played';\n if (r.color) playedEl.style.background = r.color;\n el.append(bufferedEl, playedEl);\n container.appendChild(el);\n return { ...r, el, bufferedEl, playedEl, left: 0, width: 0 };\n });\n\n // Tek track gizleniyor, parçalar onun yerini alıyor (thumb/marker'lar üstte kalsın diye track'ten hemen sonra).\n this.trackEl.style.display = 'none';\n this.trackEl.after(container);\n this.chaptersEl = container;\n this.measureChapters();\n this.render();\n return this.chapters.map((c) => c.el);\n }\n\n clearChapters(): void {\n this.chaptersEl?.remove();\n this.chaptersEl = null;\n this.chapters = [];\n this.trackEl.style.display = '';\n this.render();\n }\n\n private measureChapters(): void {\n if (!this.chapters.length) return;\n const base = this.el.getBoundingClientRect().left;\n for (const c of this.chapters) {\n const r = c.el.getBoundingClientRect();\n c.left = r.left - base;\n c.width = r.width;\n }\n }\n\n private readonly onPointerDown = (e: PointerEvent): void => {\n this.dragging = true;\n this.hoverDotEl.removeAttribute('data-visible');\n this.el.setPointerCapture(e.pointerId);\n this.seekToRatio(this.ratioFromEvent(e));\n this.el.addEventListener('pointermove', this.onPointerMove);\n this.el.addEventListener('pointerup', this.onPointerUp);\n };\n\n private readonly onPointerMove = (e: PointerEvent): void => {\n if (!this.dragging) return;\n this.seekToRatio(this.ratioFromEvent(e));\n };\n\n private readonly onPointerUp = (e: PointerEvent): void => {\n this.dragging = false;\n this.el.releasePointerCapture(e.pointerId);\n this.el.removeEventListener('pointermove', this.onPointerMove);\n this.el.removeEventListener('pointerup', this.onPointerUp);\n };\n\n private readonly onKeyDown = (e: KeyboardEvent): void => {\n const duration = this.video.duration || 0;\n if (!Number.isFinite(duration) || duration <= 0) return;\n\n if (e.key === 'ArrowRight') {\n this.video.currentTime = Math.min(duration, this.video.currentTime + 5);\n e.preventDefault();\n } else if (e.key === 'ArrowLeft') {\n this.video.currentTime = Math.max(0, this.video.currentTime - 5);\n e.preventDefault();\n }\n };\n\n private seekToRatio(ratio: number): void {\n const duration = this.video.duration;\n if (!Number.isFinite(duration) || duration <= 0) return;\n this.video.currentTime = ratio * duration;\n // video'nun kendi 'timeupdate'i asenkron/gecikmeli olabilir —\n // sürüklerken parmak/imleçle thumb arasında gecikme hissi\n // bırakmamak için konumu HEMEN, burada çiziyoruz.\n this.render();\n }\n\n private readonly startLoop = (): void => {\n if (this.rafId !== null) return;\n const tick = (): void => {\n this.render();\n this.rafId = requestAnimationFrame(tick);\n };\n this.rafId = requestAnimationFrame(tick);\n };\n\n private readonly stopLoop = (): void => {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n this.render();\n };\n\n private readonly render = (): void => {\n const duration = this.video.duration;\n // Süre yoksa (canlı yayın / henüz metadata yok) thumb gizlenir — CSS `.hp-seekbar[data-no-duration]`.\n this.el.toggleAttribute('data-no-duration', !Number.isFinite(duration) || duration <= 0);\n if (!Number.isFinite(duration) || duration <= 0) {\n this.playedEl.style.transform = 'scaleX(0)';\n this.thumbEl.style.translate = '-50% 0';\n this.bufferedEl.style.transform = 'scaleX(0)';\n return;\n }\n\n const playedRatio = this.video.currentTime / duration;\n // `translate` (transform DEĞİL): CSS'teki `scale` transform'u da ölçekleyip konumu kaydırırdı.\n this.thumbEl.style.translate = `calc(${this.xAtRatio(playedRatio)}px - 50%) 0`;\n\n let bufferedEnd = 0;\n for (let i = 0; i < this.video.buffered.length; i++) {\n if (this.video.buffered.start(i) <= this.video.currentTime) {\n bufferedEnd = Math.max(bufferedEnd, this.video.buffered.end(i));\n }\n }\n const bufferedRatio = bufferedEnd / duration;\n\n if (this.chapters.length) {\n // Her parça kendi yerel oranıyla dolar: önceki parçalar tam, sonrakiler boş.\n for (const c of this.chapters) {\n const span = c.end - c.start;\n const local = (r: number): number => (span > 0 ? Math.min(1, Math.max(0, (r - c.start) / span)) : 0);\n c.playedEl.style.transform = `scaleX(${local(playedRatio)})`;\n c.bufferedEl.style.transform = `scaleX(${local(bufferedRatio)})`;\n }\n } else {\n this.playedEl.style.transform = `scaleX(${playedRatio})`;\n this.bufferedEl.style.transform = `scaleX(${bufferedRatio})`;\n }\n\n this.el.setAttribute('aria-valuemax', String(Math.floor(duration)));\n this.el.setAttribute('aria-valuenow', String(Math.floor(this.video.currentTime)));\n };\n\n /** 0–1 arası oranda, seek bar üzerine ince bir işaret çizgisi ekler (ör. loop A/B noktaları). */\n addMarker(ratio: number, extraClass = ''): HTMLDivElement {\n const marker = document.createElement('div');\n marker.className = `hp:absolute hp:top-0 hp:bottom-0 hp:w-0.5 hp:bg-on-surface hp:pointer-events-none ${extraClass}`;\n marker.style.left = `${Math.min(1, Math.max(0, ratio)) * 100}%`;\n this.el.appendChild(marker);\n this.markerEls.push(marker);\n return marker;\n }\n\n clearMarkers(): void {\n this.markerEls.forEach((m) => m.remove());\n this.markerEls.length = 0;\n }\n\n refreshLabels(): void {\n this.el.setAttribute('aria-label', this.labels.seekBar);\n }\n\n destroy(): void {\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.resizeObserver.disconnect();\n this.el.removeEventListener('pointermove', this.onHoverMove);\n this.el.removeEventListener('pointerleave', this.onHoverLeave);\n this.video.removeEventListener('play', this.startLoop);\n this.video.removeEventListener('pause', this.stopLoop);\n this.video.removeEventListener('ended', this.stopLoop);\n this.video.removeEventListener('timeupdate', this.render);\n this.video.removeEventListener('progress', this.render);\n this.video.removeEventListener('loadedmetadata', this.render);\n this.clearMarkers();\n this.chaptersEl?.remove();\n }\n}\n","/** <i class=\"hp-icon hp-icon-NAME\"> oluşturur — font yüklemesi theme/icons/hope-icons.css'de. */\nexport function createIcon(name: string, extraClass = ''): HTMLElement {\n const el = document.createElement('i');\n el.className = `hp-icon hp-icon-${name}${extraClass ? ` ${extraClass}` : ''}`;\n el.setAttribute('aria-hidden', 'true');\n return el;\n}\n\n/** Var olan bir <i class=\"hp-icon ...\"> elementinin glyph'ini değiştirir (hp-icon-X -> hp-icon-Y). */\nexport function setIconName(el: HTMLElement, name: string): void {\n el.className = el.className.replace(/hp-icon-[\\w-]+/, `hp-icon-${name}`);\n}\n","import { createIcon, setIconName } from '../icons/Icon';\nimport type { HopeLocaleStrings } from '../i18n/types';\n\n/** Scroll ile ses adımı (tekerlek/trackpad cihazları arası tutarlılık için deltaY'in BÜYÜKLÜĞÜ değil YÖNÜ kullanılıyor — her \"tık\" sabit bir adım). */\nconst WHEEL_VOLUME_STEP = 0.05;\n/** Butondan panele geçerken gerçek (0px) bir boşluk olmasa bile, fare bir an için ikisinin de dışına çıkarsa paneli hemen kapatmamak için kısa bir tolerans. */\nconst HIDE_DELAY_MS = 150;\n\n/** Reklam sırasında ses reklamın sesini yönetir — IMA reklamı içerikten ayrı bir video'da oynatır. */\nexport interface VolumePanelAdHooks {\n isAdActive(): boolean;\n getVolume(): number;\n setVolume(volume: number): void;\n toggleMute(): void;\n}\n\n/** Mute toggle + hover'da açılan dikey ses çubuğu. */\nexport class VolumePanel {\n readonly el: HTMLDivElement;\n /** Dokunmatikte ses butonu gizli; sessiz oynarken görünen \"Sesi aç\" rozeti (chrome dışında monte edilir, otomatik gizlenmez). */\n readonly unmuteBadge: HTMLButtonElement;\n private readonly unmuteText: HTMLSpanElement;\n private readonly button: HTMLButtonElement;\n private readonly iconEl: HTMLElement;\n private readonly slider: HTMLDivElement;\n private readonly sliderFill: HTMLDivElement;\n private readonly video: HTMLVideoElement;\n private readonly labels: HopeLocaleStrings;\n private readonly adHooks: VolumePanelAdHooks;\n private dragging = false;\n private hideTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(video: HTMLVideoElement, labels: HopeLocaleStrings, adHooks: VolumePanelAdHooks) {\n this.video = video;\n this.labels = labels;\n this.adHooks = adHooks;\n\n this.el = document.createElement('div');\n this.el.className = 'hp-volume hp:relative hp:flex hp:items-center';\n\n this.unmuteBadge = document.createElement('button');\n this.unmuteBadge.type = 'button';\n this.unmuteBadge.className = 'hp-unmute-badge';\n this.unmuteBadge.setAttribute('part', 'unmute-badge');\n this.unmuteBadge.appendChild(createIcon('volume-muted', 'hp:text-base'));\n this.unmuteText = document.createElement('span');\n this.unmuteText.textContent = labels.unmute;\n this.unmuteBadge.appendChild(this.unmuteText);\n // Videoya dokunma = oynat/duraklat (HopePlayerElement) — rozete dokunmak onu tetiklemesin.\n this.unmuteBadge.addEventListener('pointerdown', (e) => e.stopPropagation());\n this.unmuteBadge.addEventListener('click', (e) => {\n e.stopPropagation();\n this.unmute();\n });\n\n this.button = document.createElement('button');\n this.button.type = 'button';\n this.button.setAttribute('part', 'volume-button');\n this.button.className =\n 'hp-chip hp:flex hp:items-center hp:justify-center hp:w-[var(--hp-ctrl-btn-size)] hp:h-[var(--hp-ctrl-btn-size)] hp:cursor-pointer';\n this.button.setAttribute('aria-label', labels.mute);\n this.button.dataset.shortcut = 'M';\n\n this.iconEl = createIcon('volume-high', 'hp:text-[length:var(--hp-ctrl-icon-size)]');\n this.button.appendChild(this.iconEl);\n this.el.appendChild(this.button);\n\n // Dikey panel butonun hemen üstünde, arada boşluk yok; görünürlük JS (mouseenter/mouseleave + kısa gecikme) —\n // CSS :hover'da aradaki boşluk paneli kapatıyordu.\n this.slider = document.createElement('div');\n this.slider.setAttribute('part', 'volume-slider');\n this.slider.className =\n 'hp-chip hp:absolute hp:bottom-full hp:left-1/2 hp-center-x hp:mb-2 ' +\n 'hp:w-7 hp:h-20 hp:rounded-full hp:cursor-pointer ' +\n 'hp:flex hp:items-end hp:justify-center hp:p-1.5 ' +\n 'hp:pointer-events-none hp:transition-opacity hp:duration-150 hp:will-change-[opacity]';\n this.slider.style.opacity = '0';\n // .hp-chip'in kendi --hp-chip-radius'u (plain CSS, Tailwind utility'lerinden\n // SONRA derleniyor) rounded-full'u ezer — tam pil şekli için inline override.\n this.slider.style.borderRadius = '9999px';\n this.slider.setAttribute('role', 'slider');\n this.slider.setAttribute('tabindex', '0');\n this.slider.setAttribute('aria-label', labels.volume);\n this.slider.setAttribute('aria-orientation', 'vertical');\n this.slider.setAttribute('aria-valuemin', '0');\n this.slider.setAttribute('aria-valuemax', '100');\n\n const track = document.createElement('div');\n track.className = 'hp:relative hp:w-1.5 hp:h-full hp:rounded-full hp:bg-on-surface/25 hp:overflow-hidden';\n this.slider.appendChild(track);\n\n this.sliderFill = document.createElement('div');\n this.sliderFill.className = 'hp:absolute hp:inset-x-0 hp:bottom-0 hp:bg-accent';\n track.appendChild(this.sliderFill);\n\n this.el.appendChild(this.slider);\n\n this.button.addEventListener('click', this.onToggleMute);\n this.slider.addEventListener('pointerdown', this.onSliderPointerDown);\n this.slider.addEventListener('keydown', this.onSliderKeyDown);\n this.el.addEventListener('mouseenter', this.openNow);\n this.el.addEventListener('mouseleave', this.scheduleHide);\n this.el.addEventListener('focusin', this.openNow);\n this.el.addEventListener('focusout', this.scheduleHide);\n // Buton VEYA panelin üzerindeyken tekerlek/trackpad ile ses ayarı —\n // sayfanın kendisinin kaymasını önlemek için preventDefault.\n this.el.addEventListener('wheel', this.onWheel, { passive: false });\n video.addEventListener('volumechange', this.render);\n video.addEventListener('play', this.render);\n video.addEventListener('pause', this.render);\n\n this.render();\n }\n\n private readonly openNow = (): void => {\n if (this.hideTimer) {\n clearTimeout(this.hideTimer);\n this.hideTimer = null;\n }\n this.slider.style.opacity = '1';\n this.slider.style.pointerEvents = 'auto';\n };\n\n private readonly scheduleHide = (): void => {\n if (this.hideTimer) clearTimeout(this.hideTimer);\n this.hideTimer = setTimeout(() => {\n this.hideTimer = null;\n this.slider.style.opacity = '0';\n this.slider.style.pointerEvents = 'none';\n }, HIDE_DELAY_MS);\n };\n\n private readonly onWheel = (e: WheelEvent): void => {\n e.preventDefault();\n if (this.adHooks.isAdActive()) {\n const current = this.adHooks.getVolume();\n this.adHooks.setVolume(Math.min(1, Math.max(0, current + (e.deltaY < 0 ? WHEEL_VOLUME_STEP : -WHEEL_VOLUME_STEP))));\n this.render();\n return;\n }\n const current = this.video.muted ? 0 : this.video.volume;\n const next = Math.min(1, Math.max(0, current + (e.deltaY < 0 ? WHEEL_VOLUME_STEP : -WHEEL_VOLUME_STEP)));\n this.video.volume = next;\n this.video.muted = next === 0;\n };\n\n /** \"Sesi aç\" rozeti: yalnızca AÇAR (toggle değil) — reklam sırasında reklamın sesini. */\n private unmute(): void {\n if (this.adHooks.isAdActive()) {\n if (this.adHooks.getVolume() === 0) this.adHooks.toggleMute();\n this.render();\n return;\n }\n this.video.muted = false;\n if (this.video.volume === 0) this.video.volume = 0.5;\n }\n\n private readonly onToggleMute = (): void => {\n if (this.adHooks.isAdActive()) {\n this.adHooks.toggleMute();\n this.render();\n return;\n }\n this.video.muted = !this.video.muted;\n if (!this.video.muted && this.video.volume === 0) this.video.volume = 0.5;\n };\n\n /** Dikey çubukta: üst = tam ses (1), alt = sessiz (0) — Y ekseni ters çevrilir. */\n private setFromClientY(clientY: number): void {\n const rect = this.slider.getBoundingClientRect();\n const ratio = rect.height > 0 ? 1 - Math.min(1, Math.max(0, (clientY - rect.top) / rect.height)) : 0;\n if (this.adHooks.isAdActive()) {\n this.adHooks.setVolume(ratio);\n this.render();\n return;\n }\n this.video.volume = ratio;\n this.video.muted = ratio === 0;\n }\n\n private readonly onSliderPointerDown = (e: PointerEvent): void => {\n this.dragging = true;\n this.slider.setPointerCapture(e.pointerId);\n this.setFromClientY(e.clientY);\n this.slider.addEventListener('pointermove', this.onSliderPointerMove);\n this.slider.addEventListener('pointerup', this.onSliderPointerUp);\n };\n\n private readonly onSliderPointerMove = (e: PointerEvent): void => {\n if (this.dragging) this.setFromClientY(e.clientY);\n };\n\n private readonly onSliderPointerUp = (e: PointerEvent): void => {\n this.dragging = false;\n this.slider.releasePointerCapture(e.pointerId);\n this.slider.removeEventListener('pointermove', this.onSliderPointerMove);\n this.slider.removeEventListener('pointerup', this.onSliderPointerUp);\n };\n\n private readonly onSliderKeyDown = (e: KeyboardEvent): void => {\n if (this.adHooks.isAdActive()) {\n if (e.key === 'ArrowUp') {\n this.adHooks.setVolume(Math.min(1, this.adHooks.getVolume() + 0.1));\n e.preventDefault();\n } else if (e.key === 'ArrowDown') {\n this.adHooks.setVolume(Math.max(0, this.adHooks.getVolume() - 0.1));\n e.preventDefault();\n } else {\n return;\n }\n this.render();\n return;\n }\n if (e.key === 'ArrowUp') {\n this.video.volume = Math.min(1, this.video.volume + 0.1);\n this.video.muted = false;\n e.preventDefault();\n } else if (e.key === 'ArrowDown') {\n this.video.volume = Math.max(0, this.video.volume - 0.1);\n e.preventDefault();\n }\n };\n\n private readonly render = (): void => {\n const effectiveVolume = this.adHooks.isAdActive() ? this.adHooks.getVolume() : this.video.muted ? 0 : this.video.volume;\n this.sliderFill.style.height = `${effectiveVolume * 100}%`;\n this.slider.setAttribute('aria-valuenow', String(Math.round(effectiveVolume * 100)));\n\n const label = effectiveVolume === 0 ? this.labels.unmute : this.labels.mute;\n this.button.setAttribute('aria-label', label);\n // Rozet: sessizken ve oynarken (ya da reklam varken) — duraklatılmış bir kapak karesinde kalabalık etmesin.\n const playing = this.adHooks.isAdActive() || !this.video.paused;\n this.unmuteBadge.toggleAttribute('data-visible', effectiveVolume === 0 && playing);\n this.unmuteText.textContent = this.labels.unmute;\n if (effectiveVolume === 0) setIconName(this.iconEl, 'volume-muted');\n else if (effectiveVolume < 0.5) setIconName(this.iconEl, 'volume-low');\n else setIconName(this.iconEl, 'volume-high');\n };\n\n refreshLabels(): void {\n this.slider.setAttribute('aria-label', this.labels.volume);\n this.render();\n }\n\n /** Reklam modu açılıp/kapanınca (`ControlBar.setAdMode`) görüntüyü hemen ad/içerik ses kaynağına göre tazeler — `volumechange` event'i beklemeden. */\n refreshForAdMode(): void {\n this.render();\n }\n\n setIconColor(color: string): void {\n this.iconEl.style.color = color;\n }\n\n setSliderFillColor(color: string): void {\n this.sliderFill.style.background = color;\n }\n\n destroy(): void {\n if (this.hideTimer) clearTimeout(this.hideTimer);\n this.el.removeEventListener('mouseenter', this.openNow);\n this.el.removeEventListener('mouseleave', this.scheduleHide);\n this.el.removeEventListener('focusin', this.openNow);\n this.el.removeEventListener('focusout', this.scheduleHide);\n this.el.removeEventListener('wheel', this.onWheel);\n this.video.removeEventListener('volumechange', this.render);\n this.video.removeEventListener('play', this.render);\n this.video.removeEventListener('pause', this.render);\n this.unmuteBadge.remove();\n }\n}\n","import { createIcon } from '../icons/Icon';\nimport type { HopeLocaleStrings } from '../i18n/types';\n\nexport interface SettingsQualityOption {\n label: string;\n onSelect: () => void;\n}\n\nexport interface SettingsCaptionOption {\n label: string;\n onSelect: () => void;\n}\n\nexport interface SettingsSubmenuItem {\n label: string;\n active: boolean;\n onSelect: () => void;\n}\n\n/** Bir renk paleti satırındaki tek bir swatch — `value` hem swatch'ın KENDİ arkaplanı hem de uygulanacak CSS rengi. */\nexport interface SettingsColorOption {\n value: string;\n active: boolean;\n ariaLabel: string;\n onSelect: () => void;\n}\n\n/** Altyazı açıkken \"Altyazı\" alt menüsüne eklenen görünüm ayarları (boyut, renkler, konumu sıfırla). */\nexport interface SettingsCaptionAppearance {\n sizeLabel: string;\n getSizeOptions: () => SettingsSubmenuItem[];\n bgColorLabel: string;\n getBgColorOptions: () => SettingsColorOption[];\n textColorLabel: string;\n getTextColorOptions: () => SettingsColorOption[];\n resetPositionLabel: string;\n onResetPosition: () => void;\n}\n\n/** Plugin'lerin ana menüye kendi satır + alt menüsünü eklemesi için. */\nexport interface SettingsSubmenuDef {\n key: string;\n title: string;\n getValueLabel: () => string;\n getItems: () => SettingsSubmenuItem[];\n}\n\n/** Ana menüde tek bir aç/kapa satırı — alt menüye inmez. */\nexport interface SettingsToggleRow {\n label: string;\n getValueLabel: () => string;\n onToggle: () => void;\n}\n\ntype PanelId = 'main' | 'speed' | 'quality' | 'captions' | 'captions-size' | 'captions-bg' | 'captions-text' | `custom:${string}`;\n\n/** Ayarlar butonu + popup: ana liste (Hız/Kalite/Altyazı) → alt liste. */\nexport class SettingsMenu {\n readonly el: HTMLDivElement;\n private readonly button: HTMLButtonElement;\n private readonly panel: HTMLDivElement;\n private readonly video: HTMLVideoElement;\n private readonly playbackRates: number[];\n private readonly labels: HopeLocaleStrings;\n\n private qualities: SettingsQualityOption[] = [];\n private activeQualityLabel: string;\n private captions: SettingsCaptionOption[] = [];\n private activeCaptionLabel: string;\n private captionAppearance: SettingsCaptionAppearance | null = null;\n private qrResumeToggle: SettingsToggleRow | null = null;\n private open = false;\n private currentPanel: PanelId = 'main';\n private submenus: SettingsSubmenuDef[] = [];\n\n constructor(video: HTMLVideoElement, playbackRates: number[], labels: HopeLocaleStrings) {\n this.video = video;\n this.playbackRates = playbackRates;\n this.labels = labels;\n this.activeQualityLabel = labels.autoQuality;\n this.activeCaptionLabel = labels.captionsOff;\n\n this.el = document.createElement('div');\n this.el.className = 'hp:relative';\n\n this.button = document.createElement('button');\n this.button.type = 'button';\n this.button.setAttribute('aria-label', labels.settings);\n this.button.className =\n 'hp-chip hp:flex hp:items-center hp:justify-center hp:w-[var(--hp-ctrl-btn-size)] hp:h-[var(--hp-ctrl-btn-size)] hp:cursor-pointer';\n this.button.appendChild(createIcon('settings', 'hp:text-[length:var(--hp-ctrl-icon-size)]'));\n\n this.panel = document.createElement('div');\n this.panel.className =\n 'hp-chip hp-chip-panel hp:hidden hp:absolute hp:bottom-full hp:right-0 hp:mb-2 hp:w-48 hp:max-h-64 hp:overflow-y-auto hp:text-sm hp:py-1';\n\n this.el.appendChild(this.button);\n this.el.appendChild(this.panel);\n\n this.button.addEventListener('click', (e) => {\n e.stopPropagation();\n this.toggle();\n });\n document.addEventListener('click', this.onDocumentClick, true);\n\n this.renderMain();\n }\n\n setQualities(options: SettingsQualityOption[], activeLabel: string): void {\n this.qualities = options;\n this.activeQualityLabel = activeLabel;\n if (this.currentPanel === 'main' || this.currentPanel === 'quality') this.render();\n }\n\n setCaptions(options: SettingsCaptionOption[], activeLabel: string): void {\n this.captions = options;\n this.activeCaptionLabel = activeLabel;\n if (this.currentPanel === 'main' || this.currentPanel === 'captions') this.render();\n }\n\n /** Altyazı AÇIKKEN \"Altyazı\" alt menüsüne eklenecek Boyut/Renk/Konum satırları — `null` kaldırır. */\n setCaptionAppearance(appearance: SettingsCaptionAppearance | null): void {\n this.captionAppearance = appearance;\n if (\n this.currentPanel === 'captions' ||\n this.currentPanel === 'captions-size' ||\n this.currentPanel === 'captions-bg' ||\n this.currentPanel === 'captions-text'\n ) {\n this.render();\n }\n }\n\n /** Ana menüye tek aç/kapa satırı ekler (ör. QrResume). */\n setQrResumeToggle(toggle: SettingsToggleRow | null): void {\n this.qrResumeToggle = toggle;\n if (this.currentPanel === 'main') this.renderMain();\n }\n\n /** Plugin'lerin (ör. dubbing) ana menüye kendi satır + alt menüsünü eklemesi için. */\n registerSubmenu(def: SettingsSubmenuDef): void {\n this.submenus = this.submenus.filter((s) => s.key !== def.key);\n this.submenus.push(def);\n if (this.currentPanel === 'main') this.renderMain();\n }\n\n unregisterSubmenu(key: string): void {\n this.submenus = this.submenus.filter((s) => s.key !== key);\n if (this.currentPanel === 'main') this.renderMain();\n else if (this.currentPanel === `custom:${key}`) this.renderMain();\n }\n\n private toggle(): void {\n this.open ? this.close() : this.openMenu();\n }\n\n private openMenu(): void {\n this.open = true;\n this.currentPanel = 'main';\n this.panel.classList.remove('hp:hidden');\n this.renderMain();\n }\n\n private close(): void {\n this.open = false;\n this.panel.classList.add('hp:hidden');\n }\n\n private readonly onDocumentClick = (e: MouseEvent): void => {\n // composedPath(): Shadow DOM'da e.target host'a retarget edilir; contains() menünün kendi satırlarını \"dışarı tıklama\" sanardı.\n if (this.open && !e.composedPath().includes(this.el)) this.close();\n };\n\n private row(label: string, value: string, onClick: () => void): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className =\n 'hp:flex hp:items-center hp:justify-between hp:w-full hp:px-3 hp:py-2 hp:text-left hp:bg-transparent hp:border-0 hp:cursor-pointer hp:text-on-surface hp:hover:bg-on-surface/10';\n btn.innerHTML = `<span>${label}</span><span class=\"hp:text-on-surface-muted hp:text-xs hp:flex hp:items-center hp:gap-1\">${value}</span>`;\n btn.addEventListener('click', onClick);\n return btn;\n }\n\n private backRow(title: string, onBack: () => void): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className =\n 'hp:flex hp:items-center hp:gap-2 hp:w-full hp:px-3 hp:py-2 hp:text-left hp:bg-transparent hp:border-0 hp:cursor-pointer hp:text-on-surface hp:font-medium hp:hover:bg-on-surface/10';\n btn.appendChild(createIcon('chevron-left', 'hp:text-sm'));\n const span = document.createElement('span');\n span.textContent = title;\n btn.appendChild(span);\n btn.addEventListener('click', onBack);\n return btn;\n }\n\n private render(): void {\n if (this.currentPanel === 'main') this.renderMain();\n else if (this.currentPanel === 'speed') this.renderSpeed();\n else if (this.currentPanel === 'quality') this.renderQuality();\n else if (this.currentPanel === 'captions') this.renderCaptions();\n else if (this.currentPanel === 'captions-size') this.renderCaptionsSize();\n else if (this.currentPanel === 'captions-bg') this.renderCaptionColorPanel('bg');\n else if (this.currentPanel === 'captions-text') this.renderCaptionColorPanel('text');\n else {\n const key = this.currentPanel.slice('custom:'.length);\n const def = this.submenus.find((s) => s.key === key);\n if (def) this.renderSubmenu(def);\n else this.renderMain();\n }\n }\n\n private renderMain(): void {\n this.currentPanel = 'main';\n this.panel.innerHTML = '';\n this.panel.appendChild(\n this.row(this.labels.playbackSpeed, this.video.playbackRate === 1 ? this.labels.normal : `${this.video.playbackRate}x`, () => {\n this.currentPanel = 'speed';\n this.renderSpeed();\n })\n );\n if (this.qualities.length > 0) {\n this.panel.appendChild(\n this.row(this.labels.quality, this.activeQualityLabel, () => {\n this.currentPanel = 'quality';\n this.renderQuality();\n })\n );\n }\n if (this.captions.length > 0) {\n this.panel.appendChild(\n this.row(this.labels.captions, this.activeCaptionLabel, () => {\n this.currentPanel = 'captions';\n this.renderCaptions();\n })\n );\n }\n for (const def of this.submenus) {\n this.panel.appendChild(\n this.row(def.title, def.getValueLabel(), () => {\n this.currentPanel = `custom:${def.key}`;\n this.renderSubmenu(def);\n })\n );\n }\n if (this.qrResumeToggle) {\n const toggle = this.qrResumeToggle;\n // Menü kapanmadan durumu değiştirip yeniden render eder.\n this.panel.appendChild(\n this.row(toggle.label, toggle.getValueLabel(), () => {\n toggle.onToggle();\n this.renderMain();\n })\n );\n }\n }\n\n private renderSubmenu(def: SettingsSubmenuDef): void {\n this.panel.innerHTML = '';\n this.panel.appendChild(this.backRow(def.title, () => this.renderMain()));\n for (const item of def.getItems()) {\n this.panel.appendChild(\n this.row(item.label, item.active ? '<i class=\"hp-icon hp-icon-check\"></i>' : '', () => {\n item.onSelect();\n this.close();\n })\n );\n }\n }\n\n private renderSpeed(): void {\n this.panel.innerHTML = '';\n this.panel.appendChild(this.backRow(this.labels.playbackSpeed, () => this.renderMain()));\n for (const rate of this.playbackRates) {\n const active = this.video.playbackRate === rate;\n const btn = this.row(rate === 1 ? this.labels.normal : `${rate}x`, active ? '<i class=\"hp-icon hp-icon-check\"></i>' : '', () => {\n this.video.playbackRate = rate;\n this.close();\n });\n this.panel.appendChild(btn);\n }\n }\n\n private renderQuality(): void {\n this.panel.innerHTML = '';\n this.panel.appendChild(this.backRow(this.labels.quality, () => this.renderMain()));\n for (const q of this.qualities) {\n const active = q.label === this.activeQualityLabel;\n this.panel.appendChild(\n this.row(q.label, active ? '<i class=\"hp-icon hp-icon-check\"></i>' : '', () => {\n q.onSelect();\n this.close();\n })\n );\n }\n }\n\n private renderCaptions(): void {\n this.panel.innerHTML = '';\n this.panel.appendChild(this.backRow(this.labels.captions, () => this.renderMain()));\n for (const c of this.captions) {\n const active = c.label === this.activeCaptionLabel;\n this.panel.appendChild(\n this.row(c.label, active ? '<i class=\"hp-icon hp-icon-check\"></i>' : '', () => {\n c.onSelect();\n this.close();\n })\n );\n }\n // Boyut/Renk/Konum satırları altyazı KAPALIYKEN anlamsız — yalnızca bir dil seçiliyken gösteriliyor.\n if (this.captionAppearance && this.activeCaptionLabel !== this.labels.captionsOff) {\n const appearance = this.captionAppearance;\n this.panel.appendChild(\n this.row(appearance.sizeLabel, '', () => {\n this.currentPanel = 'captions-size';\n this.renderCaptionsSize();\n })\n );\n this.panel.appendChild(\n this.row(appearance.bgColorLabel, '', () => {\n this.currentPanel = 'captions-bg';\n this.renderCaptionColorPanel('bg');\n })\n );\n this.panel.appendChild(\n this.row(appearance.textColorLabel, '', () => {\n this.currentPanel = 'captions-text';\n this.renderCaptionColorPanel('text');\n })\n );\n this.panel.appendChild(\n this.row(appearance.resetPositionLabel, '', () => {\n appearance.onResetPosition();\n this.close();\n })\n );\n }\n }\n\n private renderCaptionsSize(): void {\n this.panel.innerHTML = '';\n const appearance = this.captionAppearance;\n this.panel.appendChild(this.backRow(appearance?.sizeLabel ?? this.labels.captionSize, () => this.renderCaptions()));\n if (!appearance) return;\n for (const item of appearance.getSizeOptions()) {\n this.panel.appendChild(\n this.row(item.label, item.active ? '<i class=\"hp-icon hp-icon-check\"></i>' : '', () => {\n item.onSelect();\n this.close();\n })\n );\n }\n }\n\n /** \"Arka Plan Rengi\" / \"Yazı Rengi\" — düz metin satırları yerine renkli swatch grid'i (YouTube'un kendi altyazı renk seçici deseni). */\n private renderCaptionColorPanel(kind: 'bg' | 'text'): void {\n this.panel.innerHTML = '';\n const appearance = this.captionAppearance;\n const title = kind === 'bg' ? (appearance?.bgColorLabel ?? this.labels.captionBgColor) : (appearance?.textColorLabel ?? this.labels.captionTextColor);\n this.panel.appendChild(this.backRow(title, () => this.renderCaptions()));\n if (!appearance) return;\n\n const grid = document.createElement('div');\n grid.className = 'hp:flex hp:flex-wrap hp:gap-2 hp:px-3 hp:py-2';\n const options = kind === 'bg' ? appearance.getBgColorOptions() : appearance.getTextColorOptions();\n for (const opt of options) {\n const swatch = document.createElement('button');\n swatch.type = 'button';\n swatch.setAttribute('aria-label', opt.ariaLabel);\n swatch.className = 'hp:w-7 hp:h-7 hp:rounded-full hp:cursor-pointer hp:flex-shrink-0 hp:border hp:border-on-surface/20';\n swatch.style.background = opt.value;\n swatch.style.outline = opt.active ? '2px solid currentColor' : '2px solid transparent';\n swatch.style.outlineOffset = '2px';\n swatch.addEventListener('click', () => {\n opt.onSelect();\n this.render();\n });\n grid.appendChild(swatch);\n }\n this.panel.appendChild(grid);\n }\n\n /** Dil sonradan değişince statik buton etiketini tazeler + mevcut panel zaten güncel `this.labels`'ı okuyarak yeniden render edilir. */\n refreshLabels(): void {\n this.button.setAttribute('aria-label', this.labels.settings);\n this.render();\n }\n\n destroy(): void {\n document.removeEventListener('click', this.onDocumentClick, true);\n }\n}\n","import { SeekBar } from './SeekBar';\nimport { VolumePanel, type VolumePanelAdHooks } from './VolumePanel';\nimport { SettingsMenu, type SettingsCaptionOption, type SettingsQualityOption } from './SettingsMenu';\nimport { formatTime } from '../utils/format-time';\nimport { createIcon, setIconName } from '../icons/Icon';\nimport type { HopeLocaleStrings } from '../i18n/types';\n\n/** `title` bilerek set edilmiyor — tooltip'i Tooltip.ts gösteriyor, native tooltip üstüne binmesin. */\n/** Canlı uçtan bu kadar saniyeden fazla gerideyse rozet \"geride\" (gri) sayılır — HLS'in doğal gecikmesi (birkaç segment) bunun altında kalır. */\nconst LIVE_EDGE_TOLERANCE_SEC = 15;\n/** Player bu genişliğin (px) altındaysa kompakt (mobil) düzen: sağ grup üst sağa, tam ekran altta. */\nconst COMPACT_MAX_WIDTH = 480;\n\nfunction setButtonLabel(btn: HTMLButtonElement, label: string): void {\n btn.setAttribute('aria-label', label);\n}\n\n/** `shortcut`: Tooltip.ts'in gösterdiği küçük \"pill\" (ör. \"F\") — yalnızca `KeyboardController`'daki GERÇEK bir tuşla birebir eşleşiyorsa veriliyor, uydurma değil. */\nfunction iconButton(label: string, iconName: string, shortcut?: string): { btn: HTMLButtonElement; icon: HTMLElement } {\n const btn = document.createElement('button');\n btn.type = 'button';\n setButtonLabel(btn, label);\n if (shortcut) btn.dataset.shortcut = shortcut;\n // hp-chip: tema yüzeyi; boyut --hp-ctrl-* token'larından (fullscreen/dokunmatikte büyür).\n btn.className =\n 'hp-chip hp:flex hp:items-center hp:justify-center hp:w-[var(--hp-ctrl-btn-size)] hp:h-[var(--hp-ctrl-btn-size)] hp:cursor-pointer hp:shrink-0';\n const icon = createIcon(iconName, 'hp:text-[length:var(--hp-ctrl-icon-size)]');\n btn.appendChild(icon);\n return { btn, icon };\n}\n\nexport interface ControlBarCallbacks {\n onRequestFullscreen: () => void;\n onExitFullscreen: () => void;\n isFullscreen: () => boolean;\n /** Reklam modunda oynat/duraklat reklamı yönetir — IMA reklamı içerikten ayrı bir video'da oynatır. */\n isAdActive: () => boolean;\n adTogglePlay: () => void;\n adIsPaused: () => boolean;\n adVolume: VolumePanelAdHooks;\n}\n\n/** Alt kontrol çubuğunu kurar; alt bileşenleri (SeekBar/VolumePanel/SettingsMenu) birleştirir. */\nexport class ControlBar {\n readonly el: HTMLDivElement;\n readonly seekBar: SeekBar;\n readonly volumePanel: VolumePanel;\n readonly settingsMenu: SettingsMenu;\n\n private readonly video: HTMLVideoElement;\n private readonly labels: HopeLocaleStrings;\n private readonly playButton: HTMLButtonElement;\n private readonly playIcon: HTMLElement;\n private readonly pipButton: HTMLButtonElement;\n private readonly fullscreenButton: HTMLButtonElement;\n private readonly fullscreenIcon: HTMLElement;\n private readonly timeLabel: HTMLButtonElement;\n private showRemaining = false;\n /** Kompakt düzende (player < 480px) sağ grubun taşındığı üst bar; tam ekran altta kalır. */\n readonly topEl: HTMLDivElement;\n private readonly bottomRow: HTMLDivElement;\n private readonly rightGroup: HTMLDivElement;\n private readonly fullscreenSlot: HTMLDivElement;\n private compact = false;\n private readonly resizeObserver: ResizeObserver;\n private readonly liveBadge: HTMLButtonElement;\n private readonly liveText: HTMLSpanElement;\n private adMode = false;\n private readonly callbacks: ControlBarCallbacks;\n private row!: HTMLDivElement;\n private extraButtonAnchor!: HTMLElement;\n\n constructor(video: HTMLVideoElement, playbackRates: number[], callbacks: ControlBarCallbacks, labels: HopeLocaleStrings) {\n this.video = video;\n this.callbacks = callbacks;\n this.labels = labels;\n\n this.el = document.createElement('div');\n this.el.setAttribute('part', 'control-bar');\n // pointer-events-none: kapsayıcı alt şeridin tamamını kaplıyor; açık olsaydı boş alanlar reklamın\n // \"Reklamı Geç\" butonu dahil alttaki tıklamaları yutardı. Yalnızca gerçek yüzeyler pointer-events-auto.\n this.el.className =\n 'hp:absolute hp:inset-x-0 hp:bottom-0 hp:flex hp:flex-col hp:gap-1 hp:px-3 hp:pb-2 hp:pt-6 hp:pointer-events-none ' +\n 'hp:transition-opacity hp:duration-200';\n\n this.seekBar = new SeekBar(video, labels);\n this.seekBar.el.classList.add('hp:pointer-events-auto');\n this.el.appendChild(this.seekBar.el);\n\n const row = document.createElement('div');\n row.className = 'hp:flex hp:items-center hp:gap-2';\n this.el.appendChild(row);\n this.bottomRow = row;\n\n // Sol küme: oynat/duraklat + ses + süre — kendi transparan \"pill\"\n // yüzeyini paylaşıyor (`.hp-group`, theme/tailwind.css).\n const leftGroup = document.createElement('div');\n leftGroup.className = 'hp-group hp:flex hp:items-center hp:gap-1 hp:px-1.5 hp:py-1 hp:shrink-0 hp:pointer-events-auto';\n row.appendChild(leftGroup);\n\n const play = iconButton(labels.play, 'play', 'K');\n this.playButton = play.btn;\n this.playIcon = play.icon;\n this.playButton.setAttribute('part', 'play-pause-button');\n this.playButton.addEventListener('click', () => this.togglePlay());\n leftGroup.appendChild(this.playButton);\n\n this.volumePanel = new VolumePanel(video, labels, callbacks.adVolume);\n leftGroup.appendChild(this.volumePanel.el);\n\n this.timeLabel = document.createElement('button');\n this.timeLabel.type = 'button';\n this.timeLabel.setAttribute('part', 'time-display');\n this.timeLabel.className =\n 'hp:text-xs hp:text-on-surface hp:tabular-nums hp:whitespace-nowrap hp:px-1 hp:bg-transparent hp:border-0 hp:cursor-pointer hp:select-none hp:p-0 hp:hover:opacity-80 hp:transition-opacity hp:focus-visible:outline-none hp:focus-visible:ring-1 hp:focus-visible:ring-accent hp:rounded';\n this.timeLabel.textContent = '0:00 / 0:00';\n this.timeLabel.addEventListener('click', this.onTimeClick);\n leftGroup.appendChild(this.timeLabel);\n\n // Canlı yayında (duration === Infinity) süre etiketinin YERİNE —\n // YouTube tarzı \"● CANLI\": canlı uçtayken nokta kırmızı, geriye\n // sarılmışsa gri ve tıklayınca canlı uca döner.\n this.liveBadge = document.createElement('button');\n this.liveBadge.type = 'button';\n this.liveBadge.className = 'hp-live-badge';\n this.liveBadge.setAttribute('part', 'live-badge');\n this.liveBadge.setAttribute('aria-label', labels.goToLive);\n const liveDot = document.createElement('span');\n liveDot.className = 'hp-live-dot';\n this.liveText = document.createElement('span');\n this.liveText.textContent = labels.live;\n this.liveBadge.append(liveDot, this.liveText);\n this.liveBadge.style.display = 'none';\n this.liveBadge.addEventListener('click', this.goToLive);\n leftGroup.appendChild(this.liveBadge);\n\n const spacer = document.createElement('div');\n spacer.className = 'hp:flex-1';\n row.appendChild(spacer);\n\n // Sağ küme: ayarlar + plugin'lerin addButton/addElement ile eklediği\n // kendi butonları (ayarlardan ÖNCE eklenir) + PIP + tam ekran — aynı\n // pill yüzeyi.\n const rightGroup = document.createElement('div');\n rightGroup.className = 'hp-group hp:flex hp:items-center hp:gap-1 hp:px-1.5 hp:py-1 hp:shrink-0 hp:pointer-events-auto';\n row.appendChild(rightGroup);\n this.rightGroup = rightGroup;\n\n this.settingsMenu = new SettingsMenu(video, playbackRates, labels);\n rightGroup.appendChild(this.settingsMenu.el);\n this.extraButtonAnchor = this.settingsMenu.el;\n this.row = rightGroup;\n\n const pip = iconButton(labels.pip, 'pip');\n this.pipButton = pip.btn;\n this.pipButton.addEventListener('click', () => this.togglePip());\n if (!document.pictureInPictureEnabled) this.pipButton.style.display = 'none';\n rightGroup.appendChild(this.pipButton);\n\n const fullscreen = iconButton(labels.fullscreenEnter, 'fullscreen-enter', 'F');\n this.fullscreenButton = fullscreen.btn;\n this.fullscreenIcon = fullscreen.icon;\n this.fullscreenButton.addEventListener('click', () => this.toggleFullscreen());\n rightGroup.appendChild(this.fullscreenButton);\n\n this.topEl = document.createElement('div');\n this.topEl.className = 'hp-top-bar';\n this.topEl.setAttribute('part', 'top-bar');\n this.fullscreenSlot = document.createElement('div');\n this.fullscreenSlot.className = 'hp-group hp:items-center hp:px-1.5 hp:py-1 hp:shrink-0 hp:pointer-events-auto';\n this.fullscreenSlot.style.display = 'none';\n row.appendChild(this.fullscreenSlot);\n\n this.resizeObserver = new ResizeObserver(() => this.updateLayout());\n this.resizeObserver.observe(this.el);\n\n video.addEventListener('play', this.renderPlayState);\n video.addEventListener('pause', this.renderPlayState);\n video.addEventListener('timeupdate', this.renderTime);\n video.addEventListener('loadedmetadata', this.renderTime);\n video.addEventListener('durationchange', this.renderTime);\n video.addEventListener('progress', this.renderTime);\n this.renderPlayState();\n this.renderTime();\n }\n\n /** Player genişliğine göre normal / kompakt (mobil) düzen arasında geçiş — yalnızca eşik geçilince DOM taşınır. */\n private updateLayout(): void {\n const width = this.el.getBoundingClientRect().width;\n if (width === 0) return;\n const compact = width < COMPACT_MAX_WIDTH;\n if (compact === this.compact) return;\n this.compact = compact;\n this.el.toggleAttribute('data-compact', compact);\n // Video alanı da bilsin — altyazı boyutu küçük player'da küçülüyor (tailwind.css `.video-area[data-compact]`).\n this.el.closest('.video-area')?.toggleAttribute('data-compact', compact);\n if (compact) {\n this.fullscreenSlot.appendChild(this.fullscreenButton);\n this.fullscreenSlot.style.display = this.adMode ? 'none' : 'flex';\n this.topEl.appendChild(this.rightGroup);\n } else {\n this.rightGroup.appendChild(this.fullscreenButton);\n this.bottomRow.insertBefore(this.rightGroup, this.fullscreenSlot);\n this.fullscreenSlot.style.display = 'none';\n }\n }\n\n setFullscreenState(isFullscreen: boolean): void {\n setIconName(this.fullscreenIcon, isFullscreen ? 'fullscreen-exit' : 'fullscreen-enter');\n setButtonLabel(this.fullscreenButton, isFullscreen ? this.labels.fullscreenExit : this.labels.fullscreenEnter);\n }\n\n /** Dil sonradan değişince (`options.locale`/`labels`) statik (reaktif olarak yeniden render edilmeyen) etiketleri tazeler. */\n refreshLabels(): void {\n this.renderPlayState();\n setButtonLabel(this.pipButton, this.labels.pip);\n setButtonLabel(this.liveBadge, this.labels.goToLive);\n this.liveText.textContent = this.labels.live;\n this.setFullscreenState(this.callbacks.isFullscreen());\n this.seekBar.refreshLabels();\n this.volumePanel.refreshLabels();\n this.settingsMenu.refreshLabels();\n }\n\n /** Reklam modu: seek bar, süre ve sağ grup gizlenir; oynat/duraklat + ses kalır. */\n setAdMode(active: boolean): void {\n const display = active ? 'none' : '';\n this.adMode = active;\n this.seekBar.el.style.display = display;\n this.row.style.display = display;\n if (this.compact) this.fullscreenSlot.style.display = active ? 'none' : 'flex';\n // Süre etiketi / canlı rozeti hangisinin görüneceğine renderTime karar veriyor (ad modunda ikisi de gizli).\n this.renderTime();\n const iconColor = active ? '#202020' : '';\n this.playIcon.style.color = iconColor;\n this.volumePanel.setIconColor(iconColor);\n this.volumePanel.setSliderFillColor(iconColor);\n // Oynat/duraklat ikonu + ses göstergesi, ad moduna girer/çıkarken\n // doğru kaynağı (reklam ya da içerik) hemen yansıtsın.\n this.renderPlayState();\n this.volumePanel.refreshForAdMode();\n }\n\n /** `AdsController`'ın IMA'nın KENDİ UI'ı üzerinden (ör. reklam video'suna tıklama) gelen PAUSED/RESUMED event'leri için — oynat/duraklat ikonunu tazeler. */\n refreshAdPlayState(): void {\n this.renderPlayState();\n }\n\n setQualities(options: SettingsQualityOption[], activeLabel: string): void {\n this.settingsMenu.setQualities(options, activeLabel);\n }\n\n setCaptions(options: SettingsCaptionOption[], activeLabel: string): void {\n this.settingsMenu.setCaptions(options, activeLabel);\n }\n\n /** Plugin'lerin (loop-section vb.) kontrol çubuğuna kendi butonlarını eklemesi için — ayarlar menüsünden önce yerleştirilir. */\n addButton(label: string, iconName: string, onClick: () => void): { btn: HTMLButtonElement; icon: HTMLElement } {\n const { btn, icon } = iconButton(label, iconName);\n btn.addEventListener('click', onClick);\n this.row.insertBefore(btn, this.extraButtonAnchor);\n return { btn, icon };\n }\n\n /** Plugin'lerin (live-wall-clock vb.) kontrol çubuğuna buton olmayan bir element (ör. saat göstergesi) eklemesi için. */\n private readonly onTimeClick = (e: MouseEvent): void => {\n e.stopPropagation();\n this.toggleTimeMode();\n };\n\n toggleTimeMode(): void {\n this.showRemaining = !this.showRemaining;\n this.renderTime();\n }\n\n setShowRemaining(show: boolean): void {\n if (this.showRemaining === show) return;\n this.showRemaining = show;\n this.renderTime();\n }\n\n getShowRemaining(): boolean {\n return this.showRemaining;\n }\n\n addElement(el: HTMLElement): void {\n this.row.insertBefore(el, this.extraButtonAnchor);\n }\n\n private togglePlay(): void {\n if (this.callbacks.isAdActive()) {\n this.callbacks.adTogglePlay();\n this.renderPlayState();\n return;\n }\n if (this.video.paused) void this.video.play();\n else this.video.pause();\n }\n\n private async togglePip(): Promise<void> {\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else {\n await this.video.requestPictureInPicture();\n }\n } catch {\n // PIP desteklenmiyor/izin verilmedi — sessizce yoksay.\n }\n }\n\n private toggleFullscreen(): void {\n if (this.callbacks.isFullscreen()) this.callbacks.onExitFullscreen();\n else this.callbacks.onRequestFullscreen();\n }\n\n private readonly renderPlayState = (): void => {\n const paused = this.callbacks.isAdActive() ? this.callbacks.adIsPaused() : this.video.paused;\n setIconName(this.playIcon, paused ? 'play' : 'pause');\n setButtonLabel(this.playButton, paused ? this.labels.play : this.labels.pause);\n };\n\n /** Canlı uç (media-time) — seekable sonu; native HLS'te DVR'sız canlıda seekable boş kalabildiği için buffered sonu (bkz. LiveWallClock.isLive notu). */\n private liveEdge(): number | null {\n const { seekable, buffered } = this.video;\n if (seekable.length) return seekable.end(seekable.length - 1);\n if (buffered.length) return buffered.end(buffered.length - 1);\n return null;\n }\n\n private readonly renderTime = (): void => {\n const isLive = this.video.duration === Infinity;\n this.timeLabel.style.display = this.adMode || isLive ? 'none' : '';\n this.liveBadge.style.display = !this.adMode && isLive ? '' : 'none';\n\n if (!isLive) {\n const duration = this.video.duration;\n const current = this.video.currentTime;\n if (this.showRemaining) {\n const remaining = Math.max(0, (Number.isFinite(duration) ? duration : 0) - current);\n this.timeLabel.textContent = `-${formatTime(remaining)} / ${formatTime(duration)}`;\n } else {\n this.timeLabel.textContent = `${formatTime(current)} / ${formatTime(duration)}`;\n }\n return;\n }\n // Canlı uçtan LIVE_EDGE_TOLERANCE_SEC'ten fazla gerideyse \"geride\" (gri nokta, tıklanınca uca döner).\n const edge = this.liveEdge();\n const behind = edge !== null && edge - this.video.currentTime > LIVE_EDGE_TOLERANCE_SEC;\n this.liveBadge.toggleAttribute('data-behind', behind);\n };\n\n private readonly goToLive = (): void => {\n const edge = this.liveEdge();\n if (edge === null) return;\n // Tam uca değil, biraz gerisine — buffered'ın en sonuna seek edince oynatma takılabiliyor.\n this.video.currentTime = Math.max(0, edge - 1);\n if (this.video.paused) void this.video.play().catch(() => {});\n this.renderTime();\n };\n\n destroy(): void {\n this.timeLabel.removeEventListener('click', this.onTimeClick);\n this.video.removeEventListener('play', this.renderPlayState);\n this.video.removeEventListener('pause', this.renderPlayState);\n this.video.removeEventListener('timeupdate', this.renderTime);\n this.video.removeEventListener('loadedmetadata', this.renderTime);\n this.video.removeEventListener('durationchange', this.renderTime);\n this.video.removeEventListener('progress', this.renderTime);\n this.resizeObserver.disconnect();\n this.topEl.remove();\n this.seekBar.destroy();\n this.settingsMenu.destroy();\n }\n}\n","/**\n * Tema uyumlu hover tooltip — tek delegasyon dinleyicisi; aria-label'lı her button/slider için otomatik.\n * Kısayol pill'i data-shortcut'tan. Yalnızca hover yapabilen cihazlarda.\n */\nconst SHOW_DELAY_MS = 450;\nconst HIDE_DELAY_MS = 60;\nconst GAP_PX = 8;\nconst EDGE_PADDING_PX = 6;\n/** Bu selector'a uyan ama tooltip İSTEMEYEN elementler (ör. seek bar — sürekli üzerinde gezinilen bir kontrol, tooltip rahatsız eder). */\nconst EXCLUDE_PARTS = new Set(['seek-bar', 'time-display']);\n\n/** Birincil giriş hover yapabiliyor mu (fare/trackpad) — dokunmatik telefon/tablette false. */\nfunction canHover(): boolean {\n return typeof window.matchMedia !== 'function' || window.matchMedia('(hover: hover)').matches;\n}\n\nexport class TooltipController {\n private readonly el: HTMLDivElement;\n private readonly labelEl: HTMLSpanElement;\n private readonly keyEl: HTMLSpanElement;\n private showTimer: ReturnType<typeof setTimeout> | null = null;\n private hideTimer: ReturnType<typeof setTimeout> | null = null;\n private currentTarget: HTMLElement | null = null;\n /** Gösterim gecikmesi (SHOW_DELAY_MS) içinde bekleyen hedef — `currentTarget` yalnızca gerçekten gösterilince set ediliyor. */\n private pendingTarget: HTMLElement | null = null;\n\n constructor(private readonly mountEl: HTMLElement) {\n this.el = document.createElement('div');\n this.el.setAttribute('part', 'tooltip');\n this.el.setAttribute('role', 'tooltip');\n this.el.className =\n 'hp-tooltip hp:absolute hp:z-40 hp:flex hp:items-center hp:gap-1.5 hp:px-2 hp:py-1 hp:rounded hp:text-xs ' +\n 'hp:whitespace-nowrap hp:pointer-events-none hp:opacity-0 hp:transition-opacity hp:duration-100';\n this.el.style.visibility = 'hidden';\n\n this.labelEl = document.createElement('span');\n this.el.appendChild(this.labelEl);\n\n this.keyEl = document.createElement('span');\n this.keyEl.className = 'hp-tooltip-key';\n this.el.appendChild(this.keyEl);\n\n mountEl.appendChild(this.el);\n\n mountEl.addEventListener('mouseover', this.onMouseOver);\n mountEl.addEventListener('mouseout', this.onMouseOut);\n mountEl.addEventListener('focusin', this.onFocusIn);\n mountEl.addEventListener('focusout', this.onFocusOut);\n mountEl.addEventListener('pointerdown', this.hideNow);\n }\n\n destroy(): void {\n if (this.showTimer) clearTimeout(this.showTimer);\n if (this.hideTimer) clearTimeout(this.hideTimer);\n this.mountEl.removeEventListener('mouseover', this.onMouseOver);\n this.mountEl.removeEventListener('mouseout', this.onMouseOut);\n this.mountEl.removeEventListener('focusin', this.onFocusIn);\n this.mountEl.removeEventListener('focusout', this.onFocusOut);\n this.mountEl.removeEventListener('pointerdown', this.hideNow);\n this.el.remove();\n }\n\n private matchTarget(fromEl: EventTarget | null): HTMLElement | null {\n const el = fromEl as HTMLElement | null;\n const target = el?.closest?.('button[aria-label], [role=\"slider\"][aria-label]') as HTMLElement | null;\n if (!target) return null;\n const part = target.getAttribute('part');\n if (part && EXCLUDE_PARTS.has(part)) return null;\n // Görünür değilse (ör. display:none pip butonu, kapalı bir panel) ölç/konumlandırma anlamsız.\n if (target.offsetParent === null && target !== document.activeElement) return null;\n return target;\n }\n\n private readonly onMouseOver = (e: MouseEvent): void => {\n const target = this.matchTarget(e.target);\n if (!target || target === this.currentTarget) return;\n this.scheduleShow(target);\n };\n\n private readonly onMouseOut = (e: MouseEvent): void => {\n const target = this.matchTarget(e.target);\n // Gecikme içinde çıkılırsa bekleyen gösterimi de iptal et — currentTarget yalnızca gösterimden sonra set ediliyor.\n if (!target || (target !== this.currentTarget && target !== this.pendingTarget)) return;\n const related = e.relatedTarget as Node | null;\n if (related && target.contains(related)) return;\n this.scheduleHide();\n };\n\n private readonly onFocusIn = (e: FocusEvent): void => {\n const target = this.matchTarget(e.target);\n if (!target) return;\n this.show(target);\n };\n\n private readonly onFocusOut = (e: FocusEvent): void => {\n const target = this.matchTarget(e.target);\n if (!target || target !== this.currentTarget) return;\n this.hideNow();\n };\n\n private scheduleShow(target: HTMLElement): void {\n if (this.hideTimer) {\n clearTimeout(this.hideTimer);\n this.hideTimer = null;\n }\n if (this.showTimer) clearTimeout(this.showTimer);\n this.pendingTarget = target;\n this.showTimer = setTimeout(() => {\n this.showTimer = null;\n this.pendingTarget = null;\n this.show(target);\n }, SHOW_DELAY_MS);\n }\n\n private scheduleHide(): void {\n if (this.showTimer) {\n clearTimeout(this.showTimer);\n this.showTimer = null;\n }\n this.pendingTarget = null;\n if (this.hideTimer) clearTimeout(this.hideTimer);\n this.hideTimer = setTimeout(() => this.hideNow(), HIDE_DELAY_MS);\n }\n\n private readonly hideNow = (): void => {\n if (this.showTimer) {\n clearTimeout(this.showTimer);\n this.showTimer = null;\n }\n this.pendingTarget = null;\n if (this.hideTimer) {\n clearTimeout(this.hideTimer);\n this.hideTimer = null;\n }\n if (!this.currentTarget) return;\n this.currentTarget = null;\n this.el.style.opacity = '0';\n this.el.style.visibility = 'hidden';\n };\n\n private show(target: HTMLElement): void {\n // Dokunmatikte (hover yeteneği yok) gösterme — butona dokunmak hem\n // mouseover hem focusin tetikliyor, tooltip boşuna açılıyordu (istek\n // üzerine: \"mobilde buton tooltiplerini gizle\").\n if (!canHover()) return;\n const label = target.getAttribute('aria-label');\n if (!label) return;\n this.currentTarget = target;\n\n this.labelEl.textContent = label;\n const shortcut = target.dataset.shortcut;\n if (shortcut) {\n this.keyEl.textContent = shortcut;\n this.keyEl.style.display = '';\n } else {\n this.keyEl.textContent = '';\n this.keyEl.style.display = 'none';\n }\n\n // Ölçülebilmesi için önce (görünmez ama layout'ta) render ediliyor.\n this.el.style.visibility = 'hidden';\n this.el.style.opacity = '0';\n this.el.style.left = '0px';\n this.el.style.top = '0px';\n\n requestAnimationFrame(() => {\n if (this.currentTarget !== target) return;\n this.position(target);\n this.el.style.visibility = 'visible';\n this.el.style.opacity = '1';\n });\n }\n\n private position(target: HTMLElement): void {\n const mountRect = this.mountEl.getBoundingClientRect();\n const targetRect = target.getBoundingClientRect();\n const ttRect = this.el.getBoundingClientRect();\n\n let top = targetRect.top - mountRect.top - ttRect.height - GAP_PX;\n if (top < EDGE_PADDING_PX) {\n top = targetRect.bottom - mountRect.top + GAP_PX;\n }\n\n let left = targetRect.left - mountRect.left + targetRect.width / 2 - ttRect.width / 2;\n const maxLeft = mountRect.width - ttRect.width - EDGE_PADDING_PX;\n left = Math.max(EDGE_PADDING_PX, Math.min(left, maxLeft));\n\n this.el.style.top = `${top}px`;\n this.el.style.left = `${left}px`;\n }\n}\n","/** Host'a bağlı klavye kısayolları; SeekBar/VolumePanel odaktayken kendi ok tuşlarını işler. */\nexport class KeyboardController {\n private readonly host: HTMLElement;\n private readonly video: HTMLVideoElement;\n private readonly toggleFullscreen: () => void;\n\n constructor(host: HTMLElement, video: HTMLVideoElement, toggleFullscreen: () => void) {\n this.host = host;\n this.video = video;\n this.toggleFullscreen = toggleFullscreen;\n this.host.addEventListener('keydown', this.onKeyDown);\n }\n\n private readonly onKeyDown = (e: KeyboardEvent): void => {\n if (e.defaultPrevented) return;\n const duration = this.video.duration;\n\n switch (e.key) {\n case ' ':\n case 'k':\n if (this.video.paused) void this.video.play();\n else this.video.pause();\n e.preventDefault();\n break;\n case 'ArrowRight':\n case 'l':\n if (Number.isFinite(duration)) this.video.currentTime = Math.min(duration, this.video.currentTime + 5);\n e.preventDefault();\n break;\n case 'ArrowLeft':\n case 'j':\n this.video.currentTime = Math.max(0, this.video.currentTime - 5);\n e.preventDefault();\n break;\n case 'ArrowUp':\n this.video.volume = Math.min(1, this.video.volume + 0.1);\n this.video.muted = false;\n e.preventDefault();\n break;\n case 'ArrowDown':\n this.video.volume = Math.max(0, this.video.volume - 0.1);\n e.preventDefault();\n break;\n case 'm':\n this.video.muted = !this.video.muted;\n e.preventDefault();\n break;\n case 'f':\n this.toggleFullscreen();\n e.preventDefault();\n break;\n }\n };\n\n destroy(): void {\n this.host.removeEventListener('keydown', this.onKeyDown);\n }\n}\n","/** video 'waiting' olayında görünür, 'playing'/'canplay'de gizlenir. */\nexport class LoadingSpinner {\n readonly el: HTMLDivElement;\n private readonly video: HTMLVideoElement;\n\n constructor(video: HTMLVideoElement) {\n this.video = video;\n\n this.el = document.createElement('div');\n this.el.className = 'hp:absolute hp:inset-0 hp:flex hp:items-center hp:justify-center hp:pointer-events-none hp:hidden';\n this.el.innerHTML =\n '<div class=\"hp:w-10 hp:h-10 hp:border-[3px] hp:border-on-surface/30 hp:border-t-accent hp:rounded-full hp:animate-spin\"></div>';\n\n video.addEventListener('waiting', this.show);\n video.addEventListener('playing', this.hide);\n video.addEventListener('canplay', this.hide);\n video.addEventListener('pause', this.hide);\n }\n\n private readonly show = (): void => this.el.classList.remove('hp:hidden');\n private readonly hide = (): void => this.el.classList.add('hp:hidden');\n\n destroy(): void {\n this.video.removeEventListener('waiting', this.show);\n this.video.removeEventListener('playing', this.hide);\n this.video.removeEventListener('canplay', this.hide);\n this.video.removeEventListener('pause', this.hide);\n }\n}\n","import { createIcon } from '../icons/Icon';\nimport type { HopeLocaleStrings } from '../i18n/types';\n\n/** video 'error' olayında görünür; \"Tekrar Dene\" video.load()'u tetikler. */\nexport class ErrorScreen {\n readonly el: HTMLDivElement;\n private readonly video: HTMLVideoElement;\n private readonly labels: HopeLocaleStrings;\n private readonly messageEl: HTMLParagraphElement;\n private readonly retryBtn: HTMLButtonElement;\n private onRetry: (() => void) | null = null;\n\n constructor(video: HTMLVideoElement, labels: HopeLocaleStrings) {\n this.video = video;\n this.labels = labels;\n\n this.el = document.createElement('div');\n this.el.className =\n 'hp:absolute hp:inset-0 hp:hidden hp:flex-col hp:items-center hp:justify-center hp:gap-3 hp:bg-surface/95 hp:text-on-surface hp:text-sm hp:text-center hp:px-6';\n\n this.el.appendChild(createIcon('warning', 'hp:text-3xl hp:text-accent'));\n\n this.messageEl = document.createElement('p');\n this.el.appendChild(this.messageEl);\n\n this.retryBtn = document.createElement('button');\n this.retryBtn.type = 'button';\n this.retryBtn.textContent = labels.retry;\n this.retryBtn.className =\n 'hp:px-4 hp:py-1.5 hp:rounded-md hp:bg-accent hp:text-on-accent hp:text-xs hp:font-medium hp:border-0 hp:cursor-pointer';\n this.retryBtn.addEventListener('click', () => {\n this.hide();\n this.onRetry?.();\n });\n this.el.appendChild(this.retryBtn);\n\n video.addEventListener('error', this.show);\n }\n\n setOnRetry(fn: () => void): void {\n this.onRetry = fn;\n }\n\n refreshLabels(): void {\n this.retryBtn.textContent = this.labels.retry;\n if (!this.el.classList.contains('hp:hidden')) this.show();\n }\n\n private readonly show = (): void => {\n const code = this.video.error?.code ?? 0;\n const messages: Record<number, string> = {\n 1: this.labels.errorAborted,\n 2: this.labels.errorNetwork,\n 3: this.labels.errorDecode,\n 4: this.labels.errorSrcNotSupported,\n };\n this.messageEl.textContent = messages[code] ?? this.labels.errorGeneric;\n this.el.classList.remove('hp:hidden');\n this.el.classList.add('hp:flex');\n };\n\n private hide(): void {\n this.el.classList.add('hp:hidden');\n this.el.classList.remove('hp:flex');\n }\n\n destroy(): void {\n this.video.removeEventListener('error', this.show);\n }\n}\n","import type { HopeSubtitleOption } from '../types';\n\nexport interface AttachedTrack {\n label: string;\n track: TextTrack;\n}\n\n/** Altyazıları native <track> olarak ekler; mode 'hidden' — cue'lar akar ama tarayıcı çizmez (CaptionRenderer çizer). */\nexport function attachSubtitleTracks(video: HTMLVideoElement, subtitles: HopeSubtitleOption[]): AttachedTrack[] {\n video.querySelectorAll('track').forEach((t) => t.remove());\n\n const attached: AttachedTrack[] = [];\n for (const sub of subtitles) {\n const trackEl = document.createElement('track');\n trackEl.kind = 'subtitles';\n trackEl.src = sub.src;\n trackEl.srclang = sub.srclang;\n trackEl.label = sub.label;\n video.appendChild(trackEl);\n if (trackEl.track) {\n trackEl.track.mode = sub.default ? 'hidden' : 'disabled';\n attached.push({ label: sub.label, track: trackEl.track });\n }\n }\n return attached;\n}\n\n/** Yalnızca seçilen track'i 'hidden' yapar, diğerlerini kapatır (null = hepsini kapat). */\nexport function selectSubtitleTrack(tracks: AttachedTrack[], label: string | null): TextTrack | null {\n let active: TextTrack | null = null;\n for (const { label: trackLabel, track } of tracks) {\n const isActive = trackLabel === label;\n track.mode = isActive ? 'hidden' : 'disabled';\n if (isActive) active = track;\n }\n return active;\n}\n","import type { HopeLocaleStrings } from '../i18n/types';\n\nexport type CaptionFontSize = 'small' | 'normal' | 'large';\n\nconst ROWS = 6;\n/** En üst satırla video tepesi arasındaki boşluk (balon yüksekliğine eklenir). */\nconst TOP_GAP_PX = 20;\nconst GAP_ABOVE_SEEKBAR_PX = 14;\n/** Kompakt (küçük player) düzende seek bar üstü boşluk — dikey alan kıt, altyazı üst bara binmesin. */\nconst GAP_ABOVE_SEEKBAR_COMPACT_PX = 6;\n/** Kontroller gizliyken en alt satırın video altından boşluğu — video yüksekliğinin %4'ü, en az bu kadar px. */\nconst BOTTOM_GAP_MIN_PX = 10;\nconst DRAG_TAP_THRESHOLD_PX = 3;\nconst STORAGE_KEY_ROW = 'hope-caption-row';\nconst STORAGE_KEY_SIZE = 'hope-caption-font-size';\nconst STORAGE_KEY_BG_COLOR = 'hope-caption-bg-color';\nconst STORAGE_KEY_TEXT_COLOR = 'hope-caption-text-color';\n\nconst FONT_SIZE_MULTIPLIER: Record<CaptionFontSize, number> = {\n small: 0.78,\n normal: 1,\n large: 1.35,\n};\n\n/** YouTube tarzı hazır renk paleti — her ikisi de ayarlar menüsünde swatch grid'i olarak gösteriliyor (bkz. SettingsMenu.renderCaptionColorPanel). İlk eleman her zaman varsayılan. */\nconst BG_COLOR_PRESETS = [\n 'rgba(0, 0, 0, 0.75)',\n 'rgba(0, 0, 0, 0)',\n 'rgba(255, 255, 255, 0.85)',\n 'rgba(183, 28, 28, 0.8)',\n 'rgba(13, 71, 161, 0.8)',\n 'rgba(27, 94, 32, 0.8)',\n];\nconst TEXT_COLOR_PRESETS = ['#ffffff', '#000000', '#ffeb3b', '#ff5252', '#18ffff', '#69f0ae'];\n\ninterface CueWithHtml extends TextTrackCue {\n getCueAsHTML?(): DocumentFragment;\n text?: string;\n}\n\nfunction readStoredRow(): number {\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY_ROW);\n const n = raw === null ? 0 : Number(raw);\n return Number.isFinite(n) && n >= 0 && n < ROWS ? n : 0;\n } catch {\n return 0;\n }\n}\n\nfunction readStoredFontSize(): CaptionFontSize {\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY_SIZE);\n return raw === 'small' || raw === 'normal' || raw === 'large' ? raw : 'normal';\n } catch {\n return 'normal';\n }\n}\n\nfunction readStoredColor(key: string, presets: readonly string[]): string {\n const fallback = presets[0] ?? '';\n try {\n const raw = window.localStorage.getItem(key);\n return raw !== null && presets.includes(raw) ? raw : fallback;\n } catch {\n return fallback;\n }\n}\n\n/** Altyazıyı native render yerine kendi <div>'imizde çizer — YouTube tarzı sürükle-bırak, boyut/renk ayarları. */\nexport class CaptionRenderer {\n static readonly BG_COLOR_PRESETS: readonly string[] = BG_COLOR_PRESETS;\n static readonly TEXT_COLOR_PRESETS: readonly string[] = TEXT_COLOR_PRESETS;\n\n readonly layerEl: HTMLDivElement;\n private readonly bubbleEl: HTMLDivElement;\n private readonly videoArea: HTMLElement;\n private readonly seekBarEl: HTMLElement;\n private labels: HopeLocaleStrings;\n\n private activeTrack: TextTrack | null = null;\n private fontSize: CaptionFontSize = readStoredFontSize();\n private bgColor: string = readStoredColor(STORAGE_KEY_BG_COLOR, BG_COLOR_PRESETS);\n private textColor: string = readStoredColor(STORAGE_KEY_TEXT_COLOR, TEXT_COLOR_PRESETS);\n private rowIndex = readStoredRow();\n private dragging = false;\n /** Kontrol çubuğu görünür mü — görünürken altyazı seek bar'ın üstünde, değilken en altta. */\n private chromeVisible = true;\n private dragStartClientY = 0;\n private dragStartBottomPx = 0;\n private dragMoved = false;\n private rafId: number | null = null;\n private pendingDeltaPx = 0;\n private readonly resizeObserver: ResizeObserver;\n\n constructor(video: HTMLVideoElement, videoArea: HTMLElement, seekBarEl: HTMLElement, labels: HopeLocaleStrings) {\n void video;\n this.videoArea = videoArea;\n this.seekBarEl = seekBarEl;\n this.labels = labels;\n\n this.layerEl = document.createElement('div');\n this.layerEl.className = 'hp-caption-layer';\n this.layerEl.setAttribute('part', 'caption-layer');\n\n this.bubbleEl = document.createElement('div');\n this.bubbleEl.className = 'hp-caption-bubble';\n this.bubbleEl.setAttribute('part', 'caption-bubble');\n this.bubbleEl.setAttribute('role', 'note');\n this.bubbleEl.setAttribute('aria-label', labels.captionDragHandle);\n this.bubbleEl.tabIndex = -1;\n this.applyFontSizeVar();\n this.bubbleEl.style.setProperty('--hp-caption-bg', this.bgColor);\n this.bubbleEl.style.setProperty('--hp-caption-text', this.textColor);\n this.layerEl.appendChild(this.bubbleEl);\n\n this.bubbleEl.addEventListener('pointerdown', this.onPointerDown);\n\n this.resizeObserver = new ResizeObserver(() => this.recomputePosition());\n this.resizeObserver.observe(this.videoArea);\n\n this.recomputePosition();\n }\n\n /** `applyOptions()`'tan — hangi track aktif (ya da null = kapalı). */\n setActiveTrack(track: TextTrack | null): void {\n if (this.activeTrack) this.activeTrack.removeEventListener('cuechange', this.onCueChange);\n this.activeTrack = track;\n if (this.activeTrack) this.activeTrack.addEventListener('cuechange', this.onCueChange);\n this.onCueChange();\n }\n\n getFontSize(): CaptionFontSize {\n return this.fontSize;\n }\n\n setFontSize(size: CaptionFontSize): void {\n this.fontSize = size;\n this.applyFontSizeVar();\n // Boyut büyüyünce balon da büyür — en üst satırdaysa `bounds()`'un\n // tepe boşluğu (bkz. aşağıdaki not) YENİ yüksekliğe göre yeniden\n // hesaplanmazsa balon video'nun tepesinden TAŞABİLİRDİ.\n this.recomputePosition();\n try {\n window.localStorage.setItem(STORAGE_KEY_SIZE, size);\n } catch {\n /* gizli mod vb. — sessizce yoksay */\n }\n }\n\n getBgColor(): string {\n return this.bgColor;\n }\n\n setBgColor(color: string): void {\n this.bgColor = color;\n this.bubbleEl.style.setProperty('--hp-caption-bg', color);\n try {\n window.localStorage.setItem(STORAGE_KEY_BG_COLOR, color);\n } catch {\n /* gizli mod vb. — sessizce yoksay */\n }\n }\n\n getTextColor(): string {\n return this.textColor;\n }\n\n setTextColor(color: string): void {\n this.textColor = color;\n this.bubbleEl.style.setProperty('--hp-caption-text', color);\n try {\n window.localStorage.setItem(STORAGE_KEY_TEXT_COLOR, color);\n } catch {\n /* gizli mod vb. — sessizce yoksay */\n }\n }\n\n /** Ayarlar menüsündeki \"Konumu sıfırla\". */\n resetPosition(): void {\n this.setRowIndex(0, true);\n }\n\n /** Dil sonradan değişince aria-label'ı tazeler. */\n refreshLabels(labels: HopeLocaleStrings): void {\n this.labels = labels;\n this.bubbleEl.setAttribute('aria-label', labels.captionDragHandle);\n }\n\n private applyFontSizeVar(): void {\n this.bubbleEl.style.setProperty('--hp-caption-size-multiplier', String(FONT_SIZE_MULTIPLIER[this.fontSize]));\n }\n\n private readonly onCueChange = (): void => {\n const cues = this.activeTrack?.activeCues;\n if (!this.activeTrack || !cues || cues.length === 0) {\n this.bubbleEl.classList.remove('hp-caption-visible');\n this.bubbleEl.textContent = '';\n return;\n }\n this.bubbleEl.textContent = '';\n for (let i = 0; i < cues.length; i++) {\n if (i > 0) this.bubbleEl.appendChild(document.createElement('br'));\n const cue = cues[i] as CueWithHtml;\n if (typeof cue.getCueAsHTML === 'function') {\n this.bubbleEl.appendChild(cue.getCueAsHTML());\n } else {\n this.bubbleEl.appendChild(document.createTextNode(cue.text ?? ''));\n }\n }\n this.bubbleEl.classList.add('hp-caption-visible');\n };\n\n private bounds(): { min: number; max: number } {\n const areaRect = this.videoArea.getBoundingClientRect();\n const seekRect = this.seekBarEl.getBoundingClientRect();\n // Tepe boşluğu balonun kendi yüksekliği + sabit boşluk.\n const bubbleHeight = this.bubbleEl.getBoundingClientRect().height || 32;\n const topMargin = bubbleHeight + TOP_GAP_PX;\n // Kontroller görünürken seek bar'ın üstü, gizliyken (ya da seek bar gizliyse) videonun en altı.\n const bottomGap = Math.max(BOTTOM_GAP_MIN_PX, Math.round(areaRect.height * 0.04));\n const min =\n this.chromeVisible && seekRect.height > 0\n ? Math.max(0, Math.round(areaRect.bottom - seekRect.top + (this.videoArea.hasAttribute('data-compact') ? GAP_ABOVE_SEEKBAR_COMPACT_PX : GAP_ABOVE_SEEKBAR_PX)))\n : bottomGap;\n const max = Math.max(min, Math.round(areaRect.height - topMargin));\n return { min, max };\n }\n\n private pxForRow(rowIndex: number): number {\n const { min, max } = this.bounds();\n if (ROWS <= 1) return min;\n const ratio = rowIndex / (ROWS - 1);\n return Math.round(min + ratio * (max - min));\n }\n\n /** FLIP: bottom anında yazılır, yalnızca transform animasyonlanır — bottom'u animasyonlamak bırakınca zıplatıyordu. */\n private setRowIndex(rowIndex: number, animate: boolean, fromPx?: number): void {\n this.rowIndex = Math.min(ROWS - 1, Math.max(0, rowIndex));\n const targetPx = this.pxForRow(this.rowIndex);\n const prevPx = fromPx ?? parseFloat(this.bubbleEl.style.bottom || `${targetPx}`);\n\n if (animate && prevPx !== targetPx) {\n this.bubbleEl.classList.add('hp-caption-no-transition');\n this.bubbleEl.style.bottom = `${targetPx}px`;\n this.bubbleEl.style.transform = `translateX(-50%) translateY(${prevPx - targetPx}px)`;\n void this.bubbleEl.offsetHeight; // reflow'u zorla — sıradaki transform değişikliği animasyonlansın\n this.bubbleEl.classList.remove('hp-caption-no-transition');\n this.bubbleEl.style.transform = 'translateX(-50%)';\n } else {\n this.bubbleEl.style.transform = 'translateX(-50%)';\n this.bubbleEl.style.bottom = `${targetPx}px`;\n }\n\n try {\n window.localStorage.setItem(STORAGE_KEY_ROW, String(this.rowIndex));\n } catch {\n /* gizli mod vb. — sessizce yoksay */\n }\n }\n\n /** Boyut değişimi (ör. fullscreen'e giriş) sonrası AYNI satıra, YENİ sınırlara göre yeniden konumlan — animasyonsuz (boyut değişimi anlık olmalı). */\n /** HopePlayerElement.setChromeOpacity'den — kontroller açılıp kapanınca balon yumuşakça yukarı/aşağı kayar (satır korunur). */\n setChromeVisible(visible: boolean): void {\n if (visible === this.chromeVisible) return;\n this.chromeVisible = visible;\n if (!this.dragging) this.setRowIndex(this.rowIndex, true);\n }\n\n recomputePosition(): void {\n if (this.dragging) return;\n this.setRowIndex(this.rowIndex, false);\n }\n\n private readonly onPointerDown = (e: PointerEvent): void => {\n if (e.button !== 0 && e.pointerType === 'mouse') return;\n e.preventDefault();\n this.dragging = true;\n this.dragMoved = false;\n this.dragStartClientY = e.clientY;\n this.dragStartBottomPx = this.pxForRow(this.rowIndex);\n this.bubbleEl.setPointerCapture(e.pointerId);\n this.bubbleEl.classList.add('hp-caption-dragging');\n this.bubbleEl.addEventListener('pointermove', this.onPointerMove);\n this.bubbleEl.addEventListener('pointerup', this.onPointerUp);\n this.bubbleEl.addEventListener('pointercancel', this.onPointerUp);\n };\n\n private readonly onPointerMove = (e: PointerEvent): void => {\n if (!this.dragging) return;\n this.pendingDeltaPx = e.clientY - this.dragStartClientY;\n if (Math.abs(this.pendingDeltaPx) > DRAG_TAP_THRESHOLD_PX) this.dragMoved = true;\n if (this.rafId === null) this.rafId = requestAnimationFrame(this.applyPendingDrag);\n };\n\n private readonly applyPendingDrag = (): void => {\n this.rafId = null;\n if (!this.dragging) return;\n const { min, max } = this.bounds();\n // Aşağı sürüklemek (deltaPx pozitif) effective bottom'u AZALTMALI.\n const targetBottom = Math.min(max, Math.max(min, this.dragStartBottomPx - this.pendingDeltaPx));\n const translatePx = this.dragStartBottomPx - targetBottom;\n this.bubbleEl.style.transform = `translateX(-50%) translateY(${translatePx}px)`;\n };\n\n private readonly onPointerUp = (e: PointerEvent): void => {\n if (!this.dragging) return;\n this.dragging = false;\n this.bubbleEl.releasePointerCapture(e.pointerId);\n this.bubbleEl.removeEventListener('pointermove', this.onPointerMove);\n this.bubbleEl.removeEventListener('pointerup', this.onPointerUp);\n this.bubbleEl.removeEventListener('pointercancel', this.onPointerUp);\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n this.bubbleEl.classList.remove('hp-caption-dragging');\n if (!this.dragMoved) return;\n const { min, max } = this.bounds();\n const finalBottom = Math.min(max, Math.max(min, this.dragStartBottomPx - this.pendingDeltaPx));\n const ratio = max > min ? (finalBottom - min) / (max - min) : 0;\n const snappedIndex = Math.round(ratio * (ROWS - 1));\n this.setRowIndex(snappedIndex, true, finalBottom);\n };\n\n destroy(): void {\n if (this.activeTrack) this.activeTrack.removeEventListener('cuechange', this.onCueChange);\n this.resizeObserver.disconnect();\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.bubbleEl.removeEventListener('pointerdown', this.onPointerDown);\n }\n}\n","/**\n * Kontroller gizliyken video alanının en altında, kenardan kenara ince\n * ilerleme çizgisi (`options.miniProgress`). Görünürlüğü HopePlayerElement\n * belirler (chrome gizli + reklam/giriş ekranı yok + canlı değil); çizim\n * yalnızca görünürken ve oynarken rAF ile yapılır.\n */\nexport class MiniProgress {\n readonly el: HTMLDivElement;\n private readonly bufferedEl: HTMLDivElement;\n private readonly playedEl: HTMLDivElement;\n private visible = false;\n private rafId: number | null = null;\n\n constructor(private readonly video: HTMLVideoElement) {\n this.el = document.createElement('div');\n this.el.className = 'hp-mini-progress';\n this.el.setAttribute('part', 'mini-progress');\n this.el.setAttribute('aria-hidden', 'true');\n this.bufferedEl = document.createElement('div');\n this.bufferedEl.className = 'hp-mini-progress-fill hp-mini-progress-buffered';\n this.playedEl = document.createElement('div');\n this.playedEl.className = 'hp-mini-progress-fill hp-mini-progress-played';\n this.el.append(this.bufferedEl, this.playedEl);\n\n video.addEventListener('play', this.sync);\n video.addEventListener('pause', this.sync);\n video.addEventListener('timeupdate', this.render);\n video.addEventListener('progress', this.render);\n video.addEventListener('durationchange', this.render);\n }\n\n setVisible(visible: boolean): void {\n if (visible === this.visible) return;\n this.visible = visible;\n this.el.toggleAttribute('data-visible', visible);\n this.sync();\n }\n\n destroy(): void {\n this.stop();\n this.video.removeEventListener('play', this.sync);\n this.video.removeEventListener('pause', this.sync);\n this.video.removeEventListener('timeupdate', this.render);\n this.video.removeEventListener('progress', this.render);\n this.video.removeEventListener('durationchange', this.render);\n this.el.remove();\n }\n\n private readonly sync = (): void => {\n this.render();\n if (this.visible && !this.video.paused) this.start();\n else this.stop();\n };\n\n private start(): void {\n if (this.rafId !== null) return;\n const tick = (): void => {\n this.render();\n this.rafId = requestAnimationFrame(tick);\n };\n this.rafId = requestAnimationFrame(tick);\n }\n\n private stop(): void {\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n\n private readonly render = (): void => {\n const duration = this.video.duration;\n // Canlı yayın (Infinity) ya da süre henüz bilinmiyor — boş bir çizgi gösterme.\n const hasDuration = Number.isFinite(duration) && duration > 0;\n this.el.toggleAttribute('data-disabled', !hasDuration);\n if (!this.visible || !hasDuration) return;\n this.playedEl.style.transform = `scaleX(${Math.min(1, this.video.currentTime / duration)})`;\n const { buffered } = this.video;\n let end = 0;\n for (let i = 0; i < buffered.length; i++) {\n if (buffered.start(i) <= this.video.currentTime) end = Math.max(end, buffered.end(i));\n }\n this.bufferedEl.style.transform = `scaleX(${Math.min(1, end / duration)})`;\n };\n}\n","import iconFontFaceCss from '../theme/icons/hope-icons-font-face.css?inline';\n\nconst STYLE_ID = 'hope-player-icon-font';\n\n/** @font-face Shadow DOM içinde uygulanmadığı için (crbug.com/41085401) document.head'e bir kez enjekte edilir. */\nexport function injectIconFont(): void {\n if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return;\n const style = document.createElement('style');\n style.id = STYLE_ID;\n style.textContent = iconFontFaceCss;\n document.head.appendChild(style);\n}\n","import type { HopeLocaleStrings } from '../types';\n\n/** Varsayılan dil — mevcut (çeviri öncesi) sabit kodlanmış metinlerle birebir aynı, davranış değişikliği yok. */\nexport const tr: HopeLocaleStrings = {\n play: 'Oynat',\n pause: 'Duraklat',\n mute: 'Sessize al',\n unmute: 'Sesi aç',\n volume: 'Ses seviyesi',\n seekBar: 'Video konumu',\n settings: 'Ayarlar',\n pip: 'Resim içinde resim',\n fullscreenEnter: 'Tam ekran',\n fullscreenExit: 'Tam ekrandan çık',\n playbackSpeed: 'Oynatma Hızı',\n normal: 'Normal',\n quality: 'Kalite',\n captions: 'Altyazı',\n captionsOff: 'Kapalı',\n captionSize: 'Yazı Boyutu',\n captionSizeSmall: 'Küçük',\n captionSizeNormal: 'Normal',\n captionSizeLarge: 'Büyük',\n captionResetPosition: 'Konumu sıfırla',\n captionBgColor: 'Arka Plan Rengi',\n captionTextColor: 'Yazı Rengi',\n captionDragHandle: 'Altyazı konumu — tutup sürükleyin',\n autoQuality: 'Oto',\n loop: 'Döngü',\n close: 'Kapat',\n retry: 'Tekrar Dene',\n errorAborted: 'Video yüklemesi iptal edildi.',\n errorNetwork: 'Ağ hatası — video yüklenemedi.',\n errorDecode: 'Video kodu çözülemedi.',\n errorSrcNotSupported: 'Bu video kaynağı desteklenmiyor.',\n errorGeneric: 'Video oynatılırken bir hata oluştu.',\n countdownRemaining: 'Kalan süre',\n geoDefaultWarning: 'Erişim engellendi.',\n geoUnknownCountry: 'Ülke bilgisi bulunamadı.',\n redirectCancel: 'İptal',\n redirectPlayNow: 'Şimdi Oynat',\n redirectCountdown: (seconds) => `Sıradaki video ${seconds} saniye içinde oynatılacak.`,\n redirectNowPlaying: 'Video oynatılıyor...',\n qrResumeTitle: 'Devam etmek için kodu telefonunuzla okutun',\n qrResumeDontShowAgain: 'Bir daha gösterme',\n qrResumeContinue: 'Devam Et',\n qrResumeMenuLabel: 'QR ile Devam Et',\n qrResumeOn: 'Açık',\n qrResumeOff: 'Kapalı',\n markerLearnMore: 'Daha fazla bilgi',\n markerContinue: 'Devam et',\n playlistTitle: 'Oynatma Listesi',\n playlistPrev: 'Önceki',\n playlistNext: 'Sonraki',\n videoFallbackTitle: (index) => `Video ${index + 1}`,\n storyPrev: 'Önceki video',\n storyNext: 'Sonraki video',\n storyAllVideos: 'Tüm videolar',\n dubbingTitle: 'Ses / Dil',\n liveClock: 'Canlı saat',\n live: 'CANLI',\n goToLive: 'Canlıya git',\n};\n","import type { HopeLocaleStrings } from '../types';\n\nexport const en: HopeLocaleStrings = {\n play: 'Play',\n pause: 'Pause',\n mute: 'Mute',\n unmute: 'Unmute',\n volume: 'Volume',\n seekBar: 'Seek',\n settings: 'Settings',\n pip: 'Picture-in-picture',\n fullscreenEnter: 'Fullscreen',\n fullscreenExit: 'Exit fullscreen',\n playbackSpeed: 'Playback speed',\n normal: 'Normal',\n quality: 'Quality',\n captions: 'Captions',\n captionsOff: 'Off',\n captionSize: 'Font Size',\n captionSizeSmall: 'Small',\n captionSizeNormal: 'Normal',\n captionSizeLarge: 'Large',\n captionResetPosition: 'Reset position',\n captionBgColor: 'Background Color',\n captionTextColor: 'Text Color',\n captionDragHandle: 'Caption position — drag to move',\n autoQuality: 'Auto',\n loop: 'Loop',\n close: 'Close',\n retry: 'Retry',\n errorAborted: 'Video loading was aborted.',\n errorNetwork: 'Network error — the video could not load.',\n errorDecode: 'The video could not be decoded.',\n errorSrcNotSupported: 'This video source is not supported.',\n errorGeneric: 'An error occurred while playing the video.',\n countdownRemaining: 'Time remaining',\n geoDefaultWarning: 'Access denied.',\n geoUnknownCountry: 'No country information found.',\n redirectCancel: 'Cancel',\n redirectPlayNow: 'Play now',\n redirectCountdown: (seconds) => `Next video will play in ${seconds} seconds.`,\n redirectNowPlaying: 'Now playing...',\n qrResumeTitle: 'Scan to continue watching on your phone',\n qrResumeDontShowAgain: \"Don't show again\",\n qrResumeContinue: 'Continue',\n qrResumeMenuLabel: 'Continue via QR',\n qrResumeOn: 'On',\n qrResumeOff: 'Off',\n markerLearnMore: 'Learn more',\n markerContinue: 'Continue',\n playlistTitle: 'Playlist',\n playlistPrev: 'Previous',\n playlistNext: 'Next',\n videoFallbackTitle: (index) => `Video ${index + 1}`,\n storyPrev: 'Previous video',\n storyNext: 'Next video',\n storyAllVideos: 'All videos',\n dubbingTitle: 'Audio / Language',\n liveClock: 'Live clock',\n live: 'LIVE',\n goToLive: 'Go to live',\n};\n","import { tr } from './locales/tr';\nimport { en } from './locales/en';\nimport type { HopeLocale, HopeLocaleStrings } from './types';\n\nconst BUILTIN_LOCALES: Record<string, HopeLocaleStrings> = { tr, en };\n\n/** Paylaşılan, mutable dil sözlüğü üretir (bkz. HopePlayerElement.i18n). */\nexport function createLocaleStrings(locale?: HopeLocale, overrides?: Partial<HopeLocaleStrings>): HopeLocaleStrings {\n const base = BUILTIN_LOCALES[locale ?? 'tr'] ?? tr;\n return { ...base, ...overrides };\n}\n\n/** Var olan (mutable, paylaşılan) bir i18n objesinin alanlarını YERİNDE günceller — referansı korur. */\nexport function applyLocale(target: HopeLocaleStrings, locale?: HopeLocale, overrides?: Partial<HopeLocaleStrings>): void {\n Object.assign(target, createLocaleStrings(locale, overrides));\n}\n\nexport { tr, en };\nexport type { HopeLocale, HopeLocaleStrings };\n","import tailwindCss from './theme/tailwind.css?inline';\nimport type { AdsOptions, HopePlayerOptions } from './types';\nimport { SourceManager, type HlsQualityLevel } from './hls/SourceManager';\nimport { ControlBar } from './controls/ControlBar';\nimport { TooltipController } from './controls/Tooltip';\nimport { KeyboardController } from './keyboard/KeyboardController';\nimport { LoadingSpinner } from './screens/LoadingSpinner';\nimport { ErrorScreen } from './screens/ErrorScreen';\nimport { attachSubtitleTracks, selectSubtitleTrack, type AttachedTrack } from './subtitles/attachTracks';\nimport { CaptionRenderer, type CaptionFontSize } from './subtitles/CaptionRenderer';\nimport { MiniProgress } from './controls/MiniProgress';\nimport type { SettingsCaptionAppearance, SettingsColorOption } from './controls/SettingsMenu';\nimport { createIcon } from './icons/Icon';\nimport { injectIconFont } from './icons/injectIconFont';\nimport type { AdsController, AdsPlayerContext } from './plugins/ads';\nimport type { GestureControls } from './plugins/gesture';\nimport type { LoopSection } from './plugins/loop-section';\nimport type { InViewAutoplay } from './plugins/in-view-autoplay';\nimport type { StickyUnregister } from './plugins/sticky';\nimport type { PlaylistRunner } from './plugins/playlist';\nimport type { HopeStory } from './plugins/story';\nimport type { MarkProgress } from './plugins/markers';\nimport type { Segments } from './plugins/segments';\nimport type { SpriteThumbnails } from './plugins/sprite-thumbnails';\nimport type { CountdownScreen } from './plugins/countdown-screen';\nimport type { GeoChecker } from './plugins/geo-checker';\nimport type { RedirectScreen } from './plugins/redirect-screen';\nimport type { QrResume } from './plugins/qr-resume';\nimport type { Dubbing } from './plugins/dubbing';\nimport type { LiveWallClock } from './plugins/live';\nimport type { DaiController } from './plugins/dai';\nimport { createLocaleStrings, applyLocale } from './i18n';\nimport type { HopeLocaleStrings } from './i18n/types';\n\nconst DEFAULT_PLAYBACK_RATES = [0.5, 0.75, 1, 1.25, 1.5, 2];\n/** options.autoHideDelayMs verilmezse kullanılan varsayılan. */\nconst DEFAULT_AUTO_HIDE_DELAY_MS = 1200;\n/** Basış ile kalkış arasındaki imleç/parmak hareketi bu eşiği aşarsa \"tık\" değil sürükleme sayılır — toggle tetiklenmez. */\nconst TAP_MAX_MOVE_PX = 10;\n\nconst TEMPLATE = /* html */ `\n <div class=\"video-area\">\n <div class=\"media-layer\">\n <video part=\"video\" playsinline></video>\n <div part=\"ad-layer\" class=\"hp:absolute hp:inset-0 hp:z-10 hp:hidden\"></div>\n </div>\n </div>\n`;\n\n/** <hope-player> — çekirdek oynatma ve kontroller; plugin'ler ilgili option verilince dinamik import edilir. */\nexport class HopePlayerElement extends HTMLElement {\n static get observedAttributes(): string[] {\n return ['src', 'poster', 'autoplay', 'muted', 'loop', 'theme', 'locale'];\n }\n\n private readonly root: ShadowRoot;\n private readonly videoArea: HTMLDivElement;\n private readonly videoEl: HTMLVideoElement;\n private readonly adLayerEl: HTMLDivElement;\n private readonly chromeEl: HTMLDivElement;\n private readonly centerPlayButton: HTMLButtonElement;\n private readonly captionRenderer: CaptionRenderer;\n /** options.miniProgress açıkken kurulur. */\n private miniProgress: MiniProgress | null = null;\n private chromeVisible = true;\n\n private readonly sourceManager: SourceManager;\n private readonly controlBar: ControlBar;\n private readonly tooltip: TooltipController;\n private readonly keyboard: KeyboardController;\n private readonly loadingSpinner: LoadingSpinner;\n private readonly errorScreen: ErrorScreen;\n private adsController: AdsController | null = null;\n private gestureControls: GestureControls | null = null;\n private loopSection: LoopSection | null = null;\n private inViewAutoplay: InViewAutoplay | null = null;\n private unregisterSticky: StickyUnregister | null = null;\n private playlistRunner: PlaylistRunner | null = null;\n private hopeStory: HopeStory | null = null;\n private markProgress: MarkProgress | null = null;\n private segments: Segments | null = null;\n private spriteThumbnails: SpriteThumbnails | null = null;\n private countdownScreen: CountdownScreen | null = null;\n private geoChecker: GeoChecker | null = null;\n private redirectScreen: RedirectScreen | null = null;\n private qrResume: QrResume | null = null;\n private dubbing: Dubbing | null = null;\n private liveWallClock: LiveWallClock | null = null;\n private daiController: DaiController | null = null;\n private readonly instanceKey: string;\n\n private subtitleTracks: AttachedTrack[] = [];\n /** `applyOptions()`'ta aktif bir altyazı track'i seçiliyken `true` — dil değişince Boyut/Konum görünümünü tazelemek için. */\n private captionTrackActive = false;\n /**\n * countdownScreen varken gerçek init (kaynak + içerik plugin'leri) ertelenir; en güncel options snapshot'ı.\n * onComplete kaydı tek sefer yapılır (bkz. playbackInitRegistered) — init birden fazla kez tetiklenmesin.\n */\n private pendingPlaybackOptions: HopePlayerOptions | null = null;\n private playbackInitRegistered = false;\n /**\n * countdownScreen gibi alanlar yalnızca .options ile gelir. connectedCallback'teki ilk (options'suz) geçiş chrome'u\n * bir an açıp player'ı gösteriyordu; 'boot' bloklayıcısı gerçek options gelene kadar bekletir.\n */\n private bootResolved = false;\n private bootGraceTimer: ReturnType<typeof setTimeout> | null = null;\n private _options: HopePlayerOptions = {};\n private hideTimer: ReturnType<typeof setTimeout> | null = null;\n private autoHideDelayMs = DEFAULT_AUTO_HIDE_DELAY_MS;\n private tapCandidate = false;\n private tapStartX = 0;\n private tapStartY = 0;\n /** Tüm UI'ın paylaştığı tek, mutable sözlük — dil değişince referans değil alanlar güncellenir. */\n private readonly i18n: HopeLocaleStrings = createLocaleStrings('tr');\n /** IMA SDK'nın kendi ad-UI dili (skip butonu/sayaç metni) de aynı dili takip etsin diye — bkz. plugins/ads/AdsController. */\n private localeCode = 'tr';\n\n constructor() {\n super();\n injectIconFont();\n this.root = this.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = tailwindCss;\n this.root.appendChild(style);\n\n const wrapper = document.createElement('div');\n wrapper.innerHTML = TEMPLATE;\n this.root.appendChild(wrapper);\n\n this.videoArea = this.root.querySelector('.video-area')!;\n this.videoEl = this.root.querySelector('video')!;\n this.adLayerEl = this.root.querySelector('[part=\"ad-layer\"]')!;\n this.instanceKey = `hp-${Math.random().toString(36).slice(2, 10)}`;\n\n this.loadingSpinner = new LoadingSpinner(this.videoEl);\n this.root.querySelector('.media-layer')!.appendChild(this.loadingSpinner.el);\n\n this.errorScreen = new ErrorScreen(this.videoEl, this.i18n);\n this.errorScreen.setOnRetry(() => this.videoEl.load());\n this.root.querySelector('.media-layer')!.appendChild(this.errorScreen.el);\n\n this.centerPlayButton = document.createElement('button');\n this.centerPlayButton.type = 'button';\n this.centerPlayButton.setAttribute('part', 'center-play-button');\n this.centerPlayButton.setAttribute('aria-label', this.i18n.play);\n // Tıklama alanı tüm video alanı; görsel olarak yalnızca ortadaki yuvarlak buton.\n this.centerPlayButton.className =\n 'hp:absolute hp:inset-0 hp:flex hp:items-center hp:justify-center hp:bg-transparent hp:border-0 hp:cursor-pointer hp:text-on-surface hp:transition-opacity';\n const centerChip = document.createElement('span');\n centerChip.className = 'hp-chip hp:flex hp:items-center hp:justify-center hp:w-16 hp:h-16';\n // .hp-chip'in kendi --hp-chip-radius'u rounded-full utility'sini ezer\n // (bkz. VolumePanel'deki aynı not) — tam daire için inline override.\n centerChip.style.borderRadius = '9999px';\n centerChip.appendChild(createIcon('play', 'hp:text-2xl'));\n this.centerPlayButton.appendChild(centerChip);\n this.centerPlayButton.addEventListener('click', () => {\n if (this.videoEl.paused) void this.videoEl.play();\n });\n this.videoArea.appendChild(this.centerPlayButton);\n\n this.chromeEl = document.createElement('div');\n // pointer-events-none: tüm video alanını kaplıyor; açık olsaydı alttaki video/reklam tıklamalarını yutardı.\n this.chromeEl.className = 'hp:absolute hp:inset-0 hp:z-20 hp:pointer-events-none';\n this.videoArea.appendChild(this.chromeEl);\n\n this.sourceManager = new SourceManager(this.videoEl, this.onHlsLevelsChanged);\n\n this.controlBar = new ControlBar(\n this.videoEl,\n DEFAULT_PLAYBACK_RATES,\n {\n onRequestFullscreen: () => this.requestFullscreenCompat(),\n onExitFullscreen: () => this.exitFullscreenCompat(),\n isFullscreen: () => this.isFullscreenActive(),\n // adsController sonradan kurulur — closure'lar her çağrıda güncel this.adsController'ı okur.\n isAdActive: () => this.isAdPlaying(),\n adTogglePlay: () => this.adsController?.toggleAdPlayPause(),\n adIsPaused: () => this.adsController?.isAdPaused() ?? true,\n adVolume: {\n isAdActive: () => this.isAdPlaying(),\n getVolume: () => this.adsController?.getAdVolume() ?? 1,\n setVolume: (v) => this.adsController?.setAdVolume(v),\n toggleMute: () => this.adsController?.toggleAdMute(),\n },\n },\n this.i18n\n );\n this.chromeEl.appendChild(this.controlBar.el);\n // Kompakt (küçük player) düzende sağ grubun taşındığı üst bar — chrome'la birlikte otomatik gizlenir.\n this.chromeEl.appendChild(this.controlBar.topEl);\n // \"Sesi aç\" rozeti chrome'un DIŞINDA: kontroller gizlense de sessiz videoda görünür kalmalı.\n this.videoArea.appendChild(this.controlBar.volumePanel.unmuteBadge);\n\n // z-index: video < caption(5) < ad-layer(10) < chrome(20) — reklam altyazıyı kendiliğinden örter.\n this.captionRenderer = new CaptionRenderer(this.videoEl, this.videoArea, this.controlBar.seekBar.el, this.i18n);\n this.videoArea.appendChild(this.captionRenderer.layerEl);\n\n this.keyboard = new KeyboardController(this, this.videoEl, () =>\n this.isFullscreenActive() ? this.exitFullscreenCompat() : this.requestFullscreenCompat()\n );\n\n // Tek bir delegasyon dinleyicisi, TÜM butonlar için (bkz. Tooltip.ts'teki\n // mimari not) — videoArea zaten position:relative (bkz. tailwind.css),\n // bu yüzden tooltip'in konum hesaplaması bu kapsayıcıya göre doğru çalışır.\n this.tooltip = new TooltipController(this.videoArea);\n\n // 'boot': gerçek `.options` (ör. countdownScreen) gelene kadar chrome\n // HİÇ görünmesin diye — bkz. `bootResolved` alanındaki mimari not.\n this.blockChrome('boot');\n }\n\n connectedCallback(): void {\n // tabIndex constructor'da değil burada: tabindex attribute'una yansır ve Custom Elements spec'i\n // constructor'da attribute eklemeyi yasaklar (createElement \"must not have attributes\" hatası).\n this.tabIndex = this.tabIndex || 0;\n\n this.syncFromAttributes();\n\n // Yalnızca HTML attribute'larıyla kullanım için güvenlik ağı — .options set edilirse bu zamanlayıcı iptal edilir.\n if (!this.bootResolved) {\n this.bootGraceTimer = setTimeout(() => {\n this.bootGraceTimer = null;\n if (!this.bootResolved) {\n this.bootResolved = true;\n this.syncFromAttributes();\n }\n }, 80);\n }\n\n this.videoEl.addEventListener('play', this.onPlay);\n this.videoEl.addEventListener('pause', this.onPause);\n this.addEventListener('pointermove', this.scheduleAutoHide);\n this.addEventListener('pointerdown', this.onPointerDownFocus);\n document.addEventListener('fullscreenchange', this.onFullscreenChange);\n\n // \"Ekrana dokun → oynat/duraklat\": doğrudan videoEl'e bağlı, kontrol çubuğu tıklamaları tetiklemez.\n this.videoEl.addEventListener('mousedown', this.onVideoPressStart);\n this.videoEl.addEventListener('mouseup', this.onVideoPressEnd);\n this.videoEl.addEventListener('mouseleave', this.onVideoPressCancel);\n this.videoEl.addEventListener('touchstart', this.onVideoPressStart, { passive: true });\n this.videoEl.addEventListener('touchend', this.onVideoPressEnd);\n this.videoEl.addEventListener('touchcancel', this.onVideoPressCancel);\n\n this.dispatchEvent(new CustomEvent('hp:ready'));\n }\n\n disconnectedCallback(): void {\n this.miniProgress?.destroy();\n this.miniProgress = null;\n this.videoEl.removeEventListener('play', this.onPlay);\n this.videoEl.removeEventListener('pause', this.onPause);\n this.removeEventListener('pointermove', this.scheduleAutoHide);\n this.removeEventListener('pointerdown', this.onPointerDownFocus);\n document.removeEventListener('fullscreenchange', this.onFullscreenChange);\n this.videoEl.removeEventListener('mousedown', this.onVideoPressStart);\n this.videoEl.removeEventListener('mouseup', this.onVideoPressEnd);\n this.videoEl.removeEventListener('mouseleave', this.onVideoPressCancel);\n this.videoEl.removeEventListener('touchstart', this.onVideoPressStart);\n this.videoEl.removeEventListener('touchend', this.onVideoPressEnd);\n this.videoEl.removeEventListener('touchcancel', this.onVideoPressCancel);\n this.controlBar.destroy();\n this.captionRenderer.destroy();\n this.keyboard.destroy();\n this.tooltip.destroy();\n this.loadingSpinner.destroy();\n this.errorScreen.destroy();\n this.sourceManager.destroy();\n this.adsController?.destroy();\n this.gestureControls?.destroy();\n this.loopSection?.destroy();\n this.inViewAutoplay?.destroy();\n this.unregisterSticky?.();\n this.playlistRunner?.destroy();\n this.hopeStory?.destroy();\n this.markProgress?.destroy();\n this.segments?.destroy();\n this.spriteThumbnails?.destroy();\n this.countdownScreen?.destroy();\n this.geoChecker?.destroy();\n this.redirectScreen?.destroy();\n this.qrResume?.destroy();\n this.dubbing?.destroy();\n this.liveWallClock?.destroy();\n this.daiController?.destroy();\n if (this.hideTimer) clearTimeout(this.hideTimer);\n if (this.bootGraceTimer) clearTimeout(this.bootGraceTimer);\n }\n\n /** Reklam/consent-farkında plugin'lerin (gesture/sticky/in-view-autoplay) ortak sorgusu. */\n isAdPlaying(): boolean {\n return this.chromeBlockers.has('ads');\n }\n\n attributeChangedCallback(): void {\n this.syncFromAttributes();\n }\n\n get options(): HopePlayerOptions {\n return this._options;\n }\n\n set options(value: HopePlayerOptions) {\n this._options = value ?? {};\n // Attribute'larla birleştir — aksi halde theme alanı olmayan bir .options ataması attribute'tan gelen temayı silerdi.\n if (this.bootGraceTimer) {\n clearTimeout(this.bootGraceTimer);\n this.bootGraceTimer = null;\n }\n this.bootResolved = true;\n this.syncFromAttributes();\n }\n\n play(): Promise<void> {\n return this.videoEl.play();\n }\n\n pause(): void {\n this.videoEl.pause();\n }\n\n /** `options.qrResume` kuruluysa \"telefonundan devam et\" QR ekranını manuel göster (ör. entegratörün kendi \"telefona gönder\" butonu) — otomatik gösterim kuralları (minElapsed/minRemaining) burada uygulanmaz. */\n showQrResume(): void {\n this.qrResume?.show();\n }\n\n get showRemainingTime(): boolean {\n return this.controlBar.getShowRemaining();\n }\n\n set showRemainingTime(value: boolean) {\n this.controlBar.setShowRemaining(value);\n }\n\n toggleTimeDisplay(): void {\n this.controlBar.toggleTimeMode();\n }\n\n private syncFromAttributes(): void {\n const attrOptions: HopePlayerOptions = {\n src: this.getAttribute('src') ?? undefined,\n poster: this.getAttribute('poster') ?? undefined,\n autoplay: this.hasAttribute('autoplay'),\n muted: this.hasAttribute('muted'),\n loop: this.hasAttribute('loop'),\n theme: this.getAttribute('theme') ?? undefined,\n locale: this.getAttribute('locale') ?? undefined,\n };\n void this.applyOptions({ ...attrOptions, ...this._options });\n }\n\n private async applyOptions(options: HopePlayerOptions): Promise<void> {\n if (options.poster) this.videoEl.poster = options.poster;\n this.videoEl.autoplay = !!options.autoplay;\n this.videoEl.muted = !!options.muted;\n this.videoEl.loop = !!options.loop;\n this.autoHideDelayMs = options.autoHideDelayMs ?? DEFAULT_AUTO_HIDE_DELAY_MS;\n if (options.miniProgress && !this.miniProgress) {\n this.miniProgress = new MiniProgress(this.videoEl);\n this.videoArea.appendChild(this.miniProgress.el);\n this.updateMiniProgress();\n } else if (!options.miniProgress && this.miniProgress) {\n this.miniProgress.destroy();\n this.miniProgress = null;\n }\n if (options.showRemainingTime !== undefined) {\n this.controlBar.setShowRemaining(options.showRemainingTime);\n }\n if (options.theme) this.setAttribute('data-theme', options.theme);\n else this.removeAttribute('data-theme');\n\n this.localeCode = options.locale ?? 'tr';\n applyLocale(this.i18n, options.locale, options.labels);\n this.centerPlayButton.setAttribute('aria-label', this.i18n.play);\n this.controlBar.refreshLabels();\n this.captionRenderer.refreshLabels(this.i18n);\n if (this.captionTrackActive) this.controlBar.settingsMenu.setCaptionAppearance(this.buildCaptionAppearance());\n this.errorScreen.refreshLabels();\n this.playlistRunner?.refreshLabels();\n this.hopeStory?.refreshLabels();\n this.countdownScreen?.refreshLabels();\n this.geoChecker?.refreshLabels();\n this.redirectScreen?.refreshLabels();\n this.qrResume?.refreshLabels();\n this.dubbing?.refreshLabels();\n this.liveWallClock?.refreshLabels();\n this.loopSection?.refreshLabels();\n this.markProgress?.refreshLabels();\n this.unregisterSticky?.refreshLabels?.();\n\n if (!this.bootResolved) {\n return;\n }\n\n // Gate plugin'leri (countdown/geo) KAYNAK YÜKLENMEDEN/autoplay denenmeden\n // ÖNCE kuruluyor ki blockChrome() + 'play' dinleyicisi zaten takılı olsun\n // — aksi halde autoplay bir an için gerçekten oynamaya başlayabilirdi.\n const gateCtx = () => ({\n videoEl: this.videoEl,\n overlayContainerEl: this.videoArea,\n blockChrome: () => this.blockChrome('countdown-geo'),\n unblockChrome: () => this.unblockChrome('countdown-geo'),\n i18n: this.i18n,\n });\n\n if (options.countdownScreen && !this.countdownScreen) {\n const { installCountdownScreen } = await import('./plugins/countdown-screen');\n this.countdownScreen = installCountdownScreen(gateCtx(), options.countdownScreen);\n }\n\n if (options.geoChecker && !this.geoChecker) {\n const { installGeoChecker } = await import('./plugins/geo-checker');\n this.geoChecker = installGeoChecker(gateCtx(), options.geoChecker);\n }\n\n this.unblockChrome('boot');\n\n if (this.countdownScreen && !this.countdownScreen.isComplete()) {\n this.pendingPlaybackOptions = options;\n if (!this.playbackInitRegistered) {\n this.playbackInitRegistered = true;\n this.countdownScreen.onComplete(() => {\n const pending = this.pendingPlaybackOptions;\n this.pendingPlaybackOptions = null;\n if (pending) void this.initPlayback(pending);\n });\n }\n } else {\n await this.initPlayback(options);\n }\n }\n\n private async initPlayback(options: HopePlayerOptions): Promise<void> {\n const sources = options.sources?.length ? options.sources : options.src ? [{ src: options.src, label: this.i18n.autoQuality }] : [];\n if (sources.length > 0) {\n const initial = sources.find((s) => s.selected) ?? sources[0]!;\n await this.sourceManager.load(initial.src, initial.type);\n if (options.autoplay) this.videoEl.play().catch(() => {});\n }\n\n if (sources.length > 1) {\n this.controlBar.setQualities(\n sources.map((s) => ({\n label: s.label,\n onSelect: () => void this.switchQualitySource(s),\n })),\n sources.find((s) => s.selected)?.label ?? sources[0]!.label\n );\n }\n\n if (options.ads && !this.adsController) {\n const adsOptions: AdsOptions = options.ads === true ? {} : options.ads;\n // Reklamsız entegrasyonlarda bu import hiç tetiklenmez — bkz. plan:\n // \"eklenmeyen plugin yük bindirmemeli\" (dinamik import = ayrı chunk).\n const { installAds } = await import('./plugins/ads');\n this.adsController = await installAds(\n {\n videoEl: this.videoEl,\n hostEl: this,\n adLayerEl: this.adLayerEl,\n hideChrome: () => this.blockChrome('ads', 'reduced'),\n showChrome: () => this.unblockChrome('ads'),\n // IMA'nın KENDİ UI'ı üzerinden (ör. reklam video'suna\n // tıklama) duraklatılır/devam ettirilirse toolbar'ımızın\n // ikonu da senkron kalsın diye.\n onAdPlayStateChange: () => this.controlBar.refreshAdPlayState(),\n locale: this.localeCode,\n },\n adsOptions\n );\n }\n\n if (options.gesture && !this.gestureControls) {\n const gestureOptions = options.gesture === true ? {} : options.gesture;\n const { installGesture } = await import('./plugins/gesture');\n this.gestureControls = installGesture(\n { videoEl: this.videoEl, overlayContainerEl: this.videoArea, isAdActive: () => this.isAdPlaying() },\n gestureOptions\n );\n }\n\n if (options.loopSection && !this.loopSection) {\n const loopOptions = options.loopSection === true ? {} : options.loopSection;\n const { installLoopSection } = await import('./plugins/loop-section');\n this.loopSection = installLoopSection(\n {\n videoEl: this.videoEl,\n seekBarEl: this.controlBar.seekBar.el,\n markers: this.controlBar.seekBar,\n addControlButton: (label, icon, onClick) => this.controlBar.addButton(label, icon, onClick),\n i18n: this.i18n,\n },\n loopOptions\n );\n }\n\n if (options.inViewAutoplay && !this.inViewAutoplay) {\n const inViewOptions = options.inViewAutoplay === true ? {} : options.inViewAutoplay;\n const { installInViewAutoplay } = await import('./plugins/in-view-autoplay');\n this.inViewAutoplay = installInViewAutoplay(\n { videoEl: this.videoEl, observeEl: this, isAdActive: () => this.isAdPlaying() },\n inViewOptions\n );\n }\n\n if (options.sticky && !this.unregisterSticky) {\n const stickyOptions = options.sticky === true ? {} : options.sticky;\n const { installSticky } = await import('./plugins/sticky');\n this.unregisterSticky = installSticky(\n {\n key: this.instanceKey,\n videoEl: this.videoEl,\n hostEl: this,\n wrapperEl: this,\n closeButtonMountEl: this.videoArea,\n isAdActive: () => this.isAdPlaying(),\n i18n: this.i18n,\n },\n stickyOptions\n );\n }\n\n if (options.playlist && !this.playlistRunner) {\n const { installPlaylist } = await import('./plugins/playlist');\n this.playlistRunner = installPlaylist(\n {\n videoEl: this.videoEl,\n hostEl: this,\n panelEl: this.getOrCreatePanelContainer(),\n loadSource: (src, type) => this.sourceManager.load(src, type),\n setPoster: (url) => {\n this.videoEl.poster = url;\n },\n requestFreshAd: (tag) => this.adsController?.resetForNewItem(tag),\n i18n: this.i18n,\n },\n options.playlist\n );\n }\n\n if (options.story && !this.hopeStory) {\n const { installStory } = await import('./plugins/story');\n this.hopeStory = installStory(\n {\n videoEl: this.videoEl,\n hostEl: this,\n videoAreaEl: this.videoArea,\n playerBodyEls: [this.root.querySelector<HTMLDivElement>('.media-layer')!, this.chromeEl, this.centerPlayButton],\n loadSource: (src, type) => this.sourceManager.load(src, type),\n setPoster: (url) => {\n this.videoEl.poster = url;\n },\n requestFreshAd: (tag) => this.adsController?.resetForNewItem(tag),\n i18n: this.i18n,\n },\n options.story\n );\n }\n\n if (options.markers && !this.markProgress) {\n const { installMarkers } = await import('./plugins/markers');\n this.markProgress = installMarkers(\n {\n videoEl: this.videoEl,\n overlayContainerEl: this.videoArea,\n addSeekBarMarker: (ratio, extraClass) => this.controlBar.seekBar.addMarker(ratio, extraClass),\n i18n: this.i18n,\n },\n options.markers\n );\n }\n\n if (options.segments?.length && !this.segments) {\n const { installSegments } = await import('./plugins/segments');\n this.segments = installSegments({ videoEl: this.videoEl, seekBar: this.controlBar.seekBar }, options.segments);\n }\n\n if (options.spriteThumbnails && !this.spriteThumbnails) {\n const { installSpriteThumbnails } = await import('./plugins/sprite-thumbnails');\n this.spriteThumbnails = installSpriteThumbnails(\n {\n videoEl: this.videoEl,\n seekBar: this.controlBar.seekBar,\n playerWidth: () => this.videoArea.clientWidth,\n },\n options.spriteThumbnails\n );\n }\n\n if (options.redirectScreen && !this.redirectScreen) {\n const { installRedirectScreen } = await import('./plugins/redirect-screen');\n this.redirectScreen = installRedirectScreen(\n { videoEl: this.videoEl, overlayContainerEl: this.videoArea, isAdActive: () => this.isAdPlaying(), i18n: this.i18n },\n options.redirectScreen\n );\n }\n\n if (options.qrResume && !this.qrResume) {\n const { installQrResume } = await import('./plugins/qr-resume');\n this.qrResume = installQrResume({ videoEl: this.videoEl, overlayContainerEl: this.videoArea, i18n: this.i18n }, options.qrResume);\n }\n if (this.qrResume) {\n // QrResume aç/kapa satırı her initPlayback'te yeniden eklenir (dil değişimi vb.).\n const qr = this.qrResume;\n this.controlBar.settingsMenu.setQrResumeToggle({\n label: this.i18n.qrResumeMenuLabel,\n getValueLabel: () => (qr.isEnabled() ? this.i18n.qrResumeOn : this.i18n.qrResumeOff),\n onToggle: () => qr.setEnabled(!qr.isEnabled()),\n });\n }\n\n if (options.dubbing && !this.dubbing) {\n const { installDubbing } = await import('./plugins/dubbing');\n this.dubbing = installDubbing(\n {\n videoEl: this.videoEl,\n loadSource: (src, type) => this.sourceManager.load(src, type),\n registerSubmenu: (def) => this.controlBar.settingsMenu.registerSubmenu(def),\n unregisterSubmenu: (key) => this.controlBar.settingsMenu.unregisterSubmenu(key),\n i18n: this.i18n,\n },\n options.dubbing\n );\n }\n\n if (options.liveWallClock && !this.liveWallClock) {\n const liveWallClockOptions = options.liveWallClock === true ? {} : options.liveWallClock;\n const { installLiveWallClock } = await import('./plugins/live');\n this.liveWallClock = installLiveWallClock(\n {\n videoEl: this.videoEl,\n seekBarEl: this.controlBar.seekBar.el,\n addControlElement: (el) => this.controlBar.addElement(el),\n i18n: this.i18n,\n },\n liveWallClockOptions\n );\n }\n\n if (options.dai && !this.daiController) {\n const { installDai } = await import('./plugins/dai');\n this.daiController = await installDai(\n {\n videoEl: this.videoEl,\n hostEl: this,\n adUiEl: this.adLayerEl,\n loadStreamUrl: (url) => this.sourceManager.load(url),\n disableSeeking: () => this.disableSeeking(),\n enableSeeking: () => this.enableSeeking(),\n },\n options.dai\n );\n }\n\n if (options.subtitles?.length) {\n this.subtitleTracks = attachSubtitleTracks(this.videoEl, options.subtitles);\n const defaultTrack = options.subtitles.find((s) => s.default);\n // selectCaption: altyazı seçiminin tek doğruluk kaynağı (track mode + renderer + ayarlar menüsü).\n const selectCaption = (label: string | null): void => {\n const track = selectSubtitleTrack(this.subtitleTracks, label);\n this.captionRenderer.setActiveTrack(track);\n this.captionTrackActive = track !== null;\n this.controlBar.settingsMenu.setCaptionAppearance(track !== null ? this.buildCaptionAppearance() : null);\n };\n this.controlBar.setCaptions(\n [\n { label: this.i18n.captionsOff, onSelect: () => selectCaption(null) },\n ...this.subtitleTracks.map(({ label }) => ({\n label,\n onSelect: () => selectCaption(label),\n })),\n ],\n defaultTrack?.label ?? this.i18n.captionsOff\n );\n selectCaption(defaultTrack?.label ?? null);\n } else {\n this.captionRenderer.setActiveTrack(null);\n this.captionTrackActive = false;\n this.controlBar.settingsMenu.setCaptionAppearance(null);\n }\n }\n\n /** Ayarlar menüsünün \"Altyazı\" alt menüsüne eklenen Boyut/Renk/Konum satırları — her zaman GÜNCEL `this.i18n`'i okur (dil sonradan değişse bile). */\n private buildCaptionAppearance(): SettingsCaptionAppearance {\n const sizes: CaptionFontSize[] = ['small', 'normal', 'large'];\n const buildColorOptions = (\n presets: readonly string[],\n get: () => string,\n set: (value: string) => void,\n label: string\n ): SettingsColorOption[] =>\n presets.map((value, i) => ({\n value,\n active: get() === value,\n ariaLabel: `${label} ${i + 1}`,\n onSelect: () => set(value),\n }));\n return {\n sizeLabel: this.i18n.captionSize,\n getSizeOptions: () =>\n sizes.map((size) => ({\n label:\n size === 'small'\n ? this.i18n.captionSizeSmall\n : size === 'large'\n ? this.i18n.captionSizeLarge\n : this.i18n.captionSizeNormal,\n active: this.captionRenderer.getFontSize() === size,\n onSelect: () => this.captionRenderer.setFontSize(size),\n })),\n bgColorLabel: this.i18n.captionBgColor,\n getBgColorOptions: () =>\n buildColorOptions(\n CaptionRenderer.BG_COLOR_PRESETS,\n () => this.captionRenderer.getBgColor(),\n (v) => this.captionRenderer.setBgColor(v),\n this.i18n.captionBgColor\n ),\n textColorLabel: this.i18n.captionTextColor,\n getTextColorOptions: () =>\n buildColorOptions(\n CaptionRenderer.TEXT_COLOR_PRESETS,\n () => this.captionRenderer.getTextColor(),\n (v) => this.captionRenderer.setTextColor(v),\n this.i18n.captionTextColor\n ),\n resetPositionLabel: this.i18n.captionResetPosition,\n onResetPosition: () => this.captionRenderer.resetPosition(),\n };\n }\n\n /** Playlist panelinin monte edileceği, .video-area'nın ALTINDAKİ (shadow root içi) kapsayıcı — ilk ihtiyaçta oluşturulur. */\n private panelContainer: HTMLDivElement | null = null;\n private getOrCreatePanelContainer(): HTMLDivElement {\n if (!this.panelContainer) {\n this.panelContainer = document.createElement('div');\n this.root.appendChild(this.panelContainer);\n }\n return this.panelContainer;\n }\n\n /** Kalite değişirken oynatma konumunu ve play/pause durumunu korur. */\n private async switchQualitySource(source: NonNullable<HopePlayerOptions['sources']>[number]): Promise<void> {\n const resumeTime = this.videoEl.currentTime;\n const wasPlaying = !this.videoEl.paused;\n await this.sourceManager.load(source.src, source.type);\n this.videoEl.currentTime = resumeTime;\n if (wasPlaying) this.videoEl.play().catch(() => {});\n this.dispatchEvent(new CustomEvent('hp:qualitychange', { detail: { label: source.label } }));\n }\n\n private readonly onHlsLevelsChanged = (levels: HlsQualityLevel[], activeIndex: number): void => {\n if (levels.length <= 1) return;\n const label = (l: HlsQualityLevel) => `${l.height}p`;\n this.controlBar.setQualities(\n [\n { label: this.i18n.autoQuality, onSelect: () => this.sourceManager.setLevel(-1) },\n ...levels.map((l) => ({ label: label(l), onSelect: () => this.sourceManager.setLevel(l.index) })),\n ],\n activeIndex === -1 ? this.i18n.autoQuality : label(levels[activeIndex]!)\n );\n };\n\n // ── Fullscreen (vendor-prefix uyumlu) ───────────────────────────────\n\n private requestFullscreenCompat(): void {\n const el = this as unknown as {\n requestFullscreen?: () => Promise<void>;\n webkitRequestFullscreen?: () => void;\n };\n if (el.requestFullscreen) void el.requestFullscreen();\n else if (el.webkitRequestFullscreen) el.webkitRequestFullscreen();\n }\n\n private exitFullscreenCompat(): void {\n const doc = document as unknown as { webkitExitFullscreen?: () => void };\n if (document.exitFullscreen) void document.exitFullscreen();\n else if (doc.webkitExitFullscreen) doc.webkitExitFullscreen();\n }\n\n private isFullscreenActive(): boolean {\n return document.fullscreenElement === this;\n }\n\n private readonly onFullscreenChange = (): void => {\n this.controlBar.setFullscreenState(this.isFullscreenActive());\n };\n\n // ── Oynatma durumuna göre merkez buton + otomatik gizlenme ──\n\n // Değer: 'hidden' (tamamen gizle — countdown/geo) ya da 'reduced' (yalnızca oynat/duraklat + ses — ads).\n private readonly chromeBlockers = new Map<string, 'hidden' | 'reduced'>();\n private get isChromeBlocked(): boolean {\n return this.chromeBlockers.size > 0;\n }\n private get isChromeFullyHidden(): boolean {\n for (const mode of this.chromeBlockers.values()) if (mode === 'hidden') return true;\n return false;\n }\n\n private readonly onPlay = (): void => {\n if (!this.isChromeBlocked) {\n this.centerPlayButton.style.opacity = '0';\n this.centerPlayButton.style.pointerEvents = 'none';\n this.scheduleAutoHide();\n }\n this.dispatchEvent(new CustomEvent('hp:play'));\n };\n\n private readonly onPause = (): void => {\n if (!this.isChromeBlocked) {\n this.centerPlayButton.style.opacity = '1';\n this.centerPlayButton.style.pointerEvents = 'auto';\n this.showChrome();\n }\n this.dispatchEvent(new CustomEvent('hp:pause'));\n };\n\n private readonly onPointerDownFocus = (): void => {\n this.focus();\n // AdDisplayContainer.initialize() bir kullanıcı jestinde çağrılmalı (IMA) — player'a ilk dokunuşta.\n this.adsController?.initializeDisplayContainerOnce();\n };\n\n private readonly onVideoPressStart = (e: MouseEvent | TouchEvent): void => {\n this.tapCandidate = true;\n const point = 'touches' in e ? e.touches[0] : e;\n if (!point) return;\n this.tapStartX = point.clientX;\n this.tapStartY = point.clientY;\n };\n\n private readonly onVideoPressEnd = (e: MouseEvent | TouchEvent): void => {\n if (!this.tapCandidate) return;\n this.tapCandidate = false;\n if (this.isChromeBlocked) return;\n if (this.gestureControls?.isCurrentlyHolding()) return;\n\n const point = 'changedTouches' in e ? e.changedTouches[0] : e;\n if (point) {\n const moved = Math.hypot(point.clientX - this.tapStartX, point.clientY - this.tapStartY);\n if (moved > TAP_MAX_MOVE_PX) return;\n }\n if (this.videoEl.paused) void this.videoEl.play().catch(() => {});\n else this.videoEl.pause();\n };\n\n private readonly onVideoPressCancel = (): void => {\n this.tapCandidate = false;\n };\n\n private showChrome(): void {\n this.setChromeOpacity('1');\n }\n\n /** Chrome görünürlüğünün tek giriş noktası — altyazı da haberdar olur (kontroller gizlenince en alta iner). */\n private setChromeOpacity(value: '0' | '1'): void {\n this.chromeEl.style.opacity = value;\n this.chromeVisible = value === '1';\n // captionRenderer constructor'da chrome'dan SONRA kuruluyor — o ana kadarki çağrılar için güvenli.\n this.captionRenderer?.setChromeVisible(this.chromeVisible);\n this.updateMiniProgress();\n }\n\n /** İnce ilerleme çizgisi: yalnızca kontroller gizliyken; reklam/giriş ekranı (chrome bloklu) sırasında değil. */\n private updateMiniProgress(): void {\n this.miniProgress?.setVisible(!this.chromeVisible && !this.isChromeBlocked);\n }\n\n /**\n * Plugin (ads/countdown/geo) chrome'u kendi key'iyle gizler; unblockChrome aynı key'le açar.\n * 'reduced' (ads): yalnızca oynat/duraklat + ses kalır. Merkez buton her modda gizli.\n */\n blockChrome(key: string, mode: 'hidden' | 'reduced' = 'hidden'): void {\n this.chromeBlockers.set(key, mode);\n this.updateMiniProgress();\n if (this.hideTimer) clearTimeout(this.hideTimer);\n this.centerPlayButton.style.opacity = '0';\n this.centerPlayButton.style.pointerEvents = 'none';\n if (this.isChromeFullyHidden) {\n this.setChromeOpacity('0');\n this.chromeEl.style.pointerEvents = 'none';\n } else {\n // pointerEvents'e inline dokunma — CSS'teki pointer-events-none'ı ezip reklamın \"Reklamı Geç\" butonunu kapatırdı.\n this.setChromeOpacity('1');\n }\n this.controlBar.setAdMode(this.chromeBlockers.get('ads') === 'reduced');\n }\n\n /** Bloklayan plugin işini bitirince çağırır — başka bir blocker hâlâ aktifse chrome açılmaz. */\n unblockChrome(key: string): void {\n this.chromeBlockers.delete(key);\n this.updateMiniProgress();\n this.controlBar.setAdMode(this.chromeBlockers.get('ads') === 'reduced');\n if (this.isChromeBlocked) {\n if (this.isChromeFullyHidden) {\n this.setChromeOpacity('0');\n this.chromeEl.style.pointerEvents = 'none';\n } else {\n // bkz. blockChrome'daki not — pointerEvents'a KASITLI dokunulmuyor.\n this.setChromeOpacity('1');\n this.chromeEl.style.pointerEvents = '';\n }\n return;\n }\n\n this.chromeEl.style.pointerEvents = '';\n if (this.videoEl.paused) {\n this.centerPlayButton.style.opacity = '1';\n this.centerPlayButton.style.pointerEvents = 'auto';\n this.showChrome();\n } else {\n this.scheduleAutoHide();\n }\n }\n\n /** DAI reklam arası boyunca kullanıcı reklamın İÇİNE seek edemesin diye (sunucu taraflı eklenen reklamlar seekable aralığın parçası). */\n disableSeeking(): void {\n this.controlBar.seekBar.el.style.pointerEvents = 'none';\n this.controlBar.seekBar.el.style.opacity = '0.5';\n }\n\n enableSeeking(): void {\n this.controlBar.seekBar.el.style.pointerEvents = '';\n this.controlBar.seekBar.el.style.opacity = '';\n }\n\n private readonly scheduleAutoHide = (): void => {\n this.showChrome();\n if (this.hideTimer) clearTimeout(this.hideTimer);\n if (this.videoEl.paused) return;\n this.hideTimer = setTimeout(() => {\n this.setChromeOpacity('0');\n }, this.autoHideDelayMs);\n };\n}\n","import { HopePlayerElement } from './HopePlayerElement';\n\nif (typeof window !== 'undefined' && !customElements.get('hope-player')) {\n customElements.define('hope-player', HopePlayerElement);\n}\n\nexport { HopePlayerElement };\nexport type {\n HopeThemePreset,\n HopeLocale,\n HopeLocaleStrings,\n HopePlayerOptions,\n HopePlayerEventMap,\n AdsOptions,\n AdsRetryOptions,\n PrebidOptions,\n PrebidBreakOptions,\n PrebidBidderConfig,\n GestureOptions,\n LoopSectionOptions,\n InViewAutoplayOptions,\n StickyOptions,\n StickyCorner,\n PlayableItem,\n PlaylistOptions,\n PlaylistUiOptions,\n StoryOptions,\n StoryUiOptions,\n StoryGestureOptions,\n MarkerPopupOptions,\n MarkerPingOptions,\n MarkerAction,\n MarkerItem,\n MarkersOptions,\n SegmentItem,\n SpriteThumbnailsOptions,\n CountdownScreenOptions,\n GeoCheckerOptions,\n RedirectScreenSuggestion,\n RedirectScreenOptions,\n QrResumeOptions,\n DubbingTrack,\n DubbingOptions,\n LiveWallClockOptions,\n DaiOptions,\n LiveAdsOptions,\n} from './types';\nexport type { SettingsSubmenuDef, SettingsSubmenuItem } from './controls/SettingsMenu';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'hope-player': HopePlayerElement;\n }\n}\n"],"names":["detectSourceType","src","type","normalizedType","_a","SourceManager","video","onLevelsChanged","__publicField","Hls","hls","levels","level","index","_event","data","formatTime","seconds","totalSeconds","h","m","mm","ss","SeekBar","labels","duration","hasDuration","ratio","rect","w","x","tick","playedRatio","bufferedEnd","i","bufferedRatio","c","span","local","r","track","key","suppressed","clientX","next","zoneEnd","ch","ranges","container","el","bufferedEl","playedEl","base","extraClass","marker","createIcon","name","setIconName","WHEEL_VOLUME_STEP","HIDE_DELAY_MS","VolumePanel","adHooks","current","effectiveVolume","label","playing","e","clientY","color","SettingsMenu","playbackRates","options","activeLabel","appearance","toggle","def","s","value","onClick","btn","title","onBack","item","rate","active","q","kind","grid","opt","swatch","LIVE_EDGE_TOLERANCE_SEC","COMPACT_MAX_WIDTH","setButtonLabel","iconButton","iconName","shortcut","icon","ControlBar","callbacks","paused","isLive","remaining","edge","behind","row","leftGroup","play","liveDot","spacer","rightGroup","pip","fullscreen","width","compact","isFullscreen","display","iconColor","show","seekable","buffered","SHOW_DELAY_MS","GAP_PX","EDGE_PADDING_PX","EXCLUDE_PARTS","canHover","TooltipController","mountEl","target","related","fromEl","part","mountRect","targetRect","ttRect","top","left","maxLeft","KeyboardController","host","toggleFullscreen","LoadingSpinner","ErrorScreen","code","messages","fn","attachSubtitleTracks","subtitles","t","attached","sub","trackEl","selectSubtitleTrack","tracks","trackLabel","isActive","ROWS","TOP_GAP_PX","GAP_ABOVE_SEEKBAR_PX","GAP_ABOVE_SEEKBAR_COMPACT_PX","BOTTOM_GAP_MIN_PX","DRAG_TAP_THRESHOLD_PX","STORAGE_KEY_ROW","STORAGE_KEY_SIZE","STORAGE_KEY_BG_COLOR","STORAGE_KEY_TEXT_COLOR","FONT_SIZE_MULTIPLIER","BG_COLOR_PRESETS","TEXT_COLOR_PRESETS","readStoredRow","raw","n","readStoredFontSize","readStoredColor","presets","fallback","CaptionRenderer","videoArea","seekBarEl","cues","cue","min","max","targetBottom","translatePx","finalBottom","snappedIndex","size","areaRect","seekRect","topMargin","bottomGap","rowIndex","animate","fromPx","targetPx","prevPx","visible","MiniProgress","end","STYLE_ID","injectIconFont","style","iconFontFaceCss","tr","en","BUILTIN_LOCALES","createLocaleStrings","locale","overrides","applyLocale","DEFAULT_PLAYBACK_RATES","DEFAULT_AUTO_HIDE_DELAY_MS","TAP_MAX_MOVE_PX","TEMPLATE","HopePlayerElement","activeIndex","l","point","tailwindCss","wrapper","centerChip","v","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","_q","_r","attrOptions","gateCtx","installCountdownScreen","installGeoChecker","pending","sources","initial","adsOptions","installAds","gestureOptions","installGesture","loopOptions","installLoopSection","inViewOptions","installInViewAutoplay","stickyOptions","installSticky","installPlaylist","url","tag","installStory","installMarkers","installSegments","installSpriteThumbnails","installRedirectScreen","installQrResume","qr","installDubbing","liveWallClockOptions","installLiveWallClock","installDai","defaultTrack","selectCaption","sizes","buildColorOptions","get","set","source","resumeTime","wasPlaying","doc","mode"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var A = Object.defineProperty;
|
|
2
2
|
var g = (h, t, e) => t in h ? A(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
|
|
3
3
|
var n = (h, t, e) => g(h, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
-
import { c as b } from "./index-
|
|
4
|
+
import { c as b } from "./index-BjmWoP4E.js";
|
|
5
5
|
const P = {
|
|
6
6
|
startMode: "after_current",
|
|
7
7
|
startIndex: 0,
|
|
@@ -233,4 +233,4 @@ export {
|
|
|
233
233
|
I as PlaylistRunner,
|
|
234
234
|
M as installPlaylist
|
|
235
235
|
};
|
|
236
|
-
//# sourceMappingURL=index-
|
|
236
|
+
//# sourceMappingURL=index-CEmsL1uT.js.map
|