@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
@@ -1,208 +0,0 @@
1
- var w = Object.defineProperty;
2
- var N = (o, e, t) => e in o ? w(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
- var l = (o, e, t) => N(o, typeof e != "symbol" ? e + "" : e, t);
4
- import { c as f } from "./player-D7WQxMzr.js";
5
- const b = "http://www.w3.org/2000/svg", C = 18, g = 2 * Math.PI * C, A = 10;
6
- function y(o) {
7
- const e = document.createElementNS(b, "svg");
8
- e.setAttribute("viewBox", "0 0 40 40"), e.setAttribute("aria-hidden", "true"), e.setAttribute("class", o);
9
- const t = document.createElementNS(b, "circle"), i = document.createElementNS(b, "circle");
10
- for (const n of [t, i])
11
- n.setAttribute("cx", "20"), n.setAttribute("cy", "20"), n.setAttribute("r", String(C));
12
- return t.setAttribute("class", "hp-redirect-ring-track"), i.setAttribute("class", "hp-redirect-ring-bar"), i.setAttribute("stroke-dasharray", String(g)), e.append(t, i), {
13
- el: e,
14
- set: (n) => i.setAttribute("stroke-dashoffset", String(g * (1 - Math.min(1, Math.max(0, n)))))
15
- };
16
- }
17
- function E(o, e, t) {
18
- const i = document.createElement("span");
19
- if (i.className = t, o) {
20
- const s = document.createElement("img");
21
- s.src = o, s.alt = "", s.decoding = "async", s.addEventListener("error", () => s.remove()), i.appendChild(s);
22
- }
23
- const n = y("hp-redirect-ring"), r = document.createElement("span");
24
- if (r.className = "hp-redirect-play", r.appendChild(f("play")), i.append(n.el, r), e) {
25
- const s = document.createElement("span");
26
- s.className = "hp-redirect-duration", s.textContent = e, i.appendChild(s);
27
- }
28
- return { el: i, ring: n };
29
- }
30
- class L {
31
- constructor(e, t) {
32
- l(this, "counterTimer", null);
33
- l(this, "wrapper", null);
34
- l(this, "card", null);
35
- l(this, "cardRing", null);
36
- l(this, "cardLabel", null);
37
- l(this, "cancelled", !1);
38
- l(this, "waitingForAd", !1);
39
- l(this, "mode");
40
- l(this, "onPlay", () => {
41
- this.remove();
42
- });
43
- l(this, "onEnded", () => {
44
- if (this.ctx.isAdActive()) {
45
- this.waitForAd();
46
- return;
47
- }
48
- this.finish();
49
- });
50
- l(this, "onAdEnd", () => {
51
- this.ctx.hostEl.removeEventListener("hp:adend", this.onAdEnd), this.waitingForAd = !1, this.ctx.videoEl.ended && this.finish();
52
- });
53
- // ── 'card' modu ─────────────────────────────────────────────────────────
54
- l(this, "onTimeUpdate", () => {
55
- var s;
56
- const e = this.ctx.videoEl, t = Math.max(1, this.options.showBefore ?? A), i = e.duration;
57
- if (!Number.isFinite(i) || i <= 0) return;
58
- const n = i - e.currentTime;
59
- if (n > t) {
60
- n > t + 1 && (this.cancelled = !1), this.hideCard();
61
- return;
62
- }
63
- if (this.cancelled || this.ctx.isAdActive() || e.ended || n <= 0) {
64
- this.ctx.isAdActive() && this.hideCard();
65
- return;
66
- }
67
- this.card || this.showCard();
68
- const r = Math.ceil(n);
69
- (s = this.cardRing) == null || s.set(n / t), this.cardLabel && (this.cardLabel.textContent = `${this.options.label ?? this.ctx.i18n.redirectUpNext} · ${r}`);
70
- });
71
- this.ctx = e, this.options = t, this.mode = t.mode === "card" ? "card" : "screen", t.enabled !== !1 && (e.videoEl.addEventListener("ended", this.onEnded), e.videoEl.addEventListener("play", this.onPlay), this.mode === "card" && e.videoEl.addEventListener("timeupdate", this.onTimeUpdate));
72
- }
73
- /** Ekranlar her gösterimde güncel `ctx.i18n` ile kurulur; açık kartın etiketi burada tazelenir. */
74
- refreshLabels() {
75
- var e, t;
76
- (t = (e = this.card) == null ? void 0 : e.querySelector(".hp-redirect-close")) == null || t.setAttribute("aria-label", this.ctx.i18n.redirectCancelCard);
77
- }
78
- destroy() {
79
- const e = this.ctx.videoEl;
80
- e.removeEventListener("ended", this.onEnded), e.removeEventListener("play", this.onPlay), e.removeEventListener("timeupdate", this.onTimeUpdate), this.ctx.hostEl.removeEventListener("hp:adend", this.onAdEnd), this.remove(), this.hideCard();
81
- }
82
- emit(e, t) {
83
- return this.ctx.hostEl.dispatchEvent(
84
- new CustomEvent("hp:redirect", { detail: { state: e, url: this.options.url, mode: this.mode, reason: t }, cancelable: e === "redirect" })
85
- );
86
- }
87
- go(e) {
88
- this.remove(), this.hideCard(), this.emit("redirect", e) && (this.options.newTab ? window.open(this.options.url, "_blank", "noopener") : window.location.href = this.options.url);
89
- }
90
- waitForAd() {
91
- this.waitingForAd || (this.waitingForAd = !0, this.ctx.hostEl.addEventListener("hp:adend", this.onAdEnd));
92
- }
93
- finish() {
94
- var e;
95
- if (this.mode === "card") {
96
- this.hideCard(), this.cancelled ? (e = this.options.suggestions) != null && e.length && this.showSuggestions(this.options.suggestions) : this.go("auto");
97
- return;
98
- }
99
- this.createScreen();
100
- }
101
- showCard() {
102
- const e = this.options, t = document.createElement("div");
103
- t.className = "hp-redirect-card", t.setAttribute("part", "redirect-card"), t.setAttribute("data-position", e.position ?? "bottom-right");
104
- const i = document.createElement("button");
105
- i.type = "button", i.className = "hp-redirect-card-main", i.addEventListener("click", () => this.go("click"));
106
- const n = E(e.image, e.duration, "hp-redirect-thumb"), r = document.createElement("span");
107
- r.className = "hp-redirect-text";
108
- const s = document.createElement("span");
109
- if (s.className = "hp-redirect-label", r.appendChild(s), e.title) {
110
- const a = document.createElement("span");
111
- a.className = "hp-redirect-title", a.textContent = e.title, r.appendChild(a);
112
- }
113
- if (e.subtitle) {
114
- const a = document.createElement("span");
115
- a.className = "hp-redirect-sub", a.textContent = e.subtitle, r.appendChild(a);
116
- }
117
- n.el.setAttribute("aria-hidden", "true");
118
- const d = document.createElement("span");
119
- d.className = "hp-sr-only", d.textContent = ` — ${this.ctx.i18n.redirectPlayNow}`, r.appendChild(d), i.append(n.el, r);
120
- const h = document.createElement("button");
121
- h.type = "button", h.className = "hp-redirect-close", h.setAttribute("aria-label", this.ctx.i18n.redirectCancelCard), h.appendChild(f("close")), h.addEventListener("click", () => {
122
- this.cancelled = !0, this.hideCard(), this.emit("cancel");
123
- }), t.append(i, h);
124
- for (const a of ["pointerdown", "click", "dblclick"]) t.addEventListener(a, (p) => p.stopPropagation());
125
- this.ctx.overlayContainerEl.appendChild(t), this.card = t, this.cardRing = n.ring, this.cardLabel = s, this.emit("shown");
126
- }
127
- hideCard() {
128
- var e;
129
- (e = this.card) == null || e.remove(), this.card = null, this.cardRing = null, this.cardLabel = null;
130
- }
131
- // ── 'screen' modu ───────────────────────────────────────────────────────
132
- remove() {
133
- var e;
134
- this.counterTimer && (clearInterval(this.counterTimer), this.counterTimer = null), (e = this.wrapper) == null || e.remove(), this.wrapper = null;
135
- }
136
- createScreen() {
137
- this.remove();
138
- const e = this.options, t = document.createElement("div");
139
- if (t.setAttribute("part", "redirect-screen"), t.className = "hp-redirect-screen", e.image) {
140
- const c = document.createElement("img");
141
- c.className = "hp-redirect-bg", c.src = e.image, c.alt = "", c.addEventListener("error", () => c.remove()), t.appendChild(c);
142
- }
143
- const i = document.createElement("div");
144
- i.className = "hp-redirect-panel";
145
- const n = document.createElement("span");
146
- n.className = "hp-redirect-label", n.textContent = e.label ?? this.ctx.i18n.redirectUpNext, i.appendChild(n);
147
- const r = document.createElement("button");
148
- r.type = "button", r.className = "hp-redirect-poster", r.setAttribute("aria-label", this.ctx.i18n.redirectPlayNow);
149
- const s = E(e.image, e.duration, "hp-redirect-thumb");
150
- if (r.appendChild(s.el), r.addEventListener("click", () => this.go("click")), i.appendChild(r), e.title) {
151
- const c = document.createElement("div");
152
- c.className = "hp-redirect-title", c.textContent = e.title, i.appendChild(c);
153
- }
154
- if (e.subtitle) {
155
- const c = document.createElement("div");
156
- c.className = "hp-redirect-sub", c.textContent = e.subtitle, i.appendChild(c);
157
- }
158
- const d = document.createElement("div");
159
- d.className = "hp-redirect-counter", d.setAttribute("aria-live", "polite"), i.appendChild(d);
160
- const h = document.createElement("div");
161
- h.className = "hp-redirect-actions";
162
- const a = document.createElement("button");
163
- a.type = "button", a.className = "hp-redirect-btn", a.textContent = this.ctx.i18n.redirectCancel;
164
- const p = document.createElement("button");
165
- p.type = "button", p.className = "hp-redirect-btn hp-redirect-btn-primary", p.textContent = this.ctx.i18n.redirectPlayNow, p.addEventListener("click", () => this.go("click")), a.addEventListener("click", () => {
166
- var c;
167
- this.remove(), this.emit("cancel"), (c = e.suggestions) != null && c.length && this.showSuggestions(e.suggestions);
168
- }), h.append(a, p), i.appendChild(h), t.appendChild(i);
169
- for (const c of ["pointerdown", "click", "dblclick"]) t.addEventListener(c, (x) => x.stopPropagation());
170
- this.ctx.overlayContainerEl.appendChild(t), this.wrapper = t, this.emit("shown");
171
- const u = Math.max(0, e.time);
172
- let m = u;
173
- const v = () => {
174
- d.textContent = this.ctx.i18n.redirectCountdown(m), s.ring.set(u > 0 ? m / u : 0);
175
- };
176
- v(), this.counterTimer = setInterval(() => {
177
- if (m--, m > 0) {
178
- v();
179
- return;
180
- }
181
- this.counterTimer && clearInterval(this.counterTimer), this.counterTimer = null, d.textContent = this.ctx.i18n.redirectNowPlaying, s.ring.set(0), this.go("auto");
182
- }, 1e3);
183
- }
184
- showSuggestions(e) {
185
- var i;
186
- this.remove();
187
- const t = document.createElement("div");
188
- t.setAttribute("part", "redirect-suggestions"), t.className = "hp-redirect-suggestions";
189
- for (const n of e) {
190
- const r = document.createElement("a");
191
- r.href = n.url, this.options.newTab && (r.target = "_blank", r.rel = "noopener"), r.className = "hp-redirect-suggestion";
192
- const s = E(n.image, n.duration, "hp-redirect-thumb");
193
- (i = s.el.querySelector(".hp-redirect-ring")) == null || i.remove();
194
- const d = document.createElement("span");
195
- d.className = "hp-redirect-title", d.textContent = n.title, r.append(s.el, d), t.appendChild(r);
196
- }
197
- for (const n of ["pointerdown", "click", "dblclick"]) t.addEventListener(n, (r) => r.stopPropagation());
198
- this.ctx.overlayContainerEl.appendChild(t), this.wrapper = t;
199
- }
200
- }
201
- function T(o, e) {
202
- return new L(o, e);
203
- }
204
- export {
205
- L as RedirectScreen,
206
- T as installRedirectScreen
207
- };
208
- //# sourceMappingURL=redirectScreen-5HAVRtxe.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"redirectScreen-5HAVRtxe.js","sources":["../../src/plugins/redirect-screen/RedirectScreen.ts","../../src/plugins/redirect-screen/index.ts"],"sourcesContent":["import type { RedirectScreenOptions, RedirectScreenSuggestion } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { createIcon } from '../../icons/Icon';\n\nexport interface RedirectScreenPlayerContext {\n /** hp:redirect olayları ve postroll'un bitişini (hp:adend) dinlemek için. */\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n overlayContainerEl: HTMLElement;\n isAdActive(): boolean;\n i18n: HopeLocaleStrings;\n}\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\nconst RING_R = 18;\nconst RING_C = 2 * Math.PI * RING_R;\nconst DEFAULT_SHOW_BEFORE = 10;\n\n/** Dairesel geri sayım halkası (SVG) — `set(oran)` ile 1 → 0 boşalır. */\nfunction ring(className: string): { el: SVGSVGElement; set(fraction: number): void } {\n const svg = document.createElementNS(SVG_NS, 'svg');\n svg.setAttribute('viewBox', '0 0 40 40');\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('class', className);\n const track = document.createElementNS(SVG_NS, 'circle');\n const bar = document.createElementNS(SVG_NS, 'circle');\n for (const c of [track, bar]) {\n c.setAttribute('cx', '20');\n c.setAttribute('cy', '20');\n c.setAttribute('r', String(RING_R));\n }\n track.setAttribute('class', 'hp-redirect-ring-track');\n bar.setAttribute('class', 'hp-redirect-ring-bar');\n bar.setAttribute('stroke-dasharray', String(RING_C));\n svg.append(track, bar);\n return {\n el: svg,\n set: (fraction) => bar.setAttribute('stroke-dashoffset', String(RING_C * (1 - Math.min(1, Math.max(0, fraction))))),\n };\n}\n\n/** Görsel + süre rozeti + oynat ikonu + halka — kart ve tam ekran aynı parçayı kullanır. */\nfunction thumb(image: string | undefined, duration: string | undefined, className: string): { el: HTMLSpanElement; ring: ReturnType<typeof ring> } {\n const el = document.createElement('span');\n el.className = className;\n if (image) {\n const img = document.createElement('img');\n img.src = image;\n img.alt = '';\n img.decoding = 'async';\n img.addEventListener('error', () => img.remove());\n el.appendChild(img);\n }\n const r = ring('hp-redirect-ring');\n const play = document.createElement('span');\n play.className = 'hp-redirect-play';\n play.appendChild(createIcon('play'));\n el.append(r.el, play);\n if (duration) {\n const d = document.createElement('span');\n d.className = 'hp-redirect-duration';\n d.textContent = duration;\n el.appendChild(d);\n }\n return { el, ring: r };\n}\n\n/**\n * Sıradaki videoya yönlendirme. İki mod:\n * - 'screen' (varsayılan): video bitince tam alan ekran + `time` sn geri sayım; iptal → öneriler.\n * - 'card': bitime `showBefore` sn kala köşede küçük \"Sıradaki\" kartı; geri sayım videoyla birlikte işler (duraklatınca\n * durur), video bitince yönlendirilir. Karta tıklamak hemen yönlendirir, X iptal eder.\n * Bitişte postroll oynuyorsa yönlendirme reklam bitene kadar bekler. `hp:redirect` (state: redirect) iptal edilirse\n * (`preventDefault`) sayfa değişmez.\n */\nexport class RedirectScreen {\n private counterTimer: ReturnType<typeof setInterval> | null = null;\n private wrapper: HTMLElement | null = null;\n private card: HTMLDivElement | null = null;\n private cardRing: ReturnType<typeof ring> | null = null;\n private cardLabel: HTMLSpanElement | null = null;\n private cancelled = false;\n private waitingForAd = false;\n private readonly mode: 'screen' | 'card';\n\n constructor(\n private readonly ctx: RedirectScreenPlayerContext,\n private readonly options: RedirectScreenOptions\n ) {\n this.mode = options.mode === 'card' ? 'card' : 'screen';\n if (options.enabled === false) return;\n ctx.videoEl.addEventListener('ended', this.onEnded);\n ctx.videoEl.addEventListener('play', this.onPlay);\n if (this.mode === 'card') ctx.videoEl.addEventListener('timeupdate', this.onTimeUpdate);\n }\n\n /** Ekranlar her gösterimde güncel `ctx.i18n` ile kurulur; açık kartın etiketi burada tazelenir. */\n refreshLabels(): void {\n this.card?.querySelector('.hp-redirect-close')?.setAttribute('aria-label', this.ctx.i18n.redirectCancelCard);\n }\n\n destroy(): void {\n const v = this.ctx.videoEl;\n v.removeEventListener('ended', this.onEnded);\n v.removeEventListener('play', this.onPlay);\n v.removeEventListener('timeupdate', this.onTimeUpdate);\n this.ctx.hostEl.removeEventListener('hp:adend', this.onAdEnd);\n this.remove();\n this.hideCard();\n }\n\n private emit(state: 'shown' | 'cancel' | 'redirect', reason?: 'auto' | 'click'): boolean {\n return this.ctx.hostEl.dispatchEvent(\n new CustomEvent('hp:redirect', { detail: { state, url: this.options.url, mode: this.mode, reason }, cancelable: state === 'redirect' })\n );\n }\n\n private go(reason: 'auto' | 'click'): void {\n this.remove();\n this.hideCard();\n if (!this.emit('redirect', reason)) return; // entegratör kendisi yönlendirecek\n if (this.options.newTab) window.open(this.options.url, '_blank', 'noopener');\n else window.location.href = this.options.url;\n }\n\n private readonly onPlay = (): void => {\n this.remove();\n };\n\n private readonly onEnded = (): void => {\n // Postroll oynuyorsa (ya da birazdan başlayacaksa) reklam bitince devam.\n if (this.ctx.isAdActive()) {\n this.waitForAd();\n return;\n }\n this.finish();\n };\n\n private waitForAd(): void {\n if (this.waitingForAd) return;\n this.waitingForAd = true;\n this.ctx.hostEl.addEventListener('hp:adend', this.onAdEnd);\n }\n\n private readonly onAdEnd = (): void => {\n this.ctx.hostEl.removeEventListener('hp:adend', this.onAdEnd);\n this.waitingForAd = false;\n if (this.ctx.videoEl.ended) this.finish();\n };\n\n private finish(): void {\n if (this.mode === 'card') {\n this.hideCard();\n if (!this.cancelled) this.go('auto');\n else if (this.options.suggestions?.length) this.showSuggestions(this.options.suggestions);\n return;\n }\n this.createScreen();\n }\n\n // ── 'card' modu ─────────────────────────────────────────────────────────\n\n private readonly onTimeUpdate = (): void => {\n const v = this.ctx.videoEl;\n const showBefore = Math.max(1, this.options.showBefore ?? DEFAULT_SHOW_BEFORE);\n const d = v.duration;\n if (!Number.isFinite(d) || d <= 0) return; // canlı yayında kart yok\n const remaining = d - v.currentTime;\n if (remaining > showBefore) {\n // Geri sarıldı (eşiğin belirgin üstüne): iptal unutulur — tekrar yaklaşınca kart yine gelir.\n if (remaining > showBefore + 1) this.cancelled = false;\n this.hideCard();\n return;\n }\n if (this.cancelled || this.ctx.isAdActive() || v.ended || remaining <= 0) {\n if (this.ctx.isAdActive()) this.hideCard();\n return;\n }\n if (!this.card) this.showCard();\n const secs = Math.ceil(remaining);\n this.cardRing?.set(remaining / showBefore);\n if (this.cardLabel) this.cardLabel.textContent = `${this.options.label ?? this.ctx.i18n.redirectUpNext} · ${secs}`;\n };\n\n private showCard(): void {\n const o = this.options;\n const card = document.createElement('div');\n card.className = 'hp-redirect-card';\n card.setAttribute('part', 'redirect-card');\n card.setAttribute('data-position', o.position ?? 'bottom-right');\n\n const main = document.createElement('button');\n main.type = 'button';\n main.className = 'hp-redirect-card-main';\n main.addEventListener('click', () => this.go('click'));\n const t = thumb(o.image, o.duration, 'hp-redirect-thumb');\n const text = document.createElement('span');\n text.className = 'hp-redirect-text';\n const label = document.createElement('span');\n label.className = 'hp-redirect-label';\n text.appendChild(label);\n if (o.title) {\n const title = document.createElement('span');\n title.className = 'hp-redirect-title';\n title.textContent = o.title;\n text.appendChild(title);\n }\n if (o.subtitle) {\n const sub = document.createElement('span');\n sub.className = 'hp-redirect-sub';\n sub.textContent = o.subtitle;\n text.appendChild(sub);\n }\n // Erişilebilir ad görünen metinden oluşur (\"Sıradaki · 4 Başlık Alt başlık\"); sonuna yalnızca ekran okuyucunun\n // duyduğu \"Şimdi oynat\" eklenir — görsel / süre rozeti okunmaz.\n t.el.setAttribute('aria-hidden', 'true');\n const action = document.createElement('span');\n action.className = 'hp-sr-only';\n action.textContent = ` — ${this.ctx.i18n.redirectPlayNow}`;\n text.appendChild(action);\n main.append(t.el, text);\n\n const close = document.createElement('button');\n close.type = 'button';\n close.className = 'hp-redirect-close';\n close.setAttribute('aria-label', this.ctx.i18n.redirectCancelCard);\n close.appendChild(createIcon('close'));\n close.addEventListener('click', () => {\n this.cancelled = true;\n this.hideCard();\n this.emit('cancel');\n });\n\n card.append(main, close);\n // Karta dokunmak videoyu oynat / duraklat yapmasın.\n for (const ev of ['pointerdown', 'click', 'dblclick'] as const) card.addEventListener(ev, (e) => e.stopPropagation());\n this.ctx.overlayContainerEl.appendChild(card);\n this.card = card;\n this.cardRing = t.ring;\n this.cardLabel = label;\n this.emit('shown');\n }\n\n private hideCard(): void {\n this.card?.remove();\n this.card = null;\n this.cardRing = null;\n this.cardLabel = null;\n }\n\n // ── 'screen' modu ───────────────────────────────────────────────────────\n\n private remove(): void {\n if (this.counterTimer) {\n clearInterval(this.counterTimer);\n this.counterTimer = null;\n }\n this.wrapper?.remove();\n this.wrapper = null;\n }\n\n private createScreen(): void {\n this.remove();\n const o = this.options;\n const wrapper = document.createElement('div');\n wrapper.setAttribute('part', 'redirect-screen');\n wrapper.className = 'hp-redirect-screen';\n\n if (o.image) {\n const bg = document.createElement('img');\n bg.className = 'hp-redirect-bg';\n bg.src = o.image;\n bg.alt = '';\n bg.addEventListener('error', () => bg.remove());\n wrapper.appendChild(bg);\n }\n\n const panel = document.createElement('div');\n panel.className = 'hp-redirect-panel';\n const label = document.createElement('span');\n label.className = 'hp-redirect-label';\n label.textContent = o.label ?? this.ctx.i18n.redirectUpNext;\n panel.appendChild(label);\n\n const poster = document.createElement('button');\n poster.type = 'button';\n poster.className = 'hp-redirect-poster';\n poster.setAttribute('aria-label', this.ctx.i18n.redirectPlayNow);\n const t = thumb(o.image, o.duration, 'hp-redirect-thumb');\n poster.appendChild(t.el);\n poster.addEventListener('click', () => this.go('click'));\n panel.appendChild(poster);\n\n if (o.title) {\n const title = document.createElement('div');\n title.className = 'hp-redirect-title';\n title.textContent = o.title;\n panel.appendChild(title);\n }\n if (o.subtitle) {\n const sub = document.createElement('div');\n sub.className = 'hp-redirect-sub';\n sub.textContent = o.subtitle;\n panel.appendChild(sub);\n }\n\n const counter = document.createElement('div');\n counter.className = 'hp-redirect-counter';\n counter.setAttribute('aria-live', 'polite');\n panel.appendChild(counter);\n\n const actions = document.createElement('div');\n actions.className = 'hp-redirect-actions';\n const cancelBtn = document.createElement('button');\n cancelBtn.type = 'button';\n cancelBtn.className = 'hp-redirect-btn';\n cancelBtn.textContent = this.ctx.i18n.redirectCancel;\n const acceptBtn = document.createElement('button');\n acceptBtn.type = 'button';\n acceptBtn.className = 'hp-redirect-btn hp-redirect-btn-primary';\n acceptBtn.textContent = this.ctx.i18n.redirectPlayNow;\n acceptBtn.addEventListener('click', () => this.go('click'));\n cancelBtn.addEventListener('click', () => {\n this.remove();\n this.emit('cancel');\n if (o.suggestions?.length) this.showSuggestions(o.suggestions);\n });\n actions.append(cancelBtn, acceptBtn);\n panel.appendChild(actions);\n wrapper.appendChild(panel);\n\n for (const ev of ['pointerdown', 'click', 'dblclick'] as const) wrapper.addEventListener(ev, (e) => e.stopPropagation());\n this.ctx.overlayContainerEl.appendChild(wrapper);\n this.wrapper = wrapper;\n this.emit('shown');\n\n const total = Math.max(0, o.time);\n let remaining = total;\n const render = (): void => {\n counter.textContent = this.ctx.i18n.redirectCountdown(remaining);\n t.ring.set(total > 0 ? remaining / total : 0);\n };\n render();\n this.counterTimer = setInterval(() => {\n remaining--;\n if (remaining > 0) {\n render();\n return;\n }\n if (this.counterTimer) clearInterval(this.counterTimer);\n this.counterTimer = null;\n counter.textContent = this.ctx.i18n.redirectNowPlaying;\n t.ring.set(0);\n this.go('auto');\n }, 1000);\n }\n\n private showSuggestions(items: RedirectScreenSuggestion[]): void {\n this.remove();\n const wrapper = document.createElement('div');\n wrapper.setAttribute('part', 'redirect-suggestions');\n wrapper.className = 'hp-redirect-suggestions';\n for (const item of items) {\n const box = document.createElement('a');\n box.href = item.url;\n if (this.options.newTab) {\n box.target = '_blank';\n box.rel = 'noopener';\n }\n box.className = 'hp-redirect-suggestion';\n const t = thumb(item.image, item.duration, 'hp-redirect-thumb');\n t.el.querySelector('.hp-redirect-ring')?.remove();\n const title = document.createElement('span');\n title.className = 'hp-redirect-title';\n title.textContent = item.title;\n box.append(t.el, title);\n wrapper.appendChild(box);\n }\n for (const ev of ['pointerdown', 'click', 'dblclick'] as const) wrapper.addEventListener(ev, (e) => e.stopPropagation());\n this.ctx.overlayContainerEl.appendChild(wrapper);\n this.wrapper = wrapper;\n }\n}\n","import { RedirectScreen, type RedirectScreenPlayerContext } from './RedirectScreen';\nimport type { RedirectScreenOptions } from '../../types';\n\nexport function installRedirectScreen(ctx: RedirectScreenPlayerContext, options: RedirectScreenOptions): RedirectScreen {\n return new RedirectScreen(ctx, options);\n}\n\nexport { RedirectScreen };\nexport type { RedirectScreenPlayerContext };\n"],"names":["SVG_NS","RING_R","RING_C","DEFAULT_SHOW_BEFORE","ring","className","svg","track","bar","c","fraction","thumb","image","duration","el","img","r","play","createIcon","d","RedirectScreen","ctx","options","__publicField","v","showBefore","remaining","secs","_a","_b","state","reason","o","card","main","t","text","label","title","sub","action","close","ev","e","wrapper","bg","panel","poster","counter","actions","cancelBtn","acceptBtn","total","render","items","item","box","installRedirectScreen"],"mappings":"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"}
@@ -1,63 +0,0 @@
1
- var m = Object.defineProperty;
2
- var v = (r, t, e) => t in r ? m(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
- var n = (r, t, e) => v(r, typeof t != "symbol" ? t + "" : t, e);
4
- import { f as E } from "./player-D7WQxMzr.js";
5
- class u {
6
- constructor(t, e) {
7
- n(this, "chapters", []);
8
- n(this, "chapterEls", []);
9
- n(this, "hoverIndex", -1);
10
- n(this, "tooltipEl");
11
- n(this, "titleEl");
12
- n(this, "timeEl");
13
- n(this, "onLoadedMetadata", () => {
14
- const t = this.ctx.videoEl.duration;
15
- !Number.isFinite(t) || t <= 0 || (this.chapters = f(this.segments, t), this.chapterEls = this.ctx.seekBar.setChapters(
16
- this.chapters.map((e) => ({ start: e.start / t, end: e.end / t, color: e.color }))
17
- ));
18
- });
19
- n(this, "onPointerMove", (t) => {
20
- const e = this.ctx.videoEl.duration;
21
- if (!this.chapters.length || !Number.isFinite(e) || e <= 0) return;
22
- const i = this.ctx.seekBar.ratioAtClientX(t.clientX) * e;
23
- let a = this.chapters.findIndex((c) => i < c.end);
24
- a === -1 && (a = this.chapters.length - 1), this.setHover(a);
25
- const s = this.chapters[a];
26
- this.titleEl.textContent = s.text ?? "", this.titleEl.style.display = s.text ? "" : "none", this.timeEl.textContent = E(i);
27
- const o = this.ctx.seekBar.el.querySelector('[part="sprite-tooltip"]'), l = o && o.hasAttribute("data-visible") && o.offsetHeight > 0 ? o.offsetHeight + 8 : 0;
28
- this.tooltipEl.style.bottom = l ? `calc(100% + 6px + ${l}px)` : "", this.timeEl.style.display = l ? "none" : "";
29
- const h = this.ctx.seekBar.el.getBoundingClientRect();
30
- this.tooltipEl.setAttribute("data-visible", "");
31
- const p = this.tooltipEl.offsetWidth, d = Math.min(Math.max(t.clientX - h.left - p / 2, 0), Math.max(h.width - p, 0));
32
- this.tooltipEl.style.transform = `translateX(${d}px)`;
33
- });
34
- n(this, "onPointerLeave", () => {
35
- this.setHover(-1), this.tooltipEl.removeAttribute("data-visible");
36
- });
37
- this.ctx = t, this.segments = e, this.tooltipEl = document.createElement("div"), this.tooltipEl.className = "hp-chapter-tooltip", this.tooltipEl.setAttribute("part", "segment-tooltip"), this.titleEl = document.createElement("div"), this.titleEl.className = "hp-chapter-tooltip-title", this.timeEl = document.createElement("div"), this.timeEl.className = "hp-chapter-tooltip-time", this.tooltipEl.append(this.titleEl, this.timeEl), t.seekBar.el.appendChild(this.tooltipEl), t.seekBar.suppressHoverTime("segments", !0), t.seekBar.el.addEventListener("pointermove", this.onPointerMove), t.seekBar.el.addEventListener("pointerleave", this.onPointerLeave), t.videoEl.addEventListener("loadedmetadata", this.onLoadedMetadata), t.videoEl.readyState >= 1 && this.onLoadedMetadata();
38
- }
39
- destroy() {
40
- this.ctx.videoEl.removeEventListener("loadedmetadata", this.onLoadedMetadata), this.ctx.seekBar.el.removeEventListener("pointermove", this.onPointerMove), this.ctx.seekBar.el.removeEventListener("pointerleave", this.onPointerLeave), this.ctx.seekBar.clearChapters(), this.ctx.seekBar.suppressHoverTime("segments", !1), this.tooltipEl.remove(), this.chapterEls = [], this.chapters = [];
41
- }
42
- setHover(t) {
43
- var e, i;
44
- t !== this.hoverIndex && ((e = this.chapterEls[this.hoverIndex]) == null || e.removeAttribute("data-hover"), this.hoverIndex = t, (i = this.chapterEls[t]) == null || i.setAttribute("data-hover", ""));
45
- }
46
- }
47
- function f(r, t) {
48
- const e = r.filter((s) => Number.isFinite(s.start) && s.start < t).slice().sort((s, o) => s.start - o.start), i = [];
49
- let a = 0;
50
- for (const s of e) {
51
- const o = Math.max(s.start, a), l = Math.min(Number.isFinite(s.end) ? s.end : t, t);
52
- l <= o || (o > a && i.push({ start: a, end: o }), i.push({ start: o, end: l, text: s.text, color: s.color }), a = l);
53
- }
54
- return i.length ? (a < t && (i[i.length - 1].end = t), i) : [];
55
- }
56
- function g(r, t) {
57
- return new u(r, t);
58
- }
59
- export {
60
- u as Segments,
61
- g as installSegments
62
- };
63
- //# sourceMappingURL=segments-gCPrWRig.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"segments-gCPrWRig.js","sources":["../../src/plugins/segments/Segments.ts","../../src/plugins/segments/index.ts"],"sourcesContent":["import type { SegmentItem } from '../../types';\nimport type { SeekBarChapterRange } from '../../controls/SeekBar';\nimport { formatTime } from '../../utils/format-time';\n\nexport interface SegmentsPlayerContext {\n videoEl: HTMLVideoElement;\n /** Chapter modunu destekleyen seek bar — parçalara bölme/zaman eşlemesi onda. */\n seekBar: {\n readonly el: HTMLElement;\n setChapters(ranges: SeekBarChapterRange[]): HTMLElement[];\n suppressHoverTime(key: string, suppressed: boolean): void;\n clearChapters(): void;\n ratioAtClientX(clientX: number): number;\n };\n}\n\ninterface Chapter {\n start: number;\n end: number;\n text?: string;\n color?: string;\n}\n\n/**\n * YouTube tarzı bölümler: seek bar parçalara bölünür (SeekBar.setChapters), hover'da bölüm adı + zaman.\n * Zaman çizgisi her zaman tam kaplanır (boşluklar adsız bölüm, son bölüm sona uzar).\n */\nexport class Segments {\n private chapters: Chapter[] = [];\n private chapterEls: HTMLElement[] = [];\n private hoverIndex = -1;\n private readonly tooltipEl: HTMLDivElement;\n private readonly titleEl: HTMLDivElement;\n private readonly timeEl: HTMLDivElement;\n\n constructor(\n private readonly ctx: SegmentsPlayerContext,\n private readonly segments: SegmentItem[]\n ) {\n this.tooltipEl = document.createElement('div');\n this.tooltipEl.className = 'hp-chapter-tooltip';\n this.tooltipEl.setAttribute('part', 'segment-tooltip');\n this.titleEl = document.createElement('div');\n this.titleEl.className = 'hp-chapter-tooltip-title';\n this.timeEl = document.createElement('div');\n this.timeEl.className = 'hp-chapter-tooltip-time';\n this.tooltipEl.append(this.titleEl, this.timeEl);\n ctx.seekBar.el.appendChild(this.tooltipEl);\n // Popup zamanı zaten gösteriyor — seek bar'ın varsayılan hover zamanı ikinci kez yazmasın.\n ctx.seekBar.suppressHoverTime('segments', true);\n\n ctx.seekBar.el.addEventListener('pointermove', this.onPointerMove);\n ctx.seekBar.el.addEventListener('pointerleave', this.onPointerLeave);\n ctx.videoEl.addEventListener('loadedmetadata', this.onLoadedMetadata);\n if (ctx.videoEl.readyState >= 1) this.onLoadedMetadata();\n }\n\n destroy(): void {\n this.ctx.videoEl.removeEventListener('loadedmetadata', this.onLoadedMetadata);\n this.ctx.seekBar.el.removeEventListener('pointermove', this.onPointerMove);\n this.ctx.seekBar.el.removeEventListener('pointerleave', this.onPointerLeave);\n this.ctx.seekBar.clearChapters();\n this.ctx.seekBar.suppressHoverTime('segments', false);\n this.tooltipEl.remove();\n this.chapterEls = [];\n this.chapters = [];\n }\n\n private readonly onLoadedMetadata = (): void => {\n const duration = this.ctx.videoEl.duration;\n if (!Number.isFinite(duration) || duration <= 0) return;\n\n this.chapters = buildChapters(this.segments, duration);\n this.chapterEls = this.ctx.seekBar.setChapters(\n this.chapters.map((c) => ({ start: c.start / duration, end: c.end / duration, color: c.color }))\n );\n };\n\n private readonly onPointerMove = (e: PointerEvent): void => {\n const duration = this.ctx.videoEl.duration;\n if (!this.chapters.length || !Number.isFinite(duration) || duration <= 0) return;\n\n const time = this.ctx.seekBar.ratioAtClientX(e.clientX) * duration;\n let index = this.chapters.findIndex((c) => time < c.end);\n if (index === -1) index = this.chapters.length - 1;\n this.setHover(index);\n\n const chapter = this.chapters[index]!;\n this.titleEl.textContent = chapter.text ?? '';\n this.titleEl.style.display = chapter.text ? '' : 'none';\n this.timeEl.textContent = formatTime(time);\n\n // sprite-thumbnails önizlemesi de seek bar'ın hemen üstünde açılıyor —\n // görünürse popup onun ÜSTÜNE çıkıyor (üst üste binmesin).\n const sprite = this.ctx.seekBar.el.querySelector<HTMLElement>('[part=\"sprite-tooltip\"]');\n const spriteH = sprite && sprite.hasAttribute('data-visible') && sprite.offsetHeight > 0 ? sprite.offsetHeight + 8 : 0;\n this.tooltipEl.style.bottom = spriteH ? `calc(100% + 6px + ${spriteH}px)` : '';\n // Sprite önizlemesi zamanı zaten kendi altında gösteriyor — aynı zaman iki kez yazılmasın.\n this.timeEl.style.display = spriteH ? 'none' : '';\n\n // Popup imleci ortalar ama seek bar kenarlarından taşmaz.\n const barRect = this.ctx.seekBar.el.getBoundingClientRect();\n this.tooltipEl.setAttribute('data-visible', '');\n const tipWidth = this.tooltipEl.offsetWidth;\n const x = Math.min(Math.max(e.clientX - barRect.left - tipWidth / 2, 0), Math.max(barRect.width - tipWidth, 0));\n this.tooltipEl.style.transform = `translateX(${x}px)`;\n };\n\n private readonly onPointerLeave = (): void => {\n this.setHover(-1);\n this.tooltipEl.removeAttribute('data-visible');\n };\n\n private setHover(index: number): void {\n if (index === this.hoverIndex) return;\n this.chapterEls[this.hoverIndex]?.removeAttribute('data-hover');\n this.hoverIndex = index;\n this.chapterEls[index]?.setAttribute('data-hover', '');\n }\n}\n\n/** Segmentleri sıralar, boşlukları adsız bölümle doldurur, son bölümü video sonuna uzatır — sonuç 0→duration'ı kesintisiz kaplar. */\nfunction buildChapters(segments: SegmentItem[], duration: number): Chapter[] {\n const sorted = segments\n .filter((s) => Number.isFinite(s.start) && s.start < duration)\n .slice()\n .sort((a, b) => a.start - b.start);\n\n const chapters: Chapter[] = [];\n let cursor = 0;\n for (const seg of sorted) {\n const start = Math.max(seg.start, cursor);\n const end = Math.min(Number.isFinite(seg.end) ? seg.end : duration, duration);\n if (end <= start) continue;\n if (start > cursor) chapters.push({ start: cursor, end: start });\n chapters.push({ start, end, text: seg.text, color: seg.color });\n cursor = end;\n }\n if (!chapters.length) return [];\n if (cursor < duration) chapters[chapters.length - 1]!.end = duration;\n return chapters;\n}\n","import { Segments, type SegmentsPlayerContext } from './Segments';\nimport type { SegmentItem } from '../../types';\n\nexport function installSegments(ctx: SegmentsPlayerContext, items: SegmentItem[]): Segments {\n return new Segments(ctx, items);\n}\n\nexport { Segments };\nexport type { SegmentsPlayerContext };\n"],"names":["Segments","ctx","segments","__publicField","duration","buildChapters","c","e","time","index","chapter","formatTime","sprite","spriteH","barRect","tipWidth","x","_a","_b","sorted","a","b","chapters","cursor","seg","start","end","installSegments","items"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"spriteThumbnails-B7oDZFTo.js","sources":["../../src/plugins/sprite-thumbnails/SpriteThumbnails.ts","../../src/plugins/sprite-thumbnails/index.ts"],"sourcesContent":["import type { SpriteThumbnailsOptions } from '../../types';\nimport { formatTime } from '../../utils/format-time';\n\nexport interface SpriteThumbnailsPlayerContext {\n videoEl: HTMLVideoElement;\n /** Önizlemenin bağlandığı seek bar — zaman eşlemesi (chapter boşlukları dahil) onun `ratioAtClientX`'inden. */\n seekBar: {\n readonly el: HTMLElement;\n ratioAtClientX(clientX: number): number;\n suppressHoverTime(key: string, suppressed: boolean): void;\n };\n /** Responsive ölçekleme için referans genişlik — genelde player/video alanının genişliği. */\n playerWidth(): number;\n}\n\n/** Bir önizleme karesi: hangi görselin hangi dikdörtgeni. */\ninterface Frame {\n url: string;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\ninterface Sheet {\n img: HTMLImageElement;\n ready: boolean;\n failed: boolean;\n promise: Promise<void>;\n}\n\nexport interface VttCue {\n start: number;\n end: number;\n url: string;\n /** `#xywh` yoksa null → görselin tamamı. */\n rect: { x: number; y: number; w: number; h: number } | null;\n}\n\n/** Aynı anda bellekte (decode edilmiş) tutulan en fazla sheet — uzun videolarda bellek sınırsız büyümesin. */\nconst MAX_CACHED_SHEETS = 8;\n/** Sheet numarası şablonu: `%d` ya da sıfır dolgulu `%03d`. */\nconst SHEET_TEMPLATE = /%(0(\\d+))?d/;\n\n/**\n * Seek bar hover önizlemesi. Kaynak: tek görsel, çok parçalı (%d / %03d şablonu ya da sheets) veya WebVTT (#xywh).\n * sheetDuration verilmezse ilk sheet'in ızgarasından hesaplanır. Kurulumda hiçbir şey indirilmez; yalnızca imlecin\n * altındaki sheet + komşuları yüklenir, decode bitmeden gösterilmez, LRU cache.\n */\nexport class SpriteThumbnails {\n private readonly tooltip: HTMLElement;\n private readonly imageEl: HTMLElement;\n private readonly timeEl: HTMLElement;\n private readonly sheets = new Map<string, Sheet>();\n private vttCues: VttCue[] | null = null;\n private vttLoading: Promise<void> | null = null;\n /** Çok parçalı modda otomatik hesaplanan sheet süresi (ilk sheet yüklenince). */\n private derivedSheetDuration: number | null = null;\n private warmed = false;\n private hovering = false;\n private lastClientX = 0;\n private rafId: number | null = null;\n private destroyed = false;\n\n constructor(\n private readonly ctx: SpriteThumbnailsPlayerContext,\n private readonly options: SpriteThumbnailsOptions\n ) {\n this.tooltip = document.createElement('div');\n this.tooltip.setAttribute('part', 'sprite-tooltip');\n this.tooltip.className = 'hp-sprite-tooltip';\n this.imageEl = document.createElement('div');\n this.imageEl.className = 'hp-sprite-image';\n this.timeEl = document.createElement('div');\n this.timeEl.className = 'hp-sprite-time';\n this.tooltip.append(this.imageEl, this.timeEl);\n ctx.seekBar.el.appendChild(this.tooltip);\n // Önizlemenin altında zaman zaten yazıyor — varsayılan hover zamanı ikinci kez göstermesin.\n ctx.seekBar.suppressHoverTime('sprite', true);\n\n ctx.seekBar.el.addEventListener('pointerenter', this.onPointerEnter);\n ctx.seekBar.el.addEventListener('pointermove', this.onPointerMove);\n ctx.seekBar.el.addEventListener('pointerleave', this.onPointerLeave);\n ctx.videoEl.addEventListener('play', this.warm);\n }\n\n destroy(): void {\n this.destroyed = true;\n if (this.rafId !== null) cancelAnimationFrame(this.rafId);\n this.ctx.seekBar.el.removeEventListener('pointerenter', this.onPointerEnter);\n this.ctx.seekBar.el.removeEventListener('pointermove', this.onPointerMove);\n this.ctx.seekBar.el.removeEventListener('pointerleave', this.onPointerLeave);\n this.ctx.videoEl.removeEventListener('play', this.warm);\n this.tooltip.remove();\n this.ctx.seekBar.suppressHoverTime('sprite', false);\n for (const sheet of this.sheets.values()) sheet.img.src = '';\n this.sheets.clear();\n }\n\n // ── olaylar ──\n\n private readonly onPointerEnter = (e: PointerEvent): void => {\n this.hovering = true;\n this.lastClientX = e.clientX;\n this.warm();\n this.scheduleRender();\n };\n\n private readonly onPointerMove = (e: PointerEvent): void => {\n this.hovering = true;\n this.lastClientX = e.clientX;\n this.scheduleRender();\n };\n\n private readonly onPointerLeave = (): void => {\n this.hovering = false;\n this.tooltip.removeAttribute('data-visible');\n };\n\n /** İlk ihtiyaç anında (hover / oynatma) kaynağı hazırla — kurulumda hiçbir şey indirilmiyor. */\n private readonly warm = (): void => {\n if (this.warmed || this.destroyed) return;\n this.warmed = true;\n if (this.options.vtt) {\n void this.loadVtt();\n return;\n }\n const duration = this.ctx.videoEl.duration;\n const t = Number.isFinite(duration) ? this.ctx.videoEl.currentTime : 0;\n // Şablonlu/çok parçalı modda sheet süresi henüz bilinmiyorsa ilk sheet'ten öğrenilecek.\n void this.ensureSheet(this.sheetUrl(this.isMultiSheet() && this.sheetDuration() === null ? 0 : this.sheetIndexAt(t)));\n };\n\n private scheduleRender(): void {\n if (this.rafId !== null) return;\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null;\n this.render();\n });\n }\n\n // ── çizim ──\n\n private render(): void {\n if (!this.hovering || this.destroyed) return;\n const duration = this.ctx.videoEl.duration;\n if (!Number.isFinite(duration) || duration <= 0) return;\n\n const seconds = this.ctx.seekBar.ratioAtClientX(this.lastClientX) * duration;\n this.timeEl.textContent = formatTime(seconds);\n\n const frame = this.isNetworkEligible() ? this.frameAt(seconds, duration) : null;\n const scale = this.scale();\n if (frame) {\n const sheet = this.sheets.get(frame.url)!;\n const { naturalWidth, naturalHeight } = sheet.img;\n this.imageEl.style.display = '';\n this.imageEl.style.width = `${frame.w * scale}px`;\n this.imageEl.style.height = `${frame.h * scale}px`;\n this.imageEl.style.backgroundImage = `url(\"${frame.url}\")`;\n this.imageEl.style.backgroundSize = `${naturalWidth * scale}px ${naturalHeight * scale}px`;\n this.imageEl.style.backgroundPosition = `${-frame.x * scale}px ${-frame.y * scale}px`;\n } else if (!this.imageEl.style.backgroundImage) {\n // Henüz hiçbir kare yüklenmedi — yalnızca zaman (yükleme bitince yeniden çizilir).\n this.imageEl.style.display = 'none';\n }\n\n // Kenarlarda taşmasın: imleci ortala ama seek bar sınırlarında kal.\n this.tooltip.setAttribute('data-visible', '');\n const barRect = this.ctx.seekBar.el.getBoundingClientRect();\n const tipWidth = this.tooltip.offsetWidth;\n const x = Math.min(Math.max(this.lastClientX - barRect.left - tipWidth / 2, 0), Math.max(barRect.width - tipWidth, 0));\n this.tooltip.style.transform = `translateX(${x}px)`;\n }\n\n private scale(): number {\n const responsive = this.options.responsive;\n const playerWidth = this.ctx.playerWidth();\n return responsive && playerWidth && playerWidth < responsive ? playerWidth / responsive : 1;\n }\n\n private isNetworkEligible(): boolean {\n const nav = navigator as Navigator & { connection?: { downlink?: number } };\n const downlink = nav.connection?.downlink;\n const anyReady = Array.from(this.sheets.values()).some((s) => s.ready);\n return downlink === undefined || downlink >= (this.options.downlink ?? 2) || anyReady;\n }\n\n // ── kare çözümleme ──\n\n /** Saniyedeki kareyi döner; gereken sheet hazır değilse yüklemeyi başlatıp null döner (yüklenince render tekrar çağrılır). */\n private frameAt(seconds: number, duration: number): Frame | null {\n return this.options.vtt ? this.vttFrameAt(seconds) : this.gridFrameAt(seconds, duration);\n }\n\n private isMultiSheet(): boolean {\n return !!this.options.sheets?.length || SHEET_TEMPLATE.test(this.options.url ?? '');\n }\n\n /** Tek sheet → Infinity (tüm video); çok parçalı → verilen ya da ilk sheet'ten hesaplanan süre; henüz bilinmiyorsa null. */\n private sheetDuration(): number | null {\n if (!this.isMultiSheet()) return Infinity;\n return this.options.sheetDuration ?? this.derivedSheetDuration;\n }\n\n private sheetIndexAt(seconds: number): number {\n const d = this.sheetDuration();\n if (d === null || d === Infinity) return 0;\n // floor (ceil DEĞİL): tam sınırda (ör. 60. sn) bir SONRAKİ sheet'in ilk karesi.\n let index = Math.floor(Math.max(0, seconds) / d);\n if (this.options.sheets?.length) index = Math.min(index, this.options.sheets.length - 1);\n return index;\n }\n\n /** 0 tabanlı sheet index'inden URL. */\n private sheetUrl(index: number): string {\n if (this.options.sheets?.length) return this.options.sheets[Math.min(index, this.options.sheets.length - 1)]!;\n const url = this.options.url ?? '';\n const number = index + (this.options.firstSheetIndex ?? 1);\n return url.replace(SHEET_TEMPLATE, (_m, _p, width?: string) => String(number).padStart(width ? Number(width) : 0, '0'));\n }\n\n private gridFrameAt(seconds: number, duration: number): Frame | null {\n const { width, height } = this.options;\n if (!width || !height) return null;\n const interval = this.options.interval || 1;\n\n const sheetDuration = this.sheetDuration();\n if (sheetDuration === null) {\n // Çok parçalı ama süre bilinmiyor — ilk sheet yüklenince hesaplanacak.\n void this.ensureSheet(this.sheetUrl(0));\n return null;\n }\n\n const lastIndex = sheetDuration === Infinity ? 0 : this.sheetIndexAt(Math.max(0, duration - 0.001));\n const index = Math.min(this.sheetIndexAt(seconds), lastIndex);\n const url = this.sheetUrl(index);\n this.preloadAround(index, lastIndex);\n\n const sheet = this.sheets.get(url);\n if (!sheet?.ready) {\n void this.ensureSheet(url);\n return null;\n }\n this.touch(url);\n\n // Her sheet'in KENDİ boyutu (son sheet daha kısa olabilir).\n const columns = Math.max(1, Math.floor(sheet.img.naturalWidth / width));\n const rows = Math.max(1, Math.floor(sheet.img.naturalHeight / height));\n const local = sheetDuration === Infinity ? seconds : seconds - index * sheetDuration;\n const frameIndex = Math.min(Math.max(0, Math.floor(local / interval)), columns * rows - 1);\n return { url, x: (frameIndex % columns) * width, y: Math.floor(frameIndex / columns) * height, w: width, h: height };\n }\n\n private preloadAround(index: number, lastIndex: number): void {\n const n = this.options.preloadSheets ?? 1;\n for (let d = 1; d <= n; d++) {\n if (index + d <= lastIndex) void this.ensureSheet(this.sheetUrl(index + d));\n if (index - d >= 0) void this.ensureSheet(this.sheetUrl(index - d));\n }\n }\n\n private vttFrameAt(seconds: number): Frame | null {\n if (!this.vttCues) {\n void this.loadVtt();\n return null;\n }\n const cues = this.vttCues;\n if (!cues.length) return null;\n // İkili arama — saatlerce süren videolarda binlerce cue olabilir.\n let lo = 0;\n let hi = cues.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (cues[mid]!.start <= seconds) lo = mid;\n else hi = mid - 1;\n }\n const cue = cues[lo]!;\n const neighbours = [cues[lo + 1], cues[lo - 1]].filter((c): c is VttCue => !!c && c.url !== cue.url);\n neighbours.forEach((c) => void this.ensureSheet(c.url));\n\n const sheet = this.sheets.get(cue.url);\n if (!sheet?.ready) {\n void this.ensureSheet(cue.url);\n return null;\n }\n this.touch(cue.url);\n const rect = cue.rect ?? { x: 0, y: 0, w: sheet.img.naturalWidth, h: sheet.img.naturalHeight };\n return { url: cue.url, ...rect };\n }\n\n // ── yükleme / cache ──\n\n private ensureSheet(url: string): Promise<void> {\n if (!url) return Promise.resolve();\n const existing = this.sheets.get(url);\n if (existing) return existing.promise;\n\n const img = new Image();\n img.decoding = 'async';\n const sheet: Sheet = { img, ready: false, failed: false, promise: Promise.resolve() };\n sheet.promise = new Promise<void>((resolve) => {\n img.onload = () => {\n // decode() bitmeden gösterme — yeni sheet'e geçerken boş/yanlış kare titremesi olmasın.\n const done = () => {\n if (this.destroyed) return resolve();\n sheet.ready = true;\n this.learnSheetDuration(img);\n if (this.hovering) this.scheduleRender();\n resolve();\n };\n img.decode ? img.decode().then(done, done) : done();\n };\n img.onerror = () => {\n sheet.failed = true;\n resolve();\n };\n });\n img.src = url;\n this.sheets.set(url, sheet);\n this.evict();\n return sheet.promise;\n }\n\n /** Çok parçalı modda `sheetDuration` verilmediyse ilk yüklenen sheet'in ızgara kapasitesinden hesapla. */\n private learnSheetDuration(img: HTMLImageElement): void {\n if (this.derivedSheetDuration !== null || this.options.vtt || !this.isMultiSheet() || this.options.sheetDuration) return;\n const { width, height } = this.options;\n if (!width || !height) return;\n const capacity = Math.max(1, Math.floor(img.naturalWidth / width)) * Math.max(1, Math.floor(img.naturalHeight / height));\n this.derivedSheetDuration = capacity * (this.options.interval || 1);\n }\n\n /** LRU: kullanılan sheet'i sona taşı. */\n private touch(url: string): void {\n const sheet = this.sheets.get(url);\n if (!sheet) return;\n this.sheets.delete(url);\n this.sheets.set(url, sheet);\n }\n\n private evict(): void {\n while (this.sheets.size > MAX_CACHED_SHEETS) {\n const oldest = this.sheets.keys().next().value as string;\n const sheet = this.sheets.get(oldest)!;\n sheet.img.onload = null;\n sheet.img.onerror = null;\n this.sheets.delete(oldest);\n }\n }\n\n private loadVtt(): Promise<void> {\n if (this.vttLoading) return this.vttLoading;\n const vttUrl = this.options.vtt!;\n this.vttLoading = fetch(vttUrl)\n .then((r) => {\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r.text();\n })\n .then((text) => {\n if (this.destroyed) return;\n this.vttCues = parseThumbnailVtt(text, new URL(vttUrl, document.baseURI).href);\n if (this.vttCues.length) void this.ensureSheet(this.vttCues[0]!.url);\n if (this.hovering) this.scheduleRender();\n })\n .catch((err) => {\n console.warn('[HopePlayer sprite-thumbnails] VTT yüklenemedi:', err);\n this.vttCues = [];\n });\n return this.vttLoading;\n }\n}\n\n/** \"01:02:03.500\" / \"02:03.500\" → saniye. */\nfunction parseVttTime(value: string): number {\n const parts = value.trim().split(':').map(Number);\n return parts.reduce((acc, n) => acc * 60 + n, 0);\n}\n\n/** WebVTT thumbnail dosyası → sıralı cue listesi. Görsel yolları VTT dosyasına göre çözümlenir. */\nexport function parseThumbnailVtt(text: string, baseUrl: string): VttCue[] {\n const cues: VttCue[] = [];\n const blocks = text.replace(/\\r/g, '').split(/\\n\\n+/);\n for (const block of blocks) {\n const lines = block.split('\\n').filter(Boolean);\n const timingIndex = lines.findIndex((l) => l.includes('-->'));\n if (timingIndex === -1) continue;\n const [startStr, endStr] = lines[timingIndex]!.split('-->');\n const target = lines[timingIndex + 1]?.trim();\n if (!startStr || !endStr || !target) continue;\n\n const [path, hash] = target.split('#');\n const match = hash?.match(/xywh=(\\d+),(\\d+),(\\d+),(\\d+)/);\n cues.push({\n start: parseVttTime(startStr),\n end: parseVttTime(endStr.trim().split(/\\s+/)[0]!),\n url: new URL(path!, baseUrl).href,\n rect: match ? { x: +match[1]!, y: +match[2]!, w: +match[3]!, h: +match[4]! } : null,\n });\n }\n return cues.sort((a, b) => a.start - b.start);\n}\n","import { SpriteThumbnails, type SpriteThumbnailsPlayerContext } from './SpriteThumbnails';\nimport type { SpriteThumbnailsOptions } from '../../types';\n\nexport function installSpriteThumbnails(ctx: SpriteThumbnailsPlayerContext, options: SpriteThumbnailsOptions): SpriteThumbnails {\n return new SpriteThumbnails(ctx, options);\n}\n\nexport { SpriteThumbnails };\nexport type { SpriteThumbnailsPlayerContext };\n"],"names":["MAX_CACHED_SHEETS","SHEET_TEMPLATE","SpriteThumbnails","ctx","options","__publicField","e","duration","t","sheet","seconds","formatTime","frame","scale","naturalWidth","naturalHeight","barRect","tipWidth","x","responsive","playerWidth","downlink","_a","anyReady","s","d","index","url","number","_m","_p","width","height","interval","sheetDuration","lastIndex","columns","rows","local","frameIndex","n","cues","lo","hi","mid","cue","c","rect","existing","img","resolve","done","capacity","oldest","vttUrl","r","text","parseThumbnailVtt","err","parseVttTime","value","acc","baseUrl","blocks","block","lines","timingIndex","l","startStr","endStr","target","path","hash","match","a","b","installSpriteThumbnails"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"statsPanel-DSClIwA3.js","sources":["../../src/plugins/stats/StatsPanel.ts","../../src/plugins/stats/index.ts"],"sourcesContent":["import type { HopeLocaleStrings } from '../../i18n/types';\nimport type { PlaybackEngineInfo } from '../../hls/SourceManager';\n\n/** hls.js instance'ından okunan alanlar — tam tipi içe aktarmamak için. */\ninterface HlsStatsSource {\n currentLevel: number;\n autoLevelEnabled: boolean;\n levels: { height: number; width: number; bitrate: number; videoCodec?: string; audioCodec?: string; details?: { live: boolean } }[];\n bandwidthEstimate: number;\n latency: number;\n config: { maxBufferLength: number };\n}\n\nexport interface StatsPlayerContext {\n videoEl: HTMLVideoElement;\n containerEl: HTMLElement;\n i18n: HopeLocaleStrings;\n version: string;\n getEngine(): PlaybackEngineInfo;\n getHls(): HlsStatsSource | null;\n}\n\nconst REFRESH_MS = 500;\n\n/** Sağ tık menüsündeki \"İstatistikler\" — player üstünde canlı teknik bilgi paneli (YouTube'daki \"Stats for nerds\" gibi). */\nexport class StatsPanel {\n private readonly el: HTMLDivElement;\n private readonly titleEl: HTMLSpanElement;\n private readonly closeBtn: HTMLButtonElement;\n private readonly body: HTMLDListElement;\n private timer: ReturnType<typeof setInterval> | null = null;\n\n constructor(private readonly ctx: StatsPlayerContext) {\n this.el = document.createElement('div');\n this.el.className = 'hp-stats';\n this.el.setAttribute('part', 'stats-panel');\n this.el.setAttribute('role', 'dialog');\n\n const header = document.createElement('div');\n header.className = 'hp-stats-header';\n this.titleEl = document.createElement('span');\n this.closeBtn = document.createElement('button');\n this.closeBtn.type = 'button';\n this.closeBtn.className = 'hp-stats-close';\n this.closeBtn.innerHTML =\n '<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" aria-hidden=\"true\"><path d=\"M6 6l12 12M18 6L6 18\"/></svg>';\n this.closeBtn.addEventListener('click', () => this.hide());\n header.append(this.titleEl, this.closeBtn);\n\n this.body = document.createElement('dl');\n this.body.className = 'hp-stats-body';\n this.el.append(header, this.body);\n // Panel tıklamaları videoyu oynat/duraklat yapmasın.\n this.el.addEventListener('pointerdown', (e) => e.stopPropagation());\n this.el.addEventListener('click', (e) => e.stopPropagation());\n this.refreshLabels();\n }\n\n get isVisible(): boolean {\n return this.el.isConnected;\n }\n\n show(): void {\n if (!this.isVisible) this.ctx.containerEl.appendChild(this.el);\n this.render();\n if (!this.timer) this.timer = setInterval(() => this.render(), REFRESH_MS);\n }\n\n hide(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n this.el.remove();\n }\n\n toggle(force?: boolean): void {\n if (force ?? !this.isVisible) this.show();\n else this.hide();\n }\n\n refreshLabels(): void {\n this.titleEl.textContent = this.ctx.i18n.statsTitle;\n this.closeBtn.setAttribute('aria-label', this.ctx.i18n.statsClose);\n if (this.isVisible) this.render();\n }\n\n destroy(): void {\n this.hide();\n }\n\n private render(): void {\n const { videoEl: v, i18n: t } = this.ctx;\n const hls = this.ctx.getHls();\n const engine = this.ctx.getEngine();\n const level = hls && hls.currentLevel >= 0 ? hls.levels[hls.currentLevel] : undefined;\n const quality = v.getVideoPlaybackQuality?.();\n const rect = v.getBoundingClientRect();\n const dpr = window.devicePixelRatio || 1;\n\n let ahead = 0;\n for (let i = 0; i < v.buffered.length; i++) {\n if (v.buffered.start(i) <= v.currentTime + 0.5 && v.buffered.end(i) > v.currentTime) ahead = v.buffered.end(i) - v.currentTime;\n }\n\n const rows: [string, string][] = [\n [t.statsEngine, engine.engine + (engine.reason ? ` (${engine.reason})` : '')],\n [t.statsResolution, `${v.videoWidth}×${v.videoHeight} / ${Math.round(rect.width * dpr)}×${Math.round(rect.height * dpr)}`],\n [t.statsQuality, level ? `${level.height}p · ${Math.round(level.bitrate / 1000)} kbps${hls!.autoLevelEnabled ? ' · auto' : ''}` : '—'],\n [t.statsCodecs, level ? [level.videoCodec, level.audioCodec].filter(Boolean).join(', ') || '—' : '—'],\n [t.statsBandwidth, hls ? `${(hls.bandwidthEstimate / 1e6).toFixed(2)} Mbps` : '—'],\n [t.statsBuffer, `${ahead.toFixed(1)} s`],\n [t.statsDropped, quality ? `${quality.droppedVideoFrames} / ${quality.totalVideoFrames}` : '—'],\n // hls.js `latency`'yi VOD'da da hesaplıyor (süre - konum) — yalnızca canlı yayında anlamlı.\n [t.statsLatency, level?.details?.live && Number.isFinite(hls!.latency) ? `${hls!.latency.toFixed(1)} s` : '—'],\n [t.statsSpeedVolume, `${v.playbackRate}× · ${v.muted ? 0 : Math.round(v.volume * 100)}%`],\n [t.statsSource, v.currentSrc && !v.currentSrc.startsWith('blob:') ? v.currentSrc : v.currentSrc ? 'MediaSource (hls.js)' : '—'],\n [t.statsVersion, `HopeCorePlayer ${this.ctx.version}`],\n ];\n this.body.replaceChildren(\n ...rows.flatMap(([k, val]) => {\n const dt = document.createElement('dt');\n dt.textContent = k;\n const dd = document.createElement('dd');\n dd.textContent = val;\n dd.title = val;\n return [dt, dd];\n })\n );\n }\n}\n","import { StatsPanel, type StatsPlayerContext } from './StatsPanel';\n\nexport function installStats(ctx: StatsPlayerContext): StatsPanel {\n return new StatsPanel(ctx);\n}\n\nexport { StatsPanel };\nexport type { StatsPlayerContext };\n"],"names":["StatsPanel","ctx","__publicField","header","e","force","_a","_b","v","t","hls","engine","level","quality","rect","dpr","ahead","i","rows","k","val","dt","dd","installStats"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sticky-D_eLCNFk.js","sources":["../../src/plugins/sticky/StickyManager.ts","../../src/plugins/sticky/index.ts"],"sourcesContent":["import type { StickyCorner, StickyOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\n\nexport interface StickyPlayerContext {\n key: string;\n videoEl: HTMLVideoElement;\n hostEl: HTMLElement;\n /** Sticky olarak köşeye taşınacak element — genelde hostEl'in kendisi (bkz. options.wrapperSelector). */\n wrapperEl: HTMLElement;\n /**\n * Kapat butonu wrapperEl'e değil shadow root içine eklenir — wrapperEl varsayılan olarak host;\n * slot olmadığı için light DOM child'ı render edilmez.\n */\n closeButtonMountEl: HTMLElement;\n isAdActive(): boolean;\n i18n: HopeLocaleStrings;\n}\n\n/** `register()`'ın döndürdüğü unregister fonksiyonu — dil sonradan değişince close butonunun statik etiketini tazelemek için `refreshLabels` da taşıyor (bkz. loop-section'daki aynı \"fonksiyona metod ekleme\" deseni). */\nexport type StickyUnregister = (() => void) & { refreshLabels?: () => void };\n\ninterface StickyItemState {\n inView: boolean;\n playing: boolean;\n sticky: boolean;\n hasEverBeenInView: boolean;\n hasEverBeenInViewWhilePlaying: boolean;\n watchMsInView: number;\n lastTickAt: number;\n minPlaySatisfied: boolean;\n userPaused: boolean;\n userPausedAt: number;\n adStartedOnce: boolean;\n contentStartedOnce: boolean;\n blockResumeUntil: number;\n programmaticPauseUntil: number;\n placeholderEl: HTMLElement | null;\n closeBtnEl: HTMLElement | null;\n}\n\ninterface StickyItem {\n ctx: StickyPlayerContext;\n options: Required<Omit<StickyOptions, 'wrapperSelector'>>;\n state: StickyItemState;\n /** wrapperEl'in doğal konumundaki görünmez işaretçi — IntersectionObserver bunu izler (sticky olunca wrapper yer değiştirir). */\n sentinelEl: HTMLElement;\n}\n\nconst GESTURE_WINDOW_MS = 1200;\nconst USER_PAUSED_MAX_MS = 30000;\nconst PROGRAMMATIC_PAUSE_MS = 800;\nconst BLOCK_RESUME_MS = 1200;\nconst STORAGE_KEY = 'hope_sticky_dismissed_until';\nconst STORAGE_KEY_FOREVER = 'hope_sticky_dismissed_forever';\n\n/** Sayfadaki tüm sticky player'ları koordine eden modül seviyesi singleton (aynı anda tek sticky). */\nclass StickyManagerImpl {\n private readonly items = new Map<string, StickyItem>();\n private activeKey: string | null = null;\n private observer: IntersectionObserver | null = null;\n\n private lastUserGestureAt = 0;\n private lastGestureType: 'play' | 'pause' | 'other' | null = null;\n private gestureListenersAttached = false;\n\n private dismissedUntil = 0;\n private dismissedForever = false;\n private dismissLoaded = false;\n\n register(ctx: StickyPlayerContext, options: StickyOptions): StickyUnregister {\n this.ensureGestureListeners();\n this.loadDismissState();\n\n const resolved: StickyItem['options'] = {\n enabled: options.enabled ?? true,\n corner: options.corner ?? 'br',\n requirePlaying: options.requirePlaying ?? true,\n minPlayMs: options.minPlayMs ?? 800,\n onlyOneSticky: options.onlyOneSticky ?? true,\n closeActiveStickyOnAnotherPlay: options.closeActiveStickyOnAnotherPlay ?? true,\n userGestureWindowMs: options.userGestureWindowMs ?? GESTURE_WINDOW_MS,\n adCanTriggerSticky: options.adCanTriggerSticky ?? 'preroll-only',\n dismissMode: options.dismissMode ?? 'cooldown',\n cooldownMinutes: options.cooldownMinutes ?? 5,\n storage: options.storage ?? 'local',\n closeButton: options.closeButton ?? true,\n };\n\n if (!resolved.enabled) return () => {};\n\n const sentinel = document.createElement('div');\n sentinel.setAttribute('aria-hidden', 'true');\n sentinel.style.cssText = 'position:relative;width:1px;height:1px;pointer-events:none;opacity:0;';\n ctx.wrapperEl.parentNode?.insertBefore(sentinel, ctx.wrapperEl);\n\n const item: StickyItem = {\n ctx,\n options: resolved,\n sentinelEl: sentinel,\n state: {\n inView: true,\n playing: false,\n sticky: false,\n hasEverBeenInView: false,\n hasEverBeenInViewWhilePlaying: false,\n watchMsInView: 0,\n lastTickAt: 0,\n minPlaySatisfied: false,\n userPaused: false,\n userPausedAt: 0,\n adStartedOnce: false,\n contentStartedOnce: false,\n blockResumeUntil: 0,\n programmaticPauseUntil: 0,\n placeholderEl: null,\n closeBtnEl: null,\n },\n };\n this.items.set(ctx.key, item);\n\n this.ensureObserver().observe(sentinel);\n\n const onPlay = () => this.handlePlay(item);\n const onPause = () => this.handlePauseOrEnded(item, 'pause');\n const onEnded = () => this.handlePauseOrEnded(item, 'ended');\n const onAdStart = () => this.handleAdStart(item);\n const onAdEnd = () => this.handleAdEnd(item);\n\n ctx.videoEl.addEventListener('play', onPlay);\n ctx.videoEl.addEventListener('pause', onPause);\n ctx.videoEl.addEventListener('ended', onEnded);\n ctx.hostEl.addEventListener('hp:adstart', onAdStart);\n ctx.hostEl.addEventListener('hp:adend', onAdEnd);\n\n // Plugin dinamik yüklendiği için autoplay video'yu bu dinleyiciden önce başlatmış olabilir —\n // kaçırılan 'play'i telafi et, yoksa requirePlaying sticky'yi hiç açmaz.\n if (!ctx.videoEl.paused && !ctx.videoEl.ended) {\n this.handlePlay(item);\n }\n\n const unregister: StickyUnregister = () => {\n if (item.state.sticky) this.unstick(ctx.key, 'destroy');\n ctx.videoEl.removeEventListener('play', onPlay);\n ctx.videoEl.removeEventListener('pause', onPause);\n ctx.videoEl.removeEventListener('ended', onEnded);\n ctx.hostEl.removeEventListener('hp:adstart', onAdStart);\n ctx.hostEl.removeEventListener('hp:adend', onAdEnd);\n this.observer?.unobserve(sentinel);\n sentinel.remove();\n this.items.delete(ctx.key);\n };\n unregister.refreshLabels = () => {\n if (item.state.closeBtnEl) {\n item.state.closeBtnEl.setAttribute('aria-label', ctx.i18n.close);\n }\n };\n return unregister;\n }\n\n // ── gesture tracking (tüm sayfa için tek dinleyici) ──\n\n private ensureGestureListeners(): void {\n if (this.gestureListenersAttached || typeof window === 'undefined') return;\n this.gestureListenersAttached = true;\n\n window.addEventListener(\n 'pointerdown',\n (e) => {\n this.lastUserGestureAt = Date.now();\n // composedPath()[0]: Shadow DOM'da e.target host'a retarget edilir; gerçek iç butonu almak için.\n const target = (e.composedPath()[0] ?? e.target) as HTMLElement | null;\n const btn = target?.closest?.('button,[role=\"button\"]') as HTMLElement | null;\n if (btn?.querySelector('.hp-icon-pause')) this.lastGestureType = 'pause';\n else if (btn?.querySelector('.hp-icon-play')) this.lastGestureType = 'play';\n else this.lastGestureType = 'other';\n },\n { capture: true, passive: true }\n );\n window.addEventListener(\n 'keydown',\n () => {\n this.lastUserGestureAt = Date.now();\n this.lastGestureType = 'other';\n },\n { capture: true }\n );\n }\n\n // ── intersection observer (tüm sticky item'lar için tek instance) ──\n\n private ensureObserver(): IntersectionObserver {\n if (this.observer) return this.observer;\n this.observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n const item = [...this.items.values()].find((i) => i.sentinelEl === entry.target);\n if (!item) continue;\n this.onIntersect(item, entry);\n }\n },\n { threshold: [0.35], rootMargin: '0px 0px -20% 0px' }\n );\n return this.observer;\n }\n\n private onIntersect(item: StickyItem, entry: IntersectionObserverEntry): void {\n this.accumulateWatch(item);\n const inView = entry.isIntersecting && entry.intersectionRatio >= 0.35;\n item.state.inView = inView;\n\n if (inView) {\n item.state.hasEverBeenInView = true;\n if (item.state.playing) item.state.hasEverBeenInViewWhilePlaying = true;\n if (item.state.sticky) this.unstick(item.ctx.key, 'back_in_view');\n } else {\n if (!item.state.hasEverBeenInView) return;\n const isActive = item.state.playing;\n if (item.options.requirePlaying && !isActive) return;\n this.maybeStick(item, 'out_of_view');\n }\n }\n\n // ── player event handlers ──\n\n private handlePlay(item: StickyItem): void {\n if (item.state.blockResumeUntil && Date.now() < item.state.blockResumeUntil) {\n item.ctx.videoEl.pause();\n item.state.playing = false;\n return;\n }\n if (item.ctx.isAdActive()) return;\n\n item.state.contentStartedOnce = true;\n const wasPlaying = item.state.playing;\n item.state.playing = true;\n if (!wasPlaying) {\n item.state.lastTickAt = Date.now();\n item.state.watchMsInView = 0;\n }\n if (item.state.inView) item.state.hasEverBeenInViewWhilePlaying = true;\n\n const gestureWindow = item.options.userGestureWindowMs;\n let userInitiated = Date.now() - this.lastUserGestureAt <= gestureWindow;\n if (this.lastGestureType === 'pause') userInitiated = false;\n if (item.state.userPaused && Date.now() - item.state.userPausedAt <= 1500) userInitiated = false;\n\n if (userInitiated) {\n item.state.userPaused = false;\n item.state.userPausedAt = 0;\n this.lastGestureType = 'play';\n }\n\n this.handleBecameActive(item, 'content', userInitiated);\n }\n\n private handlePauseOrEnded(item: StickyItem, kind: 'pause' | 'ended'): void {\n this.accumulateWatch(item);\n if (item.ctx.isAdActive()) {\n item.state.playing = true;\n return;\n }\n item.state.playing = false;\n\n const now = Date.now();\n if (item.state.programmaticPauseUntil && now < item.state.programmaticPauseUntil) {\n item.state.programmaticPauseUntil = 0;\n item.state.userPaused = false;\n item.state.userPausedAt = 0;\n return;\n }\n\n if (kind === 'pause') {\n const isUserPause = now - this.lastUserGestureAt <= item.options.userGestureWindowMs;\n if (isUserPause) {\n item.state.userPaused = true;\n item.state.userPausedAt = now;\n this.lastGestureType = 'pause';\n }\n } else if (item.state.sticky) {\n this.unstick(item.ctx.key, 'ended');\n }\n }\n\n private handleAdStart(item: StickyItem): void {\n const mode = item.options.adCanTriggerSticky;\n const isCurrentlySticky = this.activeKey === item.ctx.key;\n const isFirstAdEver = !item.state.adStartedOnce;\n item.state.adStartedOnce = true;\n item.state.lastTickAt = Date.now();\n item.state.playing = true;\n\n let allow = false;\n if (mode === 'always') allow = true;\n else if (mode === 'never') allow = false;\n else allow = isCurrentlySticky || (isFirstAdEver && !item.state.contentStartedOnce);\n\n if (!allow) return;\n this.handleBecameActive(item, 'ad', false);\n }\n\n private handleAdEnd(item: StickyItem): void {\n this.accumulateWatch(item);\n item.state.playing = !item.ctx.videoEl.paused && !item.ctx.videoEl.ended;\n item.state.lastTickAt = Date.now();\n }\n\n private handleBecameActive(item: StickyItem, source: 'content' | 'ad', userInitiated: boolean): void {\n item.state.playing = true;\n if (userInitiated) {\n item.state.userPaused = false;\n item.state.userPausedAt = 0;\n this.lastGestureType = 'play';\n }\n\n const now = Date.now();\n if (!item.state.lastTickAt) item.state.lastTickAt = now;\n if (item.state.inView) {\n item.state.hasEverBeenInView = true;\n item.state.hasEverBeenInViewWhilePlaying = true;\n }\n\n if (item.options.closeActiveStickyOnAnotherPlay && userInitiated && this.activeKey && this.activeKey !== item.ctx.key) {\n this.pauseAndUnstick(this.activeKey, 'another_played');\n }\n\n if (!item.state.inView) this.maybeStick(item, source === 'ad' ? 'play_ad' : 'play');\n }\n\n private accumulateWatch(item: StickyItem): void {\n const now = Date.now();\n const last = item.state.lastTickAt || now;\n item.state.lastTickAt = now;\n if (!item.state.playing || !item.state.inView) return;\n\n item.state.watchMsInView += now - last;\n if (!item.state.minPlaySatisfied && item.options.minPlayMs > 0 && item.state.watchMsInView >= item.options.minPlayMs) {\n item.state.minPlaySatisfied = true;\n }\n }\n\n // ── stick / unstick ──\n\n private maybeStick(item: StickyItem, _trigger: string): void {\n const maxMs = USER_PAUSED_MAX_MS;\n if (item.state.userPaused && Date.now() - item.state.userPausedAt > maxMs) {\n item.state.userPaused = false;\n item.state.userPausedAt = 0;\n }\n\n if (!item.state.hasEverBeenInView) return;\n if (!item.state.hasEverBeenInViewWhilePlaying) return;\n if (item.state.userPaused) return;\n\n const now = Date.now();\n if (item.options.dismissMode === 'never' && this.dismissedForever) return;\n if (item.options.dismissMode === 'cooldown' && this.dismissedUntil && now < this.dismissedUntil) return;\n\n if (item.options.requirePlaying && !item.state.playing) return;\n if (item.state.sticky) return;\n if (item.options.minPlayMs > 0 && !item.state.minPlaySatisfied) return;\n\n if (item.options.onlyOneSticky && this.activeKey && this.activeKey !== item.ctx.key) {\n this.pauseAndUnstick(this.activeKey, 'replaced');\n }\n\n this.stick(item);\n }\n\n private stick(item: StickyItem): void {\n const wrapper = item.ctx.wrapperEl;\n const corner = item.options.corner;\n\n if (!item.state.placeholderEl) {\n const ph = document.createElement('div');\n ph.setAttribute('data-hope-sticky-placeholder', '1');\n const rect = wrapper.getBoundingClientRect();\n ph.style.height = `${rect.height}px`;\n wrapper.parentNode?.insertBefore(ph, wrapper);\n item.state.placeholderEl = ph;\n }\n\n wrapper.setAttribute('data-sticky', '1');\n wrapper.setAttribute('data-sticky-corner', corner);\n\n if (item.options.closeButton && !item.state.closeBtnEl) {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.setAttribute('part', 'sticky-close-button');\n btn.setAttribute('aria-label', item.ctx.i18n.close);\n btn.className =\n 'hp:absolute hp:top-1 hp:right-1 hp:z-30 hp:flex hp:items-center hp:justify-center hp:w-6 hp:h-6 ' +\n 'hp:rounded-full hp:bg-black/60 hp:text-white hp:border-0 hp:cursor-pointer';\n btn.innerHTML = '<i class=\"hp-icon hp-icon-close\" aria-hidden=\"true\"></i>';\n btn.addEventListener('click', () => {\n this.applyGlobalDismiss(item.options);\n this.pauseAndUnstick(item.ctx.key, 'closed');\n });\n item.ctx.closeButtonMountEl.appendChild(btn);\n item.state.closeBtnEl = btn;\n }\n\n item.state.sticky = true;\n this.activeKey = item.ctx.key;\n item.ctx.hostEl.dispatchEvent(new CustomEvent('hp:sticky', { detail: { sticky: true, corner } }));\n }\n\n private unstick(key: string, _reason: string): void {\n const item = this.items.get(key);\n if (!item) return;\n\n const wrapper = item.ctx.wrapperEl;\n wrapper.removeAttribute('data-sticky');\n wrapper.removeAttribute('data-sticky-corner');\n\n item.state.closeBtnEl?.remove();\n item.state.closeBtnEl = null;\n item.state.placeholderEl?.remove();\n item.state.placeholderEl = null;\n\n item.state.sticky = false;\n if (this.activeKey === key) this.activeKey = null;\n item.ctx.hostEl.dispatchEvent(new CustomEvent('hp:sticky', { detail: { sticky: false } }));\n }\n\n private pauseAndUnstick(key: string, reason: string): void {\n const item = this.items.get(key);\n if (!item) return;\n\n const now = Date.now();\n item.state.blockResumeUntil = now + BLOCK_RESUME_MS;\n item.state.programmaticPauseUntil = now + PROGRAMMATIC_PAUSE_MS;\n\n item.ctx.videoEl.pause();\n item.state.playing = false;\n this.unstick(key, reason);\n }\n\n // ── global dismiss (localStorage/sessionStorage) ──\n\n private loadDismissState(): void {\n if (this.dismissLoaded) return;\n this.dismissLoaded = true;\n try {\n const st = window.localStorage;\n this.dismissedUntil = Number(st.getItem(STORAGE_KEY) || 0) || 0;\n this.dismissedForever = st.getItem(STORAGE_KEY_FOREVER) === '1';\n } catch {\n /* storage erişilemez (gizli mod vb.) — sessizce yoksay */\n }\n }\n\n private applyGlobalDismiss(options: StickyItem['options']): void {\n if (options.dismissMode === 'none') return;\n const storage = options.storage === 'memory' ? null : options.storage === 'session' ? window.sessionStorage : window.localStorage;\n\n if (options.dismissMode === 'never') {\n this.dismissedForever = true;\n try {\n storage?.setItem(STORAGE_KEY_FOREVER, '1');\n } catch {\n /* no-op */\n }\n return;\n }\n\n const until = Date.now() + options.cooldownMinutes * 60000;\n this.dismissedUntil = until;\n try {\n storage?.setItem(STORAGE_KEY, String(until));\n } catch {\n /* no-op */\n }\n }\n}\n\nexport const stickyManager = new StickyManagerImpl();\nexport type { StickyCorner };\n","import { stickyManager, type StickyPlayerContext, type StickyUnregister } from './StickyManager';\nimport type { StickyOptions } from '../../types';\n\n/** Dönen fonksiyon unregister/cleanup — HopePlayerElement.disconnectedCallback'te çağrılmalı. `refreshLabels()` da taşır (dil değişince close butonu için). */\nexport function installSticky(ctx: StickyPlayerContext, options: StickyOptions): StickyUnregister {\n return stickyManager.register(ctx, options);\n}\n\nexport type { StickyPlayerContext, StickyUnregister };\n"],"names":["STORAGE_KEY","STORAGE_KEY_FOREVER","StickyManagerImpl","__publicField","ctx","options","_a","resolved","sentinel","item","onPlay","onPause","onEnded","onAdStart","onAdEnd","unregister","target","btn","entries","entry","i","inView","isActive","wasPlaying","gestureWindow","userInitiated","kind","now","mode","isCurrentlySticky","isFirstAdEver","allow","source","last","_trigger","wrapper","corner","ph","rect","key","_reason","_b","reason","st","storage","until","stickyManager","installSticky"],"mappings":"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"}