@hopeplayer/core 1.4.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 (151) hide show
  1. package/dist/HopePlayerElement.d.ts +42 -2
  2. package/dist/HopePlayerElement.d.ts.map +1 -1
  3. package/dist/chunks/NativeEme-CXosVcw8.js +80 -0
  4. package/dist/chunks/NativeEme-CXosVcw8.js.map +1 -0
  5. package/dist/chunks/{accessibility-DeUIoAda.js → accessibility-DFx4CE0H.js} +9 -8
  6. package/dist/chunks/{accessibility-DeUIoAda.js.map → accessibility-DFx4CE0H.js.map} +1 -1
  7. package/dist/chunks/adTriggers-BIAWe8o4.js +419 -0
  8. package/dist/chunks/adTriggers-BIAWe8o4.js.map +1 -0
  9. package/dist/chunks/{ads-CdWbE9aD.js → ads-DlpHPpR9.js} +3 -3
  10. package/dist/chunks/ads-DlpHPpR9.js.map +1 -0
  11. package/dist/chunks/analytics-DEjTAJO9.js +281 -0
  12. package/dist/chunks/analytics-DEjTAJO9.js.map +1 -0
  13. package/dist/chunks/{cast-BQ-suTcF.js → cast-vHyi7oV_.js} +2 -2
  14. package/dist/chunks/{cast-BQ-suTcF.js.map → cast-vHyi7oV_.js.map} +1 -1
  15. package/dist/chunks/dash-CWjy-y7B.js +22 -0
  16. package/dist/chunks/dash-CWjy-y7B.js.map +1 -0
  17. package/dist/chunks/docPip-wybMVP1H.js +82 -0
  18. package/dist/chunks/docPip-wybMVP1H.js.map +1 -0
  19. package/dist/chunks/heatmap-Bb7neaYU.js +92 -0
  20. package/dist/chunks/heatmap-Bb7neaYU.js.map +1 -0
  21. package/dist/chunks/{history-DAbqEhNB.js → history-CwqLXiZi.js} +2 -2
  22. package/dist/chunks/{history-DAbqEhNB.js.map → history-CwqLXiZi.js.map} +1 -1
  23. package/dist/chunks/interactive-CgltIneu.js +189 -0
  24. package/dist/chunks/interactive-CgltIneu.js.map +1 -0
  25. package/dist/chunks/keySystems-CNzjRq6e.js +70 -0
  26. package/dist/chunks/keySystems-CNzjRq6e.js.map +1 -0
  27. package/dist/chunks/{loopSection-CvF4l5uf.js → loopSection-Bwk4W8vz.js} +16 -16
  28. package/dist/chunks/loopSection-Bwk4W8vz.js.map +1 -0
  29. package/dist/chunks/{markers-B04NMI79.js → markers-L69W3kj6.js} +53 -51
  30. package/dist/chunks/markers-L69W3kj6.js.map +1 -0
  31. package/dist/chunks/player-D2_HRzot.js +4351 -0
  32. package/dist/chunks/player-D2_HRzot.js.map +1 -0
  33. package/dist/chunks/{playlist-C6Mh9BE8.js → playlist-CHfStNbQ.js} +29 -21
  34. package/dist/chunks/playlist-CHfStNbQ.js.map +1 -0
  35. package/dist/chunks/plugin-style-CPJELe-i.js +17 -0
  36. package/dist/chunks/plugin-style-CPJELe-i.js.map +1 -0
  37. package/dist/chunks/pluginHost-cN2uGFeG.js +566 -0
  38. package/dist/chunks/pluginHost-cN2uGFeG.js.map +1 -0
  39. package/dist/chunks/redirectScreen-TIqLdvBY.js +239 -0
  40. package/dist/chunks/redirectScreen-TIqLdvBY.js.map +1 -0
  41. package/dist/chunks/{rewardedUnlock-CGhQyWOk.js → rewardedUnlock-DUqYwXTr.js} +2 -2
  42. package/dist/chunks/{rewardedUnlock-CGhQyWOk.js.map → rewardedUnlock-DUqYwXTr.js.map} +1 -1
  43. package/dist/chunks/segments-Ds-c1b5e.js +66 -0
  44. package/dist/chunks/segments-Ds-c1b5e.js.map +1 -0
  45. package/dist/chunks/{skipSegments-BbWzPpXz.js → skipSegments-ByNoF1qZ.js} +2 -2
  46. package/dist/chunks/{skipSegments-BbWzPpXz.js.map → skipSegments-ByNoF1qZ.js.map} +1 -1
  47. package/dist/chunks/{spriteThumbnails-B7oDZFTo.js → spriteThumbnails-Cr9UmkM9.js} +74 -51
  48. package/dist/chunks/spriteThumbnails-Cr9UmkM9.js.map +1 -0
  49. package/dist/chunks/{statsPanel-DSClIwA3.js → statsPanel-D0DtoFgS.js} +2 -2
  50. package/dist/chunks/statsPanel-D0DtoFgS.js.map +1 -0
  51. package/dist/chunks/{sticky-D_eLCNFk.js → sticky-BDStzjBM.js} +27 -26
  52. package/dist/chunks/sticky-BDStzjBM.js.map +1 -0
  53. package/dist/chunks/{story-BLBij82f.js → story-CodA2dfn.js} +2 -2
  54. package/dist/chunks/{story-BLBij82f.js.map → story-CodA2dfn.js.map} +1 -1
  55. package/dist/chunks/transcript-LG7E9UYE.js +186 -0
  56. package/dist/chunks/transcript-LG7E9UYE.js.map +1 -0
  57. package/dist/controls/ContextMenu.d.ts +1 -0
  58. package/dist/controls/ContextMenu.d.ts.map +1 -1
  59. package/dist/controls/ControlBar.d.ts +6 -0
  60. package/dist/controls/ControlBar.d.ts.map +1 -1
  61. package/dist/controls/SeekBar.d.ts +5 -2
  62. package/dist/controls/SeekBar.d.ts.map +1 -1
  63. package/dist/controls/SettingsMenu.d.ts +2 -1
  64. package/dist/controls/SettingsMenu.d.ts.map +1 -1
  65. package/dist/drm/NativeEme.d.ts +23 -0
  66. package/dist/drm/NativeEme.d.ts.map +1 -0
  67. package/dist/drm/keySystems.d.ts +18 -0
  68. package/dist/drm/keySystems.d.ts.map +1 -0
  69. package/dist/hls/SourceManager.d.ts +31 -5
  70. package/dist/hls/SourceManager.d.ts.map +1 -1
  71. package/dist/hls/dashEngine.d.ts +85 -0
  72. package/dist/hls/dashEngine.d.ts.map +1 -0
  73. package/dist/hls/sourceGroups.d.ts.map +1 -1
  74. package/dist/hope-player.js +1 -1
  75. package/dist/i18n/locales/en.d.ts.map +1 -1
  76. package/dist/i18n/locales/tr.d.ts.map +1 -1
  77. package/dist/i18n/types.d.ts +28 -0
  78. package/dist/i18n/types.d.ts.map +1 -1
  79. package/dist/index.d.ts +2 -2
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/keyboard/KeyboardController.d.ts +14 -0
  82. package/dist/keyboard/KeyboardController.d.ts.map +1 -1
  83. package/dist/plugin-api/PluginAds.d.ts +61 -0
  84. package/dist/plugin-api/PluginAds.d.ts.map +1 -0
  85. package/dist/plugin-api/PluginHost.d.ts +6 -0
  86. package/dist/plugin-api/PluginHost.d.ts.map +1 -1
  87. package/dist/plugin-api/types.d.ts +39 -0
  88. package/dist/plugin-api/types.d.ts.map +1 -1
  89. package/dist/plugins/accessibility/Accessibility.d.ts.map +1 -1
  90. package/dist/plugins/ad-triggers/AdTriggers.d.ts +5 -0
  91. package/dist/plugins/ad-triggers/AdTriggers.d.ts.map +1 -1
  92. package/dist/plugins/ads/AdsController.d.ts +2 -0
  93. package/dist/plugins/ads/AdsController.d.ts.map +1 -1
  94. package/dist/plugins/analytics/QoeTracker.d.ts +71 -0
  95. package/dist/plugins/analytics/QoeTracker.d.ts.map +1 -0
  96. package/dist/plugins/analytics/index.d.ts +6 -0
  97. package/dist/plugins/analytics/index.d.ts.map +1 -0
  98. package/dist/plugins/doc-pip/DocumentPip.d.ts +44 -0
  99. package/dist/plugins/doc-pip/DocumentPip.d.ts.map +1 -0
  100. package/dist/plugins/doc-pip/index.d.ts +5 -0
  101. package/dist/plugins/doc-pip/index.d.ts.map +1 -0
  102. package/dist/plugins/heatmap/Heatmap.d.ts +36 -0
  103. package/dist/plugins/heatmap/Heatmap.d.ts.map +1 -0
  104. package/dist/plugins/heatmap/index.d.ts +6 -0
  105. package/dist/plugins/heatmap/index.d.ts.map +1 -0
  106. package/dist/plugins/interactive/Interactive.d.ts +45 -0
  107. package/dist/plugins/interactive/Interactive.d.ts.map +1 -0
  108. package/dist/plugins/interactive/index.d.ts +6 -0
  109. package/dist/plugins/interactive/index.d.ts.map +1 -0
  110. package/dist/plugins/markers/MarkProgress.d.ts +3 -1
  111. package/dist/plugins/markers/MarkProgress.d.ts.map +1 -1
  112. package/dist/plugins/playlist/PlaylistRunner.d.ts +2 -0
  113. package/dist/plugins/playlist/PlaylistRunner.d.ts.map +1 -1
  114. package/dist/plugins/redirect-screen/RedirectScreen.d.ts +3 -1
  115. package/dist/plugins/redirect-screen/RedirectScreen.d.ts.map +1 -1
  116. package/dist/plugins/segments/Segments.d.ts +1 -0
  117. package/dist/plugins/segments/Segments.d.ts.map +1 -1
  118. package/dist/plugins/sprite-thumbnails/SpriteThumbnails.d.ts +9 -0
  119. package/dist/plugins/sprite-thumbnails/SpriteThumbnails.d.ts.map +1 -1
  120. package/dist/plugins/sticky/StickyManager.d.ts +2 -0
  121. package/dist/plugins/sticky/StickyManager.d.ts.map +1 -1
  122. package/dist/plugins/transcript/Transcript.d.ts +65 -0
  123. package/dist/plugins/transcript/Transcript.d.ts.map +1 -0
  124. package/dist/plugins/transcript/index.d.ts +6 -0
  125. package/dist/plugins/transcript/index.d.ts.map +1 -0
  126. package/dist/screens/ErrorScreen.d.ts +1 -1
  127. package/dist/screens/ErrorScreen.d.ts.map +1 -1
  128. package/dist/subtitles/attachTracks.d.ts +6 -0
  129. package/dist/subtitles/attachTracks.d.ts.map +1 -1
  130. package/dist/types/index.d.ts +320 -16
  131. package/dist/types/index.d.ts.map +1 -1
  132. package/dist/utils/plugin-style.d.ts +5 -0
  133. package/dist/utils/plugin-style.d.ts.map +1 -0
  134. package/package.json +2 -1
  135. package/dist/chunks/adTriggers-DXmtF4t2.js +0 -410
  136. package/dist/chunks/adTriggers-DXmtF4t2.js.map +0 -1
  137. package/dist/chunks/ads-CdWbE9aD.js.map +0 -1
  138. package/dist/chunks/loopSection-CvF4l5uf.js.map +0 -1
  139. package/dist/chunks/markers-B04NMI79.js.map +0 -1
  140. package/dist/chunks/player-D7WQxMzr.js +0 -3894
  141. package/dist/chunks/player-D7WQxMzr.js.map +0 -1
  142. package/dist/chunks/playlist-C6Mh9BE8.js.map +0 -1
  143. package/dist/chunks/pluginHost-DjvLmMYZ.js +0 -376
  144. package/dist/chunks/pluginHost-DjvLmMYZ.js.map +0 -1
  145. package/dist/chunks/redirectScreen-5HAVRtxe.js +0 -208
  146. package/dist/chunks/redirectScreen-5HAVRtxe.js.map +0 -1
  147. package/dist/chunks/segments-gCPrWRig.js +0 -63
  148. package/dist/chunks/segments-gCPrWRig.js.map +0 -1
  149. package/dist/chunks/spriteThumbnails-B7oDZFTo.js.map +0 -1
  150. package/dist/chunks/statsPanel-DSClIwA3.js.map +0 -1
  151. package/dist/chunks/sticky-D_eLCNFk.js.map +0 -1
@@ -0,0 +1,82 @@
1
+ var w = Object.defineProperty;
2
+ var v = (s, t, e) => t in s ? w(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
+ var d = (s, t, e) => v(s, typeof t != "symbol" ? t + "" : t, e);
4
+ import { c as E } from "./player-D2_HRzot.js";
5
+ import { a as k, c as b } from "./plugin-style-CPJELe-i.js";
6
+ const C = ":host(.hp-docpip){display:block;width:100%;height:100%}:host(.hp-docpip) .hp-root{height:100%}:host(.hp-docpip) .video-area{width:100%;height:100%;aspect-ratio:auto;border-radius:0;background:#000}.hp-docpip-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;width:100%;box-sizing:border-box;padding:16px;border-radius:var(--hp-radius);background:#0b0b0f;color:#fff;font:500 14px/1.4 system-ui,-apple-system,sans-serif;text-align:center}.hp-docpip-btn{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border:0;border-radius:999px;background:#ffffff24;color:#fff;font:600 13px/1 system-ui,-apple-system,sans-serif;cursor:pointer}.hp-docpip-btn:hover{background:#ffffff3d}.hp-docpip-btn:focus-visible{outline:2px solid var(--hp-color-accent, #fff);outline-offset:2px}";
7
+ function A() {
8
+ return window.documentPictureInPicture ?? null;
9
+ }
10
+ class P {
11
+ constructor(t) {
12
+ d(this, "win", null);
13
+ d(this, "placeholder", null);
14
+ d(this, "pipRoot", null);
15
+ d(this, "restore", () => {
16
+ const t = this.placeholder;
17
+ if (!t) return;
18
+ const { videoArea: e } = this.ctx;
19
+ e.removeAttribute("data-docpip"), this.pipRoot && b(this.pipRoot, this.ctx.hostEl.shadowRoot), this.pipRoot = null, t.replaceWith(e), this.placeholder = null, this.win = null, this.ctx.onChange(!1, null);
20
+ });
21
+ this.ctx = t, k(t.rootEl, "doc-pip", C);
22
+ }
23
+ get active() {
24
+ return this.win !== null;
25
+ }
26
+ async open(t) {
27
+ const e = A();
28
+ if (!e || this.win) return !1;
29
+ const n = this.ctx.videoArea.getBoundingClientRect(), c = n.width > 0 && n.height > 0 ? n.height / n.width : 9 / 16, l = Math.round(t.width ?? Math.min(Math.max(n.width, 320), 640)), h = Math.round(t.height ?? l * c), u = await e.requestWindow({ width: l, height: h });
30
+ return this.mount(u), !0;
31
+ }
32
+ close() {
33
+ var t;
34
+ (t = this.win) == null || t.close();
35
+ }
36
+ destroy() {
37
+ if (this.win) {
38
+ const t = this.win;
39
+ this.restore(), t.close();
40
+ }
41
+ }
42
+ mount(t) {
43
+ const e = t.document, { hostEl: n, videoArea: c, rootEl: l } = this.ctx;
44
+ e.title = document.title;
45
+ const h = e.createElement("style");
46
+ h.textContent = "html,body{margin:0;height:100%;background:#000;overflow:hidden}", e.head.appendChild(h);
47
+ const u = document.getElementById("hope-player-icon-font");
48
+ u && e.head.appendChild(u.cloneNode(!0));
49
+ const a = e.createElement("div");
50
+ a.className = "hp-docpip";
51
+ for (const { name: o, value: i } of Array.from(n.attributes)) o.startsWith("data-") && a.setAttribute(o, i);
52
+ const f = getComputedStyle(n);
53
+ for (let o = 0; o < f.length; o++) {
54
+ const i = f[o];
55
+ i.startsWith("--hp-") && a.style.setProperty(i, f.getPropertyValue(i));
56
+ }
57
+ a.style.fontFamily = f.fontFamily;
58
+ const m = a.attachShadow({ mode: "open" }), y = e.createElement("style");
59
+ y.textContent = this.ctx.css;
60
+ const x = e.createElement("div");
61
+ x.className = "hp-root", m.append(y, x), b(n.shadowRoot, m), this.pipRoot = m, e.body.appendChild(a);
62
+ const r = document.createElement("div");
63
+ r.className = "hp-docpip-placeholder", r.setAttribute("part", "pip-placeholder");
64
+ const g = document.createElement("span");
65
+ g.textContent = this.ctx.i18n.pipPlaying;
66
+ const p = document.createElement("button");
67
+ p.type = "button", p.className = "hp-docpip-btn", p.append(E("pip"), document.createTextNode(this.ctx.i18n.pipBack)), p.addEventListener("click", () => this.close()), r.append(g, p), r.style.aspectRatio = `${Math.max(1, c.offsetWidth)} / ${Math.max(1, c.offsetHeight)}`, l.insertBefore(r, c), x.appendChild(c), c.setAttribute("data-docpip", ""), this.placeholder = r, this.win = t, e.addEventListener("keydown", (o) => {
68
+ if (o.defaultPrevented) return;
69
+ const i = o.composedPath()[0];
70
+ i instanceof Element && i.closest("input, textarea, select") || (o.key === " " || o.key === "Enter") && i instanceof Element && i.closest("button") || this.ctx.forwardKey(o) && o.preventDefault();
71
+ }), t.addEventListener("pagehide", this.restore, { once: !0 }), this.ctx.onChange(!0, t);
72
+ }
73
+ }
74
+ function W(s) {
75
+ return new P(s);
76
+ }
77
+ export {
78
+ P as DocumentPip,
79
+ A as documentPipApi,
80
+ W as installDocumentPip
81
+ };
82
+ //# sourceMappingURL=docPip-wybMVP1H.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docPip-wybMVP1H.js","sources":["../../src/plugins/doc-pip/DocumentPip.ts","../../src/plugins/doc-pip/index.ts"],"sourcesContent":["import type { DocumentPipOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { createIcon } from '../../icons/Icon';\nimport { adoptStyle, copyAdoptedStyles } from '../../utils/plugin-style';\nimport css from './doc-pip.css?inline';\n\nexport interface DocumentPipContext {\n hostEl: HTMLElement;\n /** Taşınan katman: video + kontroller + reklam + eklentiler. */\n videoArea: HTMLElement;\n /** videoArea'nın shadow içindeki kabı (.hp-root) — yer tutucu buraya girer. */\n rootEl: HTMLElement;\n css: string;\n i18n: HopeLocaleStrings;\n /** Pencere açıldı / kapandı. */\n onChange(active: boolean, win: Window | null): void;\n /** PiP penceresindeki tuşu player'a ilet; işlendiyse true. */\n forwardKey(e: KeyboardEvent): boolean;\n}\n\ninterface DocPipApi {\n requestWindow(options?: { width?: number; height?: number; disallowReturnToOpener?: boolean }): Promise<Window>;\n window: Window | null;\n}\n\nexport function documentPipApi(): DocPipApi | null {\n return (window as unknown as { documentPictureInPicture?: DocPipApi }).documentPictureInPicture ?? null;\n}\n\n/**\n * Document Picture-in-Picture (Chrome / Edge 116+): oynatıcının video alanı — kontroller, altyazı, menüler, reklam\n * katmanı ve eklentiler — her zaman üstte duran ayrı bir pencereye taşınır. Pencere kapanınca (X, \"geri al\",\n * sayfadan ayrılma) yerine döner. Video elementi aynı kalır: oynatma, tampon ve reklam durumu kesilmez.\n */\nexport class DocumentPip {\n private win: Window | null = null;\n private placeholder: HTMLElement | null = null;\n\n private pipRoot: ShadowRoot | null = null;\n\n constructor(private readonly ctx: DocumentPipContext) {\n adoptStyle(ctx.rootEl, 'doc-pip', css);\n }\n\n get active(): boolean {\n return this.win !== null;\n }\n\n async open(options: DocumentPipOptions): Promise<boolean> {\n const api = documentPipApi();\n if (!api || this.win) return false;\n const rect = this.ctx.videoArea.getBoundingClientRect();\n const ratio = rect.width > 0 && rect.height > 0 ? rect.height / rect.width : 9 / 16;\n const width = Math.round(options.width ?? Math.min(Math.max(rect.width, 320), 640));\n const height = Math.round(options.height ?? width * ratio);\n const win = await api.requestWindow({ width, height });\n this.mount(win);\n return true;\n }\n\n close(): void {\n this.win?.close();\n }\n\n destroy(): void {\n if (this.win) {\n const win = this.win;\n this.restore();\n win.close();\n }\n }\n\n private mount(win: Window): void {\n const doc = win.document;\n const { hostEl, videoArea, rootEl } = this.ctx;\n doc.title = document.title;\n const base = doc.createElement('style');\n base.textContent = 'html,body{margin:0;height:100%;background:#000;overflow:hidden}';\n doc.head.appendChild(base);\n // İkon fontu belge başına enjekte edilir (Shadow DOM'da @font-face çalışmıyor).\n const iconFont = document.getElementById('hope-player-icon-font');\n if (iconFont) doc.head.appendChild(iconFont.cloneNode(true));\n\n const host = doc.createElement('div');\n host.className = 'hp-docpip';\n // Tema ve sayfadan gelen token'lar (`hope-player { --hp-color-accent: … }`) pencereye de geçsin.\n for (const { name, value } of Array.from(hostEl.attributes)) if (name.startsWith('data-')) host.setAttribute(name, value);\n const computed = getComputedStyle(hostEl);\n for (let i = 0; i < computed.length; i++) {\n const prop = computed[i]!;\n if (prop.startsWith('--hp-')) host.style.setProperty(prop, computed.getPropertyValue(prop));\n }\n host.style.fontFamily = computed.fontFamily;\n const shadow = host.attachShadow({ mode: 'open' });\n const style = doc.createElement('style');\n style.textContent = this.ctx.css;\n const wrap = doc.createElement('div');\n wrap.className = 'hp-root';\n shadow.append(style, wrap);\n // Eklentilerin sonradan eklenen stilleri (transkript, etkileşimli…) pencereye de.\n copyAdoptedStyles(hostEl.shadowRoot!, shadow);\n this.pipRoot = shadow;\n doc.body.appendChild(host);\n\n const placeholder = document.createElement('div');\n placeholder.className = 'hp-docpip-placeholder';\n placeholder.setAttribute('part', 'pip-placeholder');\n const text = document.createElement('span');\n text.textContent = this.ctx.i18n.pipPlaying;\n const back = document.createElement('button');\n back.type = 'button';\n back.className = 'hp-docpip-btn';\n back.append(createIcon('pip'), document.createTextNode(this.ctx.i18n.pipBack));\n back.addEventListener('click', () => this.close());\n placeholder.append(text, back);\n // Yer tutucu oynatıcının boyutunu korur — sayfa düzeni kaymasın.\n placeholder.style.aspectRatio = `${Math.max(1, videoArea.offsetWidth)} / ${Math.max(1, videoArea.offsetHeight)}`;\n\n // Taşıma tek adımda (appendChild) — video oynamaya devam eder.\n rootEl.insertBefore(placeholder, videoArea);\n wrap.appendChild(videoArea);\n videoArea.setAttribute('data-docpip', '');\n this.placeholder = placeholder;\n this.win = win;\n\n doc.addEventListener('keydown', (e) => {\n if (e.defaultPrevented) return;\n const t = e.composedPath()[0];\n // Odaktaki buton / alan tuşu kendisi işlesin.\n if (t instanceof Element && t.closest('input, textarea, select')) return;\n if ((e.key === ' ' || e.key === 'Enter') && t instanceof Element && t.closest('button')) return;\n if (this.ctx.forwardKey(e)) e.preventDefault();\n });\n win.addEventListener('pagehide', this.restore, { once: true });\n this.ctx.onChange(true, win);\n }\n\n private readonly restore = (): void => {\n const placeholder = this.placeholder;\n if (!placeholder) return;\n const { videoArea } = this.ctx;\n videoArea.removeAttribute('data-docpip');\n // Pencere açıkken kurulan eklentilerin stilleri sayfaya dönsün.\n if (this.pipRoot) copyAdoptedStyles(this.pipRoot, this.ctx.hostEl.shadowRoot!);\n this.pipRoot = null;\n placeholder.replaceWith(videoArea);\n this.placeholder = null;\n this.win = null;\n this.ctx.onChange(false, null);\n };\n}\n","import { DocumentPip, documentPipApi, type DocumentPipContext } from './DocumentPip';\n\nexport function installDocumentPip(ctx: DocumentPipContext): DocumentPip {\n return new DocumentPip(ctx);\n}\n\nexport { DocumentPip, documentPipApi };\nexport type { DocumentPipContext };\n"],"names":["documentPipApi","DocumentPip","ctx","__publicField","placeholder","videoArea","copyAdoptedStyles","adoptStyle","css","options","api","rect","ratio","width","height","win","_a","doc","hostEl","rootEl","base","iconFont","host","name","value","computed","i","prop","shadow","style","wrap","text","back","createIcon","e","t","installDocumentPip"],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ var b = Object.defineProperty;
2
+ var E = (s, t, e) => t in s ? b(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
+ var r = (s, t, e) => E(s, typeof t != "symbol" ? t + "" : t, e);
4
+ import { a as g } from "./plugin-style-CPJELe-i.js";
5
+ const L = ".hp-heatmap{position:absolute;left:0;right:0;bottom:50%;height:var(--hp-heatmap-h, 36px);pointer-events:none;opacity:0;transition:opacity .2s ease}.hp-heatmap[hidden]{display:none}.hp-heatmap[data-show=always],.hp-seekbar:hover .hp-heatmap,.hp-seekbar:focus-visible .hp-heatmap{opacity:1}.hp-heatmap-base,.hp-heatmap-played{position:absolute;top:0;right:0;bottom:0;left:0}.hp-heatmap svg{display:block;filter:drop-shadow(0 0 1.5px rgba(0,0,0,.25));width:100%;height:100%}.hp-heatmap-base path{fill:color-mix(in srgb,var(--hp-color-on-surface) 28%,transparent)}.hp-heatmap-played{clip-path:inset(0 calc(100% - var(--hp-heatmap-p, 0%)) 0 0)}.hp-heatmap-played path{fill:color-mix(in srgb,var(--hp-color-accent, #fff) 60%,transparent)}", m = "http://www.w3.org/2000/svg", d = 1e3, p = 100;
6
+ function w(s) {
7
+ const t = s.map((a) => Number.isFinite(a) && a > 0 ? a : 0), e = Math.max(0, ...t);
8
+ return e > 0 ? t.map((a) => a / e) : t;
9
+ }
10
+ function A(s) {
11
+ const t = s.length;
12
+ if (!t) return "";
13
+ const e = s.map((i, o) => [(o + 0.5) / t * d, p - i * p * 0.92]);
14
+ e.unshift([0, e[0][1]]), e.push([d, e[e.length - 1][1]]);
15
+ let a = `M0 ${p}L${e[0][0]} ${e[0][1].toFixed(1)}`;
16
+ for (let i = 0; i < e.length - 1; i++) {
17
+ const o = e[i - 1] ?? e[i], n = e[i], h = e[i + 1], l = e[i + 2] ?? h, u = Math.min(p, Math.max(0, n[1] + (h[1] - o[1]) / 6)), v = Math.min(p, Math.max(0, h[1] - (l[1] - n[1]) / 6)), f = n[0] + (h[0] - o[0]) / 6, y = h[0] - (l[0] - n[0]) / 6;
18
+ a += `C${f.toFixed(1)} ${u.toFixed(1)} ${y.toFixed(1)} ${v.toFixed(1)} ${h[0].toFixed(1)} ${h[1].toFixed(1)}`;
19
+ }
20
+ return `${a}L${d} ${p}Z`;
21
+ }
22
+ function c(s) {
23
+ const t = document.createElement("div");
24
+ t.className = s;
25
+ const e = document.createElementNS(m, "svg");
26
+ e.setAttribute("viewBox", `0 0 ${d} ${p}`), e.setAttribute("preserveAspectRatio", "none"), e.setAttribute("aria-hidden", "true");
27
+ const a = document.createElementNS(m, "path");
28
+ return e.appendChild(a), t.appendChild(e), { el: t, path: a };
29
+ }
30
+ class x {
31
+ constructor(t, e) {
32
+ r(this, "el");
33
+ r(this, "base");
34
+ r(this, "played");
35
+ r(this, "destroyed", !1);
36
+ r(this, "rafId", null);
37
+ r(this, "startLoop", () => {
38
+ if (this.rafId !== null) return;
39
+ const t = () => {
40
+ this.onTime(), this.rafId = requestAnimationFrame(t);
41
+ };
42
+ this.rafId = requestAnimationFrame(t);
43
+ });
44
+ r(this, "stopLoop", () => {
45
+ this.rafId !== null && cancelAnimationFrame(this.rafId), this.rafId = null, this.onTime();
46
+ });
47
+ r(this, "onDuration", () => {
48
+ const t = this.ctx.videoEl.duration;
49
+ this.el.hidden = !Number.isFinite(t) || t <= 0 || this.el.hasAttribute("data-empty") || !this.base.getAttribute("d"), this.onTime();
50
+ });
51
+ r(this, "onTime", () => {
52
+ const t = this.ctx.videoEl, e = Number.isFinite(t.duration) && t.duration > 0 ? Math.min(1, Math.max(0, t.currentTime / t.duration)) : 0;
53
+ this.el.hidden || this.el.style.setProperty("--hp-heatmap-p", `${(e * 100).toFixed(3)}%`);
54
+ });
55
+ var n;
56
+ this.ctx = t, this.options = e, g(t.seekBar.el, "heatmap", L);
57
+ const a = document.createElement("div");
58
+ a.className = "hp-heatmap", a.setAttribute("part", "heatmap"), a.setAttribute("aria-hidden", "true"), a.setAttribute("data-show", e.show === "always" ? "always" : "hover"), e.height && a.style.setProperty("--hp-heatmap-h", `${Math.max(8, e.height)}px`);
59
+ const i = c("hp-heatmap-base"), o = c("hp-heatmap-played");
60
+ a.append(i.el, o.el), this.el = a, this.base = i.path, this.played = o.path, a.hidden = !0, t.seekBar.el.prepend(a), t.videoEl.addEventListener("timeupdate", this.onTime), t.videoEl.addEventListener("seeking", this.onTime), t.videoEl.addEventListener("play", this.startLoop), t.videoEl.addEventListener("pause", this.stopLoop), t.videoEl.addEventListener("ended", this.stopLoop), t.videoEl.paused || this.startLoop(), t.videoEl.addEventListener("durationchange", this.onDuration), t.videoEl.addEventListener("loadedmetadata", this.onDuration), (n = e.data) != null && n.length ? this.setData(e.data) : e.src && this.fetchData(e.src);
61
+ }
62
+ /** Yeni değerler (ör. sunucudan güncel istatistik). */
63
+ setData(t) {
64
+ const e = A(w(t));
65
+ this.base.setAttribute("d", e), this.played.setAttribute("d", e), this.el.toggleAttribute("data-empty", !e), this.onDuration();
66
+ }
67
+ destroy() {
68
+ this.destroyed = !0;
69
+ const t = this.ctx.videoEl;
70
+ t.removeEventListener("timeupdate", this.onTime), t.removeEventListener("seeking", this.onTime), t.removeEventListener("durationchange", this.onDuration), t.removeEventListener("loadedmetadata", this.onDuration), t.removeEventListener("play", this.startLoop), t.removeEventListener("pause", this.stopLoop), t.removeEventListener("ended", this.stopLoop), this.stopLoop(), this.el.remove();
71
+ }
72
+ async fetchData(t) {
73
+ var e, a;
74
+ try {
75
+ const i = await fetch(t);
76
+ if (!i.ok) throw new Error(`HTTP ${i.status}`);
77
+ const o = await i.json(), n = Array.isArray(o) ? o : o == null ? void 0 : o.data;
78
+ if (!Array.isArray(n)) throw new Error("number[] bekleniyordu");
79
+ this.destroyed || this.setData(n.map(Number));
80
+ } catch (i) {
81
+ (a = (e = this.ctx).log) == null || a.call(e, { message: `Heatmap data could not be loaded: ${String(i)}`, details: { src: t } });
82
+ }
83
+ }
84
+ }
85
+ function D(s, t) {
86
+ return new x(s, t);
87
+ }
88
+ export {
89
+ x as Heatmap,
90
+ D as installHeatmap
91
+ };
92
+ //# sourceMappingURL=heatmap-Bb7neaYU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heatmap-Bb7neaYU.js","sources":["../../src/plugins/heatmap/Heatmap.ts","../../src/plugins/heatmap/index.ts"],"sourcesContent":["import type { HeatmapOptions } from '../../types';\nimport { adoptStyle } from '../../utils/plugin-style';\nimport css from './heatmap.css?inline';\n\nexport interface HeatmapPlayerContext {\n videoEl: HTMLVideoElement;\n seekBar: { readonly el: HTMLElement };\n log?: (entry: { message: string; details?: Record<string, string> }) => void;\n}\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\nconst W = 1000;\nconst H = 100;\n\n/** Değerleri 0–1'e indirger (en yüksek = 1); geçersizler 0. */\nfunction normalize(values: number[]): number[] {\n const clean = values.map((v) => (Number.isFinite(v) && v > 0 ? v : 0));\n const max = Math.max(0, ...clean);\n return max > 0 ? clean.map((v) => v / max) : clean;\n}\n\n/** Noktalardan yumuşak (Catmull-Rom → Bezier) kapalı alan yolu; tabanı seek bar çizgisi. */\nexport function heatmapPath(values: number[]): string {\n const n = values.length;\n if (!n) return '';\n const pts: [number, number][] = values.map((v, i) => [((i + 0.5) / n) * W, H - v * H * 0.92]);\n pts.unshift([0, pts[0]![1]]);\n pts.push([W, pts[pts.length - 1]![1]]);\n let d = `M0 ${H}L${pts[0]![0]} ${pts[0]![1].toFixed(1)}`;\n for (let i = 0; i < pts.length - 1; i++) {\n const p0 = pts[i - 1] ?? pts[i]!;\n const p1 = pts[i]!;\n const p2 = pts[i + 1]!;\n const p3 = pts[i + 2] ?? p2;\n // Kontrol noktaları tabanın altına / tepenin üstüne taşmasın.\n const c1y = Math.min(H, Math.max(0, p1[1] + (p2[1] - p0[1]) / 6));\n const c2y = Math.min(H, Math.max(0, p2[1] - (p3[1] - p1[1]) / 6));\n const c1x = p1[0] + (p2[0] - p0[0]) / 6;\n const c2x = p2[0] - (p3[0] - p1[0]) / 6;\n d += `C${c1x.toFixed(1)} ${c1y.toFixed(1)} ${c2x.toFixed(1)} ${c2y.toFixed(1)} ${p2[0].toFixed(1)} ${p2[1].toFixed(1)}`;\n }\n return `${d}L${W} ${H}Z`;\n}\n\nfunction layer(className: string): { el: HTMLDivElement; path: SVGPathElement } {\n const el = document.createElement('div');\n el.className = className;\n const svg = document.createElementNS(SVG_NS, 'svg');\n svg.setAttribute('viewBox', `0 0 ${W} ${H}`);\n svg.setAttribute('preserveAspectRatio', 'none');\n svg.setAttribute('aria-hidden', 'true');\n const path = document.createElementNS(SVG_NS, 'path');\n svg.appendChild(path);\n el.appendChild(svg);\n return { el, path };\n}\n\n/**\n * \"En çok izlenen\" ısı haritası: seek bar'ın hemen üstünde yoğunluk eğrisi. Değerler videoya eşit aralıklarla\n * yayılır; izlenen kısım vurgu rengiyle dolar. Canlı yayında (süre bilinmiyorsa) gizlenir.\n */\nexport class Heatmap {\n private readonly el: HTMLDivElement;\n private readonly base: SVGPathElement;\n private readonly played: SVGPathElement;\n private destroyed = false;\n\n constructor(\n private readonly ctx: HeatmapPlayerContext,\n private readonly options: HeatmapOptions\n ) {\n adoptStyle(ctx.seekBar.el, 'heatmap', css);\n const el = document.createElement('div');\n el.className = 'hp-heatmap';\n el.setAttribute('part', 'heatmap');\n el.setAttribute('aria-hidden', 'true');\n el.setAttribute('data-show', options.show === 'always' ? 'always' : 'hover');\n if (options.height) el.style.setProperty('--hp-heatmap-h', `${Math.max(8, options.height)}px`);\n const base = layer('hp-heatmap-base');\n const played = layer('hp-heatmap-played');\n el.append(base.el, played.el);\n this.el = el;\n this.base = base.path;\n this.played = played.path;\n el.hidden = true;\n ctx.seekBar.el.prepend(el);\n\n ctx.videoEl.addEventListener('timeupdate', this.onTime);\n ctx.videoEl.addEventListener('seeking', this.onTime);\n // Oynarken her karede güncellenir — seek bar'daki ilerleme gibi akıcı.\n ctx.videoEl.addEventListener('play', this.startLoop);\n ctx.videoEl.addEventListener('pause', this.stopLoop);\n ctx.videoEl.addEventListener('ended', this.stopLoop);\n if (!ctx.videoEl.paused) this.startLoop();\n ctx.videoEl.addEventListener('durationchange', this.onDuration);\n ctx.videoEl.addEventListener('loadedmetadata', this.onDuration);\n\n if (options.data?.length) this.setData(options.data);\n else if (options.src) void this.fetchData(options.src);\n }\n\n /** Yeni değerler (ör. sunucudan güncel istatistik). */\n setData(values: number[]): void {\n const d = heatmapPath(normalize(values));\n this.base.setAttribute('d', d);\n this.played.setAttribute('d', d);\n this.el.toggleAttribute('data-empty', !d);\n this.onDuration();\n }\n\n destroy(): void {\n this.destroyed = true;\n const v = this.ctx.videoEl;\n v.removeEventListener('timeupdate', this.onTime);\n v.removeEventListener('seeking', this.onTime);\n v.removeEventListener('durationchange', this.onDuration);\n v.removeEventListener('loadedmetadata', this.onDuration);\n v.removeEventListener('play', this.startLoop);\n v.removeEventListener('pause', this.stopLoop);\n v.removeEventListener('ended', this.stopLoop);\n this.stopLoop();\n this.el.remove();\n }\n\n private rafId: number | null = null;\n\n private readonly startLoop = (): void => {\n if (this.rafId !== null) return;\n const tick = (): void => {\n this.onTime();\n this.rafId = requestAnimationFrame(tick);\n };\n this.rafId = requestAnimationFrame(tick);\n };\n\n private readonly stopLoop = (): void => {\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.rafId = null;\n this.onTime();\n };\n\n private async fetchData(src: string): Promise<void> {\n try {\n const res = await fetch(src);\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const json: unknown = await res.json();\n const values = Array.isArray(json) ? json : (json as { data?: unknown })?.data;\n if (!Array.isArray(values)) throw new Error('number[] bekleniyordu');\n if (!this.destroyed) this.setData(values.map(Number));\n } catch (err) {\n this.ctx.log?.({ message: `Heatmap data could not be loaded: ${String(err)}`, details: { src } });\n }\n }\n\n private readonly onDuration = (): void => {\n const d = this.ctx.videoEl.duration;\n this.el.hidden = !Number.isFinite(d) || d <= 0 || this.el.hasAttribute('data-empty') || !this.base.getAttribute('d');\n this.onTime();\n };\n\n private readonly onTime = (): void => {\n const v = this.ctx.videoEl;\n const ratio = Number.isFinite(v.duration) && v.duration > 0 ? Math.min(1, Math.max(0, v.currentTime / v.duration)) : 0;\n // Gizliyken (canlı yayın / veri yok) stil yazma.\n if (this.el.hidden) return;\n this.el.style.setProperty('--hp-heatmap-p', `${(ratio * 100).toFixed(3)}%`);\n };\n}\n","import { Heatmap, type HeatmapPlayerContext } from './Heatmap';\nimport type { HeatmapOptions } from '../../types';\n\nexport function installHeatmap(ctx: HeatmapPlayerContext, options: HeatmapOptions): Heatmap {\n return new Heatmap(ctx, options);\n}\n\nexport { Heatmap };\nexport type { HeatmapPlayerContext };\n"],"names":["SVG_NS","W","H","normalize","values","clean","v","max","heatmapPath","n","pts","i","d","p0","p1","p2","p3","c1y","c2y","c1x","c2x","layer","className","el","svg","path","Heatmap","ctx","options","__publicField","tick","ratio","adoptStyle","css","base","played","_a","src","res","json","err","_b","installHeatmap"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  var m = Object.defineProperty;
2
2
  var v = (n, t, e) => t in n ? m(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
3
  var s = (n, t, e) => v(n, typeof t != "symbol" ? t + "" : t, e);
4
- import { f as E } from "./player-D7WQxMzr.js";
4
+ import { f as E } from "./player-D2_HRzot.js";
5
5
  import { s as p } from "./seekWhenReady-Clzne3-S.js";
6
6
  const d = "hp-history-positions", c = "hp-history-volume", y = 10, f = 15, L = 50, k = 30, T = 5e3, N = 6e3;
7
7
  class x {
@@ -141,4 +141,4 @@ export {
141
141
  x as PlaybackHistory,
142
142
  w as installHistory
143
143
  };
144
- //# sourceMappingURL=history-DAbqEhNB.js.map
144
+ //# sourceMappingURL=history-CwqLXiZi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"history-DAbqEhNB.js","sources":["../../src/plugins/history/PlaybackHistory.ts","../../src/plugins/history/index.ts"],"sourcesContent":["import type { HistoryOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { formatTime } from '../../utils/format-time';\nimport { seekWhenReady } from '../shared/seekWhenReady';\n\nexport interface HistoryPlayerContext {\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n overlayContainerEl: HTMLElement;\n i18n: HopeLocaleStrings;\n /** Şu an yüklü kaynağın adresi (hls.js'te blob değil gerçek .m3u8) — `id` verilmezse videonun anahtarı. */\n currentSrc(): string | null;\n isAdActive(): boolean;\n /** `options.muted` — otomatik oynatma için sessiz istendiyse hatırlanan \"sesli\" durumu onu bozmasın. */\n mutedRequested(): boolean;\n /** QR ile devam (`?vtime=`) bu sayfa açılışında bir konum getirdiyse — ilk yüklemede o kazanır. */\n linkTimePresent: boolean;\n}\n\nconst POSITIONS_KEY = 'hp-history-positions';\nconst VOLUME_KEY = 'hp-history-volume';\n/** Bu kadar saniye izlenmeden konum kaydedilmez (yanlışlıkla açılan video). */\nconst DEFAULT_MIN_WATCHED = 10;\n/** Sona bu kadar kala \"bitti\" sayılır — kayıt silinir, sonraki açılışta baştan başlar. */\nconst DEFAULT_END_MARGIN = 15;\nconst DEFAULT_MAX_ENTRIES = 50;\nconst DEFAULT_TTL_DAYS = 30;\n/** Oynarken konum en fazla bu sıklıkla yazılır (ms). */\nconst SAVE_EVERY_MS = 5000;\nconst NOTICE_MS = 6000;\n\ninterface Entry {\n t: number;\n d: number;\n at: number;\n}\n\n/**\n * Zaman ve ses geçmişi: video yarıda bırakılırsa bir sonraki açılışta kaldığı yerden başlar (\"Kaldığınız yerden devam:\n * 0:42 · Baştan başla\" bildirimiyle); ses seviyesi ve sessiz durumu sitede hatırlanır. Kayıtlar tarayıcıda (localStorage).\n * Canlı yayında, reklam sırasında ve sona yakın konumda kayıt yapılmaz.\n */\nexport class PlaybackHistory {\n private key: string | null = null;\n private lastSaveAt = 0;\n private noticeEl: HTMLDivElement | null = null;\n private noticeTimer: ReturnType<typeof setTimeout> | null = null;\n private skipNextRestore: boolean;\n private readonly position: boolean;\n private readonly volume: boolean;\n private readonly minWatched: number;\n private readonly endMargin: number;\n\n constructor(\n private readonly ctx: HistoryPlayerContext,\n private readonly options: HistoryOptions\n ) {\n this.position = options.position !== false;\n this.volume = options.volume !== false;\n this.minWatched = options.minWatched ?? DEFAULT_MIN_WATCHED;\n this.endMargin = options.endMargin ?? DEFAULT_END_MARGIN;\n this.skipNextRestore = ctx.linkTimePresent;\n\n const v = ctx.videoEl;\n if (this.volume) {\n this.restoreVolume();\n v.addEventListener('volumechange', this.saveVolume);\n }\n if (this.position) {\n v.addEventListener('loadedmetadata', this.onLoadedMetadata);\n v.addEventListener('timeupdate', this.onTimeUpdate);\n v.addEventListener('pause', this.savePosition);\n v.addEventListener('seeked', this.savePosition);\n v.addEventListener('ended', this.onEnded);\n window.addEventListener('pagehide', this.savePosition);\n document.addEventListener('visibilitychange', this.onVisibility);\n if (v.readyState >= 1) this.onLoadedMetadata();\n }\n }\n\n destroy(): void {\n const v = this.ctx.videoEl;\n this.savePosition();\n v.removeEventListener('volumechange', this.saveVolume);\n v.removeEventListener('loadedmetadata', this.onLoadedMetadata);\n v.removeEventListener('timeupdate', this.onTimeUpdate);\n v.removeEventListener('pause', this.savePosition);\n v.removeEventListener('seeked', this.savePosition);\n v.removeEventListener('ended', this.onEnded);\n window.removeEventListener('pagehide', this.savePosition);\n document.removeEventListener('visibilitychange', this.onVisibility);\n this.hideNotice();\n }\n\n refreshLabels(): void {\n this.hideNotice();\n }\n\n // ── Konum ──\n\n private videoKey(): string | null {\n if (this.options.id) return `id:${this.options.id}`;\n const src = this.ctx.currentSrc();\n if (!src || src.startsWith('blob:') || src.startsWith('data:')) return null;\n try {\n const u = new URL(src, location.href);\n u.hash = '';\n return u.href;\n } catch {\n return src;\n }\n }\n\n private readonly onLoadedMetadata = (): void => {\n const v = this.ctx.videoEl;\n this.key = this.videoKey();\n this.lastSaveAt = 0;\n if (!this.key || !Number.isFinite(v.duration)) return;\n // Link ile gelen konum (QR ile devam) yalnızca bu açılışta kazanır.\n if (this.skipNextRestore) {\n this.skipNextRestore = false;\n return;\n }\n // Başka bir şey zaten sarmışsa (ör. kaynak değişiminde korunan konum) dokunma.\n if (v.currentTime > 1) return;\n const entry = this.entries()[this.key];\n if (!entry || entry.t < this.minWatched || entry.t > v.duration - this.endMargin) return;\n seekWhenReady(v, entry.t, { attempts: 2 });\n this.showNotice(entry.t);\n this.emit('resumed', entry.t);\n };\n\n private readonly onTimeUpdate = (): void => {\n if (Date.now() - this.lastSaveAt < SAVE_EVERY_MS) return;\n this.savePosition();\n };\n\n private readonly onVisibility = (): void => {\n if (document.visibilityState === 'hidden') this.savePosition();\n };\n\n private readonly savePosition = (): void => {\n const v = this.ctx.videoEl;\n if (!this.key || this.ctx.isAdActive() || v.seeking) return;\n const d = v.duration;\n if (!Number.isFinite(d) || d <= 0) return; // canlı yayın\n this.lastSaveAt = Date.now();\n const t = v.currentTime;\n const all = this.entries();\n if (t >= d - this.endMargin) delete all[this.key];\n else if (t >= this.minWatched) all[this.key] = { t: Math.floor(t), d: Math.round(d), at: Date.now() };\n else return;\n this.store(all);\n };\n\n private readonly onEnded = (): void => {\n if (!this.key) return;\n const all = this.entries();\n delete all[this.key];\n this.store(all);\n };\n\n /** Süresi geçenleri at, en yeni `maxEntries` kaydı tut. */\n private store(all: Record<string, Entry>): void {\n const ttl = (this.options.ttlDays ?? DEFAULT_TTL_DAYS) * 86_400_000;\n const max = this.options.maxEntries ?? DEFAULT_MAX_ENTRIES;\n const now = Date.now();\n const kept = Object.entries(all)\n .filter(([, e]) => now - e.at < ttl)\n .sort((a, b) => b[1].at - a[1].at)\n .slice(0, max);\n write(POSITIONS_KEY, Object.fromEntries(kept));\n }\n\n private entries(): Record<string, Entry> {\n const raw = read<Record<string, Entry>>(POSITIONS_KEY);\n return raw && typeof raw === 'object' ? raw : {};\n }\n\n // ── Ses ──\n\n private restoreVolume(): void {\n const saved = read<{ volume: number; muted: boolean }>(VOLUME_KEY);\n if (!saved || typeof saved.volume !== 'number') return;\n const v = this.ctx.videoEl;\n v.volume = Math.min(1, Math.max(0, saved.volume));\n // Sessiz otomatik oynatma istendiyse (options.muted) \"sesli\" kaydı onu bozmasın; kullanıcı sessize aldıysa korunur.\n v.muted = this.ctx.mutedRequested() || !!saved.muted;\n }\n\n private readonly saveVolume = (): void => {\n if (this.ctx.isAdActive()) return;\n const v = this.ctx.videoEl;\n write(VOLUME_KEY, { volume: Math.round(v.volume * 100) / 100, muted: v.muted });\n };\n\n // ── Bildirim ──\n\n private showNotice(time: number): void {\n if (this.options.notice === false) return;\n this.hideNotice();\n const t = this.ctx.i18n;\n const el = document.createElement('div');\n el.className = 'hp-history-notice';\n el.setAttribute('part', 'history-notice');\n el.setAttribute('role', 'status');\n const text = document.createElement('span');\n text.textContent = t.historyResumed(formatTime(time));\n const restart = document.createElement('button');\n restart.type = 'button';\n restart.className = 'hp-history-restart';\n restart.textContent = t.historyRestart;\n restart.addEventListener('click', () => {\n const v = this.ctx.videoEl;\n v.currentTime = 0;\n if (this.key) {\n const all = this.entries();\n delete all[this.key];\n this.store(all);\n }\n this.emit('restart', 0);\n this.hideNotice();\n });\n el.append(text, restart);\n // Bildirimdeki tıklama oynat / duraklat'a geçmesin.\n for (const ev of ['pointerdown', 'mousedown', 'mouseup', 'touchstart', 'touchend', 'click', 'dblclick'] as const) el.addEventListener(ev, (e) => e.stopPropagation());\n this.ctx.overlayContainerEl.appendChild(el);\n this.noticeEl = el;\n this.noticeTimer = setTimeout(() => this.hideNotice(), NOTICE_MS);\n }\n\n private hideNotice(): void {\n if (this.noticeTimer) clearTimeout(this.noticeTimer);\n this.noticeTimer = null;\n this.noticeEl?.remove();\n this.noticeEl = null;\n }\n\n private emit(state: 'resumed' | 'restart', time: number): void {\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:history', { detail: { state, time, id: this.key } }));\n }\n}\n\nfunction read<T>(key: string): T | null {\n try {\n return JSON.parse(localStorage.getItem(key) ?? 'null') as T | null;\n } catch {\n return null;\n }\n}\n\nfunction write(key: string, value: unknown): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* gizli sekme / kota dolu — geçmiş yalnızca bu oturumda yok */\n }\n}\n","import { PlaybackHistory, type HistoryPlayerContext } from './PlaybackHistory';\nimport type { HistoryOptions } from '../../types';\n\nexport function installHistory(ctx: HistoryPlayerContext, options: HistoryOptions): PlaybackHistory {\n return new PlaybackHistory(ctx, options);\n}\n\nexport { PlaybackHistory };\nexport type { HistoryPlayerContext };\n"],"names":["POSITIONS_KEY","VOLUME_KEY","DEFAULT_MIN_WATCHED","DEFAULT_END_MARGIN","DEFAULT_MAX_ENTRIES","DEFAULT_TTL_DAYS","SAVE_EVERY_MS","NOTICE_MS","PlaybackHistory","ctx","options","__publicField","v","entry","seekWhenReady","d","t","all","write","src","u","ttl","max","now","kept","e","b","raw","read","saved","time","el","text","formatTime","restart","ev","_a","state","key","value","installHistory"],"mappings":";;;;;AAmBA,MAAMA,IAAgB,wBAChBC,IAAa,qBAEbC,IAAsB,IAEtBC,IAAqB,IACrBC,IAAsB,IACtBC,IAAmB,IAEnBC,IAAgB,KAChBC,IAAY;AAaX,MAAMC,EAAgB;AAAA,EAWzB,YACqBC,GACAC,GACnB;AAbM,IAAAC,EAAA,aAAqB;AACrB,IAAAA,EAAA,oBAAa;AACb,IAAAA,EAAA,kBAAkC;AAClC,IAAAA,EAAA,qBAAoD;AACpD,IAAAA,EAAA;AACS,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AA8DA,IAAAA,EAAA,0BAAmB,MAAY;AAC5C,YAAMC,IAAI,KAAK,IAAI;AAGnB,UAFA,KAAK,MAAM,KAAK,SAAA,GAChB,KAAK,aAAa,GACd,CAAC,KAAK,OAAO,CAAC,OAAO,SAASA,EAAE,QAAQ,EAAG;AAE/C,UAAI,KAAK,iBAAiB;AACtB,aAAK,kBAAkB;AACvB;AAAA,MACJ;AAEA,UAAIA,EAAE,cAAc,EAAG;AACvB,YAAMC,IAAQ,KAAK,QAAA,EAAU,KAAK,GAAG;AACrC,MAAI,CAACA,KAASA,EAAM,IAAI,KAAK,cAAcA,EAAM,IAAID,EAAE,WAAW,KAAK,cACvEE,EAAcF,GAAGC,EAAM,GAAG,EAAE,UAAU,GAAG,GACzC,KAAK,WAAWA,EAAM,CAAC,GACvB,KAAK,KAAK,WAAWA,EAAM,CAAC;AAAA,IAChC;AAEiB,IAAAF,EAAA,sBAAe,MAAY;AACxC,MAAI,KAAK,IAAA,IAAQ,KAAK,aAAaL,KACnC,KAAK,aAAA;AAAA,IACT;AAEiB,IAAAK,EAAA,sBAAe,MAAY;AACxC,MAAI,SAAS,oBAAoB,YAAU,KAAK,aAAA;AAAA,IACpD;AAEiB,IAAAA,EAAA,sBAAe,MAAY;AACxC,YAAMC,IAAI,KAAK,IAAI;AACnB,UAAI,CAAC,KAAK,OAAO,KAAK,IAAI,WAAA,KAAgBA,EAAE,QAAS;AACrD,YAAMG,IAAIH,EAAE;AACZ,UAAI,CAAC,OAAO,SAASG,CAAC,KAAKA,KAAK,EAAG;AACnC,WAAK,aAAa,KAAK,IAAA;AACvB,YAAMC,IAAIJ,EAAE,aACNK,IAAM,KAAK,QAAA;AACjB,UAAID,KAAKD,IAAI,KAAK,UAAW,QAAOE,EAAI,KAAK,GAAG;AAAA,eACvCD,KAAK,KAAK,WAAY,CAAAC,EAAI,KAAK,GAAG,IAAI,EAAE,GAAG,KAAK,MAAMD,CAAC,GAAG,GAAG,KAAK,MAAMD,CAAC,GAAG,IAAI,KAAK,MAAI;AAAA,UAC7F;AACL,WAAK,MAAME,CAAG;AAAA,IAClB;AAEiB,IAAAN,EAAA,iBAAU,MAAY;AACnC,UAAI,CAAC,KAAK,IAAK;AACf,YAAMM,IAAM,KAAK,QAAA;AACjB,aAAOA,EAAI,KAAK,GAAG,GACnB,KAAK,MAAMA,CAAG;AAAA,IAClB;AA8BiB,IAAAN,EAAA,oBAAa,MAAY;AACtC,UAAI,KAAK,IAAI,aAAc;AAC3B,YAAMC,IAAI,KAAK,IAAI;AACnB,MAAAM,EAAMjB,GAAY,EAAE,QAAQ,KAAK,MAAMW,EAAE,SAAS,GAAG,IAAI,KAAK,OAAOA,EAAE,OAAO;AAAA,IAClF;AA5IqB,SAAA,MAAAH,GACA,KAAA,UAAAC,GAEjB,KAAK,WAAWA,EAAQ,aAAa,IACrC,KAAK,SAASA,EAAQ,WAAW,IACjC,KAAK,aAAaA,EAAQ,cAAcR,GACxC,KAAK,YAAYQ,EAAQ,aAAaP,GACtC,KAAK,kBAAkBM,EAAI;AAE3B,UAAMG,IAAIH,EAAI;AACd,IAAI,KAAK,WACL,KAAK,cAAA,GACLG,EAAE,iBAAiB,gBAAgB,KAAK,UAAU,IAElD,KAAK,aACLA,EAAE,iBAAiB,kBAAkB,KAAK,gBAAgB,GAC1DA,EAAE,iBAAiB,cAAc,KAAK,YAAY,GAClDA,EAAE,iBAAiB,SAAS,KAAK,YAAY,GAC7CA,EAAE,iBAAiB,UAAU,KAAK,YAAY,GAC9CA,EAAE,iBAAiB,SAAS,KAAK,OAAO,GACxC,OAAO,iBAAiB,YAAY,KAAK,YAAY,GACrD,SAAS,iBAAiB,oBAAoB,KAAK,YAAY,GAC3DA,EAAE,cAAc,KAAG,KAAK,iBAAA;AAAA,EAEpC;AAAA,EAEA,UAAgB;AACZ,UAAMA,IAAI,KAAK,IAAI;AACnB,SAAK,aAAA,GACLA,EAAE,oBAAoB,gBAAgB,KAAK,UAAU,GACrDA,EAAE,oBAAoB,kBAAkB,KAAK,gBAAgB,GAC7DA,EAAE,oBAAoB,cAAc,KAAK,YAAY,GACrDA,EAAE,oBAAoB,SAAS,KAAK,YAAY,GAChDA,EAAE,oBAAoB,UAAU,KAAK,YAAY,GACjDA,EAAE,oBAAoB,SAAS,KAAK,OAAO,GAC3C,OAAO,oBAAoB,YAAY,KAAK,YAAY,GACxD,SAAS,oBAAoB,oBAAoB,KAAK,YAAY,GAClE,KAAK,WAAA;AAAA,EACT;AAAA,EAEA,gBAAsB;AAClB,SAAK,WAAA;AAAA,EACT;AAAA;AAAA,EAIQ,WAA0B;AAC9B,QAAI,KAAK,QAAQ,WAAW,MAAM,KAAK,QAAQ,EAAE;AACjD,UAAMO,IAAM,KAAK,IAAI,WAAA;AACrB,QAAI,CAACA,KAAOA,EAAI,WAAW,OAAO,KAAKA,EAAI,WAAW,OAAO,EAAG,QAAO;AACvE,QAAI;AACA,YAAMC,IAAI,IAAI,IAAID,GAAK,SAAS,IAAI;AACpC,aAAAC,EAAE,OAAO,IACFA,EAAE;AAAA,IACb,QAAQ;AACJ,aAAOD;AAAA,IACX;AAAA,EACJ;AAAA;AAAA,EAoDQ,MAAMF,GAAkC;AAC5C,UAAMI,KAAO,KAAK,QAAQ,WAAWhB,KAAoB,OACnDiB,IAAM,KAAK,QAAQ,cAAclB,GACjCmB,IAAM,KAAK,IAAA,GACXC,IAAO,OAAO,QAAQP,CAAG,EAC1B,OAAO,CAAC,CAAA,EAAGQ,CAAC,MAAMF,IAAME,EAAE,KAAKJ,CAAG,EAClC,KAAK,CAAC,GAAGK,MAAMA,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAChC,MAAM,GAAGJ,CAAG;AACjB,IAAAJ,EAAMlB,GAAe,OAAO,YAAYwB,CAAI,CAAC;AAAA,EACjD;AAAA,EAEQ,UAAiC;AACrC,UAAMG,IAAMC,EAA4B5B,CAAa;AACrD,WAAO2B,KAAO,OAAOA,KAAQ,WAAWA,IAAM,CAAA;AAAA,EAClD;AAAA;AAAA,EAIQ,gBAAsB;AAC1B,UAAME,IAAQD,EAAyC3B,CAAU;AACjE,QAAI,CAAC4B,KAAS,OAAOA,EAAM,UAAW,SAAU;AAChD,UAAMjB,IAAI,KAAK,IAAI;AACnB,IAAAA,EAAE,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGiB,EAAM,MAAM,CAAC,GAEhDjB,EAAE,QAAQ,KAAK,IAAI,oBAAoB,CAAC,CAACiB,EAAM;AAAA,EACnD;AAAA;AAAA,EAUQ,WAAWC,GAAoB;AACnC,QAAI,KAAK,QAAQ,WAAW,GAAO;AACnC,SAAK,WAAA;AACL,UAAMd,IAAI,KAAK,IAAI,MACbe,IAAK,SAAS,cAAc,KAAK;AACvC,IAAAA,EAAG,YAAY,qBACfA,EAAG,aAAa,QAAQ,gBAAgB,GACxCA,EAAG,aAAa,QAAQ,QAAQ;AAChC,UAAMC,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,cAAchB,EAAE,eAAeiB,EAAWH,CAAI,CAAC;AACpD,UAAMI,IAAU,SAAS,cAAc,QAAQ;AAC/C,IAAAA,EAAQ,OAAO,UACfA,EAAQ,YAAY,sBACpBA,EAAQ,cAAclB,EAAE,gBACxBkB,EAAQ,iBAAiB,SAAS,MAAM;AACpC,YAAMtB,IAAI,KAAK,IAAI;AAEnB,UADAA,EAAE,cAAc,GACZ,KAAK,KAAK;AACV,cAAMK,IAAM,KAAK,QAAA;AACjB,eAAOA,EAAI,KAAK,GAAG,GACnB,KAAK,MAAMA,CAAG;AAAA,MAClB;AACA,WAAK,KAAK,WAAW,CAAC,GACtB,KAAK,WAAA;AAAA,IACT,CAAC,GACDc,EAAG,OAAOC,GAAME,CAAO;AAEvB,eAAWC,KAAM,CAAC,eAAe,aAAa,WAAW,cAAc,YAAY,SAAS,UAAU,KAAe,iBAAiBA,GAAI,CAACV,MAAMA,EAAE,iBAAiB;AACpK,SAAK,IAAI,mBAAmB,YAAYM,CAAE,GAC1C,KAAK,WAAWA,GAChB,KAAK,cAAc,WAAW,MAAM,KAAK,WAAA,GAAcxB,CAAS;AAAA,EACpE;AAAA,EAEQ,aAAmB;;AACvB,IAAI,KAAK,eAAa,aAAa,KAAK,WAAW,GACnD,KAAK,cAAc,OACnB6B,IAAA,KAAK,aAAL,QAAAA,EAAe,UACf,KAAK,WAAW;AAAA,EACpB;AAAA,EAEQ,KAAKC,GAA8BP,GAAoB;AAC3D,SAAK,IAAI,OAAO,cAAc,IAAI,YAAY,cAAc,EAAE,QAAQ,EAAE,OAAAO,GAAO,MAAAP,GAAM,IAAI,KAAK,IAAA,EAAI,CAAG,CAAC;AAAA,EAC1G;AACJ;AAEA,SAASF,EAAQU,GAAuB;AACpC,MAAI;AACA,WAAO,KAAK,MAAM,aAAa,QAAQA,CAAG,KAAK,MAAM;AAAA,EACzD,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAEA,SAASpB,EAAMoB,GAAaC,GAAsB;AAC9C,MAAI;AACA,iBAAa,QAAQD,GAAK,KAAK,UAAUC,CAAK,CAAC;AAAA,EACnD,QAAQ;AAAA,EAER;AACJ;AC9PO,SAASC,EAAe/B,GAA2BC,GAA0C;AAChG,SAAO,IAAIF,EAAgBC,GAAKC,CAAO;AAC3C;"}
1
+ {"version":3,"file":"history-CwqLXiZi.js","sources":["../../src/plugins/history/PlaybackHistory.ts","../../src/plugins/history/index.ts"],"sourcesContent":["import type { HistoryOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { formatTime } from '../../utils/format-time';\nimport { seekWhenReady } from '../shared/seekWhenReady';\n\nexport interface HistoryPlayerContext {\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n overlayContainerEl: HTMLElement;\n i18n: HopeLocaleStrings;\n /** Şu an yüklü kaynağın adresi (hls.js'te blob değil gerçek .m3u8) — `id` verilmezse videonun anahtarı. */\n currentSrc(): string | null;\n isAdActive(): boolean;\n /** `options.muted` — otomatik oynatma için sessiz istendiyse hatırlanan \"sesli\" durumu onu bozmasın. */\n mutedRequested(): boolean;\n /** QR ile devam (`?vtime=`) bu sayfa açılışında bir konum getirdiyse — ilk yüklemede o kazanır. */\n linkTimePresent: boolean;\n}\n\nconst POSITIONS_KEY = 'hp-history-positions';\nconst VOLUME_KEY = 'hp-history-volume';\n/** Bu kadar saniye izlenmeden konum kaydedilmez (yanlışlıkla açılan video). */\nconst DEFAULT_MIN_WATCHED = 10;\n/** Sona bu kadar kala \"bitti\" sayılır — kayıt silinir, sonraki açılışta baştan başlar. */\nconst DEFAULT_END_MARGIN = 15;\nconst DEFAULT_MAX_ENTRIES = 50;\nconst DEFAULT_TTL_DAYS = 30;\n/** Oynarken konum en fazla bu sıklıkla yazılır (ms). */\nconst SAVE_EVERY_MS = 5000;\nconst NOTICE_MS = 6000;\n\ninterface Entry {\n t: number;\n d: number;\n at: number;\n}\n\n/**\n * Zaman ve ses geçmişi: video yarıda bırakılırsa bir sonraki açılışta kaldığı yerden başlar (\"Kaldığınız yerden devam:\n * 0:42 · Baştan başla\" bildirimiyle); ses seviyesi ve sessiz durumu sitede hatırlanır. Kayıtlar tarayıcıda (localStorage).\n * Canlı yayında, reklam sırasında ve sona yakın konumda kayıt yapılmaz.\n */\nexport class PlaybackHistory {\n private key: string | null = null;\n private lastSaveAt = 0;\n private noticeEl: HTMLDivElement | null = null;\n private noticeTimer: ReturnType<typeof setTimeout> | null = null;\n private skipNextRestore: boolean;\n private readonly position: boolean;\n private readonly volume: boolean;\n private readonly minWatched: number;\n private readonly endMargin: number;\n\n constructor(\n private readonly ctx: HistoryPlayerContext,\n private readonly options: HistoryOptions\n ) {\n this.position = options.position !== false;\n this.volume = options.volume !== false;\n this.minWatched = options.minWatched ?? DEFAULT_MIN_WATCHED;\n this.endMargin = options.endMargin ?? DEFAULT_END_MARGIN;\n this.skipNextRestore = ctx.linkTimePresent;\n\n const v = ctx.videoEl;\n if (this.volume) {\n this.restoreVolume();\n v.addEventListener('volumechange', this.saveVolume);\n }\n if (this.position) {\n v.addEventListener('loadedmetadata', this.onLoadedMetadata);\n v.addEventListener('timeupdate', this.onTimeUpdate);\n v.addEventListener('pause', this.savePosition);\n v.addEventListener('seeked', this.savePosition);\n v.addEventListener('ended', this.onEnded);\n window.addEventListener('pagehide', this.savePosition);\n document.addEventListener('visibilitychange', this.onVisibility);\n if (v.readyState >= 1) this.onLoadedMetadata();\n }\n }\n\n destroy(): void {\n const v = this.ctx.videoEl;\n this.savePosition();\n v.removeEventListener('volumechange', this.saveVolume);\n v.removeEventListener('loadedmetadata', this.onLoadedMetadata);\n v.removeEventListener('timeupdate', this.onTimeUpdate);\n v.removeEventListener('pause', this.savePosition);\n v.removeEventListener('seeked', this.savePosition);\n v.removeEventListener('ended', this.onEnded);\n window.removeEventListener('pagehide', this.savePosition);\n document.removeEventListener('visibilitychange', this.onVisibility);\n this.hideNotice();\n }\n\n refreshLabels(): void {\n this.hideNotice();\n }\n\n // ── Konum ──\n\n private videoKey(): string | null {\n if (this.options.id) return `id:${this.options.id}`;\n const src = this.ctx.currentSrc();\n if (!src || src.startsWith('blob:') || src.startsWith('data:')) return null;\n try {\n const u = new URL(src, location.href);\n u.hash = '';\n return u.href;\n } catch {\n return src;\n }\n }\n\n private readonly onLoadedMetadata = (): void => {\n const v = this.ctx.videoEl;\n this.key = this.videoKey();\n this.lastSaveAt = 0;\n if (!this.key || !Number.isFinite(v.duration)) return;\n // Link ile gelen konum (QR ile devam) yalnızca bu açılışta kazanır.\n if (this.skipNextRestore) {\n this.skipNextRestore = false;\n return;\n }\n // Başka bir şey zaten sarmışsa (ör. kaynak değişiminde korunan konum) dokunma.\n if (v.currentTime > 1) return;\n const entry = this.entries()[this.key];\n if (!entry || entry.t < this.minWatched || entry.t > v.duration - this.endMargin) return;\n seekWhenReady(v, entry.t, { attempts: 2 });\n this.showNotice(entry.t);\n this.emit('resumed', entry.t);\n };\n\n private readonly onTimeUpdate = (): void => {\n if (Date.now() - this.lastSaveAt < SAVE_EVERY_MS) return;\n this.savePosition();\n };\n\n private readonly onVisibility = (): void => {\n if (document.visibilityState === 'hidden') this.savePosition();\n };\n\n private readonly savePosition = (): void => {\n const v = this.ctx.videoEl;\n if (!this.key || this.ctx.isAdActive() || v.seeking) return;\n const d = v.duration;\n if (!Number.isFinite(d) || d <= 0) return; // canlı yayın\n this.lastSaveAt = Date.now();\n const t = v.currentTime;\n const all = this.entries();\n if (t >= d - this.endMargin) delete all[this.key];\n else if (t >= this.minWatched) all[this.key] = { t: Math.floor(t), d: Math.round(d), at: Date.now() };\n else return;\n this.store(all);\n };\n\n private readonly onEnded = (): void => {\n if (!this.key) return;\n const all = this.entries();\n delete all[this.key];\n this.store(all);\n };\n\n /** Süresi geçenleri at, en yeni `maxEntries` kaydı tut. */\n private store(all: Record<string, Entry>): void {\n const ttl = (this.options.ttlDays ?? DEFAULT_TTL_DAYS) * 86_400_000;\n const max = this.options.maxEntries ?? DEFAULT_MAX_ENTRIES;\n const now = Date.now();\n const kept = Object.entries(all)\n .filter(([, e]) => now - e.at < ttl)\n .sort((a, b) => b[1].at - a[1].at)\n .slice(0, max);\n write(POSITIONS_KEY, Object.fromEntries(kept));\n }\n\n private entries(): Record<string, Entry> {\n const raw = read<Record<string, Entry>>(POSITIONS_KEY);\n return raw && typeof raw === 'object' ? raw : {};\n }\n\n // ── Ses ──\n\n private restoreVolume(): void {\n const saved = read<{ volume: number; muted: boolean }>(VOLUME_KEY);\n if (!saved || typeof saved.volume !== 'number') return;\n const v = this.ctx.videoEl;\n v.volume = Math.min(1, Math.max(0, saved.volume));\n // Sessiz otomatik oynatma istendiyse (options.muted) \"sesli\" kaydı onu bozmasın; kullanıcı sessize aldıysa korunur.\n v.muted = this.ctx.mutedRequested() || !!saved.muted;\n }\n\n private readonly saveVolume = (): void => {\n if (this.ctx.isAdActive()) return;\n const v = this.ctx.videoEl;\n write(VOLUME_KEY, { volume: Math.round(v.volume * 100) / 100, muted: v.muted });\n };\n\n // ── Bildirim ──\n\n private showNotice(time: number): void {\n if (this.options.notice === false) return;\n this.hideNotice();\n const t = this.ctx.i18n;\n const el = document.createElement('div');\n el.className = 'hp-history-notice';\n el.setAttribute('part', 'history-notice');\n el.setAttribute('role', 'status');\n const text = document.createElement('span');\n text.textContent = t.historyResumed(formatTime(time));\n const restart = document.createElement('button');\n restart.type = 'button';\n restart.className = 'hp-history-restart';\n restart.textContent = t.historyRestart;\n restart.addEventListener('click', () => {\n const v = this.ctx.videoEl;\n v.currentTime = 0;\n if (this.key) {\n const all = this.entries();\n delete all[this.key];\n this.store(all);\n }\n this.emit('restart', 0);\n this.hideNotice();\n });\n el.append(text, restart);\n // Bildirimdeki tıklama oynat / duraklat'a geçmesin.\n for (const ev of ['pointerdown', 'mousedown', 'mouseup', 'touchstart', 'touchend', 'click', 'dblclick'] as const) el.addEventListener(ev, (e) => e.stopPropagation());\n this.ctx.overlayContainerEl.appendChild(el);\n this.noticeEl = el;\n this.noticeTimer = setTimeout(() => this.hideNotice(), NOTICE_MS);\n }\n\n private hideNotice(): void {\n if (this.noticeTimer) clearTimeout(this.noticeTimer);\n this.noticeTimer = null;\n this.noticeEl?.remove();\n this.noticeEl = null;\n }\n\n private emit(state: 'resumed' | 'restart', time: number): void {\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:history', { detail: { state, time, id: this.key } }));\n }\n}\n\nfunction read<T>(key: string): T | null {\n try {\n return JSON.parse(localStorage.getItem(key) ?? 'null') as T | null;\n } catch {\n return null;\n }\n}\n\nfunction write(key: string, value: unknown): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* gizli sekme / kota dolu — geçmiş yalnızca bu oturumda yok */\n }\n}\n","import { PlaybackHistory, type HistoryPlayerContext } from './PlaybackHistory';\nimport type { HistoryOptions } from '../../types';\n\nexport function installHistory(ctx: HistoryPlayerContext, options: HistoryOptions): PlaybackHistory {\n return new PlaybackHistory(ctx, options);\n}\n\nexport { PlaybackHistory };\nexport type { HistoryPlayerContext };\n"],"names":["POSITIONS_KEY","VOLUME_KEY","DEFAULT_MIN_WATCHED","DEFAULT_END_MARGIN","DEFAULT_MAX_ENTRIES","DEFAULT_TTL_DAYS","SAVE_EVERY_MS","NOTICE_MS","PlaybackHistory","ctx","options","__publicField","v","entry","seekWhenReady","d","t","all","write","src","u","ttl","max","now","kept","e","b","raw","read","saved","time","el","text","formatTime","restart","ev","_a","state","key","value","installHistory"],"mappings":"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"}
@@ -0,0 +1,189 @@
1
+ var A = Object.defineProperty;
2
+ var z = (p, t, i) => t in p ? A(p, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : p[t] = i;
3
+ var d = (p, t, i) => z(p, typeof t != "symbol" ? t + "" : t, i);
4
+ import { c as L } from "./player-D2_HRzot.js";
5
+ import { a as S } from "./plugin-style-CPJELe-i.js";
6
+ const q = '.hp-ia{position:absolute;z-index:24;width:min(320px,calc(100% - 24px));max-height:calc(100% - 100px);overflow-y:auto;box-sizing:border-box;padding:12px;border:1px solid rgba(255,255,255,.12);border-radius:12px;background:#0e0e12e0;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);color:#fff;box-shadow:0 16px 36px -14px #000000d9;font:13px/1.4 system-ui,-apple-system,sans-serif;animation:hp-redirect-in .3s cubic-bezier(.2,.8,.2,1)}.hp-ia[data-position=top-right]{top:12px;right:12px}.hp-ia[data-position=top-left]{top:12px;left:12px}.hp-ia[data-position=bottom-right]{right:12px;bottom:76px}.hp-ia[data-position=bottom-left]{left:12px;bottom:76px}.hp-ia[data-position=center]{top:50%;left:50%;transform:translate(-50%,-50%);animation:hp-redirect-fade .25s ease-out}.video-area[data-chrome-hidden] .hp-ia[data-position^=bottom]{bottom:12px}.video-area[data-compact] .hp-ia{width:calc(100% - 16px);max-height:calc(100% - 64px);padding:10px}.video-area[data-compact] .hp-ia[data-position$=right],.video-area[data-compact] .hp-ia[data-position$=left]{left:8px;right:8px}.video-area[data-compact] .hp-ia[data-position^=top]{top:8px}.video-area[data-compact] .hp-ia[data-position^=bottom]{bottom:56px}.hp-ia-close{position:absolute;top:8px;right:8px;display:grid;place-items:center;width:24px;height:24px;padding:0;border:0;border-radius:999px;background:#ffffff1f;color:#fff;font-size:12px;cursor:pointer}.hp-ia-close:hover{background:#ffffff3d}.hp-ia-label{display:block;margin-bottom:4px;color:var(--hp-color-accent, #fff);font:700 10px/1.2 system-ui,-apple-system,sans-serif;letter-spacing:.1em;text-transform:uppercase}.hp-ia-question{margin:0 28px 10px 0;font-weight:600;font-size:14px}.hp-ia-choices{display:grid;gap:6px}.hp-ia-choice{position:relative;display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;overflow:hidden;padding:8px 10px;border:1px solid rgba(255,255,255,.16);border-radius:8px;background:#ffffff0f;color:#fff;font:inherit;text-align:start;cursor:pointer;transition:background .15s,border-color .15s}.hp-ia-choice:hover:not(:disabled){background:#ffffff24}.hp-ia-choice:disabled{cursor:default}.hp-ia-choice[data-result]:before{content:"";position:absolute;inset:0 auto 0 0;width:var(--hp-ia-pct, 0%);background:#ffffff24;transition:width .6s cubic-bezier(.2,.8,.2,1)}.hp-ia-choice>span{position:relative}.hp-ia-choice[data-picked]{border-color:var(--hp-color-accent, #fff)}.hp-ia-choice[data-correct]{border-color:#2fbf71;background:#2fbf7138}.hp-ia-choice[data-wrong]{border-color:#e5484d;background:#e5484d38}.hp-ia-pct{flex:none;font-weight:600;font-variant-numeric:tabular-nums}.hp-ia-status{margin:8px 0 0;font-size:12.5px;opacity:.85}.hp-ia-status:empty{display:none}.hp-ia[data-type=product],.hp-ia[data-type=link]{padding:0}.hp-ia-card{display:flex;gap:10px;padding:8px 34px 8px 8px;color:#fff;text-decoration:none}.hp-ia-image{flex:none;width:72px;height:72px;border-radius:8px;object-fit:cover;background:#111}.hp-ia-body{display:flex;flex-direction:column;gap:2px;min-width:0}.hp-ia-body .hp-ia-label{margin-bottom:0}.hp-ia-title{display:-webkit-box;overflow:hidden;-webkit-line-clamp:2;-webkit-box-orient:vertical;font-weight:600}.hp-ia-sub{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;opacity:.7;font-size:12px}.hp-ia-price{display:flex;gap:6px;align-items:baseline}.hp-ia-price s{opacity:.55;font-size:12px}.hp-ia-cta{align-self:flex-start;margin-top:4px;padding:5px 12px;border-radius:999px;background:var(--hp-color-accent, #fff);color:var(--hp-color-on-accent, #000);font-weight:600;font-size:12px}.hp-ia-card:hover .hp-ia-cta{filter:brightness(.92)}.hp-ia-choice:focus-visible,.hp-ia-close:focus-visible,.hp-ia-card:focus-visible{outline:2px solid var(--hp-color-accent, #fff);outline-offset:2px}.hp-seek-marker.hp-ia-marker{background:var(--hp-ia-marker-color, #f5c518)}@media(prefers-reduced-motion:reduce){.hp-ia,.hp-ia-choice[data-result]:before{animation:none;transition:none}}', E = "hp-interactive:", C = 1.5;
7
+ function T(p, t) {
8
+ return typeof p == "string" ? { id: String(t), text: p } : { id: p.id ?? String(t), text: p.text };
9
+ }
10
+ function n(p, t, i) {
11
+ const e = document.createElement(p);
12
+ return e.className = t, i !== void 0 && (e.textContent = i), e;
13
+ }
14
+ class $ {
15
+ constructor(t, i) {
16
+ d(this, "entries", []);
17
+ d(this, "active", null);
18
+ d(this, "markers", []);
19
+ d(this, "closeTimer", null);
20
+ d(this, "drawMarkers", () => {
21
+ for (const i of this.markers) i.remove();
22
+ this.markers = [];
23
+ const t = this.ctx.videoEl.duration;
24
+ if (!(this.options.markers === !1 || !Number.isFinite(t) || t <= 0))
25
+ for (const i of this.entries) {
26
+ if (i.item.time < 0 || i.item.time > t) continue;
27
+ const e = this.ctx.addSeekBarMarker(i.item.time / t, "hp-ia-marker", "question" in i.item ? i.item.question : i.item.title), o = i.item.markerColor ?? this.options.markerColor;
28
+ o && (e.style.backgroundColor = o), this.markers.push(e);
29
+ }
30
+ });
31
+ /** Yeni kaynak: oturum durumu sıfırlanır. */
32
+ d(this, "onEmptied", () => {
33
+ this.hide(null);
34
+ for (const t of this.entries) t.done = !1;
35
+ });
36
+ d(this, "onAdStart", () => {
37
+ this.active && !this.active.answered && this.hide("timeout");
38
+ });
39
+ /** Geri sarınca sonraki öğeler yeniden gösterilebilir (cevaplanmış anket / quiz yine sorulmaz). */
40
+ d(this, "onSeeked", () => {
41
+ var i;
42
+ const t = this.ctx.videoEl.currentTime;
43
+ for (const e of this.entries) e.item.time > t + 0.1 && e !== ((i = this.active) == null ? void 0 : i.entry) && (e.done = !1);
44
+ this.onTime();
45
+ });
46
+ d(this, "onTime", () => {
47
+ const t = this.ctx.videoEl.currentTime, i = this.active;
48
+ if (i)
49
+ if (t < i.entry.item.time - 0.5) this.hide("seek");
50
+ else if (!i.answered && t >= i.shownAt + this.duration(i.entry.item)) this.hide("timeout");
51
+ else if (i.answered && this.entries.some((e) => !e.done && t >= e.item.time && t - e.item.time <= C)) this.hide(null);
52
+ else return;
53
+ if (!this.ctx.isAdActive()) {
54
+ for (const e of this.entries)
55
+ if (!(e.done || t < e.item.time) && (e.done = !0, !(t - e.item.time > C || this.remembered(e)))) {
56
+ this.show(e, t);
57
+ return;
58
+ }
59
+ }
60
+ });
61
+ this.ctx = t, this.options = i, S(t.overlayEl, "interactive", q), this.entries = i.items.map((o, s) => ({ item: o, id: o.id ?? `i${s}`, done: !1 }));
62
+ const e = t.videoEl;
63
+ e.addEventListener("timeupdate", this.onTime), e.addEventListener("seeked", this.onSeeked), e.addEventListener("loadedmetadata", this.drawMarkers), e.addEventListener("emptied", this.onEmptied), t.hostEl.addEventListener("hp:adstart", this.onAdStart), e.readyState >= 1 && this.drawMarkers();
64
+ }
65
+ /** Yalnızca fonksiyonlar değişti (ör. React'te her render'da yeni onAnswer). */
66
+ setOptions(t) {
67
+ this.options = t;
68
+ }
69
+ refreshLabels() {
70
+ var t, i;
71
+ (i = (t = this.active) == null ? void 0 : t.el.querySelector(".hp-ia-close")) == null || i.setAttribute("aria-label", this.ctx.i18n.interactiveClose);
72
+ }
73
+ destroy() {
74
+ const t = this.ctx.videoEl;
75
+ t.removeEventListener("timeupdate", this.onTime), t.removeEventListener("seeked", this.onSeeked), t.removeEventListener("loadedmetadata", this.drawMarkers), t.removeEventListener("emptied", this.onEmptied), this.ctx.hostEl.removeEventListener("hp:adstart", this.onAdStart), this.hide(null);
76
+ for (const i of this.markers) i.remove();
77
+ this.markers = [];
78
+ }
79
+ emit(t, i, e = {}) {
80
+ return this.ctx.hostEl.dispatchEvent(
81
+ new CustomEvent("hp:interactive", { detail: { state: t, id: i.id, type: i.item.type, ...e }, cancelable: t === "click" })
82
+ );
83
+ }
84
+ remembered(t) {
85
+ if (this.options.rememberAnswers === !1 || t.item.type !== "poll" && t.item.type !== "quiz") return !1;
86
+ try {
87
+ return localStorage.getItem(E + t.id) !== null;
88
+ } catch {
89
+ return !1;
90
+ }
91
+ }
92
+ remember(t, i) {
93
+ if (this.options.rememberAnswers !== !1)
94
+ try {
95
+ localStorage.setItem(E + t.id, String(i));
96
+ } catch {
97
+ }
98
+ }
99
+ duration(t) {
100
+ return t.duration ?? (t.type === "poll" || t.type === "quiz" ? 15 : 8);
101
+ }
102
+ show(t, i) {
103
+ const e = t.item, o = n("div", "hp-ia");
104
+ o.setAttribute("part", `interactive interactive-${e.type}`), o.setAttribute("data-type", e.type), o.setAttribute("data-position", e.position ?? (e.type === "poll" || e.type === "quiz" ? "top-right" : "bottom-right")), o.setAttribute("role", "group");
105
+ for (const a of ["pointerdown", "click", "dblclick"]) o.addEventListener(a, (f) => f.stopPropagation());
106
+ if (o.addEventListener("keydown", (a) => a.stopPropagation()), e.dismissible !== !1) {
107
+ const a = n("button", "hp-ia-close");
108
+ a.type = "button", a.setAttribute("aria-label", this.ctx.i18n.interactiveClose), a.appendChild(L("close")), a.addEventListener("click", () => this.hide("user")), o.appendChild(a);
109
+ }
110
+ e.type === "poll" || e.type === "quiz" ? this.buildQuestion(o, t) : this.buildCard(o, t, e), this.ctx.overlayEl.appendChild(o);
111
+ const s = this.ctx.videoEl, r = !!e.pause && !s.paused;
112
+ r && s.pause(), this.active = { entry: t, el: o, shownAt: i, pausedByUs: r, answered: !1 }, this.emit("shown", t);
113
+ }
114
+ buildQuestion(t, i) {
115
+ const e = i.item, o = this.ctx.i18n;
116
+ t.appendChild(n("span", "hp-ia-label", e.type === "poll" ? o.interactivePoll : o.interactiveQuiz));
117
+ const s = n("p", "hp-ia-question", e.question);
118
+ s.id = `hp-ia-q-${i.id}`, t.setAttribute("aria-labelledby", s.id), t.appendChild(s);
119
+ const r = n("div", "hp-ia-choices"), a = e.choices.map(T), f = a.map((v, u) => {
120
+ const c = n("button", "hp-ia-choice");
121
+ return c.type = "button", c.appendChild(n("span", "hp-ia-choice-text", v.text)), c.addEventListener("click", () => void this.answer(i, u, a[u].id, f)), r.appendChild(c), c;
122
+ });
123
+ t.appendChild(r);
124
+ const l = n("p", "hp-ia-status");
125
+ l.setAttribute("aria-live", "polite"), t.appendChild(l);
126
+ }
127
+ async answer(t, i, e, o) {
128
+ var v, u, c, g, y, k;
129
+ const s = this.active;
130
+ if (!s || s.entry !== t || s.answered) return;
131
+ s.answered = !0;
132
+ const r = t.item, a = r.type === "quiz" ? i === r.answer : void 0;
133
+ this.remember(t, i);
134
+ for (const m of o) m.disabled = !0;
135
+ (v = o[i]) == null || v.setAttribute("data-picked", "");
136
+ const f = s.el.querySelector(".hp-ia-status");
137
+ this.emit("answer", t, { choice: i, choiceId: e, ...a !== void 0 ? { correct: a } : {} });
138
+ let l;
139
+ try {
140
+ l = await ((c = (u = this.options).onAnswer) == null ? void 0 : c.call(u, { item: r, id: t.id, choice: i, choiceId: e, correct: a }));
141
+ } catch {
142
+ l = void 0;
143
+ }
144
+ if (((g = this.active) == null ? void 0 : g.entry) === t) {
145
+ if (r.type === "quiz")
146
+ (y = o[r.answer]) == null || y.setAttribute("data-correct", ""), a || (k = o[i]) == null || k.setAttribute("data-wrong", ""), f && (f.textContent = `${a ? this.ctx.i18n.interactiveCorrect : this.ctx.i18n.interactiveWrong}${r.explanation ? ` ${r.explanation}` : ""}`);
147
+ else {
148
+ const m = Array.isArray(l) ? l : r.results ? r.results.map((x, h) => x + (h === i ? 1 : 0)) : null;
149
+ if (m) {
150
+ const x = m.reduce((h, b) => h + (Number.isFinite(b) && b > 0 ? b : 0), 0) || 1;
151
+ o.forEach((h, b) => {
152
+ const w = Math.round((m[b] ?? 0) / x * 100);
153
+ h.style.setProperty("--hp-ia-pct", `${w}%`), h.setAttribute("data-result", ""), h.appendChild(n("span", "hp-ia-pct", this.ctx.i18n.interactiveVotes(w)));
154
+ });
155
+ }
156
+ }
157
+ this.closeTimer = setTimeout(() => this.hide(null), r.type === "quiz" ? 5e3 : 3500);
158
+ }
159
+ }
160
+ buildCard(t, i, e) {
161
+ const o = this.ctx.i18n, s = n("a", "hp-ia-card");
162
+ if (s.href = e.url, e.newTab !== !1 && (s.target = "_blank", s.rel = "noopener"), e.image) {
163
+ const a = n("img", "hp-ia-image");
164
+ a.src = e.image, a.alt = "", a.decoding = "async", a.addEventListener("error", () => a.remove()), s.appendChild(a);
165
+ }
166
+ const r = n("span", "hp-ia-body");
167
+ if (e.sponsored && r.appendChild(n("span", "hp-ia-label", o.interactiveSponsored)), r.appendChild(n("span", "hp-ia-title", e.title)), e.subtitle && r.appendChild(n("span", "hp-ia-sub", e.subtitle)), e.price || e.oldPrice) {
168
+ const a = n("span", "hp-ia-price");
169
+ e.price && a.appendChild(n("strong", "", e.price)), e.oldPrice && a.appendChild(n("s", "", e.oldPrice)), r.appendChild(a);
170
+ }
171
+ r.appendChild(n("span", "hp-ia-cta", e.cta ?? (e.type === "product" ? o.interactiveBuy : o.interactiveGo))), s.appendChild(r), s.addEventListener("click", (a) => {
172
+ this.emit("click", i, { url: e.url }) || a.preventDefault();
173
+ }), t.setAttribute("aria-label", e.title), t.appendChild(s);
174
+ }
175
+ hide(t) {
176
+ this.closeTimer && clearTimeout(this.closeTimer), this.closeTimer = null;
177
+ const i = this.active;
178
+ i && (this.active = null, i.el.remove(), t && this.emit("dismiss", i.entry, { reason: t }), i.pausedByUs && t !== "seek" && this.ctx.videoEl.play().catch(() => {
179
+ }));
180
+ }
181
+ }
182
+ function I(p, t) {
183
+ return new $(p, t);
184
+ }
185
+ export {
186
+ $ as Interactive,
187
+ I as installInteractive
188
+ };
189
+ //# sourceMappingURL=interactive-CgltIneu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-CgltIneu.js","sources":["../../src/plugins/interactive/Interactive.ts","../../src/plugins/interactive/index.ts"],"sourcesContent":["import type { InteractiveCard, InteractiveChoice, InteractiveItem, InteractiveOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { createIcon } from '../../icons/Icon';\nimport { adoptStyle } from '../../utils/plugin-style';\nimport css from './interactive.css?inline';\n\nexport interface InteractivePlayerContext {\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n overlayEl: HTMLElement;\n i18n: HopeLocaleStrings;\n isAdActive(): boolean;\n addSeekBarMarker(ratio: number, extraClass?: string, label?: string): HTMLElement;\n}\n\ninterface Entry {\n item: InteractiveItem;\n id: string;\n /** Bu oturumda gösterildi (ileri geri sarınca tekrar sorulmaz). */\n done: boolean;\n}\n\nconst STORE = 'hp-interactive:';\n/** Bu kadar saniye geç kalınırsa (ileri sarma) öğe atlanır. */\nconst LATE = 1.5;\n\nfunction choiceOf(c: string | InteractiveChoice, i: number): { id: string; text: string } {\n return typeof c === 'string' ? { id: String(i), text: c } : { id: c.id ?? String(i), text: c.text };\n}\n\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, className: string, text?: string): HTMLElementTagNameMap[K] {\n const e = document.createElement(tag);\n e.className = className;\n if (text !== undefined) e.textContent = text;\n return e;\n}\n\n/**\n * Etkileşimli içerik: belirli saniyelerde anket, quiz, ürün ya da bağlantı kartı. Zamanlama videonun zamanıyla\n * işler (duraklatınca süre durur); ileri sarılıp geçilen öğe gösterilmez. Cevaplanan anket / quiz izleyiciye bir daha\n * sorulmaz (localStorage). Reklam oynarken gizlenir.\n */\nexport class Interactive {\n private entries: Entry[] = [];\n private active: { entry: Entry; el: HTMLElement; shownAt: number; pausedByUs: boolean; answered: boolean } | null = null;\n private markers: HTMLElement[] = [];\n private closeTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n private readonly ctx: InteractivePlayerContext,\n private options: InteractiveOptions\n ) {\n adoptStyle(ctx.overlayEl, 'interactive', css);\n this.entries = options.items.map((item, i) => ({ item, id: item.id ?? `i${i}`, done: false }));\n const v = ctx.videoEl;\n v.addEventListener('timeupdate', this.onTime);\n v.addEventListener('seeked', this.onSeeked);\n v.addEventListener('loadedmetadata', this.drawMarkers);\n v.addEventListener('emptied', this.onEmptied);\n ctx.hostEl.addEventListener('hp:adstart', this.onAdStart);\n if (v.readyState >= 1) this.drawMarkers();\n }\n\n /** Yalnızca fonksiyonlar değişti (ör. React'te her render'da yeni onAnswer). */\n setOptions(options: InteractiveOptions): void {\n this.options = options;\n }\n\n refreshLabels(): void {\n // Açık öğenin metinleri bir sonraki gösterimde dilden okunur; açık olanın kapat etiketi güncellenir.\n this.active?.el.querySelector('.hp-ia-close')?.setAttribute('aria-label', this.ctx.i18n.interactiveClose);\n }\n\n destroy(): void {\n const v = this.ctx.videoEl;\n v.removeEventListener('timeupdate', this.onTime);\n v.removeEventListener('seeked', this.onSeeked);\n v.removeEventListener('loadedmetadata', this.drawMarkers);\n v.removeEventListener('emptied', this.onEmptied);\n this.ctx.hostEl.removeEventListener('hp:adstart', this.onAdStart);\n this.hide(null);\n for (const m of this.markers) m.remove();\n this.markers = [];\n }\n\n private emit(state: 'shown' | 'answer' | 'click' | 'dismiss', entry: Entry, extra: Record<string, unknown> = {}): boolean {\n return this.ctx.hostEl.dispatchEvent(\n new CustomEvent('hp:interactive', { detail: { state, id: entry.id, type: entry.item.type, ...extra }, cancelable: state === 'click' })\n );\n }\n\n private readonly drawMarkers = (): void => {\n for (const m of this.markers) m.remove();\n this.markers = [];\n const d = this.ctx.videoEl.duration;\n if (this.options.markers === false || !Number.isFinite(d) || d <= 0) return;\n for (const e of this.entries) {\n if (e.item.time < 0 || e.item.time > d) continue;\n const m = this.ctx.addSeekBarMarker(e.item.time / d, 'hp-ia-marker', 'question' in e.item ? e.item.question : e.item.title);\n const color = e.item.markerColor ?? this.options.markerColor;\n if (color) m.style.backgroundColor = color;\n this.markers.push(m);\n }\n };\n\n /** Yeni kaynak: oturum durumu sıfırlanır. */\n private readonly onEmptied = (): void => {\n this.hide(null);\n for (const e of this.entries) e.done = false;\n };\n\n private readonly onAdStart = (): void => {\n // Reklam açık öğeyi örtmesin — kapat, reklamdan sonra tekrar gösterilmez.\n if (this.active && !this.active.answered) this.hide('timeout');\n };\n\n private remembered(entry: Entry): boolean {\n if (this.options.rememberAnswers === false || (entry.item.type !== 'poll' && entry.item.type !== 'quiz')) return false;\n try {\n return localStorage.getItem(STORE + entry.id) !== null;\n } catch {\n return false;\n }\n }\n\n private remember(entry: Entry, choice: number): void {\n if (this.options.rememberAnswers === false) return;\n try {\n localStorage.setItem(STORE + entry.id, String(choice));\n } catch {\n /* depolama kapalı */\n }\n }\n\n private duration(item: InteractiveItem): number {\n return item.duration ?? (item.type === 'poll' || item.type === 'quiz' ? 15 : 8);\n }\n\n /** Geri sarınca sonraki öğeler yeniden gösterilebilir (cevaplanmış anket / quiz yine sorulmaz). */\n private readonly onSeeked = (): void => {\n const t = this.ctx.videoEl.currentTime;\n for (const e of this.entries) if (e.item.time > t + 0.1 && e !== this.active?.entry) e.done = false;\n this.onTime();\n };\n\n private readonly onTime = (): void => {\n const t = this.ctx.videoEl.currentTime;\n const a = this.active;\n if (a) {\n // Geri sarıldı ya da süresi doldu (cevaplanmış anket sonucu kendi zamanlayıcısıyla kapanır).\n if (t < a.entry.item.time - 0.5) this.hide('seek');\n else if (!a.answered && t >= a.shownAt + this.duration(a.entry.item)) this.hide('timeout');\n // Sonuç gösterilirken sıradaki öğenin zamanı geldi — sonucu kapat, yenisini göster.\n else if (a.answered && this.entries.some((e) => !e.done && t >= e.item.time && t - e.item.time <= LATE)) this.hide(null);\n else return;\n }\n if (this.ctx.isAdActive()) return;\n for (const e of this.entries) {\n if (e.done || t < e.item.time) continue;\n e.done = true;\n // İleri sarılıp geçildiyse ya da daha önce cevaplandıysa gösterme.\n if (t - e.item.time > LATE || this.remembered(e)) continue;\n this.show(e, t);\n return;\n }\n };\n\n private show(entry: Entry, t: number): void {\n const item = entry.item;\n const box = el('div', 'hp-ia');\n box.setAttribute('part', `interactive interactive-${item.type}`);\n box.setAttribute('data-type', item.type);\n box.setAttribute('data-position', item.position ?? (item.type === 'poll' || item.type === 'quiz' ? 'top-right' : 'bottom-right'));\n box.setAttribute('role', 'group');\n for (const ev of ['pointerdown', 'click', 'dblclick'] as const) box.addEventListener(ev, (e) => e.stopPropagation());\n box.addEventListener('keydown', (e) => e.stopPropagation());\n\n if (item.dismissible !== false) {\n const close = el('button', 'hp-ia-close');\n close.type = 'button';\n close.setAttribute('aria-label', this.ctx.i18n.interactiveClose);\n close.appendChild(createIcon('close'));\n close.addEventListener('click', () => this.hide('user'));\n box.appendChild(close);\n }\n\n if (item.type === 'poll' || item.type === 'quiz') this.buildQuestion(box, entry);\n else this.buildCard(box, entry, item);\n\n this.ctx.overlayEl.appendChild(box);\n const v = this.ctx.videoEl;\n const pausedByUs = !!item.pause && !v.paused;\n if (pausedByUs) v.pause();\n this.active = { entry, el: box, shownAt: t, pausedByUs, answered: false };\n this.emit('shown', entry);\n }\n\n private buildQuestion(box: HTMLElement, entry: Entry): void {\n const item = entry.item as Extract<InteractiveItem, { type: 'poll' | 'quiz' }>;\n const i18n = this.ctx.i18n;\n box.appendChild(el('span', 'hp-ia-label', item.type === 'poll' ? i18n.interactivePoll : i18n.interactiveQuiz));\n const q = el('p', 'hp-ia-question', item.question);\n q.id = `hp-ia-q-${entry.id}`;\n box.setAttribute('aria-labelledby', q.id);\n box.appendChild(q);\n const list = el('div', 'hp-ia-choices');\n const choices = item.choices.map(choiceOf);\n const buttons = choices.map((c, i) => {\n const b = el('button', 'hp-ia-choice');\n b.type = 'button';\n b.appendChild(el('span', 'hp-ia-choice-text', c.text));\n b.addEventListener('click', () => void this.answer(entry, i, choices[i]!.id, buttons));\n list.appendChild(b);\n return b;\n });\n box.appendChild(list);\n const status = el('p', 'hp-ia-status');\n status.setAttribute('aria-live', 'polite');\n box.appendChild(status);\n }\n\n private async answer(entry: Entry, choice: number, choiceId: string, buttons: HTMLButtonElement[]): Promise<void> {\n const a = this.active;\n if (!a || a.entry !== entry || a.answered) return;\n a.answered = true;\n const item = entry.item as Extract<InteractiveItem, { type: 'poll' | 'quiz' }>;\n const correct = item.type === 'quiz' ? choice === item.answer : undefined;\n this.remember(entry, choice);\n for (const b of buttons) b.disabled = true;\n buttons[choice]?.setAttribute('data-picked', '');\n const status = a.el.querySelector<HTMLElement>('.hp-ia-status');\n this.emit('answer', entry, { choice, choiceId, ...(correct !== undefined ? { correct } : {}) });\n\n let results: number[] | void | undefined;\n try {\n results = await this.options.onAnswer?.({ item, id: entry.id, choice, choiceId, correct });\n } catch {\n results = undefined;\n }\n if (this.active?.entry !== entry) return;\n\n if (item.type === 'quiz') {\n buttons[item.answer]?.setAttribute('data-correct', '');\n if (!correct) buttons[choice]?.setAttribute('data-wrong', '');\n if (status) status.textContent = `${correct ? this.ctx.i18n.interactiveCorrect : this.ctx.i18n.interactiveWrong}${item.explanation ? ` ${item.explanation}` : ''}`;\n } else {\n // Sonuç: onAnswer'ın döndürdüğü, yoksa verilen dağılım + bu oy.\n const base = Array.isArray(results) ? results : item.results ? item.results.map((n, i) => n + (i === choice ? 1 : 0)) : null;\n if (base) {\n const total = base.reduce((s, n) => s + (Number.isFinite(n) && n > 0 ? n : 0), 0) || 1;\n buttons.forEach((b, i) => {\n const pct = Math.round(((base[i] ?? 0) / total) * 100);\n b.style.setProperty('--hp-ia-pct', `${pct}%`);\n b.setAttribute('data-result', '');\n b.appendChild(el('span', 'hp-ia-pct', this.ctx.i18n.interactiveVotes(pct)));\n });\n }\n }\n // Sonuç birkaç saniye görünür, sonra kapanır (duraklattıysak oynatma devam eder).\n this.closeTimer = setTimeout(() => this.hide(null), item.type === 'quiz' ? 5000 : 3500);\n }\n\n private buildCard(box: HTMLElement, entry: Entry, item: InteractiveCard): void {\n const i18n = this.ctx.i18n;\n const link = el('a', 'hp-ia-card');\n link.href = item.url;\n if (item.newTab !== false) {\n link.target = '_blank';\n link.rel = 'noopener';\n }\n if (item.image) {\n const img = el('img', 'hp-ia-image');\n img.src = item.image;\n img.alt = '';\n img.decoding = 'async';\n img.addEventListener('error', () => img.remove());\n link.appendChild(img);\n }\n const body = el('span', 'hp-ia-body');\n if (item.sponsored) body.appendChild(el('span', 'hp-ia-label', i18n.interactiveSponsored));\n body.appendChild(el('span', 'hp-ia-title', item.title));\n if (item.subtitle) body.appendChild(el('span', 'hp-ia-sub', item.subtitle));\n if (item.price || item.oldPrice) {\n const price = el('span', 'hp-ia-price');\n if (item.price) price.appendChild(el('strong', '', item.price));\n if (item.oldPrice) price.appendChild(el('s', '', item.oldPrice));\n body.appendChild(price);\n }\n body.appendChild(el('span', 'hp-ia-cta', item.cta ?? (item.type === 'product' ? i18n.interactiveBuy : i18n.interactiveGo)));\n link.appendChild(body);\n link.addEventListener('click', (e) => {\n // preventDefault → entegratör kendisi açar (sepete ekle, SPA router).\n if (!this.emit('click', entry, { url: item.url })) e.preventDefault();\n });\n box.setAttribute('aria-label', item.title);\n box.appendChild(link);\n }\n\n private hide(reason: 'user' | 'timeout' | 'seek' | null): void {\n if (this.closeTimer) clearTimeout(this.closeTimer);\n this.closeTimer = null;\n const a = this.active;\n if (!a) return;\n this.active = null;\n a.el.remove();\n if (reason) this.emit('dismiss', a.entry, { reason });\n if (a.pausedByUs && reason !== 'seek') void this.ctx.videoEl.play().catch(() => {});\n }\n}\n","import { Interactive, type InteractivePlayerContext } from './Interactive';\nimport type { InteractiveOptions } from '../../types';\n\nexport function installInteractive(ctx: InteractivePlayerContext, options: InteractiveOptions): Interactive {\n return new Interactive(ctx, options);\n}\n\nexport { Interactive };\nexport type { InteractivePlayerContext };\n"],"names":["STORE","LATE","choiceOf","c","i","el","tag","className","text","Interactive","ctx","options","__publicField","m","d","e","color","_a","a","adoptStyle","css","item","v","_b","state","entry","extra","choice","t","box","ev","close","createIcon","pausedByUs","i18n","q","list","choices","buttons","b","status","choiceId","correct","results","_c","_d","_e","_f","base","n","total","s","pct","link","img","body","price","reason","installInteractive"],"mappings":";;;;;s5HAsBMA,IAAQ,mBAERC,IAAO;AAEb,SAASC,EAASC,GAA+BC,GAAyC;AACtF,SAAO,OAAOD,KAAM,WAAW,EAAE,IAAI,OAAOC,CAAC,GAAG,MAAMD,EAAA,IAAM,EAAE,IAAIA,EAAE,MAAM,OAAOC,CAAC,GAAG,MAAMD,EAAE,KAAA;AACjG;AAEA,SAASE,EAA0CC,GAAQC,GAAmBC,GAAyC;AACnH,QAAM,IAAI,SAAS,cAAcF,CAAG;AACpC,WAAE,YAAYC,GACVC,MAAS,WAAW,EAAE,cAAcA,IACjC;AACX;AAOO,MAAMC,EAAY;AAAA,EAMrB,YACqBC,GACTC,GACV;AARM,IAAAC,EAAA,iBAAmB,CAAA;AACnB,IAAAA,EAAA,gBAA4G;AAC5G,IAAAA,EAAA,iBAAyB,CAAA;AACzB,IAAAA,EAAA,oBAAmD;AA6C1C,IAAAA,EAAA,qBAAc,MAAY;AACvC,iBAAWC,KAAK,KAAK,QAAS,CAAAA,EAAE,OAAA;AAChC,WAAK,UAAU,CAAA;AACf,YAAMC,IAAI,KAAK,IAAI,QAAQ;AAC3B,UAAI,OAAK,QAAQ,YAAY,MAAS,CAAC,OAAO,SAASA,CAAC,KAAKA,KAAK;AAClE,mBAAWC,KAAK,KAAK,SAAS;AAC1B,cAAIA,EAAE,KAAK,OAAO,KAAKA,EAAE,KAAK,OAAOD,EAAG;AACxC,gBAAMD,IAAI,KAAK,IAAI,iBAAiBE,EAAE,KAAK,OAAOD,GAAG,gBAAgB,cAAcC,EAAE,OAAOA,EAAE,KAAK,WAAWA,EAAE,KAAK,KAAK,GACpHC,IAAQD,EAAE,KAAK,eAAe,KAAK,QAAQ;AACjD,UAAIC,MAAOH,EAAE,MAAM,kBAAkBG,IACrC,KAAK,QAAQ,KAAKH,CAAC;AAAA,QACvB;AAAA,IACJ;AAGiB;AAAA,IAAAD,EAAA,mBAAY,MAAY;AACrC,WAAK,KAAK,IAAI;AACd,iBAAWG,KAAK,KAAK,QAAS,CAAAA,EAAE,OAAO;AAAA,IAC3C;AAEiB,IAAAH,EAAA,mBAAY,MAAY;AAErC,MAAI,KAAK,UAAU,CAAC,KAAK,OAAO,YAAU,KAAK,KAAK,SAAS;AAAA,IACjE;AAyBiB;AAAA,IAAAA,EAAA,kBAAW,MAAY;;AACpC,YAAM,IAAI,KAAK,IAAI,QAAQ;AAC3B,iBAAW,KAAK,KAAK,QAAS,CAAI,EAAE,KAAK,OAAO,IAAI,OAAO,QAAMK,IAAA,KAAK,WAAL,gBAAAA,EAAa,aAAS,OAAO;AAC9F,WAAK,OAAA;AAAA,IACT;AAEiB,IAAAL,EAAA,gBAAS,MAAY;AAClC,YAAM,IAAI,KAAK,IAAI,QAAQ,aACrBM,IAAI,KAAK;AACf,UAAIA;AAEA,YAAI,IAAIA,EAAE,MAAM,KAAK,OAAO,IAAK,MAAK,KAAK,MAAM;AAAA,iBACxC,CAACA,EAAE,YAAY,KAAKA,EAAE,UAAU,KAAK,SAASA,EAAE,MAAM,IAAI,EAAG,MAAK,KAAK,SAAS;AAAA,iBAEhFA,EAAE,YAAY,KAAK,QAAQ,KAAK,CAAC,MAAM,CAAC,EAAE,QAAQ,KAAK,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,QAAQjB,CAAI,EAAG,MAAK,KAAK,IAAI;AAAA,YAClH;AAET,UAAI,MAAK,IAAI;AACb,mBAAW,KAAK,KAAK;AACjB,cAAI,IAAE,QAAQ,IAAI,EAAE,KAAK,UACzB,EAAE,OAAO,IAEL,MAAI,EAAE,KAAK,OAAOA,KAAQ,KAAK,WAAW,CAAC,KAC/C;AAAA,iBAAK,KAAK,GAAG,CAAC;AACd;AAAA;AAAA;AAAA,IAER;AApHqB,SAAA,MAAAS,GACT,KAAA,UAAAC,GAERQ,EAAWT,EAAI,WAAW,eAAeU,CAAG,GAC5C,KAAK,UAAUT,EAAQ,MAAM,IAAI,CAACU,GAAMjB,OAAO,EAAE,MAAAiB,GAAM,IAAIA,EAAK,MAAM,IAAIjB,CAAC,IAAI,MAAM,KAAQ;AAC7F,UAAMkB,IAAIZ,EAAI;AACd,IAAAY,EAAE,iBAAiB,cAAc,KAAK,MAAM,GAC5CA,EAAE,iBAAiB,UAAU,KAAK,QAAQ,GAC1CA,EAAE,iBAAiB,kBAAkB,KAAK,WAAW,GACrDA,EAAE,iBAAiB,WAAW,KAAK,SAAS,GAC5CZ,EAAI,OAAO,iBAAiB,cAAc,KAAK,SAAS,GACpDY,EAAE,cAAc,KAAG,KAAK,YAAA;AAAA,EAChC;AAAA;AAAA,EAGA,WAAWX,GAAmC;AAC1C,SAAK,UAAUA;AAAA,EACnB;AAAA,EAEA,gBAAsB;;AAElB,KAAAY,KAAAN,IAAA,KAAK,WAAL,gBAAAA,EAAa,GAAG,cAAc,oBAA9B,QAAAM,EAA+C,aAAa,cAAc,KAAK,IAAI,KAAK;AAAA,EAC5F;AAAA,EAEA,UAAgB;AACZ,UAAMD,IAAI,KAAK,IAAI;AACnB,IAAAA,EAAE,oBAAoB,cAAc,KAAK,MAAM,GAC/CA,EAAE,oBAAoB,UAAU,KAAK,QAAQ,GAC7CA,EAAE,oBAAoB,kBAAkB,KAAK,WAAW,GACxDA,EAAE,oBAAoB,WAAW,KAAK,SAAS,GAC/C,KAAK,IAAI,OAAO,oBAAoB,cAAc,KAAK,SAAS,GAChE,KAAK,KAAK,IAAI;AACd,eAAWT,KAAK,KAAK,QAAS,CAAAA,EAAE,OAAA;AAChC,SAAK,UAAU,CAAA;AAAA,EACnB;AAAA,EAEQ,KAAKW,GAAiDC,GAAcC,IAAiC,CAAA,GAAa;AACtH,WAAO,KAAK,IAAI,OAAO;AAAA,MACnB,IAAI,YAAY,kBAAkB,EAAE,QAAQ,EAAE,OAAAF,GAAO,IAAIC,EAAM,IAAI,MAAMA,EAAM,KAAK,MAAM,GAAGC,EAAA,GAAS,YAAYF,MAAU,SAAS;AAAA,IAAA;AAAA,EAE7I;AAAA,EA2BQ,WAAWC,GAAuB;AACtC,QAAI,KAAK,QAAQ,oBAAoB,MAAUA,EAAM,KAAK,SAAS,UAAUA,EAAM,KAAK,SAAS,OAAS,QAAO;AACjH,QAAI;AACA,aAAO,aAAa,QAAQzB,IAAQyB,EAAM,EAAE,MAAM;AAAA,IACtD,QAAQ;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEQ,SAASA,GAAcE,GAAsB;AACjD,QAAI,KAAK,QAAQ,oBAAoB;AACrC,UAAI;AACA,qBAAa,QAAQ3B,IAAQyB,EAAM,IAAI,OAAOE,CAAM,CAAC;AAAA,MACzD,QAAQ;AAAA,MAER;AAAA,EACJ;AAAA,EAEQ,SAASN,GAA+B;AAC5C,WAAOA,EAAK,aAAaA,EAAK,SAAS,UAAUA,EAAK,SAAS,SAAS,KAAK;AAAA,EACjF;AAAA,EA+BQ,KAAKI,GAAcG,GAAiB;AACxC,UAAMP,IAAOI,EAAM,MACbI,IAAMxB,EAAG,OAAO,OAAO;AAC7B,IAAAwB,EAAI,aAAa,QAAQ,2BAA2BR,EAAK,IAAI,EAAE,GAC/DQ,EAAI,aAAa,aAAaR,EAAK,IAAI,GACvCQ,EAAI,aAAa,iBAAiBR,EAAK,aAAaA,EAAK,SAAS,UAAUA,EAAK,SAAS,SAAS,cAAc,eAAe,GAChIQ,EAAI,aAAa,QAAQ,OAAO;AAChC,eAAWC,KAAM,CAAC,eAAe,SAAS,UAAU,EAAY,CAAAD,EAAI,iBAAiBC,GAAI,CAACf,MAAMA,EAAE,iBAAiB;AAGnH,QAFAc,EAAI,iBAAiB,WAAW,CAACd,MAAMA,EAAE,iBAAiB,GAEtDM,EAAK,gBAAgB,IAAO;AAC5B,YAAMU,IAAQ1B,EAAG,UAAU,aAAa;AACxC,MAAA0B,EAAM,OAAO,UACbA,EAAM,aAAa,cAAc,KAAK,IAAI,KAAK,gBAAgB,GAC/DA,EAAM,YAAYC,EAAW,OAAO,CAAC,GACrCD,EAAM,iBAAiB,SAAS,MAAM,KAAK,KAAK,MAAM,CAAC,GACvDF,EAAI,YAAYE,CAAK;AAAA,IACzB;AAEA,IAAIV,EAAK,SAAS,UAAUA,EAAK,SAAS,SAAQ,KAAK,cAAcQ,GAAKJ,CAAK,IAC1E,KAAK,UAAUI,GAAKJ,GAAOJ,CAAI,GAEpC,KAAK,IAAI,UAAU,YAAYQ,CAAG;AAClC,UAAMP,IAAI,KAAK,IAAI,SACbW,IAAa,CAAC,CAACZ,EAAK,SAAS,CAACC,EAAE;AACtC,IAAIW,OAAc,MAAA,GAClB,KAAK,SAAS,EAAE,OAAAR,GAAO,IAAII,GAAK,SAASD,GAAG,YAAAK,GAAY,UAAU,GAAA,GAClE,KAAK,KAAK,SAASR,CAAK;AAAA,EAC5B;AAAA,EAEQ,cAAcI,GAAkBJ,GAAoB;AACxD,UAAMJ,IAAOI,EAAM,MACbS,IAAO,KAAK,IAAI;AACtB,IAAAL,EAAI,YAAYxB,EAAG,QAAQ,eAAegB,EAAK,SAAS,SAASa,EAAK,kBAAkBA,EAAK,eAAe,CAAC;AAC7G,UAAMC,IAAI9B,EAAG,KAAK,kBAAkBgB,EAAK,QAAQ;AACjD,IAAAc,EAAE,KAAK,WAAWV,EAAM,EAAE,IAC1BI,EAAI,aAAa,mBAAmBM,EAAE,EAAE,GACxCN,EAAI,YAAYM,CAAC;AACjB,UAAMC,IAAO/B,EAAG,OAAO,eAAe,GAChCgC,IAAUhB,EAAK,QAAQ,IAAInB,CAAQ,GACnCoC,IAAUD,EAAQ,IAAI,CAAClC,GAAGC,MAAM;AAClC,YAAMmC,IAAIlC,EAAG,UAAU,cAAc;AACrC,aAAAkC,EAAE,OAAO,UACTA,EAAE,YAAYlC,EAAG,QAAQ,qBAAqBF,EAAE,IAAI,CAAC,GACrDoC,EAAE,iBAAiB,SAAS,MAAM,KAAK,KAAK,OAAOd,GAAOrB,GAAGiC,EAAQjC,CAAC,EAAG,IAAIkC,CAAO,CAAC,GACrFF,EAAK,YAAYG,CAAC,GACXA;AAAA,IACX,CAAC;AACD,IAAAV,EAAI,YAAYO,CAAI;AACpB,UAAMI,IAASnC,EAAG,KAAK,cAAc;AACrC,IAAAmC,EAAO,aAAa,aAAa,QAAQ,GACzCX,EAAI,YAAYW,CAAM;AAAA,EAC1B;AAAA,EAEA,MAAc,OAAOf,GAAcE,GAAgBc,GAAkBH,GAA6C;;AAC9G,UAAMpB,IAAI,KAAK;AACf,QAAI,CAACA,KAAKA,EAAE,UAAUO,KAASP,EAAE,SAAU;AAC3C,IAAAA,EAAE,WAAW;AACb,UAAMG,IAAOI,EAAM,MACbiB,IAAUrB,EAAK,SAAS,SAASM,MAAWN,EAAK,SAAS;AAChE,SAAK,SAASI,GAAOE,CAAM;AAC3B,eAAWY,KAAKD,EAAS,CAAAC,EAAE,WAAW;AACtC,KAAAtB,IAAAqB,EAAQX,CAAM,MAAd,QAAAV,EAAiB,aAAa,eAAe;AAC7C,UAAMuB,IAAStB,EAAE,GAAG,cAA2B,eAAe;AAC9D,SAAK,KAAK,UAAUO,GAAO,EAAE,QAAAE,GAAQ,UAAAc,GAAU,GAAIC,MAAY,SAAY,EAAE,SAAAA,EAAA,IAAY,CAAA,GAAK;AAE9F,QAAIC;AACJ,QAAI;AACA,MAAAA,IAAU,QAAMC,KAAArB,IAAA,KAAK,SAAQ,aAAb,gBAAAqB,EAAA,KAAArB,GAAwB,EAAE,MAAAF,GAAM,IAAII,EAAM,IAAI,QAAAE,GAAQ,UAAAc,GAAU,SAAAC,EAAA;AAAA,IACpF,QAAQ;AACJ,MAAAC,IAAU;AAAA,IACd;AACA,UAAIE,IAAA,KAAK,WAAL,gBAAAA,EAAa,WAAUpB,GAE3B;AAAA,UAAIJ,EAAK,SAAS;AACd,SAAAyB,IAAAR,EAAQjB,EAAK,MAAM,MAAnB,QAAAyB,EAAsB,aAAa,gBAAgB,KAC9CJ,MAASK,IAAAT,EAAQX,CAAM,MAAd,QAAAoB,EAAiB,aAAa,cAAc,KACtDP,QAAe,cAAc,GAAGE,IAAU,KAAK,IAAI,KAAK,qBAAqB,KAAK,IAAI,KAAK,gBAAgB,GAAGrB,EAAK,cAAc,IAAIA,EAAK,WAAW,KAAK,EAAE;AAAA,WAC7J;AAEH,cAAM2B,IAAO,MAAM,QAAQL,CAAO,IAAIA,IAAUtB,EAAK,UAAUA,EAAK,QAAQ,IAAI,CAAC4B,GAAG7C,MAAM6C,KAAK7C,MAAMuB,IAAS,IAAI,EAAE,IAAI;AACxH,YAAIqB,GAAM;AACN,gBAAME,IAAQF,EAAK,OAAO,CAACG,GAAGF,MAAME,KAAK,OAAO,SAASF,CAAC,KAAKA,IAAI,IAAIA,IAAI,IAAI,CAAC,KAAK;AACrF,UAAAX,EAAQ,QAAQ,CAACC,GAAGnC,MAAM;AACtB,kBAAMgD,IAAM,KAAK,OAAQJ,EAAK5C,CAAC,KAAK,KAAK8C,IAAS,GAAG;AACrD,YAAAX,EAAE,MAAM,YAAY,eAAe,GAAGa,CAAG,GAAG,GAC5Cb,EAAE,aAAa,eAAe,EAAE,GAChCA,EAAE,YAAYlC,EAAG,QAAQ,aAAa,KAAK,IAAI,KAAK,iBAAiB+C,CAAG,CAAC,CAAC;AAAA,UAC9E,CAAC;AAAA,QACL;AAAA,MACJ;AAEA,WAAK,aAAa,WAAW,MAAM,KAAK,KAAK,IAAI,GAAG/B,EAAK,SAAS,SAAS,MAAO,IAAI;AAAA;AAAA,EAC1F;AAAA,EAEQ,UAAUQ,GAAkBJ,GAAcJ,GAA6B;AAC3E,UAAMa,IAAO,KAAK,IAAI,MAChBmB,IAAOhD,EAAG,KAAK,YAAY;AAMjC,QALAgD,EAAK,OAAOhC,EAAK,KACbA,EAAK,WAAW,OAChBgC,EAAK,SAAS,UACdA,EAAK,MAAM,aAEXhC,EAAK,OAAO;AACZ,YAAMiC,IAAMjD,EAAG,OAAO,aAAa;AACnC,MAAAiD,EAAI,MAAMjC,EAAK,OACfiC,EAAI,MAAM,IACVA,EAAI,WAAW,SACfA,EAAI,iBAAiB,SAAS,MAAMA,EAAI,QAAQ,GAChDD,EAAK,YAAYC,CAAG;AAAA,IACxB;AACA,UAAMC,IAAOlD,EAAG,QAAQ,YAAY;AAIpC,QAHIgB,EAAK,aAAWkC,EAAK,YAAYlD,EAAG,QAAQ,eAAe6B,EAAK,oBAAoB,CAAC,GACzFqB,EAAK,YAAYlD,EAAG,QAAQ,eAAegB,EAAK,KAAK,CAAC,GAClDA,EAAK,YAAUkC,EAAK,YAAYlD,EAAG,QAAQ,aAAagB,EAAK,QAAQ,CAAC,GACtEA,EAAK,SAASA,EAAK,UAAU;AAC7B,YAAMmC,IAAQnD,EAAG,QAAQ,aAAa;AACtC,MAAIgB,EAAK,SAAOmC,EAAM,YAAYnD,EAAG,UAAU,IAAIgB,EAAK,KAAK,CAAC,GAC1DA,EAAK,YAAUmC,EAAM,YAAYnD,EAAG,KAAK,IAAIgB,EAAK,QAAQ,CAAC,GAC/DkC,EAAK,YAAYC,CAAK;AAAA,IAC1B;AACA,IAAAD,EAAK,YAAYlD,EAAG,QAAQ,aAAagB,EAAK,QAAQA,EAAK,SAAS,YAAYa,EAAK,iBAAiBA,EAAK,cAAc,CAAC,GAC1HmB,EAAK,YAAYE,CAAI,GACrBF,EAAK,iBAAiB,SAAS,CAACtC,MAAM;AAElC,MAAK,KAAK,KAAK,SAASU,GAAO,EAAE,KAAKJ,EAAK,IAAA,CAAK,KAAGN,EAAE,eAAA;AAAA,IACzD,CAAC,GACDc,EAAI,aAAa,cAAcR,EAAK,KAAK,GACzCQ,EAAI,YAAYwB,CAAI;AAAA,EACxB;AAAA,EAEQ,KAAKI,GAAkD;AAC3D,IAAI,KAAK,cAAY,aAAa,KAAK,UAAU,GACjD,KAAK,aAAa;AAClB,UAAMvC,IAAI,KAAK;AACf,IAAKA,MACL,KAAK,SAAS,MACdA,EAAE,GAAG,OAAA,GACDuC,UAAa,KAAK,WAAWvC,EAAE,OAAO,EAAE,QAAAuC,GAAQ,GAChDvC,EAAE,cAAcuC,MAAW,UAAa,KAAK,IAAI,QAAQ,KAAA,EAAO,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACtF;AACJ;ACjTO,SAASC,EAAmBhD,GAA+BC,GAA0C;AACxG,SAAO,IAAIF,EAAYC,GAAKC,CAAO;AACvC;"}