@hopeplayer/core 1.0.15 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -14
- package/dist/HopePlayerElement.d.ts +37 -0
- package/dist/HopePlayerElement.d.ts.map +1 -1
- package/dist/chunks/adTriggers-4SueRFgK.js +415 -0
- package/dist/chunks/adTriggers-4SueRFgK.js.map +1 -0
- package/dist/chunks/{index-BCMVXNL0.js → ads-DPL7m9PV.js} +135 -158
- package/dist/chunks/ads-DPL7m9PV.js.map +1 -0
- package/dist/chunks/{index-BeJNpAyx.js → audio-LkYgd5Wq.js} +7 -7
- package/dist/chunks/audio-LkYgd5Wq.js.map +1 -0
- package/dist/chunks/{ScratchSound-0XKHUcJK.js → audioScratchSound-7XkwCCDm.js} +1 -1
- package/dist/chunks/audioScratchSound-7XkwCCDm.js.map +1 -0
- package/dist/chunks/cast-DCAT2agI.js +387 -0
- package/dist/chunks/cast-DCAT2agI.js.map +1 -0
- package/dist/chunks/{index-rENB3n9O.js → countdownScreen-CI-u6jjA.js} +1 -1
- package/dist/chunks/countdownScreen-CI-u6jjA.js.map +1 -0
- package/dist/chunks/{index-Q8FMOHj0.js → dai-B9Tth1Iv.js} +1 -1
- package/dist/chunks/dai-B9Tth1Iv.js.map +1 -0
- package/dist/chunks/{index-DCXX1ZJG.js → debugPanel-Bnc_7GOn.js} +1 -1
- package/dist/chunks/debugPanel-Bnc_7GOn.js.map +1 -0
- package/dist/chunks/{index-DXWK4EFa.js → dubbing-kNMPpyHl.js} +1 -1
- package/dist/chunks/dubbing-kNMPpyHl.js.map +1 -0
- package/dist/chunks/{index-BBmuCtKu.js → geoChecker-BRtvHwI-.js} +1 -1
- package/dist/chunks/geoChecker-BRtvHwI-.js.map +1 -0
- package/dist/chunks/{index-Ca8hocby.js → gesture-BzPCgi87.js} +1 -1
- package/dist/chunks/gesture-BzPCgi87.js.map +1 -0
- package/dist/chunks/gpt-CGXHTG_H.js +18 -0
- package/dist/chunks/gpt-CGXHTG_H.js.map +1 -0
- package/dist/chunks/{index-3QALpwsf.js → inViewAutoplay-CRJe7GA4.js} +1 -1
- package/dist/chunks/inViewAutoplay-CRJe7GA4.js.map +1 -0
- package/dist/chunks/{index-7IBf8Y-R.js → liveWallClock-ChUTtzLD.js} +1 -1
- package/dist/chunks/liveWallClock-ChUTtzLD.js.map +1 -0
- package/dist/chunks/{index-f0vSgRIK.js → loopSection-CvF4l5uf.js} +1 -1
- package/dist/chunks/loopSection-CvF4l5uf.js.map +1 -0
- package/dist/chunks/{index-DRlQC-ev.js → markers-DE4O8xbw.js} +2 -2
- package/dist/chunks/markers-DE4O8xbw.js.map +1 -0
- package/dist/chunks/{index-CaMVTgh0.js → pauseAd-BQQe21X4.js} +55 -68
- package/dist/chunks/pauseAd-BQQe21X4.js.map +1 -0
- package/dist/chunks/{index-w7pACyTw.js → player-C886oKP-.js} +726 -391
- package/dist/chunks/player-C886oKP-.js.map +1 -0
- package/dist/chunks/{index-DpUZXNJS.js → playlist-CI3mRZjo.js} +2 -2
- package/dist/chunks/playlist-CI3mRZjo.js.map +1 -0
- package/dist/chunks/{VideoPrebid-CpckFzSq.js → prebid-CRY3i2OT.js} +1 -1
- package/dist/chunks/prebid-CRY3i2OT.js.map +1 -0
- package/dist/chunks/{index-DT8-oMPm.js → qrResume-BNy8XCp_.js} +1 -1
- package/dist/chunks/qrResume-BNy8XCp_.js.map +1 -0
- package/dist/chunks/redirectScreen-CJ3q9OX4.js +208 -0
- package/dist/chunks/redirectScreen-CJ3q9OX4.js.map +1 -0
- package/dist/chunks/rewardedUnlock-EyGMB9PK.js +264 -0
- package/dist/chunks/rewardedUnlock-EyGMB9PK.js.map +1 -0
- package/dist/chunks/{index-BOoNcKeR.js → segments-C2HKU6XK.js} +2 -2
- package/dist/chunks/segments-C2HKU6XK.js.map +1 -0
- package/dist/chunks/{index-D5P-LWbg.js → sponsorship-DyFwGmEb.js} +20 -20
- package/dist/chunks/sponsorship-DyFwGmEb.js.map +1 -0
- package/dist/chunks/{index-BvoB2O1p.js → spriteThumbnails-D0NQ5CCp.js} +2 -2
- package/dist/chunks/spriteThumbnails-D0NQ5CCp.js.map +1 -0
- package/dist/chunks/{index-DGtpFgHV.js → statsPanel-DSClIwA3.js} +1 -1
- package/dist/chunks/statsPanel-DSClIwA3.js.map +1 -0
- package/dist/chunks/{index-CDDke5rz.js → sticky-D_eLCNFk.js} +1 -1
- package/dist/chunks/sticky-D_eLCNFk.js.map +1 -0
- package/dist/chunks/{index-ClQg_X1N.js → story-D5Got6-6.js} +2 -2
- package/dist/chunks/{index-ClQg_X1N.js.map → story-D5Got6-6.js.map} +1 -1
- package/dist/chunks/{index-C5oGMHF_.js → tapGestures-DrC42DiI.js} +1 -1
- package/dist/chunks/tapGestures-DrC42DiI.js.map +1 -0
- package/dist/hls/SourceManager.d.ts +8 -0
- package/dist/hls/SourceManager.d.ts.map +1 -1
- package/dist/hls/sourceGroups.d.ts +19 -0
- package/dist/hls/sourceGroups.d.ts.map +1 -0
- package/dist/hope-player.js +1 -1
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/types.d.ts +12 -0
- package/dist/i18n/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/plugins/ad-triggers/AdTriggers.d.ts +99 -0
- package/dist/plugins/ad-triggers/AdTriggers.d.ts.map +1 -0
- package/dist/plugins/ad-triggers/index.d.ts +7 -0
- package/dist/plugins/ad-triggers/index.d.ts.map +1 -0
- package/dist/plugins/ads/AdsController.d.ts +8 -0
- package/dist/plugins/ads/AdsController.d.ts.map +1 -1
- package/dist/plugins/ads/generateVastUrl.d.ts +10 -0
- package/dist/plugins/ads/generateVastUrl.d.ts.map +1 -1
- package/dist/plugins/cast/CastController.d.ts +107 -0
- package/dist/plugins/cast/CastController.d.ts.map +1 -0
- package/dist/plugins/cast/RemoteMediaProxy.d.ts +41 -0
- package/dist/plugins/cast/RemoteMediaProxy.d.ts.map +1 -0
- package/dist/plugins/cast/castSdk.d.ts +160 -0
- package/dist/plugins/cast/castSdk.d.ts.map +1 -0
- package/dist/plugins/cast/index.d.ts +7 -0
- package/dist/plugins/cast/index.d.ts.map +1 -0
- package/dist/plugins/pause-ad/loadGpt.d.ts +2 -0
- package/dist/plugins/pause-ad/loadGpt.d.ts.map +1 -1
- package/dist/plugins/redirect-screen/RedirectScreen.d.ts +26 -3
- package/dist/plugins/redirect-screen/RedirectScreen.d.ts.map +1 -1
- package/dist/plugins/rewarded/RewardedUnlock.d.ts +2 -5
- package/dist/plugins/rewarded/RewardedUnlock.d.ts.map +1 -1
- package/dist/plugins/rewarded/gpt.d.ts +6 -2
- package/dist/plugins/rewarded/gpt.d.ts.map +1 -1
- package/dist/plugins/sponsorship/SponsorshipLayer.d.ts.map +1 -1
- package/dist/types/index.d.ts +308 -3
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +3 -1
- package/dist/chunks/ScratchSound-0XKHUcJK.js.map +0 -1
- package/dist/chunks/VideoPrebid-CpckFzSq.js.map +0 -1
- package/dist/chunks/index-3QALpwsf.js.map +0 -1
- package/dist/chunks/index-7IBf8Y-R.js.map +0 -1
- package/dist/chunks/index-BBmuCtKu.js.map +0 -1
- package/dist/chunks/index-BCMVXNL0.js.map +0 -1
- package/dist/chunks/index-BOoNcKeR.js.map +0 -1
- package/dist/chunks/index-BeJNpAyx.js.map +0 -1
- package/dist/chunks/index-BvoB2O1p.js.map +0 -1
- package/dist/chunks/index-C5oGMHF_.js.map +0 -1
- package/dist/chunks/index-CDDke5rz.js.map +0 -1
- package/dist/chunks/index-Ca8hocby.js.map +0 -1
- package/dist/chunks/index-CaMVTgh0.js.map +0 -1
- package/dist/chunks/index-D5P-LWbg.js.map +0 -1
- package/dist/chunks/index-D6r-BGAV.js +0 -77
- package/dist/chunks/index-D6r-BGAV.js.map +0 -1
- package/dist/chunks/index-DCXX1ZJG.js.map +0 -1
- package/dist/chunks/index-DGtpFgHV.js.map +0 -1
- package/dist/chunks/index-DRlQC-ev.js.map +0 -1
- package/dist/chunks/index-DT8-oMPm.js.map +0 -1
- package/dist/chunks/index-DXWK4EFa.js.map +0 -1
- package/dist/chunks/index-DpUZXNJS.js.map +0 -1
- package/dist/chunks/index-Q8FMOHj0.js.map +0 -1
- package/dist/chunks/index-TkG8IO6q.js +0 -239
- package/dist/chunks/index-TkG8IO6q.js.map +0 -1
- package/dist/chunks/index-f0vSgRIK.js.map +0 -1
- package/dist/chunks/index-rENB3n9O.js.map +0 -1
- package/dist/chunks/index-w7pACyTw.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debugPanel-Bnc_7GOn.js","sources":["../../src/plugins/debug/DebugPanel.ts","../../src/plugins/debug/index.ts"],"sourcesContent":["import type { HopeLocaleStrings } from '../../i18n/types';\nimport type { ErrorLog, PlayerLogEntry, PlayerLogSource } from '../../debug/ErrorLog';\n\nexport interface DebugPanelContext {\n containerEl: HTMLElement;\n i18n: HopeLocaleStrings;\n log: ErrorLog;\n version: string;\n}\n\nconst CLOSE_ICON =\n '<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" aria-hidden=\"true\"><path d=\"M6 6l12 12M18 6L6 18\"/></svg>';\n\n/**\n * Sağ tık menüsündeki \"Hata ayıklama\" — player'ın tüm hatalarını (medya, yayın, reklam, altyazı) zaman sırasıyla,\n * ayrıntılarıyla gösteren ve tüm player alanını kaplayan pencere. Uzun satırlar (URL'ler) kırılır, liste kendi içinde\n * kayar; yeni hata gelince açık pencere canlı güncellenir.\n */\nexport class DebugPanel {\n private readonly el: HTMLDivElement;\n private readonly titleEl: HTMLSpanElement;\n private readonly countEl: HTMLSpanElement;\n private readonly copyBtn: HTMLButtonElement;\n private readonly clearBtn: HTMLButtonElement;\n private readonly closeBtn: HTMLButtonElement;\n private readonly list: HTMLOListElement;\n private readonly emptyEl: HTMLParagraphElement;\n private copiedTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(private readonly ctx: DebugPanelContext) {\n this.el = document.createElement('div');\n this.el.className = 'hp-debug';\n this.el.setAttribute('part', 'debug-panel');\n this.el.setAttribute('role', 'dialog');\n // Odak pencerenin kendisinde (ESC ile kapanır) — butona odaklanınca ipucu kendiliğinden açılıyordu.\n this.el.tabIndex = -1;\n\n const header = document.createElement('div');\n header.className = 'hp-debug-header';\n const title = document.createElement('div');\n title.className = 'hp-debug-title';\n this.titleEl = document.createElement('span');\n this.countEl = document.createElement('span');\n this.countEl.className = 'hp-debug-count';\n title.append(this.titleEl, this.countEl);\n\n const actions = document.createElement('div');\n actions.className = 'hp-debug-actions';\n this.copyBtn = this.button('hp-debug-btn', () => void this.copy());\n this.clearBtn = this.button('hp-debug-btn', () => this.ctx.log.clear());\n this.closeBtn = this.button('hp-stats-close', () => this.hide());\n this.closeBtn.innerHTML = CLOSE_ICON;\n actions.append(this.copyBtn, this.clearBtn, this.closeBtn);\n header.append(title, actions);\n\n this.list = document.createElement('ol');\n this.list.className = 'hp-debug-list';\n this.emptyEl = document.createElement('p');\n this.emptyEl.className = 'hp-debug-empty';\n\n this.el.append(header, this.list, this.emptyEl);\n // Panel tıklamaları / kaydırma videoyu oynat-duraklat yapmasın, klavye kısayolları tetiklenmesin.\n this.el.addEventListener('pointerdown', (e) => e.stopPropagation());\n this.el.addEventListener('click', (e) => e.stopPropagation());\n this.el.addEventListener('dblclick', (e) => e.stopPropagation());\n this.el.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') this.hide();\n e.stopPropagation();\n });\n this.refreshLabels();\n }\n\n get isVisible(): boolean {\n return this.el.isConnected;\n }\n\n show(): void {\n if (!this.isVisible) this.ctx.containerEl.appendChild(this.el);\n this.ctx.log.onChange = () => this.render();\n this.render();\n this.el.focus({ preventScroll: true });\n }\n\n hide(): void {\n if (this.ctx.log.onChange) this.ctx.log.onChange = null;\n this.el.remove();\n }\n\n refreshLabels(): void {\n const t = this.ctx.i18n;\n this.titleEl.textContent = t.debugTitle;\n this.copyBtn.textContent = t.debugCopy;\n this.clearBtn.textContent = t.debugClear;\n this.closeBtn.setAttribute('aria-label', t.debugClose);\n this.emptyEl.textContent = t.debugEmpty;\n if (this.isVisible) this.render();\n }\n\n destroy(): void {\n if (this.copiedTimer) clearTimeout(this.copiedTimer);\n this.hide();\n }\n\n private button(className: string, onClick: () => void): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = className;\n btn.addEventListener('click', onClick);\n return btn;\n }\n\n private sourceLabel(source: PlayerLogSource): string {\n const t = this.ctx.i18n;\n return { media: t.debugSourceMedia, stream: t.debugSourceStream, ads: t.debugSourceAds, subtitles: t.debugSourceSubtitles, player: t.debugSourcePlayer }[source];\n }\n\n private render(): void {\n const entries = this.ctx.log.entries;\n this.countEl.textContent = entries.length ? String(entries.length) : '';\n this.emptyEl.hidden = entries.length > 0;\n this.clearBtn.disabled = entries.length === 0;\n this.copyBtn.disabled = entries.length === 0;\n // En yeni en üstte.\n this.list.replaceChildren(...[...entries].reverse().map((e) => this.row(e)));\n }\n\n private row(entry: PlayerLogEntry): HTMLLIElement {\n const li = document.createElement('li');\n li.className = 'hp-debug-row';\n if (entry.fatal) li.setAttribute('data-fatal', '');\n\n const head = document.createElement('div');\n head.className = 'hp-debug-row-head';\n const time = document.createElement('time');\n time.className = 'hp-debug-time';\n const d = new Date(entry.time);\n time.textContent = `${d.toLocaleTimeString([], { hour12: false })}.${String(d.getMilliseconds()).padStart(3, '0')}`;\n const source = document.createElement('span');\n source.className = 'hp-debug-source';\n source.setAttribute('data-source', entry.source);\n source.textContent = this.sourceLabel(entry.source);\n head.append(time, source);\n if (entry.fatal) {\n const fatal = document.createElement('span');\n fatal.className = 'hp-debug-fatal';\n fatal.textContent = this.ctx.i18n.debugFatal;\n head.appendChild(fatal);\n }\n\n const message = document.createElement('div');\n message.className = 'hp-debug-message';\n message.textContent = entry.message;\n if (entry.count && entry.count > 1) {\n const repeat = document.createElement('span');\n repeat.className = 'hp-debug-repeat';\n repeat.textContent = ` ×${entry.count}`;\n message.appendChild(repeat);\n }\n li.append(head, message);\n\n const details = Object.entries(entry.details ?? {}).filter(([, v]) => v !== undefined && v !== '');\n if (details.length) {\n const dl = document.createElement('dl');\n dl.className = 'hp-debug-details';\n for (const [k, v] of details) {\n const dt = document.createElement('dt');\n dt.textContent = k;\n const dd = document.createElement('dd');\n dd.textContent = String(v);\n dl.append(dt, dd);\n }\n li.appendChild(dl);\n }\n return li;\n }\n\n private async copy(): Promise<void> {\n const text = `HopeCorePlayer ${this.ctx.version} · ${navigator.userAgent}\\n${this.ctx.log.toText()}`;\n try {\n await navigator.clipboard.writeText(text);\n } catch {\n return;\n }\n this.copyBtn.textContent = this.ctx.i18n.debugCopied;\n if (this.copiedTimer) clearTimeout(this.copiedTimer);\n this.copiedTimer = setTimeout(() => {\n this.copiedTimer = null;\n this.copyBtn.textContent = this.ctx.i18n.debugCopy;\n }, 1500);\n }\n}\n","import { DebugPanel, type DebugPanelContext } from './DebugPanel';\n\nexport function installDebugPanel(ctx: DebugPanelContext): DebugPanel {\n return new DebugPanel(ctx);\n}\n\nexport { DebugPanel };\nexport type { DebugPanelContext };\n"],"names":["CLOSE_ICON","DebugPanel","ctx","__publicField","header","title","actions","e","className","onClick","btn","source","t","entries","entry","li","head","time","d","fatal","message","repeat","details","v","dl","k","dt","dd","text","installDebugPanel"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dubbing-kNMPpyHl.js","sources":["../../src/plugins/dubbing/Dubbing.ts","../../src/plugins/dubbing/index.ts"],"sourcesContent":["import type { SettingsSubmenuDef } from '../../controls/SettingsMenu';\nimport type { DubbingOptions, DubbingTrack } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\n\nexport interface DubbingPlayerContext {\n videoEl: HTMLVideoElement;\n loadSource(src: string, type?: string): Promise<void>;\n registerSubmenu(def: SettingsSubmenuDef): void;\n unregisterSubmenu(key: string): void;\n i18n: HopeLocaleStrings;\n}\n\nconst SUBMENU_KEY = 'dubbing';\n\nfunction dubLangCode(track: DubbingTrack): string {\n return (track.srclang || track.label || '').toUpperCase().slice(0, 3);\n}\n\n/** Ayarlar menüsüne \"Ses/Dil\" alt menüsü ekler (registerSubmenu). */\nexport class Dubbing {\n private activeIndex: number;\n\n constructor(\n private readonly ctx: DubbingPlayerContext,\n private readonly options: DubbingOptions\n ) {\n const defaultIdx = options.tracks.findIndex((t) => t.default);\n this.activeIndex = defaultIdx >= 0 ? defaultIdx : 0;\n\n this.registerMenu();\n }\n\n /** Dil sonradan değişince başlığı güncel `ctx.i18n.dubbingTitle`'la yeniden kaydeder — `registerSubmenu` aynı key'i replace eder. */\n refreshLabels(): void {\n this.registerMenu();\n }\n\n private registerMenu(): void {\n this.ctx.registerSubmenu({\n key: SUBMENU_KEY,\n title: this.ctx.i18n.dubbingTitle,\n getValueLabel: () => dubLangCode(this.options.tracks[this.activeIndex]!),\n getItems: () =>\n this.options.tracks.map((track, i) => ({\n label: track.label,\n active: i === this.activeIndex,\n onSelect: () => this.select(i),\n })),\n });\n }\n\n destroy(): void {\n this.ctx.unregisterSubmenu(SUBMENU_KEY);\n }\n\n private select(index: number): void {\n if (index === this.activeIndex) return;\n const track = this.options.tracks[index];\n if (!track) return;\n\n const resumeTime = this.ctx.videoEl.currentTime;\n const wasPlaying = !this.ctx.videoEl.paused;\n this.activeIndex = index;\n\n void this.ctx.loadSource(track.src, track.type).then(() => {\n this.ctx.videoEl.currentTime = resumeTime;\n if (wasPlaying) void this.ctx.videoEl.play().catch(() => {});\n });\n }\n}\n","import { Dubbing, type DubbingPlayerContext } from './Dubbing';\nimport type { DubbingOptions } from '../../types';\n\nexport function installDubbing(ctx: DubbingPlayerContext, options: DubbingOptions): Dubbing {\n return new Dubbing(ctx, options);\n}\n\nexport { Dubbing };\nexport type { DubbingPlayerContext };\n"],"names":["SUBMENU_KEY","dubLangCode","track","Dubbing","ctx","options","__publicField","defaultIdx","t","i","index","resumeTime","wasPlaying","installDubbing"],"mappings":";;;AAYA,MAAMA,IAAc;AAEpB,SAASC,EAAYC,GAA6B;AAC9C,UAAQA,EAAM,WAAWA,EAAM,SAAS,IAAI,cAAc,MAAM,GAAG,CAAC;AACxE;AAGO,MAAMC,EAAQ;AAAA,EAGjB,YACqBC,GACAC,GACnB;AALM,IAAAC,EAAA;AAGa,SAAA,MAAAF,GACA,KAAA,UAAAC;AAEjB,UAAME,IAAaF,EAAQ,OAAO,UAAU,CAACG,MAAMA,EAAE,OAAO;AAC5D,SAAK,cAAcD,KAAc,IAAIA,IAAa,GAElD,KAAK,aAAA;AAAA,EACT;AAAA;AAAA,EAGA,gBAAsB;AAClB,SAAK,aAAA;AAAA,EACT;AAAA,EAEQ,eAAqB;AACzB,SAAK,IAAI,gBAAgB;AAAA,MACrB,KAAKP;AAAA,MACL,OAAO,KAAK,IAAI,KAAK;AAAA,MACrB,eAAe,MAAMC,EAAY,KAAK,QAAQ,OAAO,KAAK,WAAW,CAAE;AAAA,MACvE,UAAU,MACN,KAAK,QAAQ,OAAO,IAAI,CAACC,GAAOO,OAAO;AAAA,QACnC,OAAOP,EAAM;AAAA,QACb,QAAQO,MAAM,KAAK;AAAA,QACnB,UAAU,MAAM,KAAK,OAAOA,CAAC;AAAA,MAAA,EAC/B;AAAA,IAAA,CACT;AAAA,EACL;AAAA,EAEA,UAAgB;AACZ,SAAK,IAAI,kBAAkBT,CAAW;AAAA,EAC1C;AAAA,EAEQ,OAAOU,GAAqB;AAChC,QAAIA,MAAU,KAAK,YAAa;AAChC,UAAMR,IAAQ,KAAK,QAAQ,OAAOQ,CAAK;AACvC,QAAI,CAACR,EAAO;AAEZ,UAAMS,IAAa,KAAK,IAAI,QAAQ,aAC9BC,IAAa,CAAC,KAAK,IAAI,QAAQ;AACrC,SAAK,cAAcF,GAEd,KAAK,IAAI,WAAWR,EAAM,KAAKA,EAAM,IAAI,EAAE,KAAK,MAAM;AACvD,WAAK,IAAI,QAAQ,cAAcS,GAC3BC,KAAiB,KAAK,IAAI,QAAQ,KAAA,EAAO,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAC/D,CAAC;AAAA,EACL;AACJ;AClEO,SAASC,EAAeT,GAA2BC,GAAkC;AACxF,SAAO,IAAIF,EAAQC,GAAKC,CAAO;AACnC;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geoChecker-BRtvHwI-.js","sources":["../../src/plugins/geo-checker/GeoChecker.ts","../../src/plugins/geo-checker/index.ts"],"sourcesContent":["import type { GeoCheckerOptions } from '../../types';\nimport type { GatePlayerContext } from '../shared/GatePlayerContext';\n\nconst EU_COUNTRIES = [\n 'EU', 'AD', 'AL', 'AT', 'BA', 'BE', 'BG', 'BY', 'CH', 'CS', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FO', 'FR', 'FX', 'GB', 'GI',\n 'GR', 'HR', 'HU', 'IE', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MD', 'MK', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI',\n 'SJ', 'SK', 'SM', 'UA', 'VA',\n];\nconst MENA_COUNTRIES = [\n 'DZ', 'BH', 'EG', 'IR', 'IQ', 'JO', 'KW', 'LB', 'LY', 'MA', 'OM', 'QA', 'SA', 'PS', 'SD', 'SY', 'TN', 'AE', 'YE',\n 'IL', 'DJ', 'TD', 'SO', 'MR', 'NL',\n];\n\n/** Ücretsiz, API anahtarı gerektirmeyen, CORS'a açık IP-coğrafya servisi. */\nconst DEFAULT_API_URL = 'https://get.geojs.io/v1/ip/geo.json';\n/** geojs'te ülke KODU (`\"TR\"`) — `country` alanı ülke ADI (`\"Türkiye\"`). */\nconst DEFAULT_PARAMETER = 'country_code';\n\n/**\n * IP-coğrafyasına göre erişim kontrolü. API'ye ulaşılamazsa erişime izin verir (fail-open) —\n * güvenlik değil, lisans/yayın bölgesi uyumluluğu.\n */\nexport class GeoChecker {\n private readonly loadingEl: HTMLElement;\n private destroyed = false;\n\n constructor(\n private readonly ctx: GatePlayerContext,\n private readonly options: GeoCheckerOptions\n ) {\n ctx.blockChrome();\n ctx.videoEl.addEventListener('play', this.onPlayWhileBlocked);\n\n this.loadingEl = document.createElement('div');\n this.loadingEl.setAttribute('part', 'geo-loading');\n this.loadingEl.className = 'hp:absolute hp:inset-0 hp:z-40 hp:flex hp:items-center hp:justify-center hp:bg-surface';\n this.loadingEl.innerHTML =\n '<div class=\"hp:w-8 hp:h-8 hp:rounded-full hp:border-2 hp:border-on-surface/30 hp:border-t-accent hp:animate-spin\"></div>';\n ctx.overlayContainerEl.appendChild(this.loadingEl);\n\n void this.check();\n }\n\n /** Uyarı ekranı bir kez (kalıcı olarak) render ediliyor — burada tazelenecek reaktif bir etiket yok, diğer gate plugin'leriyle TUTARLI bir çağrı yüzeyi için var. */\n refreshLabels(): void {\n /* no-op */\n }\n\n destroy(): void {\n this.destroyed = true;\n this.ctx.videoEl.removeEventListener('play', this.onPlayWhileBlocked);\n this.loadingEl.remove();\n }\n\n private readonly onPlayWhileBlocked = (): void => {\n this.ctx.videoEl.pause();\n };\n\n /** Varsayılan geojs: ülke kodu country_code'da (country alanı ülke adı). */\n private async resolveCountry(): Promise<string> {\n if (this.options.getCountry) return String((await this.options.getCountry()) ?? '');\n\n const response = await fetch(this.options.apiUrl || DEFAULT_API_URL);\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n const data: unknown = await response.json();\n const value = (this.options.parameter || DEFAULT_PARAMETER)\n .split('.')\n .reduce<unknown>((obj, key) => (obj && typeof obj === 'object' ? (obj as Record<string, unknown>)[key] : undefined), data);\n return typeof value === 'string' ? value : '';\n }\n\n private async check(): Promise<void> {\n let allowed = true;\n let userCountry = '';\n\n try {\n userCountry = (await this.resolveCountry()).trim().toUpperCase();\n\n let allowList = this.options.allowedCountries || [];\n if (this.options.region === 'EU') allowList = EU_COUNTRIES;\n else if (this.options.region === 'MENA') allowList = MENA_COUNTRIES;\n\n allowed = allowList.some((code) => code.trim().toUpperCase() === userCountry);\n } catch (err) {\n console.warn('[HopePlayer geo-checker] IP sorgusu başarısız, erişime izin veriliyor:', err);\n allowed = true;\n }\n\n if (this.destroyed) return;\n this.loadingEl.remove();\n\n if (allowed) {\n this.ctx.videoEl.removeEventListener('play', this.onPlayWhileBlocked);\n this.ctx.unblockChrome();\n return;\n }\n\n this.showWarning(userCountry);\n }\n\n private showWarning(country: string): void {\n const el = document.createElement('div');\n el.setAttribute('part', 'geo-warning');\n el.className = 'hp:absolute hp:inset-0 hp:z-40 hp:flex hp:flex-col hp:items-center hp:justify-center hp:gap-2 hp:bg-surface hp:text-on-surface hp:text-center hp:p-4';\n\n const messages = this.options.warningMessages?.length ? this.options.warningMessages : [this.ctx.i18n.geoDefaultWarning];\n for (const msg of messages) {\n const p = document.createElement('p');\n p.className = 'hp:text-sm hp:m-0';\n p.textContent = msg;\n el.appendChild(p);\n }\n\n const countryEl = document.createElement('span');\n countryEl.className = 'hp:text-xs hp:opacity-60';\n countryEl.textContent = country || this.ctx.i18n.geoUnknownCountry;\n el.appendChild(countryEl);\n\n this.ctx.overlayContainerEl.appendChild(el);\n // Erişim kalıcı olarak kapalı — unblockChrome() ÇAĞRILMIYOR.\n }\n}\n","import { GeoChecker } from './GeoChecker';\nimport type { GatePlayerContext } from '../shared/GatePlayerContext';\nimport type { GeoCheckerOptions } from '../../types';\n\nexport function installGeoChecker(ctx: GatePlayerContext, options: GeoCheckerOptions): GeoChecker {\n return new GeoChecker(ctx, options);\n}\n\nexport { GeoChecker };\nexport type { GatePlayerContext };\n"],"names":["EU_COUNTRIES","MENA_COUNTRIES","DEFAULT_API_URL","DEFAULT_PARAMETER","GeoChecker","ctx","options","__publicField","response","data","value","obj","key","allowed","userCountry","allowList","code","err","country","_a","el","messages","msg","p","countryEl","installGeoChecker"],"mappings":";;;AAGA,MAAMA,IAAe;AAAA,EACjB;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EACxH;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EACxH;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAC5B,GACMC,IAAiB;AAAA,EACnB;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAC5G;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAClC,GAGMC,IAAkB,uCAElBC,IAAoB;AAMnB,MAAMC,EAAW;AAAA,EAIpB,YACqBC,GACAC,GACnB;AANe,IAAAC,EAAA;AACT,IAAAA,EAAA,mBAAY;AA8BH,IAAAA,EAAA,4BAAqB,MAAY;AAC9C,WAAK,IAAI,QAAQ,MAAA;AAAA,IACrB;AA7BqB,SAAA,MAAAF,GACA,KAAA,UAAAC,GAEjBD,EAAI,YAAA,GACJA,EAAI,QAAQ,iBAAiB,QAAQ,KAAK,kBAAkB,GAE5D,KAAK,YAAY,SAAS,cAAc,KAAK,GAC7C,KAAK,UAAU,aAAa,QAAQ,aAAa,GACjD,KAAK,UAAU,YAAY,0FAC3B,KAAK,UAAU,YACX,4HACJA,EAAI,mBAAmB,YAAY,KAAK,SAAS,GAE5C,KAAK,MAAA;AAAA,EACd;AAAA;AAAA,EAGA,gBAAsB;AAAA,EAEtB;AAAA,EAEA,UAAgB;AACZ,SAAK,YAAY,IACjB,KAAK,IAAI,QAAQ,oBAAoB,QAAQ,KAAK,kBAAkB,GACpE,KAAK,UAAU,OAAA;AAAA,EACnB;AAAA;AAAA,EAOA,MAAc,iBAAkC;AAC5C,QAAI,KAAK,QAAQ,WAAY,QAAO,OAAQ,MAAM,KAAK,QAAQ,WAAA,KAAiB,EAAE;AAElF,UAAMG,IAAW,MAAM,MAAM,KAAK,QAAQ,UAAUN,CAAe;AACnE,QAAI,CAACM,EAAS,GAAI,OAAM,IAAI,MAAM,QAAQA,EAAS,MAAM,EAAE;AAC3D,UAAMC,IAAgB,MAAMD,EAAS,KAAA,GAC/BE,KAAS,KAAK,QAAQ,aAAaP,GACpC,MAAM,GAAG,EACT,OAAgB,CAACQ,GAAKC,MAASD,KAAO,OAAOA,KAAQ,WAAYA,EAAgCC,CAAG,IAAI,QAAYH,CAAI;AAC7H,WAAO,OAAOC,KAAU,WAAWA,IAAQ;AAAA,EAC/C;AAAA,EAEA,MAAc,QAAuB;AACjC,QAAIG,IAAU,IACVC,IAAc;AAElB,QAAI;AACA,MAAAA,KAAe,MAAM,KAAK,eAAA,GAAkB,KAAA,EAAO,YAAA;AAEnD,UAAIC,IAAY,KAAK,QAAQ,oBAAoB,CAAA;AACjD,MAAI,KAAK,QAAQ,WAAW,OAAMA,IAAYf,IACrC,KAAK,QAAQ,WAAW,WAAQe,IAAYd,IAErDY,IAAUE,EAAU,KAAK,CAACC,MAASA,EAAK,KAAA,EAAO,YAAA,MAAkBF,CAAW;AAAA,IAChF,SAASG,GAAK;AACV,cAAQ,KAAK,0EAA0EA,CAAG,GAC1FJ,IAAU;AAAA,IACd;AAEA,QAAI,MAAK,WAGT;AAAA,UAFA,KAAK,UAAU,OAAA,GAEXA,GAAS;AACT,aAAK,IAAI,QAAQ,oBAAoB,QAAQ,KAAK,kBAAkB,GACpE,KAAK,IAAI,cAAA;AACT;AAAA,MACJ;AAEA,WAAK,YAAYC,CAAW;AAAA;AAAA,EAChC;AAAA,EAEQ,YAAYI,GAAuB;AAjG/C,QAAAC;AAkGQ,UAAMC,IAAK,SAAS,cAAc,KAAK;AACvC,IAAAA,EAAG,aAAa,QAAQ,aAAa,GACrCA,EAAG,YAAY;AAEf,UAAMC,KAAWF,IAAA,KAAK,QAAQ,oBAAb,QAAAA,EAA8B,SAAS,KAAK,QAAQ,kBAAkB,CAAC,KAAK,IAAI,KAAK,iBAAiB;AACvH,eAAWG,KAAOD,GAAU;AACxB,YAAME,IAAI,SAAS,cAAc,GAAG;AACpC,MAAAA,EAAE,YAAY,qBACdA,EAAE,cAAcD,GAChBF,EAAG,YAAYG,CAAC;AAAA,IACpB;AAEA,UAAMC,IAAY,SAAS,cAAc,MAAM;AAC/C,IAAAA,EAAU,YAAY,4BACtBA,EAAU,cAAcN,KAAW,KAAK,IAAI,KAAK,mBACjDE,EAAG,YAAYI,CAAS,GAExB,KAAK,IAAI,mBAAmB,YAAYJ,CAAE;AAAA,EAE9C;AACJ;ACrHO,SAASK,EAAkBpB,GAAwBC,GAAwC;AAC9F,SAAO,IAAIF,EAAWC,GAAKC,CAAO;AACtC;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gesture-BzPCgi87.js","sources":["../../src/plugins/gesture/GestureControls.ts","../../src/plugins/gesture/index.ts"],"sourcesContent":["import type { GestureOptions } from '../../types';\n\nexport interface GesturePlayerContext {\n videoEl: HTMLVideoElement;\n /** Basılı tutma göstergesinin (hız/sarma overlay'i) ekleneceği katman. */\n overlayContainerEl: HTMLElement;\n isAdActive(): boolean;\n}\n\nfunction isMobileDevice(): boolean {\n if (typeof navigator === 'undefined') return false;\n return /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);\n}\n\n/** Basılı tutma: mobilde adım adım ileri sarma, masaüstünde playbackRate hızlandırma. */\nexport class GestureControls {\n private readonly options: Required<GestureOptions>;\n private readonly overlayEl: HTMLElement;\n\n private isHolding = false;\n private holdTimeout: ReturnType<typeof setTimeout> | null = null;\n private holdInterval: ReturnType<typeof setInterval> | null = null;\n private wasPaused = false;\n\n constructor(\n private readonly ctx: GesturePlayerContext,\n options: GestureOptions = {}\n ) {\n this.options = {\n holdRate: options.holdRate ?? 2,\n holdIntervalMs: options.holdIntervalMs ?? 200,\n holdDelayMs: options.holdDelayMs ?? 300,\n };\n\n this.overlayEl = document.createElement('div');\n this.overlayEl.setAttribute('part', 'gesture-overlay');\n this.overlayEl.className =\n 'hp:hidden hp:absolute hp:inset-0 hp:z-20 hp:items-center hp:justify-center hp:gap-2 ' +\n 'hp:bg-black/30 hp:text-white hp:text-xl hp:font-semibold hp:pointer-events-none';\n ctx.overlayContainerEl.appendChild(this.overlayEl);\n\n ctx.videoEl.addEventListener('touchstart', this.onPressStart, { passive: false });\n ctx.videoEl.addEventListener('touchend', this.onPressEnd);\n ctx.videoEl.addEventListener('touchcancel', this.onPressLeave);\n ctx.videoEl.addEventListener('mousedown', this.onPressStart);\n ctx.videoEl.addEventListener('mouseup', this.onPressEnd);\n ctx.videoEl.addEventListener('mouseleave', this.onPressLeave);\n }\n\n /** HopePlayerElement'in kendi \"ekrana tıkla → oynat/duraklat\" tetikleyicisinin bir hold sırasında devre dışı kalması için — tek doğruluk kaynağı burası, ayrı bir zamanlayıcı tekrarlanmıyor. */\n isCurrentlyHolding(): boolean {\n return this.isHolding;\n }\n\n destroy(): void {\n this.ctx.videoEl.removeEventListener('touchstart', this.onPressStart);\n this.ctx.videoEl.removeEventListener('touchend', this.onPressEnd);\n this.ctx.videoEl.removeEventListener('touchcancel', this.onPressLeave);\n this.ctx.videoEl.removeEventListener('mousedown', this.onPressStart);\n this.ctx.videoEl.removeEventListener('mouseup', this.onPressEnd);\n this.ctx.videoEl.removeEventListener('mouseleave', this.onPressLeave);\n if (this.holdTimeout) clearTimeout(this.holdTimeout);\n if (this.holdInterval) clearInterval(this.holdInterval);\n this.overlayEl.remove();\n }\n\n private readonly onPressStart = (e: Event): void => {\n if (this.ctx.isAdActive()) return;\n if (this.ctx.videoEl.ended) return;\n this.wasPaused = this.ctx.videoEl.paused;\n\n this.holdTimeout = setTimeout(() => this.startHold(), this.options.holdDelayMs);\n e.preventDefault();\n };\n\n private startHold(): void {\n if (this.isHolding) return;\n this.isHolding = true;\n\n if (isMobileDevice()) {\n const step = (this.options.holdRate * this.options.holdIntervalMs) / 1000;\n this.holdInterval = setInterval(() => {\n const video = this.ctx.videoEl;\n video.currentTime = Math.min(video.duration || video.currentTime + step, video.currentTime + step);\n }, this.options.holdIntervalMs);\n } else {\n this.ctx.videoEl.playbackRate = this.options.holdRate;\n }\n\n this.showOverlay(`${this.options.holdRate}x »`);\n if (this.ctx.videoEl.paused) void this.ctx.videoEl.play().catch(() => {});\n }\n\n private readonly onPressEnd = (): void => {\n this.endHold();\n };\n\n private readonly onPressLeave = (): void => {\n this.endHold();\n };\n\n private endHold(): void {\n if (this.holdTimeout) {\n clearTimeout(this.holdTimeout);\n this.holdTimeout = null;\n }\n\n // Kısa dokunuş: oynat/duraklat HopePlayerElement'in kendi dinleyicisinde.\n if (!this.isHolding) return;\n\n this.isHolding = false;\n this.ctx.videoEl.playbackRate = 1;\n if (this.holdInterval) {\n clearInterval(this.holdInterval);\n this.holdInterval = null;\n }\n this.hideOverlay();\n\n if (this.wasPaused) this.ctx.videoEl.pause();\n }\n\n private showOverlay(text: string): void {\n this.overlayEl.textContent = text;\n this.overlayEl.classList.remove('hp:hidden');\n this.overlayEl.classList.add('hp:flex');\n }\n\n private hideOverlay(): void {\n this.overlayEl.classList.add('hp:hidden');\n this.overlayEl.classList.remove('hp:flex');\n }\n}\n","import { GestureControls, type GesturePlayerContext } from './GestureControls';\nimport type { GestureOptions } from '../../types';\n\nexport function installGesture(ctx: GesturePlayerContext, options: GestureOptions): GestureControls {\n return new GestureControls(ctx, options);\n}\n\nexport { GestureControls };\nexport type { GesturePlayerContext };\n"],"names":["isMobileDevice","GestureControls","ctx","options","__publicField","step","video","text","installGesture"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const n = "https://securepubads.g.doubleclick.net/tag/js/gpt.js";
|
|
2
|
+
let o = null;
|
|
3
|
+
function d() {
|
|
4
|
+
return o || (window.googletag = window.googletag || { cmd: [] }, o = new Promise((r, c) => {
|
|
5
|
+
const t = () => {
|
|
6
|
+
window.googletag.cmd.push(() => r(window.googletag));
|
|
7
|
+
};
|
|
8
|
+
if (document.querySelector(`script[src="${n}"]`)) return t();
|
|
9
|
+
const e = document.createElement("script");
|
|
10
|
+
e.async = !0, e.src = n, e.onload = t, e.onerror = () => {
|
|
11
|
+
o = null, c(new Error("GPT yüklenemedi"));
|
|
12
|
+
}, document.head.appendChild(e);
|
|
13
|
+
}), o);
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
d as l
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=gpt-CGXHTG_H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpt-CGXHTG_H.js","sources":["../../src/plugins/pause-ad/loadGpt.ts"],"sourcesContent":["/** Google Publisher Tag (GPT) için kullanılan minimal yüzey. */\nexport interface GptSlot {\n addService(service: unknown): GptSlot;\n setTargeting(key: string, value: string | string[]): GptSlot;\n getSlotElementId(): string;\n}\n\nexport interface GptSlotRenderEndedEvent {\n slot: GptSlot;\n isEmpty: boolean;\n size: [number, number] | number[] | null;\n}\n\nexport interface GptPubAds {\n addEventListener(type: 'slotRenderEnded', listener: (e: GptSlotRenderEndedEvent) => void): void;\n removeEventListener?(type: 'slotRenderEnded', listener: (e: GptSlotRenderEndedEvent) => void): void;\n refresh(slots: GptSlot[]): void;\n isInitialLoadDisabled(): boolean;\n}\n\nexport interface GoogleTag {\n cmd: Array<() => void> | { push(fn: () => void): void };\n defineSlot(adUnitPath: string, sizes: Array<[number, number]>, divId: string): GptSlot | null;\n /** Out-of-page slot: boyutsuz; içerik (ör. özel HTML, tam sayfa kreatif) Ad Manager'da belirlenir. */\n defineOutOfPageSlot(adUnitPath: string, divId: string): GptSlot | null;\n pubads(): GptPubAds;\n enableServices(): void;\n display(divId: string): void;\n destroySlots(slots?: GptSlot[]): boolean;\n}\n\ndeclare global {\n interface Window {\n googletag?: GoogleTag;\n }\n}\n\nconst GPT_SRC = 'https://securepubads.g.doubleclick.net/tag/js/gpt.js';\nlet loading: Promise<GoogleTag> | null = null;\n\n/** GPT'yi bir kez yükler; sayfada zaten varsa onu kullanır. Komutlar googletag.cmd kuyruğuyla çalışır. */\nexport function loadGpt(): Promise<GoogleTag> {\n if (loading) return loading;\n window.googletag = window.googletag || ({ cmd: [] } as unknown as GoogleTag);\n loading = new Promise((resolve, reject) => {\n const ready = (): void => {\n window.googletag!.cmd.push(() => resolve(window.googletag!));\n };\n if (document.querySelector(`script[src=\"${GPT_SRC}\"]`)) return ready();\n const script = document.createElement('script');\n script.async = true;\n script.src = GPT_SRC;\n script.onload = ready;\n script.onerror = () => {\n loading = null;\n reject(new Error('GPT yüklenemedi'));\n };\n document.head.appendChild(script);\n });\n return loading;\n}\n"],"names":["GPT_SRC","loading","loadGpt","resolve","reject","ready","script"],"mappings":"AAqCA,MAAMA,IAAU;AAChB,IAAIC,IAAqC;AAGlC,SAASC,IAA8B;AAC1C,SAAID,MACJ,OAAO,YAAY,OAAO,aAAc,EAAE,KAAK,CAAA,EAAC,GAChDA,IAAU,IAAI,QAAQ,CAACE,GAASC,MAAW;AACvC,UAAMC,IAAQ,MAAY;AACtB,aAAO,UAAW,IAAI,KAAK,MAAMF,EAAQ,OAAO,SAAU,CAAC;AAAA,IAC/D;AACA,QAAI,SAAS,cAAc,eAAeH,CAAO,IAAI,UAAUK,EAAA;AAC/D,UAAMC,IAAS,SAAS,cAAc,QAAQ;AAC9C,IAAAA,EAAO,QAAQ,IACfA,EAAO,MAAMN,GACbM,EAAO,SAASD,GAChBC,EAAO,UAAU,MAAM;AACnB,MAAAL,IAAU,MACVG,EAAO,IAAI,MAAM,iBAAiB,CAAC;AAAA,IACvC,GACA,SAAS,KAAK,YAAYE,CAAM;AAAA,EACpC,CAAC,GACML;AACX;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inViewAutoplay-CRJe7GA4.js","sources":["../../src/plugins/in-view-autoplay/InViewAutoplay.ts","../../src/plugins/in-view-autoplay/index.ts"],"sourcesContent":["import type { InViewAutoplayOptions } from '../../types';\n\nexport interface InViewAutoplayPlayerContext {\n videoEl: HTMLVideoElement;\n /** IntersectionObserver'ın izlediği kök element — genelde player'ın host custom element'i. */\n observeEl: Element;\n isAdActive(): boolean;\n}\n\n/** Viewport dışına çıkınca duraklat; yalnızca bu plugin duraklattıysa geri girince devam et. */\nexport class InViewAutoplay {\n private readonly threshold: number;\n private readonly onlyIfMuted: boolean;\n private readonly observer: IntersectionObserver;\n private pausedByThis = false;\n\n constructor(\n private readonly ctx: InViewAutoplayPlayerContext,\n options: InViewAutoplayOptions = {}\n ) {\n this.threshold = options.threshold ?? 0.3;\n this.onlyIfMuted = options.onlyIfMuted ?? true;\n\n this.observer = new IntersectionObserver(this.onIntersect, { threshold: [this.threshold] });\n this.observer.observe(ctx.observeEl);\n }\n\n destroy(): void {\n this.observer.disconnect();\n }\n\n private readonly onIntersect = (entries: IntersectionObserverEntry[]): void => {\n if (this.ctx.isAdActive()) return;\n\n for (const entry of entries) {\n if (entry.isIntersecting && entry.intersectionRatio >= this.threshold) {\n this.resumeIfPausedByThis();\n } else {\n this.pauseIfPlaying();\n }\n }\n };\n\n private pauseIfPlaying(): void {\n const video = this.ctx.videoEl;\n if (video.paused || video.ended) return;\n this.pausedByThis = true;\n video.pause();\n }\n\n private resumeIfPausedByThis(): void {\n if (!this.pausedByThis) return;\n this.pausedByThis = false;\n const video = this.ctx.videoEl;\n if (this.onlyIfMuted && !video.muted) return;\n void video.play().catch(() => {});\n }\n}\n","import { InViewAutoplay, type InViewAutoplayPlayerContext } from './InViewAutoplay';\nimport type { InViewAutoplayOptions } from '../../types';\n\nexport function installInViewAutoplay(ctx: InViewAutoplayPlayerContext, options: InViewAutoplayOptions): InViewAutoplay {\n return new InViewAutoplay(ctx, options);\n}\n\nexport { InViewAutoplay };\nexport type { InViewAutoplayPlayerContext };\n"],"names":["InViewAutoplay","ctx","options","__publicField","entries","entry","video","installInViewAutoplay"],"mappings":";;;AAUO,MAAMA,EAAe;AAAA,EAMxB,YACqBC,GACjBC,IAAiC,IACnC;AARe,IAAAC,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACT,IAAAA,EAAA,sBAAe;AAiBN,IAAAA,EAAA,qBAAc,CAACC,MAA+C;AAC3E,UAAI,MAAK,IAAI;AAEb,mBAAWC,KAASD;AAChB,UAAIC,EAAM,kBAAkBA,EAAM,qBAAqB,KAAK,YACxD,KAAK,qBAAA,IAEL,KAAK,eAAA;AAAA,IAGjB;AAxBqB,SAAA,MAAAJ,GAGjB,KAAK,YAAYC,EAAQ,aAAa,KACtC,KAAK,cAAcA,EAAQ,eAAe,IAE1C,KAAK,WAAW,IAAI,qBAAqB,KAAK,aAAa,EAAE,WAAW,CAAC,KAAK,SAAS,GAAG,GAC1F,KAAK,SAAS,QAAQD,EAAI,SAAS;AAAA,EACvC;AAAA,EAEA,UAAgB;AACZ,SAAK,SAAS,WAAA;AAAA,EAClB;AAAA,EAcQ,iBAAuB;AAC3B,UAAMK,IAAQ,KAAK,IAAI;AACvB,IAAIA,EAAM,UAAUA,EAAM,UAC1B,KAAK,eAAe,IACpBA,EAAM,MAAA;AAAA,EACV;AAAA,EAEQ,uBAA6B;AACjC,QAAI,CAAC,KAAK,aAAc;AACxB,SAAK,eAAe;AACpB,UAAMA,IAAQ,KAAK,IAAI;AACvB,IAAI,KAAK,eAAe,CAACA,EAAM,SAC1BA,EAAM,OAAO,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACpC;AACJ;ACtDO,SAASC,EAAsBN,GAAkCC,GAAgD;AACpH,SAAO,IAAIF,EAAeC,GAAKC,CAAO;AAC1C;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liveWallClock-ChUTtzLD.js","sources":["../../src/plugins/live/LiveWallClock.ts","../../src/plugins/live/index.ts"],"sourcesContent":["import type { LiveWallClockOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\n\nexport interface LiveWallClockPlayerContext {\n videoEl: HTMLVideoElement;\n seekBarEl: HTMLElement;\n addControlElement(el: HTMLElement): void;\n /** UI dili (chrome metinleri) — `options.locale` (Intl saat biçimlendirme locale'i, ör. 'tr-TR') ile KARIŞTIRILMASIN, ayrı bir kavram. */\n i18n: HopeLocaleStrings;\n /**\n * Şu an oynatılan anın gerçek tarihi — HLS `EXT-X-PROGRAM-DATE-TIME`'dan (hls.js `playingDate`, Safari `getStartDate()`).\n * Yoksa null; saat o zaman \"canlı uçtan geride kalınan süre\"den tahmin edilir.\n */\n getPlayingDate?(): Date | null;\n}\n\nconst DEFAULTS: Required<LiveWallClockOptions> = {\n locale: 'tr-TR',\n timeZone: 'UTC',\n showSeconds: true,\n tooltipMode: 'clock',\n};\n\n/**\n * Canlı yayında duvar saati + seek bar hover tooltip'i. Yayında PROGRAM-DATE-TIME varsa saat doğrudan oradan okunur\n * (encoder/CDN gecikmesi dahil doğru); yoksa canlı uç (seekable, yoksa buffered sonu) anının şu anki saat olduğu varsayılır.\n */\nexport class LiveWallClock {\n private readonly clockEl: HTMLElement;\n private readonly tooltipEl: HTMLElement;\n private readonly options: Required<LiveWallClockOptions>;\n\n private clockTimer: ReturnType<typeof setTimeout> | null = null;\n private tooltipTimer: ReturnType<typeof setTimeout> | null = null;\n private isHovering = false;\n private lastSeekBarPoint: number | null = null;\n\n constructor(\n private readonly ctx: LiveWallClockPlayerContext,\n options: LiveWallClockOptions = {}\n ) {\n this.options = { ...DEFAULTS, ...options };\n\n this.clockEl = document.createElement('span');\n this.clockEl.setAttribute('part', 'live-clock');\n this.clockEl.setAttribute('role', 'status');\n this.clockEl.setAttribute('aria-label', ctx.i18n.liveClock);\n this.clockEl.className = 'hp:hidden hp:text-xs hp:text-on-surface hp:opacity-90 hp:tabular-nums hp:whitespace-nowrap hp:ml-1';\n ctx.addControlElement(this.clockEl);\n\n this.tooltipEl = document.createElement('div');\n this.tooltipEl.setAttribute('part', 'live-tooltip');\n this.tooltipEl.className =\n 'hp:hidden hp:absolute hp:bottom-full hp:mb-2 hp-center-x hp:px-2 hp:py-1 hp:rounded hp:bg-surface-elev hp:text-on-surface hp:text-xs hp:tabular-nums hp:whitespace-nowrap hp:pointer-events-none hp:z-20';\n ctx.seekBarEl.appendChild(this.tooltipEl);\n\n ctx.seekBarEl.addEventListener('mouseenter', this.onSeekEnter);\n ctx.seekBarEl.addEventListener('mouseleave', this.onSeekLeave);\n ctx.seekBarEl.addEventListener('mousemove', this.onSeekMove);\n\n this.startClockTick();\n }\n\n refreshLabels(): void {\n this.clockEl.setAttribute('aria-label', this.ctx.i18n.liveClock);\n }\n\n destroy(): void {\n this.stopClockTick();\n this.stopTooltipTick();\n this.ctx.seekBarEl.removeEventListener('mouseenter', this.onSeekEnter);\n this.ctx.seekBarEl.removeEventListener('mouseleave', this.onSeekLeave);\n this.ctx.seekBarEl.removeEventListener('mousemove', this.onSeekMove);\n this.clockEl.remove();\n this.tooltipEl.remove();\n }\n\n /** Canlılık için duration === Infinity yeterli — native HLS'te DVR'sız canlıda seekable boş kalabiliyor. */\n private isLive(): boolean {\n return this.ctx.videoEl.duration === Infinity;\n }\n\n /** Canlı edge'in media-time'ı (saniye) — seekable aralığının sonu; seekable boşsa (bkz. isLive notu) buffered aralığının sonu. */\n private liveEdge(): number | null {\n const { seekable, buffered } = this.ctx.videoEl;\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 /** Geri sarılabilir pencerenin başı — kayan pencereli canlıda 0 değil (ör. 3600). */\n private windowStart(): number {\n const { seekable, buffered } = this.ctx.videoEl;\n if (seekable.length) return seekable.start(0);\n if (buffered.length) return buffered.start(0);\n return 0;\n }\n\n /** `mediaTime` anının duvar saati (ms) — PROGRAM-DATE-TIME varsa ondan, yoksa canlı uca göre tahmin. */\n private wallClockAt(mediaTime: number, liveEdge: number): number {\n const playing = this.ctx.getPlayingDate?.();\n if (playing && Number.isFinite(playing.getTime())) return playing.getTime() + (mediaTime - this.ctx.videoEl.currentTime) * 1000;\n return Date.now() - Math.max(0, liveEdge - mediaTime) * 1000;\n }\n\n // ── saat ──\n\n private startClockTick(): void {\n const tick = () => {\n this.renderClock();\n const delay = 1000 - (Date.now() % 1000);\n this.clockTimer = setTimeout(tick, delay);\n };\n tick();\n }\n\n private stopClockTick(): void {\n if (this.clockTimer) {\n clearTimeout(this.clockTimer);\n this.clockTimer = null;\n }\n }\n\n private renderClock(): void {\n if (!this.isLive()) {\n this.clockEl.classList.add('hp:hidden');\n return;\n }\n\n const liveNow = this.liveEdge();\n const ct = this.ctx.videoEl.currentTime;\n if (liveNow === null || !Number.isFinite(ct)) {\n this.clockEl.textContent = '--:--:--';\n this.clockEl.classList.remove('hp:hidden');\n return;\n }\n\n this.clockEl.textContent = this.formatClock(new Date(this.wallClockAt(ct, liveNow)));\n this.clockEl.classList.remove('hp:hidden');\n }\n\n // ── seekbar hover tooltip ──\n\n private readonly onSeekEnter = (): void => {\n this.isHovering = true;\n this.renderTooltip();\n this.startTooltipTick();\n };\n\n private readonly onSeekLeave = (): void => {\n this.isHovering = false;\n this.lastSeekBarPoint = null;\n this.stopTooltipTick();\n this.hideTooltip();\n };\n\n private readonly onSeekMove = (e: MouseEvent): void => {\n const rect = this.ctx.seekBarEl.getBoundingClientRect();\n const ratio = rect.width > 0 ? (e.clientX - rect.left) / rect.width : null;\n this.lastSeekBarPoint = ratio === null ? null : Math.max(0, Math.min(1, ratio));\n this.renderTooltip();\n this.startTooltipTick();\n };\n\n private startTooltipTick(): void {\n if (this.tooltipTimer) return;\n const tick = () => {\n if (!this.isHovering || this.lastSeekBarPoint == null) {\n this.tooltipTimer = null;\n return;\n }\n this.renderTooltip();\n const delay = 1000 - (Date.now() % 1000);\n this.tooltipTimer = setTimeout(tick, delay);\n };\n tick();\n }\n\n private stopTooltipTick(): void {\n if (this.tooltipTimer) {\n clearTimeout(this.tooltipTimer);\n this.tooltipTimer = null;\n }\n }\n\n private renderTooltip(): void {\n if (!this.isLive() || this.lastSeekBarPoint == null) {\n this.hideTooltip();\n return;\n }\n\n const liveEdge = this.liveEdge();\n if (liveEdge === null || liveEdge <= 0) {\n this.hideTooltip();\n return;\n }\n\n // Seek bar canlıda geri sarılabilir pencereyi (başı → canlı uç) temsil eder.\n const start = Math.min(this.windowStart(), liveEdge);\n const hoveredTime = start + this.lastSeekBarPoint * (liveEdge - start);\n const secondsBehind = Math.max(0, liveEdge - hoveredTime);\n const wallClock = this.formatClock(new Date(this.wallClockAt(hoveredTime, liveEdge)));\n const minus = `-${this.formatDuration(secondsBehind)}`;\n\n this.tooltipEl.innerHTML = '';\n if (this.options.tooltipMode === 'behind') {\n this.tooltipEl.textContent = minus;\n } else if (this.options.tooltipMode === 'both') {\n const line1 = document.createElement('div');\n line1.textContent = wallClock;\n const line2 = document.createElement('div');\n line2.textContent = minus;\n line2.className = 'hp:opacity-70';\n this.tooltipEl.append(line1, line2);\n } else {\n this.tooltipEl.textContent = wallClock;\n }\n\n this.tooltipEl.style.left = `${this.lastSeekBarPoint * 100}%`;\n this.tooltipEl.classList.remove('hp:hidden');\n }\n\n private hideTooltip(): void {\n this.tooltipEl.classList.add('hp:hidden');\n }\n\n // ── format ──\n\n private formatClock(date: Date): string {\n const fmtOpts: Intl.DateTimeFormatOptions = this.options.showSeconds\n ? { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, timeZone: this.options.timeZone }\n : { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: this.options.timeZone };\n try {\n return new Intl.DateTimeFormat(this.options.locale, fmtOpts).format(date);\n } catch {\n const pad = (n: number) => String(n).padStart(2, '0');\n const base = `${pad(date.getHours())}:${pad(date.getMinutes())}`;\n return this.options.showSeconds ? `${base}:${pad(date.getSeconds())}` : base;\n }\n }\n\n private formatDuration(totalSeconds: number): string {\n const s = Math.floor(totalSeconds);\n const hh = Math.floor(s / 3600);\n const mm = Math.floor((s % 3600) / 60);\n const ss = s % 60;\n const pad = (n: number) => String(n).padStart(2, '0');\n return hh > 0 ? `${pad(hh)}:${pad(mm)}:${pad(ss)}` : `${pad(mm)}:${pad(ss)}`;\n }\n}\n","import { LiveWallClock, type LiveWallClockPlayerContext } from './LiveWallClock';\nimport type { LiveWallClockOptions } from '../../types';\n\nexport function installLiveWallClock(ctx: LiveWallClockPlayerContext, options: LiveWallClockOptions): LiveWallClock {\n return new LiveWallClock(ctx, options);\n}\n\nexport { LiveWallClock };\nexport type { LiveWallClockPlayerContext };\n"],"names":["DEFAULTS","LiveWallClock","ctx","options","__publicField","e","rect","ratio","seekable","buffered","mediaTime","liveEdge","_a","_b","playing","tick","delay","liveNow","ct","start","hoveredTime","secondsBehind","wallClock","minus","line1","line2","date","fmtOpts","pad","n","base","totalSeconds","s","hh","mm","ss","installLiveWallClock"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopSection-CvF4l5uf.js","sources":["../../src/plugins/loop-section/LoopSection.ts","../../src/plugins/loop-section/index.ts"],"sourcesContent":["import type { LoopSectionOptions } from '../../types';\n\nexport interface LoopSeekBarMarkers {\n addMarker(ratio: number, extraClass?: string): HTMLDivElement;\n clearMarkers(): void;\n}\n\nexport interface LoopSectionState {\n active: boolean;\n loopStart: number | null;\n loopEnd: number | null;\n}\n\n/** A/B döngü motoru. */\nexport class LoopSection {\n private readonly seconds: number;\n loopStart: number | null = null;\n loopEnd: number | null = null;\n active = false;\n\n constructor(\n private readonly video: HTMLVideoElement,\n private readonly markers: LoopSeekBarMarkers,\n options: LoopSectionOptions = {}\n ) {\n this.seconds = options.seconds || 10;\n }\n\n /** currentTime'dan geriye doğru tam N saniyelik bir aralığı döngüye alır (video başına yakınsa ileri doğru taşar). */\n enableLastN(secs?: number): void {\n const now = this.video.currentTime;\n const duration = this.video.duration;\n const s = secs || this.seconds;\n this.loopStart = Math.max(0, now - s);\n this.loopEnd = Math.min(Number.isFinite(duration) ? duration : Infinity, this.loopStart + s);\n this.activate();\n this.updateMarkers();\n }\n\n setStart(time?: number): void {\n this.loopStart = time ?? this.video.currentTime;\n this.updateMarkers();\n }\n\n setEnd(time?: number): void {\n this.loopEnd = time ?? this.video.currentTime;\n if (this.loopStart !== null && this.loopEnd > this.loopStart) {\n this.activate();\n this.updateMarkers();\n }\n }\n\n toggle(): void {\n if (this.active) this.disable();\n else this.enableLastN();\n }\n\n disable(): void {\n this.active = false;\n this.loopStart = null;\n this.loopEnd = null;\n this.video.removeEventListener('timeupdate', this.onTimeUpdate);\n this.markers.clearMarkers();\n }\n\n getState(): LoopSectionState {\n return { active: this.active, loopStart: this.loopStart, loopEnd: this.loopEnd };\n }\n\n /** `installLoopSection` bunu gerçek buton etiketini tazeleyen bir implementasyonla override eder (bkz. index.ts) — `destroy`'un üzerine yazılma deseniyle aynı. */\n refreshLabels(): void {\n /* no-op varsayılan */\n }\n\n destroy(): void {\n this.disable();\n }\n\n private activate(): void {\n this.active = true;\n this.video.removeEventListener('timeupdate', this.onTimeUpdate);\n this.video.addEventListener('timeupdate', this.onTimeUpdate);\n }\n\n private readonly onTimeUpdate = (): void => {\n if (this.loopEnd !== null && this.video.currentTime >= this.loopEnd) {\n this.video.currentTime = this.loopStart ?? 0;\n }\n };\n\n private updateMarkers(): void {\n this.markers.clearMarkers();\n const duration = this.video.duration;\n if (!duration || !Number.isFinite(duration)) return;\n\n if (this.loopStart !== null) {\n this.markers.addMarker(this.loopStart / duration, 'hp:bg-accent');\n }\n if (this.loopEnd !== null) {\n this.markers.addMarker(this.loopEnd / duration, 'hp:bg-accent');\n }\n }\n}\n","import { LoopSection, type LoopSeekBarMarkers } from './LoopSection';\nimport type { LoopSectionOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\n\nexport interface LoopSectionPlayerContext {\n videoEl: HTMLVideoElement;\n seekBarEl: HTMLElement;\n markers: LoopSeekBarMarkers;\n addControlButton(label: string, iconName: string, onClick: () => void): { btn: HTMLButtonElement; icon: HTMLElement };\n i18n: HopeLocaleStrings;\n}\n\n/** Döngü motorunu kurar: kontrol çubuğuna toggle butonu, seek bar'da orta-tık ile A → B → kapat. */\nexport function installLoopSection(ctx: LoopSectionPlayerContext, options: LoopSectionOptions): LoopSection {\n const engine = new LoopSection(ctx.videoEl, ctx.markers, options);\n\n const { btn } = ctx.addControlButton(ctx.i18n.loop, 'loop', () => {\n engine.toggle();\n refresh();\n });\n\n const refresh = (): void => {\n btn.classList.toggle('hp:text-accent', engine.active);\n };\n\n engine.refreshLabels = () => {\n btn.setAttribute('aria-label', ctx.i18n.loop);\n };\n\n const onSeekBarMiddleClick = (e: MouseEvent): void => {\n if (e.button !== 1) return;\n e.preventDefault();\n\n const rect = ctx.seekBarEl.getBoundingClientRect();\n const ratio = Math.min(1, Math.max(0, (e.clientX - rect.left) / rect.width));\n const duration = ctx.videoEl.duration;\n const clickTime = Number.isFinite(duration) ? ratio * duration : undefined;\n\n const state = engine.getState();\n if (state.active) engine.disable();\n else if (state.loopStart === null) engine.setStart(clickTime);\n else engine.setEnd(clickTime);\n\n refresh();\n };\n ctx.seekBarEl.addEventListener('mousedown', onSeekBarMiddleClick);\n\n const originalDestroy = engine.destroy.bind(engine);\n engine.destroy = () => {\n ctx.seekBarEl.removeEventListener('mousedown', onSeekBarMiddleClick);\n originalDestroy();\n };\n\n return engine;\n}\n\nexport { LoopSection };\nexport type { LoopSeekBarMarkers };\n"],"names":["LoopSection","video","markers","options","__publicField","secs","now","duration","s","time","installLoopSection","ctx","engine","btn","refresh","onSeekBarMiddleClick","e","rect","ratio","clickTime","state","originalDestroy"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var u = Object.defineProperty;
|
|
2
2
|
var m = (p, e, t) => e in p ? u(p, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[e] = t;
|
|
3
3
|
var o = (p, e, t) => m(p, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import { c as b } from "./
|
|
4
|
+
import { c as b } from "./player-C886oKP-.js";
|
|
5
5
|
const f = {
|
|
6
6
|
enabled: !1,
|
|
7
7
|
mode: "rich",
|
|
@@ -202,4 +202,4 @@ export {
|
|
|
202
202
|
v as MarkProgress,
|
|
203
203
|
y as installMarkers
|
|
204
204
|
};
|
|
205
|
-
//# sourceMappingURL=
|
|
205
|
+
//# sourceMappingURL=markers-DE4O8xbw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markers-DE4O8xbw.js","sources":["../../src/plugins/markers/MarkProgress.ts","../../src/plugins/markers/index.ts"],"sourcesContent":["import { createIcon } from '../../icons/Icon';\nimport type { MarkerItem, MarkerPingOptions, MarkerPopupOptions, MarkersOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\n\nexport interface MarkersPlayerContext {\n videoEl: HTMLVideoElement;\n /** Popup overlay'in ekleneceği katman (shadow root içinde, video üzerinde). */\n overlayContainerEl: HTMLElement;\n /** Seek bar üzerinde işaretçi çizmek için — SeekBar.addMarker ile aynı imza. */\n addSeekBarMarker(ratio: number, extraClass?: string): HTMLDivElement;\n i18n: HopeLocaleStrings;\n}\n\ninterface NormalizedMarker extends Required<Pick<MarkerItem, 'time'>> {\n idx: number;\n color?: string;\n label: string;\n pauseOnHit: boolean;\n once: boolean;\n tolerance: number;\n cooldownMs: number;\n action?: MarkerItem['action'];\n popup: MarkerPopupOptions | null;\n pingUrl: string;\n el?: HTMLElement;\n}\n\nconst POPUP_DEFAULTS: Required<MarkerPopupOptions> = {\n enabled: false,\n mode: 'rich',\n text: '',\n imageUrl: '',\n imageAlt: '',\n linkUrl: '',\n // Boş bırakılıyor (sentinel) — gerçek varsayılan metin showPopup()'ta\n // `ctx.i18n.markerLearnMore`/`markerContinue`'dan okunuyor, dil\n // değişimini takip edebilsin diye burada SABİT bir dilde gömülü değil.\n linkText: '',\n continueText: '',\n showContinue: true,\n showClose: true,\n autoplayOnClose: true,\n autoplayOnContinue: true,\n};\n\nconst PING_DEFAULTS: Required<MarkerPingOptions> = { enabled: false, url: '', method: 'GET', includeMarker: false };\n\n/** Zaman tabanlı seek bar işaretçileri — seek/jump koruması, once/cooldown, popup/ping/aksiyon. */\nexport class MarkProgress {\n private readonly markers: NormalizedMarker[];\n private readonly popupGlobal: Required<MarkerPopupOptions>;\n private readonly pingGlobal: Required<MarkerPingOptions>;\n private readonly triggerOnSeek: boolean;\n private readonly seekJumpThresholdSec: number;\n private readonly seekIgnoreWindowMs: number;\n\n private hitSet = new Set<string>();\n private lastHitAt = new Map<string, number>();\n private lastTime = 0;\n private isSeeking = false;\n private ignoreUntilTs = 0;\n private popupEl: HTMLElement | null = null;\n\n constructor(\n private readonly ctx: MarkersPlayerContext,\n options: MarkersOptions\n ) {\n this.triggerOnSeek = options.triggerOnSeek === true;\n this.seekJumpThresholdSec = options.seekJumpThresholdSec ?? 1;\n this.seekIgnoreWindowMs = options.seekIgnoreWindowMs ?? 250;\n this.popupGlobal = { ...POPUP_DEFAULTS, ...options.popup };\n this.pingGlobal = { ...PING_DEFAULTS, ...options.ping };\n\n this.markers = (options.items || [])\n .map((m, idx) => this.normalize(m, idx))\n .filter((m) => Number.isFinite(m.time) && m.time >= 0)\n .sort((a, b) => a.time - b.time);\n\n ctx.videoEl.addEventListener('loadedmetadata', this.onLoadedMetadata);\n ctx.videoEl.addEventListener('timeupdate', this.onTimeUpdate);\n ctx.videoEl.addEventListener('seeking', this.onSeeking);\n ctx.videoEl.addEventListener('seeked', this.onSeeked);\n\n if (ctx.videoEl.readyState >= 1) this.onLoadedMetadata();\n }\n\n /** Popup lazy oluşturulup yeniden kullanılıyor (`ensurePopup`) — zaten açıksa close butonunun statik etiketini tazeler. */\n refreshLabels(): void {\n const closeBtn = this.popupEl?.querySelector('button') as HTMLButtonElement | null;\n if (closeBtn) {\n closeBtn.setAttribute('aria-label', this.ctx.i18n.close);\n }\n }\n\n destroy(): void {\n this.ctx.videoEl.removeEventListener('loadedmetadata', this.onLoadedMetadata);\n this.ctx.videoEl.removeEventListener('timeupdate', this.onTimeUpdate);\n this.ctx.videoEl.removeEventListener('seeking', this.onSeeking);\n this.ctx.videoEl.removeEventListener('seeked', this.onSeeked);\n this.markers.forEach((m) => m.el?.remove());\n this.popupEl?.remove();\n this.popupEl = null;\n this.hitSet.clear();\n this.lastHitAt.clear();\n }\n\n private normalize(m: MarkerItem, idx: number): NormalizedMarker {\n return {\n idx,\n time: Number(m.time),\n color: m.color,\n label: m.label ?? '',\n pauseOnHit: m.pauseOnHit ?? true,\n once: m.once ?? true,\n tolerance: m.tolerance ?? 0.25,\n cooldownMs: m.cooldownMs ?? 600,\n action: m.action,\n popup: m.popup ?? null,\n pingUrl: m.pingUrl ?? '',\n };\n }\n\n private readonly onLoadedMetadata = (): void => {\n const duration = this.ctx.videoEl.duration;\n if (!Number.isFinite(duration) || duration <= 0) return;\n\n this.markers.forEach((m) => {\n if (m.el) return;\n const el = this.ctx.addSeekBarMarker(m.time / duration);\n if (m.color) el.style.backgroundColor = m.color;\n if (m.label) el.title = m.label;\n m.el = el;\n });\n\n this.lastTime = this.ctx.videoEl.currentTime || 0;\n };\n\n private readonly onSeeking = (): void => {\n this.isSeeking = true;\n this.ignoreUntilTs = Date.now() + this.seekIgnoreWindowMs;\n this.lastTime = this.ctx.videoEl.currentTime || 0;\n };\n\n private readonly onSeeked = (): void => {\n this.lastTime = this.ctx.videoEl.currentTime || 0;\n this.isSeeking = false;\n this.ignoreUntilTs = Date.now() + this.seekIgnoreWindowMs;\n };\n\n private readonly onTimeUpdate = (): void => {\n const now = Date.now();\n if (now < this.ignoreUntilTs) return;\n if (this.isSeeking) return;\n\n const t = this.ctx.videoEl.currentTime;\n if (!Number.isFinite(t)) return;\n\n const jumped = Math.abs(t - this.lastTime) >= this.seekJumpThresholdSec;\n if (jumped && !this.triggerOnSeek) {\n this.lastTime = t;\n return;\n }\n\n for (const m of this.markers) {\n const key = `${m.time}-${m.idx}`;\n if (m.once && this.hitSet.has(key)) continue;\n if (!m.once) {\n const last = this.lastHitAt.get(key) || 0;\n if (now - last < m.cooldownMs) continue;\n }\n\n const crossed = this.lastTime < m.time && t >= m.time - m.tolerance;\n if (!crossed) continue;\n\n if (m.once) this.hitSet.add(key);\n else this.lastHitAt.set(key, now);\n\n if (m.pauseOnHit) this.ctx.videoEl.pause();\n\n this.firePing(m);\n this.fireAction(m);\n\n const popupCfg = m.popup ? { ...this.popupGlobal, ...m.popup } : this.popupGlobal;\n if (popupCfg.enabled) {\n this.ctx.videoEl.pause();\n this.showPopup(popupCfg);\n }\n break;\n }\n\n this.lastTime = t;\n };\n\n private resolveUrlTemplate(url: string, m: NormalizedMarker): string {\n if (!url) return '';\n return url.replaceAll('{time}', encodeURIComponent(String(m.time))).replaceAll('{label}', encodeURIComponent(m.label));\n }\n\n private firePing(m: NormalizedMarker): void {\n const baseUrl = m.pingUrl || this.pingGlobal.url;\n const url = this.resolveUrlTemplate(baseUrl, m);\n if (!this.pingGlobal.enabled || !url) return;\n\n try {\n if (this.pingGlobal.method === 'POST') {\n fetch(url, {\n method: 'POST',\n keepalive: true,\n headers: this.pingGlobal.includeMarker ? { 'Content-Type': 'application/json' } : undefined,\n body: this.pingGlobal.includeMarker ? JSON.stringify({ time: m.time, label: m.label, ts: Date.now() }) : undefined,\n }).catch(() => {});\n } else {\n fetch(url, { method: 'GET', keepalive: true }).catch(() => {});\n }\n } catch {\n /* no-op */\n }\n }\n\n private fireAction(m: NormalizedMarker): void {\n const a = m.action;\n if (!a) return;\n\n if (a.type === 'log') {\n console.log('[HopePlayer markers]', a.name || 'marker_hit', { time: m.time, label: m.label }, a.payload);\n return;\n }\n\n if (a.type === 'datalayer') {\n try {\n const w = window as unknown as { dataLayer?: unknown[] };\n w.dataLayer = w.dataLayer || [];\n w.dataLayer.push({\n event: 'HopePlayerVideoEvents',\n trigger: a.name || 'marker_hit',\n marker: { time: m.time, label: m.label, color: m.color },\n payload: a.payload ?? {},\n ts: Date.now(),\n });\n } catch {\n /* no-op */\n }\n return;\n }\n\n if (a.type === 'custom') {\n const fn = a.name ? (window as unknown as Record<string, unknown>)[a.name] : null;\n if (typeof fn === 'function') {\n try {\n (fn as (ctx: unknown) => void)({ marker: m, payload: a.payload });\n } catch (err) {\n console.warn('[HopePlayer markers] custom action fonksiyonu hata verdi:', err);\n }\n } else {\n console.warn('[HopePlayer markers] custom action fonksiyonu bulunamadı: window.' + a.name);\n }\n }\n }\n\n private ensurePopup(): HTMLElement {\n if (this.popupEl) return this.popupEl;\n\n const overlay = document.createElement('div');\n overlay.setAttribute('part', 'marker-popup');\n overlay.className = 'hp:hidden hp:absolute hp:inset-0 hp:z-30 hp:items-center hp:justify-center hp:bg-black/70';\n\n const panel = document.createElement('div');\n panel.className = 'hp:relative hp:max-w-[85%] hp:bg-surface-elev hp:text-on-surface hp:rounded-lg hp:p-4 hp:text-center hp:shadow-xl';\n panel.setAttribute('role', 'dialog');\n panel.setAttribute('aria-modal', 'true');\n\n const closeBtn = document.createElement('button');\n closeBtn.type = 'button';\n closeBtn.setAttribute('aria-label', this.ctx.i18n.close);\n closeBtn.className = 'hp:absolute hp:top-1 hp:right-1 hp:w-6 hp:h-6 hp:flex hp:items-center hp:justify-center hp:bg-transparent hp:border-0 hp:cursor-pointer hp:text-on-surface';\n closeBtn.appendChild(createIcon('close', 'hp:text-sm'));\n\n const mediaWrap = document.createElement('div');\n mediaWrap.className = 'hp:hidden hp:mb-2';\n const img = document.createElement('img');\n img.className = 'hp:max-w-full hp:rounded';\n mediaWrap.appendChild(img);\n\n const textEl = document.createElement('div');\n textEl.className = 'hp:text-sm hp:mb-2';\n\n const linkEl = document.createElement('a');\n linkEl.target = '_blank';\n linkEl.rel = 'noopener noreferrer';\n linkEl.className = 'hp:hidden hp:text-accent hp:underline hp:text-sm hp:block hp:mb-2';\n\n const continueBtn = document.createElement('button');\n continueBtn.type = 'button';\n continueBtn.className = 'hp:hidden hp:px-4 hp:py-1.5 hp:rounded hp:bg-accent hp:text-on-accent hp:border-0 hp:cursor-pointer hp:text-sm';\n\n panel.append(closeBtn, mediaWrap, textEl, linkEl, continueBtn);\n overlay.appendChild(panel);\n this.ctx.overlayContainerEl.appendChild(overlay);\n this.popupEl = overlay;\n return overlay;\n }\n\n private hidePopup(): void {\n this.popupEl?.classList.add('hp:hidden');\n this.popupEl?.classList.remove('hp:flex');\n }\n\n private safePlay(): void {\n void this.ctx.videoEl.play().catch(() => {});\n }\n\n private showPopup(cfg: Required<MarkerPopupOptions>): void {\n const el = this.ensurePopup();\n const textEl = el.querySelector('div.hp\\\\:text-sm.hp\\\\:mb-2:not(.hp\\\\:hidden)') as HTMLElement | null;\n const mediaWrap = el.querySelector('div.hp\\\\:mb-2') as HTMLElement | null;\n const img = el.querySelector('img') as HTMLImageElement | null;\n const linkEl = el.querySelector('a') as HTMLAnchorElement | null;\n const continueBtn = el.querySelectorAll('button')[1] as HTMLButtonElement | null;\n const closeBtn = el.querySelector('button') as HTMLButtonElement | null;\n\n if (closeBtn) closeBtn.style.display = cfg.showClose === false ? 'none' : '';\n if (textEl) textEl.textContent = cfg.text || '';\n\n const isRich = cfg.mode === 'rich';\n if (mediaWrap && img) {\n if (isRich && cfg.imageUrl) {\n mediaWrap.classList.remove('hp:hidden');\n img.src = cfg.imageUrl;\n img.alt = cfg.imageAlt || '';\n } else {\n mediaWrap.classList.add('hp:hidden');\n img.removeAttribute('src');\n }\n }\n\n if (linkEl) {\n if (isRich && cfg.linkUrl) {\n linkEl.classList.remove('hp:hidden');\n linkEl.href = cfg.linkUrl;\n linkEl.textContent = cfg.linkText || this.ctx.i18n.markerLearnMore;\n } else {\n linkEl.classList.add('hp:hidden');\n linkEl.removeAttribute('href');\n }\n }\n\n if (continueBtn) {\n if (cfg.showContinue) {\n continueBtn.classList.remove('hp:hidden');\n continueBtn.textContent = cfg.continueText || this.ctx.i18n.markerContinue;\n } else {\n continueBtn.classList.add('hp:hidden');\n }\n }\n\n const newClose = closeBtn?.cloneNode(true) as HTMLButtonElement | undefined;\n if (closeBtn && newClose) closeBtn.replaceWith(newClose);\n const newCont = continueBtn?.cloneNode(true) as HTMLButtonElement | undefined;\n if (continueBtn && newCont) continueBtn.replaceWith(newCont);\n\n newClose?.addEventListener('click', () => {\n this.hidePopup();\n if (cfg.autoplayOnClose) this.safePlay();\n });\n newCont?.addEventListener('click', () => {\n this.hidePopup();\n if (cfg.autoplayOnContinue) this.safePlay();\n });\n\n el.classList.remove('hp:hidden');\n el.classList.add('hp:flex');\n }\n}\n","import { MarkProgress, type MarkersPlayerContext } from './MarkProgress';\nimport type { MarkersOptions } from '../../types';\n\nexport function installMarkers(ctx: MarkersPlayerContext, options: MarkersOptions): MarkProgress {\n return new MarkProgress(ctx, options);\n}\n\nexport { MarkProgress };\nexport type { MarkersPlayerContext };\n"],"names":["POPUP_DEFAULTS","PING_DEFAULTS","MarkProgress","ctx","options","__publicField","duration","m","el","now","key","last","popupCfg","idx","a","b","closeBtn","_a","url","baseUrl","w","fn","err","overlay","panel","createIcon","mediaWrap","img","textEl","linkEl","continueBtn","_b","cfg","isRich","newClose","newCont","installMarkers"],"mappings":"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"}
|
|
@@ -1,53 +1,40 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
function y() {
|
|
7
|
-
return d || (window.googletag = window.googletag || { cmd: [] }, d = new Promise((n, e) => {
|
|
8
|
-
const t = () => {
|
|
9
|
-
window.googletag.cmd.push(() => n(window.googletag));
|
|
10
|
-
};
|
|
11
|
-
if (document.querySelector(`script[src="${u}"]`)) return t();
|
|
12
|
-
const s = document.createElement("script");
|
|
13
|
-
s.async = !0, s.src = u, s.onload = t, s.onerror = () => {
|
|
14
|
-
d = null, e(new Error("GPT yüklenemedi"));
|
|
15
|
-
}, document.head.appendChild(s);
|
|
16
|
-
}), d);
|
|
17
|
-
}
|
|
18
|
-
const g = [
|
|
1
|
+
var u = Object.defineProperty;
|
|
2
|
+
var c = (o, e, t) => e in o ? u(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
|
|
3
|
+
var s = (o, e, t) => c(o, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { l as m } from "./gpt-CGXHTG_H.js";
|
|
5
|
+
const v = [
|
|
19
6
|
[300, 250],
|
|
20
7
|
[336, 280],
|
|
21
8
|
[250, 250],
|
|
22
9
|
[200, 200]
|
|
23
|
-
],
|
|
24
|
-
let
|
|
25
|
-
class
|
|
10
|
+
], d = 16, y = 104, h = "hp-pause-ad", f = 420;
|
|
11
|
+
let E = 0;
|
|
12
|
+
class g {
|
|
26
13
|
constructor(e, t) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
14
|
+
s(this, "panel");
|
|
15
|
+
s(this, "adHost");
|
|
16
|
+
s(this, "labelEl");
|
|
17
|
+
s(this, "closeBtn");
|
|
18
|
+
s(this, "resumeBtn");
|
|
19
|
+
s(this, "divId");
|
|
20
|
+
s(this, "googletag", null);
|
|
21
|
+
s(this, "slot", null);
|
|
22
|
+
s(this, "slotSizesKey", "");
|
|
23
|
+
s(this, "lastFetchAt", 0);
|
|
24
|
+
s(this, "lastFilled", !1);
|
|
25
|
+
s(this, "waitingForRender", !1);
|
|
26
|
+
s(this, "delayTimer", null);
|
|
27
|
+
s(this, "coverTimer", null);
|
|
28
|
+
s(this, "open", !1);
|
|
29
|
+
s(this, "destroyed", !1);
|
|
43
30
|
// ── olaylar ──
|
|
44
|
-
|
|
31
|
+
s(this, "onPause", () => {
|
|
45
32
|
this.delayTimer && clearTimeout(this.delayTimer), this.delayTimer = setTimeout(() => void this.request(), this.options.delayMs ?? 300);
|
|
46
33
|
});
|
|
47
|
-
|
|
34
|
+
s(this, "onPlay", () => {
|
|
48
35
|
this.delayTimer && clearTimeout(this.delayTimer), this.waitingForRender = !1, this.hide("resumed");
|
|
49
36
|
});
|
|
50
|
-
|
|
37
|
+
s(this, "onRenderEnded", (e) => {
|
|
51
38
|
if (e.slot !== this.slot) return;
|
|
52
39
|
this.lastFilled = !e.isEmpty;
|
|
53
40
|
const t = this.waitingForRender;
|
|
@@ -56,46 +43,46 @@ class w {
|
|
|
56
43
|
return;
|
|
57
44
|
}
|
|
58
45
|
if (!t || !this.ctx.videoEl.paused || this.ctx.isBlocked()) return;
|
|
59
|
-
const
|
|
60
|
-
this.show(
|
|
46
|
+
const i = Array.isArray(e.size) && typeof e.size[0] == "number" ? e.size[0] : null;
|
|
47
|
+
this.show(i ? i + d * 2 : void 0, e.size);
|
|
61
48
|
});
|
|
62
|
-
this.ctx = e, this.options = t, this.divId = `hp-pause-ad-${++
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
49
|
+
this.ctx = e, this.options = t, this.divId = `hp-pause-ad-${++E}`, this.panel = document.createElement("div"), this.panel.className = "hp-pause-ad", this.panel.setAttribute("part", "pause-ad"), this.panel.setAttribute("aria-hidden", "true");
|
|
50
|
+
const i = document.createElement("div");
|
|
51
|
+
i.className = "hp-pause-ad-header", this.labelEl = document.createElement("span"), this.labelEl.className = "hp-pause-ad-label", this.closeBtn = document.createElement("button"), this.closeBtn.type = "button", this.closeBtn.className = "hp-pause-ad-close", this.closeBtn.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg>', this.closeBtn.addEventListener("click", () => this.hide("closed")), i.append(this.labelEl, this.closeBtn);
|
|
52
|
+
const n = document.createElement("div");
|
|
53
|
+
n.className = "hp-pause-ad-body";
|
|
67
54
|
const r = document.createElement("slot");
|
|
68
|
-
r.name =
|
|
55
|
+
r.name = h, n.appendChild(r), this.resumeBtn = document.createElement("button"), this.resumeBtn.type = "button", this.resumeBtn.className = "hp-pause-ad-resume", this.resumeBtn.addEventListener("click", () => void this.ctx.videoEl.play()), t.showResumeButton === !1 && (this.resumeBtn.style.display = "none"), this.panel.append(i, n, this.resumeBtn), this.panel.addEventListener("pointerdown", (a) => a.stopPropagation()), this.panel.addEventListener("click", (a) => a.stopPropagation()), e.videoArea.appendChild(this.panel), e.videoArea.setAttribute("data-pause-ad-ready", ""), this.adHost = document.createElement("div"), this.adHost.slot = h, this.adHost.id = this.divId, e.hostEl.appendChild(this.adHost), this.refreshLabels(), e.videoEl.addEventListener("pause", this.onPause), e.videoEl.addEventListener("play", this.onPlay);
|
|
69
56
|
}
|
|
70
57
|
refreshLabels() {
|
|
71
58
|
this.labelEl.textContent = this.options.label ?? this.ctx.i18n.pauseAdLabel, this.closeBtn.setAttribute("aria-label", this.ctx.i18n.pauseAdClose), this.resumeBtn.textContent = this.ctx.i18n.pauseAdResume;
|
|
72
59
|
}
|
|
73
60
|
destroy() {
|
|
74
|
-
var e, t,
|
|
75
|
-
this.destroyed = !0, this.delayTimer && clearTimeout(this.delayTimer), this.ctx.videoEl.removeEventListener("pause", this.onPause), this.ctx.videoEl.removeEventListener("play", this.onPlay), (
|
|
61
|
+
var e, t, i, n;
|
|
62
|
+
this.destroyed = !0, this.delayTimer && clearTimeout(this.delayTimer), this.ctx.videoEl.removeEventListener("pause", this.onPause), this.ctx.videoEl.removeEventListener("play", this.onPlay), (i = (e = this.googletag) == null ? void 0 : (t = e.pubads()).removeEventListener) == null || i.call(t, "slotRenderEnded", this.onRenderEnded), this.slot && ((n = this.googletag) == null || n.destroySlots([this.slot])), this.setShift(0), this.coverTimer && clearTimeout(this.coverTimer), this.ctx.videoArea.removeAttribute("data-pause-ad"), this.ctx.videoArea.removeAttribute("data-pause-ad-ready"), this.panel.remove(), this.adHost.remove();
|
|
76
63
|
}
|
|
77
64
|
// ── istek / gösterim ──
|
|
78
65
|
/** Alana sığan reklam boyutları (genişlik oranı + dikey alan) — hiçbiri sığmazsa gösterilmez. */
|
|
79
66
|
fittingSizes() {
|
|
80
67
|
const e = this.ctx.videoArea.getBoundingClientRect();
|
|
81
68
|
if (e.width < (this.options.minPlayerWidth ?? 640)) return [];
|
|
82
|
-
const t = e.width * (this.options.maxWidthRatio ?? 0.5) -
|
|
83
|
-
return (this.options.sizes ??
|
|
69
|
+
const t = e.width * (this.options.maxWidthRatio ?? 0.5) - d * 2, i = e.height - y;
|
|
70
|
+
return (this.options.sizes ?? v).filter(([n, r]) => n <= t && r <= i);
|
|
84
71
|
}
|
|
85
72
|
async request() {
|
|
86
73
|
const e = this.ctx.videoEl;
|
|
87
74
|
if (this.destroyed || !e.paused || e.ended || e.seeking || this.ctx.isBlocked()) return;
|
|
88
75
|
const t = this.fittingSizes();
|
|
89
76
|
if (!t.length) return;
|
|
90
|
-
const
|
|
91
|
-
this.panel.style.setProperty("--hp-pause-ad-panel-w", `${
|
|
92
|
-
const
|
|
93
|
-
if (this.slot && this.lastFilled && r === this.slotSizesKey && Date.now() - this.lastFetchAt <
|
|
94
|
-
this.show(
|
|
77
|
+
const i = Math.max(...t.map(([l]) => l)) + d * 2;
|
|
78
|
+
this.panel.style.setProperty("--hp-pause-ad-panel-w", `${i}px`);
|
|
79
|
+
const n = (this.options.refreshIntervalSec ?? 30) * 1e3, r = JSON.stringify(t);
|
|
80
|
+
if (this.slot && this.lastFilled && r === this.slotSizesKey && Date.now() - this.lastFetchAt < n) {
|
|
81
|
+
this.show(i);
|
|
95
82
|
return;
|
|
96
83
|
}
|
|
97
84
|
try {
|
|
98
|
-
this.googletag = this.googletag ?? await
|
|
85
|
+
this.googletag = this.googletag ?? await m();
|
|
99
86
|
} catch (l) {
|
|
100
87
|
console.warn("[HopePlayer pause-ad]", l);
|
|
101
88
|
return;
|
|
@@ -107,7 +94,7 @@ class w {
|
|
|
107
94
|
if (!this.slot || r !== this.slotSizesKey) {
|
|
108
95
|
if (this.slot && a.destroySlots([this.slot]), this.slot = a.defineSlot(this.options.adUnitPath, t, this.divId), !this.slot) return;
|
|
109
96
|
this.slot.addService(a.pubads());
|
|
110
|
-
for (const [l,
|
|
97
|
+
for (const [l, p] of Object.entries(this.options.targeting ?? {})) this.slot.setTargeting(l, p);
|
|
111
98
|
this.slotSizesKey = r, a.pubads().addEventListener("slotRenderEnded", this.onRenderEnded), a.enableServices(), a.display(this.divId), a.pubads().isInitialLoadDisabled() && a.pubads().refresh([this.slot]);
|
|
112
99
|
} else
|
|
113
100
|
a.pubads().refresh([this.slot]);
|
|
@@ -117,8 +104,8 @@ class w {
|
|
|
117
104
|
}
|
|
118
105
|
show(e, t) {
|
|
119
106
|
e && this.panel.style.setProperty("--hp-pause-ad-panel-w", `${e}px`);
|
|
120
|
-
const
|
|
121
|
-
this.open = !0, this.panel.setAttribute("data-open", ""), this.panel.setAttribute("aria-hidden", "false"), this.setShift(
|
|
107
|
+
const i = parseFloat(this.panel.style.getPropertyValue("--hp-pause-ad-panel-w")) || 332;
|
|
108
|
+
this.open = !0, this.panel.setAttribute("data-open", ""), this.panel.setAttribute("aria-hidden", "false"), this.setShift(i), this.emit("shown", t);
|
|
122
109
|
}
|
|
123
110
|
hide(e) {
|
|
124
111
|
this.open && (this.open = !1, this.panel.removeAttribute("data-open"), this.panel.setAttribute("aria-hidden", "true"), this.setShift(0), this.emit("hidden", void 0, e));
|
|
@@ -128,17 +115,17 @@ class w {
|
|
|
128
115
|
const t = this.ctx.videoArea;
|
|
129
116
|
this.coverTimer && clearTimeout(this.coverTimer), this.coverTimer = null, t.style.setProperty("--hp-pause-ad-w", `${e}px`), e > 0 ? t.setAttribute("data-pause-ad", "") : t.hasAttribute("data-pause-ad") && (this.coverTimer = setTimeout(() => {
|
|
130
117
|
this.coverTimer = null, t.removeAttribute("data-pause-ad");
|
|
131
|
-
},
|
|
118
|
+
}, f));
|
|
132
119
|
}
|
|
133
|
-
emit(e, t,
|
|
134
|
-
this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:pausead", { detail: { state: e, size: t, reason:
|
|
120
|
+
emit(e, t, i) {
|
|
121
|
+
this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:pausead", { detail: { state: e, size: t, reason: i } }));
|
|
135
122
|
}
|
|
136
123
|
}
|
|
137
|
-
function T(
|
|
138
|
-
return new
|
|
124
|
+
function T(o, e) {
|
|
125
|
+
return new g(o, e);
|
|
139
126
|
}
|
|
140
127
|
export {
|
|
141
|
-
|
|
128
|
+
g as PauseAd,
|
|
142
129
|
T as installPauseAd
|
|
143
130
|
};
|
|
144
|
-
//# sourceMappingURL=
|
|
131
|
+
//# sourceMappingURL=pauseAd-BQQe21X4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pauseAd-BQQe21X4.js","sources":["../../src/plugins/pause-ad/PauseAd.ts","../../src/plugins/pause-ad/index.ts"],"sourcesContent":["import type { PauseAdOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { loadGpt, type GoogleTag, type GptSlot, type GptSlotRenderEndedEvent } from './loadGpt';\n\nexport interface PauseAdPlayerContext {\n videoEl: HTMLVideoElement;\n /** Light DOM sahibi (GPT reklam div'ini bulabilsin diye slot'lu div buraya eklenir) + hp:pausead olayları. */\n hostEl: HTMLElement;\n videoArea: HTMLElement;\n i18n: HopeLocaleStrings;\n /** IMA reklamı oynuyor ya da giriş ekranı (countdown/geo) açık — bu sırada gösterilmez. */\n isBlocked(): boolean;\n}\n\nconst DEFAULT_SIZES: Array<[number, number]> = [\n [300, 250],\n [336, 280],\n [250, 250],\n [200, 200],\n];\nconst PANEL_PADDING_X = 16;\n/** Başlık + \"Videoya devam et\" satırı + boşluklar (px) — dikey sığma hesabı için. */\nconst PANEL_CHROME_Y = 104;\nconst SLOT_NAME = 'hp-pause-ad';\n/** tailwind.css'teki sıkışma geçişiyle (380ms) aynı + küçük pay. */\nconst SHIFT_TRANSITION_MS = 420;\nlet instanceCount = 0;\n\n/**\n * Pause reklamı: video duraklatılınca Google display reklamı (GPT) istenir; dolarsa video sola animasyonla\n * sıkışır (cover — dış kenarlar kırpılır), sağdan reklam paneli kayar. Boş dönerse hiçbir şey açılmaz.\n * GPT reklamı document.getElementById ile bulur — Shadow DOM'u göremez; bu yüzden reklam div'i host'un light\n * DOM çocuğu olarak oluşturulup paneldeki <slot>'a yansıtılır.\n */\nexport class PauseAd {\n private readonly panel: HTMLDivElement;\n private readonly adHost: HTMLDivElement;\n private readonly labelEl: HTMLSpanElement;\n private readonly closeBtn: HTMLButtonElement;\n private readonly resumeBtn: HTMLButtonElement;\n private readonly divId: string;\n private googletag: GoogleTag | null = null;\n private slot: GptSlot | null = null;\n private slotSizesKey = '';\n private lastFetchAt = 0;\n private lastFilled = false;\n private waitingForRender = false;\n private delayTimer: ReturnType<typeof setTimeout> | null = null;\n private coverTimer: ReturnType<typeof setTimeout> | null = null;\n private open = false;\n private destroyed = false;\n\n constructor(\n private readonly ctx: PauseAdPlayerContext,\n private readonly options: PauseAdOptions\n ) {\n this.divId = `hp-pause-ad-${++instanceCount}`;\n\n this.panel = document.createElement('div');\n this.panel.className = 'hp-pause-ad';\n this.panel.setAttribute('part', 'pause-ad');\n this.panel.setAttribute('aria-hidden', 'true');\n\n const header = document.createElement('div');\n header.className = 'hp-pause-ad-header';\n this.labelEl = document.createElement('span');\n this.labelEl.className = 'hp-pause-ad-label';\n this.closeBtn = document.createElement('button');\n this.closeBtn.type = 'button';\n this.closeBtn.className = 'hp-pause-ad-close';\n this.closeBtn.innerHTML =\n '<svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" aria-hidden=\"true\"><path d=\"M6 6l12 12M18 6L6 18\"/></svg>';\n this.closeBtn.addEventListener('click', () => this.hide('closed'));\n header.append(this.labelEl, this.closeBtn);\n\n const body = document.createElement('div');\n body.className = 'hp-pause-ad-body';\n const slotEl = document.createElement('slot');\n slotEl.name = SLOT_NAME;\n body.appendChild(slotEl);\n\n this.resumeBtn = document.createElement('button');\n this.resumeBtn.type = 'button';\n this.resumeBtn.className = 'hp-pause-ad-resume';\n this.resumeBtn.addEventListener('click', () => void this.ctx.videoEl.play());\n if (options.showResumeButton === false) this.resumeBtn.style.display = 'none';\n\n this.panel.append(header, body, this.resumeBtn);\n // Videoya dokunma/tıklama (oynat/duraklat) panelden tetiklenmesin.\n this.panel.addEventListener('pointerdown', (e) => e.stopPropagation());\n this.panel.addEventListener('click', (e) => e.stopPropagation());\n ctx.videoArea.appendChild(this.panel);\n ctx.videoArea.setAttribute('data-pause-ad-ready', '');\n\n // Light DOM reklam kapsayıcısı — GPT bunu id ile bulur; görüntüsü paneldeki slot'ta.\n this.adHost = document.createElement('div');\n this.adHost.slot = SLOT_NAME;\n this.adHost.id = this.divId;\n ctx.hostEl.appendChild(this.adHost);\n\n this.refreshLabels();\n ctx.videoEl.addEventListener('pause', this.onPause);\n ctx.videoEl.addEventListener('play', this.onPlay);\n }\n\n refreshLabels(): void {\n this.labelEl.textContent = this.options.label ?? this.ctx.i18n.pauseAdLabel;\n this.closeBtn.setAttribute('aria-label', this.ctx.i18n.pauseAdClose);\n this.resumeBtn.textContent = this.ctx.i18n.pauseAdResume;\n }\n\n destroy(): void {\n this.destroyed = true;\n if (this.delayTimer) clearTimeout(this.delayTimer);\n this.ctx.videoEl.removeEventListener('pause', this.onPause);\n this.ctx.videoEl.removeEventListener('play', this.onPlay);\n this.googletag?.pubads().removeEventListener?.('slotRenderEnded', this.onRenderEnded);\n if (this.slot) this.googletag?.destroySlots([this.slot]);\n this.setShift(0);\n if (this.coverTimer) clearTimeout(this.coverTimer);\n this.ctx.videoArea.removeAttribute('data-pause-ad');\n this.ctx.videoArea.removeAttribute('data-pause-ad-ready');\n this.panel.remove();\n this.adHost.remove();\n }\n\n // ── olaylar ──\n\n private readonly onPause = (): void => {\n if (this.delayTimer) clearTimeout(this.delayTimer);\n this.delayTimer = setTimeout(() => void this.request(), this.options.delayMs ?? 300);\n };\n\n private readonly onPlay = (): void => {\n if (this.delayTimer) clearTimeout(this.delayTimer);\n this.waitingForRender = false;\n this.hide('resumed');\n };\n\n // ── istek / gösterim ──\n\n /** Alana sığan reklam boyutları (genişlik oranı + dikey alan) — hiçbiri sığmazsa gösterilmez. */\n private fittingSizes(): Array<[number, number]> {\n const area = this.ctx.videoArea.getBoundingClientRect();\n if (area.width < (this.options.minPlayerWidth ?? 640)) return [];\n const maxW = area.width * (this.options.maxWidthRatio ?? 0.5) - PANEL_PADDING_X * 2;\n const maxH = area.height - PANEL_CHROME_Y;\n return (this.options.sizes ?? DEFAULT_SIZES).filter(([w, h]) => w <= maxW && h <= maxH);\n }\n\n private async request(): Promise<void> {\n const v = this.ctx.videoEl;\n if (this.destroyed || !v.paused || v.ended || v.seeking || this.ctx.isBlocked()) return;\n const sizes = this.fittingSizes();\n if (!sizes.length) return;\n\n // Panel genişliği: sığan en geniş reklam + iç boşluk.\n const panelW = Math.max(...sizes.map(([w]) => w)) + PANEL_PADDING_X * 2;\n this.panel.style.setProperty('--hp-pause-ad-panel-w', `${panelW}px`);\n\n const refreshMs = (this.options.refreshIntervalSec ?? 30) * 1000;\n const sizesKey = JSON.stringify(sizes);\n // Yakın zamanda doldurulmuş ve boyutlar aynı → yeni istek atmadan mevcut reklamı göster.\n if (this.slot && this.lastFilled && sizesKey === this.slotSizesKey && Date.now() - this.lastFetchAt < refreshMs) {\n this.show(panelW);\n return;\n }\n\n try {\n this.googletag = this.googletag ?? (await loadGpt());\n } catch (err) {\n console.warn('[HopePlayer pause-ad]', err);\n return;\n }\n if (this.destroyed || !v.paused) return;\n const gt = this.googletag;\n this.waitingForRender = true;\n gt.cmd.push(() => {\n if (this.destroyed) return;\n if (!this.slot || sizesKey !== this.slotSizesKey) {\n if (this.slot) gt.destroySlots([this.slot]);\n this.slot = gt.defineSlot(this.options.adUnitPath, sizes, this.divId);\n if (!this.slot) return;\n this.slot.addService(gt.pubads());\n for (const [k, val] of Object.entries(this.options.targeting ?? {})) this.slot.setTargeting(k, val);\n this.slotSizesKey = sizesKey;\n gt.pubads().addEventListener('slotRenderEnded', this.onRenderEnded);\n gt.enableServices();\n gt.display(this.divId);\n // Sayfa disableInitialLoad kullanıyorsa display istek atmaz — elle refresh.\n if (gt.pubads().isInitialLoadDisabled()) gt.pubads().refresh([this.slot]);\n } else {\n gt.pubads().refresh([this.slot]);\n }\n this.lastFetchAt = Date.now();\n });\n }\n\n private readonly onRenderEnded = (e: GptSlotRenderEndedEvent): void => {\n if (e.slot !== this.slot) return;\n this.lastFilled = !e.isEmpty;\n const wasWaiting = this.waitingForRender;\n this.waitingForRender = false;\n if (e.isEmpty) {\n this.emit('empty');\n return;\n }\n // İstek sürerken kullanıcı oynattıysa açma.\n if (!wasWaiting || !this.ctx.videoEl.paused || this.ctx.isBlocked()) return;\n const width = Array.isArray(e.size) && typeof e.size[0] === 'number' ? e.size[0] : null;\n this.show(width ? width + PANEL_PADDING_X * 2 : undefined, e.size as [number, number] | undefined);\n };\n\n private show(panelW?: number, size?: [number, number]): void {\n if (panelW) this.panel.style.setProperty('--hp-pause-ad-panel-w', `${panelW}px`);\n const w = parseFloat(this.panel.style.getPropertyValue('--hp-pause-ad-panel-w')) || 332;\n this.open = true;\n this.panel.setAttribute('data-open', '');\n this.panel.setAttribute('aria-hidden', 'false');\n this.setShift(w);\n this.emit('shown', size);\n }\n\n private hide(reason: 'closed' | 'resumed'): void {\n if (!this.open) return;\n this.open = false;\n this.panel.removeAttribute('data-open');\n this.panel.setAttribute('aria-hidden', 'true');\n this.setShift(0);\n this.emit('hidden', undefined, reason);\n }\n\n /** Video ve kontrolleri panel genişliği kadar sola sıkıştırır (tailwind.css `.video-area[data-pause-ad]`). */\n private setShift(px: number): void {\n const area = this.ctx.videoArea;\n if (this.coverTimer) clearTimeout(this.coverTimer);\n this.coverTimer = null;\n area.style.setProperty('--hp-pause-ad-w', `${px}px`);\n if (px > 0) {\n area.setAttribute('data-pause-ad', '');\n } else if (area.hasAttribute('data-pause-ad')) {\n // cover, genişleme animasyonu bitene kadar kalır — hemen contain'e dönmek kapanışta görüntüyü sıçratıyordu.\n this.coverTimer = setTimeout(() => {\n this.coverTimer = null;\n area.removeAttribute('data-pause-ad');\n }, SHIFT_TRANSITION_MS);\n }\n }\n\n private emit(state: 'shown' | 'hidden' | 'empty', size?: [number, number], reason?: 'closed' | 'resumed'): void {\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:pausead', { detail: { state, size, reason } }));\n }\n}\n","import { PauseAd, type PauseAdPlayerContext } from './PauseAd';\nimport type { PauseAdOptions } from '../../types';\n\nexport function installPauseAd(ctx: PauseAdPlayerContext, options: PauseAdOptions): PauseAd {\n return new PauseAd(ctx, options);\n}\n\nexport { PauseAd };\nexport type { PauseAdPlayerContext };\n"],"names":["DEFAULT_SIZES","PANEL_PADDING_X","PANEL_CHROME_Y","SLOT_NAME","SHIFT_TRANSITION_MS","instanceCount","PauseAd","ctx","options","__publicField","wasWaiting","width","header","body","slotEl","e","_c","_a","_b","_d","area","maxW","maxH","w","h","v","sizes","panelW","refreshMs","sizesKey","loadGpt","err","gt","k","val","size","reason","px","state","installPauseAd"],"mappings":"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"}
|