@hopeplayer/core 1.0.16 → 1.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +24 -14
  2. package/dist/HopePlayerElement.d.ts +3 -0
  3. package/dist/HopePlayerElement.d.ts.map +1 -1
  4. package/dist/chunks/{index-CWLyz1fp.js → adTriggers-DXmtF4t2.js} +113 -118
  5. package/dist/chunks/adTriggers-DXmtF4t2.js.map +1 -0
  6. package/dist/chunks/{index-DITXYcHx.js → ads-MCG5a6eK.js} +130 -125
  7. package/dist/chunks/ads-MCG5a6eK.js.map +1 -0
  8. package/dist/chunks/{index-BeJNpAyx.js → audio-LkYgd5Wq.js} +7 -7
  9. package/dist/chunks/audio-LkYgd5Wq.js.map +1 -0
  10. package/dist/chunks/{ScratchSound-0XKHUcJK.js → audioScratchSound-7XkwCCDm.js} +1 -1
  11. package/dist/chunks/audioScratchSound-7XkwCCDm.js.map +1 -0
  12. package/dist/chunks/{index-Miba3PD_.js → cast-bMrkGGuD.js} +70 -66
  13. package/dist/chunks/cast-bMrkGGuD.js.map +1 -0
  14. package/dist/chunks/{index-rENB3n9O.js → countdownScreen-CI-u6jjA.js} +1 -1
  15. package/dist/chunks/countdownScreen-CI-u6jjA.js.map +1 -0
  16. package/dist/chunks/{index-Q8FMOHj0.js → dai-B9Tth1Iv.js} +1 -1
  17. package/dist/chunks/dai-B9Tth1Iv.js.map +1 -0
  18. package/dist/chunks/{index-DCXX1ZJG.js → debugPanel-Bnc_7GOn.js} +1 -1
  19. package/dist/chunks/debugPanel-Bnc_7GOn.js.map +1 -0
  20. package/dist/chunks/{index-DXWK4EFa.js → dubbing-kNMPpyHl.js} +1 -1
  21. package/dist/chunks/dubbing-kNMPpyHl.js.map +1 -0
  22. package/dist/chunks/{index-BBmuCtKu.js → geoChecker-BRtvHwI-.js} +1 -1
  23. package/dist/chunks/geoChecker-BRtvHwI-.js.map +1 -0
  24. package/dist/chunks/{index-Ca8hocby.js → gesture-BzPCgi87.js} +1 -1
  25. package/dist/chunks/gesture-BzPCgi87.js.map +1 -0
  26. package/dist/chunks/{loadGpt-CmiAy366.js → gpt-CGXHTG_H.js} +1 -1
  27. package/dist/chunks/gpt-CGXHTG_H.js.map +1 -0
  28. package/dist/chunks/{index-3QALpwsf.js → inViewAutoplay-CRJe7GA4.js} +1 -1
  29. package/dist/chunks/inViewAutoplay-CRJe7GA4.js.map +1 -0
  30. package/dist/chunks/{index-7IBf8Y-R.js → liveWallClock-ChUTtzLD.js} +1 -1
  31. package/dist/chunks/liveWallClock-ChUTtzLD.js.map +1 -0
  32. package/dist/chunks/{index-f0vSgRIK.js → loopSection-CvF4l5uf.js} +1 -1
  33. package/dist/chunks/loopSection-CvF4l5uf.js.map +1 -0
  34. package/dist/chunks/{index-e00_M05B.js → markers-BhMJLPqj.js} +2 -2
  35. package/dist/chunks/markers-BhMJLPqj.js.map +1 -0
  36. package/dist/chunks/{index-CDPrkLq0.js → pauseAd-BQQe21X4.js} +2 -2
  37. package/dist/chunks/pauseAd-BQQe21X4.js.map +1 -0
  38. package/dist/chunks/{index-DEv3YqLg.js → player-DW5iWvPs.js} +939 -880
  39. package/dist/chunks/player-DW5iWvPs.js.map +1 -0
  40. package/dist/chunks/{index-D3Z7ZDLJ.js → playlist-DYGbJ5wz.js} +24 -24
  41. package/dist/chunks/playlist-DYGbJ5wz.js.map +1 -0
  42. package/dist/chunks/{VideoPrebid-CpckFzSq.js → prebid-CRY3i2OT.js} +1 -1
  43. package/dist/chunks/prebid-CRY3i2OT.js.map +1 -0
  44. package/dist/chunks/{index-DT8-oMPm.js → qrResume-DXwD3oSA.js} +29 -30
  45. package/dist/chunks/qrResume-DXwD3oSA.js.map +1 -0
  46. package/dist/chunks/redirectScreen-CSjrS8Kg.js +208 -0
  47. package/dist/chunks/redirectScreen-CSjrS8Kg.js.map +1 -0
  48. package/dist/chunks/{index-BbRYOSvk.js → rewardedUnlock-DZ_qPcDG.js} +22 -19
  49. package/dist/chunks/rewardedUnlock-DZ_qPcDG.js.map +1 -0
  50. package/dist/chunks/seekWhenReady-Clzne3-S.js +32 -0
  51. package/dist/chunks/seekWhenReady-Clzne3-S.js.map +1 -0
  52. package/dist/chunks/{index-CBX7bn-G.js → segments-LsZPlbYi.js} +2 -2
  53. package/dist/chunks/segments-LsZPlbYi.js.map +1 -0
  54. package/dist/chunks/{index-Ch3ep-eJ.js → sponsorship-BT21uwN5.js} +36 -41
  55. package/dist/chunks/sponsorship-BT21uwN5.js.map +1 -0
  56. package/dist/chunks/{index-BXSND_xN.js → spriteThumbnails-BQkEBRu-.js} +2 -2
  57. package/dist/chunks/spriteThumbnails-BQkEBRu-.js.map +1 -0
  58. package/dist/chunks/{index-DGtpFgHV.js → statsPanel-DSClIwA3.js} +1 -1
  59. package/dist/chunks/statsPanel-DSClIwA3.js.map +1 -0
  60. package/dist/chunks/{index-CDDke5rz.js → sticky-D_eLCNFk.js} +1 -1
  61. package/dist/chunks/sticky-D_eLCNFk.js.map +1 -0
  62. package/dist/chunks/{index-C3BQGcT3.js → story-H6f7gSoX.js} +27 -15
  63. package/dist/chunks/story-H6f7gSoX.js.map +1 -0
  64. package/dist/chunks/{index-C5oGMHF_.js → tapGestures-DrC42DiI.js} +1 -1
  65. package/dist/chunks/tapGestures-DrC42DiI.js.map +1 -0
  66. package/dist/chunks/trackingPixel-D2wxdCEz.js +20 -0
  67. package/dist/chunks/trackingPixel-D2wxdCEz.js.map +1 -0
  68. package/dist/controls/SeekBar.d.ts.map +1 -1
  69. package/dist/hls/SourceManager.d.ts.map +1 -1
  70. package/dist/hope-player.js +1 -1
  71. package/dist/i18n/locales/en.d.ts.map +1 -1
  72. package/dist/i18n/locales/tr.d.ts.map +1 -1
  73. package/dist/i18n/types.d.ts +3 -0
  74. package/dist/i18n/types.d.ts.map +1 -1
  75. package/dist/index.d.ts +1 -1
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/keyboard/KeyboardController.d.ts.map +1 -1
  78. package/dist/plugins/ad-triggers/AdTriggers.d.ts.map +1 -1
  79. package/dist/plugins/ads/AdsController.d.ts.map +1 -1
  80. package/dist/plugins/ads/generateVastUrl.d.ts +10 -0
  81. package/dist/plugins/ads/generateVastUrl.d.ts.map +1 -1
  82. package/dist/plugins/cast/CastController.d.ts.map +1 -1
  83. package/dist/plugins/playlist/PlaylistRunner.d.ts.map +1 -1
  84. package/dist/plugins/qr-resume/QrResume.d.ts.map +1 -1
  85. package/dist/plugins/redirect-screen/RedirectScreen.d.ts +26 -3
  86. package/dist/plugins/redirect-screen/RedirectScreen.d.ts.map +1 -1
  87. package/dist/plugins/rewarded/RewardedUnlock.d.ts +0 -5
  88. package/dist/plugins/rewarded/RewardedUnlock.d.ts.map +1 -1
  89. package/dist/plugins/shared/seekWhenReady.d.ts +22 -0
  90. package/dist/plugins/shared/seekWhenReady.d.ts.map +1 -0
  91. package/dist/plugins/shared/trackingPixel.d.ts +8 -0
  92. package/dist/plugins/shared/trackingPixel.d.ts.map +1 -0
  93. package/dist/plugins/sponsorship/SponsorshipLayer.d.ts.map +1 -1
  94. package/dist/plugins/story/HopeStory.d.ts +2 -0
  95. package/dist/plugins/story/HopeStory.d.ts.map +1 -1
  96. package/dist/screens/ErrorScreen.d.ts +7 -0
  97. package/dist/screens/ErrorScreen.d.ts.map +1 -1
  98. package/dist/types/index.d.ts +49 -1
  99. package/dist/types/index.d.ts.map +1 -1
  100. package/dist/utils/media-error.d.ts +10 -0
  101. package/dist/utils/media-error.d.ts.map +1 -0
  102. package/dist/utils/seek-by.d.ts +8 -0
  103. package/dist/utils/seek-by.d.ts.map +1 -1
  104. package/package.json +4 -1
  105. package/dist/chunks/ScratchSound-0XKHUcJK.js.map +0 -1
  106. package/dist/chunks/VideoPrebid-CpckFzSq.js.map +0 -1
  107. package/dist/chunks/index-3QALpwsf.js.map +0 -1
  108. package/dist/chunks/index-7IBf8Y-R.js.map +0 -1
  109. package/dist/chunks/index-BBmuCtKu.js.map +0 -1
  110. package/dist/chunks/index-BXSND_xN.js.map +0 -1
  111. package/dist/chunks/index-BbRYOSvk.js.map +0 -1
  112. package/dist/chunks/index-BeJNpAyx.js.map +0 -1
  113. package/dist/chunks/index-C3BQGcT3.js.map +0 -1
  114. package/dist/chunks/index-C5oGMHF_.js.map +0 -1
  115. package/dist/chunks/index-CBX7bn-G.js.map +0 -1
  116. package/dist/chunks/index-CDDke5rz.js.map +0 -1
  117. package/dist/chunks/index-CDPrkLq0.js.map +0 -1
  118. package/dist/chunks/index-CWLyz1fp.js.map +0 -1
  119. package/dist/chunks/index-Ca8hocby.js.map +0 -1
  120. package/dist/chunks/index-Ch3ep-eJ.js.map +0 -1
  121. package/dist/chunks/index-D3Z7ZDLJ.js.map +0 -1
  122. package/dist/chunks/index-D6r-BGAV.js +0 -77
  123. package/dist/chunks/index-D6r-BGAV.js.map +0 -1
  124. package/dist/chunks/index-DCXX1ZJG.js.map +0 -1
  125. package/dist/chunks/index-DEv3YqLg.js.map +0 -1
  126. package/dist/chunks/index-DGtpFgHV.js.map +0 -1
  127. package/dist/chunks/index-DITXYcHx.js.map +0 -1
  128. package/dist/chunks/index-DT8-oMPm.js.map +0 -1
  129. package/dist/chunks/index-DXWK4EFa.js.map +0 -1
  130. package/dist/chunks/index-Miba3PD_.js.map +0 -1
  131. package/dist/chunks/index-Q8FMOHj0.js.map +0 -1
  132. package/dist/chunks/index-e00_M05B.js.map +0 -1
  133. package/dist/chunks/index-f0vSgRIK.js.map +0 -1
  134. package/dist/chunks/index-rENB3n9O.js.map +0 -1
  135. package/dist/chunks/loadGpt-CmiAy366.js.map +0 -1
@@ -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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"}
@@ -15,4 +15,4 @@ function d() {
15
15
  export {
16
16
  d as l
17
17
  };
18
- //# sourceMappingURL=loadGpt-CmiAy366.js.map
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;"}
@@ -36,4 +36,4 @@ export {
36
36
  o as InViewAutoplay,
37
37
  d as installInViewAutoplay
38
38
  };
39
- //# sourceMappingURL=index-3QALpwsf.js.map
39
+ //# sourceMappingURL=inViewAutoplay-CRJe7GA4.js.map
@@ -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;"}
@@ -142,4 +142,4 @@ export {
142
142
  u as LiveWallClock,
143
143
  k as installLiveWallClock
144
144
  };
145
- //# sourceMappingURL=index-7IBf8Y-R.js.map
145
+ //# sourceMappingURL=liveWallClock-ChUTtzLD.js.map
@@ -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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"}
@@ -72,4 +72,4 @@ export {
72
72
  E as LoopSection,
73
73
  S as installLoopSection
74
74
  };
75
- //# sourceMappingURL=index-f0vSgRIK.js.map
75
+ //# sourceMappingURL=loopSection-CvF4l5uf.js.map
@@ -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 "./index-DEv3YqLg.js";
4
+ import { c as b } from "./player-DW5iWvPs.js";
5
5
  const f = {
6
6
  enabled: !1,
7
7
  mode: "rich",
@@ -202,4 +202,4 @@ export {
202
202
  v as MarkProgress,
203
203
  y as installMarkers
204
204
  };
205
- //# sourceMappingURL=index-e00_M05B.js.map
205
+ //# sourceMappingURL=markers-BhMJLPqj.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markers-BhMJLPqj.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,7 +1,7 @@
1
1
  var u = Object.defineProperty;
2
2
  var c = (o, e, t) => e in o ? u(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
3
  var s = (o, e, t) => c(o, typeof e != "symbol" ? e + "" : e, t);
4
- import { l as m } from "./loadGpt-CmiAy366.js";
4
+ import { l as m } from "./gpt-CGXHTG_H.js";
5
5
  const v = [
6
6
  [300, 250],
7
7
  [336, 280],
@@ -128,4 +128,4 @@ export {
128
128
  g as PauseAd,
129
129
  T as installPauseAd
130
130
  };
131
- //# sourceMappingURL=index-CDPrkLq0.js.map
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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"}