@hopeplayer/core 1.5.0 → 1.6.0

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 (105) hide show
  1. package/dist/HopePlayerElement.d.ts +24 -0
  2. package/dist/HopePlayerElement.d.ts.map +1 -1
  3. package/dist/chunks/adTriggers-BIAWe8o4.js +419 -0
  4. package/dist/chunks/adTriggers-BIAWe8o4.js.map +1 -0
  5. package/dist/chunks/{ads-C4tDPsUs.js → ads-DlpHPpR9.js} +2 -2
  6. package/dist/chunks/{ads-C4tDPsUs.js.map → ads-DlpHPpR9.js.map} +1 -1
  7. package/dist/chunks/{cast-Baxvu76A.js → cast-vHyi7oV_.js} +2 -2
  8. package/dist/chunks/{cast-Baxvu76A.js.map → cast-vHyi7oV_.js.map} +1 -1
  9. package/dist/chunks/docPip-wybMVP1H.js +82 -0
  10. package/dist/chunks/docPip-wybMVP1H.js.map +1 -0
  11. package/dist/chunks/heatmap-Bb7neaYU.js +92 -0
  12. package/dist/chunks/heatmap-Bb7neaYU.js.map +1 -0
  13. package/dist/chunks/{history-CvydU0aN.js → history-CwqLXiZi.js} +2 -2
  14. package/dist/chunks/{history-CvydU0aN.js.map → history-CwqLXiZi.js.map} +1 -1
  15. package/dist/chunks/interactive-CgltIneu.js +189 -0
  16. package/dist/chunks/interactive-CgltIneu.js.map +1 -0
  17. package/dist/chunks/{loopSection-CvF4l5uf.js → loopSection-Bwk4W8vz.js} +16 -16
  18. package/dist/chunks/loopSection-Bwk4W8vz.js.map +1 -0
  19. package/dist/chunks/{markers-Dr4-CCxE.js → markers-L69W3kj6.js} +53 -51
  20. package/dist/chunks/markers-L69W3kj6.js.map +1 -0
  21. package/dist/chunks/{player-DV4Hf5Cw.js → player-D2_HRzot.js} +1382 -1158
  22. package/dist/chunks/player-D2_HRzot.js.map +1 -0
  23. package/dist/chunks/{playlist-DJsdK6xm.js → playlist-CHfStNbQ.js} +2 -2
  24. package/dist/chunks/{playlist-DJsdK6xm.js.map → playlist-CHfStNbQ.js.map} +1 -1
  25. package/dist/chunks/plugin-style-CPJELe-i.js +17 -0
  26. package/dist/chunks/plugin-style-CPJELe-i.js.map +1 -0
  27. package/dist/chunks/{pluginHost-GxNfyP5E.js → pluginHost-cN2uGFeG.js} +2 -2
  28. package/dist/chunks/{pluginHost-GxNfyP5E.js.map → pluginHost-cN2uGFeG.js.map} +1 -1
  29. package/dist/chunks/redirectScreen-TIqLdvBY.js +239 -0
  30. package/dist/chunks/redirectScreen-TIqLdvBY.js.map +1 -0
  31. package/dist/chunks/{rewardedUnlock-jFOdzfSq.js → rewardedUnlock-DUqYwXTr.js} +2 -2
  32. package/dist/chunks/{rewardedUnlock-jFOdzfSq.js.map → rewardedUnlock-DUqYwXTr.js.map} +1 -1
  33. package/dist/chunks/segments-Ds-c1b5e.js +66 -0
  34. package/dist/chunks/segments-Ds-c1b5e.js.map +1 -0
  35. package/dist/chunks/{skipSegments-vJMhdiJn.js → skipSegments-ByNoF1qZ.js} +2 -2
  36. package/dist/chunks/{skipSegments-vJMhdiJn.js.map → skipSegments-ByNoF1qZ.js.map} +1 -1
  37. package/dist/chunks/{spriteThumbnails-BoxVY--_.js → spriteThumbnails-Cr9UmkM9.js} +28 -28
  38. package/dist/chunks/spriteThumbnails-Cr9UmkM9.js.map +1 -0
  39. package/dist/chunks/{sticky-D_eLCNFk.js → sticky-BDStzjBM.js} +27 -26
  40. package/dist/chunks/sticky-BDStzjBM.js.map +1 -0
  41. package/dist/chunks/{story-BRkhSDhR.js → story-CodA2dfn.js} +2 -2
  42. package/dist/chunks/{story-BRkhSDhR.js.map → story-CodA2dfn.js.map} +1 -1
  43. package/dist/chunks/transcript-LG7E9UYE.js +186 -0
  44. package/dist/chunks/transcript-LG7E9UYE.js.map +1 -0
  45. package/dist/controls/ContextMenu.d.ts +1 -0
  46. package/dist/controls/ContextMenu.d.ts.map +1 -1
  47. package/dist/controls/ControlBar.d.ts +6 -0
  48. package/dist/controls/ControlBar.d.ts.map +1 -1
  49. package/dist/controls/SeekBar.d.ts +5 -2
  50. package/dist/controls/SeekBar.d.ts.map +1 -1
  51. package/dist/controls/SettingsMenu.d.ts +2 -1
  52. package/dist/controls/SettingsMenu.d.ts.map +1 -1
  53. package/dist/hope-player.js +1 -1
  54. package/dist/i18n/locales/en.d.ts.map +1 -1
  55. package/dist/i18n/locales/tr.d.ts.map +1 -1
  56. package/dist/i18n/types.d.ts +25 -0
  57. package/dist/i18n/types.d.ts.map +1 -1
  58. package/dist/index.d.ts +1 -1
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/plugins/ad-triggers/AdTriggers.d.ts +5 -0
  61. package/dist/plugins/ad-triggers/AdTriggers.d.ts.map +1 -1
  62. package/dist/plugins/doc-pip/DocumentPip.d.ts +44 -0
  63. package/dist/plugins/doc-pip/DocumentPip.d.ts.map +1 -0
  64. package/dist/plugins/doc-pip/index.d.ts +5 -0
  65. package/dist/plugins/doc-pip/index.d.ts.map +1 -0
  66. package/dist/plugins/heatmap/Heatmap.d.ts +36 -0
  67. package/dist/plugins/heatmap/Heatmap.d.ts.map +1 -0
  68. package/dist/plugins/heatmap/index.d.ts +6 -0
  69. package/dist/plugins/heatmap/index.d.ts.map +1 -0
  70. package/dist/plugins/interactive/Interactive.d.ts +45 -0
  71. package/dist/plugins/interactive/Interactive.d.ts.map +1 -0
  72. package/dist/plugins/interactive/index.d.ts +6 -0
  73. package/dist/plugins/interactive/index.d.ts.map +1 -0
  74. package/dist/plugins/markers/MarkProgress.d.ts +3 -1
  75. package/dist/plugins/markers/MarkProgress.d.ts.map +1 -1
  76. package/dist/plugins/redirect-screen/RedirectScreen.d.ts +3 -1
  77. package/dist/plugins/redirect-screen/RedirectScreen.d.ts.map +1 -1
  78. package/dist/plugins/segments/Segments.d.ts +1 -0
  79. package/dist/plugins/segments/Segments.d.ts.map +1 -1
  80. package/dist/plugins/sprite-thumbnails/SpriteThumbnails.d.ts +1 -0
  81. package/dist/plugins/sprite-thumbnails/SpriteThumbnails.d.ts.map +1 -1
  82. package/dist/plugins/sticky/StickyManager.d.ts +2 -0
  83. package/dist/plugins/sticky/StickyManager.d.ts.map +1 -1
  84. package/dist/plugins/transcript/Transcript.d.ts +65 -0
  85. package/dist/plugins/transcript/Transcript.d.ts.map +1 -0
  86. package/dist/plugins/transcript/index.d.ts +6 -0
  87. package/dist/plugins/transcript/index.d.ts.map +1 -0
  88. package/dist/subtitles/attachTracks.d.ts +6 -0
  89. package/dist/subtitles/attachTracks.d.ts.map +1 -1
  90. package/dist/types/index.d.ts +164 -12
  91. package/dist/types/index.d.ts.map +1 -1
  92. package/dist/utils/plugin-style.d.ts +5 -0
  93. package/dist/utils/plugin-style.d.ts.map +1 -0
  94. package/package.json +1 -1
  95. package/dist/chunks/adTriggers-DXmtF4t2.js +0 -410
  96. package/dist/chunks/adTriggers-DXmtF4t2.js.map +0 -1
  97. package/dist/chunks/loopSection-CvF4l5uf.js.map +0 -1
  98. package/dist/chunks/markers-Dr4-CCxE.js.map +0 -1
  99. package/dist/chunks/player-DV4Hf5Cw.js.map +0 -1
  100. package/dist/chunks/redirectScreen-BT_26-5g.js +0 -208
  101. package/dist/chunks/redirectScreen-BT_26-5g.js.map +0 -1
  102. package/dist/chunks/segments--hl_QVrI.js +0 -63
  103. package/dist/chunks/segments--hl_QVrI.js.map +0 -1
  104. package/dist/chunks/spriteThumbnails-BoxVY--_.js.map +0 -1
  105. package/dist/chunks/sticky-D_eLCNFk.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  var c = Object.defineProperty;
2
2
  var p = (i, e, t) => e in i ? c(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
3
3
  var h = (i, e, t) => p(i, typeof e != "symbol" ? e + "" : e, t);
4
- import { c as m, v, d as b } from "./player-DV4Hf5Cw.js";
4
+ import { c as m, v, d as b } from "./player-D2_HRzot.js";
5
5
  const k = 0.25;
6
6
  class g {
7
7
  constructor(e, t) {
@@ -132,4 +132,4 @@ export {
132
132
  g as SkipSegments,
133
133
  S as skipSegmentsPlugin
134
134
  };
135
- //# sourceMappingURL=skipSegments-vJMhdiJn.js.map
135
+ //# sourceMappingURL=skipSegments-ByNoF1qZ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skipSegments-vJMhdiJn.js","sources":["../../src/plugins/skip-segments/SkipSegments.ts","../../src/plugins/skip-segments/index.ts"],"sourcesContent":["import type { SkipSegment, SkipSegmentType } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { createIcon } from '../../icons/Icon';\nimport { vodSeekTarget } from '../../utils/seek-by';\n\nexport interface SkipSegmentsPlayerContext {\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n overlayContainerEl: HTMLElement;\n isAdActive(): boolean;\n i18n: HopeLocaleStrings;\n}\n\n/** Bölüm sonuna bu kadar kala buton kalkar — sona yaklaşırken bir an görünüp kaybolmasın. */\nconst END_MARGIN_SEC = 0.25;\n\ninterface Active {\n index: number;\n segment: SkipSegment;\n end: number;\n /** Butonun göründüğü video zamanı — `hideAfter` / `autoSkip` geri sayımı video zamanıyla işler (duraklatınca durur). */\n shownAt: number;\n /** Kullanıcı bölüme sararak girdi ya da bölüm içinde geri sardı → bu gösterimde otomatik atlama yok. */\n autoCancelled: boolean;\n}\n\n/**\n * \"İntroyu atla\" / \"Özeti atla\" / \"Jeneriği atla\": bölüm oynarken köşede bir buton, basınca bölümün sonuna atlar.\n * `autoSkip` ile basılmadan (isteğe bağlı geri sayımla) atlar; `hideAfter` ile bir süre sonra çekilir, kontroller\n * açılınca geri gelir. Reklam sırasında görünmez. `hp:skip` (`skip`) iptal edilebilir.\n */\nexport class SkipSegments {\n private active: Active | null = null;\n private button: HTMLButtonElement | null = null;\n private labelEl: HTMLSpanElement | null = null;\n /** Kullanıcının (bizim değil) yaptığı sarma — bir sonraki timeupdate'te işlenir. */\n private userSeeked = false;\n private ownSeek = false;\n\n constructor(\n private readonly ctx: SkipSegmentsPlayerContext,\n private readonly segments: SkipSegment[]\n ) {\n const v = ctx.videoEl;\n v.addEventListener('timeupdate', this.update);\n v.addEventListener('seeking', this.onSeeking);\n v.addEventListener('seeked', this.update);\n v.addEventListener('loadstart', this.onSourceChange);\n ctx.hostEl.addEventListener('hp:adstart', this.update);\n ctx.hostEl.addEventListener('hp:adend', this.update);\n this.update();\n }\n\n destroy(): void {\n const v = this.ctx.videoEl;\n v.removeEventListener('timeupdate', this.update);\n v.removeEventListener('seeking', this.onSeeking);\n v.removeEventListener('seeked', this.update);\n v.removeEventListener('loadstart', this.onSourceChange);\n this.ctx.hostEl.removeEventListener('hp:adstart', this.update);\n this.ctx.hostEl.removeEventListener('hp:adend', this.update);\n this.hide();\n }\n\n refreshLabels(): void {\n if (this.active && this.labelEl) this.labelEl.textContent = this.label(this.active.segment);\n }\n\n private label(s: SkipSegment): string {\n if (s.label) return s.label;\n const t = this.ctx.i18n;\n const byType: Record<SkipSegmentType, string> = { intro: t.skipIntro, recap: t.skipRecap, credits: t.skipCredits, custom: t.skipSegment };\n return byType[s.type ?? 'intro'] ?? t.skipSegment;\n }\n\n /** Bölümün sonu: `end` yoksa videonun sonu (süre bilinmiyorsa bölüm yok sayılır). */\n private endOf(s: SkipSegment): number | null {\n if (Number.isFinite(s.end)) return s.end!;\n const d = this.ctx.videoEl.duration;\n return Number.isFinite(d) && d > 0 ? d : null;\n }\n\n private readonly onSeeking = (): void => {\n if (this.ownSeek) this.ownSeek = false;\n else this.userSeeked = true;\n };\n\n private readonly onSourceChange = (): void => {\n this.hide();\n this.userSeeked = false;\n };\n\n private readonly update = (): void => {\n const v = this.ctx.videoEl;\n const t = v.currentTime;\n const seeked = this.userSeeked;\n this.userSeeked = false;\n\n let found: { index: number; segment: SkipSegment; end: number } | null = null;\n if (!this.ctx.isAdActive()) {\n for (let i = 0; i < this.segments.length; i++) {\n const s = this.segments[i]!;\n const end = this.endOf(s);\n if (end === null || !Number.isFinite(s.start)) continue;\n const from = Math.max(s.start, Number.isFinite(s.showFrom) ? s.showFrom! : s.start);\n const until = Number.isFinite(s.showUntil) ? Math.min(s.showUntil!, end) : end;\n if (t >= from && t < until - END_MARGIN_SEC) {\n found = { index: i, segment: s, end };\n break;\n }\n }\n }\n\n if (!found) {\n this.hide();\n return;\n }\n if (this.active?.index !== found.index) {\n this.hide();\n this.active = { ...found, shownAt: t, autoCancelled: seeked };\n this.show();\n this.emit('shown');\n } else if (seeked) {\n // Bölüm içinde sarma: geri sardıysa (kullanıcı bölümü izlemek istiyor) otomatik atlama bu gösterimde kapanır.\n this.active.autoCancelled = true;\n this.active.shownAt = Math.min(this.active.shownAt, t);\n }\n this.tick(t);\n };\n\n /** `hideAfter` (çekilme) ve `autoSkip` geri sayımı. */\n private tick(t: number): void {\n const a = this.active;\n if (!a || !this.button) return;\n const elapsed = Math.max(0, t - a.shownAt);\n const hideAfter = a.segment.hideAfter ?? 0;\n this.button.toggleAttribute('data-faded', hideAfter > 0 && elapsed >= hideAfter);\n\n const auto = a.segment.autoSkip;\n if (!auto || a.autoCancelled) {\n this.button.removeAttribute('data-auto');\n return;\n }\n const delay = auto === true ? 0 : Math.max(0, auto);\n if (elapsed >= delay) {\n this.skip('auto');\n return;\n }\n this.button.setAttribute('data-auto', '');\n this.button.style.setProperty('--hp-skip-progress', String(delay ? elapsed / delay : 1));\n }\n\n private show(): void {\n const a = this.active!;\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'hp-skip-segment';\n btn.setAttribute('part', 'skip-segment');\n btn.setAttribute('data-position', a.segment.position ?? 'bottom-right');\n btn.setAttribute('data-type', a.segment.type ?? 'intro');\n const label = document.createElement('span');\n label.className = 'hp-skip-segment-label';\n label.textContent = this.label(a.segment);\n btn.append(label, createIcon('skip-forward', 'hp-skip-segment-icon'));\n btn.addEventListener('click', () => this.skip('click'));\n // Oynat/duraklat ve çift tık tam ekran alttaki video alanına geçmesin.\n for (const ev of ['pointerdown', 'pointerup', 'click', 'dblclick'] as const) btn.addEventListener(ev, (e) => e.stopPropagation());\n this.ctx.overlayContainerEl.appendChild(btn);\n this.button = btn;\n this.labelEl = label;\n }\n\n private hide(): void {\n this.button?.remove();\n this.button = null;\n this.labelEl = null;\n this.active = null;\n }\n\n private emit(state: 'shown' | 'skip', reason?: 'click' | 'auto'): boolean {\n const a = this.active!;\n return this.ctx.hostEl.dispatchEvent(\n new CustomEvent('hp:skip', {\n detail: { state, type: a.segment.type ?? 'intro', start: a.segment.start, end: a.end, reason },\n cancelable: state === 'skip',\n })\n );\n }\n\n private skip(reason: 'click' | 'auto'): void {\n const a = this.active;\n if (!a) return;\n const focused = !!this.button?.matches(':focus');\n if (!this.emit('skip', reason)) {\n // Entegratör kendisi halletti — bu gösterim için otomatik atlama tekrar tetiklenmesin.\n a.autoCancelled = true;\n this.button?.removeAttribute('data-auto');\n return;\n }\n const v = this.ctx.videoEl;\n this.hide();\n this.ownSeek = true;\n v.currentTime = vodSeekTarget(v, a.end);\n // Klavyeyle basıldıysa odak kaybolmasın — player'a dön (kısayollar çalışmaya devam etsin).\n if (focused) this.ctx.hostEl.focus({ preventScroll: true });\n }\n}\n","import { SkipSegments, type SkipSegmentsPlayerContext } from './SkipSegments';\nimport type { SkipSegment } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { definePlugin } from '../../plugin-api/registry';\n\nexport function installSkipSegments(ctx: SkipSegmentsPlayerContext, segments: SkipSegment[]): SkipSegments {\n return new SkipSegments(ctx, segments);\n}\n\n/** \"İntroyu atla\", herkese açık eklenti API'si üzerinden. */\nexport const skipSegmentsPlugin = definePlugin<SkipSegment[]>({\n name: 'hope:skip-segments',\n setup(player, segments) {\n const layer = player.ui.addLayer({ position: 'fill' });\n const skip = new SkipSegments(\n {\n hostEl: player.element,\n videoEl: player.video,\n overlayContainerEl: layer.el,\n isAdActive: () => player.isAdPlaying,\n i18n: player.labels as unknown as HopeLocaleStrings,\n },\n segments\n );\n player.onLocaleChange(() => skip.refreshLabels());\n return () => skip.destroy();\n },\n});\n\nexport { SkipSegments };\nexport type { SkipSegmentsPlayerContext };\n"],"names":["END_MARGIN_SEC","SkipSegments","ctx","segments","__publicField","seeked","found","i","s","end","from","until","_a","v","d","t","a","elapsed","hideAfter","auto","delay","btn","label","createIcon","ev","e","state","reason","focused","_b","vodSeekTarget","skipSegmentsPlugin","definePlugin","player","layer","skip"],"mappings":"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"}
1
+ {"version":3,"file":"skipSegments-ByNoF1qZ.js","sources":["../../src/plugins/skip-segments/SkipSegments.ts","../../src/plugins/skip-segments/index.ts"],"sourcesContent":["import type { SkipSegment, SkipSegmentType } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { createIcon } from '../../icons/Icon';\nimport { vodSeekTarget } from '../../utils/seek-by';\n\nexport interface SkipSegmentsPlayerContext {\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n overlayContainerEl: HTMLElement;\n isAdActive(): boolean;\n i18n: HopeLocaleStrings;\n}\n\n/** Bölüm sonuna bu kadar kala buton kalkar — sona yaklaşırken bir an görünüp kaybolmasın. */\nconst END_MARGIN_SEC = 0.25;\n\ninterface Active {\n index: number;\n segment: SkipSegment;\n end: number;\n /** Butonun göründüğü video zamanı — `hideAfter` / `autoSkip` geri sayımı video zamanıyla işler (duraklatınca durur). */\n shownAt: number;\n /** Kullanıcı bölüme sararak girdi ya da bölüm içinde geri sardı → bu gösterimde otomatik atlama yok. */\n autoCancelled: boolean;\n}\n\n/**\n * \"İntroyu atla\" / \"Özeti atla\" / \"Jeneriği atla\": bölüm oynarken köşede bir buton, basınca bölümün sonuna atlar.\n * `autoSkip` ile basılmadan (isteğe bağlı geri sayımla) atlar; `hideAfter` ile bir süre sonra çekilir, kontroller\n * açılınca geri gelir. Reklam sırasında görünmez. `hp:skip` (`skip`) iptal edilebilir.\n */\nexport class SkipSegments {\n private active: Active | null = null;\n private button: HTMLButtonElement | null = null;\n private labelEl: HTMLSpanElement | null = null;\n /** Kullanıcının (bizim değil) yaptığı sarma — bir sonraki timeupdate'te işlenir. */\n private userSeeked = false;\n private ownSeek = false;\n\n constructor(\n private readonly ctx: SkipSegmentsPlayerContext,\n private readonly segments: SkipSegment[]\n ) {\n const v = ctx.videoEl;\n v.addEventListener('timeupdate', this.update);\n v.addEventListener('seeking', this.onSeeking);\n v.addEventListener('seeked', this.update);\n v.addEventListener('loadstart', this.onSourceChange);\n ctx.hostEl.addEventListener('hp:adstart', this.update);\n ctx.hostEl.addEventListener('hp:adend', this.update);\n this.update();\n }\n\n destroy(): void {\n const v = this.ctx.videoEl;\n v.removeEventListener('timeupdate', this.update);\n v.removeEventListener('seeking', this.onSeeking);\n v.removeEventListener('seeked', this.update);\n v.removeEventListener('loadstart', this.onSourceChange);\n this.ctx.hostEl.removeEventListener('hp:adstart', this.update);\n this.ctx.hostEl.removeEventListener('hp:adend', this.update);\n this.hide();\n }\n\n refreshLabels(): void {\n if (this.active && this.labelEl) this.labelEl.textContent = this.label(this.active.segment);\n }\n\n private label(s: SkipSegment): string {\n if (s.label) return s.label;\n const t = this.ctx.i18n;\n const byType: Record<SkipSegmentType, string> = { intro: t.skipIntro, recap: t.skipRecap, credits: t.skipCredits, custom: t.skipSegment };\n return byType[s.type ?? 'intro'] ?? t.skipSegment;\n }\n\n /** Bölümün sonu: `end` yoksa videonun sonu (süre bilinmiyorsa bölüm yok sayılır). */\n private endOf(s: SkipSegment): number | null {\n if (Number.isFinite(s.end)) return s.end!;\n const d = this.ctx.videoEl.duration;\n return Number.isFinite(d) && d > 0 ? d : null;\n }\n\n private readonly onSeeking = (): void => {\n if (this.ownSeek) this.ownSeek = false;\n else this.userSeeked = true;\n };\n\n private readonly onSourceChange = (): void => {\n this.hide();\n this.userSeeked = false;\n };\n\n private readonly update = (): void => {\n const v = this.ctx.videoEl;\n const t = v.currentTime;\n const seeked = this.userSeeked;\n this.userSeeked = false;\n\n let found: { index: number; segment: SkipSegment; end: number } | null = null;\n if (!this.ctx.isAdActive()) {\n for (let i = 0; i < this.segments.length; i++) {\n const s = this.segments[i]!;\n const end = this.endOf(s);\n if (end === null || !Number.isFinite(s.start)) continue;\n const from = Math.max(s.start, Number.isFinite(s.showFrom) ? s.showFrom! : s.start);\n const until = Number.isFinite(s.showUntil) ? Math.min(s.showUntil!, end) : end;\n if (t >= from && t < until - END_MARGIN_SEC) {\n found = { index: i, segment: s, end };\n break;\n }\n }\n }\n\n if (!found) {\n this.hide();\n return;\n }\n if (this.active?.index !== found.index) {\n this.hide();\n this.active = { ...found, shownAt: t, autoCancelled: seeked };\n this.show();\n this.emit('shown');\n } else if (seeked) {\n // Bölüm içinde sarma: geri sardıysa (kullanıcı bölümü izlemek istiyor) otomatik atlama bu gösterimde kapanır.\n this.active.autoCancelled = true;\n this.active.shownAt = Math.min(this.active.shownAt, t);\n }\n this.tick(t);\n };\n\n /** `hideAfter` (çekilme) ve `autoSkip` geri sayımı. */\n private tick(t: number): void {\n const a = this.active;\n if (!a || !this.button) return;\n const elapsed = Math.max(0, t - a.shownAt);\n const hideAfter = a.segment.hideAfter ?? 0;\n this.button.toggleAttribute('data-faded', hideAfter > 0 && elapsed >= hideAfter);\n\n const auto = a.segment.autoSkip;\n if (!auto || a.autoCancelled) {\n this.button.removeAttribute('data-auto');\n return;\n }\n const delay = auto === true ? 0 : Math.max(0, auto);\n if (elapsed >= delay) {\n this.skip('auto');\n return;\n }\n this.button.setAttribute('data-auto', '');\n this.button.style.setProperty('--hp-skip-progress', String(delay ? elapsed / delay : 1));\n }\n\n private show(): void {\n const a = this.active!;\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'hp-skip-segment';\n btn.setAttribute('part', 'skip-segment');\n btn.setAttribute('data-position', a.segment.position ?? 'bottom-right');\n btn.setAttribute('data-type', a.segment.type ?? 'intro');\n const label = document.createElement('span');\n label.className = 'hp-skip-segment-label';\n label.textContent = this.label(a.segment);\n btn.append(label, createIcon('skip-forward', 'hp-skip-segment-icon'));\n btn.addEventListener('click', () => this.skip('click'));\n // Oynat/duraklat ve çift tık tam ekran alttaki video alanına geçmesin.\n for (const ev of ['pointerdown', 'pointerup', 'click', 'dblclick'] as const) btn.addEventListener(ev, (e) => e.stopPropagation());\n this.ctx.overlayContainerEl.appendChild(btn);\n this.button = btn;\n this.labelEl = label;\n }\n\n private hide(): void {\n this.button?.remove();\n this.button = null;\n this.labelEl = null;\n this.active = null;\n }\n\n private emit(state: 'shown' | 'skip', reason?: 'click' | 'auto'): boolean {\n const a = this.active!;\n return this.ctx.hostEl.dispatchEvent(\n new CustomEvent('hp:skip', {\n detail: { state, type: a.segment.type ?? 'intro', start: a.segment.start, end: a.end, reason },\n cancelable: state === 'skip',\n })\n );\n }\n\n private skip(reason: 'click' | 'auto'): void {\n const a = this.active;\n if (!a) return;\n const focused = !!this.button?.matches(':focus');\n if (!this.emit('skip', reason)) {\n // Entegratör kendisi halletti — bu gösterim için otomatik atlama tekrar tetiklenmesin.\n a.autoCancelled = true;\n this.button?.removeAttribute('data-auto');\n return;\n }\n const v = this.ctx.videoEl;\n this.hide();\n this.ownSeek = true;\n v.currentTime = vodSeekTarget(v, a.end);\n // Klavyeyle basıldıysa odak kaybolmasın — player'a dön (kısayollar çalışmaya devam etsin).\n if (focused) this.ctx.hostEl.focus({ preventScroll: true });\n }\n}\n","import { SkipSegments, type SkipSegmentsPlayerContext } from './SkipSegments';\nimport type { SkipSegment } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { definePlugin } from '../../plugin-api/registry';\n\nexport function installSkipSegments(ctx: SkipSegmentsPlayerContext, segments: SkipSegment[]): SkipSegments {\n return new SkipSegments(ctx, segments);\n}\n\n/** \"İntroyu atla\", herkese açık eklenti API'si üzerinden. */\nexport const skipSegmentsPlugin = definePlugin<SkipSegment[]>({\n name: 'hope:skip-segments',\n setup(player, segments) {\n const layer = player.ui.addLayer({ position: 'fill' });\n const skip = new SkipSegments(\n {\n hostEl: player.element,\n videoEl: player.video,\n overlayContainerEl: layer.el,\n isAdActive: () => player.isAdPlaying,\n i18n: player.labels as unknown as HopeLocaleStrings,\n },\n segments\n );\n player.onLocaleChange(() => skip.refreshLabels());\n return () => skip.destroy();\n },\n});\n\nexport { SkipSegments };\nexport type { SkipSegmentsPlayerContext };\n"],"names":["END_MARGIN_SEC","SkipSegments","ctx","segments","__publicField","seeked","found","i","s","end","from","until","_a","v","d","t","a","elapsed","hideAfter","auto","delay","btn","label","createIcon","ev","e","state","reason","focused","_b","vodSeekTarget","skipSegmentsPlugin","definePlugin","player","layer","skip"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- var w = Object.defineProperty;
2
- var E = (u, t, e) => t in u ? w(u, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : u[t] = e;
3
- var l = (u, t, e) => E(u, typeof t != "symbol" ? t + "" : t, e);
4
- import { f as y } from "./player-DV4Hf5Cw.js";
5
- const x = 8, v = /%(0(\d+))?d/;
1
+ var E = Object.defineProperty;
2
+ var y = (u, t, e) => t in u ? E(u, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : u[t] = e;
3
+ var l = (u, t, e) => y(u, typeof t != "symbol" ? t + "" : t, e);
4
+ import { f as v } from "./player-D2_HRzot.js";
5
+ const x = 8, g = /%(0(\d+))?d/;
6
6
  class S {
7
7
  constructor(t, e) {
8
8
  l(this, "tooltip");
@@ -57,22 +57,22 @@ class S {
57
57
  }
58
58
  // ── çizim ──
59
59
  render() {
60
- var h;
60
+ var d, p, f;
61
61
  if (!this.hovering || this.destroyed) return;
62
62
  const t = this.ctx.videoEl.duration;
63
63
  if (!Number.isFinite(t) || t <= 0) return;
64
- const e = this.ctx.seekBar.ratioAtClientX(this.lastClientX) * t;
65
- this.timeEl.textContent = y(e);
66
- const i = this.isNetworkEligible() ? this.frameAt(e, t) : null;
67
- i && (this.lastFrameWidth = i.w);
68
- const s = i ?? this.lowResFrameAt(e, t), n = i ? this.sheets.get(i.url).img : (h = this.lowSheet) == null ? void 0 : h.img;
69
- if (s && n) {
70
- const d = (this.options.displayWidth ?? (i ? i.w : this.options.width || this.lastFrameWidth || s.w)) * this.scale(), c = d / s.w;
71
- this.imageEl.style.display = "", this.imageEl.toggleAttribute("data-lowres", !i), this.imageEl.style.width = `${d}px`, this.imageEl.style.height = `${s.h * c}px`, this.imageEl.style.backgroundImage = `url("${s.url}")`, this.imageEl.style.backgroundSize = `${n.naturalWidth * c}px ${n.naturalHeight * c}px`, this.imageEl.style.backgroundPosition = `${-s.x * c}px ${-s.y * c}px`;
64
+ const e = this.ctx.seekBar.ratioAtClientX(this.lastClientX) * t, i = (p = (d = this.ctx.seekBar).markerLabelAt) == null ? void 0 : p.call(d, this.lastClientX);
65
+ this.timeEl.textContent = i ? `${i} · ${v(e)}` : v(e);
66
+ const s = this.isNetworkEligible() ? this.frameAt(e, t) : null;
67
+ s && (this.lastFrameWidth = s.w);
68
+ const n = s ?? this.lowResFrameAt(e, t), r = s ? this.sheets.get(s.url).img : (f = this.lowSheet) == null ? void 0 : f.img;
69
+ if (n && r) {
70
+ const c = (this.options.displayWidth ?? (s ? s.w : this.options.width || this.lastFrameWidth || n.w)) * this.scale(), m = c / n.w;
71
+ this.imageEl.style.display = "", this.imageEl.toggleAttribute("data-lowres", !s), this.imageEl.style.width = `${c}px`, this.imageEl.style.height = `${n.h * m}px`, this.imageEl.style.backgroundImage = `url("${n.url}")`, this.imageEl.style.backgroundSize = `${r.naturalWidth * m}px ${r.naturalHeight * m}px`, this.imageEl.style.backgroundPosition = `${-n.x * m}px ${-n.y * m}px`;
72
72
  } else this.imageEl.style.backgroundImage || (this.imageEl.style.display = "none");
73
73
  this.tooltip.setAttribute("data-visible", "");
74
- const r = this.ctx.seekBar.el.getBoundingClientRect(), o = this.tooltip.offsetWidth, a = Math.min(Math.max(this.lastClientX - r.left - o / 2, 0), Math.max(r.width - o, 0));
75
- this.tooltip.style.transform = `translateX(${a}px)`;
74
+ const o = this.ctx.seekBar.el.getBoundingClientRect(), a = this.tooltip.offsetWidth, h = Math.min(Math.max(this.lastClientX - o.left - a / 2, 0), Math.max(o.width - a, 0));
75
+ this.tooltip.style.transform = `translateX(${h}px)`;
76
76
  }
77
77
  scale() {
78
78
  const t = this.options.responsive, e = this.ctx.playerWidth();
@@ -98,7 +98,7 @@ class S {
98
98
  }
99
99
  isMultiSheet() {
100
100
  var t;
101
- return !!((t = this.options.sheets) != null && t.length) || v.test(this.options.url ?? "");
101
+ return !!((t = this.options.sheets) != null && t.length) || g.test(this.options.url ?? "");
102
102
  }
103
103
  /** Tek sheet → Infinity (tüm video); çok parçalı → verilen ya da ilk sheet'ten hesaplanan süre; henüz bilinmiyorsa null. */
104
104
  sheetDuration() {
@@ -116,7 +116,7 @@ class S {
116
116
  var s;
117
117
  if ((s = this.options.sheets) != null && s.length) return this.options.sheets[Math.min(t, this.options.sheets.length - 1)];
118
118
  const e = this.options.url ?? "", i = t + (this.options.firstSheetIndex ?? 1);
119
- return e.replace(v, (n, r, o) => String(i).padStart(o ? Number(o) : 0, "0"));
119
+ return e.replace(g, (n, r, o) => String(i).padStart(o ? Number(o) : 0, "0"));
120
120
  }
121
121
  gridFrameAt(t, e) {
122
122
  const { width: i, height: s } = this.options;
@@ -130,8 +130,8 @@ class S {
130
130
  if (!(d != null && d.ready))
131
131
  return this.ensureSheet(h), null;
132
132
  this.touch(h);
133
- const c = Math.max(1, Math.floor(d.img.naturalWidth / i)), p = Math.max(1, Math.floor(d.img.naturalHeight / s)), m = r === 1 / 0 ? t : t - a * r, f = Math.min(Math.max(0, Math.floor(m / n)), c * p - 1);
134
- return { url: h, x: f % c * i, y: Math.floor(f / c) * s, w: i, h: s };
133
+ const p = Math.max(1, Math.floor(d.img.naturalWidth / i)), f = Math.max(1, Math.floor(d.img.naturalHeight / s)), c = r === 1 / 0 ? t : t - a * r, m = Math.min(Math.max(0, Math.floor(c / n)), p * f - 1);
134
+ return { url: h, x: m % p * i, y: Math.floor(m / p) * s, w: i, h: s };
135
135
  }
136
136
  preloadAround(t, e) {
137
137
  const i = this.options.preloadSheets ?? 1;
@@ -216,7 +216,7 @@ class S {
216
216
  }), this.vttLoading;
217
217
  }
218
218
  }
219
- function g(u) {
219
+ function w(u) {
220
220
  return u.trim().split(":").map(Number).reduce((e, i) => e * 60 + i, 0);
221
221
  }
222
222
  function M(u, t) {
@@ -224,16 +224,16 @@ function M(u, t) {
224
224
  const e = [], i = u.replace(/\r/g, "").split(/\n\n+/);
225
225
  for (const n of i) {
226
226
  const r = n.split(`
227
- `).filter(Boolean), o = r.findIndex((f) => f.includes("-->"));
227
+ `).filter(Boolean), o = r.findIndex((m) => m.includes("-->"));
228
228
  if (o === -1) continue;
229
229
  const [a, h] = r[o].split("-->"), d = (s = r[o + 1]) == null ? void 0 : s.trim();
230
230
  if (!a || !h || !d) continue;
231
- const [c, p] = d.split("#"), m = p == null ? void 0 : p.match(/xywh=(\d+),(\d+),(\d+),(\d+)/);
231
+ const [p, f] = d.split("#"), c = f == null ? void 0 : f.match(/xywh=(\d+),(\d+),(\d+),(\d+)/);
232
232
  e.push({
233
- start: g(a),
234
- end: g(h.trim().split(/\s+/)[0]),
235
- url: new URL(c, t).href,
236
- rect: m ? { x: +m[1], y: +m[2], w: +m[3], h: +m[4] } : null
233
+ start: w(a),
234
+ end: w(h.trim().split(/\s+/)[0]),
235
+ url: new URL(p, t).href,
236
+ rect: c ? { x: +c[1], y: +c[2], w: +c[3], h: +c[4] } : null
237
237
  });
238
238
  }
239
239
  return e.sort((n, r) => n.start - r.start);
@@ -245,4 +245,4 @@ export {
245
245
  S as SpriteThumbnails,
246
246
  A as installSpriteThumbnails
247
247
  };
248
- //# sourceMappingURL=spriteThumbnails-BoxVY--_.js.map
248
+ //# sourceMappingURL=spriteThumbnails-Cr9UmkM9.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spriteThumbnails-Cr9UmkM9.js","sources":["../../src/plugins/sprite-thumbnails/SpriteThumbnails.ts","../../src/plugins/sprite-thumbnails/index.ts"],"sourcesContent":["import type { SpriteThumbnailsOptions } from '../../types';\nimport { formatTime } from '../../utils/format-time';\n\nexport interface SpriteThumbnailsPlayerContext {\n videoEl: HTMLVideoElement;\n /** Önizlemenin bağlandığı seek bar — zaman eşlemesi (chapter boşlukları dahil) onun `ratioAtClientX`'inden. */\n seekBar: {\n readonly el: HTMLElement;\n ratioAtClientX(clientX: number): number;\n suppressHoverTime(key: string, suppressed: boolean): void;\n markerLabelAt?(clientX: number): string | null;\n };\n /** Responsive ölçekleme için referans genişlik — genelde player/video alanının genişliği. */\n playerWidth(): number;\n}\n\n/** Bir önizleme karesi: hangi görselin hangi dikdörtgeni. */\ninterface Frame {\n url: string;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\ninterface Sheet {\n img: HTMLImageElement;\n ready: boolean;\n failed: boolean;\n promise: Promise<void>;\n}\n\nexport interface VttCue {\n start: number;\n end: number;\n url: string;\n /** `#xywh` yoksa null → görselin tamamı. */\n rect: { x: number; y: number; w: number; h: number } | null;\n}\n\n/** Aynı anda bellekte (decode edilmiş) tutulan en fazla sheet — uzun videolarda bellek sınırsız büyümesin. */\nconst MAX_CACHED_SHEETS = 8;\n/** Sheet numarası şablonu: `%d` ya da sıfır dolgulu `%03d`. */\nconst SHEET_TEMPLATE = /%(0(\\d+))?d/;\n\n/**\n * Seek bar hover önizlemesi. Kaynak: tek görsel, çok parçalı (%d / %03d şablonu ya da sheets) veya WebVTT (#xywh).\n * sheetDuration verilmezse ilk sheet'in ızgarasından hesaplanır. Kurulumda hiçbir şey indirilmez; yalnızca imlecin\n * altındaki sheet + komşuları yüklenir, decode bitmeden gösterilmez, LRU cache.\n */\nexport class SpriteThumbnails {\n private readonly tooltip: HTMLElement;\n private readonly imageEl: HTMLElement;\n private readonly timeEl: HTMLElement;\n private readonly sheets = new Map<string, Sheet>();\n private vttCues: VttCue[] | null = null;\n private vttLoading: Promise<void> | null = null;\n /** Çok parçalı modda otomatik hesaplanan sheet süresi (ilk sheet yüklenince). */\n private derivedSheetDuration: number | null = null;\n /** `lowRes` sheet'i — LRU dışında, hep bellekte. */\n private lowSheet: Sheet | null = null;\n /** Son çizilen asıl karenin genişliği (VTT'de `width` yok). */\n private lastFrameWidth = 0;\n private warmed = false;\n private hovering = false;\n private lastClientX = 0;\n private rafId: number | null = null;\n private destroyed = false;\n\n constructor(\n private readonly ctx: SpriteThumbnailsPlayerContext,\n private readonly options: SpriteThumbnailsOptions\n ) {\n this.tooltip = document.createElement('div');\n this.tooltip.setAttribute('part', 'sprite-tooltip');\n this.tooltip.className = 'hp-sprite-tooltip';\n this.imageEl = document.createElement('div');\n this.imageEl.className = 'hp-sprite-image';\n this.timeEl = document.createElement('div');\n this.timeEl.className = 'hp-sprite-time';\n this.tooltip.append(this.imageEl, this.timeEl);\n ctx.seekBar.el.appendChild(this.tooltip);\n // Önizlemenin altında zaman zaten yazıyor — varsayılan hover zamanı ikinci kez göstermesin.\n ctx.seekBar.suppressHoverTime('sprite', true);\n\n ctx.seekBar.el.addEventListener('pointerenter', this.onPointerEnter);\n ctx.seekBar.el.addEventListener('pointermove', this.onPointerMove);\n ctx.seekBar.el.addEventListener('pointerleave', this.onPointerLeave);\n ctx.videoEl.addEventListener('play', this.warm);\n }\n\n destroy(): void {\n this.destroyed = true;\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.ctx.seekBar.el.removeEventListener('pointerenter', this.onPointerEnter);\n this.ctx.seekBar.el.removeEventListener('pointermove', this.onPointerMove);\n this.ctx.seekBar.el.removeEventListener('pointerleave', this.onPointerLeave);\n this.ctx.videoEl.removeEventListener('play', this.warm);\n this.tooltip.remove();\n this.ctx.seekBar.suppressHoverTime('sprite', false);\n for (const sheet of this.sheets.values()) sheet.img.src = '';\n if (this.lowSheet) this.lowSheet.img.src = '';\n this.sheets.clear();\n }\n\n // ── olaylar ──\n\n private readonly onPointerEnter = (e: PointerEvent): void => {\n this.hovering = true;\n this.lastClientX = e.clientX;\n this.warm();\n this.scheduleRender();\n };\n\n private readonly onPointerMove = (e: PointerEvent): void => {\n this.hovering = true;\n this.lastClientX = e.clientX;\n this.scheduleRender();\n };\n\n private readonly onPointerLeave = (): void => {\n this.hovering = false;\n this.tooltip.removeAttribute('data-visible');\n };\n\n /** İlk ihtiyaç anında (hover / oynatma) kaynağı hazırla — kurulumda hiçbir şey indirilmiyor. */\n private readonly warm = (): void => {\n if (this.warmed || this.destroyed) return;\n this.warmed = true;\n // Küçük sheet bağlantı hızından bağımsız hemen iner.\n if (this.options.lowRes?.url) this.lowSheet = this.createSheet(this.options.lowRes.url, () => this.hovering && this.scheduleRender());\n if (this.options.vtt) {\n void this.loadVtt();\n return;\n }\n const duration = this.ctx.videoEl.duration;\n const t = Number.isFinite(duration) ? this.ctx.videoEl.currentTime : 0;\n // Şablonlu/çok parçalı modda sheet süresi henüz bilinmiyorsa ilk sheet'ten öğrenilecek.\n void this.ensureSheet(this.sheetUrl(this.isMultiSheet() && this.sheetDuration() === null ? 0 : this.sheetIndexAt(t)));\n };\n\n private scheduleRender(): void {\n if (this.rafId !== null) return;\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null;\n this.render();\n });\n }\n\n // ── çizim ──\n\n private render(): void {\n if (!this.hovering || this.destroyed) return;\n const duration = this.ctx.videoEl.duration;\n if (!Number.isFinite(duration) || duration <= 0) return;\n\n const seconds = this.ctx.seekBar.ratioAtClientX(this.lastClientX) * duration;\n const label = this.ctx.seekBar.markerLabelAt?.(this.lastClientX);\n this.timeEl.textContent = label ? `${label} · ${formatTime(seconds)}` : formatTime(seconds);\n\n // Asıl kare hazır değilse küçük sheet'ten doğru zamanın karesi; o da yoksa son kare ekranda kalır.\n const hi = this.isNetworkEligible() ? this.frameAt(seconds, duration) : null;\n if (hi) this.lastFrameWidth = hi.w;\n const frame = hi ?? this.lowResFrameAt(seconds, duration);\n const img = hi ? this.sheets.get(hi.url)!.img : this.lowSheet?.img;\n if (frame && img) {\n // Hedef genişlik: displayWidth → kare genişliği; küçük kare aynı boyuta büyütülür.\n const target = (this.options.displayWidth ?? (hi ? hi.w : this.options.width || this.lastFrameWidth || frame.w)) * this.scale();\n const k = target / frame.w;\n this.imageEl.style.display = '';\n this.imageEl.toggleAttribute('data-lowres', !hi);\n this.imageEl.style.width = `${target}px`;\n this.imageEl.style.height = `${frame.h * k}px`;\n this.imageEl.style.backgroundImage = `url(\"${frame.url}\")`;\n this.imageEl.style.backgroundSize = `${img.naturalWidth * k}px ${img.naturalHeight * k}px`;\n this.imageEl.style.backgroundPosition = `${-frame.x * k}px ${-frame.y * k}px`;\n } else if (!this.imageEl.style.backgroundImage) {\n // Henüz hiçbir kare yüklenmedi — yalnızca zaman (yükleme bitince yeniden çizilir).\n this.imageEl.style.display = 'none';\n }\n\n // Kenarlarda taşmasın: imleci ortala ama seek bar sınırlarında kal.\n this.tooltip.setAttribute('data-visible', '');\n const barRect = this.ctx.seekBar.el.getBoundingClientRect();\n const tipWidth = this.tooltip.offsetWidth;\n const x = Math.min(Math.max(this.lastClientX - barRect.left - tipWidth / 2, 0), Math.max(barRect.width - tipWidth, 0));\n this.tooltip.style.transform = `translateX(${x}px)`;\n }\n\n private scale(): number {\n const responsive = this.options.responsive;\n const playerWidth = this.ctx.playerWidth();\n return responsive && playerWidth && playerWidth < responsive ? playerWidth / responsive : 1;\n }\n\n private isNetworkEligible(): boolean {\n const nav = navigator as Navigator & { connection?: { downlink?: number } };\n const downlink = nav.connection?.downlink;\n const anyReady = Array.from(this.sheets.values()).some((s) => s.ready);\n return downlink === undefined || downlink >= (this.options.downlink ?? 2) || anyReady;\n }\n\n // ── kare çözümleme ──\n\n /** `lowRes` sheet'inden saniyedeki kare (hazır değilse null). */\n private lowResFrameAt(seconds: number, duration: number): Frame | null {\n const o = this.options.lowRes;\n const img = this.lowSheet?.ready ? this.lowSheet.img : null;\n if (!o || !img || !o.width || !o.height) return null;\n const columns = Math.max(1, Math.floor(img.naturalWidth / o.width));\n const count = columns * Math.max(1, Math.floor(img.naturalHeight / o.height));\n const interval = o.interval || duration / count;\n const i = Math.min(count - 1, Math.max(0, Math.floor(seconds / interval)));\n return { url: o.url, x: (i % columns) * o.width, y: Math.floor(i / columns) * o.height, w: o.width, h: o.height };\n }\n\n /** Saniyedeki kareyi döner; gereken sheet hazır değilse yüklemeyi başlatıp null döner (yüklenince render tekrar çağrılır). */\n private frameAt(seconds: number, duration: number): Frame | null {\n return this.options.vtt ? this.vttFrameAt(seconds) : this.gridFrameAt(seconds, duration);\n }\n\n private isMultiSheet(): boolean {\n return !!this.options.sheets?.length || SHEET_TEMPLATE.test(this.options.url ?? '');\n }\n\n /** Tek sheet → Infinity (tüm video); çok parçalı → verilen ya da ilk sheet'ten hesaplanan süre; henüz bilinmiyorsa null. */\n private sheetDuration(): number | null {\n if (!this.isMultiSheet()) return Infinity;\n return this.options.sheetDuration ?? this.derivedSheetDuration;\n }\n\n private sheetIndexAt(seconds: number): number {\n const d = this.sheetDuration();\n if (d === null || d === Infinity) return 0;\n // floor (ceil DEĞİL): tam sınırda (ör. 60. sn) bir SONRAKİ sheet'in ilk karesi.\n let index = Math.floor(Math.max(0, seconds) / d);\n if (this.options.sheets?.length) index = Math.min(index, this.options.sheets.length - 1);\n return index;\n }\n\n /** 0 tabanlı sheet index'inden URL. */\n private sheetUrl(index: number): string {\n if (this.options.sheets?.length) return this.options.sheets[Math.min(index, this.options.sheets.length - 1)]!;\n const url = this.options.url ?? '';\n const number = index + (this.options.firstSheetIndex ?? 1);\n return url.replace(SHEET_TEMPLATE, (_m, _p, width?: string) => String(number).padStart(width ? Number(width) : 0, '0'));\n }\n\n private gridFrameAt(seconds: number, duration: number): Frame | null {\n const { width, height } = this.options;\n if (!width || !height) return null;\n const interval = this.options.interval || 1;\n\n const sheetDuration = this.sheetDuration();\n if (sheetDuration === null) {\n // Çok parçalı ama süre bilinmiyor — ilk sheet yüklenince hesaplanacak.\n void this.ensureSheet(this.sheetUrl(0));\n return null;\n }\n\n const lastIndex = sheetDuration === Infinity ? 0 : this.sheetIndexAt(Math.max(0, duration - 0.001));\n const index = Math.min(this.sheetIndexAt(seconds), lastIndex);\n const url = this.sheetUrl(index);\n this.preloadAround(index, lastIndex);\n\n const sheet = this.sheets.get(url);\n if (!sheet?.ready) {\n void this.ensureSheet(url);\n return null;\n }\n this.touch(url);\n\n // Her sheet'in KENDİ boyutu (son sheet daha kısa olabilir).\n const columns = Math.max(1, Math.floor(sheet.img.naturalWidth / width));\n const rows = Math.max(1, Math.floor(sheet.img.naturalHeight / height));\n const local = sheetDuration === Infinity ? seconds : seconds - index * sheetDuration;\n const frameIndex = Math.min(Math.max(0, Math.floor(local / interval)), columns * rows - 1);\n return { url, x: (frameIndex % columns) * width, y: Math.floor(frameIndex / columns) * height, w: width, h: height };\n }\n\n private preloadAround(index: number, lastIndex: number): void {\n const n = this.options.preloadSheets ?? 1;\n for (let d = 1; d <= n; d++) {\n if (index + d <= lastIndex) void this.ensureSheet(this.sheetUrl(index + d));\n if (index - d >= 0) void this.ensureSheet(this.sheetUrl(index - d));\n }\n }\n\n private vttFrameAt(seconds: number): Frame | null {\n if (!this.vttCues) {\n void this.loadVtt();\n return null;\n }\n const cues = this.vttCues;\n if (!cues.length) return null;\n // İkili arama — saatlerce süren videolarda binlerce cue olabilir.\n let lo = 0;\n let hi = cues.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (cues[mid]!.start <= seconds) lo = mid;\n else hi = mid - 1;\n }\n const cue = cues[lo]!;\n const neighbours = [cues[lo + 1], cues[lo - 1]].filter((c): c is VttCue => !!c && c.url !== cue.url);\n neighbours.forEach((c) => void this.ensureSheet(c.url));\n\n const sheet = this.sheets.get(cue.url);\n if (!sheet?.ready) {\n void this.ensureSheet(cue.url);\n return null;\n }\n this.touch(cue.url);\n const rect = cue.rect ?? { x: 0, y: 0, w: sheet.img.naturalWidth, h: sheet.img.naturalHeight };\n return { url: cue.url, ...rect };\n }\n\n // ── yükleme / cache ──\n\n private ensureSheet(url: string): Promise<void> {\n if (!url) return Promise.resolve();\n const existing = this.sheets.get(url);\n if (existing) return existing.promise;\n\n const sheet = this.createSheet(url, (img) => {\n this.learnSheetDuration(img);\n if (this.hovering) this.scheduleRender();\n });\n this.sheets.set(url, sheet);\n this.evict();\n return sheet.promise;\n }\n\n /** Görseli yükler; decode bitmeden hazır sayılmaz (sheet geçişinde titreme olmasın). */\n private createSheet(url: string, onReady: (img: HTMLImageElement) => void): Sheet {\n const img = new Image();\n img.decoding = 'async';\n const sheet: Sheet = { img, ready: false, failed: false, promise: Promise.resolve() };\n sheet.promise = new Promise<void>((resolve) => {\n img.onload = () => {\n const done = () => {\n if (this.destroyed) return resolve();\n sheet.ready = true;\n onReady(img);\n resolve();\n };\n img.decode ? img.decode().then(done, done) : done();\n };\n img.onerror = () => {\n sheet.failed = true;\n resolve();\n };\n });\n img.src = url;\n return sheet;\n }\n\n /** Çok parçalı modda `sheetDuration` verilmediyse ilk yüklenen sheet'in ızgara kapasitesinden hesapla. */\n private learnSheetDuration(img: HTMLImageElement): void {\n if (this.derivedSheetDuration !== null || this.options.vtt || !this.isMultiSheet() || this.options.sheetDuration) return;\n const { width, height } = this.options;\n if (!width || !height) return;\n const capacity = Math.max(1, Math.floor(img.naturalWidth / width)) * Math.max(1, Math.floor(img.naturalHeight / height));\n this.derivedSheetDuration = capacity * (this.options.interval || 1);\n }\n\n /** LRU: kullanılan sheet'i sona taşı. */\n private touch(url: string): void {\n const sheet = this.sheets.get(url);\n if (!sheet) return;\n this.sheets.delete(url);\n this.sheets.set(url, sheet);\n }\n\n private evict(): void {\n while (this.sheets.size > MAX_CACHED_SHEETS) {\n const oldest = this.sheets.keys().next().value as string;\n const sheet = this.sheets.get(oldest)!;\n sheet.img.onload = null;\n sheet.img.onerror = null;\n this.sheets.delete(oldest);\n }\n }\n\n private loadVtt(): Promise<void> {\n if (this.vttLoading) return this.vttLoading;\n const vttUrl = this.options.vtt!;\n this.vttLoading = fetch(vttUrl)\n .then((r) => {\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r.text();\n })\n .then((text) => {\n if (this.destroyed) return;\n this.vttCues = parseThumbnailVtt(text, new URL(vttUrl, document.baseURI).href);\n if (this.vttCues.length) void this.ensureSheet(this.vttCues[0]!.url);\n if (this.hovering) this.scheduleRender();\n })\n .catch((err) => {\n console.warn('[HopePlayer sprite-thumbnails] VTT yüklenemedi:', err);\n this.vttCues = [];\n });\n return this.vttLoading;\n }\n}\n\n/** \"01:02:03.500\" / \"02:03.500\" → saniye. */\nfunction parseVttTime(value: string): number {\n const parts = value.trim().split(':').map(Number);\n return parts.reduce((acc, n) => acc * 60 + n, 0);\n}\n\n/** WebVTT thumbnail dosyası → sıralı cue listesi. Görsel yolları VTT dosyasına göre çözümlenir. */\nexport function parseThumbnailVtt(text: string, baseUrl: string): VttCue[] {\n const cues: VttCue[] = [];\n const blocks = text.replace(/\\r/g, '').split(/\\n\\n+/);\n for (const block of blocks) {\n const lines = block.split('\\n').filter(Boolean);\n const timingIndex = lines.findIndex((l) => l.includes('-->'));\n if (timingIndex === -1) continue;\n const [startStr, endStr] = lines[timingIndex]!.split('-->');\n const target = lines[timingIndex + 1]?.trim();\n if (!startStr || !endStr || !target) continue;\n\n const [path, hash] = target.split('#');\n const match = hash?.match(/xywh=(\\d+),(\\d+),(\\d+),(\\d+)/);\n cues.push({\n start: parseVttTime(startStr),\n end: parseVttTime(endStr.trim().split(/\\s+/)[0]!),\n url: new URL(path!, baseUrl).href,\n rect: match ? { x: +match[1]!, y: +match[2]!, w: +match[3]!, h: +match[4]! } : null,\n });\n }\n return cues.sort((a, b) => a.start - b.start);\n}\n","import { SpriteThumbnails, type SpriteThumbnailsPlayerContext } from './SpriteThumbnails';\nimport type { SpriteThumbnailsOptions } from '../../types';\n\nexport function installSpriteThumbnails(ctx: SpriteThumbnailsPlayerContext, options: SpriteThumbnailsOptions): SpriteThumbnails {\n return new SpriteThumbnails(ctx, options);\n}\n\nexport { SpriteThumbnails };\nexport type { SpriteThumbnailsPlayerContext };\n"],"names":["MAX_CACHED_SHEETS","SHEET_TEMPLATE","SpriteThumbnails","ctx","options","__publicField","e","_a","duration","t","sheet","seconds","label","_b","formatTime","hi","frame","img","_c","target","k","barRect","tipWidth","x","responsive","playerWidth","downlink","anyReady","s","o","columns","count","interval","i","d","index","url","number","_m","_p","width","height","sheetDuration","lastIndex","rows","local","frameIndex","n","cues","lo","mid","cue","c","rect","existing","onReady","resolve","done","capacity","oldest","vttUrl","r","text","parseThumbnailVtt","err","parseVttTime","value","acc","baseUrl","blocks","block","lines","timingIndex","l","startStr","endStr","path","hash","match","a","b","installSpriteThumbnails"],"mappings":"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"}
@@ -1,18 +1,18 @@
1
1
  var E = Object.defineProperty;
2
- var w = (r, e, t) => e in r ? E(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
- var i = (r, e, t) => w(r, typeof e != "symbol" ? e + "" : e, t);
4
- const v = "hope_sticky_dismissed_until", f = "hope_sticky_dismissed_forever";
2
+ var w = (l, e, t) => e in l ? E(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t;
3
+ var r = (l, e, t) => w(l, typeof e != "symbol" ? e + "" : e, t);
4
+ const f = "hope_sticky_dismissed_until", v = "hope_sticky_dismissed_forever";
5
5
  class k {
6
6
  constructor() {
7
- i(this, "items", /* @__PURE__ */ new Map());
8
- i(this, "activeKey", null);
9
- i(this, "observer", null);
10
- i(this, "lastUserGestureAt", 0);
11
- i(this, "lastGestureType", null);
12
- i(this, "gestureListenersAttached", !1);
13
- i(this, "dismissedUntil", 0);
14
- i(this, "dismissedForever", !1);
15
- i(this, "dismissLoaded", !1);
7
+ r(this, "items", /* @__PURE__ */ new Map());
8
+ r(this, "activeKey", null);
9
+ r(this, "observer", null);
10
+ r(this, "lastUserGestureAt", 0);
11
+ r(this, "lastGestureType", null);
12
+ r(this, "gestureListenersAttached", !1);
13
+ r(this, "dismissedUntil", 0);
14
+ r(this, "dismissedForever", !1);
15
+ r(this, "dismissLoaded", !1);
16
16
  }
17
17
  register(e, t) {
18
18
  var p;
@@ -59,11 +59,11 @@ class k {
59
59
  }
60
60
  };
61
61
  this.items.set(e.key, n), this.ensureObserver().observe(a);
62
- const l = () => this.handlePlay(n), o = () => this.handlePauseOrEnded(n, "pause"), c = () => this.handlePauseOrEnded(n, "ended"), d = () => this.handleAdStart(n), u = () => this.handleAdEnd(n);
63
- e.videoEl.addEventListener("play", l), e.videoEl.addEventListener("pause", o), e.videoEl.addEventListener("ended", c), e.hostEl.addEventListener("hp:adstart", d), e.hostEl.addEventListener("hp:adend", u), !e.videoEl.paused && !e.videoEl.ended && this.handlePlay(n);
62
+ const i = () => this.handlePlay(n), o = () => this.handlePauseOrEnded(n, "pause"), c = () => this.handlePauseOrEnded(n, "ended"), d = () => this.handleAdStart(n), u = () => this.handleAdEnd(n);
63
+ e.videoEl.addEventListener("play", i), e.videoEl.addEventListener("pause", o), e.videoEl.addEventListener("ended", c), e.hostEl.addEventListener("hp:adstart", d), e.hostEl.addEventListener("hp:adend", u), !e.videoEl.paused && !e.videoEl.ended && this.handlePlay(n);
64
64
  const h = () => {
65
65
  var y;
66
- n.state.sticky && this.unstick(e.key, "destroy"), e.videoEl.removeEventListener("play", l), e.videoEl.removeEventListener("pause", o), e.videoEl.removeEventListener("ended", c), e.hostEl.removeEventListener("hp:adstart", d), e.hostEl.removeEventListener("hp:adend", u), (y = this.observer) == null || y.unobserve(a), a.remove(), this.items.delete(e.key);
66
+ n.state.sticky && this.unstick(e.key, "destroy"), e.videoEl.removeEventListener("play", i), e.videoEl.removeEventListener("pause", o), e.videoEl.removeEventListener("ended", c), e.hostEl.removeEventListener("hp:adstart", d), e.hostEl.removeEventListener("hp:adend", u), (y = this.observer) == null || y.unobserve(a), a.remove(), this.items.delete(e.key);
67
67
  };
68
68
  return h.refreshLabels = () => {
69
69
  n.state.closeBtnEl && n.state.closeBtnEl.setAttribute("aria-label", e.i18n.close);
@@ -159,7 +159,8 @@ class k {
159
159
  }
160
160
  // ── stick / unstick ──
161
161
  maybeStick(e, t) {
162
- if (e.state.userPaused && Date.now() - e.state.userPausedAt > 3e4 && (e.state.userPaused = !1, e.state.userPausedAt = 0), !e.state.hasEverBeenInView || !e.state.hasEverBeenInViewWhilePlaying || e.state.userPaused) return;
162
+ var n, i;
163
+ if ((i = (n = e.ctx).isSuspended) != null && i.call(n) || (e.state.userPaused && Date.now() - e.state.userPausedAt > 3e4 && (e.state.userPaused = !1, e.state.userPausedAt = 0), !e.state.hasEverBeenInView) || !e.state.hasEverBeenInViewWhilePlaying || e.state.userPaused) return;
163
164
  const a = Date.now();
164
165
  e.options.dismissMode === "never" && this.dismissedForever || e.options.dismissMode === "cooldown" && this.dismissedUntil && a < this.dismissedUntil || e.options.requirePlaying && !e.state.playing || e.state.sticky || e.options.minPlayMs > 0 && !e.state.minPlaySatisfied || (e.options.onlyOneSticky && this.activeKey && this.activeKey !== e.ctx.key && this.pauseAndUnstick(this.activeKey, "replaced"), this.stick(e));
165
166
  }
@@ -169,8 +170,8 @@ class k {
169
170
  if (!e.state.placeholderEl) {
170
171
  const n = document.createElement("div");
171
172
  n.setAttribute("data-hope-sticky-placeholder", "1");
172
- const l = t.getBoundingClientRect();
173
- n.style.height = `${l.height}px`, (a = t.parentNode) == null || a.insertBefore(n, t), e.state.placeholderEl = n;
173
+ const i = t.getBoundingClientRect();
174
+ n.style.height = `${i.height}px`, (a = t.parentNode) == null || a.insertBefore(n, t), e.state.placeholderEl = n;
174
175
  }
175
176
  if (t.setAttribute("data-sticky", "1"), t.setAttribute("data-sticky-corner", s), e.options.closeButton && !e.state.closeBtnEl) {
176
177
  const n = document.createElement("button");
@@ -181,11 +182,11 @@ class k {
181
182
  e.state.sticky = !0, this.activeKey = e.ctx.key, e.ctx.hostEl.dispatchEvent(new CustomEvent("hp:sticky", { detail: { sticky: !0, corner: s } }));
182
183
  }
183
184
  unstick(e, t) {
184
- var n, l;
185
+ var n, i;
185
186
  const s = this.items.get(e);
186
187
  if (!s) return;
187
188
  const a = s.ctx.wrapperEl;
188
- a.removeAttribute("data-sticky"), a.removeAttribute("data-sticky-corner"), (n = s.state.closeBtnEl) == null || n.remove(), s.state.closeBtnEl = null, (l = s.state.placeholderEl) == null || l.remove(), s.state.placeholderEl = null, s.state.sticky = !1, this.activeKey === e && (this.activeKey = null), s.ctx.hostEl.dispatchEvent(new CustomEvent("hp:sticky", { detail: { sticky: !1 } }));
189
+ a.removeAttribute("data-sticky"), a.removeAttribute("data-sticky-corner"), (n = s.state.closeBtnEl) == null || n.remove(), s.state.closeBtnEl = null, (i = s.state.placeholderEl) == null || i.remove(), s.state.placeholderEl = null, s.state.sticky = !1, this.activeKey === e && (this.activeKey = null), s.ctx.hostEl.dispatchEvent(new CustomEvent("hp:sticky", { detail: { sticky: !1 } }));
189
190
  }
190
191
  pauseAndUnstick(e, t) {
191
192
  const s = this.items.get(e);
@@ -199,7 +200,7 @@ class k {
199
200
  this.dismissLoaded = !0;
200
201
  try {
201
202
  const e = window.localStorage;
202
- this.dismissedUntil = Number(e.getItem(v) || 0) || 0, this.dismissedForever = e.getItem(f) === "1";
203
+ this.dismissedUntil = Number(e.getItem(f) || 0) || 0, this.dismissedForever = e.getItem(v) === "1";
203
204
  } catch {
204
205
  }
205
206
  }
@@ -210,7 +211,7 @@ class k {
210
211
  if (e.dismissMode === "never") {
211
212
  this.dismissedForever = !0;
212
213
  try {
213
- t == null || t.setItem(f, "1");
214
+ t == null || t.setItem(v, "1");
214
215
  } catch {
215
216
  }
216
217
  return;
@@ -218,16 +219,16 @@ class k {
218
219
  const s = Date.now() + e.cooldownMinutes * 6e4;
219
220
  this.dismissedUntil = s;
220
221
  try {
221
- t == null || t.setItem(v, String(s));
222
+ t == null || t.setItem(f, String(s));
222
223
  } catch {
223
224
  }
224
225
  }
225
226
  }
226
227
  const A = new k();
227
- function P(r, e) {
228
- return A.register(r, e);
228
+ function P(l, e) {
229
+ return A.register(l, e);
229
230
  }
230
231
  export {
231
232
  P as installSticky
232
233
  };
233
- //# sourceMappingURL=sticky-D_eLCNFk.js.map
234
+ //# sourceMappingURL=sticky-BDStzjBM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sticky-BDStzjBM.js","sources":["../../src/plugins/sticky/StickyManager.ts","../../src/plugins/sticky/index.ts"],"sourcesContent":["import type { StickyCorner, StickyOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\n\nexport interface StickyPlayerContext {\n key: string;\n videoEl: HTMLVideoElement;\n hostEl: HTMLElement;\n /** Sticky olarak köşeye taşınacak element — genelde hostEl'in kendisi (bkz. options.wrapperSelector). */\n wrapperEl: HTMLElement;\n /**\n * Kapat butonu wrapperEl'e değil shadow root içine eklenir — wrapperEl varsayılan olarak host;\n * slot olmadığı için light DOM child'ı render edilmez.\n */\n closeButtonMountEl: HTMLElement;\n isAdActive(): boolean;\n /** true iken köşeye yapışmaz (ör. video Document PiP penceresinde). */\n isSuspended?(): boolean;\n i18n: HopeLocaleStrings;\n}\n\n/** `register()`'ın döndürdüğü unregister fonksiyonu — dil sonradan değişince close butonunun statik etiketini tazelemek için `refreshLabels` da taşıyor (bkz. loop-section'daki aynı \"fonksiyona metod ekleme\" deseni). */\nexport type StickyUnregister = (() => void) & { refreshLabels?: () => void };\n\ninterface StickyItemState {\n inView: boolean;\n playing: boolean;\n sticky: boolean;\n hasEverBeenInView: boolean;\n hasEverBeenInViewWhilePlaying: boolean;\n watchMsInView: number;\n lastTickAt: number;\n minPlaySatisfied: boolean;\n userPaused: boolean;\n userPausedAt: number;\n adStartedOnce: boolean;\n contentStartedOnce: boolean;\n blockResumeUntil: number;\n programmaticPauseUntil: number;\n placeholderEl: HTMLElement | null;\n closeBtnEl: HTMLElement | null;\n}\n\ninterface StickyItem {\n ctx: StickyPlayerContext;\n options: Required<Omit<StickyOptions, 'wrapperSelector'>>;\n state: StickyItemState;\n /** wrapperEl'in doğal konumundaki görünmez işaretçi — IntersectionObserver bunu izler (sticky olunca wrapper yer değiştirir). */\n sentinelEl: HTMLElement;\n}\n\nconst GESTURE_WINDOW_MS = 1200;\nconst USER_PAUSED_MAX_MS = 30000;\nconst PROGRAMMATIC_PAUSE_MS = 800;\nconst BLOCK_RESUME_MS = 1200;\nconst STORAGE_KEY = 'hope_sticky_dismissed_until';\nconst STORAGE_KEY_FOREVER = 'hope_sticky_dismissed_forever';\n\n/** Sayfadaki tüm sticky player'ları koordine eden modül seviyesi singleton (aynı anda tek sticky). */\nclass StickyManagerImpl {\n private readonly items = new Map<string, StickyItem>();\n private activeKey: string | null = null;\n private observer: IntersectionObserver | null = null;\n\n private lastUserGestureAt = 0;\n private lastGestureType: 'play' | 'pause' | 'other' | null = null;\n private gestureListenersAttached = false;\n\n private dismissedUntil = 0;\n private dismissedForever = false;\n private dismissLoaded = false;\n\n register(ctx: StickyPlayerContext, options: StickyOptions): StickyUnregister {\n this.ensureGestureListeners();\n this.loadDismissState();\n\n const resolved: StickyItem['options'] = {\n enabled: options.enabled ?? true,\n corner: options.corner ?? 'br',\n requirePlaying: options.requirePlaying ?? true,\n minPlayMs: options.minPlayMs ?? 800,\n onlyOneSticky: options.onlyOneSticky ?? true,\n closeActiveStickyOnAnotherPlay: options.closeActiveStickyOnAnotherPlay ?? true,\n userGestureWindowMs: options.userGestureWindowMs ?? GESTURE_WINDOW_MS,\n adCanTriggerSticky: options.adCanTriggerSticky ?? 'preroll-only',\n dismissMode: options.dismissMode ?? 'cooldown',\n cooldownMinutes: options.cooldownMinutes ?? 5,\n storage: options.storage ?? 'local',\n closeButton: options.closeButton ?? true,\n };\n\n if (!resolved.enabled) return () => {};\n\n const sentinel = document.createElement('div');\n sentinel.setAttribute('aria-hidden', 'true');\n sentinel.style.cssText = 'position:relative;width:1px;height:1px;pointer-events:none;opacity:0;';\n ctx.wrapperEl.parentNode?.insertBefore(sentinel, ctx.wrapperEl);\n\n const item: StickyItem = {\n ctx,\n options: resolved,\n sentinelEl: sentinel,\n state: {\n inView: true,\n playing: false,\n sticky: false,\n hasEverBeenInView: false,\n hasEverBeenInViewWhilePlaying: false,\n watchMsInView: 0,\n lastTickAt: 0,\n minPlaySatisfied: false,\n userPaused: false,\n userPausedAt: 0,\n adStartedOnce: false,\n contentStartedOnce: false,\n blockResumeUntil: 0,\n programmaticPauseUntil: 0,\n placeholderEl: null,\n closeBtnEl: null,\n },\n };\n this.items.set(ctx.key, item);\n\n this.ensureObserver().observe(sentinel);\n\n const onPlay = () => this.handlePlay(item);\n const onPause = () => this.handlePauseOrEnded(item, 'pause');\n const onEnded = () => this.handlePauseOrEnded(item, 'ended');\n const onAdStart = () => this.handleAdStart(item);\n const onAdEnd = () => this.handleAdEnd(item);\n\n ctx.videoEl.addEventListener('play', onPlay);\n ctx.videoEl.addEventListener('pause', onPause);\n ctx.videoEl.addEventListener('ended', onEnded);\n ctx.hostEl.addEventListener('hp:adstart', onAdStart);\n ctx.hostEl.addEventListener('hp:adend', onAdEnd);\n\n // Plugin dinamik yüklendiği için autoplay video'yu bu dinleyiciden önce başlatmış olabilir —\n // kaçırılan 'play'i telafi et, yoksa requirePlaying sticky'yi hiç açmaz.\n if (!ctx.videoEl.paused && !ctx.videoEl.ended) {\n this.handlePlay(item);\n }\n\n const unregister: StickyUnregister = () => {\n if (item.state.sticky) this.unstick(ctx.key, 'destroy');\n ctx.videoEl.removeEventListener('play', onPlay);\n ctx.videoEl.removeEventListener('pause', onPause);\n ctx.videoEl.removeEventListener('ended', onEnded);\n ctx.hostEl.removeEventListener('hp:adstart', onAdStart);\n ctx.hostEl.removeEventListener('hp:adend', onAdEnd);\n this.observer?.unobserve(sentinel);\n sentinel.remove();\n this.items.delete(ctx.key);\n };\n unregister.refreshLabels = () => {\n if (item.state.closeBtnEl) {\n item.state.closeBtnEl.setAttribute('aria-label', ctx.i18n.close);\n }\n };\n return unregister;\n }\n\n // ── gesture tracking (tüm sayfa için tek dinleyici) ──\n\n private ensureGestureListeners(): void {\n if (this.gestureListenersAttached || typeof window === 'undefined') return;\n this.gestureListenersAttached = true;\n\n window.addEventListener(\n 'pointerdown',\n (e) => {\n this.lastUserGestureAt = Date.now();\n // composedPath()[0]: Shadow DOM'da e.target host'a retarget edilir; gerçek iç butonu almak için.\n const target = (e.composedPath()[0] ?? e.target) as HTMLElement | null;\n const btn = target?.closest?.('button,[role=\"button\"]') as HTMLElement | null;\n if (btn?.querySelector('.hp-icon-pause')) this.lastGestureType = 'pause';\n else if (btn?.querySelector('.hp-icon-play')) this.lastGestureType = 'play';\n else this.lastGestureType = 'other';\n },\n { capture: true, passive: true }\n );\n window.addEventListener(\n 'keydown',\n () => {\n this.lastUserGestureAt = Date.now();\n this.lastGestureType = 'other';\n },\n { capture: true }\n );\n }\n\n // ── intersection observer (tüm sticky item'lar için tek instance) ──\n\n private ensureObserver(): IntersectionObserver {\n if (this.observer) return this.observer;\n this.observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n const item = [...this.items.values()].find((i) => i.sentinelEl === entry.target);\n if (!item) continue;\n this.onIntersect(item, entry);\n }\n },\n { threshold: [0.35], rootMargin: '0px 0px -20% 0px' }\n );\n return this.observer;\n }\n\n private onIntersect(item: StickyItem, entry: IntersectionObserverEntry): void {\n this.accumulateWatch(item);\n const inView = entry.isIntersecting && entry.intersectionRatio >= 0.35;\n item.state.inView = inView;\n\n if (inView) {\n item.state.hasEverBeenInView = true;\n if (item.state.playing) item.state.hasEverBeenInViewWhilePlaying = true;\n if (item.state.sticky) this.unstick(item.ctx.key, 'back_in_view');\n } else {\n if (!item.state.hasEverBeenInView) return;\n const isActive = item.state.playing;\n if (item.options.requirePlaying && !isActive) return;\n this.maybeStick(item, 'out_of_view');\n }\n }\n\n // ── player event handlers ──\n\n private handlePlay(item: StickyItem): void {\n if (item.state.blockResumeUntil && Date.now() < item.state.blockResumeUntil) {\n item.ctx.videoEl.pause();\n item.state.playing = false;\n return;\n }\n if (item.ctx.isAdActive()) return;\n\n item.state.contentStartedOnce = true;\n const wasPlaying = item.state.playing;\n item.state.playing = true;\n if (!wasPlaying) {\n item.state.lastTickAt = Date.now();\n item.state.watchMsInView = 0;\n }\n if (item.state.inView) item.state.hasEverBeenInViewWhilePlaying = true;\n\n const gestureWindow = item.options.userGestureWindowMs;\n let userInitiated = Date.now() - this.lastUserGestureAt <= gestureWindow;\n if (this.lastGestureType === 'pause') userInitiated = false;\n if (item.state.userPaused && Date.now() - item.state.userPausedAt <= 1500) userInitiated = false;\n\n if (userInitiated) {\n item.state.userPaused = false;\n item.state.userPausedAt = 0;\n this.lastGestureType = 'play';\n }\n\n this.handleBecameActive(item, 'content', userInitiated);\n }\n\n private handlePauseOrEnded(item: StickyItem, kind: 'pause' | 'ended'): void {\n this.accumulateWatch(item);\n if (item.ctx.isAdActive()) {\n item.state.playing = true;\n return;\n }\n item.state.playing = false;\n\n const now = Date.now();\n if (item.state.programmaticPauseUntil && now < item.state.programmaticPauseUntil) {\n item.state.programmaticPauseUntil = 0;\n item.state.userPaused = false;\n item.state.userPausedAt = 0;\n return;\n }\n\n if (kind === 'pause') {\n const isUserPause = now - this.lastUserGestureAt <= item.options.userGestureWindowMs;\n if (isUserPause) {\n item.state.userPaused = true;\n item.state.userPausedAt = now;\n this.lastGestureType = 'pause';\n }\n } else if (item.state.sticky) {\n this.unstick(item.ctx.key, 'ended');\n }\n }\n\n private handleAdStart(item: StickyItem): void {\n const mode = item.options.adCanTriggerSticky;\n const isCurrentlySticky = this.activeKey === item.ctx.key;\n const isFirstAdEver = !item.state.adStartedOnce;\n item.state.adStartedOnce = true;\n item.state.lastTickAt = Date.now();\n item.state.playing = true;\n\n let allow = false;\n if (mode === 'always') allow = true;\n else if (mode === 'never') allow = false;\n else allow = isCurrentlySticky || (isFirstAdEver && !item.state.contentStartedOnce);\n\n if (!allow) return;\n this.handleBecameActive(item, 'ad', false);\n }\n\n private handleAdEnd(item: StickyItem): void {\n this.accumulateWatch(item);\n item.state.playing = !item.ctx.videoEl.paused && !item.ctx.videoEl.ended;\n item.state.lastTickAt = Date.now();\n }\n\n private handleBecameActive(item: StickyItem, source: 'content' | 'ad', userInitiated: boolean): void {\n item.state.playing = true;\n if (userInitiated) {\n item.state.userPaused = false;\n item.state.userPausedAt = 0;\n this.lastGestureType = 'play';\n }\n\n const now = Date.now();\n if (!item.state.lastTickAt) item.state.lastTickAt = now;\n if (item.state.inView) {\n item.state.hasEverBeenInView = true;\n item.state.hasEverBeenInViewWhilePlaying = true;\n }\n\n if (item.options.closeActiveStickyOnAnotherPlay && userInitiated && this.activeKey && this.activeKey !== item.ctx.key) {\n this.pauseAndUnstick(this.activeKey, 'another_played');\n }\n\n if (!item.state.inView) this.maybeStick(item, source === 'ad' ? 'play_ad' : 'play');\n }\n\n private accumulateWatch(item: StickyItem): void {\n const now = Date.now();\n const last = item.state.lastTickAt || now;\n item.state.lastTickAt = now;\n if (!item.state.playing || !item.state.inView) return;\n\n item.state.watchMsInView += now - last;\n if (!item.state.minPlaySatisfied && item.options.minPlayMs > 0 && item.state.watchMsInView >= item.options.minPlayMs) {\n item.state.minPlaySatisfied = true;\n }\n }\n\n // ── stick / unstick ──\n\n private maybeStick(item: StickyItem, _trigger: string): void {\n if (item.ctx.isSuspended?.()) return;\n const maxMs = USER_PAUSED_MAX_MS;\n if (item.state.userPaused && Date.now() - item.state.userPausedAt > maxMs) {\n item.state.userPaused = false;\n item.state.userPausedAt = 0;\n }\n\n if (!item.state.hasEverBeenInView) return;\n if (!item.state.hasEverBeenInViewWhilePlaying) return;\n if (item.state.userPaused) return;\n\n const now = Date.now();\n if (item.options.dismissMode === 'never' && this.dismissedForever) return;\n if (item.options.dismissMode === 'cooldown' && this.dismissedUntil && now < this.dismissedUntil) return;\n\n if (item.options.requirePlaying && !item.state.playing) return;\n if (item.state.sticky) return;\n if (item.options.minPlayMs > 0 && !item.state.minPlaySatisfied) return;\n\n if (item.options.onlyOneSticky && this.activeKey && this.activeKey !== item.ctx.key) {\n this.pauseAndUnstick(this.activeKey, 'replaced');\n }\n\n this.stick(item);\n }\n\n private stick(item: StickyItem): void {\n const wrapper = item.ctx.wrapperEl;\n const corner = item.options.corner;\n\n if (!item.state.placeholderEl) {\n const ph = document.createElement('div');\n ph.setAttribute('data-hope-sticky-placeholder', '1');\n const rect = wrapper.getBoundingClientRect();\n ph.style.height = `${rect.height}px`;\n wrapper.parentNode?.insertBefore(ph, wrapper);\n item.state.placeholderEl = ph;\n }\n\n wrapper.setAttribute('data-sticky', '1');\n wrapper.setAttribute('data-sticky-corner', corner);\n\n if (item.options.closeButton && !item.state.closeBtnEl) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.setAttribute('part', 'sticky-close-button');\n btn.setAttribute('aria-label', item.ctx.i18n.close);\n btn.className =\n 'hp:absolute hp:top-1 hp:right-1 hp:z-30 hp:flex hp:items-center hp:justify-center hp:w-6 hp:h-6 ' +\n 'hp:rounded-full hp:bg-black/60 hp:text-white hp:border-0 hp:cursor-pointer';\n btn.innerHTML = '<i class=\"hp-icon hp-icon-close\" aria-hidden=\"true\"></i>';\n btn.addEventListener('click', () => {\n this.applyGlobalDismiss(item.options);\n this.pauseAndUnstick(item.ctx.key, 'closed');\n });\n item.ctx.closeButtonMountEl.appendChild(btn);\n item.state.closeBtnEl = btn;\n }\n\n item.state.sticky = true;\n this.activeKey = item.ctx.key;\n item.ctx.hostEl.dispatchEvent(new CustomEvent('hp:sticky', { detail: { sticky: true, corner } }));\n }\n\n private unstick(key: string, _reason: string): void {\n const item = this.items.get(key);\n if (!item) return;\n\n const wrapper = item.ctx.wrapperEl;\n wrapper.removeAttribute('data-sticky');\n wrapper.removeAttribute('data-sticky-corner');\n\n item.state.closeBtnEl?.remove();\n item.state.closeBtnEl = null;\n item.state.placeholderEl?.remove();\n item.state.placeholderEl = null;\n\n item.state.sticky = false;\n if (this.activeKey === key) this.activeKey = null;\n item.ctx.hostEl.dispatchEvent(new CustomEvent('hp:sticky', { detail: { sticky: false } }));\n }\n\n private pauseAndUnstick(key: string, reason: string): void {\n const item = this.items.get(key);\n if (!item) return;\n\n const now = Date.now();\n item.state.blockResumeUntil = now + BLOCK_RESUME_MS;\n item.state.programmaticPauseUntil = now + PROGRAMMATIC_PAUSE_MS;\n\n item.ctx.videoEl.pause();\n item.state.playing = false;\n this.unstick(key, reason);\n }\n\n // ── global dismiss (localStorage/sessionStorage) ──\n\n private loadDismissState(): void {\n if (this.dismissLoaded) return;\n this.dismissLoaded = true;\n try {\n const st = window.localStorage;\n this.dismissedUntil = Number(st.getItem(STORAGE_KEY) || 0) || 0;\n this.dismissedForever = st.getItem(STORAGE_KEY_FOREVER) === '1';\n } catch {\n /* storage erişilemez (gizli mod vb.) — sessizce yoksay */\n }\n }\n\n private applyGlobalDismiss(options: StickyItem['options']): void {\n if (options.dismissMode === 'none') return;\n const storage = options.storage === 'memory' ? null : options.storage === 'session' ? window.sessionStorage : window.localStorage;\n\n if (options.dismissMode === 'never') {\n this.dismissedForever = true;\n try {\n storage?.setItem(STORAGE_KEY_FOREVER, '1');\n } catch {\n /* no-op */\n }\n return;\n }\n\n const until = Date.now() + options.cooldownMinutes * 60000;\n this.dismissedUntil = until;\n try {\n storage?.setItem(STORAGE_KEY, String(until));\n } catch {\n /* no-op */\n }\n }\n}\n\nexport const stickyManager = new StickyManagerImpl();\nexport type { StickyCorner };\n","import { stickyManager, type StickyPlayerContext, type StickyUnregister } from './StickyManager';\nimport type { StickyOptions } from '../../types';\n\n/** Dönen fonksiyon unregister/cleanup — HopePlayerElement.disconnectedCallback'te çağrılmalı. `refreshLabels()` da taşır (dil değişince close butonu için). */\nexport function installSticky(ctx: StickyPlayerContext, options: StickyOptions): StickyUnregister {\n return stickyManager.register(ctx, options);\n}\n\nexport type { StickyPlayerContext, StickyUnregister };\n"],"names":["STORAGE_KEY","STORAGE_KEY_FOREVER","StickyManagerImpl","__publicField","ctx","options","_a","resolved","sentinel","item","onPlay","onPause","onEnded","onAdStart","onAdEnd","unregister","target","btn","entries","entry","i","inView","isActive","wasPlaying","gestureWindow","userInitiated","kind","now","mode","isCurrentlySticky","isFirstAdEver","allow","source","last","_trigger","_b","wrapper","corner","ph","rect","key","_reason","reason","st","storage","until","stickyManager","installSticky"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  var A = Object.defineProperty;
2
2
  var N = (h, t, e) => t in h ? A(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
3
3
  var r = (h, t, e) => N(h, typeof t != "symbol" ? t + "" : t, e);
4
- import { c as b } from "./player-DV4Hf5Cw.js";
4
+ import { c as b } from "./player-D2_HRzot.js";
5
5
  const P = {
6
6
  startIndex: 0,
7
7
  loop: !0,
@@ -331,4 +331,4 @@ export {
331
331
  L as HopeStory,
332
332
  M as installStory
333
333
  };
334
- //# sourceMappingURL=story-BRkhSDhR.js.map
334
+ //# sourceMappingURL=story-CodA2dfn.js.map