vidply 1.1.12 → 1.1.16

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 (166) hide show
  1. package/dist/dev/{vidply.AudioDescriptionManager-BUFHX3J2.js → vidply.AudioDescriptionManager-DRSYPKJ6.js} +21 -16
  2. package/dist/dev/vidply.AudioDescriptionManager-DRSYPKJ6.js.map +7 -0
  3. package/dist/dev/{vidply.DASHRenderer-FOAYYIJF.js → vidply.DASHRenderer-A6G2BQJ6.js} +56 -39
  4. package/dist/dev/vidply.DASHRenderer-A6G2BQJ6.js.map +7 -0
  5. package/dist/dev/{vidply.FloatingPlayerManager-3UNT4M6W.js → vidply.FloatingPlayerManager-JXGJXNFA.js} +29 -18
  6. package/dist/dev/vidply.FloatingPlayerManager-JXGJXNFA.js.map +7 -0
  7. package/dist/dev/{vidply.HLSRenderer-HH6XVVMY.js → vidply.HLSRenderer-Q2JSD7RA.js} +40 -28
  8. package/dist/dev/vidply.HLSRenderer-Q2JSD7RA.js.map +7 -0
  9. package/dist/dev/vidply.HTML5Renderer-R6HBNQGN.js +12 -0
  10. package/dist/dev/{vidply.SignLanguageManager-4M2MIZC3.js → vidply.SignLanguageManager-VS46ZIEP.js} +170 -338
  11. package/dist/dev/vidply.SignLanguageManager-VS46ZIEP.js.map +7 -0
  12. package/dist/dev/{vidply.SoundCloudRenderer-2JJDYREC.js → vidply.SoundCloudRenderer-3PTUSVC2.js} +46 -29
  13. package/dist/dev/vidply.SoundCloudRenderer-3PTUSVC2.js.map +7 -0
  14. package/dist/dev/{vidply.TranscriptManager-F6PJXVO4.js → vidply.TranscriptManager-JBZE7C5T.js} +324 -431
  15. package/dist/dev/vidply.TranscriptManager-JBZE7C5T.js.map +7 -0
  16. package/dist/dev/{vidply.VimeoRenderer-IO3K5LSS.js → vidply.VimeoRenderer-EUAXCCV6.js} +20 -14
  17. package/dist/dev/vidply.VimeoRenderer-EUAXCCV6.js.map +7 -0
  18. package/dist/dev/{vidply.YouTubeRenderer-ZJHLTZZU.js → vidply.YouTubeRenderer-SZIXDNNX.js} +10 -8
  19. package/dist/dev/vidply.YouTubeRenderer-SZIXDNNX.js.map +7 -0
  20. package/dist/dev/{vidply.chunk-SQ6JPO2C.js → vidply.chunk-C7HDJYKX.js} +81 -50
  21. package/dist/dev/vidply.chunk-C7HDJYKX.js.map +7 -0
  22. package/dist/dev/vidply.chunk-HXHMFMHC.js +30 -0
  23. package/dist/dev/vidply.chunk-HXHMFMHC.js.map +7 -0
  24. package/dist/dev/{vidply.chunk-TZTAOWPB.js → vidply.chunk-R6IULD5Y.js} +37 -30
  25. package/dist/dev/vidply.chunk-R6IULD5Y.js.map +7 -0
  26. package/dist/dev/{vidply.chunk-AGRQTQJL.js → vidply.chunk-RTPBWCLO.js} +3 -3
  27. package/dist/dev/{vidply.chunk-7KJ26XHK.js → vidply.chunk-SE2O3UVV.js} +3 -118
  28. package/dist/dev/vidply.chunk-SE2O3UVV.js.map +7 -0
  29. package/dist/dev/{vidply.chunk-KKMHWBRM.js → vidply.chunk-TTVAXCEY.js} +5 -5
  30. package/dist/dev/{vidply.chunk-KKMHWBRM.js.map → vidply.chunk-TTVAXCEY.js.map} +2 -2
  31. package/dist/dev/{vidply.chunk-QHRUGI7L.js → vidply.chunk-VUS3KFUI.js} +6 -15
  32. package/dist/dev/vidply.chunk-VUS3KFUI.js.map +7 -0
  33. package/dist/dev/vidply.chunk-XC5S5TJQ.js +626 -0
  34. package/dist/dev/vidply.chunk-XC5S5TJQ.js.map +7 -0
  35. package/dist/dev/vidply.chunk-ZJNPHZJJ.js +136 -0
  36. package/dist/dev/vidply.chunk-ZJNPHZJJ.js.map +7 -0
  37. package/dist/dev/{vidply.de-WKTHZS7V.js → vidply.de-56C63R72.js} +8 -2
  38. package/dist/dev/vidply.de-56C63R72.js.map +7 -0
  39. package/dist/dev/{vidply.es-43TEOQ7X.js → vidply.es-LGU3X3UX.js} +8 -2
  40. package/dist/dev/vidply.es-LGU3X3UX.js.map +7 -0
  41. package/dist/dev/vidply.esm.js +2172 -3561
  42. package/dist/dev/vidply.esm.js.map +4 -4
  43. package/dist/dev/{vidply.fr-DWFE563C.js → vidply.fr-2JONULHF.js} +8 -2
  44. package/dist/dev/vidply.fr-2JONULHF.js.map +7 -0
  45. package/dist/dev/{vidply.ja-2KWGACH2.js → vidply.ja-MH6HHB6U.js} +8 -2
  46. package/dist/dev/vidply.ja-MH6HHB6U.js.map +7 -0
  47. package/dist/legacy/vidply.js +6551 -7582
  48. package/dist/legacy/vidply.js.map +4 -4
  49. package/dist/legacy/vidply.min.js +2 -2
  50. package/dist/legacy/vidply.min.meta.json +319 -84
  51. package/dist/prod/vidply.AudioDescriptionManager-SJKJGDIZ.min.js +6 -0
  52. package/dist/prod/vidply.DASHRenderer-JG6IH7ZH.min.js +6 -0
  53. package/dist/prod/vidply.FloatingPlayerManager-MBEVSQCW.min.js +6 -0
  54. package/dist/prod/vidply.HLSRenderer-GPHLTIF3.min.js +6 -0
  55. package/dist/prod/vidply.HTML5Renderer-MYPIJQEW.min.js +6 -0
  56. package/dist/prod/vidply.SignLanguageManager-6GAWSH6N.min.js +6 -0
  57. package/dist/prod/vidply.SoundCloudRenderer-6THKJJ4P.min.js +6 -0
  58. package/dist/prod/vidply.TranscriptManager-7U6EVG52.min.js +6 -0
  59. package/dist/prod/vidply.VimeoRenderer-KMP7OYF5.min.js +6 -0
  60. package/dist/prod/vidply.YouTubeRenderer-YRFOTEQW.min.js +6 -0
  61. package/dist/prod/vidply.chunk-63LS37ZO.min.js +6 -0
  62. package/dist/prod/vidply.chunk-6FJLQPFL.min.js +6 -0
  63. package/dist/prod/vidply.chunk-72BLBALO.min.js +6 -0
  64. package/dist/prod/vidply.chunk-G2VT3POS.min.js +6 -0
  65. package/dist/prod/{vidply.chunk-BNWQRQHX.min.js → vidply.chunk-I727HSZS.min.js} +2 -2
  66. package/dist/prod/vidply.chunk-IREBITW2.min.js +6 -0
  67. package/dist/prod/{vidply.chunk-R4GW3ADH.min.js → vidply.chunk-M5AGRIJK.min.js} +2 -2
  68. package/dist/prod/vidply.chunk-RTY62AYD.min.js +6 -0
  69. package/dist/prod/vidply.chunk-RYYSYGOB.min.js +6 -0
  70. package/dist/prod/vidply.de-R3S3GYZY.min.js +6 -0
  71. package/dist/prod/vidply.es-DBFW2CCV.min.js +6 -0
  72. package/dist/prod/vidply.esm.min.js +2 -2
  73. package/dist/prod/vidply.fr-MLCUJBE6.min.js +6 -0
  74. package/dist/prod/vidply.ja-QZ5LFAZD.min.js +6 -0
  75. package/dist/vidply.css +3317 -3243
  76. package/dist/vidply.esm.min.meta.json +415 -175
  77. package/dist/vidply.min.css +1 -1
  78. package/package.json +4 -4
  79. package/src/controls/CaptionManager.ts +84 -47
  80. package/src/controls/ControlBar.ts +392 -305
  81. package/src/controls/KeyboardManager.ts +3 -7
  82. package/src/controls/SettingsDialog.ts +13 -13
  83. package/src/controls/TranscriptManager.ts +432 -626
  84. package/src/core/AudioDescriptionManager.ts +48 -24
  85. package/src/core/FloatingPlayerManager.ts +27 -13
  86. package/src/core/LazyInit.ts +80 -0
  87. package/src/core/MetadataAlertsManager.ts +513 -0
  88. package/src/core/Player.ts +2659 -6134
  89. package/src/core/PosterManager.ts +169 -0
  90. package/src/core/PseudoFullscreen.ts +177 -0
  91. package/src/core/ResponsiveManager.ts +231 -0
  92. package/src/core/ResumeManager.ts +236 -0
  93. package/src/core/SignLanguageManager.ts +244 -413
  94. package/src/core/ThemeManager.ts +157 -0
  95. package/src/features/PlaylistManager.ts +120 -72
  96. package/src/i18n/i18n.ts +4 -17
  97. package/src/i18n/languages/de.ts +6 -0
  98. package/src/i18n/languages/en.ts +6 -0
  99. package/src/i18n/languages/es.ts +6 -0
  100. package/src/i18n/languages/fr.ts +6 -0
  101. package/src/i18n/languages/ja.ts +6 -0
  102. package/src/icons/Icons.ts +45 -3
  103. package/src/index.ts +13 -78
  104. package/src/renderers/DASHRenderer.ts +93 -50
  105. package/src/renderers/HLSRenderer.ts +76 -38
  106. package/src/renderers/HTML5Renderer.ts +3 -3
  107. package/src/renderers/SoundCloudRenderer.ts +81 -45
  108. package/src/renderers/VimeoRenderer.ts +27 -18
  109. package/src/renderers/YouTubeRenderer.ts +13 -11
  110. package/src/styles/vidply.css +3317 -3243
  111. package/src/types/globals.d.ts +53 -4
  112. package/src/types/renderer.ts +9 -0
  113. package/src/utils/DOMUtils.ts +43 -29
  114. package/src/utils/DraggablePanel.ts +539 -0
  115. package/src/utils/DraggablePanelMenu.ts +195 -0
  116. package/src/utils/DraggableResizable.ts +16 -2
  117. package/src/utils/EventEmitter.ts +15 -6
  118. package/src/utils/FormUtils.ts +2 -2
  119. package/src/utils/MenuFactory.ts +11 -11
  120. package/src/utils/Sanitize.ts +70 -0
  121. package/src/utils/SettingsMenuFactory.ts +1 -1
  122. package/src/utils/StorageManager.ts +6 -18
  123. package/src/utils/UrlSafe.ts +69 -0
  124. package/src/utils/VideoFrameCapture.ts +5 -1
  125. package/src/utils/WindowComponents.ts +2 -2
  126. package/dist/dev/vidply.AudioDescriptionManager-BUFHX3J2.js.map +0 -7
  127. package/dist/dev/vidply.DASHRenderer-FOAYYIJF.js.map +0 -7
  128. package/dist/dev/vidply.FloatingPlayerManager-3UNT4M6W.js.map +0 -7
  129. package/dist/dev/vidply.HLSRenderer-HH6XVVMY.js.map +0 -7
  130. package/dist/dev/vidply.HTML5Renderer-EALCGW6I.js +0 -12
  131. package/dist/dev/vidply.SignLanguageManager-4M2MIZC3.js.map +0 -7
  132. package/dist/dev/vidply.SoundCloudRenderer-2JJDYREC.js.map +0 -7
  133. package/dist/dev/vidply.TranscriptManager-F6PJXVO4.js.map +0 -7
  134. package/dist/dev/vidply.VimeoRenderer-IO3K5LSS.js.map +0 -7
  135. package/dist/dev/vidply.YouTubeRenderer-ZJHLTZZU.js.map +0 -7
  136. package/dist/dev/vidply.chunk-46U2YWJW.js +0 -222
  137. package/dist/dev/vidply.chunk-46U2YWJW.js.map +0 -7
  138. package/dist/dev/vidply.chunk-7KJ26XHK.js.map +0 -7
  139. package/dist/dev/vidply.chunk-QHRUGI7L.js.map +0 -7
  140. package/dist/dev/vidply.chunk-SQ6JPO2C.js.map +0 -7
  141. package/dist/dev/vidply.chunk-TZTAOWPB.js.map +0 -7
  142. package/dist/dev/vidply.de-WKTHZS7V.js.map +0 -7
  143. package/dist/dev/vidply.es-43TEOQ7X.js.map +0 -7
  144. package/dist/dev/vidply.fr-DWFE563C.js.map +0 -7
  145. package/dist/dev/vidply.ja-2KWGACH2.js.map +0 -7
  146. package/dist/prod/vidply.AudioDescriptionManager-X5IBMNM7.min.js +0 -6
  147. package/dist/prod/vidply.DASHRenderer-56SHWHFN.min.js +0 -6
  148. package/dist/prod/vidply.FloatingPlayerManager-FP2EPESL.min.js +0 -6
  149. package/dist/prod/vidply.HLSRenderer-KDGO2GEU.min.js +0 -6
  150. package/dist/prod/vidply.HTML5Renderer-MD6GPCQP.min.js +0 -6
  151. package/dist/prod/vidply.SignLanguageManager-TFFPBAN5.min.js +0 -6
  152. package/dist/prod/vidply.SoundCloudRenderer-VBBM46FY.min.js +0 -6
  153. package/dist/prod/vidply.TranscriptManager-KQGUUYD4.min.js +0 -6
  154. package/dist/prod/vidply.VimeoRenderer-E456QYON.min.js +0 -6
  155. package/dist/prod/vidply.YouTubeRenderer-IPB6SQ2I.min.js +0 -6
  156. package/dist/prod/vidply.chunk-EBN67ABC.min.js +0 -6
  157. package/dist/prod/vidply.chunk-FYSQ2U7B.min.js +0 -6
  158. package/dist/prod/vidply.chunk-KANRCZJM.min.js +0 -6
  159. package/dist/prod/vidply.chunk-PYSBWJTI.min.js +0 -6
  160. package/dist/prod/vidply.chunk-TFIOVVVW.min.js +0 -6
  161. package/dist/prod/vidply.de-ISOL3VDS.min.js +0 -6
  162. package/dist/prod/vidply.es-U32GBZD6.min.js +0 -6
  163. package/dist/prod/vidply.fr-QDYS4CZW.min.js +0 -6
  164. package/dist/prod/vidply.ja-WC2U6RI4.min.js +0 -6
  165. /package/dist/dev/{vidply.HTML5Renderer-EALCGW6I.js.map → vidply.HTML5Renderer-R6HBNQGN.js.map} +0 -0
  166. /package/dist/dev/{vidply.chunk-AGRQTQJL.js.map → vidply.chunk-RTPBWCLO.js.map} +0 -0
@@ -1,13 +1,13 @@
1
1
  /*!
2
- * VidPly v1.1.12 - Universal, Accessible Video Player
2
+ * VidPly v1.1.16 - Universal, Accessible Video Player
3
3
  * (c) 2026 Matthias Peltzer
4
4
  * Released under GPL-2.0-or-later License
5
5
  */
6
6
  import {
7
7
  CaptionManager
8
- } from "./vidply.chunk-TZTAOWPB.js";
9
- import "./vidply.chunk-QHRUGI7L.js";
10
- import "./vidply.chunk-SQ6JPO2C.js";
8
+ } from "./vidply.chunk-R6IULD5Y.js";
9
+ import "./vidply.chunk-VUS3KFUI.js";
10
+ import "./vidply.chunk-C7HDJYKX.js";
11
11
 
12
12
  // src/core/AudioDescriptionManager.ts
13
13
  var AudioDescriptionManager = class {
@@ -63,7 +63,7 @@ var AudioDescriptionManager = class {
63
63
  trackElements.forEach((trackEl) => {
64
64
  const trackKind = trackEl.getAttribute("kind");
65
65
  const trackDescSrc = trackEl.getAttribute("data-desc-src");
66
- if ((trackKind === "captions" || trackKind === "subtitles" || trackKind === "chapters" || trackKind === "descriptions") && trackDescSrc) {
66
+ if ((trackKind === "captions" || trackKind === "subtitles" || trackKind === "chapters" || trackKind === "descriptions") && trackDescSrc && trackEl instanceof HTMLTrackElement) {
67
67
  this.captionTracks.push({
68
68
  trackElement: trackEl,
69
69
  originalSrc: trackEl.getAttribute("src"),
@@ -82,7 +82,7 @@ var AudioDescriptionManager = class {
82
82
  const hasSourceElementsWithDesc = this.player.sourceElements.some(
83
83
  (el) => el.getAttribute("data-desc-src")
84
84
  );
85
- return !!(this.src || hasSourceElementsWithDesc || this.captionTracks.length > 0);
85
+ return Boolean(this.src || hasSourceElementsWithDesc || this.captionTracks.length > 0);
86
86
  }
87
87
  /**
88
88
  * Enable audio description
@@ -217,10 +217,10 @@ var AudioDescriptionManager = class {
217
217
  const validationPromises = this.captionTracks.map(async (trackInfo) => {
218
218
  if (trackInfo.trackElement && trackInfo.describedSrc) {
219
219
  if (trackInfo.explicit === true) {
220
+ const url = toDescribed ? trackInfo.describedSrc : trackInfo.originalSrc;
221
+ if (!url) return { trackInfo, exists: false };
220
222
  try {
221
- const exists = await this._validateTrackExists(
222
- toDescribed ? trackInfo.describedSrc : trackInfo.originalSrc
223
- );
223
+ const exists = await this._validateTrackExists(url);
224
224
  return { trackInfo, exists };
225
225
  } catch {
226
226
  return { trackInfo, exists: false };
@@ -263,9 +263,12 @@ var AudioDescriptionManager = class {
263
263
  await new Promise((resolve) => {
264
264
  setTimeout(() => {
265
265
  tracksToReadd.forEach(({ trackInfo, parent, nextSibling, attributes }) => {
266
+ const newSrc = toDescribed ? trackInfo.describedSrc : trackInfo.originalSrc;
267
+ if (!newSrc) {
268
+ return;
269
+ }
266
270
  swappedTracks.push(trackInfo);
267
271
  const newTrackElement = document.createElement("track");
268
- const newSrc = toDescribed ? trackInfo.describedSrc : trackInfo.originalSrc;
269
272
  newTrackElement.setAttribute("src", newSrc);
270
273
  Object.keys(attributes).forEach((attrName) => {
271
274
  if (attrName !== "src" && attrName !== "data-desc-src") {
@@ -284,7 +287,8 @@ var AudioDescriptionManager = class {
284
287
  const setupNewTracks = () => {
285
288
  this.player.setManagedTimeout(() => {
286
289
  swappedTracks.forEach((trackInfo) => {
287
- const newTextTrack = trackInfo.trackElement.track;
290
+ const trackElement = trackInfo.trackElement;
291
+ const newTextTrack = trackElement.track;
288
292
  if (newTextTrack) {
289
293
  const modeInfo = trackModes.get(trackInfo) || { wasShowing: false, wasHidden: false };
290
294
  newTextTrack.mode = "hidden";
@@ -295,11 +299,11 @@ var AudioDescriptionManager = class {
295
299
  newTextTrack.mode = "disabled";
296
300
  }
297
301
  };
298
- if (newTextTrack.readyState >= 2) {
302
+ if (trackElement.readyState >= 2) {
299
303
  restoreMode();
300
304
  } else {
301
- newTextTrack.addEventListener("load", restoreMode, { once: true });
302
- newTextTrack.addEventListener("error", restoreMode, { once: true });
305
+ trackElement.addEventListener("load", restoreMode, { once: true });
306
+ trackElement.addEventListener("error", restoreMode, { once: true });
303
307
  }
304
308
  }
305
309
  });
@@ -328,7 +332,7 @@ var AudioDescriptionManager = class {
328
332
  const currentSrc = sourceEl.getAttribute("src");
329
333
  if (descSrcAttr) {
330
334
  const type = sourceEl.getAttribute("type");
331
- let origSrc = sourceEl.getAttribute("data-orig-src") || currentSrc;
335
+ const origSrc = sourceEl.getAttribute("data-orig-src") || currentSrc;
332
336
  sourcesToUpdate.push({
333
337
  src: toDescribed ? descSrcAttr : origSrc,
334
338
  type,
@@ -470,6 +474,7 @@ var AudioDescriptionManager = class {
470
474
  if (posterValue && this.player.element.tagName === "VIDEO") {
471
475
  this.player.element.poster = posterValue;
472
476
  }
477
+ if (!this.src) return;
473
478
  this.player.element.src = this.src;
474
479
  await this._waitForMediaReady(currentTime > 0 || wasPlaying);
475
480
  if (currentTime > 0) {
@@ -584,4 +589,4 @@ var AudioDescriptionManager = class {
584
589
  export {
585
590
  AudioDescriptionManager
586
591
  };
587
- //# sourceMappingURL=vidply.AudioDescriptionManager-BUFHX3J2.js.map
592
+ //# sourceMappingURL=vidply.AudioDescriptionManager-DRSYPKJ6.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/AudioDescriptionManager.ts"],
4
+ "sourcesContent": ["/**\n * Audio Description Manager\n * Handles audio-described video source switching and caption track swapping\n */\n\nimport { CaptionManager } from '../controls/CaptionManager.js';\nimport type { Player } from './Player.js';\n\n/**\n * Caption-track entry tracked by the audio-description manager. Each\n * entry pairs a `<track>` element with its described/original source\n * URLs so the manager can swap the rendered captions when the user\n * toggles audio description.\n */\ninterface CaptionTrackInfo {\n trackElement: HTMLTrackElement;\n originalSrc: string | null;\n describedSrc: string;\n originalTrackSrc: string | null;\n explicit: boolean;\n}\n\nexport class AudioDescriptionManager {\n player: Player;\n captionTracks: CaptionTrackInfo[];\n desiredState: boolean;\n enabled: boolean;\n originalSource: string | null;\n sourceElement: Element | null;\n src: string | null;\n\n constructor(player: Player) {\n this.player = player;\n \n // State\n this.enabled = false;\n this.desiredState = false;\n \n // Sources\n this.src = player.options.audioDescriptionSrc;\n this.sourceElement = null;\n this.originalSource = null;\n this.captionTracks = [];\n }\n\n /**\n * Initialize audio description from source elements\n * Called during player initialization\n */\n initFromSourceElements(sourceElements: Element[], trackElements: Element[]) {\n // Check for source elements with audio description attributes\n for (const sourceEl of sourceElements) {\n const descSrc = sourceEl.getAttribute('data-desc-src');\n const origSrc = sourceEl.getAttribute('data-orig-src');\n \n if (descSrc || origSrc) {\n if (!this.sourceElement) {\n this.sourceElement = sourceEl;\n }\n \n if (origSrc) {\n if (!this.originalSource) {\n this.originalSource = origSrc;\n }\n if (!this.player.originalSrc) {\n this.player.originalSrc = origSrc;\n }\n } else {\n const currentSrcAttr = sourceEl.getAttribute('src');\n if (!this.originalSource && currentSrcAttr) {\n this.originalSource = currentSrcAttr;\n }\n if (!this.player.originalSrc && currentSrcAttr) {\n this.player.originalSrc = currentSrcAttr;\n }\n }\n \n if (descSrc && !this.src) {\n this.src = descSrc;\n }\n }\n }\n\n // Check for text tracks with audio description versions\n trackElements.forEach((trackEl: Element) => {\n const trackKind = trackEl.getAttribute('kind');\n const trackDescSrc = trackEl.getAttribute('data-desc-src');\n\n if ((trackKind === 'captions' || trackKind === 'subtitles' ||\n trackKind === 'chapters' || trackKind === 'descriptions') &&\n trackDescSrc && trackEl instanceof HTMLTrackElement) {\n this.captionTracks.push({\n trackElement: trackEl,\n originalSrc: trackEl.getAttribute('src'),\n describedSrc: trackDescSrc,\n originalTrackSrc: trackEl.getAttribute('data-orig-src') || trackEl.getAttribute('src'),\n explicit: true\n });\n this.player.log(`Found explicit described ${trackKind} track: ${trackEl.getAttribute('src')} -> ${trackDescSrc}`);\n }\n });\n }\n\n /**\n * Check if audio description is available\n */\n isAvailable() {\n const hasSourceElementsWithDesc = this.player.sourceElements.some(\n (el: Element) => el.getAttribute('data-desc-src')\n );\n return Boolean(this.src || hasSourceElementsWithDesc || this.captionTracks.length > 0);\n }\n\n /**\n * Enable audio description\n */\n async enable() {\n const hasSourceElementsWithDesc = this.player.sourceElements.some(\n (el: Element) => el.getAttribute('data-desc-src')\n );\n const hasTracksWithDesc = this.captionTracks.length > 0;\n \n if (!this.src && !hasSourceElementsWithDesc && !hasTracksWithDesc) {\n console.warn('VidPly: No audio description source, source elements, or tracks provided');\n return;\n }\n\n this.desiredState = true;\n\n // Store current state for restoration\n const currentTime = this.player.state.currentTime;\n const wasPlaying = this.player.state.playing;\n const posterValue = (this.player.element as HTMLVideoElement).poster || \n this.player.element.getAttribute('poster') || \n this.player.options.poster;\n const shouldKeepPoster = currentTime < 0.1 && !wasPlaying;\n\n // Get current caption text for synchronization\n const currentCaptionText = this._getCurrentCaptionText();\n\n // Switch to audio-described version based on what's available\n if (this.sourceElement) {\n // Use source element approach (data-desc-src on <source> elements)\n await this._enableWithSourceElement(currentTime, wasPlaying, posterValue, shouldKeepPoster, currentCaptionText);\n } else if (this.src) {\n // Use direct src approach (audioDescriptionSrc option)\n await this._enableWithDirectSrc(currentTime, wasPlaying, posterValue, shouldKeepPoster);\n } else if (hasTracksWithDesc) {\n // Only caption tracks with descriptions - swap tracks without changing video source\n await this._swapCaptionTracks(true);\n this.enabled = true;\n this.player.emit('audiodescriptionenabled');\n }\n // If none of the above, we already returned at the top check\n }\n\n /**\n * Disable audio description\n */\n async disable() {\n this.desiredState = false;\n\n // If we only had caption tracks (no video source swap), just swap tracks back\n const hasTracksWithDesc = this.captionTracks.length > 0;\n if (!this.sourceElement && !this.src && hasTracksWithDesc) {\n await this._swapCaptionTracks(false);\n this.enabled = false;\n this.player.emit('audiodescriptiondisabled');\n return;\n }\n\n if (!this.player.originalSrc) {\n return;\n }\n\n // Store current state\n const currentTime = this.player.state.currentTime;\n const wasPlaying = this.player.state.playing;\n const posterValue = (this.player.element as HTMLVideoElement).poster || \n this.player.element.getAttribute('poster') || \n this.player.options.poster;\n const shouldKeepPoster = currentTime < 0.1 && !wasPlaying;\n\n // Get current caption for sync\n const currentCaptionText = this._getCurrentCaptionText();\n\n if (this.sourceElement) {\n await this._disableWithSourceElement(currentTime, wasPlaying, posterValue, shouldKeepPoster, currentCaptionText);\n } else if (this.src) {\n await this._disableWithDirectSrc(currentTime, wasPlaying, posterValue);\n }\n }\n\n /**\n * Toggle audio description\n */\n async toggle() {\n const descriptionTrack = this.player.findTextTrack('descriptions');\n const hasAudioDescriptionSrc = this.isAvailable();\n \n if (descriptionTrack && !hasAudioDescriptionSrc) {\n // Toggle description track playback\n if (descriptionTrack.mode === 'showing') {\n descriptionTrack.mode = 'hidden';\n this.enabled = false;\n this.player.emit('audiodescriptiondisabled');\n } else {\n descriptionTrack.mode = 'showing';\n this.enabled = true;\n this.player.emit('audiodescriptionenabled');\n }\n } else if (descriptionTrack && hasAudioDescriptionSrc) {\n // Toggle both\n if (this.enabled) {\n this.desiredState = false;\n await this.disable();\n } else {\n descriptionTrack.mode = 'showing';\n this.desiredState = true;\n await this.enable();\n }\n } else if (hasAudioDescriptionSrc) {\n // Toggle source\n if (this.enabled) {\n this.desiredState = false;\n await this.disable();\n } else {\n this.desiredState = true;\n await this.enable();\n }\n }\n }\n\n /**\n * Get current caption text for synchronization\n */\n _getCurrentCaptionText() {\n if (this.player.captionManager && \n this.player.captionManager.currentTrack && \n this.player.captionManager.currentCue) {\n return this.player.captionManager.currentCue.text;\n }\n return null;\n }\n\n /**\n * Validate that a track URL exists. Bounded by the player's lifecycle\n * AbortController + an 8s timeout so a torn-down player cannot leak\n * the request.\n */\n async _validateTrackExists(url: string): Promise<boolean> {\n if (typeof url !== 'string' || !url) return false;\n const signals: AbortSignal[] = [];\n const lifecycle = (this.player as { lifecycleSignal?: AbortSignal }).lifecycleSignal;\n if (lifecycle) signals.push(lifecycle);\n if (typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function') {\n signals.push(AbortSignal.timeout(8000));\n }\n let signal: AbortSignal | undefined;\n if (signals.length === 1) signal = signals[0];\n else if (signals.length > 1) {\n const anyFn = (AbortSignal as { any?: (s: AbortSignal[]) => AbortSignal }).any;\n signal = anyFn ? anyFn(signals) : signals[0];\n }\n try {\n const response = await fetch(url, { method: 'HEAD', signal });\n return response.ok;\n } catch {\n return false;\n }\n }\n\n /**\n * Swap caption tracks to described versions\n */\n async _swapCaptionTracks(toDescribed = true) {\n if (this.captionTracks.length === 0) return [];\n\n const swappedTracks: CaptionTrackInfo[] = [];\n \n const validationPromises = this.captionTracks.map(async (trackInfo) => {\n if (trackInfo.trackElement && trackInfo.describedSrc) {\n if (trackInfo.explicit === true) {\n const url = toDescribed ? trackInfo.describedSrc : trackInfo.originalSrc;\n if (!url) return { trackInfo, exists: false };\n try {\n const exists = await this._validateTrackExists(url);\n return { trackInfo, exists };\n } catch {\n return { trackInfo, exists: false };\n }\n }\n }\n return { trackInfo, exists: false };\n });\n \n const validationResults = await Promise.all(validationPromises);\n const tracksToSwap = validationResults.filter(result => result.exists);\n \n if (tracksToSwap.length > 0) {\n // Store track modes before removing\n const trackModes = new Map();\n tracksToSwap.forEach(({ trackInfo }) => {\n const textTrack = trackInfo.trackElement.track;\n if (textTrack) {\n trackModes.set(trackInfo, {\n wasShowing: textTrack.mode === 'showing',\n wasHidden: textTrack.mode === 'hidden'\n });\n } else {\n trackModes.set(trackInfo, { wasShowing: false, wasHidden: false });\n }\n });\n \n // Store track info and remove\n const tracksToReadd = tracksToSwap.map(({ trackInfo }) => {\n const attributes: Record<string, string> = {};\n Array.from(trackInfo.trackElement.attributes).forEach((attr: Attr) => {\n attributes[attr.name] = attr.value;\n });\n \n const result = {\n trackInfo,\n oldSrc: trackInfo.trackElement.getAttribute('src'),\n parent: trackInfo.trackElement.parentNode,\n nextSibling: trackInfo.trackElement.nextSibling,\n attributes\n };\n \n trackInfo.trackElement.remove();\n return result;\n });\n \n // Force browser to process removal\n this.player.element.load();\n \n // Re-add tracks with new src\n await new Promise<void>(resolve => {\n setTimeout(() => {\n tracksToReadd.forEach(({ trackInfo, parent, nextSibling, attributes }) => {\n const newSrc = toDescribed ? trackInfo.describedSrc : trackInfo.originalSrc;\n if (!newSrc) {\n // Skip tracks without a usable src; no swap can occur.\n return;\n }\n swappedTracks.push(trackInfo);\n\n const newTrackElement = document.createElement('track');\n newTrackElement.setAttribute('src', newSrc);\n \n Object.keys(attributes).forEach(attrName => {\n if (attrName !== 'src' && attrName !== 'data-desc-src') {\n newTrackElement.setAttribute(attrName, attributes[attrName]);\n }\n });\n \n // Use the player's video element as parent if the original parent is null\n const targetParent = parent || this.player.element;\n \n if (nextSibling && nextSibling.parentNode) {\n targetParent.insertBefore(newTrackElement, nextSibling);\n } else {\n targetParent.appendChild(newTrackElement);\n }\n \n trackInfo.trackElement = newTrackElement;\n });\n \n this.player.invalidateTrackCache();\n \n // Setup new tracks\n const setupNewTracks = () => {\n this.player.setManagedTimeout(() => {\n swappedTracks.forEach((trackInfo) => {\n const trackElement = trackInfo.trackElement;\n const newTextTrack = trackElement.track;\n if (newTextTrack) {\n const modeInfo = trackModes.get(trackInfo) || { wasShowing: false, wasHidden: false };\n newTextTrack.mode = 'hidden';\n\n const restoreMode = () => {\n if (modeInfo.wasShowing || modeInfo.wasHidden) {\n newTextTrack.mode = 'hidden';\n } else {\n newTextTrack.mode = 'disabled';\n }\n };\n\n // `readyState` and the `load`/`error`\n // events live on `<track>`, not on\n // the underlying TextTrack object.\n if (trackElement.readyState >= 2) {\n restoreMode();\n } else {\n trackElement.addEventListener('load', restoreMode, { once: true });\n trackElement.addEventListener('error', restoreMode, { once: true });\n }\n }\n });\n }, 300);\n };\n \n if (this.player.element.readyState >= 1) {\n setTimeout(setupNewTracks, 200);\n } else {\n this.player.element.addEventListener('loadedmetadata', setupNewTracks, { once: true });\n setTimeout(setupNewTracks, 2000);\n }\n \n resolve();\n }, 100);\n });\n }\n \n return swappedTracks;\n }\n\n /**\n * Update source elements to described versions\n */\n _updateSourceElements(toDescribed = true) {\n const sourceElements = this.player.sourceElements;\n const sourcesToUpdate: Array<{ src: string | null; type: string | null; origSrc: string | null; descSrc: string | null }> = [];\n \n sourceElements.forEach((sourceEl: Element) => {\n const descSrcAttr = sourceEl.getAttribute('data-desc-src');\n const currentSrc = sourceEl.getAttribute('src');\n \n if (descSrcAttr) {\n const type = sourceEl.getAttribute('type');\n const origSrc = sourceEl.getAttribute('data-orig-src') || currentSrc;\n \n sourcesToUpdate.push({\n src: toDescribed ? descSrcAttr : origSrc,\n type,\n origSrc,\n descSrc: descSrcAttr\n });\n } else {\n sourcesToUpdate.push({\n src: sourceEl.getAttribute('src'),\n type: sourceEl.getAttribute('type'),\n origSrc: null,\n descSrc: null\n });\n }\n });\n \n // Remove src attribute if present\n if (this.player.element.hasAttribute('src')) {\n this.player.element.removeAttribute('src');\n }\n \n // Remove all source elements\n sourceElements.forEach((sourceEl: Element) => sourceEl.remove());\n \n // Re-add with updated src\n sourcesToUpdate.forEach((sourceInfo) => {\n if (!sourceInfo.src) {\n return;\n }\n const newSource = document.createElement('source');\n newSource.setAttribute('src', sourceInfo.src);\n if (sourceInfo.type) {\n newSource.setAttribute('type', sourceInfo.type);\n }\n if (sourceInfo.origSrc) {\n newSource.setAttribute('data-orig-src', sourceInfo.origSrc);\n }\n if (sourceInfo.descSrc) {\n newSource.setAttribute('data-desc-src', sourceInfo.descSrc);\n }\n \n const firstTrack = this.player.element.querySelector('track');\n if (firstTrack) {\n this.player.element.insertBefore(newSource, firstTrack);\n } else {\n this.player.element.appendChild(newSource);\n }\n });\n \n this.player._sourceElementsDirty = true;\n this.player._sourceElementsCache = null;\n }\n\n /**\n * Wait for media to be ready\n */\n async _waitForMediaReady(needSeek = false) {\n // Wait for metadata\n await new Promise<void>((resolve) => {\n if (this.player.element.readyState >= 1) {\n resolve();\n } else {\n const onLoad = () => {\n this.player.element.removeEventListener('loadedmetadata', onLoad);\n resolve();\n };\n this.player.element.addEventListener('loadedmetadata', onLoad);\n }\n });\n \n // Wait for tracks\n await new Promise(resolve => setTimeout(resolve, 300));\n \n // Wait for playback if needed\n if (needSeek) {\n await new Promise<void>((resolve) => {\n if (this.player.element.readyState >= 3) {\n resolve();\n } else {\n const onCanPlay = () => {\n this.player.element.removeEventListener('canplay', onCanPlay);\n this.player.element.removeEventListener('canplaythrough', onCanPlay);\n resolve();\n };\n this.player.element.addEventListener('canplay', onCanPlay, { once: true });\n this.player.element.addEventListener('canplaythrough', onCanPlay, { once: true });\n setTimeout(() => {\n this.player.element.removeEventListener('canplay', onCanPlay);\n this.player.element.removeEventListener('canplaythrough', onCanPlay);\n resolve();\n }, 3000);\n }\n });\n }\n }\n\n /**\n * Restore playback state after source change\n */\n async _restorePlaybackState(currentTime: number, wasPlaying: boolean, shouldKeepPoster: boolean, currentCaptionText: string | null) {\n // Try to find matching caption for sync\n let syncTime = currentTime;\n if (currentCaptionText && this.player.captionManager && this.player.captionManager.tracks.length > 0) {\n await new Promise(resolve => setTimeout(resolve, 500));\n const matchingTime = this.player.findMatchingCaptionTime(\n currentCaptionText, \n this.player.captionManager.tracks\n );\n if (matchingTime !== null) {\n syncTime = matchingTime;\n if (this.player.options.debug) {\n this.player.log(`[VidPly] Syncing via caption: ${currentTime}s -> ${syncTime}s`);\n }\n }\n }\n \n // Seek\n if (syncTime > 0) {\n this.player.seek(syncTime);\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n \n // Play/pause\n if (wasPlaying) {\n await this.player.play();\n this.player.setManagedTimeout(() => {\n this.player.hidePosterOverlay();\n }, 100);\n } else {\n this.player.pause();\n if (!shouldKeepPoster) {\n this.player.hidePosterOverlay();\n }\n }\n }\n\n /**\n * Enable with source element method\n */\n async _enableWithSourceElement(currentTime: number, wasPlaying: boolean, posterValue: string | null, shouldKeepPoster: boolean, currentCaptionText: string | null) {\n // Swap caption tracks\n await this._swapCaptionTracks(true);\n \n // Update source elements\n this._updateSourceElements(true);\n \n // Preserve poster\n if (posterValue && this.player.element.tagName === 'VIDEO') {\n (this.player.element as HTMLVideoElement).poster = posterValue;\n }\n \n // Reload\n this.player.element.load();\n \n // Wait for ready\n await this._waitForMediaReady(currentTime > 0 || wasPlaying);\n \n // Restore playback\n await this._restorePlaybackState(currentTime, wasPlaying, shouldKeepPoster, currentCaptionText);\n \n // Update state\n if (!this.desiredState) return;\n this.enabled = true;\n this.player.state.audioDescriptionEnabled = true;\n this.player.emit('audiodescriptionenabled');\n \n // Reload transcript if visible\n this._reloadTranscript();\n }\n\n /**\n * Enable with direct src method\n */\n async _enableWithDirectSrc(currentTime: number, wasPlaying: boolean, posterValue: string | null, shouldKeepPoster: boolean) {\n // Swap caption tracks\n await this._swapCaptionTracks(true);\n \n // Set poster\n if (posterValue && this.player.element.tagName === 'VIDEO') {\n (this.player.element as HTMLVideoElement).poster = posterValue;\n }\n \n // Set src (this method should only be called when this.src exists)\n if (!this.src) return;\n this.player.element.src = this.src;\n \n // Wait and restore\n await this._waitForMediaReady(currentTime > 0 || wasPlaying);\n \n if (currentTime > 0) {\n this.player.seek(currentTime);\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n \n if (wasPlaying) {\n await this.player.play();\n } else {\n this.player.pause();\n if (!shouldKeepPoster) {\n this.player.hidePosterOverlay();\n }\n }\n \n if (!this.desiredState) return;\n this.enabled = true;\n this.player.state.audioDescriptionEnabled = true;\n this.player.emit('audiodescriptionenabled');\n \n // Reload transcript if visible\n this._reloadTranscript();\n }\n\n /**\n * Disable with source element method\n */\n async _disableWithSourceElement(currentTime: number, wasPlaying: boolean, posterValue: string | null, shouldKeepPoster: boolean, currentCaptionText: string | null) {\n // Swap caption tracks back\n await this._swapCaptionTracks(false);\n \n // Update source elements\n this._updateSourceElements(false);\n \n // Preserve poster\n if (posterValue && this.player.element.tagName === 'VIDEO') {\n (this.player.element as HTMLVideoElement).poster = posterValue;\n }\n \n // Reload\n this.player.element.load();\n this.player.invalidateTrackCache();\n \n // Wait for ready\n await this._waitForMediaReady(currentTime > 0 || wasPlaying);\n \n // Restore playback\n await this._restorePlaybackState(currentTime, wasPlaying, shouldKeepPoster, currentCaptionText);\n \n // Reinitialize caption manager\n if (this.player.captionManager) {\n this.player.captionManager.destroy();\n this.player.captionManager = new CaptionManager(this.player);\n }\n \n // Update state\n if (this.desiredState) return;\n this.enabled = false;\n this.player.state.audioDescriptionEnabled = false;\n this.player.emit('audiodescriptiondisabled');\n \n // Reload transcript if visible\n this._reloadTranscript();\n }\n\n /**\n * Disable with direct src method\n */\n async _disableWithDirectSrc(currentTime: number, wasPlaying: boolean, posterValue: string | null) {\n // Swap caption tracks back\n await this._swapCaptionTracks(false);\n \n // Set poster\n if (posterValue && this.player.element.tagName === 'VIDEO') {\n (this.player.element as HTMLVideoElement).poster = posterValue;\n }\n \n // Restore original src\n const originalSrcToUse = this.originalSource || this.player.originalSrc;\n if (!originalSrcToUse) {\n return;\n }\n this.player.element.src = originalSrcToUse;\n this.player.element.load();\n \n // Wait and restore\n await this._waitForMediaReady(currentTime > 0 || wasPlaying);\n \n if (currentTime > 0) {\n this.player.seek(currentTime);\n }\n \n if (wasPlaying) {\n await this.player.play();\n }\n \n if (this.desiredState) return;\n this.enabled = false;\n this.player.state.audioDescriptionEnabled = false;\n this.player.emit('audiodescriptiondisabled');\n \n // Reload transcript if visible\n this._reloadTranscript();\n }\n\n /**\n * Reload transcript after audio description state change\n */\n _reloadTranscript() {\n if (this.player.transcriptManager && this.player.transcriptManager.isVisible) {\n // Wait for tracks to load after source swap\n this.player.setManagedTimeout(() => {\n if (this.player.transcriptManager && this.player.transcriptManager.loadTranscriptData) {\n this.player.transcriptManager.loadTranscriptData();\n }\n }, 800);\n }\n }\n\n /**\n * Update sources (called when playlist changes)\n */\n updateSources(audioDescriptionSrc: string | null | undefined) {\n this.src = audioDescriptionSrc || null;\n // Reset state for new playlist item\n this.enabled = false;\n this.desiredState = false;\n this.sourceElement = null;\n this.originalSource = null;\n this.captionTracks = [];\n }\n \n /**\n * Reinitialize from current player elements (called after playlist loads new tracks)\n */\n reinitialize() {\n this.player.invalidateTrackCache();\n this.initFromSourceElements(this.player.sourceElements, this.player.trackElements);\n }\n\n /**\n * Cleanup\n */\n destroy() {\n this.enabled = false;\n this.desiredState = false;\n this.captionTracks = [];\n this.sourceElement = null;\n this.originalSource = null;\n }\n}\n\n"],
5
+ "mappings": ";;;;;;;;;;;;AAsBO,IAAM,0BAAN,MAA8B;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,QAAgB;AACxB,SAAK,SAAS;AAGd,SAAK,UAAU;AACf,SAAK,eAAe;AAGpB,SAAK,MAAM,OAAO,QAAQ;AAC1B,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,gBAAgB,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAuB,gBAA2B,eAA0B;AAExE,eAAW,YAAY,gBAAgB;AACnC,YAAM,UAAU,SAAS,aAAa,eAAe;AACrD,YAAM,UAAU,SAAS,aAAa,eAAe;AAErD,UAAI,WAAW,SAAS;AACpB,YAAI,CAAC,KAAK,eAAe;AACrB,eAAK,gBAAgB;AAAA,QACzB;AAEA,YAAI,SAAS;AACT,cAAI,CAAC,KAAK,gBAAgB;AACtB,iBAAK,iBAAiB;AAAA,UAC1B;AACA,cAAI,CAAC,KAAK,OAAO,aAAa;AAC1B,iBAAK,OAAO,cAAc;AAAA,UAC9B;AAAA,QACJ,OAAO;AACH,gBAAM,iBAAiB,SAAS,aAAa,KAAK;AAClD,cAAI,CAAC,KAAK,kBAAkB,gBAAgB;AACxC,iBAAK,iBAAiB;AAAA,UAC1B;AACA,cAAI,CAAC,KAAK,OAAO,eAAe,gBAAgB;AAC5C,iBAAK,OAAO,cAAc;AAAA,UAC9B;AAAA,QACJ;AAEA,YAAI,WAAW,CAAC,KAAK,KAAK;AACtB,eAAK,MAAM;AAAA,QACf;AAAA,MACJ;AAAA,IACJ;AAGA,kBAAc,QAAQ,CAAC,YAAqB;AACxC,YAAM,YAAY,QAAQ,aAAa,MAAM;AAC7C,YAAM,eAAe,QAAQ,aAAa,eAAe;AAEzD,WAAK,cAAc,cAAc,cAAc,eAC1C,cAAc,cAAc,cAAc,mBAC1C,gBAAgB,mBAAmB,kBAAkB;AACtD,aAAK,cAAc,KAAK;AAAA,UACpB,cAAc;AAAA,UACd,aAAa,QAAQ,aAAa,KAAK;AAAA,UACvC,cAAc;AAAA,UACd,kBAAkB,QAAQ,aAAa,eAAe,KAAK,QAAQ,aAAa,KAAK;AAAA,UACrF,UAAU;AAAA,QACd,CAAC;AACD,aAAK,OAAO,IAAI,4BAA4B,SAAS,WAAW,QAAQ,aAAa,KAAK,CAAC,OAAO,YAAY,EAAE;AAAA,MACpH;AAAA,IACJ,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc;AACV,UAAM,4BAA4B,KAAK,OAAO,eAAe;AAAA,MACzD,CAAC,OAAgB,GAAG,aAAa,eAAe;AAAA,IACpD;AACA,WAAO,QAAQ,KAAK,OAAO,6BAA6B,KAAK,cAAc,SAAS,CAAC;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS;AACX,UAAM,4BAA4B,KAAK,OAAO,eAAe;AAAA,MACzD,CAAC,OAAgB,GAAG,aAAa,eAAe;AAAA,IACpD;AACA,UAAM,oBAAoB,KAAK,cAAc,SAAS;AAEtD,QAAI,CAAC,KAAK,OAAO,CAAC,6BAA6B,CAAC,mBAAmB;AAC/D,cAAQ,KAAK,0EAA0E;AACvF;AAAA,IACJ;AAEA,SAAK,eAAe;AAGpB,UAAM,cAAc,KAAK,OAAO,MAAM;AACtC,UAAM,aAAa,KAAK,OAAO,MAAM;AACrC,UAAM,cAAe,KAAK,OAAO,QAA6B,UAC3C,KAAK,OAAO,QAAQ,aAAa,QAAQ,KACzC,KAAK,OAAO,QAAQ;AACvC,UAAM,mBAAmB,cAAc,OAAO,CAAC;AAG/C,UAAM,qBAAqB,KAAK,uBAAuB;AAGvD,QAAI,KAAK,eAAe;AAEpB,YAAM,KAAK,yBAAyB,aAAa,YAAY,aAAa,kBAAkB,kBAAkB;AAAA,IAClH,WAAW,KAAK,KAAK;AAEjB,YAAM,KAAK,qBAAqB,aAAa,YAAY,aAAa,gBAAgB;AAAA,IAC1F,WAAW,mBAAmB;AAE1B,YAAM,KAAK,mBAAmB,IAAI;AAClC,WAAK,UAAU;AACf,WAAK,OAAO,KAAK,yBAAyB;AAAA,IAC9C;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU;AACZ,SAAK,eAAe;AAGpB,UAAM,oBAAoB,KAAK,cAAc,SAAS;AACtD,QAAI,CAAC,KAAK,iBAAiB,CAAC,KAAK,OAAO,mBAAmB;AACvD,YAAM,KAAK,mBAAmB,KAAK;AACnC,WAAK,UAAU;AACf,WAAK,OAAO,KAAK,0BAA0B;AAC3C;AAAA,IACJ;AAEA,QAAI,CAAC,KAAK,OAAO,aAAa;AAC1B;AAAA,IACJ;AAGA,UAAM,cAAc,KAAK,OAAO,MAAM;AACtC,UAAM,aAAa,KAAK,OAAO,MAAM;AACrC,UAAM,cAAe,KAAK,OAAO,QAA6B,UAC3C,KAAK,OAAO,QAAQ,aAAa,QAAQ,KACzC,KAAK,OAAO,QAAQ;AACvC,UAAM,mBAAmB,cAAc,OAAO,CAAC;AAG/C,UAAM,qBAAqB,KAAK,uBAAuB;AAEvD,QAAI,KAAK,eAAe;AACpB,YAAM,KAAK,0BAA0B,aAAa,YAAY,aAAa,kBAAkB,kBAAkB;AAAA,IACnH,WAAW,KAAK,KAAK;AACjB,YAAM,KAAK,sBAAsB,aAAa,YAAY,WAAW;AAAA,IACzE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS;AACX,UAAM,mBAAmB,KAAK,OAAO,cAAc,cAAc;AACjE,UAAM,yBAAyB,KAAK,YAAY;AAEhD,QAAI,oBAAoB,CAAC,wBAAwB;AAE7C,UAAI,iBAAiB,SAAS,WAAW;AACrC,yBAAiB,OAAO;AACxB,aAAK,UAAU;AACf,aAAK,OAAO,KAAK,0BAA0B;AAAA,MAC/C,OAAO;AACH,yBAAiB,OAAO;AACxB,aAAK,UAAU;AACf,aAAK,OAAO,KAAK,yBAAyB;AAAA,MAC9C;AAAA,IACJ,WAAW,oBAAoB,wBAAwB;AAEnD,UAAI,KAAK,SAAS;AACd,aAAK,eAAe;AACpB,cAAM,KAAK,QAAQ;AAAA,MACvB,OAAO;AACH,yBAAiB,OAAO;AACxB,aAAK,eAAe;AACpB,cAAM,KAAK,OAAO;AAAA,MACtB;AAAA,IACJ,WAAW,wBAAwB;AAE/B,UAAI,KAAK,SAAS;AACd,aAAK,eAAe;AACpB,cAAM,KAAK,QAAQ;AAAA,MACvB,OAAO;AACH,aAAK,eAAe;AACpB,cAAM,KAAK,OAAO;AAAA,MACtB;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,yBAAyB;AACrB,QAAI,KAAK,OAAO,kBACZ,KAAK,OAAO,eAAe,gBAC3B,KAAK,OAAO,eAAe,YAAY;AACvC,aAAO,KAAK,OAAO,eAAe,WAAW;AAAA,IACjD;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,qBAAqB,KAA+B;AACtD,QAAI,OAAO,QAAQ,YAAY,CAAC,IAAK,QAAO;AAC5C,UAAM,UAAyB,CAAC;AAChC,UAAM,YAAa,KAAK,OAA6C;AACrE,QAAI,UAAW,SAAQ,KAAK,SAAS;AACrC,QAAI,OAAO,gBAAgB,eAAe,OAAO,YAAY,YAAY,YAAY;AACjF,cAAQ,KAAK,YAAY,QAAQ,GAAI,CAAC;AAAA,IAC1C;AACA,QAAI;AACJ,QAAI,QAAQ,WAAW,EAAG,UAAS,QAAQ,CAAC;AAAA,aACnC,QAAQ,SAAS,GAAG;AACzB,YAAM,QAAS,YAA4D;AAC3E,eAAS,QAAQ,MAAM,OAAO,IAAI,QAAQ,CAAC;AAAA,IAC/C;AACA,QAAI;AACA,YAAM,WAAW,MAAM,MAAM,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC;AAC5D,aAAO,SAAS;AAAA,IACpB,QAAQ;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAmB,cAAc,MAAM;AACzC,QAAI,KAAK,cAAc,WAAW,EAAG,QAAO,CAAC;AAE7C,UAAM,gBAAoC,CAAC;AAE3C,UAAM,qBAAqB,KAAK,cAAc,IAAI,OAAO,cAAc;AACnE,UAAI,UAAU,gBAAgB,UAAU,cAAc;AAClD,YAAI,UAAU,aAAa,MAAM;AAC7B,gBAAM,MAAM,cAAc,UAAU,eAAe,UAAU;AAC7D,cAAI,CAAC,IAAK,QAAO,EAAE,WAAW,QAAQ,MAAM;AAC5C,cAAI;AACA,kBAAM,SAAS,MAAM,KAAK,qBAAqB,GAAG;AAClD,mBAAO,EAAE,WAAW,OAAO;AAAA,UAC/B,QAAQ;AACJ,mBAAO,EAAE,WAAW,QAAQ,MAAM;AAAA,UACtC;AAAA,QACJ;AAAA,MACJ;AACA,aAAO,EAAE,WAAW,QAAQ,MAAM;AAAA,IACtC,CAAC;AAED,UAAM,oBAAoB,MAAM,QAAQ,IAAI,kBAAkB;AAC9D,UAAM,eAAe,kBAAkB,OAAO,YAAU,OAAO,MAAM;AAErE,QAAI,aAAa,SAAS,GAAG;AAEzB,YAAM,aAAa,oBAAI,IAAI;AAC3B,mBAAa,QAAQ,CAAC,EAAE,UAAU,MAAM;AACpC,cAAM,YAAY,UAAU,aAAa;AACzC,YAAI,WAAW;AACX,qBAAW,IAAI,WAAW;AAAA,YACtB,YAAY,UAAU,SAAS;AAAA,YAC/B,WAAW,UAAU,SAAS;AAAA,UAClC,CAAC;AAAA,QACL,OAAO;AACH,qBAAW,IAAI,WAAW,EAAE,YAAY,OAAO,WAAW,MAAM,CAAC;AAAA,QACrE;AAAA,MACJ,CAAC;AAGD,YAAM,gBAAgB,aAAa,IAAI,CAAC,EAAE,UAAU,MAAM;AACtD,cAAM,aAAqC,CAAC;AAC5C,cAAM,KAAK,UAAU,aAAa,UAAU,EAAE,QAAQ,CAAC,SAAe;AAClE,qBAAW,KAAK,IAAI,IAAI,KAAK;AAAA,QACjC,CAAC;AAED,cAAM,SAAS;AAAA,UACX;AAAA,UACA,QAAQ,UAAU,aAAa,aAAa,KAAK;AAAA,UACjD,QAAQ,UAAU,aAAa;AAAA,UAC/B,aAAa,UAAU,aAAa;AAAA,UACpC;AAAA,QACJ;AAEA,kBAAU,aAAa,OAAO;AAC9B,eAAO;AAAA,MACX,CAAC;AAGD,WAAK,OAAO,QAAQ,KAAK;AAGzB,YAAM,IAAI,QAAc,aAAW;AAC/B,mBAAW,MAAM;AACb,wBAAc,QAAQ,CAAC,EAAE,WAAW,QAAQ,aAAa,WAAW,MAAM;AACtE,kBAAM,SAAS,cAAc,UAAU,eAAe,UAAU;AAChE,gBAAI,CAAC,QAAQ;AAET;AAAA,YACJ;AACA,0BAAc,KAAK,SAAS;AAE5B,kBAAM,kBAAkB,SAAS,cAAc,OAAO;AACtD,4BAAgB,aAAa,OAAO,MAAM;AAE1C,mBAAO,KAAK,UAAU,EAAE,QAAQ,cAAY;AACxC,kBAAI,aAAa,SAAS,aAAa,iBAAiB;AACpD,gCAAgB,aAAa,UAAU,WAAW,QAAQ,CAAC;AAAA,cAC/D;AAAA,YACJ,CAAC;AAGD,kBAAM,eAAe,UAAU,KAAK,OAAO;AAE3C,gBAAI,eAAe,YAAY,YAAY;AACvC,2BAAa,aAAa,iBAAiB,WAAW;AAAA,YAC1D,OAAO;AACH,2BAAa,YAAY,eAAe;AAAA,YAC5C;AAEA,sBAAU,eAAe;AAAA,UAC7B,CAAC;AAED,eAAK,OAAO,qBAAqB;AAGjC,gBAAM,iBAAiB,MAAM;AACzB,iBAAK,OAAO,kBAAkB,MAAM;AAChC,4BAAc,QAAQ,CAAC,cAAc;AACjC,sBAAM,eAAe,UAAU;AAC/B,sBAAM,eAAe,aAAa;AAClC,oBAAI,cAAc;AACd,wBAAM,WAAW,WAAW,IAAI,SAAS,KAAK,EAAE,YAAY,OAAO,WAAW,MAAM;AACpF,+BAAa,OAAO;AAEpB,wBAAM,cAAc,MAAM;AACtB,wBAAI,SAAS,cAAc,SAAS,WAAW;AAC3C,mCAAa,OAAO;AAAA,oBACxB,OAAO;AACH,mCAAa,OAAO;AAAA,oBACxB;AAAA,kBACJ;AAKA,sBAAI,aAAa,cAAc,GAAG;AAC9B,gCAAY;AAAA,kBAChB,OAAO;AACH,iCAAa,iBAAiB,QAAQ,aAAa,EAAE,MAAM,KAAK,CAAC;AACjE,iCAAa,iBAAiB,SAAS,aAAa,EAAE,MAAM,KAAK,CAAC;AAAA,kBACtE;AAAA,gBACJ;AAAA,cACJ,CAAC;AAAA,YACL,GAAG,GAAG;AAAA,UACV;AAEA,cAAI,KAAK,OAAO,QAAQ,cAAc,GAAG;AACrC,uBAAW,gBAAgB,GAAG;AAAA,UAClC,OAAO;AACH,iBAAK,OAAO,QAAQ,iBAAiB,kBAAkB,gBAAgB,EAAE,MAAM,KAAK,CAAC;AACrF,uBAAW,gBAAgB,GAAI;AAAA,UACnC;AAEA,kBAAQ;AAAA,QACZ,GAAG,GAAG;AAAA,MACV,CAAC;AAAA,IACL;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,cAAc,MAAM;AACtC,UAAM,iBAAiB,KAAK,OAAO;AACnC,UAAM,kBAAsH,CAAC;AAE7H,mBAAe,QAAQ,CAAC,aAAsB;AAC1C,YAAM,cAAc,SAAS,aAAa,eAAe;AACzD,YAAM,aAAa,SAAS,aAAa,KAAK;AAE9C,UAAI,aAAa;AACb,cAAM,OAAO,SAAS,aAAa,MAAM;AACzC,cAAM,UAAU,SAAS,aAAa,eAAe,KAAK;AAE1D,wBAAgB,KAAK;AAAA,UACjB,KAAK,cAAc,cAAc;AAAA,UACjC;AAAA,UACA;AAAA,UACA,SAAS;AAAA,QACb,CAAC;AAAA,MACL,OAAO;AACH,wBAAgB,KAAK;AAAA,UACjB,KAAK,SAAS,aAAa,KAAK;AAAA,UAChC,MAAM,SAAS,aAAa,MAAM;AAAA,UAClC,SAAS;AAAA,UACT,SAAS;AAAA,QACb,CAAC;AAAA,MACL;AAAA,IACJ,CAAC;AAGD,QAAI,KAAK,OAAO,QAAQ,aAAa,KAAK,GAAG;AACzC,WAAK,OAAO,QAAQ,gBAAgB,KAAK;AAAA,IAC7C;AAGA,mBAAe,QAAQ,CAAC,aAAsB,SAAS,OAAO,CAAC;AAG/D,oBAAgB,QAAQ,CAAC,eAAe;AACpC,UAAI,CAAC,WAAW,KAAK;AACjB;AAAA,MACJ;AACA,YAAM,YAAY,SAAS,cAAc,QAAQ;AACjD,gBAAU,aAAa,OAAO,WAAW,GAAG;AAC5C,UAAI,WAAW,MAAM;AACjB,kBAAU,aAAa,QAAQ,WAAW,IAAI;AAAA,MAClD;AACA,UAAI,WAAW,SAAS;AACpB,kBAAU,aAAa,iBAAiB,WAAW,OAAO;AAAA,MAC9D;AACA,UAAI,WAAW,SAAS;AACpB,kBAAU,aAAa,iBAAiB,WAAW,OAAO;AAAA,MAC9D;AAEA,YAAM,aAAa,KAAK,OAAO,QAAQ,cAAc,OAAO;AAC5D,UAAI,YAAY;AACZ,aAAK,OAAO,QAAQ,aAAa,WAAW,UAAU;AAAA,MAC1D,OAAO;AACH,aAAK,OAAO,QAAQ,YAAY,SAAS;AAAA,MAC7C;AAAA,IACJ,CAAC;AAED,SAAK,OAAO,uBAAuB;AACnC,SAAK,OAAO,uBAAuB;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAmB,WAAW,OAAO;AAEvC,UAAM,IAAI,QAAc,CAAC,YAAY;AACjC,UAAI,KAAK,OAAO,QAAQ,cAAc,GAAG;AACrC,gBAAQ;AAAA,MACZ,OAAO;AACH,cAAM,SAAS,MAAM;AACjB,eAAK,OAAO,QAAQ,oBAAoB,kBAAkB,MAAM;AAChE,kBAAQ;AAAA,QACZ;AACA,aAAK,OAAO,QAAQ,iBAAiB,kBAAkB,MAAM;AAAA,MACjE;AAAA,IACJ,CAAC;AAGD,UAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAG,CAAC;AAGrD,QAAI,UAAU;AACV,YAAM,IAAI,QAAc,CAAC,YAAY;AACjC,YAAI,KAAK,OAAO,QAAQ,cAAc,GAAG;AACrC,kBAAQ;AAAA,QACZ,OAAO;AACH,gBAAM,YAAY,MAAM;AACpB,iBAAK,OAAO,QAAQ,oBAAoB,WAAW,SAAS;AAC5D,iBAAK,OAAO,QAAQ,oBAAoB,kBAAkB,SAAS;AACnE,oBAAQ;AAAA,UACZ;AACA,eAAK,OAAO,QAAQ,iBAAiB,WAAW,WAAW,EAAE,MAAM,KAAK,CAAC;AACzE,eAAK,OAAO,QAAQ,iBAAiB,kBAAkB,WAAW,EAAE,MAAM,KAAK,CAAC;AAChF,qBAAW,MAAM;AACb,iBAAK,OAAO,QAAQ,oBAAoB,WAAW,SAAS;AAC5D,iBAAK,OAAO,QAAQ,oBAAoB,kBAAkB,SAAS;AACnE,oBAAQ;AAAA,UACZ,GAAG,GAAI;AAAA,QACX;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,sBAAsB,aAAqB,YAAqB,kBAA2B,oBAAmC;AAEhI,QAAI,WAAW;AACf,QAAI,sBAAsB,KAAK,OAAO,kBAAkB,KAAK,OAAO,eAAe,OAAO,SAAS,GAAG;AAClG,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAG,CAAC;AACrD,YAAM,eAAe,KAAK,OAAO;AAAA,QAC7B;AAAA,QACA,KAAK,OAAO,eAAe;AAAA,MAC/B;AACA,UAAI,iBAAiB,MAAM;AACvB,mBAAW;AACX,YAAI,KAAK,OAAO,QAAQ,OAAO;AAC3B,eAAK,OAAO,IAAI,iCAAiC,WAAW,QAAQ,QAAQ,GAAG;AAAA,QACnF;AAAA,MACJ;AAAA,IACJ;AAGA,QAAI,WAAW,GAAG;AACd,WAAK,OAAO,KAAK,QAAQ;AACzB,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAG,CAAC;AAAA,IACzD;AAGA,QAAI,YAAY;AACZ,YAAM,KAAK,OAAO,KAAK;AACvB,WAAK,OAAO,kBAAkB,MAAM;AAChC,aAAK,OAAO,kBAAkB;AAAA,MAClC,GAAG,GAAG;AAAA,IACV,OAAO;AACH,WAAK,OAAO,MAAM;AAClB,UAAI,CAAC,kBAAkB;AACnB,aAAK,OAAO,kBAAkB;AAAA,MAClC;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,yBAAyB,aAAqB,YAAqB,aAA4B,kBAA2B,oBAAmC;AAE/J,UAAM,KAAK,mBAAmB,IAAI;AAGlC,SAAK,sBAAsB,IAAI;AAG/B,QAAI,eAAe,KAAK,OAAO,QAAQ,YAAY,SAAS;AACxD,MAAC,KAAK,OAAO,QAA6B,SAAS;AAAA,IACvD;AAGA,SAAK,OAAO,QAAQ,KAAK;AAGzB,UAAM,KAAK,mBAAmB,cAAc,KAAK,UAAU;AAG3D,UAAM,KAAK,sBAAsB,aAAa,YAAY,kBAAkB,kBAAkB;AAG9F,QAAI,CAAC,KAAK,aAAc;AACxB,SAAK,UAAU;AACf,SAAK,OAAO,MAAM,0BAA0B;AAC5C,SAAK,OAAO,KAAK,yBAAyB;AAG1C,SAAK,kBAAkB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAqB,aAAqB,YAAqB,aAA4B,kBAA2B;AAExH,UAAM,KAAK,mBAAmB,IAAI;AAGlC,QAAI,eAAe,KAAK,OAAO,QAAQ,YAAY,SAAS;AACxD,MAAC,KAAK,OAAO,QAA6B,SAAS;AAAA,IACvD;AAGA,QAAI,CAAC,KAAK,IAAK;AACf,SAAK,OAAO,QAAQ,MAAM,KAAK;AAG/B,UAAM,KAAK,mBAAmB,cAAc,KAAK,UAAU;AAE3D,QAAI,cAAc,GAAG;AACjB,WAAK,OAAO,KAAK,WAAW;AAC5B,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAG,CAAC;AAAA,IACzD;AAEA,QAAI,YAAY;AACZ,YAAM,KAAK,OAAO,KAAK;AAAA,IAC3B,OAAO;AACH,WAAK,OAAO,MAAM;AAClB,UAAI,CAAC,kBAAkB;AACnB,aAAK,OAAO,kBAAkB;AAAA,MAClC;AAAA,IACJ;AAEA,QAAI,CAAC,KAAK,aAAc;AACxB,SAAK,UAAU;AACf,SAAK,OAAO,MAAM,0BAA0B;AAC5C,SAAK,OAAO,KAAK,yBAAyB;AAG1C,SAAK,kBAAkB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,0BAA0B,aAAqB,YAAqB,aAA4B,kBAA2B,oBAAmC;AAEhK,UAAM,KAAK,mBAAmB,KAAK;AAGnC,SAAK,sBAAsB,KAAK;AAGhC,QAAI,eAAe,KAAK,OAAO,QAAQ,YAAY,SAAS;AACxD,MAAC,KAAK,OAAO,QAA6B,SAAS;AAAA,IACvD;AAGA,SAAK,OAAO,QAAQ,KAAK;AACzB,SAAK,OAAO,qBAAqB;AAGjC,UAAM,KAAK,mBAAmB,cAAc,KAAK,UAAU;AAG3D,UAAM,KAAK,sBAAsB,aAAa,YAAY,kBAAkB,kBAAkB;AAG9F,QAAI,KAAK,OAAO,gBAAgB;AAC5B,WAAK,OAAO,eAAe,QAAQ;AACnC,WAAK,OAAO,iBAAiB,IAAI,eAAe,KAAK,MAAM;AAAA,IAC/D;AAGA,QAAI,KAAK,aAAc;AACvB,SAAK,UAAU;AACf,SAAK,OAAO,MAAM,0BAA0B;AAC5C,SAAK,OAAO,KAAK,0BAA0B;AAG3C,SAAK,kBAAkB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,sBAAsB,aAAqB,YAAqB,aAA4B;AAE9F,UAAM,KAAK,mBAAmB,KAAK;AAGnC,QAAI,eAAe,KAAK,OAAO,QAAQ,YAAY,SAAS;AACxD,MAAC,KAAK,OAAO,QAA6B,SAAS;AAAA,IACvD;AAGA,UAAM,mBAAmB,KAAK,kBAAkB,KAAK,OAAO;AAC5D,QAAI,CAAC,kBAAkB;AACnB;AAAA,IACJ;AACA,SAAK,OAAO,QAAQ,MAAM;AAC1B,SAAK,OAAO,QAAQ,KAAK;AAGzB,UAAM,KAAK,mBAAmB,cAAc,KAAK,UAAU;AAE3D,QAAI,cAAc,GAAG;AACjB,WAAK,OAAO,KAAK,WAAW;AAAA,IAChC;AAEA,QAAI,YAAY;AACZ,YAAM,KAAK,OAAO,KAAK;AAAA,IAC3B;AAEA,QAAI,KAAK,aAAc;AACvB,SAAK,UAAU;AACf,SAAK,OAAO,MAAM,0BAA0B;AAC5C,SAAK,OAAO,KAAK,0BAA0B;AAG3C,SAAK,kBAAkB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB;AAChB,QAAI,KAAK,OAAO,qBAAqB,KAAK,OAAO,kBAAkB,WAAW;AAE1E,WAAK,OAAO,kBAAkB,MAAM;AAChC,YAAI,KAAK,OAAO,qBAAqB,KAAK,OAAO,kBAAkB,oBAAoB;AACnF,eAAK,OAAO,kBAAkB,mBAAmB;AAAA,QACrD;AAAA,MACJ,GAAG,GAAG;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,qBAAgD;AAC1D,SAAK,MAAM,uBAAuB;AAElC,SAAK,UAAU;AACf,SAAK,eAAe;AACpB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,gBAAgB,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe;AACX,SAAK,OAAO,qBAAqB;AACjC,SAAK,uBAAuB,KAAK,OAAO,gBAAgB,KAAK,OAAO,aAAa;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACN,SAAK,UAAU;AACf,SAAK,eAAe;AACpB,SAAK,gBAAgB,CAAC;AACtB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AAAA,EAC1B;AACJ;",
6
+ "names": []
7
+ }
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * VidPly v1.1.12 - Universal, Accessible Video Player
2
+ * VidPly v1.1.16 - Universal, Accessible Video Player
3
3
  * (c) 2026 Matthias Peltzer
4
4
  * Released under GPL-2.0-or-later License
5
5
  */
@@ -190,10 +190,12 @@ var DASHRenderer = class {
190
190
  }
191
191
  attachDashEvents() {
192
192
  const dashjs = window.dashjs;
193
- if (!dashjs) return;
193
+ const dash = this.dash;
194
+ if (!dashjs || !dash) return;
194
195
  const dashEvents = dashjs.MediaPlayer.events;
195
- this.dash.on(dashEvents.MANIFEST_LOADED, (e) => {
196
- const data = e.data || e;
196
+ dash.on(dashEvents.MANIFEST_LOADED, (...args) => {
197
+ const e = args[0];
198
+ const data = e?.data ?? e;
197
199
  this.player.log("DASH manifest loaded");
198
200
  this.player.emit("dashmanifestloaded", data);
199
201
  if (this.player.container) {
@@ -203,14 +205,16 @@ var DASHRenderer = class {
203
205
  this._checkSubtitleTracks();
204
206
  }, 500);
205
207
  });
206
- this.dash.on(dashEvents.QUALITY_CHANGE_RENDERED, (e) => {
208
+ dash.on(dashEvents.QUALITY_CHANGE_RENDERED, (...args) => {
209
+ const e = args[0];
207
210
  if (e.mediaType === "video") {
208
211
  this.player.log("DASH quality changed to index " + e.newQuality);
209
212
  this.player.emit("dashqualitychanged", e);
210
213
  }
211
214
  });
212
- this.dash.on(dashEvents.TEXT_TRACKS_ADDED, (e) => {
213
- const tracks = e.tracks || [];
215
+ dash.on(dashEvents.TEXT_TRACKS_ADDED, (...args) => {
216
+ const e = args[0];
217
+ const tracks = e?.tracks ?? [];
214
218
  this._dashTextTracks = tracks;
215
219
  this._dashTextIsTtml = tracks.some(
216
220
  (t) => t.isTTML || /stpp|ttml/i.test(t.codec || "") || /ttml/i.test(t.mimeType || "")
@@ -221,15 +225,15 @@ var DASHRenderer = class {
221
225
  this.updateCaptionButtonsForDash();
222
226
  if (tracks.length > 0) {
223
227
  try {
224
- this.dash.setTextTrack(0);
225
- } catch (err) {
228
+ dash.setTextTrack(0);
229
+ } catch {
226
230
  }
227
231
  if (!this._dashTextIsTtml) {
228
232
  this._startCueUpdatePolling();
229
233
  }
230
234
  }
231
235
  });
232
- this.dash.on(dashEvents.STREAM_INITIALIZED, () => {
236
+ dash.on(dashEvents.STREAM_INITIALIZED, () => {
233
237
  this.player.log("DASH stream initialized");
234
238
  this.player.emit("dashstreaminitialized");
235
239
  this._setTimeout(() => {
@@ -239,12 +243,13 @@ var DASHRenderer = class {
239
243
  }
240
244
  }, 300);
241
245
  });
242
- this.dash.on(dashEvents.ERROR, (e) => {
243
- this.handleDashError(e);
246
+ dash.on(dashEvents.ERROR, (...args) => {
247
+ this.handleDashError(args[0]);
244
248
  });
245
- this.dash.on(dashEvents.FRAGMENT_LOADING_COMPLETED, (e) => {
249
+ dash.on(dashEvents.FRAGMENT_LOADING_COMPLETED, (...args) => {
250
+ const e = args[0];
246
251
  this.player.state.buffering = false;
247
- if (e.request && e.request.mediaType === "text" && !this._dashTextIsTtml) {
252
+ if (e?.request?.mediaType === "text" && !this._dashTextIsTtml) {
248
253
  this._setTimeout(() => {
249
254
  const count = this._getTotalCueCount();
250
255
  if (count > this._lastKnownCueCount) {
@@ -310,7 +315,7 @@ var DASHRenderer = class {
310
315
  if (this.dash) {
311
316
  try {
312
317
  this.dash.setTextTrack(-1);
313
- } catch (e) {
318
+ } catch {
314
319
  }
315
320
  }
316
321
  };
@@ -334,7 +339,7 @@ var DASHRenderer = class {
334
339
  this.player.log(`Syncing DASH text track to index ${dashIndex} (${lang})`);
335
340
  try {
336
341
  this.dash.setTextTrack(dashIndex);
337
- } catch (err) {
342
+ } catch {
338
343
  }
339
344
  if (!this._dashTextIsTtml) {
340
345
  this._lastKnownCueCount = 0;
@@ -516,16 +521,17 @@ var DASHRenderer = class {
516
521
  });
517
522
  }
518
523
  handleDashError(e) {
519
- const error = e.error || e;
524
+ const wrapped = e;
525
+ const error = wrapped?.error ?? wrapped;
520
526
  if (!error) return;
521
527
  const code = error.code ?? "";
522
528
  const message = error.message || "";
523
529
  this.player.log(`DASH Error - Code: ${code}, Message: ${message}`, "warn");
524
- if (code && code >= 100) {
530
+ if (typeof code === "number" && code >= 100) {
525
531
  this.player.log("Fatal DASH error", "error");
526
532
  this.player.handleError(new Error(`DASH Error: ${code} - ${message}`));
527
533
  } else {
528
- this.player.log("Non-fatal DASH error: " + (message || error), "warn");
534
+ this.player.log("Non-fatal DASH error: " + (message || String(error)), "warn");
529
535
  }
530
536
  }
531
537
  ensureLoaded() {
@@ -545,7 +551,7 @@ var DASHRenderer = class {
545
551
  try {
546
552
  this.dash.attachSource(src);
547
553
  this._dashSourceLoaded = true;
548
- } catch (e) {
554
+ } catch {
549
555
  }
550
556
  }
551
557
  play() {
@@ -557,7 +563,7 @@ var DASHRenderer = class {
557
563
  try {
558
564
  this.dash.attachSource(src);
559
565
  this._dashSourceLoaded = true;
560
- } catch (e) {
566
+ } catch {
561
567
  }
562
568
  }
563
569
  }
@@ -671,7 +677,7 @@ var DASHRenderer = class {
671
677
  name
672
678
  };
673
679
  });
674
- } catch (e) {
680
+ } catch {
675
681
  return [];
676
682
  }
677
683
  }
@@ -687,7 +693,7 @@ var DASHRenderer = class {
687
693
  }
688
694
  }
689
695
  return this.dash.getQualityFor("video");
690
- } catch (e) {
696
+ } catch {
691
697
  return -1;
692
698
  }
693
699
  }
@@ -715,7 +721,7 @@ var DASHRenderer = class {
715
721
  this.player.log(`Activating DASH text track index ${dashIndex} for transcript language "${lang}"`);
716
722
  try {
717
723
  this.dash.setTextTrack(dashIndex);
718
- } catch (err) {
724
+ } catch {
719
725
  }
720
726
  if (this.media.paused) {
721
727
  const pos = this.media.currentTime;
@@ -754,18 +760,29 @@ var DASHRenderer = class {
754
760
  if (!manifest) return [];
755
761
  const baseUrl = this._manifestUrl.substring(0, this._manifestUrl.lastIndexOf("/") + 1);
756
762
  const results = [];
757
- const periods = manifest.Period || manifest.period || (manifest.periods ? manifest.periods : [manifest]);
758
- for (const period of Array.isArray(periods) ? periods : [periods]) {
759
- const adaptSets = period.AdaptationSet || period.adaptationSet || period.AdaptationSet_asArray || [];
760
- for (const as of Array.isArray(adaptSets) ? adaptSets : [adaptSets]) {
761
- const ct = as.contentType || as.ContentType || "";
762
- const mime = as.mimeType || as.MimeType || "";
763
+ const rawPeriods = manifest.Period || manifest.period || manifest.periods || manifest;
764
+ const periods = Array.isArray(rawPeriods) ? rawPeriods : [rawPeriods];
765
+ for (const period of periods) {
766
+ const rawAdaptSets = period.AdaptationSet || period.adaptationSet || period.AdaptationSet_asArray || [];
767
+ const adaptSets = Array.isArray(rawAdaptSets) ? rawAdaptSets : [rawAdaptSets];
768
+ for (const as of adaptSets) {
769
+ const ct = String(as.contentType || as.ContentType || "");
770
+ const mime = String(as.mimeType || as.MimeType || "");
763
771
  if (ct !== "text" && !/text\/vtt|application\/ttml/i.test(mime)) continue;
764
- const lang = as.lang || as.language || "";
765
- const reps = as.Representation || as.representation || as.Representation_asArray || [];
766
- for (const rep of Array.isArray(reps) ? reps : [reps]) {
772
+ const lang = String(as.lang || as.language || "");
773
+ const rawReps = as.Representation || as.representation || as.Representation_asArray || [];
774
+ const reps = Array.isArray(rawReps) ? rawReps : [rawReps];
775
+ for (const rep of reps) {
767
776
  const bu = rep.BaseURL || rep.baseURL || rep.BaseURL_asArray;
768
- const rawUrl = Array.isArray(bu) ? bu[0]?.__text || bu[0] : bu?.__text || bu;
777
+ let rawUrl;
778
+ if (Array.isArray(bu)) {
779
+ const first = bu[0];
780
+ rawUrl = typeof first === "string" ? first : first?.__text;
781
+ } else if (typeof bu === "string") {
782
+ rawUrl = bu;
783
+ } else {
784
+ rawUrl = bu?.__text;
785
+ }
769
786
  if (!rawUrl) continue;
770
787
  const url = rawUrl.startsWith("http") ? rawUrl : new URL(rawUrl, baseUrl).href;
771
788
  results.push({ lang, url });
@@ -787,9 +804,9 @@ var DASHRenderer = class {
787
804
  if (typeof this.dash.getAutoSwitchQualityFor === "function") {
788
805
  return this.dash.getAutoSwitchQualityFor("video");
789
806
  }
790
- const settings = this.dash.getSettings();
807
+ const settings = this.dash.getSettings?.();
791
808
  return settings?.streaming?.abr?.autoSwitchBitrate?.video !== false;
792
- } catch (e) {
809
+ } catch {
793
810
  return true;
794
811
  }
795
812
  }
@@ -822,11 +839,11 @@ var DASHRenderer = class {
822
839
  try {
823
840
  this.dash.updateSettings({ debug: { logLevel: 0 } });
824
841
  this.dash.reset();
825
- } catch (e) {
842
+ } catch {
826
843
  }
827
844
  try {
828
845
  this.dash.destroy();
829
- } catch (e) {
846
+ } catch {
830
847
  }
831
848
  this.dash = null;
832
849
  }
@@ -838,4 +855,4 @@ var DASHRenderer = class {
838
855
  export {
839
856
  DASHRenderer
840
857
  };
841
- //# sourceMappingURL=vidply.DASHRenderer-FOAYYIJF.js.map
858
+ //# sourceMappingURL=vidply.DASHRenderer-A6G2BQJ6.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/renderers/DASHRenderer.ts"],
4
+ "sourcesContent": ["import type { Renderer } from '../types/renderer.js';\nimport type { Player } from '../core/Player.js';\n\ninterface DashTextTrack {\n lang?: string;\n language?: string;\n srclang?: string;\n kind?: string;\n label?: string;\n labels?: string;\n isTTML?: boolean;\n codec?: string;\n mimeType?: string;\n [key: string]: unknown;\n}\n\n/**\n * Shape of payloads emitted by VidPly's `captionsenabled` event when\n * routed into a DASH renderer. These come from CaptionManager and carry\n * both the language and the underlying TextTrack reference.\n */\ninterface CaptionTrackSelection {\n language?: string;\n label?: string;\n track?: TextTrack;\n}\n\ntype CaptionEnabledHandler = (track: CaptionTrackSelection) => void;\ntype CaptionDisabledHandler = () => void;\n\nexport class DASHRenderer implements Renderer {\n player: Player;\n media: HTMLMediaElement;\n dash: DashMediaPlayerInstance | null;\n readonly isStreaming = true;\n _dashSourceLoaded: boolean;\n _pendingSrc: string | null;\n _dashSubtitleTracksCount: number | undefined;\n _dashTextTracks: DashTextTrack[];\n _cueUpdateTimer: ReturnType<typeof setInterval> | null;\n _captionEnabledHandler: CaptionEnabledHandler | null;\n _captionDisabledHandler: CaptionDisabledHandler | null;\n _lastKnownCueCount: number;\n _dashTextIsTtml: boolean;\n _pendingTimeouts: ReturnType<typeof setTimeout>[];\n _ttmlDiv: HTMLElement | null;\n _manifestUrl: string | null;\n\n constructor(player: Player) {\n this.player = player;\n this.media = player.element;\n this.dash = null;\n this._dashSourceLoaded = false;\n this._pendingSrc = null;\n this._dashSubtitleTracksCount = undefined;\n this._dashTextTracks = [];\n this._cueUpdateTimer = null;\n this._captionEnabledHandler = null;\n this._captionDisabledHandler = null;\n this._lastKnownCueCount = 0;\n this._dashTextIsTtml = false;\n this._pendingTimeouts = [];\n this._ttmlDiv = null;\n this._manifestUrl = null;\n }\n\n async init() {\n this.player.log('Using dash.js for DASH support');\n await this.initDashJs();\n }\n\n async initDashJs() {\n this.media.controls = false;\n this.media.removeAttribute('controls');\n\n if (!window.dashjs) {\n await this.loadDashJs();\n }\n\n // Remove <source> children — dash.js manages the src via MSE\n const sourceElements = Array.from(this.media.querySelectorAll('source'));\n let originalSrc = null;\n if (sourceElements.length > 0) {\n originalSrc = sourceElements[0].getAttribute('src');\n sourceElements.forEach(source => source.remove());\n this.player.log('Removed <source> elements for HTML5 validity (dash.js uses MSE)');\n }\n\n const dashjs = window.dashjs;\n if (!dashjs) {\n throw new Error('dash.js not available');\n }\n this.dash = dashjs.MediaPlayer().create();\n\n this.dash.updateSettings({\n debug: {\n logLevel: this.player.options.debug ? 4 : 0\n },\n streaming: {\n // Override dash.js default of 'lowestStartupDelay'. For audio\n // AdaptationSets that tie on selectionPriority and role=main (e.g.\n // Axinom's three en/en-low/en-high tracks), 'lowestStartupDelay'\n // falls through to 'highestEfficiency' which, for audio, has no\n // meaningful pixels-per-bit metric and collapses to \"highest\n // bitrate\". 'firstTrack' respects manifest order instead, which is\n // both predictable and closer to the MPD author's intent.\n selectionModeForInitialTrack: 'firstTrack',\n // NOTE on pre-play preload: we deliberately do NOT set\n // streaming.scheduling.scheduleWhilePaused = false here. While that\n // is the documented dash.js way to suppress segment downloads while\n // paused / before the first play, in our setup (dash.js 5.1.1 +\n // dash.initialize(media, null, false) + attachSource at init) it\n // tears down the SourceBuffers mid-init with\n // \"SourceBuffer has been removed from the parent media source\"\n // exceptions, which leaves the player unable to seek or play. The\n // PR #3785 fix that was supposed to handle the initial-playback /\n // autoPlay=false case is fragile against our usage pattern.\n // Instead we keep dash.js's default scheduling (scheduleWhilePaused\n // stays at its default `true`) and let the buffer caps below limit\n // how much is fetched before play. With a single ~6s segment size,\n // the visible network preload is one init segment per track plus\n // 1–2 media segments — the same \"first two chunks\" behavior the\n // user previously confirmed as acceptable for DASH.\n buffer: {\n bufferTimeAtTopQuality: 30,\n bufferTimeAtTopQualityLongForm: 60,\n // dash.js 5.x: use bufferTimeDefault (replaces removed stableBufferTime).\n // Keep at 12s — going lower (0 / 1) was tested but dash.js still\n // loads the first segment regardless because it's needed to make\n // the MediaSource playable, so the savings are negligible while\n // hurting mid-playback resilience on slow networks.\n bufferTimeDefault: 12,\n bufferToKeep: 20,\n bufferPruningInterval: 10\n },\n retryAttempts: {\n MPD: 4,\n MediaSegment: 6,\n InitializationSegment: 4,\n BitstreamSwitchingSegment: 4\n },\n retryIntervals: {\n MPD: 1000,\n MediaSegment: 1000,\n InitializationSegment: 1000,\n BitstreamSwitchingSegment: 1000\n },\n abr: {\n autoSwitchBitrate: { video: true, audio: true }\n },\n text: {\n defaultEnabled: true\n }\n }\n });\n\n // Create the TTML rendering div before initialize() so the DOM element\n // exists, but attach it to dash.js after initialize() because\n // attachTTMLRenderingDiv() requires attachView() which initialize() calls.\n this._ttmlDiv = document.createElement('div');\n this._ttmlDiv.className = 'vidply-dash-ttml';\n this._ttmlDiv.style.visibility = 'hidden';\n const wrapper = this.player.videoWrapper || this.media.parentElement;\n if (wrapper) {\n wrapper.appendChild(this._ttmlDiv);\n }\n\n this.dash.initialize(this.media, null, false);\n this.dash.attachTTMLRenderingDiv(this._ttmlDiv);\n\n // Resolve source URL\n let src = this.player.currentSource;\n\n if (!src && originalSrc) {\n src = originalSrc;\n }\n\n if (!src) {\n src = this.player.element.getAttribute('data-vidply-src');\n }\n\n if (!src) {\n const elementSrc = this.player.element.getAttribute('src') || this.player.element.src;\n if (elementSrc && !elementSrc.startsWith('blob:')) {\n src = elementSrc;\n }\n }\n\n this.player.log(`Loading DASH source: ${src}`, 'log');\n\n if (!src) {\n throw new Error('No DASH source found');\n }\n\n // Always attach the source at init so the manifest is fetched and the\n // seekbar / duration / quality list are available before the first play.\n // We deliberately don't honor `deferLoad` here: deferring attachSource\n // would leave duration unknown and seek requests unserviceable. The\n // small preload (init segments + ~1 segment of media data) that dash.js\n // does up to bufferTimeDefault is acceptable; in exchange the seekbar\n // becomes functional immediately.\n this._pendingSrc = src;\n this._manifestUrl = src;\n this.dash.attachSource(src);\n this._dashSourceLoaded = true;\n\n // Force the vidply poster overlay even though dash.js will paint the\n // first decoded frame into the <video> element. With MSE attached and\n // init/startup segments appended, the browser ignores the native\n // `poster` attribute and shows the first frame instead. We instead use\n // the `vidply-forced-poster` CSS class, which sets `<video>` to\n // opacity:0 and renders the poster image as a wrapper background — the\n // user sees the artwork until they press play, just like on a fully\n // native HTML5 video. The 'play' handler in Player.ts already calls\n // hidePosterOverlay() on first playback, so we don't need to remove it\n // manually here.\n this.player.showPosterOverlay();\n\n this.attachDashEvents();\n this.attachMediaEvents();\n this._setupCaptionSync();\n }\n\n /**\n * Load dash.js. Pinned to an exact version (the previous default\n * `5.1.1` is preserved) and overridable via `options.dashScriptUrl`\n * (URL) / `options.dashScriptIntegrity` (SRI hash). See\n * HLSRenderer.loadHlsJs() for the SRI computation command.\n */\n async loadDashJs(): Promise<void> {\n const defaultUrl = 'https://cdn.jsdelivr.net/npm/dashjs@5.1.1/dist/modern/umd/dash.all.min.js';\n const url: string = (this.player.options.dashScriptUrl as string | undefined) || defaultUrl;\n const integrity = this.player.options.dashScriptIntegrity as string | undefined;\n\n return new Promise<void>((resolve, reject) => {\n const script = document.createElement('script');\n script.src = url;\n if (integrity) {\n script.integrity = integrity;\n script.crossOrigin = 'anonymous';\n script.referrerPolicy = 'no-referrer';\n }\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load dash.js'));\n document.head.appendChild(script);\n });\n }\n\n _setTimeout(fn: () => void, delay: number) {\n const id = setTimeout(() => {\n this._pendingTimeouts = this._pendingTimeouts.filter(t => t !== id);\n fn();\n }, delay);\n this._pendingTimeouts.push(id);\n return id;\n }\n\n attachDashEvents() {\n const dashjs = window.dashjs;\n const dash = this.dash;\n if (!dashjs || !dash) return;\n const dashEvents = dashjs.MediaPlayer.events;\n\n dash.on(dashEvents.MANIFEST_LOADED, (...args: unknown[]) => {\n const e = args[0] as { data?: unknown } | undefined;\n const data = e?.data ?? e;\n this.player.log('DASH manifest loaded');\n this.player.emit('dashmanifestloaded', data);\n\n if (this.player.container) {\n this.player.container.classList.remove('vidply-external-controls');\n }\n\n this._setTimeout(() => {\n this._checkSubtitleTracks();\n }, 500);\n });\n\n dash.on(dashEvents.QUALITY_CHANGE_RENDERED, (...args: unknown[]) => {\n const e = args[0] as { mediaType?: string; newQuality?: number };\n if (e.mediaType === 'video') {\n this.player.log('DASH quality changed to index ' + e.newQuality);\n this.player.emit('dashqualitychanged', e);\n }\n });\n\n dash.on(dashEvents.TEXT_TRACKS_ADDED, (...args: unknown[]) => {\n const e = args[0] as { tracks?: DashTextTrack[] } | undefined;\n const tracks = e?.tracks ?? [];\n this._dashTextTracks = tracks;\n this._dashTextIsTtml = tracks.some((t) =>\n t.isTTML || /stpp|ttml/i.test(t.codec || '') || /ttml/i.test(t.mimeType || '')\n );\n this.player.log(`DASH text tracks added: ${tracks.length} tracks, format: ${this._dashTextIsTtml ? 'TTML' : 'WebVTT'}`);\n this._dashSubtitleTracksCount = tracks.length;\n this.player.emit('dashsubtitletracksupdated', { tracks });\n this.updateCaptionButtonsForDash();\n\n if (tracks.length > 0) {\n try {\n dash.setTextTrack(0);\n } catch {\n // ignore if not ready yet\n }\n if (!this._dashTextIsTtml) {\n this._startCueUpdatePolling();\n }\n }\n });\n\n dash.on(dashEvents.STREAM_INITIALIZED, () => {\n this.player.log('DASH stream initialized');\n this.player.emit('dashstreaminitialized');\n\n this._setTimeout(() => {\n const qualities = this.getQualities();\n if (qualities.length > 0) {\n this.player.emit('dashmanifestparsed', { qualities });\n }\n }, 300);\n });\n\n dash.on(dashEvents.ERROR, (...args: unknown[]) => {\n this.handleDashError(args[0]);\n });\n\n dash.on(dashEvents.FRAGMENT_LOADING_COMPLETED, (...args: unknown[]) => {\n const e = args[0] as { request?: { mediaType?: string } } | undefined;\n this.player.state.buffering = false;\n if (e?.request?.mediaType === 'text' && !this._dashTextIsTtml) {\n this._setTimeout(() => {\n const count = this._getTotalCueCount();\n if (count > this._lastKnownCueCount) {\n this._lastKnownCueCount = count;\n this.player.emit('textcuesupdate');\n }\n }, 100);\n }\n });\n }\n\n /**\n * Count total cues across all subtitle/caption tracks (for WebVTT DASH).\n */\n _getTotalCueCount() {\n const textTracks = this.media.textTracks;\n let total = 0;\n if (!textTracks) return total;\n for (let i = 0; i < textTracks.length; i++) {\n const track = textTracks[i];\n if ((track.kind === 'subtitles' || track.kind === 'captions') && !track._vidplyStale && track.cues) {\n total += track.cues.length;\n }\n }\n return total;\n }\n\n /**\n * Return true if `time` falls inside any TimeRange the SourceBuffer already\n * holds, with a small tolerance to absorb GOP boundaries. Used by the\n * seeking handler to decide whether to surface a 'waiting' event for the\n * spinner UI when the user scrubs while paused.\n */\n _isTimeBuffered(time: number): boolean {\n const buffered = this.media.buffered;\n if (!buffered || buffered.length === 0) return false;\n const tolerance = 0.25;\n for (let i = 0; i < buffered.length; i++) {\n if (time >= buffered.start(i) - tolerance && time <= buffered.end(i) + tolerance) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Sync VidPly caption track switches with dash.js so it loads\n * subtitle segments for the selected language.\n */\n _setupCaptionSync() {\n this._captionEnabledHandler = (selectedTrack) => {\n if (this._dashTextIsTtml) {\n // dash.js only renders TTML content to the rendering div when the\n // TextTrack mode is 'showing'. CaptionManager sets it to 'hidden',\n // so we override it here. VidPly's own caption overlay is skipped\n // via handlesOwnCaptions().\n if (selectedTrack.track) {\n selectedTrack.track.mode = 'showing';\n }\n if (this._ttmlDiv) {\n this._ttmlDiv.style.visibility = 'visible';\n }\n }\n this._syncDashTextTrack(selectedTrack);\n };\n this._captionDisabledHandler = () => {\n if (this._dashTextIsTtml && this._ttmlDiv) {\n this._ttmlDiv.style.visibility = 'hidden';\n }\n if (this.dash) {\n try { this.dash.setTextTrack(-1); } catch { /* ignore */ }\n }\n };\n this.player.on('captionsenabled', this._captionEnabledHandler);\n this.player.on('captionsdisabled', this._captionDisabledHandler);\n }\n\n /**\n * Map a VidPly caption track to the corresponding dash.js track index\n * and switch dash.js to load segments for that language.\n */\n _syncDashTextTrack(selectedTrack: CaptionTrackSelection) {\n if (!this.dash || !this._dashTextTracks.length) return;\n\n const lang = selectedTrack.language;\n if (!lang) return;\n\n const dashIndex = this._dashTextTracks.findIndex(dt => {\n const dtLang = dt.lang || dt.language || dt.srclang || '';\n if (!dtLang) return false;\n return dtLang === lang || dtLang.startsWith(lang) || lang.startsWith(dtLang);\n });\n\n if (dashIndex >= 0) {\n this.player.log(`Syncing DASH text track to index ${dashIndex} (${lang})`);\n try {\n this.dash.setTextTrack(dashIndex);\n } catch { /* ignore */ }\n if (!this._dashTextIsTtml) {\n this._lastKnownCueCount = 0;\n this._startCueUpdatePolling();\n }\n }\n }\n\n /**\n * Poll for new WebVTT cues being added by dash.js as subtitle segments load.\n * Emits events for transcript refresh when new cues arrive.\n */\n _startCueUpdatePolling() {\n this._stopCueUpdatePolling();\n let prevCueCount = 0;\n let stableRounds = 0;\n\n this._cueUpdateTimer = setInterval(() => {\n const count = this._getTotalCueCount();\n\n if (count > prevCueCount) {\n prevCueCount = count;\n stableRounds = 0;\n this.player.emit('textcuesupdate');\n } else {\n stableRounds++;\n if (stableRounds >= 8) {\n this._stopCueUpdatePolling();\n if (count > 0) {\n this.player.emit('textcuesupdate');\n }\n }\n }\n }, 500);\n }\n\n _stopCueUpdatePolling() {\n if (this._cueUpdateTimer) {\n clearInterval(this._cueUpdateTimer);\n this._cueUpdateTimer = null;\n }\n }\n\n _checkSubtitleTracks() {\n if (this._dashSubtitleTracksCount !== undefined && this._dashSubtitleTracksCount > 0) {\n return;\n }\n const tracks = this.media.textTracks;\n let count = 0;\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n if ((track.kind === 'subtitles' || track.kind === 'captions') && !track._vidplyStale) {\n count++;\n }\n }\n this._dashSubtitleTracksCount = count;\n this.updateCaptionButtonsForDash();\n }\n\n updateCaptionButtonsForDash(retryCount = 0) {\n const tracksCount = this._dashSubtitleTracksCount || 0;\n\n const doUpdate = () => {\n this.player.invalidateTrackCache();\n\n if (tracksCount > 0) {\n if (this.player.captionManager) {\n const found = this.player.captionManager.refreshTracks();\n\n // dash.js fires TEXT_TRACKS_ADDED when it knows about the\n // tracks, but the browser TextTrackList may not yet enumerate\n // the new TextTrack objects synchronously. If refreshTracks\n // found nothing, retry a few times with increasing delays.\n if (found === 0 && retryCount < 5) {\n const delay = (retryCount + 1) * 200;\n this.player.log(`DASH caption tracks not yet on video element, retrying in ${delay}ms (attempt ${retryCount + 1})`, 'info');\n this._setTimeout(() => {\n this.updateCaptionButtonsForDash(retryCount + 1);\n }, delay);\n return;\n }\n }\n\n if (!this._dashTextIsTtml && this.player.transcriptManager?.isVisible) {\n this.player.transcriptManager.loadTranscriptData();\n this.player.transcriptManager.updateLanguageSelector();\n }\n\n if (this.player.controlBar) {\n this.player.controlBar.ensureCaptionsButton();\n if (!this._dashTextIsTtml) {\n this.player.controlBar.ensureCaptionStyleButton();\n this.player.controlBar.ensureTranscriptButton();\n }\n }\n } else {\n if (this.player.captionManager) {\n this.player.captionManager.refreshTracks();\n }\n\n if (this.player.transcriptManager?.isVisible) {\n this.player.transcriptManager.hideTranscript();\n }\n\n if (this.player.controlBar) {\n this.player.controlBar.removeHlsCaptionButtons(true);\n }\n }\n };\n\n if (this.player.controlBar) {\n doUpdate();\n return;\n }\n\n const onReady = () => {\n this.player.off('ready', onReady);\n doUpdate();\n };\n this.player.on('ready', onReady);\n }\n\n attachMediaEvents() {\n this.media.addEventListener('loadedmetadata', () => {\n this.player.state.duration = this.media.duration;\n this.player.emit('loadedmetadata');\n });\n\n this.media.addEventListener('durationchange', () => {\n const duration = this.media.duration;\n if (duration && isFinite(duration) && duration > 0) {\n this.player.state.duration = duration;\n this.player.emit('durationchange', duration);\n }\n });\n\n this.media.addEventListener('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n\n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n });\n\n this.media.addEventListener('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n\n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.media.addEventListener('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n\n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n\n if (this.player.options.loop) {\n this.player.seek(0);\n this.player.play();\n }\n });\n\n this.media.addEventListener('timeupdate', () => {\n this.player.state.currentTime = this.media.currentTime;\n this.player.emit('timeupdate', this.media.currentTime);\n\n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\n }\n });\n\n this.media.addEventListener('volumechange', () => {\n this.player.state.volume = this.media.volume;\n this.player.state.muted = this.media.muted;\n this.player.emit('volumechange', this.media.volume);\n });\n\n this.media.addEventListener('seeking', () => {\n this.player.state.seeking = true;\n this.player.emit('seeking');\n\n // Browsers do not fire `waiting` when seeking on a paused media element\n // — there is nothing to \"wait\" for since playback isn't requested. With\n // dash.js + MSE, scrubbing while paused (or before the first play)\n // still triggers a real fragment download, but the spinner stays hidden\n // because no `waiting` event reaches the buffering UI. Detect a seek\n // into an unbuffered range here and surface it as 'waiting' so the\n // spinner appears. Cleared again by the existing `canplay` /\n // `seeked` paths.\n if (!this._isTimeBuffered(this.media.currentTime)) {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n }\n });\n\n this.media.addEventListener('seeked', () => {\n this.player.state.seeking = false;\n this.player.emit('seeked');\n });\n\n this.media.addEventListener('waiting', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.media.addEventListener('canplay', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.media.addEventListener('error', () => {\n this.player.handleError(this.media.error);\n });\n }\n\n handleDashError(e: unknown) {\n const wrapped = e as { error?: { code?: number; message?: string }; code?: number; message?: string } | undefined;\n const error = wrapped?.error ?? wrapped;\n if (!error) return;\n const code = error.code ?? '';\n const message = error.message || '';\n this.player.log(`DASH Error - Code: ${code}, Message: ${message}`, 'warn');\n\n if (typeof code === 'number' && code >= 100) {\n this.player.log('Fatal DASH error', 'error');\n this.player.handleError(new Error(`DASH Error: ${code} - ${message}`));\n } else {\n this.player.log('Non-fatal DASH error: ' + (message || String(error)), 'warn');\n }\n }\n\n ensureLoaded() {\n if (!this.player.options.deferLoad) {\n return;\n }\n\n if (!this.dash) {\n return;\n }\n\n if (this._dashSourceLoaded) {\n return;\n }\n\n const src = this._pendingSrc || this.player._pendingSource || this.player.currentSource;\n if (!src) {\n return;\n }\n\n try {\n this.dash.attachSource(src);\n this._dashSourceLoaded = true;\n } catch {\n // ignore\n }\n }\n\n play() {\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n\n // Defer-load (legacy code path, kept for completeness): the source is\n // normally attached at init and dash.js is configured with\n // scheduling.scheduleWhilePaused: false to keep prefetch at zero until\n // play. If for any reason the source is still pending here, attach it\n // now. Note that media.play() is called immediately afterwards; on\n // modern dash.js this races cleanly because attachSource() is sync\n // enough for the MediaSource to be ready by the time the play promise\n // resolves, and the configured zero-prefetch settings make the race\n // window very short. The general \"no preload\" UX no longer relies on\n // this branch.\n if (this.player.options.deferLoad && this.dash && !this._dashSourceLoaded) {\n const src = this._pendingSrc || this.player.currentSource;\n if (src) {\n try {\n this.dash.attachSource(src);\n this._dashSourceLoaded = true;\n } catch {\n // ignore and let media.play() surface errors if any\n }\n }\n }\n\n const promise = this.media.play();\n\n window.scrollTo(scrollX, scrollY);\n\n if (promise !== undefined) {\n promise.catch(error => {\n this.player.log('Play failed:', error, 'warn');\n });\n }\n }\n\n pause() {\n // dash.js stops scheduling new fragment downloads once `paused` is true,\n // because we configured `streaming.scheduling.scheduleWhilePaused: false`\n // at init. Already-buffered data stays in the SourceBuffer, so a\n // subsequent play() resumes near-instantly while pause saves bandwidth.\n this.media.pause();\n }\n\n seek(time: number) {\n this.media.currentTime = time;\n }\n\n setVolume(volume: number) {\n this.media.volume = volume;\n }\n\n setMuted(muted: boolean) {\n this.media.muted = muted;\n }\n\n setPlaybackSpeed(speed: number) {\n this.media.playbackRate = speed;\n }\n\n switchQuality(qualityIndex: number) {\n if (!this.dash) return;\n\n if (qualityIndex === -1) {\n // Re-enable ABR auto-switching\n if (typeof this.dash.setAutoSwitchQualityFor === 'function') {\n this.dash.setAutoSwitchQualityFor('video', true);\n } else {\n this.dash.updateSettings({\n streaming: { abr: { autoSwitchBitrate: { video: true } } }\n });\n }\n } else {\n // Disable ABR and lock to the chosen quality\n if (typeof this.dash.setAutoSwitchQualityFor === 'function') {\n this.dash.setAutoSwitchQualityFor('video', false);\n } else {\n this.dash.updateSettings({\n streaming: { abr: { autoSwitchBitrate: { video: false } } }\n });\n }\n\n if (typeof this.dash.setRepresentationForTypeByIndex === 'function') {\n this.dash.setRepresentationForTypeByIndex('video', qualityIndex);\n } else if (typeof this.dash.setQualityFor === 'function') {\n this.dash.setQualityFor('video', qualityIndex, true);\n }\n }\n }\n\n getQualities() {\n if (!this.dash) return [];\n\n try {\n // dash.js v5+: getRepresentationsByType\n let reps = null;\n if (typeof this.dash.getRepresentationsByType === 'function') {\n reps = this.dash.getRepresentationsByType('video');\n }\n\n if (reps && reps.length > 0) {\n const heightCounts: Record<number, number> = {};\n reps.forEach((r: DashRepresentation) => {\n const h = Number(r.height) || 0;\n heightCounts[h] = (heightCounts[h] || 0) + 1;\n });\n\n return reps.map((rep: DashRepresentation, index: number) => {\n const height = Number(rep.height) || 0;\n const bitrate = Number(rep.bandwidth || rep.bitrate) || 0;\n const kb = bitrate > 0 ? Math.round(bitrate / 1000) : 0;\n let name;\n if (height > 0 && heightCounts[height] > 1 && kb > 0) {\n name = `${height}p (${kb} kbps)`;\n } else if (height > 0) {\n name = `${height}p`;\n } else {\n name = kb > 0 ? `${kb} kbps` : 'Auto';\n }\n return {\n index,\n id: rep.id,\n height: rep.height,\n width: rep.width,\n bitrate,\n name\n };\n });\n }\n\n // Fallback: dash.js v4 and earlier\n const bitrateList = this.dash.getBitrateInfoListFor('video');\n if (!bitrateList || bitrateList.length === 0) return [];\n\n const heightCounts: Record<number, number> = {};\n bitrateList.forEach((info: DashBitrateInfo) => {\n const h = Number(info.height) || 0;\n heightCounts[h] = (heightCounts[h] || 0) + 1;\n });\n\n return bitrateList.map((info: DashBitrateInfo, index: number) => {\n const height = Number(info.height) || 0;\n const bitrate = Number(info.bitrate) || 0;\n const kb = bitrate > 0 ? Math.round(bitrate / 1000) : 0;\n let name;\n if (height > 0 && heightCounts[height] > 1 && kb > 0) {\n name = `${height}p (${kb} kbps)`;\n } else if (height > 0) {\n name = `${height}p`;\n } else {\n name = kb > 0 ? `${kb} kbps` : 'Auto';\n }\n return {\n index,\n height: info.height,\n width: info.width,\n bitrate: info.bitrate,\n name\n };\n });\n } catch {\n return [];\n }\n }\n\n getCurrentQuality() {\n if (!this.dash) return -1;\n try {\n if (typeof this.dash.getRepresentationsByType === 'function') {\n const reps = this.dash.getRepresentationsByType('video');\n const current = this.dash.getCurrentRepresentationForType?.('video');\n if (current && reps) {\n const idx = reps.findIndex((r: DashRepresentation) => r.id === current.id);\n if (idx >= 0) return idx;\n }\n }\n return this.dash.getQualityFor('video');\n } catch {\n return -1;\n }\n }\n\n handlesOwnCaptions() {\n return this._dashTextIsTtml;\n }\n\n /**\n * Tell dash.js to activate the text track for `lang` so it begins\n * downloading subtitle segments and populating cues for that language.\n */\n activateTextTrackForLanguage(lang: string): boolean {\n if (!this.dash || !this._dashTextTracks.length || !lang) return false;\n\n let dashIndex = this._dashTextTracks.findIndex(dt => {\n const dtLang = dt.lang || dt.language || dt.srclang || '';\n if (!dtLang) return false;\n return dtLang === lang || dtLang.startsWith(lang) || lang.startsWith(dtLang);\n });\n\n if (dashIndex < 0) {\n dashIndex = this._dashTextTracks.findIndex(dt => {\n const dtLabel = (dt.label || dt.labels || '').toString().toLowerCase();\n return dtLabel.includes(lang.toLowerCase());\n });\n }\n\n if (dashIndex < 0) return false;\n\n this.player.log(`Activating DASH text track index ${dashIndex} for transcript language \"${lang}\"`);\n try {\n this.dash.setTextTrack(dashIndex);\n } catch { /* ignore */ }\n\n // dash.js's text scheduler only fetches segments while the video is\n // playing. When paused, a brief play–pause cycle forces the scheduler\n // to buffer text data for the newly selected track.\n if (this.media.paused) {\n const pos = this.media.currentTime;\n const wasMuted = this.media.muted;\n this.media.muted = true;\n const playPromise = this.media.play();\n const doPause = () => {\n if (this.media && !this.media.paused) {\n this.media.pause();\n this.media.muted = wasMuted;\n // Restore position in case it drifted\n if (Math.abs(this.media.currentTime - pos) > 0.5) {\n this.media.currentTime = pos;\n }\n }\n };\n if (playPromise && typeof playPromise.then === 'function') {\n playPromise.then(() => {\n this._setTimeout(doPause, 250);\n }).catch(() => {\n this.media.muted = wasMuted;\n });\n } else {\n this._setTimeout(doPause, 250);\n }\n }\n\n if (!this._dashTextIsTtml) {\n this._lastKnownCueCount = 0;\n this._startCueUpdatePolling();\n }\n return true;\n }\n\n getTextTrackURLs(): { lang: string; url: string }[] {\n if (!this.dash || !this._manifestUrl) return [];\n try {\n // dash.js manifest objects are loosely shaped (XML-derived), so we\n // walk them through index-keyed records and narrow as we go.\n type ManifestNode = Record<string, unknown>;\n const manifest = this.dash.getManifest?.() as ManifestNode | undefined;\n if (!manifest) return [];\n\n const baseUrl = this._manifestUrl.substring(0, this._manifestUrl.lastIndexOf('/') + 1);\n const results: { lang: string; url: string }[] = [];\n\n const rawPeriods = manifest.Period || manifest.period || manifest.periods || manifest;\n const periods = (Array.isArray(rawPeriods) ? rawPeriods : [rawPeriods]) as ManifestNode[];\n for (const period of periods) {\n const rawAdaptSets = period.AdaptationSet || period.adaptationSet || period.AdaptationSet_asArray || [];\n const adaptSets = (Array.isArray(rawAdaptSets) ? rawAdaptSets : [rawAdaptSets]) as ManifestNode[];\n for (const as of adaptSets) {\n const ct = String(as.contentType || as.ContentType || '');\n const mime = String(as.mimeType || as.MimeType || '');\n if (ct !== 'text' && !/text\\/vtt|application\\/ttml/i.test(mime)) continue;\n\n const lang = String(as.lang || as.language || '');\n const rawReps = as.Representation || as.representation || as.Representation_asArray || [];\n const reps = (Array.isArray(rawReps) ? rawReps : [rawReps]) as ManifestNode[];\n for (const rep of reps) {\n const bu = (rep.BaseURL || rep.baseURL || rep.BaseURL_asArray) as\n | string\n | { __text?: string }\n | Array<string | { __text?: string }>\n | undefined;\n let rawUrl: string | undefined;\n if (Array.isArray(bu)) {\n const first = bu[0];\n rawUrl = typeof first === 'string' ? first : first?.__text;\n } else if (typeof bu === 'string') {\n rawUrl = bu;\n } else {\n rawUrl = bu?.__text;\n }\n if (!rawUrl) continue;\n const url = rawUrl.startsWith('http') ? rawUrl : new URL(rawUrl, baseUrl).href;\n results.push({ lang, url });\n break;\n }\n }\n }\n return results;\n } catch {\n return [];\n }\n }\n\n supportsAutoQuality() {\n return true;\n }\n\n isAutoQuality() {\n if (!this.dash) return true;\n try {\n if (typeof this.dash.getAutoSwitchQualityFor === 'function') {\n return this.dash.getAutoSwitchQualityFor('video');\n }\n const settings = this.dash.getSettings?.();\n return settings?.streaming?.abr?.autoSwitchBitrate?.video !== false;\n } catch {\n return true;\n }\n }\n\n destroy() {\n this._pendingTimeouts.forEach(id => clearTimeout(id));\n this._pendingTimeouts = [];\n this._stopCueUpdatePolling();\n this._lastKnownCueCount = 0;\n\n if (this._captionEnabledHandler) {\n this.player.off('captionsenabled', this._captionEnabledHandler);\n this._captionEnabledHandler = null;\n }\n if (this._captionDisabledHandler) {\n this.player.off('captionsdisabled', this._captionDisabledHandler);\n this._captionDisabledHandler = null;\n }\n\n if (this._ttmlDiv && this._ttmlDiv.parentNode) {\n this._ttmlDiv.parentNode.removeChild(this._ttmlDiv);\n this._ttmlDiv = null;\n }\n\n // Mark all subtitle/caption text tracks as stale. dash.js creates\n // programmatic TextTrack objects that persist on the <video> element\n // after destroy() and cannot be removed via standard APIs. The stale\n // flag prevents _checkSubtitleTracks() in a new renderer instance from\n // treating them as tracks belonging to the current stream.\n const textTracks = this.media.textTracks;\n for (let i = 0; i < textTracks.length; i++) {\n const track = textTracks[i];\n if (track.kind === 'subtitles' || track.kind === 'captions') {\n track._vidplyStale = true;\n track.mode = 'disabled';\n }\n }\n\n if (this.dash) {\n try {\n // Silence dash.js logging during teardown to suppress harmless\n // SourceBuffer errors from in-flight async operations.\n this.dash.updateSettings({ debug: { logLevel: 0 } });\n // reset() cleanly detaches from MediaSource and cancels pending\n // buffer operations before destroy() releases all resources.\n this.dash.reset();\n } catch { /* ignore teardown errors */ }\n try {\n this.dash.destroy();\n } catch { /* ignore teardown errors */ }\n this.dash = null;\n }\n this._dashTextTracks = [];\n this._dashTextIsTtml = false;\n this._manifestUrl = null;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["heightCounts"]
7
+ }