@gcorevideo/player 2.19.15 → 2.20.3

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 (338) hide show
  1. package/assets/level-selector/list.ejs +1 -1
  2. package/dist/core.js +2 -2
  3. package/dist/index.css +966 -966
  4. package/dist/index.js +884 -627
  5. package/dist/player.d.ts +536 -122
  6. package/dist/plugins/index.css +1160 -1160
  7. package/dist/plugins/index.js +2006 -1725
  8. package/docs/api/player.audioselector.md +1 -251
  9. package/docs/api/player.bigmutebutton.md +1 -156
  10. package/docs/api/player.clapprnerdstats.md +12 -259
  11. package/docs/api/player.clapprstats.exportmetrics.md +4 -0
  12. package/docs/api/player.clapprstats.md +7 -223
  13. package/docs/api/player.clapprstats.setupdatemetrics.md +2 -0
  14. package/docs/api/player.clicktopause.md +5 -113
  15. package/docs/api/player.clipsplugin.gettext.md +9 -0
  16. package/docs/api/player.clipsplugin.md +10 -94
  17. package/docs/api/{player.playbackrate.setselectedrate.md → player.clipspluginsettings.md} +18 -10
  18. package/docs/api/player.clipspluginsettings.text.md +13 -0
  19. package/docs/api/player.contextmenu._constructor_.md +6 -3
  20. package/docs/api/player.contextmenu.md +13 -256
  21. package/docs/api/player.contextmenupluginsettings.label.md +11 -0
  22. package/docs/api/player.contextmenupluginsettings.md +93 -0
  23. package/docs/api/player.contextmenupluginsettings.preventshowcontextmenu.md +11 -0
  24. package/docs/api/player.contextmenupluginsettings.url.md +11 -0
  25. package/docs/api/player.dvrcontrols.md +5 -1
  26. package/docs/api/player.errorscreen.attributes.md +3 -0
  27. package/docs/api/player.errorscreen.bindevents.md +3 -0
  28. package/docs/api/player.errorscreen.container.md +3 -0
  29. package/docs/api/player.errorscreen.hide.md +3 -0
  30. package/docs/api/player.errorscreen.md +25 -0
  31. package/docs/api/player.errorscreen.name.md +3 -0
  32. package/docs/api/player.errorscreen.render.md +3 -0
  33. package/docs/api/player.errorscreen.show.md +3 -0
  34. package/docs/api/player.errorscreen.supportedversion.md +3 -0
  35. package/docs/api/player.errorscreen.template.md +3 -0
  36. package/docs/api/player.errorscreen.unbindevents.md +3 -0
  37. package/docs/api/player.favicon._constructor_.md +3 -0
  38. package/docs/api/player.favicon.bindevents.md +3 -0
  39. package/docs/api/player.favicon.configure.md +3 -0
  40. package/docs/api/player.favicon.destroy.md +3 -0
  41. package/docs/api/player.favicon.disable.md +3 -0
  42. package/docs/api/player.favicon.md +18 -1
  43. package/docs/api/player.favicon.name.md +3 -0
  44. package/docs/api/player.favicon.supportedversion.md +3 -0
  45. package/docs/api/player.gearevents.md +4 -1
  46. package/docs/api/player.googleanalytics._constructor_.md +3 -0
  47. package/docs/api/player.googleanalytics.addeventlisteners.md +3 -0
  48. package/docs/api/player.googleanalytics.embedscript.md +3 -0
  49. package/docs/api/player.googleanalytics.md +42 -1
  50. package/docs/api/player.googleanalytics.name.md +3 -0
  51. package/docs/api/player.googleanalytics.onbufferfull.md +3 -0
  52. package/docs/api/player.googleanalytics.onbuffering.md +3 -0
  53. package/docs/api/player.googleanalytics.ondvr.md +3 -0
  54. package/docs/api/player.googleanalytics.onended.md +3 -0
  55. package/docs/api/player.googleanalytics.onerror.md +3 -0
  56. package/docs/api/player.googleanalytics.onfullscreen.md +3 -0
  57. package/docs/api/player.googleanalytics.onhd.md +3 -0
  58. package/docs/api/player.googleanalytics.onpause.md +3 -0
  59. package/docs/api/player.googleanalytics.onplay.md +3 -0
  60. package/docs/api/player.googleanalytics.onready.md +3 -0
  61. package/docs/api/player.googleanalytics.onseek.md +3 -0
  62. package/docs/api/player.googleanalytics.onstop.md +3 -0
  63. package/docs/api/player.googleanalytics.onvolumechanged.md +3 -0
  64. package/docs/api/player.googleanalytics.push.md +3 -0
  65. package/docs/api/player.googleanalytics.supportedversion.md +3 -0
  66. package/docs/api/{player.clapprstats.name.md → player.initeventdata.event.md} +3 -3
  67. package/docs/api/player.initeventdata.md +60 -0
  68. package/docs/api/player.logo._constructor_.md +3 -0
  69. package/docs/api/player.logo.attributes.md +3 -0
  70. package/docs/api/player.logo.bindevents.md +3 -0
  71. package/docs/api/player.logo.md +20 -1
  72. package/docs/api/player.logo.name.md +3 -0
  73. package/docs/api/player.logo.render.md +3 -0
  74. package/docs/api/player.logo.stoplistening.md +3 -0
  75. package/docs/api/player.logo.supportedversion.md +3 -0
  76. package/docs/api/player.logo.template.md +3 -0
  77. package/docs/api/player.md +149 -18
  78. package/docs/api/player.mediacontrolelement.md +1 -1
  79. package/docs/api/player.multicamera.md +2 -0
  80. package/docs/api/player.pictureinpicture.md +9 -197
  81. package/docs/api/player.playbackrate.md +10 -314
  82. package/docs/api/player.seektime.attributes.md +3 -0
  83. package/docs/api/player.seektime.bindevents.md +3 -0
  84. package/docs/api/player.seektime.durationshown.md +3 -0
  85. package/docs/api/player.seektime.getseektime.md +3 -0
  86. package/docs/api/player.seektime.islivestreamwithdvr.md +3 -0
  87. package/docs/api/player.seektime.md +31 -0
  88. package/docs/api/player.seektime.mediacontrol.md +3 -0
  89. package/docs/api/player.seektime.mediacontrolcontainer.md +3 -0
  90. package/docs/api/player.seektime.name.md +3 -0
  91. package/docs/api/player.seektime.render.md +3 -0
  92. package/docs/api/player.seektime.shouldbevisible.md +3 -0
  93. package/docs/api/player.seektime.supportedversion.md +3 -0
  94. package/docs/api/player.seektime.template.md +3 -0
  95. package/docs/api/player.seektime.update.md +3 -0
  96. package/docs/api/player.share.md +2 -0
  97. package/docs/api/player.skiptime.md +2 -0
  98. package/docs/api/{player.clapprstats.destroy.md → player.stalleventdata.count.md} +5 -7
  99. package/docs/api/{player.bigmutebutton.template.md → player.stalleventdata.event.md} +3 -3
  100. package/docs/api/player.stalleventdata.md +117 -0
  101. package/docs/api/{player.audioselector.onshowlevelselectmenu.md → player.stalleventdata.time.md} +5 -7
  102. package/docs/api/{player.clapprstats.starttimers.md → player.stalleventdata.total_ms.md} +5 -7
  103. package/docs/api/{player.audioselector.template.md → player.starteventdata.event.md} +3 -3
  104. package/docs/api/player.starteventdata.md +60 -0
  105. package/docs/api/{player.clapprstats._defaultreport.md → player.telemetry._constructor_.md} +7 -9
  106. package/docs/api/player.telemetry.md +146 -0
  107. package/docs/api/{player.clapprnerdstats.name.md → player.telemetry.name.md} +4 -2
  108. package/docs/api/{player.clapprstats.supportedversion.md → player.telemetry.supportedversion.md} +4 -2
  109. package/docs/api/player.telemetryevent.md +100 -0
  110. package/docs/api/player.telemetryeventdata.md +18 -0
  111. package/docs/api/player.telemetrypluginsettings.md +60 -0
  112. package/docs/api/{player.audioselector.bindevents.md → player.telemetrypluginsettings.send.md} +5 -7
  113. package/docs/api/{player.audioselector.reload.md → player.telemetryrecord.md} +8 -6
  114. package/docs/api/player.thumbnails.md +21 -139
  115. package/docs/api/player.thumbnailspluginsettings.md +23 -0
  116. package/docs/api/player.volumefade.md +1 -93
  117. package/docs/api/{player.audioselector.name.md → player.watcheventdata.event.md} +3 -3
  118. package/docs/api/player.watcheventdata.md +60 -0
  119. package/lib/index.plugins.d.ts +2 -3
  120. package/lib/index.plugins.d.ts.map +1 -1
  121. package/lib/index.plugins.js +2 -3
  122. package/lib/playback/hls-playback/HlsPlayback.js +1 -1
  123. package/lib/plugins/audio-selector/AudioSelector.d.ts +28 -6
  124. package/lib/plugins/audio-selector/AudioSelector.d.ts.map +1 -1
  125. package/lib/plugins/audio-selector/AudioSelector.js +52 -22
  126. package/lib/plugins/big-mute-button/BigMuteButton.d.ts +18 -2
  127. package/lib/plugins/big-mute-button/BigMuteButton.d.ts.map +1 -1
  128. package/lib/plugins/big-mute-button/BigMuteButton.js +21 -16
  129. package/lib/plugins/bottom-gear/BottomGear.d.ts +1 -0
  130. package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
  131. package/lib/plugins/bottom-gear/BottomGear.js +1 -0
  132. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +38 -5
  133. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
  134. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +63 -17
  135. package/lib/plugins/clappr-stats/ClapprStats.d.ts +31 -8
  136. package/lib/plugins/clappr-stats/ClapprStats.d.ts.map +1 -1
  137. package/lib/plugins/clappr-stats/ClapprStats.js +24 -0
  138. package/lib/plugins/clappr-stats/types.d.ts +12 -0
  139. package/lib/plugins/clappr-stats/types.d.ts.map +1 -1
  140. package/lib/plugins/clappr-stats/types.js +3 -0
  141. package/lib/plugins/click-to-pause/ClickToPause.d.ts +13 -1
  142. package/lib/plugins/click-to-pause/ClickToPause.d.ts.map +1 -1
  143. package/lib/plugins/click-to-pause/ClickToPause.js +14 -4
  144. package/lib/plugins/clips/Clips.d.ts +34 -2
  145. package/lib/plugins/clips/Clips.d.ts.map +1 -1
  146. package/lib/plugins/clips/Clips.js +51 -22
  147. package/lib/plugins/context-menu/ContextMenu.d.ts +40 -13
  148. package/lib/plugins/context-menu/ContextMenu.d.ts.map +1 -1
  149. package/lib/plugins/context-menu/ContextMenu.js +48 -36
  150. package/lib/plugins/dvr-controls/DvrControls.d.ts +5 -4
  151. package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -1
  152. package/lib/plugins/dvr-controls/DvrControls.js +15 -29
  153. package/lib/plugins/error-screen/ErrorScreen.d.ts +4 -0
  154. package/lib/plugins/error-screen/ErrorScreen.d.ts.map +1 -1
  155. package/lib/plugins/error-screen/ErrorScreen.js +4 -0
  156. package/lib/plugins/favicon/Favicon.d.ts +4 -0
  157. package/lib/plugins/favicon/Favicon.d.ts.map +1 -1
  158. package/lib/plugins/favicon/Favicon.js +4 -0
  159. package/lib/plugins/google-analytics/GoogleAnalytics.d.ts +4 -0
  160. package/lib/plugins/google-analytics/GoogleAnalytics.d.ts.map +1 -1
  161. package/lib/plugins/google-analytics/GoogleAnalytics.js +5 -1
  162. package/lib/plugins/index.d.ts +2 -4
  163. package/lib/plugins/index.d.ts.map +1 -1
  164. package/lib/plugins/index.js +2 -4
  165. package/lib/plugins/logo/Logo.d.ts +4 -0
  166. package/lib/plugins/logo/Logo.d.ts.map +1 -1
  167. package/lib/plugins/logo/Logo.js +4 -0
  168. package/lib/plugins/media-control/MediaControl.d.ts +1 -1
  169. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  170. package/lib/plugins/media-control/MediaControl.js +3 -1
  171. package/lib/plugins/multi-camera/MultiCamera.d.ts +3 -0
  172. package/lib/plugins/multi-camera/MultiCamera.d.ts.map +1 -1
  173. package/lib/plugins/multi-camera/MultiCamera.js +3 -0
  174. package/lib/plugins/picture-in-picture/PictureInPicture.d.ts +32 -4
  175. package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -1
  176. package/lib/plugins/picture-in-picture/PictureInPicture.js +30 -2
  177. package/lib/plugins/playback-rate/PlaybackRate.d.ts +47 -14
  178. package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
  179. package/lib/plugins/playback-rate/PlaybackRate.js +38 -9
  180. package/lib/plugins/seek-time/SeekTime.d.ts +4 -0
  181. package/lib/plugins/seek-time/SeekTime.d.ts.map +1 -1
  182. package/lib/plugins/seek-time/SeekTime.js +5 -1
  183. package/lib/plugins/share/Share.d.ts +3 -0
  184. package/lib/plugins/share/Share.d.ts.map +1 -1
  185. package/lib/plugins/share/Share.js +3 -0
  186. package/lib/plugins/skip-time/SkipTime.d.ts +3 -0
  187. package/lib/plugins/skip-time/SkipTime.d.ts.map +1 -1
  188. package/lib/plugins/skip-time/SkipTime.js +3 -0
  189. package/lib/plugins/statistics/Statistics.d.ts +38 -3
  190. package/lib/plugins/statistics/Statistics.d.ts.map +1 -1
  191. package/lib/plugins/statistics/Statistics.js +51 -9
  192. package/lib/plugins/telemetry/Telemetry.d.ts +153 -0
  193. package/lib/plugins/telemetry/Telemetry.d.ts.map +1 -0
  194. package/lib/plugins/telemetry/Telemetry.js +181 -0
  195. package/lib/plugins/thumbnails/Thumbnails.d.ts +48 -3
  196. package/lib/plugins/thumbnails/Thumbnails.d.ts.map +1 -1
  197. package/lib/plugins/thumbnails/Thumbnails.js +52 -18
  198. package/lib/plugins/volume-fade/VolumeFade.d.ts +8 -1
  199. package/lib/plugins/volume-fade/VolumeFade.d.ts.map +1 -1
  200. package/lib/plugins/volume-fade/VolumeFade.js +9 -1
  201. package/package.json +1 -1
  202. package/src/index.plugins.ts +2 -3
  203. package/src/playback/hls-playback/HlsPlayback.ts +1 -1
  204. package/src/plugins/audio-selector/AudioSelector.ts +227 -154
  205. package/src/plugins/big-mute-button/BigMuteButton.ts +100 -79
  206. package/src/plugins/bottom-gear/BottomGear.ts +1 -0
  207. package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +240 -173
  208. package/src/plugins/clappr-stats/ClapprStats.ts +32 -8
  209. package/src/plugins/clappr-stats/types.ts +13 -0
  210. package/src/plugins/click-to-pause/ClickToPause.ts +47 -36
  211. package/src/plugins/clips/Clips.ts +127 -71
  212. package/src/plugins/context-menu/ContextMenu.ts +105 -76
  213. package/src/plugins/dvr-controls/DvrControls.ts +15 -31
  214. package/src/plugins/error-screen/ErrorScreen.ts +4 -0
  215. package/src/plugins/favicon/Favicon.ts +4 -0
  216. package/src/plugins/google-analytics/GoogleAnalytics.ts +5 -1
  217. package/src/plugins/index.ts +2 -4
  218. package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +47 -26
  219. package/src/plugins/level-selector/__tests__/__snapshots__/LevelSelector.test.ts.snap +18 -18
  220. package/src/plugins/logo/Logo.ts +4 -0
  221. package/src/plugins/media-control/MediaControl.ts +4 -1
  222. package/src/plugins/multi-camera/MultiCamera.ts +3 -0
  223. package/src/plugins/picture-in-picture/PictureInPicture.ts +35 -7
  224. package/src/plugins/playback-rate/PlaybackRate.ts +53 -24
  225. package/src/plugins/seek-time/SeekTime.ts +5 -1
  226. package/src/plugins/share/Share.ts +3 -0
  227. package/src/plugins/skip-time/SkipTime.ts +3 -0
  228. package/src/plugins/telemetry/Telemetry.ts +317 -0
  229. package/src/plugins/thumbnails/Thumbnails.ts +268 -194
  230. package/src/plugins/volume-fade/VolumeFade.ts +10 -2
  231. package/temp/player.api.json +2457 -5257
  232. package/tsconfig.tsbuildinfo +1 -1
  233. package/docs/api/player.audioselector.attributes.md +0 -17
  234. package/docs/api/player.audioselector.events.md +0 -17
  235. package/docs/api/player.audioselector.hideselecttrackmenu.md +0 -18
  236. package/docs/api/player.audioselector.render.md +0 -18
  237. package/docs/api/player.audioselector.supportedversion.md +0 -16
  238. package/docs/api/player.audioselector.togglecontextmenu.md +0 -18
  239. package/docs/api/player.audioselector.unbindevents.md +0 -18
  240. package/docs/api/player.audioselector.version.md +0 -14
  241. package/docs/api/player.bigmutebutton.bindevents.md +0 -18
  242. package/docs/api/player.bigmutebutton.events.md +0 -17
  243. package/docs/api/player.bigmutebutton.name.md +0 -14
  244. package/docs/api/player.bigmutebutton.render.md +0 -18
  245. package/docs/api/player.bigmutebutton.supportedversion.md +0 -16
  246. package/docs/api/player.clapprnerdstats.attributes.md +0 -17
  247. package/docs/api/player.clapprnerdstats.bindevents.md +0 -18
  248. package/docs/api/player.clapprnerdstats.events.md +0 -18
  249. package/docs/api/player.clapprnerdstats.playerheight.md +0 -14
  250. package/docs/api/player.clapprnerdstats.playerwidth.md +0 -14
  251. package/docs/api/player.clapprnerdstats.render.md +0 -18
  252. package/docs/api/player.clapprnerdstats.statsboxelem.md +0 -14
  253. package/docs/api/player.clapprnerdstats.statsboxwidththreshold.md +0 -14
  254. package/docs/api/player.clapprnerdstats.supportedversion.md +0 -16
  255. package/docs/api/player.clapprnerdstats.template.md +0 -14
  256. package/docs/api/player.clapprstats._buildreport.md +0 -18
  257. package/docs/api/player.clapprstats._playbackname.md +0 -14
  258. package/docs/api/player.clapprstats._playbacktype.md +0 -14
  259. package/docs/api/player.clapprstats.bindevents.md +0 -18
  260. package/docs/api/player.clapprstats.onfirstplaying.md +0 -18
  261. package/docs/api/player.clapprstats.playafterpause.md +0 -18
  262. package/docs/api/player.clapprstats.stopreporting.md +0 -18
  263. package/docs/api/player.clicktopause.bindevents.md +0 -15
  264. package/docs/api/player.clicktopause.config.md +0 -11
  265. package/docs/api/player.clicktopause.name.md +0 -11
  266. package/docs/api/player.clicktopause.supportedversion.md +0 -13
  267. package/docs/api/player.clipsplugin.attributes.md +0 -13
  268. package/docs/api/player.clipsplugin.bindevents.md +0 -15
  269. package/docs/api/player.clipsplugin.makesvg.md +0 -49
  270. package/docs/api/player.clipsplugin.name.md +0 -11
  271. package/docs/api/player.clipsplugin.unbindevents.md +0 -15
  272. package/docs/api/player.contextmenu.attributes.md +0 -13
  273. package/docs/api/player.contextmenu.bindevents.md +0 -15
  274. package/docs/api/player.contextmenu.destroy.md +0 -15
  275. package/docs/api/player.contextmenu.events.md +0 -13
  276. package/docs/api/player.contextmenu.exposeversion.md +0 -14
  277. package/docs/api/player.contextmenu.label.md +0 -11
  278. package/docs/api/player.contextmenu.mediacontrol.md +0 -11
  279. package/docs/api/player.contextmenu.name.md +0 -11
  280. package/docs/api/player.contextmenu.render.md +0 -15
  281. package/docs/api/player.contextmenu.supportedversion.md +0 -13
  282. package/docs/api/player.contextmenu.template.md +0 -11
  283. package/docs/api/player.contextmenu.url.md +0 -11
  284. package/docs/api/player.disablecontrols.bindevents.md +0 -15
  285. package/docs/api/player.disablecontrols.container.md +0 -11
  286. package/docs/api/player.disablecontrols.md +0 -138
  287. package/docs/api/player.disablecontrols.name.md +0 -11
  288. package/docs/api/player.disablecontrols.supportedversion.md +0 -13
  289. package/docs/api/player.disablecontrols.unbindevents.md +0 -15
  290. package/docs/api/player.pictureinpicture.bindevents.md +0 -15
  291. package/docs/api/player.pictureinpicture.events.md +0 -13
  292. package/docs/api/player.pictureinpicture.exitpictureinpicture.md +0 -15
  293. package/docs/api/player.pictureinpicture.name.md +0 -11
  294. package/docs/api/player.pictureinpicture.render.md +0 -15
  295. package/docs/api/player.pictureinpicture.requestpictureinpicture.md +0 -15
  296. package/docs/api/player.pictureinpicture.supportedversion.md +0 -13
  297. package/docs/api/player.pictureinpicture.togglepictureinpicture.md +0 -15
  298. package/docs/api/player.pictureinpicture.version.md +0 -11
  299. package/docs/api/player.pictureinpicture.videoelement.md +0 -11
  300. package/docs/api/player.playbackrate.attributes.md +0 -14
  301. package/docs/api/player.playbackrate.bindevents.md +0 -15
  302. package/docs/api/player.playbackrate.events.md +0 -15
  303. package/docs/api/player.playbackrate.gettitle.md +0 -15
  304. package/docs/api/player.playbackrate.goback.md +0 -15
  305. package/docs/api/player.playbackrate.highlightcurrentrate.md +0 -15
  306. package/docs/api/player.playbackrate.name.md +0 -11
  307. package/docs/api/player.playbackrate.onfinishad.md +0 -15
  308. package/docs/api/player.playbackrate.onplay.md +0 -15
  309. package/docs/api/player.playbackrate.onrateselect.md +0 -49
  310. package/docs/api/player.playbackrate.onshowmenu.md +0 -15
  311. package/docs/api/player.playbackrate.onstartad.md +0 -15
  312. package/docs/api/player.playbackrate.onstop.md +0 -15
  313. package/docs/api/player.playbackrate.reload.md +0 -15
  314. package/docs/api/player.playbackrate.render.md +0 -15
  315. package/docs/api/player.playbackrate.supportedversion.md +0 -13
  316. package/docs/api/player.playbackrate.template.md +0 -11
  317. package/docs/api/player.playbackrate.unbindevents.md +0 -15
  318. package/docs/api/player.playbackrate.updateplaybackrate.md +0 -49
  319. package/docs/api/player.pluginsettings.md +0 -13
  320. package/docs/api/player.statistics._constructor_.md +0 -47
  321. package/docs/api/player.statistics.bindevents.md +0 -15
  322. package/docs/api/player.statistics.md +0 -141
  323. package/docs/api/player.statistics.name.md +0 -11
  324. package/docs/api/player.statistics.supportedversion.md +0 -13
  325. package/docs/api/player.thumbnails.attributes.md +0 -13
  326. package/docs/api/player.thumbnails.bindevents.md +0 -15
  327. package/docs/api/player.thumbnails.name.md +0 -11
  328. package/docs/api/player.thumbnails.settext.md +0 -49
  329. package/docs/api/player.thumbnails.supportedversion.md +0 -13
  330. package/docs/api/player.thumbnails.template.md +0 -11
  331. package/docs/api/player.volumefade.bindevents.md +0 -18
  332. package/docs/api/player.volumefade.name.md +0 -14
  333. package/docs/api/player.volumefade.unbindevents.md +0 -18
  334. package/src/plugins/disable-controls/DisableControls.ts +0 -81
  335. package/src/plugins/ga-events/GaEvents.js +0 -395
  336. package/src/plugins/ga-events/ga-tracking.js +0 -46
  337. package/src/plugins/statistics/Statistics.ts +0 -207
  338. /package/src/plugins/{statistics → telemetry}/Statistics copy.xts +0 -0
@@ -31431,1328 +31431,1360 @@ const pluginHtml$8 = "<button data-track-selector-button class='gcore-skin-butto
31431
31431
 
31432
31432
  const audioArrow = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"9px\" height=\"6px\" viewBox=\"0 0 9 6\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <!-- Generator: Sketch 49 (51002) - http://www.bohemiancoding.com/sketch -->\n <title>quality-arrow</title>\n <desc>Created with Sketch.</desc>\n <defs></defs>\n <g id=\"quality-arrow\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <path\n d=\"M5.07079194,5.78553848 C4.91457318,5.94277844 4.70551573,6.00941824 4.50028717,5.99893557 C4.2950586,6.00941824 4.08676693,5.94277844 3.92978239,5.78553848 L0.221118462,1.2997069 C-0.0737061539,1.00469478 -0.0737061539,0.526236029 0.221118462,0.231972666 C0.515177299,-0.0630394586 1.23500883,0.00734414472 1.64852907,0.00734414472 L7.77475484,0.00734414472 C8.21201421,0.00734414472 8.48539703,-0.0630394586 8.77945587,0.231972666 C9.07351471,0.526236029 9.07351471,1.00469478 8.77945587,1.2997069 L5.07079194,5.78553848 Z\"\n fill=\"#FFFFFE\"></path>\n </g>\n</svg>\n";
31433
31433
 
31434
- const VERSION$6 = '0.0.1';
31435
- // const T = 'plugins.audio_selector';
31436
- const AUTO = 0;
31434
+ const global$1 = (typeof global !== "undefined" ? global :
31435
+ typeof self !== "undefined" ? self :
31436
+ typeof window !== "undefined" ? window : {});
31437
+
31438
+ // the following is from is-buffer, also by Feross Aboukhadijeh and with same lisence
31439
+ // The _isBuffer check is for Safari 5-7 support, because it's missing
31440
+ // Object.prototype.constructor. Remove this eventually
31441
+ function isBuffer(obj) {
31442
+ return obj != null && (!!obj._isBuffer || isFastBuffer(obj) || isSlowBuffer(obj))
31443
+ }
31444
+
31445
+ function isFastBuffer (obj) {
31446
+ return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
31447
+ }
31448
+
31449
+ // For Node v0.10 support. Remove this eventually.
31450
+ function isSlowBuffer (obj) {
31451
+ return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isFastBuffer(obj.slice(0, 0))
31452
+ }
31453
+
31454
+ var inherits;
31455
+ if (typeof Object.create === 'function'){
31456
+ inherits = function inherits(ctor, superCtor) {
31457
+ // implementation from standard node.js 'util' module
31458
+ ctor.super_ = superCtor;
31459
+ ctor.prototype = Object.create(superCtor.prototype, {
31460
+ constructor: {
31461
+ value: ctor,
31462
+ enumerable: false,
31463
+ writable: true,
31464
+ configurable: true
31465
+ }
31466
+ });
31467
+ };
31468
+ } else {
31469
+ inherits = function inherits(ctor, superCtor) {
31470
+ ctor.super_ = superCtor;
31471
+ var TempCtor = function () {};
31472
+ TempCtor.prototype = superCtor.prototype;
31473
+ ctor.prototype = new TempCtor();
31474
+ ctor.prototype.constructor = ctor;
31475
+ };
31476
+ }
31477
+
31437
31478
  /**
31438
- * @beta
31479
+ * Echos the value of a value. Trys to print the value out
31480
+ * in the best way possible given the different types.
31481
+ *
31482
+ * @param {Object} obj The object to print out.
31483
+ * @param {Object} opts Optional options object that alters the output.
31439
31484
  */
31440
- class AudioSelector extends UICorePlugin {
31441
- selectedTrackId;
31442
- currentTrack = null;
31443
- tracks = [];
31444
- get name() {
31445
- return 'media_control_audio_selector';
31446
- }
31447
- get supportedVersion() {
31448
- return { min: CLAPPR_VERSION };
31485
+ /* legacy: obj, showHidden, depth, colors*/
31486
+ function inspect$1(obj, opts) {
31487
+ // default options
31488
+ var ctx = {
31489
+ seen: [],
31490
+ stylize: stylizeNoColor
31491
+ };
31492
+ // legacy...
31493
+ if (arguments.length >= 3) ctx.depth = arguments[2];
31494
+ if (arguments.length >= 4) ctx.colors = arguments[3];
31495
+ if (isBoolean(opts)) {
31496
+ // legacy...
31497
+ ctx.showHidden = opts;
31498
+ } else if (opts) {
31499
+ // got an "options" object
31500
+ _extend(ctx, opts);
31501
+ }
31502
+ // set default options
31503
+ if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
31504
+ if (isUndefined(ctx.depth)) ctx.depth = 2;
31505
+ if (isUndefined(ctx.colors)) ctx.colors = false;
31506
+ if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
31507
+ if (ctx.colors) ctx.stylize = stylizeWithColor;
31508
+ return formatValue(ctx, obj, ctx.depth);
31509
+ }
31510
+
31511
+ // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
31512
+ inspect$1.colors = {
31513
+ 'bold' : [1, 22],
31514
+ 'italic' : [3, 23],
31515
+ 'underline' : [4, 24],
31516
+ 'inverse' : [7, 27],
31517
+ 'white' : [37, 39],
31518
+ 'grey' : [90, 39],
31519
+ 'black' : [30, 39],
31520
+ 'blue' : [34, 39],
31521
+ 'cyan' : [36, 39],
31522
+ 'green' : [32, 39],
31523
+ 'magenta' : [35, 39],
31524
+ 'red' : [31, 39],
31525
+ 'yellow' : [33, 39]
31526
+ };
31527
+
31528
+ // Don't use 'blue' not visible on cmd.exe
31529
+ inspect$1.styles = {
31530
+ 'special': 'cyan',
31531
+ 'number': 'yellow',
31532
+ 'boolean': 'yellow',
31533
+ 'undefined': 'grey',
31534
+ 'null': 'bold',
31535
+ 'string': 'green',
31536
+ 'date': 'magenta',
31537
+ // "name": intentionally not styling
31538
+ 'regexp': 'red'
31539
+ };
31540
+
31541
+
31542
+ function stylizeWithColor(str, styleType) {
31543
+ var style = inspect$1.styles[styleType];
31544
+
31545
+ if (style) {
31546
+ return '\u001b[' + inspect$1.colors[style][0] + 'm' + str +
31547
+ '\u001b[' + inspect$1.colors[style][1] + 'm';
31548
+ } else {
31549
+ return str;
31550
+ }
31551
+ }
31552
+
31553
+
31554
+ function stylizeNoColor(str, styleType) {
31555
+ return str;
31556
+ }
31557
+
31558
+
31559
+ function arrayToHash(array) {
31560
+ var hash = {};
31561
+
31562
+ array.forEach(function(val, idx) {
31563
+ hash[val] = true;
31564
+ });
31565
+
31566
+ return hash;
31567
+ }
31568
+
31569
+
31570
+ function formatValue(ctx, value, recurseTimes) {
31571
+ // Provide a hook for user-specified inspect functions.
31572
+ // Check that value is an object with an inspect function on it
31573
+ if (ctx.customInspect &&
31574
+ value &&
31575
+ isFunction(value.inspect) &&
31576
+ // Filter out the util module, it's inspect function is special
31577
+ value.inspect !== inspect$1 &&
31578
+ // Also filter out any prototype objects using the circular check.
31579
+ !(value.constructor && value.constructor.prototype === value)) {
31580
+ var ret = value.inspect(recurseTimes, ctx);
31581
+ if (!isString(ret)) {
31582
+ ret = formatValue(ctx, ret, recurseTimes);
31449
31583
  }
31450
- static get version() {
31451
- return VERSION$6;
31584
+ return ret;
31585
+ }
31586
+
31587
+ // Primitive types cannot have properties
31588
+ var primitive = formatPrimitive(ctx, value);
31589
+ if (primitive) {
31590
+ return primitive;
31591
+ }
31592
+
31593
+ // Look up the keys of the object.
31594
+ var keys = Object.keys(value);
31595
+ var visibleKeys = arrayToHash(keys);
31596
+
31597
+ if (ctx.showHidden) {
31598
+ keys = Object.getOwnPropertyNames(value);
31599
+ }
31600
+
31601
+ // IE doesn't make error fields non-enumerable
31602
+ // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
31603
+ if (isError(value)
31604
+ && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
31605
+ return formatError(value);
31606
+ }
31607
+
31608
+ // Some type of object without properties can be shortcutted.
31609
+ if (keys.length === 0) {
31610
+ if (isFunction(value)) {
31611
+ var name = value.name ? ': ' + value.name : '';
31612
+ return ctx.stylize('[Function' + name + ']', 'special');
31452
31613
  }
31453
- get template() {
31454
- return tmpl(pluginHtml$8);
31614
+ if (isRegExp(value)) {
31615
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
31455
31616
  }
31456
- get attributes() {
31457
- return {
31458
- 'class': this.name,
31459
- 'data-track-selector': ''
31460
- };
31617
+ if (isDate(value)) {
31618
+ return ctx.stylize(Date.prototype.toString.call(value), 'date');
31461
31619
  }
31462
- get events() {
31463
- return {
31464
- 'click [data-track-selector-select]': 'onTrackSelect',
31465
- 'click [data-track-selector-button]': 'onShowLevelSelectMenu'
31466
- };
31620
+ if (isError(value)) {
31621
+ return formatError(value);
31467
31622
  }
31468
- bindEvents() {
31469
- this.listenTo(this.core, Events$1.CORE_READY, this.bindPlaybackEvents);
31470
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.reload);
31471
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.render);
31472
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_HIDE, this.hideSelectTrackMenu);
31623
+ }
31624
+
31625
+ var base = '', array = false, braces = ['{', '}'];
31626
+
31627
+ // Make Array say that they are Array
31628
+ if (isArray(value)) {
31629
+ array = true;
31630
+ braces = ['[', ']'];
31631
+ }
31632
+
31633
+ // Make functions say that they are functions
31634
+ if (isFunction(value)) {
31635
+ var n = value.name ? ': ' + value.name : '';
31636
+ base = ' [Function' + n + ']';
31637
+ }
31638
+
31639
+ // Make RegExps say that they are RegExps
31640
+ if (isRegExp(value)) {
31641
+ base = ' ' + RegExp.prototype.toString.call(value);
31642
+ }
31643
+
31644
+ // Make dates with properties first say the date
31645
+ if (isDate(value)) {
31646
+ base = ' ' + Date.prototype.toUTCString.call(value);
31647
+ }
31648
+
31649
+ // Make error with message first say the error
31650
+ if (isError(value)) {
31651
+ base = ' ' + formatError(value);
31652
+ }
31653
+
31654
+ if (keys.length === 0 && (!array || value.length == 0)) {
31655
+ return braces[0] + base + braces[1];
31656
+ }
31657
+
31658
+ if (recurseTimes < 0) {
31659
+ if (isRegExp(value)) {
31660
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
31661
+ } else {
31662
+ return ctx.stylize('[Object]', 'special');
31473
31663
  }
31474
- unBindEvents() {
31475
- // @ts-ignore
31476
- this.stopListening(this.core, Events$1.CORE_READY);
31477
- // @ts-ignore
31478
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED);
31479
- // @ts-ignore
31480
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED);
31481
- // @ts-ignore
31482
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_HIDE);
31483
- }
31484
- bindPlaybackEvents() {
31485
- // this.currentTrack = {};
31486
- // this.removeAuto = false;
31487
- this.selectedTrackId = undefined;
31488
- const currentPlayback = this.core.activePlayback;
31489
- this.listenTo(currentPlayback, Events$1.PLAYBACK_STOP, this.onStop);
31490
- this.setupAudioTrackListeners();
31491
- }
31492
- setupAudioTrackListeners() {
31493
- const currentPlayback = this.core.activePlayback;
31494
- // TODO no-crutch:currentPlayback._hls
31495
- if (currentPlayback._hls) {
31496
- // TODO AUDIO_TRACKS_UPDATED
31497
- // currentPlayback._hls.on('hlsAudioTracksUpdated', (e, data) => {
31498
- currentPlayback._hls.on(Events.AUDIO_TRACKS_UPDATED, (e, data) => {
31499
- // let id = -1;
31500
- // for (const audioTrack of data.audioTracks) {
31501
- // if (audioTrack.default) {
31502
- // id = audioTrack.id;
31503
- // this.currentTrack = audioTrack;
31504
- // }
31505
- // }
31506
- const defaultTrack = data.audioTracks.find((track) => track.default);
31507
- if (defaultTrack) {
31508
- this.currentTrack = {
31509
- id: defaultTrack.id,
31510
- label: defaultTrack.name
31511
- };
31512
- }
31513
- this.fillTracks(data.audioTracks.map(p => ({
31514
- id: p.id,
31515
- label: p.name
31516
- })), defaultTrack?.id);
31517
- });
31518
- currentPlayback._hls.on(Events.AUDIO_TRACK_SWITCHING, this.startTrackSwitch.bind(this));
31519
- currentPlayback._hls.on(Events.AUDIO_TRACK_SWITCHED, this.updateCurrentTrack.bind(this));
31520
- currentPlayback._hls.on(Events.AUDIO_TRACK_LOADED, this.updateCurrentTrack.bind(this));
31521
- }
31522
- else {
31523
- this.listenToOnce(currentPlayback, Events$1.PLAYBACK_PLAY, () => {
31524
- const mediaElement = currentPlayback.$el.get(0);
31525
- // const { audioTracks } = currentPlayback.$el.get(0);
31526
- const audioTracks = mediaElement.audioTracks;
31527
- if (audioTracks && audioTracks.length) {
31528
- let index = 0;
31529
- const trackItems = [];
31530
- for (const audioTrack of audioTracks) {
31531
- if (audioTrack.enabled) {
31532
- const t = {
31533
- id: index,
31534
- label: audioTrack.label,
31535
- };
31536
- this.currentTrack = t;
31537
- trackItems.push(t);
31538
- index++;
31539
- }
31540
- }
31541
- audioTracks.addEventListener('change', () => this.updateCurrentTrackW3C());
31542
- this.fillTracks(trackItems, trackItems[0].id);
31543
- }
31544
- });
31545
- }
31546
- }
31547
- onStop() { }
31548
- reload() {
31549
- this.unBindEvents();
31550
- this.bindEvents();
31551
- this.bindPlaybackEvents();
31552
- }
31553
- shouldRender() {
31554
- if (!this.core.activeContainer) {
31555
- return false;
31556
- }
31557
- const currentPlayback = this.core.activePlayback;
31558
- if (!currentPlayback) {
31559
- return false;
31560
- }
31561
- const { audioTracks } = (currentPlayback.activePlayback._hls || currentPlayback.$el.get(0));
31562
- this.tracks = audioTracks;
31563
- // Only care if we have at least 2 to choose from
31564
- return this.tracks && this.tracks.length > 1;
31565
- }
31566
- render() {
31567
- if (this.shouldRender()) {
31568
- this.$el.html(this.template({ 'tracks': this.tracks, 'title': this.getTitle() }));
31569
- if (Object.prototype.hasOwnProperty.call(this.core.mediaControl, '$audioTracksSelector') &&
31570
- this.core.mediaControl.$audioTracksSelector.length > 0) {
31571
- this.core.mediaControl.$audioTracksSelector.append(this.el);
31572
- }
31573
- this.highlightCurrentTrack();
31574
- }
31575
- if (Object.prototype.hasOwnProperty.call(this.core.mediaControl, '$audioTracksSelector') &&
31576
- this.core.mediaControl.$audioTracksSelector.find('span.audio-arrow').length > 0) {
31577
- this.core.mediaControl.$audioTracksSelector.find('span.audio-arrow').append(audioArrow);
31578
- }
31579
- return this;
31664
+ }
31665
+
31666
+ ctx.seen.push(value);
31667
+
31668
+ var output;
31669
+ if (array) {
31670
+ output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
31671
+ } else {
31672
+ output = keys.map(function(key) {
31673
+ return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
31674
+ });
31675
+ }
31676
+
31677
+ ctx.seen.pop();
31678
+
31679
+ return reduceToSingleString(output, base, braces);
31680
+ }
31681
+
31682
+
31683
+ function formatPrimitive(ctx, value) {
31684
+ if (isUndefined(value))
31685
+ return ctx.stylize('undefined', 'undefined');
31686
+ if (isString(value)) {
31687
+ var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
31688
+ .replace(/'/g, "\\'")
31689
+ .replace(/\\"/g, '"') + '\'';
31690
+ return ctx.stylize(simple, 'string');
31691
+ }
31692
+ if (isNumber(value))
31693
+ return ctx.stylize('' + value, 'number');
31694
+ if (isBoolean(value))
31695
+ return ctx.stylize('' + value, 'boolean');
31696
+ // For some reason typeof null is "object", so special case here.
31697
+ if (isNull(value))
31698
+ return ctx.stylize('null', 'null');
31699
+ }
31700
+
31701
+
31702
+ function formatError(value) {
31703
+ return '[' + Error.prototype.toString.call(value) + ']';
31704
+ }
31705
+
31706
+
31707
+ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
31708
+ var output = [];
31709
+ for (var i = 0, l = value.length; i < l; ++i) {
31710
+ if (hasOwnProperty(value, String(i))) {
31711
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
31712
+ String(i), true));
31713
+ } else {
31714
+ output.push('');
31580
31715
  }
31581
- fillTracks(tracks, selected = AUTO) {
31582
- if (this.selectedTrackId === undefined) {
31583
- this.selectedTrackId = selected;
31584
- }
31585
- // this.tracks = levels.audioTracks;
31586
- // for (let i = 0; i < this.tracks.length; i++) {
31587
- // if (this.tracks[i].name && !this.tracks[i].label) {
31588
- // this.tracks[i].label = this.tracks[i].name;
31589
- // }
31590
- // }
31591
- this.tracks = tracks;
31592
- // Player.player.trigger('tracks', this.tracks);
31593
- // this.core.trigger('tracks', this.tracks);
31594
- this.render();
31716
+ }
31717
+ keys.forEach(function(key) {
31718
+ if (!key.match(/^\d+$/)) {
31719
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
31720
+ key, true));
31595
31721
  }
31596
- findTrackBy(id) {
31597
- return this.tracks.find((track) => track.id === id);
31722
+ });
31723
+ return output;
31724
+ }
31725
+
31726
+
31727
+ function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
31728
+ var name, str, desc;
31729
+ desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
31730
+ if (desc.get) {
31731
+ if (desc.set) {
31732
+ str = ctx.stylize('[Getter/Setter]', 'special');
31733
+ } else {
31734
+ str = ctx.stylize('[Getter]', 'special');
31598
31735
  }
31599
- onTrackSelect(event) {
31600
- // this.selectedTrackId = parseInt(event.target.dataset.levelSelectorSelect, 10)
31601
- const id = event.target?.dataset?.trackSelectorSelect;
31602
- if (id) {
31603
- this.setIndexTrack(Number(id));
31604
- }
31605
- this.toggleContextMenu();
31606
- event.stopPropagation();
31607
- return false;
31736
+ } else {
31737
+ if (desc.set) {
31738
+ str = ctx.stylize('[Setter]', 'special');
31608
31739
  }
31609
- setIndexTrack(index) {
31610
- this.selectedTrackId = index;
31611
- if (this.core.activePlayback._hls) {
31612
- if (this.core.activePlayback._hls.audioTrack.id === this.selectedTrackId) {
31613
- return;
31614
- }
31615
- this.core.activePlayback._hls.audioTrack = this.selectedTrackId;
31616
- }
31617
- else {
31618
- const { audioTracks } = this.core.activePlayback.$el.get(0);
31619
- for (const track of audioTracks) {
31620
- track.enabled = track.id === this.selectedTrackId;
31621
- }
31740
+ }
31741
+ if (!hasOwnProperty(visibleKeys, key)) {
31742
+ name = '[' + key + ']';
31743
+ }
31744
+ if (!str) {
31745
+ if (ctx.seen.indexOf(desc.value) < 0) {
31746
+ if (isNull(recurseTimes)) {
31747
+ str = formatValue(ctx, desc.value, null);
31748
+ } else {
31749
+ str = formatValue(ctx, desc.value, recurseTimes - 1);
31750
+ }
31751
+ if (str.indexOf('\n') > -1) {
31752
+ if (array) {
31753
+ str = str.split('\n').map(function(line) {
31754
+ return ' ' + line;
31755
+ }).join('\n').substr(2);
31756
+ } else {
31757
+ str = '\n' + str.split('\n').map(function(line) {
31758
+ return ' ' + line;
31759
+ }).join('\n');
31622
31760
  }
31623
- this.updateText(this.selectedTrackId);
31624
- }
31625
- onShowLevelSelectMenu() {
31626
- this.toggleContextMenu();
31627
- }
31628
- hideSelectTrackMenu() {
31629
- this.$('.audio_selector ul').hide();
31630
- }
31631
- toggleContextMenu() {
31632
- this.$('.audio_selector ul').toggle();
31633
- }
31634
- buttonElement() {
31635
- return this.$('.audio_selector button');
31761
+ }
31762
+ } else {
31763
+ str = ctx.stylize('[Circular]', 'special');
31636
31764
  }
31637
- buttonElementText() {
31638
- return this.$('.audio_selector button .audio-text');
31765
+ }
31766
+ if (isUndefined(name)) {
31767
+ if (array && key.match(/^\d+$/)) {
31768
+ return str;
31639
31769
  }
31640
- trackElement(id) {
31641
- return this.$('.audio_selector ul a' + (id !== undefined ? '[data-track-selector-select="' + id + '"]' : '')).parent();
31770
+ name = JSON.stringify('' + key);
31771
+ if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
31772
+ name = name.substr(1, name.length - 2);
31773
+ name = ctx.stylize(name, 'name');
31774
+ } else {
31775
+ name = name.replace(/'/g, "\\'")
31776
+ .replace(/\\"/g, '"')
31777
+ .replace(/(^"|"$)/g, "'");
31778
+ name = ctx.stylize(name, 'string');
31642
31779
  }
31643
- getTitle() {
31644
- if (!this.tracks) {
31645
- return '';
31646
- }
31647
- const selectedTrackId = this.selectedTrackId || 0;
31648
- const selectedTrack = this.tracks[selectedTrackId];
31649
- return selectedTrack?.label || '';
31650
- }
31651
- startTrackSwitch() {
31652
- this.buttonElement().addClass('changing');
31653
- }
31654
- updateText(trackId) {
31655
- if (trackId === undefined) {
31656
- return;
31657
- }
31658
- const track = this.findTrackBy(trackId);
31659
- if (track) {
31660
- this.buttonElementText().text(track.label);
31661
- }
31662
- }
31663
- updateCurrentTrack(e, info) {
31664
- // if (!info) {
31665
- // const { audioTracks } = this.core.activePlayback.$el.get(0);
31666
- // for (const track of audioTracks) {
31667
- // if (track.enabled) {
31668
- // info = track;
31669
- // }
31670
- // }
31671
- // }
31672
- // if (!info) {
31673
- // return;
31674
- // }
31675
- // const track = this.findTrackBy(info.id);
31676
- // this.currentTrack = track ? track : null;
31677
- // this.selectedTrackId = track?.id;
31678
- // this.highlightCurrentTrack();
31679
- // this.buttonElement().removeClass('changing');
31680
- this.setCurrentTrack(info.id);
31681
- }
31682
- updateCurrentTrackW3C() {
31683
- const { audioTracks } = this.core.activePlayback.$el.get(0);
31684
- const index = audioTracks.findIndex((track) => track.enabled);
31685
- if (index >= 0) {
31686
- this.setCurrentTrack(index);
31687
- }
31688
- }
31689
- setCurrentTrack(index) {
31690
- const track = this.findTrackBy(index);
31691
- this.currentTrack = track ?? null;
31692
- this.selectedTrackId = index;
31693
- this.highlightCurrentTrack();
31694
- this.buttonElement().removeClass('changing');
31695
- }
31696
- highlightCurrentTrack() {
31697
- this.trackElement().removeClass('current');
31698
- this.trackElement().find('a').removeClass('gcore-skin-active');
31699
- if (this.currentTrack) {
31700
- const currentTrackElement = this.trackElement(this.currentTrack.id);
31701
- currentTrackElement.addClass('current');
31702
- currentTrackElement.find('a').addClass('gcore-skin-active');
31703
- }
31704
- this.updateText(this.selectedTrackId);
31705
- }
31706
- }
31780
+ }
31707
31781
 
31708
- /**
31709
- * @public
31710
- * @param msg
31711
- * @param data
31712
- */
31713
- function trace(msg, data = {}) {
31782
+ return name + ': ' + str;
31714
31783
  }
31715
31784
 
31716
- const volumeOffIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.50025 8.00025C4.67125 8.00025 4.00025 8.67225 4.00025 9.50025V14.5003C4.00025 15.3283 4.67125 16.0003 5.50025 16.0003H7.24824C7.65024 16.0003 8.03627 16.1613 8.31727 16.4483L12.5443 20.7413C12.7083 20.9073 12.9262 20.9963 13.1492 20.9963C13.2572 20.9963 13.3672 20.9763 13.4722 20.9333C13.7932 20.8013 14.0003 20.4923 14.0003 20.1462V16.3283C14.0003 16.1963 13.9473 16.0683 13.8543 15.9753L6.02528 8.14625C5.93228 8.05325 5.80425 8.00025 5.67225 8.00025H5.50025ZM14.0003 3.85426C14.0003 3.50826 13.7932 3.19927 13.4722 3.06727C13.1502 2.93627 12.7873 3.01226 12.5443 3.25926L9.33827 6.51527C9.14627 6.71127 9.14626 7.02625 9.34126 7.22025L13.5733 11.4522C13.7313 11.6102 14.0003 11.4982 14.0003 11.2752V3.85426ZM20.8543 20.8543C20.7563 20.9513 20.6283 21.0003 20.5003 21.0003C20.3723 21.0003 20.2442 20.9513 20.1462 20.8543L3.14625 3.85426C2.95125 3.65826 2.95125 3.34225 3.14625 3.14625C3.34225 2.95125 3.65826 2.95125 3.85426 3.14625L20.8543 20.1462C21.0493 20.3422 21.0493 20.6583 20.8543 20.8543Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
31717
31785
 
31718
- const pluginHtml$7 = "<div class=\"big-mute-icon-wrapper\" data-big-mute>\n <div class=\"big-mute-icon gcore-skin-border-color\" data-big-mute-icon></div>\n</div>\n";
31786
+ function reduceToSingleString(output, base, braces) {
31787
+ var length = output.reduce(function(prev, cur) {
31788
+ if (cur.indexOf('\n') >= 0) ;
31789
+ return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
31790
+ }, 0);
31719
31791
 
31720
- const T$8 = "plugins.big_mute_button";
31721
- /**
31722
- * @beta
31723
- */
31724
- class BigMuteButton extends UICorePlugin {
31725
- isBigMuteButtonHidden = false;
31726
- _adIsPlaying = false;
31727
- $bigMuteBtnContainer = null;
31728
- $bigMuteButton = null;
31729
- get name() {
31730
- return 'big_mute_button';
31731
- }
31732
- get supportedVersion() {
31733
- return { min: CLAPPR_VERSION };
31734
- }
31735
- get template() {
31736
- return tmpl(pluginHtml$7);
31737
- }
31738
- get events() {
31739
- return {
31740
- 'click .big-mute-icon': 'handleBigMuteBtnClick',
31741
- 'click .big-mute-icon-wrapper': 'destroyBigMuteBtn',
31742
- };
31743
- }
31744
- bindEvents() {
31745
- super.bindEvents();
31746
- this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
31747
- this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
31748
- this.listenTo(this.core, 'core:advertisement:finish', this.onFinishAd);
31749
- trace(`${T$8} bindEvents`, {
31750
- mediacontrol: !!this.core.mediaControl,
31751
- });
31752
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.mediaControlRendered);
31753
- }
31754
- unBindEvents() {
31755
- // @ts-ignore
31756
- this.stopListening(this.core, Events$1.CORE_READY);
31757
- this.stopListening(this.core, 'core:advertisement:start', this.onStartAd);
31758
- this.stopListening(this.core, 'core:advertisement:finish', this.onFinishAd);
31759
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.mediaControlRendered);
31760
- const container = this.core.activeContainer;
31761
- if (container) {
31762
- this.stopListening(container.playback, Events$1.PLAYBACK_PLAY, this.render);
31763
- }
31764
- }
31765
- onCoreReady() {
31766
- this.listenTo(this.core.activeContainer, Events$1.CONTAINER_VOLUME, this.onContainerVolume);
31767
- this.listenTo(this.core.activeContainer, Events$1.CONTAINER_READY, this.onContainerStart);
31768
- this.listenTo(this.core.activePlayback, Events$1.PLAYBACK_ENDED, this.onPlaybackEnded);
31769
- }
31770
- onContainerVolume(value) {
31771
- if (value !== 0) {
31772
- this.destroyBigMuteBtn();
31773
- }
31774
- }
31775
- onContainerStart() {
31776
- if (this.isBigMuteButtonHidden) {
31777
- this.showBigMuteBtn();
31778
- }
31779
- }
31780
- onPlaybackEnded() {
31781
- this.hideBigMuteBtn();
31782
- }
31783
- mediaControlRendered() {
31784
- const container = this.core.activeContainer;
31785
- if (container) {
31786
- this.listenTo(container.playback, Events$1.PLAYBACK_PLAY, () => {
31787
- this.render();
31788
- });
31789
- }
31790
- }
31791
- onStartAd() {
31792
- this._adIsPlaying = true;
31793
- if (this.$bigMuteBtnContainer) {
31794
- this.$bigMuteBtnContainer.addClass('hide');
31795
- }
31796
- }
31797
- onFinishAd() {
31798
- this._adIsPlaying = false;
31799
- if (this.$bigMuteBtnContainer) {
31800
- this.$bigMuteBtnContainer.removeClass('hide');
31801
- }
31802
- }
31803
- shouldRender() {
31804
- const container = this.core.activeContainer;
31805
- if (!container) {
31806
- return false;
31807
- }
31808
- const { autoPlay, wasMuted } = this.options;
31809
- const volume = container.volume;
31810
- return autoPlay && !wasMuted && volume === 0;
31811
- }
31812
- render() {
31813
- if (this.shouldRender()) {
31814
- trace(`${T$8} render`, {
31815
- el: !!this.$el,
31816
- });
31817
- this.$el.html(this.template());
31818
- this.$bigMuteBtnContainer = this.$el.find('.big-mute-icon-wrapper[data-big-mute]');
31819
- this._adIsPlaying && this.$bigMuteBtnContainer.addClass('hide');
31820
- this.$bigMuteButton = this.$bigMuteBtnContainer.find('.big-mute-icon');
31821
- this.$bigMuteButton.append(volumeOffIcon);
31822
- const container = this.core.activeContainer;
31823
- container.$el.append(this.$el.get(0));
31824
- }
31825
- return this;
31826
- }
31827
- hideBigMuteBtn() {
31828
- this.isBigMuteButtonHidden = true;
31829
- this.$bigMuteBtnContainer?.addClass('hide');
31830
- }
31831
- showBigMuteBtn() {
31832
- this.isBigMuteButtonHidden = false;
31833
- if (this.$bigMuteBtnContainer) {
31834
- this.$bigMuteBtnContainer.removeClass('hide');
31835
- }
31836
- }
31837
- destroyBigMuteBtn(e) {
31838
- this.hideBigMuteBtn();
31839
- if (e && e.stopPropagation) {
31840
- e.stopPropagation();
31841
- }
31842
- this.destroy();
31843
- }
31844
- handleBigMuteBtnClick(e) {
31845
- const localVolume = Utils.Config.restore('volume');
31846
- const volume = !isNaN(localVolume) ? localVolume : 100;
31847
- // TODO use container.setVolume() instead
31848
- this.core.mediaControl.setVolume(volume === 0 ? 100 : volume);
31849
- this.destroyBigMuteBtn(e);
31850
- }
31792
+ if (length > 60) {
31793
+ return braces[0] +
31794
+ (base === '' ? '' : base + '\n ') +
31795
+ ' ' +
31796
+ output.join(',\n ') +
31797
+ ' ' +
31798
+ braces[1];
31799
+ }
31800
+
31801
+ return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
31851
31802
  }
31852
31803
 
31853
- const global$1 = (typeof global !== "undefined" ? global :
31854
- typeof self !== "undefined" ? self :
31855
- typeof window !== "undefined" ? window : {});
31856
31804
 
31857
- // the following is from is-buffer, also by Feross Aboukhadijeh and with same lisence
31858
- // The _isBuffer check is for Safari 5-7 support, because it's missing
31859
- // Object.prototype.constructor. Remove this eventually
31860
- function isBuffer(obj) {
31861
- return obj != null && (!!obj._isBuffer || isFastBuffer(obj) || isSlowBuffer(obj))
31805
+ // NOTE: These type checking functions intentionally don't use `instanceof`
31806
+ // because it is fragile and can be easily faked with `Object.create()`.
31807
+ function isArray(ar) {
31808
+ return Array.isArray(ar);
31862
31809
  }
31863
31810
 
31864
- function isFastBuffer (obj) {
31865
- return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
31811
+ function isBoolean(arg) {
31812
+ return typeof arg === 'boolean';
31866
31813
  }
31867
31814
 
31868
- // For Node v0.10 support. Remove this eventually.
31869
- function isSlowBuffer (obj) {
31870
- return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isFastBuffer(obj.slice(0, 0))
31815
+ function isNull(arg) {
31816
+ return arg === null;
31871
31817
  }
31872
31818
 
31873
- var inherits;
31874
- if (typeof Object.create === 'function'){
31875
- inherits = function inherits(ctor, superCtor) {
31876
- // implementation from standard node.js 'util' module
31877
- ctor.super_ = superCtor;
31878
- ctor.prototype = Object.create(superCtor.prototype, {
31879
- constructor: {
31880
- value: ctor,
31881
- enumerable: false,
31882
- writable: true,
31883
- configurable: true
31884
- }
31885
- });
31886
- };
31887
- } else {
31888
- inherits = function inherits(ctor, superCtor) {
31889
- ctor.super_ = superCtor;
31890
- var TempCtor = function () {};
31891
- TempCtor.prototype = superCtor.prototype;
31892
- ctor.prototype = new TempCtor();
31893
- ctor.prototype.constructor = ctor;
31894
- };
31819
+ function isNumber(arg) {
31820
+ return typeof arg === 'number';
31895
31821
  }
31896
31822
 
31897
- /**
31898
- * Echos the value of a value. Trys to print the value out
31899
- * in the best way possible given the different types.
31900
- *
31901
- * @param {Object} obj The object to print out.
31902
- * @param {Object} opts Optional options object that alters the output.
31903
- */
31904
- /* legacy: obj, showHidden, depth, colors*/
31905
- function inspect$1(obj, opts) {
31906
- // default options
31907
- var ctx = {
31908
- seen: [],
31909
- stylize: stylizeNoColor
31910
- };
31911
- // legacy...
31912
- if (arguments.length >= 3) ctx.depth = arguments[2];
31913
- if (arguments.length >= 4) ctx.colors = arguments[3];
31914
- if (isBoolean(opts)) {
31915
- // legacy...
31916
- ctx.showHidden = opts;
31917
- } else if (opts) {
31918
- // got an "options" object
31919
- _extend(ctx, opts);
31920
- }
31921
- // set default options
31922
- if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
31923
- if (isUndefined(ctx.depth)) ctx.depth = 2;
31924
- if (isUndefined(ctx.colors)) ctx.colors = false;
31925
- if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
31926
- if (ctx.colors) ctx.stylize = stylizeWithColor;
31927
- return formatValue(ctx, obj, ctx.depth);
31823
+ function isString(arg) {
31824
+ return typeof arg === 'string';
31928
31825
  }
31929
31826
 
31930
- // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
31931
- inspect$1.colors = {
31932
- 'bold' : [1, 22],
31933
- 'italic' : [3, 23],
31934
- 'underline' : [4, 24],
31935
- 'inverse' : [7, 27],
31936
- 'white' : [37, 39],
31937
- 'grey' : [90, 39],
31938
- 'black' : [30, 39],
31939
- 'blue' : [34, 39],
31940
- 'cyan' : [36, 39],
31941
- 'green' : [32, 39],
31942
- 'magenta' : [35, 39],
31943
- 'red' : [31, 39],
31944
- 'yellow' : [33, 39]
31945
- };
31946
-
31947
- // Don't use 'blue' not visible on cmd.exe
31948
- inspect$1.styles = {
31949
- 'special': 'cyan',
31950
- 'number': 'yellow',
31951
- 'boolean': 'yellow',
31952
- 'undefined': 'grey',
31953
- 'null': 'bold',
31954
- 'string': 'green',
31955
- 'date': 'magenta',
31956
- // "name": intentionally not styling
31957
- 'regexp': 'red'
31958
- };
31959
-
31960
-
31961
- function stylizeWithColor(str, styleType) {
31962
- var style = inspect$1.styles[styleType];
31827
+ function isUndefined(arg) {
31828
+ return arg === undefined;
31829
+ }
31963
31830
 
31964
- if (style) {
31965
- return '\u001b[' + inspect$1.colors[style][0] + 'm' + str +
31966
- '\u001b[' + inspect$1.colors[style][1] + 'm';
31967
- } else {
31968
- return str;
31969
- }
31831
+ function isRegExp(re) {
31832
+ return isObject(re) && objectToString(re) === '[object RegExp]';
31970
31833
  }
31971
31834
 
31835
+ function isObject(arg) {
31836
+ return typeof arg === 'object' && arg !== null;
31837
+ }
31972
31838
 
31973
- function stylizeNoColor(str, styleType) {
31974
- return str;
31839
+ function isDate(d) {
31840
+ return isObject(d) && objectToString(d) === '[object Date]';
31975
31841
  }
31976
31842
 
31843
+ function isError(e) {
31844
+ return isObject(e) &&
31845
+ (objectToString(e) === '[object Error]' || e instanceof Error);
31846
+ }
31977
31847
 
31978
- function arrayToHash(array) {
31979
- var hash = {};
31848
+ function isFunction(arg) {
31849
+ return typeof arg === 'function';
31850
+ }
31980
31851
 
31981
- array.forEach(function(val, idx) {
31982
- hash[val] = true;
31983
- });
31852
+ function isPrimitive(arg) {
31853
+ return arg === null ||
31854
+ typeof arg === 'boolean' ||
31855
+ typeof arg === 'number' ||
31856
+ typeof arg === 'string' ||
31857
+ typeof arg === 'symbol' || // ES6 symbol
31858
+ typeof arg === 'undefined';
31859
+ }
31984
31860
 
31985
- return hash;
31861
+ function objectToString(o) {
31862
+ return Object.prototype.toString.call(o);
31986
31863
  }
31987
31864
 
31865
+ function _extend(origin, add) {
31866
+ // Don't do anything if add isn't an object
31867
+ if (!add || !isObject(add)) return origin;
31988
31868
 
31989
- function formatValue(ctx, value, recurseTimes) {
31990
- // Provide a hook for user-specified inspect functions.
31991
- // Check that value is an object with an inspect function on it
31992
- if (ctx.customInspect &&
31993
- value &&
31994
- isFunction(value.inspect) &&
31995
- // Filter out the util module, it's inspect function is special
31996
- value.inspect !== inspect$1 &&
31997
- // Also filter out any prototype objects using the circular check.
31998
- !(value.constructor && value.constructor.prototype === value)) {
31999
- var ret = value.inspect(recurseTimes, ctx);
32000
- if (!isString(ret)) {
32001
- ret = formatValue(ctx, ret, recurseTimes);
32002
- }
32003
- return ret;
31869
+ var keys = Object.keys(add);
31870
+ var i = keys.length;
31871
+ while (i--) {
31872
+ origin[keys[i]] = add[keys[i]];
32004
31873
  }
31874
+ return origin;
31875
+ }
31876
+ function hasOwnProperty(obj, prop) {
31877
+ return Object.prototype.hasOwnProperty.call(obj, prop);
31878
+ }
32005
31879
 
32006
- // Primitive types cannot have properties
32007
- var primitive = formatPrimitive(ctx, value);
32008
- if (primitive) {
32009
- return primitive;
31880
+ function compare(a, b) {
31881
+ if (a === b) {
31882
+ return 0;
32010
31883
  }
32011
31884
 
32012
- // Look up the keys of the object.
32013
- var keys = Object.keys(value);
32014
- var visibleKeys = arrayToHash(keys);
31885
+ var x = a.length;
31886
+ var y = b.length;
32015
31887
 
32016
- if (ctx.showHidden) {
32017
- keys = Object.getOwnPropertyNames(value);
31888
+ for (var i = 0, len = Math.min(x, y); i < len; ++i) {
31889
+ if (a[i] !== b[i]) {
31890
+ x = a[i];
31891
+ y = b[i];
31892
+ break;
31893
+ }
32018
31894
  }
32019
31895
 
32020
- // IE doesn't make error fields non-enumerable
32021
- // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
32022
- if (isError(value)
32023
- && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
32024
- return formatError(value);
31896
+ if (x < y) {
31897
+ return -1;
32025
31898
  }
32026
-
32027
- // Some type of object without properties can be shortcutted.
32028
- if (keys.length === 0) {
32029
- if (isFunction(value)) {
32030
- var name = value.name ? ': ' + value.name : '';
32031
- return ctx.stylize('[Function' + name + ']', 'special');
32032
- }
32033
- if (isRegExp(value)) {
32034
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
32035
- }
32036
- if (isDate(value)) {
32037
- return ctx.stylize(Date.prototype.toString.call(value), 'date');
32038
- }
32039
- if (isError(value)) {
32040
- return formatError(value);
32041
- }
31899
+ if (y < x) {
31900
+ return 1;
32042
31901
  }
31902
+ return 0;
31903
+ }
31904
+ var hasOwn = Object.prototype.hasOwnProperty;
32043
31905
 
32044
- var base = '', array = false, braces = ['{', '}'];
32045
-
32046
- // Make Array say that they are Array
32047
- if (isArray(value)) {
32048
- array = true;
32049
- braces = ['[', ']'];
31906
+ var objectKeys = Object.keys || function (obj) {
31907
+ var keys = [];
31908
+ for (var key in obj) {
31909
+ if (hasOwn.call(obj, key)) keys.push(key);
32050
31910
  }
32051
-
32052
- // Make functions say that they are functions
32053
- if (isFunction(value)) {
32054
- var n = value.name ? ': ' + value.name : '';
32055
- base = ' [Function' + n + ']';
31911
+ return keys;
31912
+ };
31913
+ var pSlice = Array.prototype.slice;
31914
+ var _functionsHaveNames;
31915
+ function functionsHaveNames() {
31916
+ if (typeof _functionsHaveNames !== 'undefined') {
31917
+ return _functionsHaveNames;
32056
31918
  }
32057
-
32058
- // Make RegExps say that they are RegExps
32059
- if (isRegExp(value)) {
32060
- base = ' ' + RegExp.prototype.toString.call(value);
31919
+ return _functionsHaveNames = (function () {
31920
+ return function foo() {}.name === 'foo';
31921
+ }());
31922
+ }
31923
+ function pToString (obj) {
31924
+ return Object.prototype.toString.call(obj);
31925
+ }
31926
+ function isView(arrbuf) {
31927
+ if (isBuffer(arrbuf)) {
31928
+ return false;
32061
31929
  }
32062
-
32063
- // Make dates with properties first say the date
32064
- if (isDate(value)) {
32065
- base = ' ' + Date.prototype.toUTCString.call(value);
31930
+ if (typeof global$1.ArrayBuffer !== 'function') {
31931
+ return false;
32066
31932
  }
32067
-
32068
- // Make error with message first say the error
32069
- if (isError(value)) {
32070
- base = ' ' + formatError(value);
31933
+ if (typeof ArrayBuffer.isView === 'function') {
31934
+ return ArrayBuffer.isView(arrbuf);
32071
31935
  }
32072
-
32073
- if (keys.length === 0 && (!array || value.length == 0)) {
32074
- return braces[0] + base + braces[1];
31936
+ if (!arrbuf) {
31937
+ return false;
32075
31938
  }
32076
-
32077
- if (recurseTimes < 0) {
32078
- if (isRegExp(value)) {
32079
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
32080
- } else {
32081
- return ctx.stylize('[Object]', 'special');
32082
- }
31939
+ if (arrbuf instanceof DataView) {
31940
+ return true;
31941
+ }
31942
+ if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
31943
+ return true;
32083
31944
  }
31945
+ return false;
31946
+ }
31947
+ // 1. The assert module provides functions that throw
31948
+ // AssertionError's when particular conditions are not met. The
31949
+ // assert module must conform to the following interface.
32084
31950
 
32085
- ctx.seen.push(value);
32086
-
32087
- var output;
32088
- if (array) {
32089
- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
32090
- } else {
32091
- output = keys.map(function(key) {
32092
- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
32093
- });
32094
- }
32095
-
32096
- ctx.seen.pop();
32097
-
32098
- return reduceToSingleString(output, base, braces);
32099
- }
31951
+ function assert(value, message) {
31952
+ if (!value) fail(value, true, message, '==', ok);
31953
+ }
32100
31954
 
31955
+ // 2. The AssertionError is defined in assert.
31956
+ // new assert.AssertionError({ message: message,
31957
+ // actual: actual,
31958
+ // expected: expected })
32101
31959
 
32102
- function formatPrimitive(ctx, value) {
32103
- if (isUndefined(value))
32104
- return ctx.stylize('undefined', 'undefined');
32105
- if (isString(value)) {
32106
- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
32107
- .replace(/'/g, "\\'")
32108
- .replace(/\\"/g, '"') + '\'';
32109
- return ctx.stylize(simple, 'string');
31960
+ var regex = /\s*function\s+([^\(\s]*)\s*/;
31961
+ // based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
31962
+ function getName(func) {
31963
+ if (!isFunction(func)) {
31964
+ return;
32110
31965
  }
32111
- if (isNumber(value))
32112
- return ctx.stylize('' + value, 'number');
32113
- if (isBoolean(value))
32114
- return ctx.stylize('' + value, 'boolean');
32115
- // For some reason typeof null is "object", so special case here.
32116
- if (isNull(value))
32117
- return ctx.stylize('null', 'null');
32118
- }
32119
-
32120
-
32121
- function formatError(value) {
32122
- return '[' + Error.prototype.toString.call(value) + ']';
31966
+ if (functionsHaveNames()) {
31967
+ return func.name;
31968
+ }
31969
+ var str = func.toString();
31970
+ var match = str.match(regex);
31971
+ return match && match[1];
32123
31972
  }
31973
+ assert.AssertionError = AssertionError;
31974
+ function AssertionError(options) {
31975
+ this.name = 'AssertionError';
31976
+ this.actual = options.actual;
31977
+ this.expected = options.expected;
31978
+ this.operator = options.operator;
31979
+ if (options.message) {
31980
+ this.message = options.message;
31981
+ this.generatedMessage = false;
31982
+ } else {
31983
+ this.message = getMessage(this);
31984
+ this.generatedMessage = true;
31985
+ }
31986
+ var stackStartFunction = options.stackStartFunction || fail;
31987
+ if (Error.captureStackTrace) {
31988
+ Error.captureStackTrace(this, stackStartFunction);
31989
+ } else {
31990
+ // non v8 browsers so we can have a stacktrace
31991
+ var err = new Error();
31992
+ if (err.stack) {
31993
+ var out = err.stack;
32124
31994
 
31995
+ // try to strip useless frames
31996
+ var fn_name = getName(stackStartFunction);
31997
+ var idx = out.indexOf('\n' + fn_name);
31998
+ if (idx >= 0) {
31999
+ // once we have located the function frame
32000
+ // we need to strip out everything before it (and its line)
32001
+ var next_line = out.indexOf('\n', idx + 1);
32002
+ out = out.substring(next_line + 1);
32003
+ }
32125
32004
 
32126
- function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
32127
- var output = [];
32128
- for (var i = 0, l = value.length; i < l; ++i) {
32129
- if (hasOwnProperty(value, String(i))) {
32130
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
32131
- String(i), true));
32132
- } else {
32133
- output.push('');
32005
+ this.stack = out;
32134
32006
  }
32135
32007
  }
32136
- keys.forEach(function(key) {
32137
- if (!key.match(/^\d+$/)) {
32138
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
32139
- key, true));
32140
- }
32141
- });
32142
- return output;
32143
32008
  }
32144
32009
 
32010
+ // assert.AssertionError instanceof Error
32011
+ inherits(AssertionError, Error);
32145
32012
 
32146
- function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
32147
- var name, str, desc;
32148
- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
32149
- if (desc.get) {
32150
- if (desc.set) {
32151
- str = ctx.stylize('[Getter/Setter]', 'special');
32152
- } else {
32153
- str = ctx.stylize('[Getter]', 'special');
32154
- }
32013
+ function truncate(s, n) {
32014
+ if (typeof s === 'string') {
32015
+ return s.length < n ? s : s.slice(0, n);
32155
32016
  } else {
32156
- if (desc.set) {
32157
- str = ctx.stylize('[Setter]', 'special');
32158
- }
32159
- }
32160
- if (!hasOwnProperty(visibleKeys, key)) {
32161
- name = '[' + key + ']';
32162
- }
32163
- if (!str) {
32164
- if (ctx.seen.indexOf(desc.value) < 0) {
32165
- if (isNull(recurseTimes)) {
32166
- str = formatValue(ctx, desc.value, null);
32167
- } else {
32168
- str = formatValue(ctx, desc.value, recurseTimes - 1);
32169
- }
32170
- if (str.indexOf('\n') > -1) {
32171
- if (array) {
32172
- str = str.split('\n').map(function(line) {
32173
- return ' ' + line;
32174
- }).join('\n').substr(2);
32175
- } else {
32176
- str = '\n' + str.split('\n').map(function(line) {
32177
- return ' ' + line;
32178
- }).join('\n');
32179
- }
32180
- }
32181
- } else {
32182
- str = ctx.stylize('[Circular]', 'special');
32183
- }
32017
+ return s;
32184
32018
  }
32185
- if (isUndefined(name)) {
32186
- if (array && key.match(/^\d+$/)) {
32187
- return str;
32188
- }
32189
- name = JSON.stringify('' + key);
32190
- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
32191
- name = name.substr(1, name.length - 2);
32192
- name = ctx.stylize(name, 'name');
32193
- } else {
32194
- name = name.replace(/'/g, "\\'")
32195
- .replace(/\\"/g, '"')
32196
- .replace(/(^"|"$)/g, "'");
32197
- name = ctx.stylize(name, 'string');
32198
- }
32019
+ }
32020
+ function inspect(something) {
32021
+ if (functionsHaveNames() || !isFunction(something)) {
32022
+ return inspect$1(something);
32199
32023
  }
32200
-
32201
- return name + ': ' + str;
32024
+ var rawname = getName(something);
32025
+ var name = rawname ? ': ' + rawname : '';
32026
+ return '[Function' + name + ']';
32027
+ }
32028
+ function getMessage(self) {
32029
+ return truncate(inspect(self.actual), 128) + ' ' +
32030
+ self.operator + ' ' +
32031
+ truncate(inspect(self.expected), 128);
32202
32032
  }
32203
32033
 
32034
+ // At present only the three keys mentioned above are used and
32035
+ // understood by the spec. Implementations or sub modules can pass
32036
+ // other keys to the AssertionError's constructor - they will be
32037
+ // ignored.
32204
32038
 
32205
- function reduceToSingleString(output, base, braces) {
32206
- var length = output.reduce(function(prev, cur) {
32207
- if (cur.indexOf('\n') >= 0) ;
32208
- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
32209
- }, 0);
32210
-
32211
- if (length > 60) {
32212
- return braces[0] +
32213
- (base === '' ? '' : base + '\n ') +
32214
- ' ' +
32215
- output.join(',\n ') +
32216
- ' ' +
32217
- braces[1];
32218
- }
32039
+ // 3. All of the following functions must throw an AssertionError
32040
+ // when a corresponding condition is not met, with a message that
32041
+ // may be undefined if not provided. All assertion methods provide
32042
+ // both the actual and expected values to the assertion error for
32043
+ // display purposes.
32219
32044
 
32220
- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
32045
+ function fail(actual, expected, message, operator, stackStartFunction) {
32046
+ throw new AssertionError({
32047
+ message: message,
32048
+ actual: actual,
32049
+ expected: expected,
32050
+ operator: operator,
32051
+ stackStartFunction: stackStartFunction
32052
+ });
32221
32053
  }
32222
32054
 
32055
+ // EXTENSION! allows for well behaved errors defined elsewhere.
32056
+ assert.fail = fail;
32223
32057
 
32224
- // NOTE: These type checking functions intentionally don't use `instanceof`
32225
- // because it is fragile and can be easily faked with `Object.create()`.
32226
- function isArray(ar) {
32227
- return Array.isArray(ar);
32228
- }
32058
+ // 4. Pure assertion tests whether a value is truthy, as determined
32059
+ // by !!guard.
32060
+ // assert.ok(guard, message_opt);
32061
+ // This statement is equivalent to assert.equal(true, !!guard,
32062
+ // message_opt);. To test strictly for the value true, use
32063
+ // assert.strictEqual(true, guard, message_opt);.
32229
32064
 
32230
- function isBoolean(arg) {
32231
- return typeof arg === 'boolean';
32065
+ function ok(value, message) {
32066
+ if (!value) fail(value, true, message, '==', ok);
32232
32067
  }
32068
+ assert.ok = ok;
32233
32069
 
32234
- function isNull(arg) {
32235
- return arg === null;
32070
+ // 5. The equality assertion tests shallow, coercive equality with
32071
+ // ==.
32072
+ // assert.equal(actual, expected, message_opt);
32073
+ assert.equal = equal;
32074
+ function equal(actual, expected, message) {
32075
+ if (actual != expected) fail(actual, expected, message, '==', equal);
32236
32076
  }
32237
32077
 
32238
- function isNumber(arg) {
32239
- return typeof arg === 'number';
32078
+ // 6. The non-equality assertion tests for whether two objects are not equal
32079
+ // with != assert.notEqual(actual, expected, message_opt);
32080
+ assert.notEqual = notEqual;
32081
+ function notEqual(actual, expected, message) {
32082
+ if (actual == expected) {
32083
+ fail(actual, expected, message, '!=', notEqual);
32084
+ }
32240
32085
  }
32241
32086
 
32242
- function isString(arg) {
32243
- return typeof arg === 'string';
32087
+ // 7. The equivalence assertion tests a deep equality relation.
32088
+ // assert.deepEqual(actual, expected, message_opt);
32089
+ assert.deepEqual = deepEqual;
32090
+ function deepEqual(actual, expected, message) {
32091
+ if (!_deepEqual(actual, expected, false)) {
32092
+ fail(actual, expected, message, 'deepEqual', deepEqual);
32093
+ }
32244
32094
  }
32245
-
32246
- function isUndefined(arg) {
32247
- return arg === undefined;
32095
+ assert.deepStrictEqual = deepStrictEqual;
32096
+ function deepStrictEqual(actual, expected, message) {
32097
+ if (!_deepEqual(actual, expected, true)) {
32098
+ fail(actual, expected, message, 'deepStrictEqual', deepStrictEqual);
32099
+ }
32248
32100
  }
32249
32101
 
32250
- function isRegExp(re) {
32251
- return isObject(re) && objectToString(re) === '[object RegExp]';
32252
- }
32102
+ function _deepEqual(actual, expected, strict, memos) {
32103
+ // 7.1. All identical values are equivalent, as determined by ===.
32104
+ if (actual === expected) {
32105
+ return true;
32106
+ } else if (isBuffer(actual) && isBuffer(expected)) {
32107
+ return compare(actual, expected) === 0;
32253
32108
 
32254
- function isObject(arg) {
32255
- return typeof arg === 'object' && arg !== null;
32256
- }
32109
+ // 7.2. If the expected value is a Date object, the actual value is
32110
+ // equivalent if it is also a Date object that refers to the same time.
32111
+ } else if (isDate(actual) && isDate(expected)) {
32112
+ return actual.getTime() === expected.getTime();
32257
32113
 
32258
- function isDate(d) {
32259
- return isObject(d) && objectToString(d) === '[object Date]';
32260
- }
32114
+ // 7.3 If the expected value is a RegExp object, the actual value is
32115
+ // equivalent if it is also a RegExp object with the same source and
32116
+ // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
32117
+ } else if (isRegExp(actual) && isRegExp(expected)) {
32118
+ return actual.source === expected.source &&
32119
+ actual.global === expected.global &&
32120
+ actual.multiline === expected.multiline &&
32121
+ actual.lastIndex === expected.lastIndex &&
32122
+ actual.ignoreCase === expected.ignoreCase;
32261
32123
 
32262
- function isError(e) {
32263
- return isObject(e) &&
32264
- (objectToString(e) === '[object Error]' || e instanceof Error);
32265
- }
32124
+ // 7.4. Other pairs that do not both pass typeof value == 'object',
32125
+ // equivalence is determined by ==.
32126
+ } else if ((actual === null || typeof actual !== 'object') &&
32127
+ (expected === null || typeof expected !== 'object')) {
32128
+ return strict ? actual === expected : actual == expected;
32266
32129
 
32267
- function isFunction(arg) {
32268
- return typeof arg === 'function';
32269
- }
32130
+ // If both values are instances of typed arrays, wrap their underlying
32131
+ // ArrayBuffers in a Buffer each to increase performance
32132
+ // This optimization requires the arrays to have the same type as checked by
32133
+ // Object.prototype.toString (aka pToString). Never perform binary
32134
+ // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
32135
+ // bit patterns are not identical.
32136
+ } else if (isView(actual) && isView(expected) &&
32137
+ pToString(actual) === pToString(expected) &&
32138
+ !(actual instanceof Float32Array ||
32139
+ actual instanceof Float64Array)) {
32140
+ return compare(new Uint8Array(actual.buffer),
32141
+ new Uint8Array(expected.buffer)) === 0;
32270
32142
 
32271
- function isPrimitive(arg) {
32272
- return arg === null ||
32273
- typeof arg === 'boolean' ||
32274
- typeof arg === 'number' ||
32275
- typeof arg === 'string' ||
32276
- typeof arg === 'symbol' || // ES6 symbol
32277
- typeof arg === 'undefined';
32278
- }
32143
+ // 7.5 For all other Object pairs, including Array objects, equivalence is
32144
+ // determined by having the same number of owned properties (as verified
32145
+ // with Object.prototype.hasOwnProperty.call), the same set of keys
32146
+ // (although not necessarily the same order), equivalent values for every
32147
+ // corresponding key, and an identical 'prototype' property. Note: this
32148
+ // accounts for both named and indexed properties on Arrays.
32149
+ } else if (isBuffer(actual) !== isBuffer(expected)) {
32150
+ return false;
32151
+ } else {
32152
+ memos = memos || {actual: [], expected: []};
32279
32153
 
32280
- function objectToString(o) {
32281
- return Object.prototype.toString.call(o);
32282
- }
32154
+ var actualIndex = memos.actual.indexOf(actual);
32155
+ if (actualIndex !== -1) {
32156
+ if (actualIndex === memos.expected.indexOf(expected)) {
32157
+ return true;
32158
+ }
32159
+ }
32283
32160
 
32284
- function _extend(origin, add) {
32285
- // Don't do anything if add isn't an object
32286
- if (!add || !isObject(add)) return origin;
32161
+ memos.actual.push(actual);
32162
+ memos.expected.push(expected);
32287
32163
 
32288
- var keys = Object.keys(add);
32289
- var i = keys.length;
32290
- while (i--) {
32291
- origin[keys[i]] = add[keys[i]];
32164
+ return objEquiv(actual, expected, strict, memos);
32292
32165
  }
32293
- return origin;
32294
32166
  }
32295
- function hasOwnProperty(obj, prop) {
32296
- return Object.prototype.hasOwnProperty.call(obj, prop);
32167
+
32168
+ function isArguments(object) {
32169
+ return Object.prototype.toString.call(object) == '[object Arguments]';
32297
32170
  }
32298
32171
 
32299
- function compare(a, b) {
32300
- if (a === b) {
32301
- return 0;
32172
+ function objEquiv(a, b, strict, actualVisitedObjects) {
32173
+ if (a === null || a === undefined || b === null || b === undefined)
32174
+ return false;
32175
+ // if one is a primitive, the other must be same
32176
+ if (isPrimitive(a) || isPrimitive(b))
32177
+ return a === b;
32178
+ if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
32179
+ return false;
32180
+ var aIsArgs = isArguments(a);
32181
+ var bIsArgs = isArguments(b);
32182
+ if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
32183
+ return false;
32184
+ if (aIsArgs) {
32185
+ a = pSlice.call(a);
32186
+ b = pSlice.call(b);
32187
+ return _deepEqual(a, b, strict);
32302
32188
  }
32303
-
32304
- var x = a.length;
32305
- var y = b.length;
32306
-
32307
- for (var i = 0, len = Math.min(x, y); i < len; ++i) {
32308
- if (a[i] !== b[i]) {
32309
- x = a[i];
32310
- y = b[i];
32311
- break;
32312
- }
32189
+ var ka = objectKeys(a);
32190
+ var kb = objectKeys(b);
32191
+ var key, i;
32192
+ // having the same number of owned properties (keys incorporates
32193
+ // hasOwnProperty)
32194
+ if (ka.length !== kb.length)
32195
+ return false;
32196
+ //the same set of keys (although not necessarily the same order),
32197
+ ka.sort();
32198
+ kb.sort();
32199
+ //~~~cheap key test
32200
+ for (i = ka.length - 1; i >= 0; i--) {
32201
+ if (ka[i] !== kb[i])
32202
+ return false;
32313
32203
  }
32314
-
32315
- if (x < y) {
32316
- return -1;
32204
+ //equivalent values for every corresponding key, and
32205
+ //~~~possibly expensive deep test
32206
+ for (i = ka.length - 1; i >= 0; i--) {
32207
+ key = ka[i];
32208
+ if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
32209
+ return false;
32317
32210
  }
32318
- if (y < x) {
32319
- return 1;
32211
+ return true;
32212
+ }
32213
+
32214
+ // 8. The non-equivalence assertion tests for any deep inequality.
32215
+ // assert.notDeepEqual(actual, expected, message_opt);
32216
+ assert.notDeepEqual = notDeepEqual;
32217
+ function notDeepEqual(actual, expected, message) {
32218
+ if (_deepEqual(actual, expected, false)) {
32219
+ fail(actual, expected, message, 'notDeepEqual', notDeepEqual);
32320
32220
  }
32321
- return 0;
32322
32221
  }
32323
- var hasOwn = Object.prototype.hasOwnProperty;
32324
32222
 
32325
- var objectKeys = Object.keys || function (obj) {
32326
- var keys = [];
32327
- for (var key in obj) {
32328
- if (hasOwn.call(obj, key)) keys.push(key);
32223
+ assert.notDeepStrictEqual = notDeepStrictEqual;
32224
+ function notDeepStrictEqual(actual, expected, message) {
32225
+ if (_deepEqual(actual, expected, true)) {
32226
+ fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
32329
32227
  }
32330
- return keys;
32331
- };
32332
- var pSlice = Array.prototype.slice;
32333
- var _functionsHaveNames;
32334
- function functionsHaveNames() {
32335
- if (typeof _functionsHaveNames !== 'undefined') {
32336
- return _functionsHaveNames;
32228
+ }
32229
+
32230
+
32231
+ // 9. The strict equality assertion tests strict equality, as determined by ===.
32232
+ // assert.strictEqual(actual, expected, message_opt);
32233
+ assert.strictEqual = strictEqual;
32234
+ function strictEqual(actual, expected, message) {
32235
+ if (actual !== expected) {
32236
+ fail(actual, expected, message, '===', strictEqual);
32337
32237
  }
32338
- return _functionsHaveNames = (function () {
32339
- return function foo() {}.name === 'foo';
32340
- }());
32341
32238
  }
32342
- function pToString (obj) {
32343
- return Object.prototype.toString.call(obj);
32239
+
32240
+ // 10. The strict non-equality assertion tests for strict inequality, as
32241
+ // determined by !==. assert.notStrictEqual(actual, expected, message_opt);
32242
+ assert.notStrictEqual = notStrictEqual;
32243
+ function notStrictEqual(actual, expected, message) {
32244
+ if (actual === expected) {
32245
+ fail(actual, expected, message, '!==', notStrictEqual);
32246
+ }
32344
32247
  }
32345
- function isView(arrbuf) {
32346
- if (isBuffer(arrbuf)) {
32248
+
32249
+ function expectedException(actual, expected) {
32250
+ if (!actual || !expected) {
32347
32251
  return false;
32348
32252
  }
32349
- if (typeof global$1.ArrayBuffer !== 'function') {
32350
- return false;
32253
+
32254
+ if (Object.prototype.toString.call(expected) == '[object RegExp]') {
32255
+ return expected.test(actual);
32351
32256
  }
32352
- if (typeof ArrayBuffer.isView === 'function') {
32353
- return ArrayBuffer.isView(arrbuf);
32257
+
32258
+ try {
32259
+ if (actual instanceof expected) {
32260
+ return true;
32261
+ }
32262
+ } catch (e) {
32263
+ // Ignore. The instanceof check doesn't work for arrow functions.
32354
32264
  }
32355
- if (!arrbuf) {
32265
+
32266
+ if (Error.isPrototypeOf(expected)) {
32356
32267
  return false;
32357
32268
  }
32358
- if (arrbuf instanceof DataView) {
32359
- return true;
32360
- }
32361
- if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
32362
- return true;
32363
- }
32364
- return false;
32269
+
32270
+ return expected.call({}, actual) === true;
32365
32271
  }
32366
- // 1. The assert module provides functions that throw
32367
- // AssertionError's when particular conditions are not met. The
32368
- // assert module must conform to the following interface.
32369
32272
 
32370
- function assert(value, message) {
32371
- if (!value) fail(value, true, message, '==', ok);
32273
+ function _tryBlock(block) {
32274
+ var error;
32275
+ try {
32276
+ block();
32277
+ } catch (e) {
32278
+ error = e;
32279
+ }
32280
+ return error;
32372
32281
  }
32373
32282
 
32374
- // 2. The AssertionError is defined in assert.
32375
- // new assert.AssertionError({ message: message,
32376
- // actual: actual,
32377
- // expected: expected })
32283
+ function _throws(shouldThrow, block, expected, message) {
32284
+ var actual;
32378
32285
 
32379
- var regex = /\s*function\s+([^\(\s]*)\s*/;
32380
- // based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
32381
- function getName(func) {
32382
- if (!isFunction(func)) {
32383
- return;
32286
+ if (typeof block !== 'function') {
32287
+ throw new TypeError('"block" argument must be a function');
32384
32288
  }
32385
- if (functionsHaveNames()) {
32386
- return func.name;
32289
+
32290
+ if (typeof expected === 'string') {
32291
+ message = expected;
32292
+ expected = null;
32387
32293
  }
32388
- var str = func.toString();
32389
- var match = str.match(regex);
32390
- return match && match[1];
32391
- }
32392
- assert.AssertionError = AssertionError;
32393
- function AssertionError(options) {
32394
- this.name = 'AssertionError';
32395
- this.actual = options.actual;
32396
- this.expected = options.expected;
32397
- this.operator = options.operator;
32398
- if (options.message) {
32399
- this.message = options.message;
32400
- this.generatedMessage = false;
32401
- } else {
32402
- this.message = getMessage(this);
32403
- this.generatedMessage = true;
32404
- }
32405
- var stackStartFunction = options.stackStartFunction || fail;
32406
- if (Error.captureStackTrace) {
32407
- Error.captureStackTrace(this, stackStartFunction);
32408
- } else {
32409
- // non v8 browsers so we can have a stacktrace
32410
- var err = new Error();
32411
- if (err.stack) {
32412
- var out = err.stack;
32413
-
32414
- // try to strip useless frames
32415
- var fn_name = getName(stackStartFunction);
32416
- var idx = out.indexOf('\n' + fn_name);
32417
- if (idx >= 0) {
32418
- // once we have located the function frame
32419
- // we need to strip out everything before it (and its line)
32420
- var next_line = out.indexOf('\n', idx + 1);
32421
- out = out.substring(next_line + 1);
32422
- }
32423
32294
 
32424
- this.stack = out;
32425
- }
32426
- }
32427
- }
32295
+ actual = _tryBlock(block);
32428
32296
 
32429
- // assert.AssertionError instanceof Error
32430
- inherits(AssertionError, Error);
32297
+ message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
32298
+ (message ? ' ' + message : '.');
32431
32299
 
32432
- function truncate(s, n) {
32433
- if (typeof s === 'string') {
32434
- return s.length < n ? s : s.slice(0, n);
32435
- } else {
32436
- return s;
32437
- }
32438
- }
32439
- function inspect(something) {
32440
- if (functionsHaveNames() || !isFunction(something)) {
32441
- return inspect$1(something);
32300
+ if (shouldThrow && !actual) {
32301
+ fail(actual, expected, 'Missing expected exception' + message);
32442
32302
  }
32443
- var rawname = getName(something);
32444
- var name = rawname ? ': ' + rawname : '';
32445
- return '[Function' + name + ']';
32446
- }
32447
- function getMessage(self) {
32448
- return truncate(inspect(self.actual), 128) + ' ' +
32449
- self.operator + ' ' +
32450
- truncate(inspect(self.expected), 128);
32451
- }
32452
-
32453
- // At present only the three keys mentioned above are used and
32454
- // understood by the spec. Implementations or sub modules can pass
32455
- // other keys to the AssertionError's constructor - they will be
32456
- // ignored.
32457
-
32458
- // 3. All of the following functions must throw an AssertionError
32459
- // when a corresponding condition is not met, with a message that
32460
- // may be undefined if not provided. All assertion methods provide
32461
- // both the actual and expected values to the assertion error for
32462
- // display purposes.
32463
-
32464
- function fail(actual, expected, message, operator, stackStartFunction) {
32465
- throw new AssertionError({
32466
- message: message,
32467
- actual: actual,
32468
- expected: expected,
32469
- operator: operator,
32470
- stackStartFunction: stackStartFunction
32471
- });
32472
- }
32473
-
32474
- // EXTENSION! allows for well behaved errors defined elsewhere.
32475
- assert.fail = fail;
32476
-
32477
- // 4. Pure assertion tests whether a value is truthy, as determined
32478
- // by !!guard.
32479
- // assert.ok(guard, message_opt);
32480
- // This statement is equivalent to assert.equal(true, !!guard,
32481
- // message_opt);. To test strictly for the value true, use
32482
- // assert.strictEqual(true, guard, message_opt);.
32483
-
32484
- function ok(value, message) {
32485
- if (!value) fail(value, true, message, '==', ok);
32486
- }
32487
- assert.ok = ok;
32488
32303
 
32489
- // 5. The equality assertion tests shallow, coercive equality with
32490
- // ==.
32491
- // assert.equal(actual, expected, message_opt);
32492
- assert.equal = equal;
32493
- function equal(actual, expected, message) {
32494
- if (actual != expected) fail(actual, expected, message, '==', equal);
32495
- }
32304
+ var userProvidedMessage = typeof message === 'string';
32305
+ var isUnwantedException = !shouldThrow && isError(actual);
32306
+ var isUnexpectedException = !shouldThrow && actual && !expected;
32496
32307
 
32497
- // 6. The non-equality assertion tests for whether two objects are not equal
32498
- // with != assert.notEqual(actual, expected, message_opt);
32499
- assert.notEqual = notEqual;
32500
- function notEqual(actual, expected, message) {
32501
- if (actual == expected) {
32502
- fail(actual, expected, message, '!=', notEqual);
32308
+ if ((isUnwantedException &&
32309
+ userProvidedMessage &&
32310
+ expectedException(actual, expected)) ||
32311
+ isUnexpectedException) {
32312
+ fail(actual, expected, 'Got unwanted exception' + message);
32503
32313
  }
32504
- }
32505
32314
 
32506
- // 7. The equivalence assertion tests a deep equality relation.
32507
- // assert.deepEqual(actual, expected, message_opt);
32508
- assert.deepEqual = deepEqual;
32509
- function deepEqual(actual, expected, message) {
32510
- if (!_deepEqual(actual, expected, false)) {
32511
- fail(actual, expected, message, 'deepEqual', deepEqual);
32512
- }
32513
- }
32514
- assert.deepStrictEqual = deepStrictEqual;
32515
- function deepStrictEqual(actual, expected, message) {
32516
- if (!_deepEqual(actual, expected, true)) {
32517
- fail(actual, expected, message, 'deepStrictEqual', deepStrictEqual);
32315
+ if ((shouldThrow && actual && expected &&
32316
+ !expectedException(actual, expected)) || (!shouldThrow && actual)) {
32317
+ throw actual;
32518
32318
  }
32519
32319
  }
32520
32320
 
32521
- function _deepEqual(actual, expected, strict, memos) {
32522
- // 7.1. All identical values are equivalent, as determined by ===.
32523
- if (actual === expected) {
32524
- return true;
32525
- } else if (isBuffer(actual) && isBuffer(expected)) {
32526
- return compare(actual, expected) === 0;
32527
-
32528
- // 7.2. If the expected value is a Date object, the actual value is
32529
- // equivalent if it is also a Date object that refers to the same time.
32530
- } else if (isDate(actual) && isDate(expected)) {
32531
- return actual.getTime() === expected.getTime();
32532
-
32533
- // 7.3 If the expected value is a RegExp object, the actual value is
32534
- // equivalent if it is also a RegExp object with the same source and
32535
- // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
32536
- } else if (isRegExp(actual) && isRegExp(expected)) {
32537
- return actual.source === expected.source &&
32538
- actual.global === expected.global &&
32539
- actual.multiline === expected.multiline &&
32540
- actual.lastIndex === expected.lastIndex &&
32541
- actual.ignoreCase === expected.ignoreCase;
32542
-
32543
- // 7.4. Other pairs that do not both pass typeof value == 'object',
32544
- // equivalence is determined by ==.
32545
- } else if ((actual === null || typeof actual !== 'object') &&
32546
- (expected === null || typeof expected !== 'object')) {
32547
- return strict ? actual === expected : actual == expected;
32548
-
32549
- // If both values are instances of typed arrays, wrap their underlying
32550
- // ArrayBuffers in a Buffer each to increase performance
32551
- // This optimization requires the arrays to have the same type as checked by
32552
- // Object.prototype.toString (aka pToString). Never perform binary
32553
- // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
32554
- // bit patterns are not identical.
32555
- } else if (isView(actual) && isView(expected) &&
32556
- pToString(actual) === pToString(expected) &&
32557
- !(actual instanceof Float32Array ||
32558
- actual instanceof Float64Array)) {
32559
- return compare(new Uint8Array(actual.buffer),
32560
- new Uint8Array(expected.buffer)) === 0;
32561
-
32562
- // 7.5 For all other Object pairs, including Array objects, equivalence is
32563
- // determined by having the same number of owned properties (as verified
32564
- // with Object.prototype.hasOwnProperty.call), the same set of keys
32565
- // (although not necessarily the same order), equivalent values for every
32566
- // corresponding key, and an identical 'prototype' property. Note: this
32567
- // accounts for both named and indexed properties on Arrays.
32568
- } else if (isBuffer(actual) !== isBuffer(expected)) {
32569
- return false;
32570
- } else {
32571
- memos = memos || {actual: [], expected: []};
32572
-
32573
- var actualIndex = memos.actual.indexOf(actual);
32574
- if (actualIndex !== -1) {
32575
- if (actualIndex === memos.expected.indexOf(expected)) {
32576
- return true;
32577
- }
32578
- }
32579
-
32580
- memos.actual.push(actual);
32581
- memos.expected.push(expected);
32582
-
32583
- return objEquiv(actual, expected, strict, memos);
32584
- }
32321
+ // 11. Expected to throw an error:
32322
+ // assert.throws(block, Error_opt, message_opt);
32323
+ assert.throws = throws;
32324
+ function throws(block, /*optional*/error, /*optional*/message) {
32325
+ _throws(true, block, error, message);
32585
32326
  }
32586
32327
 
32587
- function isArguments(object) {
32588
- return Object.prototype.toString.call(object) == '[object Arguments]';
32328
+ // EXTENSION! This is annoying to write outside this module.
32329
+ assert.doesNotThrow = doesNotThrow;
32330
+ function doesNotThrow(block, /*optional*/error, /*optional*/message) {
32331
+ _throws(false, block, error, message);
32589
32332
  }
32590
32333
 
32591
- function objEquiv(a, b, strict, actualVisitedObjects) {
32592
- if (a === null || a === undefined || b === null || b === undefined)
32593
- return false;
32594
- // if one is a primitive, the other must be same
32595
- if (isPrimitive(a) || isPrimitive(b))
32596
- return a === b;
32597
- if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
32598
- return false;
32599
- var aIsArgs = isArguments(a);
32600
- var bIsArgs = isArguments(b);
32601
- if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
32602
- return false;
32603
- if (aIsArgs) {
32604
- a = pSlice.call(a);
32605
- b = pSlice.call(b);
32606
- return _deepEqual(a, b, strict);
32607
- }
32608
- var ka = objectKeys(a);
32609
- var kb = objectKeys(b);
32610
- var key, i;
32611
- // having the same number of owned properties (keys incorporates
32612
- // hasOwnProperty)
32613
- if (ka.length !== kb.length)
32614
- return false;
32615
- //the same set of keys (although not necessarily the same order),
32616
- ka.sort();
32617
- kb.sort();
32618
- //~~~cheap key test
32619
- for (i = ka.length - 1; i >= 0; i--) {
32620
- if (ka[i] !== kb[i])
32621
- return false;
32622
- }
32623
- //equivalent values for every corresponding key, and
32624
- //~~~possibly expensive deep test
32625
- for (i = ka.length - 1; i >= 0; i--) {
32626
- key = ka[i];
32627
- if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
32628
- return false;
32629
- }
32630
- return true;
32334
+ assert.ifError = ifError;
32335
+ function ifError(err) {
32336
+ if (err) throw err;
32631
32337
  }
32632
32338
 
32633
- // 8. The non-equivalence assertion tests for any deep inequality.
32634
- // assert.notDeepEqual(actual, expected, message_opt);
32635
- assert.notDeepEqual = notDeepEqual;
32636
- function notDeepEqual(actual, expected, message) {
32637
- if (_deepEqual(actual, expected, false)) {
32638
- fail(actual, expected, message, 'notDeepEqual', notDeepEqual);
32639
- }
32640
- }
32641
-
32642
- assert.notDeepStrictEqual = notDeepStrictEqual;
32643
- function notDeepStrictEqual(actual, expected, message) {
32644
- if (_deepEqual(actual, expected, true)) {
32645
- fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
32646
- }
32647
- }
32648
-
32649
-
32650
- // 9. The strict equality assertion tests strict equality, as determined by ===.
32651
- // assert.strictEqual(actual, expected, message_opt);
32652
- assert.strictEqual = strictEqual;
32653
- function strictEqual(actual, expected, message) {
32654
- if (actual !== expected) {
32655
- fail(actual, expected, message, '===', strictEqual);
32656
- }
32339
+ const VERSION$6 = '0.0.1';
32340
+ // const T = 'plugins.audio_selector';
32341
+ const AUTO = 0;
32342
+ /**
32343
+ * Adds an audio track selector to the media control UI.
32344
+ * @beta
32345
+ */
32346
+ class AudioSelector extends UICorePlugin {
32347
+ // TODO
32348
+ selectedTrackId;
32349
+ currentTrack = null;
32350
+ tracks = [];
32351
+ /**
32352
+ * @internal
32353
+ */
32354
+ get name() {
32355
+ return 'audio_selector';
32356
+ }
32357
+ /**
32358
+ * @internal
32359
+ */
32360
+ get supportedVersion() {
32361
+ return { min: CLAPPR_VERSION };
32362
+ }
32363
+ /**
32364
+ * @internal
32365
+ */
32366
+ static get version() {
32367
+ return VERSION$6;
32368
+ }
32369
+ static template = tmpl(pluginHtml$8);
32370
+ /**
32371
+ * @internal
32372
+ */
32373
+ get attributes() {
32374
+ return {
32375
+ class: this.name,
32376
+ 'data-track-selector': '',
32377
+ };
32378
+ }
32379
+ /**
32380
+ * @internal
32381
+ */
32382
+ get events() {
32383
+ return {
32384
+ 'click [data-track-selector-select]': 'onTrackSelect',
32385
+ 'click [data-track-selector-button]': 'onShowLevelSelectMenu',
32386
+ };
32387
+ }
32388
+ /**
32389
+ * @internal
32390
+ */
32391
+ bindEvents() {
32392
+ this.listenTo(this.core, Events$1.CORE_READY, this.bindPlaybackEvents);
32393
+ // TODO CORE_ACTIVE_CONTAINER_CHANGED
32394
+ this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.reload);
32395
+ this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.render);
32396
+ this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_HIDE, this.hideSelectTrackMenu);
32397
+ }
32398
+ unBindEvents() {
32399
+ // @ts-ignore
32400
+ this.stopListening(this.core, Events$1.CORE_READY);
32401
+ // @ts-ignore
32402
+ this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED);
32403
+ // @ts-ignore
32404
+ this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED);
32405
+ // @ts-ignore
32406
+ this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_HIDE);
32407
+ }
32408
+ bindPlaybackEvents() {
32409
+ // this.currentTrack = {};
32410
+ // this.removeAuto = false;
32411
+ this.selectedTrackId = undefined;
32412
+ const currentPlayback = this.core.activePlayback;
32413
+ this.listenTo(currentPlayback, Events$1.PLAYBACK_STOP, this.onStop);
32414
+ this.setupAudioTrackListeners();
32415
+ }
32416
+ setupAudioTrackListeners() {
32417
+ const currentPlayback = this.core.activePlayback;
32418
+ // TODO no-crutch:currentPlayback._hls
32419
+ if (currentPlayback._hls) {
32420
+ // TODO AUDIO_TRACKS_UPDATED
32421
+ // currentPlayback._hls.on('hlsAudioTracksUpdated', (e, data) => {
32422
+ currentPlayback._hls.on(Events.AUDIO_TRACKS_UPDATED, (e, data) => {
32423
+ // let id = -1;
32424
+ // for (const audioTrack of data.audioTracks) {
32425
+ // if (audioTrack.default) {
32426
+ // id = audioTrack.id;
32427
+ // this.currentTrack = audioTrack;
32428
+ // }
32429
+ // }
32430
+ const defaultTrack = data.audioTracks.find((track) => track.default);
32431
+ if (defaultTrack) {
32432
+ this.currentTrack = {
32433
+ id: defaultTrack.id,
32434
+ label: defaultTrack.name,
32435
+ };
32436
+ }
32437
+ this.fillTracks(data.audioTracks.map((p) => ({
32438
+ id: p.id,
32439
+ label: p.name,
32440
+ })), defaultTrack?.id);
32441
+ });
32442
+ currentPlayback._hls.on(Events.AUDIO_TRACK_SWITCHING, this.startTrackSwitch.bind(this));
32443
+ currentPlayback._hls.on(Events.AUDIO_TRACK_SWITCHED, this.updateCurrentTrack.bind(this));
32444
+ currentPlayback._hls.on(Events.AUDIO_TRACK_LOADED, this.updateCurrentTrack.bind(this));
32445
+ }
32446
+ else {
32447
+ this.listenToOnce(currentPlayback, Events$1.PLAYBACK_PLAY, () => {
32448
+ const mediaElement = currentPlayback.$el.get(0);
32449
+ // const { audioTracks } = currentPlayback.$el.get(0);
32450
+ const audioTracks = mediaElement.audioTracks;
32451
+ if (audioTracks && audioTracks.length) {
32452
+ let index = 0;
32453
+ const trackItems = [];
32454
+ for (const audioTrack of audioTracks) {
32455
+ if (audioTrack.enabled) {
32456
+ const t = {
32457
+ id: index,
32458
+ label: audioTrack.label,
32459
+ };
32460
+ this.currentTrack = t;
32461
+ trackItems.push(t);
32462
+ index++;
32463
+ }
32464
+ }
32465
+ audioTracks.addEventListener('change', () => this.updateCurrentTrackW3C());
32466
+ this.fillTracks(trackItems, trackItems[0].id);
32467
+ }
32468
+ });
32469
+ }
32470
+ }
32471
+ onStop() { }
32472
+ reload() {
32473
+ this.unBindEvents();
32474
+ this.bindEvents();
32475
+ this.bindPlaybackEvents();
32476
+ }
32477
+ shouldRender() {
32478
+ if (!this.core.activeContainer) {
32479
+ return false;
32480
+ }
32481
+ const currentPlayback = this.core.activePlayback;
32482
+ if (!currentPlayback) {
32483
+ return false;
32484
+ }
32485
+ const { audioTracks } = currentPlayback.activePlayback._hls || currentPlayback.$el.get(0);
32486
+ this.tracks = audioTracks;
32487
+ // Only care if we have at least 2 to choose from
32488
+ return this.tracks && this.tracks.length > 1;
32489
+ }
32490
+ /**
32491
+ * @internal
32492
+ */
32493
+ render() {
32494
+ if (!this.shouldRender()) {
32495
+ return this;
32496
+ }
32497
+ const mediaControl = this.core.getPlugin('media_control');
32498
+ assert(mediaControl, 'media_control plugin is required');
32499
+ this.$el.html(AudioSelector.template({ tracks: this.tracks, title: this.getTitle() }));
32500
+ const ats = mediaControl.getElement('audioTracksSelector');
32501
+ if (!(ats && ats.length > 0)) {
32502
+ return this;
32503
+ }
32504
+ ats.append(this.el);
32505
+ this.highlightCurrentTrack();
32506
+ const aa = ats.find('audioArrow');
32507
+ if (aa.length > 0) {
32508
+ aa.append(audioArrow);
32509
+ }
32510
+ return this;
32511
+ }
32512
+ fillTracks(tracks, selected = AUTO) {
32513
+ if (this.selectedTrackId === undefined) {
32514
+ this.selectedTrackId = selected;
32515
+ }
32516
+ // this.tracks = levels.audioTracks;
32517
+ // for (let i = 0; i < this.tracks.length; i++) {
32518
+ // if (this.tracks[i].name && !this.tracks[i].label) {
32519
+ // this.tracks[i].label = this.tracks[i].name;
32520
+ // }
32521
+ // }
32522
+ this.tracks = tracks;
32523
+ // Player.player.trigger('tracks', this.tracks);
32524
+ // this.core.trigger('tracks', this.tracks);
32525
+ this.render();
32526
+ }
32527
+ findTrackBy(id) {
32528
+ return this.tracks.find((track) => track.id === id);
32529
+ }
32530
+ onTrackSelect(event) {
32531
+ // this.selectedTrackId = parseInt(event.target.dataset.levelSelectorSelect, 10)
32532
+ const id = event.target?.dataset?.trackSelectorSelect;
32533
+ if (id) {
32534
+ this.setIndexTrack(Number(id));
32535
+ }
32536
+ this.toggleContextMenu();
32537
+ event.stopPropagation();
32538
+ return false;
32539
+ }
32540
+ setIndexTrack(index) {
32541
+ this.selectedTrackId = index;
32542
+ if (this.core.activePlayback._hls) {
32543
+ if (this.core.activePlayback._hls.audioTrack.id === this.selectedTrackId) {
32544
+ return;
32545
+ }
32546
+ this.core.activePlayback._hls.audioTrack = this.selectedTrackId;
32547
+ }
32548
+ else {
32549
+ const { audioTracks } = this.core.activePlayback.$el.get(0);
32550
+ for (const track of audioTracks) {
32551
+ track.enabled = track.id === this.selectedTrackId;
32552
+ }
32553
+ }
32554
+ this.updateText(this.selectedTrackId);
32555
+ }
32556
+ onShowLevelSelectMenu() {
32557
+ this.toggleContextMenu();
32558
+ }
32559
+ hideSelectTrackMenu() {
32560
+ this.$('.audio_selector ul').hide();
32561
+ }
32562
+ toggleContextMenu() {
32563
+ this.$('.audio_selector ul').toggle();
32564
+ }
32565
+ buttonElement() {
32566
+ return this.$('.audio_selector button');
32567
+ }
32568
+ buttonElementText() {
32569
+ return this.$('.audio_selector button .audio-text');
32570
+ }
32571
+ trackElement(id) {
32572
+ return this.$('.audio_selector ul a' +
32573
+ (id !== undefined ? '[data-track-selector-select="' + id + '"]' : '')).parent();
32574
+ }
32575
+ getTitle() {
32576
+ if (!this.tracks) {
32577
+ return '';
32578
+ }
32579
+ const selectedTrackId = this.selectedTrackId || 0;
32580
+ const selectedTrack = this.tracks[selectedTrackId];
32581
+ return selectedTrack?.label || '';
32582
+ }
32583
+ startTrackSwitch() {
32584
+ this.buttonElement().addClass('changing');
32585
+ }
32586
+ updateText(trackId) {
32587
+ if (trackId === undefined) {
32588
+ return;
32589
+ }
32590
+ const track = this.findTrackBy(trackId);
32591
+ if (track) {
32592
+ this.buttonElementText().text(track.label);
32593
+ }
32594
+ }
32595
+ updateCurrentTrack(e, info) {
32596
+ // if (!info) {
32597
+ // const { audioTracks } = this.core.activePlayback.$el.get(0);
32598
+ // for (const track of audioTracks) {
32599
+ // if (track.enabled) {
32600
+ // info = track;
32601
+ // }
32602
+ // }
32603
+ // }
32604
+ // if (!info) {
32605
+ // return;
32606
+ // }
32607
+ // const track = this.findTrackBy(info.id);
32608
+ // this.currentTrack = track ? track : null;
32609
+ // this.selectedTrackId = track?.id;
32610
+ // this.highlightCurrentTrack();
32611
+ // this.buttonElement().removeClass('changing');
32612
+ this.setCurrentTrack(info.id);
32613
+ }
32614
+ updateCurrentTrackW3C() {
32615
+ const { audioTracks } = this.core.activePlayback.$el.get(0);
32616
+ const index = audioTracks.findIndex((track) => track.enabled);
32617
+ if (index >= 0) {
32618
+ this.setCurrentTrack(index);
32619
+ }
32620
+ }
32621
+ setCurrentTrack(index) {
32622
+ const track = this.findTrackBy(index);
32623
+ this.currentTrack = track ?? null;
32624
+ this.selectedTrackId = index;
32625
+ this.highlightCurrentTrack();
32626
+ this.buttonElement().removeClass('changing');
32627
+ }
32628
+ highlightCurrentTrack() {
32629
+ this.trackElement().removeClass('current');
32630
+ this.trackElement().find('a').removeClass('gcore-skin-active');
32631
+ if (this.currentTrack) {
32632
+ const currentTrackElement = this.trackElement(this.currentTrack.id);
32633
+ currentTrackElement.addClass('current');
32634
+ currentTrackElement.find('a').addClass('gcore-skin-active');
32635
+ }
32636
+ this.updateText(this.selectedTrackId);
32637
+ }
32657
32638
  }
32658
32639
 
32659
- // 10. The strict non-equality assertion tests for strict inequality, as
32660
- // determined by !==. assert.notStrictEqual(actual, expected, message_opt);
32661
- assert.notStrictEqual = notStrictEqual;
32662
- function notStrictEqual(actual, expected, message) {
32663
- if (actual === expected) {
32664
- fail(actual, expected, message, '!==', notStrictEqual);
32665
- }
32640
+ /**
32641
+ * @public
32642
+ * @param msg
32643
+ * @param data
32644
+ */
32645
+ function trace(msg, data = {}) {
32666
32646
  }
32667
32647
 
32668
- function expectedException(actual, expected) {
32669
- if (!actual || !expected) {
32670
- return false;
32671
- }
32648
+ const volumeOffIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.50025 8.00025C4.67125 8.00025 4.00025 8.67225 4.00025 9.50025V14.5003C4.00025 15.3283 4.67125 16.0003 5.50025 16.0003H7.24824C7.65024 16.0003 8.03627 16.1613 8.31727 16.4483L12.5443 20.7413C12.7083 20.9073 12.9262 20.9963 13.1492 20.9963C13.2572 20.9963 13.3672 20.9763 13.4722 20.9333C13.7932 20.8013 14.0003 20.4923 14.0003 20.1462V16.3283C14.0003 16.1963 13.9473 16.0683 13.8543 15.9753L6.02528 8.14625C5.93228 8.05325 5.80425 8.00025 5.67225 8.00025H5.50025ZM14.0003 3.85426C14.0003 3.50826 13.7932 3.19927 13.4722 3.06727C13.1502 2.93627 12.7873 3.01226 12.5443 3.25926L9.33827 6.51527C9.14627 6.71127 9.14626 7.02625 9.34126 7.22025L13.5733 11.4522C13.7313 11.6102 14.0003 11.4982 14.0003 11.2752V3.85426ZM20.8543 20.8543C20.7563 20.9513 20.6283 21.0003 20.5003 21.0003C20.3723 21.0003 20.2442 20.9513 20.1462 20.8543L3.14625 3.85426C2.95125 3.65826 2.95125 3.34225 3.14625 3.14625C3.34225 2.95125 3.65826 2.95125 3.85426 3.14625L20.8543 20.1462C21.0493 20.3422 21.0493 20.6583 20.8543 20.8543Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
32672
32649
 
32673
- if (Object.prototype.toString.call(expected) == '[object RegExp]') {
32674
- return expected.test(actual);
32675
- }
32650
+ const pluginHtml$7 = "<div class=\"big-mute-icon-wrapper\" data-big-mute>\n <div class=\"big-mute-icon gcore-skin-border-color\" data-big-mute-icon></div>\n</div>\n";
32676
32651
 
32677
- try {
32678
- if (actual instanceof expected) {
32679
- return true;
32652
+ const T$9 = 'plugins.big_mute_button';
32653
+ // TODO rewrite as a container plugin
32654
+ /**
32655
+ * Displays a big mute button over the video when it's muted.
32656
+ * Once pressed, it unmutes the video.
32657
+ * @beta
32658
+ */
32659
+ class BigMuteButton extends UICorePlugin {
32660
+ isBigMuteButtonHidden = false;
32661
+ _adIsPlaying = false;
32662
+ $bigMuteBtnContainer = null;
32663
+ $bigMuteButton = null;
32664
+ /**
32665
+ * @internal
32666
+ */
32667
+ get name() {
32668
+ return 'big_mute_button';
32669
+ }
32670
+ /**
32671
+ * @internal
32672
+ */
32673
+ get supportedVersion() {
32674
+ return { min: CLAPPR_VERSION };
32675
+ }
32676
+ static template = tmpl(pluginHtml$7);
32677
+ /**
32678
+ * @internal
32679
+ */
32680
+ get events() {
32681
+ return {
32682
+ 'click .big-mute-icon': 'handleBigMuteBtnClick',
32683
+ 'click .big-mute-icon-wrapper': 'destroyBigMuteBtn',
32684
+ };
32685
+ }
32686
+ /**
32687
+ * @internal
32688
+ */
32689
+ bindEvents() {
32690
+ super.bindEvents();
32691
+ this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
32692
+ this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
32693
+ this.listenTo(this.core, 'core:advertisement:finish', this.onFinishAd);
32694
+ trace(`${T$9} bindEvents`, {
32695
+ mediacontrol: !!this.core.mediaControl,
32696
+ });
32697
+ this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.mediaControlRendered);
32698
+ }
32699
+ onCoreReady() {
32700
+ this.listenTo(this.core.activeContainer, Events$1.CONTAINER_VOLUME, this.onContainerVolume);
32701
+ this.listenTo(this.core.activeContainer, Events$1.CONTAINER_READY, this.onContainerStart);
32702
+ this.listenTo(this.core.activePlayback, Events$1.PLAYBACK_ENDED, this.onPlaybackEnded);
32703
+ }
32704
+ onContainerVolume(value) {
32705
+ if (value !== 0) {
32706
+ this.destroyBigMuteBtn();
32707
+ }
32708
+ }
32709
+ onContainerStart() {
32710
+ if (this.isBigMuteButtonHidden) {
32711
+ this.showBigMuteBtn();
32712
+ }
32713
+ }
32714
+ onPlaybackEnded() {
32715
+ this.hideBigMuteBtn();
32716
+ }
32717
+ mediaControlRendered() {
32718
+ const container = this.core.activeContainer;
32719
+ if (container) {
32720
+ this.listenTo(container.playback, Events$1.PLAYBACK_PLAY, () => {
32721
+ this.render();
32722
+ });
32723
+ }
32724
+ }
32725
+ onStartAd() {
32726
+ this._adIsPlaying = true;
32727
+ if (this.$bigMuteBtnContainer) {
32728
+ this.$bigMuteBtnContainer.addClass('hide');
32729
+ }
32730
+ }
32731
+ onFinishAd() {
32732
+ this._adIsPlaying = false;
32733
+ if (this.$bigMuteBtnContainer) {
32734
+ this.$bigMuteBtnContainer.removeClass('hide');
32735
+ }
32736
+ }
32737
+ shouldRender() {
32738
+ const container = this.core.activeContainer;
32739
+ if (!container) {
32740
+ return false;
32741
+ }
32742
+ const { autoPlay, wasMuted } = this.options;
32743
+ const volume = container.volume;
32744
+ return autoPlay && !wasMuted && volume === 0;
32745
+ }
32746
+ /**
32747
+ * @internal
32748
+ */
32749
+ render() {
32750
+ if (this.shouldRender()) {
32751
+ trace(`${T$9} render`, {
32752
+ el: !!this.$el,
32753
+ });
32754
+ this.$el.html(BigMuteButton.template());
32755
+ this.$bigMuteBtnContainer = this.$el.find('.big-mute-icon-wrapper[data-big-mute]');
32756
+ this._adIsPlaying && this.$bigMuteBtnContainer.addClass('hide');
32757
+ this.$bigMuteButton = this.$bigMuteBtnContainer.find('.big-mute-icon');
32758
+ this.$bigMuteButton.append(volumeOffIcon);
32759
+ const container = this.core.activeContainer;
32760
+ container.$el.append(this.$el.get(0));
32761
+ }
32762
+ return this;
32763
+ }
32764
+ hideBigMuteBtn() {
32765
+ this.isBigMuteButtonHidden = true;
32766
+ this.$bigMuteBtnContainer?.addClass('hide');
32767
+ }
32768
+ showBigMuteBtn() {
32769
+ this.isBigMuteButtonHidden = false;
32770
+ if (this.$bigMuteBtnContainer) {
32771
+ this.$bigMuteBtnContainer.removeClass('hide');
32772
+ }
32773
+ }
32774
+ destroyBigMuteBtn(e) {
32775
+ this.hideBigMuteBtn();
32776
+ if (e && e.stopPropagation) {
32777
+ e.stopPropagation();
32778
+ }
32779
+ this.destroy();
32780
+ }
32781
+ handleBigMuteBtnClick(e) {
32782
+ const localVolume = Utils.Config.restore('volume');
32783
+ const volume = !isNaN(localVolume) ? localVolume : 100;
32784
+ // TODO use container.setVolume() instead
32785
+ this.core.mediaControl.setVolume(volume === 0 ? 100 : volume);
32786
+ this.destroyBigMuteBtn(e);
32680
32787
  }
32681
- } catch (e) {
32682
- // Ignore. The instanceof check doesn't work for arrow functions.
32683
- }
32684
-
32685
- if (Error.isPrototypeOf(expected)) {
32686
- return false;
32687
- }
32688
-
32689
- return expected.call({}, actual) === true;
32690
- }
32691
-
32692
- function _tryBlock(block) {
32693
- var error;
32694
- try {
32695
- block();
32696
- } catch (e) {
32697
- error = e;
32698
- }
32699
- return error;
32700
- }
32701
-
32702
- function _throws(shouldThrow, block, expected, message) {
32703
- var actual;
32704
-
32705
- if (typeof block !== 'function') {
32706
- throw new TypeError('"block" argument must be a function');
32707
- }
32708
-
32709
- if (typeof expected === 'string') {
32710
- message = expected;
32711
- expected = null;
32712
- }
32713
-
32714
- actual = _tryBlock(block);
32715
-
32716
- message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
32717
- (message ? ' ' + message : '.');
32718
-
32719
- if (shouldThrow && !actual) {
32720
- fail(actual, expected, 'Missing expected exception' + message);
32721
- }
32722
-
32723
- var userProvidedMessage = typeof message === 'string';
32724
- var isUnwantedException = !shouldThrow && isError(actual);
32725
- var isUnexpectedException = !shouldThrow && actual && !expected;
32726
-
32727
- if ((isUnwantedException &&
32728
- userProvidedMessage &&
32729
- expectedException(actual, expected)) ||
32730
- isUnexpectedException) {
32731
- fail(actual, expected, 'Got unwanted exception' + message);
32732
- }
32733
-
32734
- if ((shouldThrow && actual && expected &&
32735
- !expectedException(actual, expected)) || (!shouldThrow && actual)) {
32736
- throw actual;
32737
- }
32738
- }
32739
-
32740
- // 11. Expected to throw an error:
32741
- // assert.throws(block, Error_opt, message_opt);
32742
- assert.throws = throws;
32743
- function throws(block, /*optional*/error, /*optional*/message) {
32744
- _throws(true, block, error, message);
32745
- }
32746
-
32747
- // EXTENSION! This is annoying to write outside this module.
32748
- assert.doesNotThrow = doesNotThrow;
32749
- function doesNotThrow(block, /*optional*/error, /*optional*/message) {
32750
- _throws(false, block, error, message);
32751
- }
32752
-
32753
- assert.ifError = ifError;
32754
- function ifError(err) {
32755
- if (err) throw err;
32756
32788
  }
32757
32789
 
32758
32790
  const pluginHtml$6 = "<div class=\"media-control-gear\" data-<%= name %>>\n <button type=\"button\" class=\"button-gear gplayer-lite-btn gcore-skin-button-color\" data-gear-button=\"-1\">\n <span class=\"gear-icon\"><%= icon %></span>\n </button>\n <div class=\"gear-wrapper gcore-skin-bg-color\">\n <ul class=\"gear-options-list\">\n <% items.forEach(function (gear) { %>\n <li data-<%= gear %>></li>\n <% }); %>\n </ul>\n </div>\n</div>\n";
@@ -32764,6 +32796,7 @@ const gearHdIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\
32764
32796
  const VERSION$5 = '2.19.12';
32765
32797
  /**
32766
32798
  * Custom events emitted by the plugin
32799
+ * @beta
32767
32800
  */
32768
32801
  var GearEvents;
32769
32802
  (function (GearEvents) {
@@ -33963,6 +33996,9 @@ function requireMousetrap () {
33963
33996
  var mousetrapExports = requireMousetrap();
33964
33997
  const Mousetrap = /*@__PURE__*/getDefaultExportFromCjs(mousetrapExports);
33965
33998
 
33999
+ /**
34000
+ * @beta
34001
+ */
33966
34002
  var ClapprStatsEvents;
33967
34003
  (function (ClapprStatsEvents) {
33968
34004
  ClapprStatsEvents["REPORT_EVENT"] = "clappr:stats:report";
@@ -34962,7 +34998,7 @@ const qualityClasses = [
34962
34998
  'speedtest-quality-value-2',
34963
34999
  'speedtest-quality-value-3',
34964
35000
  'speedtest-quality-value-4',
34965
- 'speedtest-quality-value-5'
35001
+ 'speedtest-quality-value-5',
34966
35002
  ];
34967
35003
  const getDownloadQuality = (speedValue) => {
34968
35004
  if (speedValue < 3) {
@@ -35026,7 +35062,22 @@ const drawSummary = (customMetrics, vodContainer, liveContainer) => {
35026
35062
  };
35027
35063
  // const T = 'plugins.clappr_nerd_stats';
35028
35064
  /**
35065
+ * Displays useful network-related statistics.
35029
35066
  * @beta
35067
+ *
35068
+ * @remarks
35069
+ * Depends on:
35070
+ *
35071
+ * - {@link MediaControl}
35072
+ *
35073
+ * - {@link BottomGear}
35074
+ *
35075
+ * - {@link ClapprStats}
35076
+ *
35077
+ * The plugin is rendered as an item in the gear menu.
35078
+ *
35079
+ * When clicked, it shows an overlay window with the information about the network speed, latency, etc,
35080
+ * and recommended quality level.
35030
35081
  */
35031
35082
  class ClapprNerdStats extends UICorePlugin {
35032
35083
  container = null;
@@ -35039,21 +35090,31 @@ class ClapprNerdStats extends UICorePlugin {
35039
35090
  showing = false;
35040
35091
  shortcut;
35041
35092
  iconPosition;
35093
+ /**
35094
+ * @internal
35095
+ */
35042
35096
  get name() {
35043
35097
  return 'nerd_stats';
35044
35098
  }
35099
+ /**
35100
+ * @internal
35101
+ */
35045
35102
  get supportedVersion() {
35046
35103
  return { min: CLAPPR_VERSION };
35047
35104
  }
35048
- get template() {
35049
- return tmpl(pluginHtml$5);
35050
- }
35105
+ static template = tmpl(pluginHtml$5);
35106
+ /**
35107
+ * @internal
35108
+ */
35051
35109
  get attributes() {
35052
35110
  return {
35053
35111
  'data-clappr-nerd-stats': '',
35054
- 'class': 'clappr-nerd-stats'
35112
+ class: 'clappr-nerd-stats',
35055
35113
  };
35056
35114
  }
35115
+ /**
35116
+ * @internal
35117
+ */
35057
35118
  get events() {
35058
35119
  return {
35059
35120
  'click [data-show-stats-button]': 'showOrHide',
@@ -35075,8 +35136,12 @@ class ClapprNerdStats extends UICorePlugin {
35075
35136
  }
35076
35137
  constructor(core) {
35077
35138
  super(core);
35078
- this.shortcut = core.options.clapprNerdStats?.shortcut ?? ['command+shift+s', 'ctrl+shift+s'];
35079
- this.iconPosition = core.options.clapprNerdStats?.iconPosition ?? 'bottom-right';
35139
+ this.shortcut = core.options.clapprNerdStats?.shortcut ?? [
35140
+ 'command+shift+s',
35141
+ 'ctrl+shift+s',
35142
+ ];
35143
+ this.iconPosition =
35144
+ core.options.clapprNerdStats?.iconPosition ?? 'bottom-right';
35080
35145
  this.customMetrics = {
35081
35146
  connectionSpeed: 0,
35082
35147
  ping: 0,
@@ -35084,6 +35149,9 @@ class ClapprNerdStats extends UICorePlugin {
35084
35149
  };
35085
35150
  configureSpeedTest(core.options.clapprNerdStats?.speedTestServers ?? []);
35086
35151
  }
35152
+ /**
35153
+ * @internal
35154
+ */
35087
35155
  bindEvents() {
35088
35156
  const mediaControl = this.core.getPlugin('media_control');
35089
35157
  assert(mediaControl, 'media_control plugin is required');
@@ -35120,9 +35188,11 @@ class ClapprNerdStats extends UICorePlugin {
35120
35188
  this.core.$el.find(this.statsBoxElem).show();
35121
35189
  this.showing = true;
35122
35190
  this.refreshSpeedTest();
35123
- initSpeedTest(this.customMetrics).then(() => {
35191
+ initSpeedTest(this.customMetrics)
35192
+ .then(() => {
35124
35193
  startSpeedtest();
35125
- }).catch(e => {
35194
+ })
35195
+ .catch((e) => {
35126
35196
  this.disable();
35127
35197
  });
35128
35198
  }
@@ -35136,13 +35206,19 @@ class ClapprNerdStats extends UICorePlugin {
35136
35206
  }
35137
35207
  addGeneralMetrics() {
35138
35208
  this.metrics.general = {
35139
- displayResolution: (this.playerWidth + 'x' + this.playerHeight),
35140
- volume: this.container?.volume
35209
+ displayResolution: this.playerWidth + 'x' + this.playerHeight,
35210
+ volume: this.container?.volume,
35141
35211
  };
35142
35212
  }
35143
35213
  addCustomMetrics() {
35144
35214
  this.metrics.custom = this.customMetrics;
35145
- const videoQualityNames = ['SD (480p)', 'HD (720p)', 'Full HD (1080p)', '2K (1440p)', '4K (2160p)'];
35215
+ const videoQualityNames = [
35216
+ 'SD (480p)',
35217
+ 'HD (720p)',
35218
+ 'Full HD (1080p)',
35219
+ '2K (1440p)',
35220
+ '4K (2160p)',
35221
+ ];
35146
35222
  const { connectionSpeed, ping } = this.customMetrics;
35147
35223
  if (!connectionSpeed || !ping) {
35148
35224
  const calculatingText = 'Calculating... Please wait.';
@@ -35154,17 +35230,19 @@ class ClapprNerdStats extends UICorePlugin {
35154
35230
  const pingQuality = getPingQuality(ping);
35155
35231
  const liveQuality = Math.min(downloadQuality, pingQuality);
35156
35232
  const prefix = 'Optimal for ';
35157
- this.metrics.custom.vodQuality = prefix + videoQualityNames[downloadQuality - 1];
35158
- this.metrics.custom.liveQuality = prefix + videoQualityNames[liveQuality - 1];
35233
+ this.metrics.custom.vodQuality =
35234
+ prefix + videoQualityNames[downloadQuality - 1];
35235
+ this.metrics.custom.liveQuality =
35236
+ prefix + videoQualityNames[liveQuality - 1];
35159
35237
  }
35160
35238
  updateMetrics(metrics) {
35161
35239
  Object.assign(this.metrics, metrics);
35162
35240
  this.addGeneralMetrics();
35163
35241
  this.addCustomMetrics();
35164
35242
  const scrollTop = this.core.$el.find(this.statsBoxElem).scrollTop();
35165
- this.$el.html(this.template({
35243
+ this.$el.html(ClapprNerdStats.template({
35166
35244
  metrics: Formatter.format(this.metrics),
35167
- iconPosition: this.iconPosition
35245
+ iconPosition: this.iconPosition,
35168
35246
  }));
35169
35247
  this.setStatsBoxSize();
35170
35248
  drawSpeedTestResults();
@@ -35184,7 +35262,11 @@ class ClapprNerdStats extends UICorePlugin {
35184
35262
  this.$el.find(this.statsBoxElem).addClass('narrow');
35185
35263
  }
35186
35264
  }
35265
+ /**
35266
+ * @internal
35267
+ */
35187
35268
  render() {
35269
+ // TODO append to the container
35188
35270
  this.core.$el.append(this.$el[0]);
35189
35271
  this.hide();
35190
35272
  return this;
@@ -35236,7 +35318,10 @@ function newMetrics() {
35236
35318
  // TODO: fix
35237
35319
  const updateMetrics = () => { };
35238
35320
  /**
35321
+ * Collects useful statistics about playback performance.
35239
35322
  * @beta
35323
+ * @remarks
35324
+ * This plugin does not render anything and is supposed to be extended or used together with other plugins that actually render something.
35240
35325
  */
35241
35326
  class ClapprStats extends ContainerPlugin {
35242
35327
  bwMeasureCount = 0;
@@ -35258,9 +35343,15 @@ class ClapprStats extends ContainerPlugin {
35258
35343
  updateFn = updateMetrics;
35259
35344
  urisToMeasureBandwidth;
35260
35345
  uriToMeasureLatency;
35346
+ /**
35347
+ * @internal
35348
+ */
35261
35349
  get name() {
35262
35350
  return 'clappr_stats';
35263
35351
  }
35352
+ /**
35353
+ * @internal
35354
+ */
35264
35355
  get supportedVersion() {
35265
35356
  return { min: CLAPPR_VERSION };
35266
35357
  }
@@ -35288,6 +35379,10 @@ class ClapprStats extends ContainerPlugin {
35288
35379
  // this._metrics.timers[timer] += this._now() - this[`_start${timer}`];
35289
35380
  this.metrics.timers[timer] += this._now() - this.timers[timer];
35290
35381
  }
35382
+ /**
35383
+ * Registers a callback to receive the metrics.
35384
+ * @param updateMetricsFn
35385
+ */
35291
35386
  setUpdateMetrics(updateMetricsFn) {
35292
35387
  this.updateFn = updateMetricsFn;
35293
35388
  }
@@ -35306,6 +35401,9 @@ class ClapprStats extends ContainerPlugin {
35306
35401
  calls: []
35307
35402
  };
35308
35403
  }
35404
+ /**
35405
+ * @internal
35406
+ */
35309
35407
  bindEvents() {
35310
35408
  this.listenTo(this.container, Events$1.CONTAINER_BITRATE, this.onBitrate);
35311
35409
  this.listenTo(this.container, Events$1.CONTAINER_STOP, this.stopReporting);
@@ -35324,10 +35422,17 @@ class ClapprStats extends ContainerPlugin {
35324
35422
  this.listenTo(this.container.playback, Events$1.PLAYBACK_PROGRESS, this.onProgress);
35325
35423
  this.listenTo(this.container.playback, Events$1.PLAYBACK_TIMEUPDATE, this.onTimeUpdate);
35326
35424
  }
35425
+ /**
35426
+ * @internal
35427
+ */
35327
35428
  destroy() {
35328
35429
  this.stopReporting();
35329
35430
  super.destroy();
35330
35431
  }
35432
+ /**
35433
+ * Returns the collected metrics.
35434
+ * @returns The collected metrics
35435
+ */
35331
35436
  exportMetrics() {
35332
35437
  return structuredClone(this.metrics);
35333
35438
  }
@@ -35349,6 +35454,7 @@ class ClapprStats extends ContainerPlugin {
35349
35454
  this.intervalId = null;
35350
35455
  }
35351
35456
  this._newMetrics();
35457
+ // TODO
35352
35458
  // @ts-ignore
35353
35459
  this.stopListening();
35354
35460
  this.bindEvents();
@@ -35566,19 +35672,29 @@ class ClapprStats extends ContainerPlugin {
35566
35672
 
35567
35673
  //Copyright 2014 Globo.com Player authors. All rights reserved.
35568
35674
  // Use of this source code is governed by a BSD-style
35569
- // license that can be found in the LICENSE file.
35675
+ // license that can be found at https://github.com/clappr/clappr-plugins/blob/master/LICENSE.
35676
+ /**
35677
+ * Adds a behavior of toggling the playback state on click over the container
35678
+ * @beta
35679
+ */
35570
35680
  class ClickToPause extends ContainerPlugin {
35571
35681
  pointerEnabled = false;
35572
35682
  timer = null;
35683
+ /**
35684
+ * @internal
35685
+ */
35573
35686
  get name() {
35574
35687
  return 'click_to_pause_custom';
35575
35688
  }
35689
+ /**
35690
+ * @internal
35691
+ */
35576
35692
  get supportedVersion() {
35577
35693
  return { min: CLAPPR_VERSION };
35578
35694
  }
35579
- get config() {
35580
- return this.container.options.clickToPauseConfig || {};
35581
- }
35695
+ /**
35696
+ * @internal
35697
+ */
35582
35698
  bindEvents() {
35583
35699
  this.listenTo(this.container, Events$1.CONTAINER_CLICK, this.click);
35584
35700
  this.listenTo(this.container, Events$1.CONTAINER_SETTINGSUPDATE, this.settingsUpdate);
@@ -35685,23 +35801,45 @@ function getPageX(event) {
35685
35801
  return 0;
35686
35802
  }
35687
35803
 
35804
+ /**
35805
+ * Adds a behavior of showing a text over the seekbar to indicate the current clip.
35806
+ * @beta
35807
+ * @remarks
35808
+ * Depends on:
35809
+ *
35810
+ * - {@link MediaControl}
35811
+ *
35812
+ * Configuration options - {@link ClipsPluginSettings}
35813
+ */
35688
35814
  class ClipsPlugin extends UICorePlugin {
35689
35815
  clips = new Map();
35690
35816
  duration = 0;
35691
35817
  durationGetting = false;
35692
35818
  _oldContainer;
35693
35819
  svgMask = null;
35820
+ /**
35821
+ * @internal
35822
+ */
35694
35823
  get name() {
35695
- return 'media_control_clips';
35824
+ return 'clips';
35696
35825
  }
35826
+ /**
35827
+ * @internal
35828
+ */
35697
35829
  get attributes() {
35698
35830
  return {
35699
- 'class': this.name
35831
+ class: this.name,
35700
35832
  };
35701
35833
  }
35834
+ /**
35835
+ * @internal
35836
+ */
35702
35837
  bindEvents() {
35838
+ const mediaControl = this.core.getPlugin('media_control');
35839
+ assert(mediaControl, 'media_control plugin is required');
35703
35840
  this.listenToOnce(this.core, Events$1.CORE_READY, this._onCoreReady);
35704
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this._onMediaControlContainerChanged);
35841
+ // TODO listen to CORE_ACTIVE_CONTAINER_CHANGED
35842
+ this.listenTo(mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this._onMediaControlContainerChanged);
35705
35843
  this.listenTo(this.core, Events$1.CORE_RESIZE, this.playerResize);
35706
35844
  }
35707
35845
  _onCoreReady() {
@@ -35711,12 +35849,6 @@ class ClipsPlugin extends UICorePlugin {
35711
35849
  }
35712
35850
  this.parseClips();
35713
35851
  }
35714
- unbindEvents() {
35715
- // @ts-ignore
35716
- this.stopListening(this.core, Events$1.CORE_READY);
35717
- // @ts-ignore
35718
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED);
35719
- }
35720
35852
  _onMediaControlContainerChanged() {
35721
35853
  this._bindContainerEvents();
35722
35854
  }
@@ -35730,9 +35862,10 @@ class ClipsPlugin extends UICorePlugin {
35730
35862
  if (this._oldContainer) {
35731
35863
  this.stopListening(this._oldContainer, Events$1.CONTAINER_TIMEUPDATE, this.onTimeUpdate);
35732
35864
  }
35733
- this._oldContainer = this.core.mediaControl.container;
35865
+ const mediaControl = this.core.getPlugin('media_control');
35866
+ this._oldContainer = mediaControl.container;
35734
35867
  this.durationGetting = false;
35735
- this.listenTo(this.core.mediaControl.container, Events$1.CONTAINER_TIMEUPDATE, this.onTimeUpdate);
35868
+ this.listenTo(mediaControl.container, Events$1.CONTAINER_TIMEUPDATE, this.onTimeUpdate);
35736
35869
  }
35737
35870
  onTimeUpdate(event) {
35738
35871
  if (!this.durationGetting) {
@@ -35749,13 +35882,17 @@ class ClipsPlugin extends UICorePlugin {
35749
35882
  }
35750
35883
  parseClips() {
35751
35884
  const textArr = this.options.clips.text.split('\n');
35752
- const clipsArr = textArr.map((val) => {
35885
+ const clipsArr = textArr
35886
+ .map((val) => {
35753
35887
  const matchRes = val.match(/(\d+:\d+|:\d+) (.+)/i);
35754
- return matchRes ? {
35755
- start: strtimeToMiliseconds(matchRes[1]),
35756
- text: matchRes[2],
35757
- } : null;
35758
- }).filter((clip) => clip !== null);
35888
+ return matchRes
35889
+ ? {
35890
+ start: strtimeToMiliseconds(matchRes[1]),
35891
+ text: matchRes[2],
35892
+ }
35893
+ : null;
35894
+ })
35895
+ .filter((clip) => clip !== null);
35759
35896
  clipsArr.sort((a, b) => a.start - b.start);
35760
35897
  clipsArr.forEach((clip, index) => {
35761
35898
  this.clips.set(clip.start, {
@@ -35766,6 +35903,11 @@ class ClipsPlugin extends UICorePlugin {
35766
35903
  });
35767
35904
  });
35768
35905
  }
35906
+ /**
35907
+ * Returns the text of the current clip.
35908
+ * @param time - The current time of the player.
35909
+ * @returns The text of the current clip.
35910
+ */
35769
35911
  getText(time) {
35770
35912
  for (const [key, value] of this.clips.entries()) {
35771
35913
  if (time >= value.start && time < value.end) {
@@ -35776,14 +35918,14 @@ class ClipsPlugin extends UICorePlugin {
35776
35918
  }
35777
35919
  makeSvg(duration) {
35778
35920
  let svg = '<svg width="0" height="0">\n' + '<defs>\n' + '<clipPath id="myClip">\n';
35779
- const widthOfSeek = this.core.mediaControl.container.$el.width();
35921
+ const widthOfSeek = this.core.activeContainer.$el.width();
35780
35922
  let finishValue = 0;
35781
- this.clips.forEach(val => {
35923
+ this.clips.forEach((val) => {
35782
35924
  let end = val.end;
35783
35925
  if (!end) {
35784
35926
  end = val.end = duration;
35785
35927
  }
35786
- const widthChunk = (end - val.start) * widthOfSeek / duration;
35928
+ const widthChunk = ((end - val.start) * widthOfSeek) / duration;
35787
35929
  svg += `<rect x="${finishValue}" y="0" width="${widthChunk - 2}" height="30"/>\n`;
35788
35930
  finishValue += widthChunk;
35789
35931
  });
@@ -35796,7 +35938,8 @@ class ClipsPlugin extends UICorePlugin {
35796
35938
  if (this.svgMask) {
35797
35939
  this.svgMask.remove();
35798
35940
  }
35799
- const $seekBarContainer = this.core.mediaControl.getElement('seekBarContainer');
35941
+ const mediaControl = this.core.getPlugin('media_control');
35942
+ const $seekBarContainer = mediaControl.getElement('seekBarContainer');
35800
35943
  if ($seekBarContainer?.get(0)) {
35801
35944
  $seekBarContainer.addClass('clips');
35802
35945
  }
@@ -35804,7 +35947,8 @@ class ClipsPlugin extends UICorePlugin {
35804
35947
  $seekBarContainer?.append(this.svgMask);
35805
35948
  }
35806
35949
  setClipText(text) {
35807
- const $clipText = this.core.mediaControl.getElement('clipText');
35950
+ const mediaControl = this.core.getPlugin('media_control');
35951
+ const $clipText = mediaControl.getElement('clipText');
35808
35952
  if ($clipText && text) {
35809
35953
  $clipText.show();
35810
35954
  $clipText.text(`${text}`);
@@ -35814,28 +35958,61 @@ class ClipsPlugin extends UICorePlugin {
35814
35958
 
35815
35959
  const templateHtml$1 = "<ul class=\"context-menu-list\">\n <% if(options) { %>\n <% for (var i = 0; i < options.length; i++) { %>\n <li class=\"context-menu-list-item <%= options[i].class %>\"\n data-<%= options[i].name %>><%= options[i].label %></li>\n <% } %>\n <% } %>\n</ul>\n";
35816
35960
 
35817
- class ContextMenu extends UICorePlugin {
35961
+ var version$1 = "2.20.3";
35962
+
35963
+ var packages = {
35964
+ "node_modules/@clappr/core": {
35965
+ version: "0.11.4"},
35966
+ "node_modules/dashjs": {
35967
+ version: "4.7.4"},
35968
+ "node_modules/hls.js": {
35969
+ version: "1.5.20"}};
35970
+
35971
+ /**
35972
+ * Version information about the gplayer and its main dependencies
35973
+ * @returns Version information about the gplayer and its main dependencies
35974
+ * @beta
35975
+ */
35976
+ function version() {
35977
+ return {
35978
+ gplayer: version$1,
35979
+ clappr: packages['node_modules/@clappr/core'].version,
35980
+ dashjs: packages['node_modules/dashjs'].version,
35981
+ hlsjs: packages['node_modules/hls.js'].version,
35982
+ };
35983
+ }
35984
+
35985
+ /**
35986
+ * Displays a small context menu when clicked on the player container.
35987
+ * @beta
35988
+ * @remarks
35989
+ * Configuration options - {@link ContextMenuPluginSettings}
35990
+ */
35991
+ class ContextMenu extends UIContainerPlugin {
35818
35992
  _label = '';
35819
35993
  _url = '';
35820
- container = null;
35821
35994
  menuOptions = [];
35995
+ /**
35996
+ * @internal
35997
+ */
35822
35998
  get name() {
35823
35999
  return 'context_menu';
35824
36000
  }
36001
+ /**
36002
+ * @internal
36003
+ */
35825
36004
  get supportedVersion() {
35826
36005
  return { min: CLAPPR_VERSION };
35827
36006
  }
36007
+ /**
36008
+ * @internal
36009
+ */
35828
36010
  get attributes() {
35829
- return { 'class': 'context-menu' };
35830
- }
35831
- get mediaControl() {
35832
- return this.core.mediaControl;
35833
- }
35834
- get template() {
35835
- return tmpl(templateHtml$1);
36011
+ return { class: 'context-menu' };
35836
36012
  }
36013
+ static template = tmpl(templateHtml$1);
35837
36014
  get label() {
35838
- return this._label || 'Gcore player ver. ' + process.env.VERSION;
36015
+ return this._label || 'Gcore player ver. ' + version().gplayer;
35839
36016
  }
35840
36017
  get url() {
35841
36018
  return this._url || 'https://gcore.com/';
@@ -35843,16 +36020,19 @@ class ContextMenu extends UICorePlugin {
35843
36020
  get exposeVersion() {
35844
36021
  return {
35845
36022
  label: this.label,
35846
- name: 'version'
36023
+ name: 'version',
35847
36024
  };
35848
36025
  }
36026
+ /**
36027
+ * @internal
36028
+ */
35849
36029
  get events() {
35850
36030
  return {
35851
- 'click [data-version]': 'onOpenMainPage'
36031
+ 'click [data-version]': 'onOpenMainPage',
35852
36032
  };
35853
36033
  }
35854
- constructor(core) {
35855
- super(core);
36034
+ constructor(container) {
36035
+ super(container);
35856
36036
  if (this.options.contextMenu && this.options.contextMenu.label) {
35857
36037
  this._label = this.options.contextMenu.label;
35858
36038
  }
@@ -35862,28 +36042,21 @@ class ContextMenu extends UICorePlugin {
35862
36042
  this.render();
35863
36043
  this.bindEvents();
35864
36044
  }
36045
+ /**
36046
+ * @internal
36047
+ */
35865
36048
  bindEvents() {
35866
- if (this.mediaControl) {
35867
- this.listenTo(this.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.containerChanged);
35868
- if (this.container) {
35869
- this.listenTo(this.container, Events$1.CONTAINER_CONTEXTMENU, this.toggleContextMenu);
35870
- this.listenTo(this.container, Events$1.CONTAINER_CLICK, this.hide);
35871
- }
35872
- }
35873
- $('body').on('click', this.hide.bind(this));
36049
+ this.listenTo(this.container, Events$1.CONTAINER_CONTEXTMENU, this.toggleContextMenu);
36050
+ this.listenTo(this.container, Events$1.CONTAINER_CLICK, this.hide);
36051
+ $('body').on('click', this.hideOnBodyClick);
35874
36052
  }
36053
+ /**
36054
+ * @internal
36055
+ */
35875
36056
  destroy() {
35876
- $('body').off('click', this.hide.bind(this));
35877
- // @ts-ignore
35878
- this.stopListening();
36057
+ $('body').off('click', this.hideOnBodyClick);
35879
36058
  return super.destroy();
35880
36059
  }
35881
- containerChanged() {
35882
- this.container = this.core.activeContainer;
35883
- // @ts-ignore
35884
- this.stopListening();
35885
- this.bindEvents();
35886
- }
35887
36060
  toggleContextMenu(event) {
35888
36061
  event.preventDefault();
35889
36062
  const offset = this.container?.$el.offset();
@@ -35891,7 +36064,8 @@ class ContextMenu extends UICorePlugin {
35891
36064
  }
35892
36065
  show(top, left) {
35893
36066
  this.hide();
35894
- if (this.options.contextMenu && this.options.contextMenu.preventShowContextMenu) {
36067
+ if (this.options.contextMenu &&
36068
+ this.options.contextMenu.preventShowContextMenu) {
35895
36069
  return;
35896
36070
  }
35897
36071
  this.$el.css({ top, left });
@@ -35903,80 +36077,19 @@ class ContextMenu extends UICorePlugin {
35903
36077
  onOpenMainPage() {
35904
36078
  window.open(this.url, '_blank');
35905
36079
  }
36080
+ /**
36081
+ * @internal
36082
+ */
35906
36083
  render() {
35907
36084
  this.menuOptions = [this.exposeVersion];
35908
- this.$el.html(this.template({ options: this.menuOptions }));
35909
- this.core.$el.append(this.$el);
36085
+ this.$el.html(ContextMenu.template({ options: this.menuOptions }));
36086
+ this.container.$el.append(this.$el); // TODO append to the container, turn into a container plugin
35910
36087
  this.hide();
35911
- this.disable();
35912
36088
  return this;
35913
36089
  }
35914
- }
35915
-
35916
- class DisableControls extends UICorePlugin {
35917
- get name() {
35918
- return 'disable_controls';
35919
- }
35920
- get container() {
35921
- return this.core && this.core.activeContainer;
35922
- }
35923
- get supportedVersion() {
35924
- return { min: CLAPPR_VERSION };
35925
- }
35926
- bindEvents() {
35927
- if (this.container) {
35928
- this.listenTo(this.container, Events$1.CONTAINER_MEDIACONTROL_ENABLE, this.enableControls);
35929
- this.listenTo(this.container, Events$1.CONTAINER_PLAY, this.enableControls);
35930
- this.listenTo(this.container, Events$1.CONTAINER_PAUSE, this.enableControls);
35931
- this.listenTo(this.container, Events$1.CONTAINER_STOP, this.enableControls);
35932
- this.listenTo(this.container, Events$1.CONTAINER_ENDED, this.enableControls);
35933
- this.listenTo(this.container, 'container:advertisement:start', this.enableControls);
35934
- }
35935
- this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
35936
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_SHOW, this.enableControls);
35937
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.enableControls);
35938
- }
35939
- unbindEvents() {
35940
- // @ts-ignore
35941
- this.stopListening(this.core, Events$1.CORE_READY);
35942
- // @ts-ignore
35943
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_SHOW);
35944
- // @ts-ignore
35945
- this.stopListening(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED);
35946
- // @ts-ignore
35947
- this.stopListening(this.container, Events$1.CONTAINER_MEDIACONTROL_ENABLE);
35948
- // @ts-ignore
35949
- this.stopListening(this.container, Events$1.CONTAINER_PLAY);
35950
- // @ts-ignore
35951
- this.stopListening(this.container, Events$1.CONTAINER_PAUSE);
35952
- // @ts-ignore
35953
- this.stopListening(this.container, Events$1.CONTAINER_STOP);
35954
- // @ts-ignore
35955
- this.stopListening(this.container, Events$1.CONTAINER_ENDED);
35956
- // @ts-ignore
35957
- this.stopListening(this.container, 'container:advertisement:start');
35958
- }
35959
- setDisableStyles() {
35960
- const css = document.createElement('style');
35961
- const styles = '.control-need-disable { display: none!important; }';
35962
- css.appendChild(document.createTextNode(styles));
35963
- this.core.$el.get(0).appendChild(css);
35964
- }
35965
- onCoreReady() {
35966
- this.setDisableStyles();
35967
- this.bindEvents();
35968
- this.enableControls();
35969
- }
35970
- enableControls() {
35971
- this.disableAllControls();
35972
- }
35973
- disableAllControls() {
35974
- setTimeout(() => {
35975
- const spinnerPlugin = this.container.getPlugin('spinner');
35976
- spinnerPlugin?.destroy();
35977
- this.container.disableMediaControl();
35978
- }, 0);
35979
- }
36090
+ hideOnBodyClick = () => {
36091
+ this.hide();
36092
+ };
35980
36093
  }
35981
36094
 
35982
36095
  const dvrHTML = "<div class=\"live-info\"><%= live %></div>\n<button type=\"button\" class=\"live-button\" aria-label=\"<%= backToLive %>\"><%= backToLive %></button>\n";
@@ -35986,8 +36099,11 @@ const dvrHTML = "<div class=\"live-info\"><%= live %></div>\n<button type=\"butt
35986
36099
  * @beta
35987
36100
  *
35988
36101
  * @remarks
35989
- * The plugin is rendered in the {@link MediaControl | media control} UI.
35990
- * It renders the live stream indicator and the DVR seek bar if DVR is enabled.
36102
+ * Depends on:
36103
+ *
36104
+ * - {@link MediaControl}
36105
+ *
36106
+ * The plugin renders the live stream indicator and the DVR seek bar, if DVR is enabled, in the media control UI.
35991
36107
  */
35992
36108
  class DvrControls extends UICorePlugin {
35993
36109
  static template = tmpl(dvrHTML);
@@ -35995,7 +36111,7 @@ class DvrControls extends UICorePlugin {
35995
36111
  * @internal
35996
36112
  */
35997
36113
  get name() {
35998
- return 'media_control_dvr';
36114
+ return 'dvr_controls';
35999
36115
  }
36000
36116
  /**
36001
36117
  * @internal
@@ -36028,32 +36144,15 @@ class DvrControls extends UICorePlugin {
36028
36144
  * @internal
36029
36145
  */
36030
36146
  bindEvents() {
36031
- this.bindCoreEvents();
36032
- this.bindContainerEvents();
36033
- if (this.core.activeContainer) {
36034
- this.listenTo(this.core.activeContainer, Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.dvrChanged);
36035
- }
36036
- }
36037
- bindCoreEvents() {
36038
- if (this.core.mediaControl.settings) {
36039
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.containerChanged);
36040
- this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.settingsUpdate);
36041
- this.listenTo(this.core, Events$1.CORE_OPTIONS_CHANGE, this.render);
36042
- }
36043
- else {
36044
- setTimeout(() => this.bindCoreEvents(), 100);
36045
- }
36147
+ const mediaControl = this.core.getPlugin('media_control');
36148
+ assert(mediaControl, 'media_control plugin is required');
36149
+ this.listenTo(mediaControl, Events$1.MEDIACONTROL_RENDERED, this.settingsUpdate);
36150
+ this.listenTo(this.core, Events$1.CORE_OPTIONS_CHANGE, this.render);
36151
+ this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, this.bindContainerEvents);
36046
36152
  }
36047
36153
  bindContainerEvents() {
36048
- if (this.core.activeContainer) {
36049
- this.listenToOnce(this.core.activeContainer, Events$1.CONTAINER_TIMEUPDATE, this.render);
36050
- this.listenTo(this.core.activeContainer, Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.dvrChanged);
36051
- }
36052
- }
36053
- containerChanged() {
36054
- // @ts-ignore
36055
- this.stopListening();
36056
- this.bindEvents();
36154
+ this.listenToOnce(this.core.activeContainer, Events$1.CONTAINER_TIMEUPDATE, this.render);
36155
+ this.listenTo(this.core.activeContainer, Events$1.CONTAINER_PLAYBACKDVRSTATECHANGED, this.dvrChanged);
36057
36156
  }
36058
36157
  dvrChanged(dvrEnabled) {
36059
36158
  if (this.core.getPlaybackType() !== Playback.LIVE) {
@@ -36086,7 +36185,7 @@ class DvrControls extends UICorePlugin {
36086
36185
  settingsUpdate() {
36087
36186
  // @ts-ignore
36088
36187
  this.stopListening(); // TODO sort out
36089
- this.core.mediaControl.$el.removeClass('live');
36188
+ this.core.getPlugin('media_control').$el.removeClass('live'); // TODO don't access directly
36090
36189
  if (this.shouldRender()) {
36091
36190
  this.render();
36092
36191
  this.$el.click(() => this.click());
@@ -36106,7 +36205,7 @@ class DvrControls extends UICorePlugin {
36106
36205
  backToLive: this.core.i18n.t('back_to_live')
36107
36206
  }));
36108
36207
  if (this.shouldRender()) {
36109
- const mediaControl = this.core.mediaControl;
36208
+ const mediaControl = this.core.getPlugin('media_control');
36110
36209
  assert(mediaControl, 'media_control plugin is required');
36111
36210
  // TODO don't tap into the $el directly
36112
36211
  mediaControl.$el.addClass('live');
@@ -36122,6 +36221,10 @@ const templateHtml = "<div class=\"player-error-screen__content\" data-error-scr
36122
36221
 
36123
36222
  const TIME_FOR_UPDATE = 10000;
36124
36223
  const MAX_RETRY = 10;
36224
+ /**
36225
+ * Displays a descriptive error in the overlay on top of the player.
36226
+ * @beta
36227
+ */
36125
36228
  class ErrorScreen extends UICorePlugin {
36126
36229
  _retry = 0;
36127
36230
  err = null;
@@ -36299,6 +36402,10 @@ const stopIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\
36299
36402
  const FAVICON_COLOR = '#567';
36300
36403
  const FAVICON_SELECTOR = 'link[rel="shortcut icon"]';
36301
36404
  // const oldIcon = $(FAVICON_SELECTOR);
36405
+ /**
36406
+ * The plugin adds custom favicon to the player's tab.
36407
+ * @beta
36408
+ */
36302
36409
  class Favicon extends CorePlugin {
36303
36410
  _container = null;
36304
36411
  oldIcon;
@@ -36400,7 +36507,11 @@ class Favicon extends CorePlugin {
36400
36507
 
36401
36508
  // Copyright 2014 Globo.com Player authors. All rights reserved.
36402
36509
  // Use of this source code is governed by a BSD-style
36403
- // license that can be found in the LICENSE file.
36510
+ // license that can be found at https://github.com/clappr/clappr-plugins/blob/master/LICENSE
36511
+ /**
36512
+ * An example Google Analytics integration plugin
36513
+ * @beta
36514
+ */
36404
36515
  class GoogleAnalytics extends ContainerPlugin {
36405
36516
  account = '';
36406
36517
  trackerName = '';
@@ -36711,7 +36822,7 @@ function keyName(keyCode) {
36711
36822
 
36712
36823
  const buttonHtml$2 = "<button class='gplayer-lite-btn gcore-skin-text-color gear-option'>\n <% if (isHd) { %>\n <span class=\"gear-option_hd-icon\"><%= hdIcon %></span>\n <% } %>\n <span>Quality</span>\n <span class=\"gear-option_arrow-right-icon\"><%= arrowRightIcon %></span>\n <span class='gear-option_value'><%= currentText %></span>\n</button>\n";
36713
36824
 
36714
- const listHtml$1 = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n Quality\n</button>\n<ul class=\"gear-sub-menu\">\n <% if (!removeAuto) { %>\n <li>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"-1\" id=\"level_selector_auto\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n Auto\n </a>\n </li>\n <% } %>\n <% for (const level of levels.slice().reverse()) { %>\n <li <% if (maxLevel >= 0 && level.level > maxLevel) { %>class=\"level-disabled\"<% } %>>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"<%= level.level %>\" id=\"level_selector_<%= level.level %>\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= labels[level.level] %>\n </a>\n </li>\n <% } %>\n</ul>\n";
36825
+ const listHtml$1 = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n Quality\n</button>\n<ul class=\"gear-sub-menu\">\n <% if (!removeAuto) { %>\n <li>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"-1\" id=\"level_selector_auto\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n Auto\n </a>\n </li>\n <% } %>\n <% for (const level of levels.slice().reverse()) { %>\n <li <% if (maxLevel >= 0 && level.level > maxLevel) { %>class=\"level-disabled\"<% } %>>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"<%= level.level %>\" id=\"level_selector_<%= level.height %>\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= labels[level.level] %>\n </a>\n </li>\n <% } %>\n</ul>\n";
36715
36826
 
36716
36827
  const hdIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14.9562 8.22232H13.9961V15.1873H14.9562C15.8914 15.1873 16.766 14.8253 17.4195 14.1676C18.0786 13.5037 18.4415 12.6281 18.4415 11.7026C18.4415 9.7837 16.8781 8.22253 14.9561 8.22253L14.9562 8.22232Z\"\n fill=\"#C9C9C9\"/>\n <path\n d=\"M22.0801 4H1.91994C0.859222 4 0 4.86406 0 5.91994V17.4878C0 18.5437 0.859222 19.4078 1.91994 19.4078H22.0801C23.1408 19.4078 24 18.5437 24 17.4878V5.91994C24 4.86406 23.1408 4 22.0801 4ZM10.3975 15.3473C10.3975 15.6124 10.1827 15.8272 9.91754 15.8272C9.65216 15.8272 9.43761 15.6122 9.43761 15.3473V12.0239H5.55956V15.3473C5.55956 15.6124 5.34481 15.8272 5.07963 15.8272C4.81425 15.8272 4.5997 15.6122 4.5997 15.3473L4.59949 7.74042C4.59949 7.47524 4.81425 7.26049 5.07943 7.26049C5.34481 7.26049 5.55936 7.47544 5.55936 7.74042V11.0636H9.43741V7.74042C9.43741 7.47524 9.65216 7.26049 9.91734 7.26049C10.1827 7.26049 10.3973 7.47544 10.3973 7.74042L10.3975 15.3473ZM18.1005 14.8438C17.2652 15.6844 16.1486 16.1472 14.9561 16.1472H13.5161C13.2507 16.1472 13.0361 15.9323 13.0361 15.6673V7.74263C13.0361 7.47745 13.2509 7.26269 13.5161 7.26269H14.9561C17.4072 7.26269 19.4013 9.25438 19.4013 11.7027C19.4013 12.8835 18.9392 13.9991 18.1005 14.844V14.8438Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
36717
36828
 
@@ -36721,7 +36832,7 @@ const arrowLeftIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fil
36721
36832
 
36722
36833
  const checkIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M20.5793 4.19296C20.1216 3.86696 19.4777 3.96396 19.1424 4.40896L9.37295 17.3809L4.81634 12.107C4.45222 11.683 3.80218 11.6289 3.36709 11.9839C2.932 12.3389 2.87543 12.97 3.2416 13.393L8.64165 19.643C8.83708 19.869 9.12506 20 9.42849 20C9.4398 20 9.45114 20 9.46246 19.999C9.77926 19.989 10.0724 19.838 10.2586 19.59L20.8015 5.58996C21.1368 5.14496 21.0371 4.51896 20.5793 4.19296Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
36723
36834
 
36724
- const T$7 = 'plugins.level_selector';
36835
+ const T$8 = 'plugins.level_selector';
36725
36836
  const VERSION$4 = '2.19.4';
36726
36837
  /**
36727
36838
  * A {@link MediaControl | media control} plugin that provides a UI to control the quality level of the playback.
@@ -36825,7 +36936,7 @@ class LevelSelector extends UICorePlugin {
36825
36936
  onStop() {
36826
36937
  const currentPlayback = this.core.activePlayback;
36827
36938
  this.listenToOnce(currentPlayback, Events$1.PLAYBACK_PLAY, () => {
36828
- trace(`${T$7} on PLAYBACK_PLAY after stop`, { selectedLevelId: this.selectedLevelId });
36939
+ trace(`${T$8} on PLAYBACK_PLAY after stop`, { selectedLevelId: this.selectedLevelId });
36829
36940
  if (currentPlayback.getPlaybackType() === 'live') {
36830
36941
  if (this.selectedLevelId !== -1) {
36831
36942
  currentPlayback.currentLevel = this.selectedLevelId;
@@ -36980,7 +37091,7 @@ class LevelSelector extends UICorePlugin {
36980
37091
  this.highlightCurrentLevel();
36981
37092
  }
36982
37093
  highlightCurrentLevel() {
36983
- trace(`${T$7} highlightCurrentLevel`, {
37094
+ trace(`${T$8} highlightCurrentLevel`, {
36984
37095
  selectedLevelId: this.selectedLevelId,
36985
37096
  });
36986
37097
  this.allLevelElements().removeClass('current');
@@ -37044,6 +37155,10 @@ function calculateSize(original) {
37044
37155
 
37045
37156
  const logoHTML = "<div class=\"clappr-logo control-need-disable\">\n <img class=\"clappr-logo-img\"/>\n</div>\n";
37046
37157
 
37158
+ /**
37159
+ * The plugin adds custom logo to the player.
37160
+ * @beta
37161
+ */
37047
37162
  class Logo extends UIContainerPlugin {
37048
37163
  hasStartedPlaying = false;
37049
37164
  $logoContainer = null;
@@ -37321,7 +37436,7 @@ class MediaControl extends UICorePlugin {
37321
37436
  return { min: CLAPPR_VERSION };
37322
37437
  }
37323
37438
  get disabled() {
37324
- const playbackIsNOOP = this.container && this.container.getPlaybackType() === Playback.NO_OP;
37439
+ const playbackIsNOOP = this.core.activeContainer && this.core.activeContainer.getPlaybackType() === Playback.NO_OP;
37325
37440
  return this.userDisabled || playbackIsNOOP;
37326
37441
  }
37327
37442
  /**
@@ -38001,6 +38116,8 @@ class MediaControl extends UICorePlugin {
38001
38116
  */
38002
38117
  getElement(name) {
38003
38118
  switch (name) {
38119
+ case 'audioTracksSelector':
38120
+ return this.$audioTracksSelector;
38004
38121
  case 'clipText':
38005
38122
  return this.$clipText;
38006
38123
  case 'bottomGear':
@@ -38305,7 +38422,10 @@ const streamsMomentoIcon = "<svg id=\"Слой_1\" data-name=\"Слой 1\" xmln
38305
38422
  const streamsWhiteNightsIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"50\" height=\"50\" viewBox=\"0 0 50 50\">\n <defs>\n <clipPath id=\"clip-Icon\">\n <rect width=\"50\" height=\"50\"/>\n </clipPath>\n </defs>\n <g id=\"Icon\" clip-path=\"url(#clip-Icon)\">\n <g id=\"icon2\" transform=\"translate(-0.041 0)\">\n <path id=\"Контур_77\" data-name=\"Контур 77\" d=\"M6.493,13v8.266h6.275V19.74H8.31V17.714h4.006V16.3H8.31V14.53h4.365V13Zm7.5,0v8.266h1.7V15.732h.023l3.438,5.534h1.818V13h-1.7v5.545h-.023L15.8,13Z\" fill=\"#fff\"/>\n <path id=\"Контур_76\" data-name=\"Контур 76\" d=\"M29.949,29.1V26.774H31.94a1.4,1.4,0,0,1,.938.272,1.1,1.1,0,0,1,.313.874,1.155,1.155,0,0,1-.313.9,1.375,1.375,0,0,1-.938.278ZM28.132,25.36v8.266h1.817V30.4h1.818a1.353,1.353,0,0,1,.984.3,1.637,1.637,0,0,1,.394.949c.046.333.079.681.1,1.042a3.2,3.2,0,0,0,.185.938h1.819a1.218,1.218,0,0,1-.191-.423,3.611,3.611,0,0,1-.093-.527c-.019-.185-.033-.367-.041-.544s-.016-.332-.023-.463a5.052,5.052,0,0,0-.087-.625,2.109,2.109,0,0,0-.2-.573,1.586,1.586,0,0,0-.359-.451,1.414,1.414,0,0,0-.556-.284v-.023a1.926,1.926,0,0,0,1-.81,2.494,2.494,0,0,0,.307-1.262,2.308,2.308,0,0,0-.165-.88,2.128,2.128,0,0,0-.486-.724,2.3,2.3,0,0,0-.764-.492,2.67,2.67,0,0,0-1-.179ZM43.506,30.5V25.36H41.689V30.5a2.065,2.065,0,0,1-.37,1.36,1.7,1.7,0,0,1-1.343.434,2.086,2.086,0,0,1-.886-.156,1.283,1.283,0,0,1-.758-.978,3.748,3.748,0,0,1-.058-.66V25.36H36.456V30.5a3.16,3.16,0,0,0,.92,2.5,3.807,3.807,0,0,0,2.6.81,3.82,3.82,0,0,0,2.593-.816,3.132,3.132,0,0,0,.937-2.492Z\" fill=\"#fff\"/>\n <path id=\"Контур_80\" data-name=\"Контур 80\" d=\"M22.646,31.2H4.689a4.505,4.505,0,0,1-4.5-4.5V8.5A4.505,4.505,0,0,1,4.689,4h18.2a4.505,4.505,0,0,1,4.5,4.5v8.445l-.893.1a3.184,3.184,0,0,0-2.846,3.177V30.5l-.465.7ZM4.689,6a2.5,2.5,0,0,0-2.5,2.5V26.7a2.5,2.5,0,0,0,2.5,2.5H21.65V20.22a5.18,5.18,0,0,1,3.739-4.992V8.5a2.5,2.5,0,0,0-2.5-2.5Z\" fill=\"#fff\"/>\n <path id=\"Контур_81\" data-name=\"Контур 81\" d=\"M30.127,47.884a1,1,0,0,1-1-1V43.267H26.846a5.206,5.206,0,0,1-5.2-5.2V20.222a5.206,5.206,0,0,1,5.2-5.2H44.692a5.206,5.206,0,0,1,5.2,5.2V38.068a5.206,5.206,0,0,1-5.2,5.2H35.058l-4.216,4.316A1,1,0,0,1,30.127,47.884ZM26.846,17.022a3.2,3.2,0,0,0-3.2,3.2V38.067a3.2,3.2,0,0,0,3.2,3.2h3.281a1,1,0,0,1,1,1v2.162l2.8-2.86a1,1,0,0,1,.715-.3H44.692a3.2,3.2,0,0,0,3.2-3.2V20.222a3.2,3.2,0,0,0-3.2-3.2Z\" fill=\"#fff\"/>\n </g>\n </g>\n</svg>\n";
38306
38423
 
38307
38424
  const VERSION$3 = '0.0.1';
38308
- const T$6 = 'plugins.media_control_multicamera';
38425
+ const T$7 = 'plugins.media_control_multicamera';
38426
+ /**
38427
+ * The plugin adds support for loading multiple streams and switching between them using the media control UI.
38428
+ */
38309
38429
  class MultiCamera extends UICorePlugin {
38310
38430
  currentCamera = null;
38311
38431
  currentTime = 0;
@@ -38574,7 +38694,7 @@ class MultiCamera extends UICorePlugin {
38574
38694
  // TODO figure out what this does
38575
38695
  playbackOptions.recycleVideo = Browser.isMobile;
38576
38696
  this.currentCamera = this.findElementById(id) ?? null;
38577
- trace(`${T$6} changeById`, { currentCamera: this.currentCamera, multicamera: this.multicamera });
38697
+ trace(`${T$7} changeById`, { currentCamera: this.currentCamera, multicamera: this.multicamera });
38578
38698
  if (!this.currentCamera) {
38579
38699
  return;
38580
38700
  }
@@ -38590,7 +38710,7 @@ class MultiCamera extends UICorePlugin {
38590
38710
  // TODO remove?
38591
38711
  // for html5 playback:
38592
38712
  this.options.dvrEnabled = this.currentCamera.dvr;
38593
- trace(`${T$6} changeById`, { currentCamera: this.currentCamera });
38713
+ trace(`${T$7} changeById`, { currentCamera: this.currentCamera });
38594
38714
  // TODO
38595
38715
  this.core.configure({
38596
38716
  playback: playbackOptions,
@@ -38648,17 +38768,39 @@ const pipIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"no
38648
38768
  const buttonHtml$1 = "<button class=\"gplayer-lite-btn gcore-skin-button-color\">\n <span><%= pipIcon %></span>\n</button>\n";
38649
38769
 
38650
38770
  const VERSION$2 = '0.0.1';
38651
- const T$5 = `plugins.media_control_pip`;
38771
+ const T$6 = `plugins.pip`;
38772
+ /**
38773
+ * Enables picture in picture mode.
38774
+ * @beta
38775
+ * @remarks
38776
+ * Depends on:
38777
+ *
38778
+ * - {@link MediaControl}
38779
+ *
38780
+ * It renders a button to toggle picture in picture mode in the media control UI.
38781
+ */
38652
38782
  class PictureInPicture extends UICorePlugin {
38783
+ /**
38784
+ * @internal
38785
+ */
38653
38786
  get name() {
38654
- return 'media_control_pip';
38787
+ return 'pip';
38655
38788
  }
38789
+ /**
38790
+ * @internal
38791
+ */
38656
38792
  get supportedVersion() {
38657
38793
  return { min: CLAPPR_VERSION };
38658
38794
  }
38795
+ /**
38796
+ * @internal
38797
+ */
38659
38798
  static get version() {
38660
38799
  return VERSION$2;
38661
38800
  }
38801
+ /**
38802
+ * @internal
38803
+ */
38662
38804
  get events() {
38663
38805
  return {
38664
38806
  'click button': 'togglePictureInPicture',
@@ -38667,12 +38809,18 @@ class PictureInPicture extends UICorePlugin {
38667
38809
  get videoElement() {
38668
38810
  return this.core.activePlayback.el;
38669
38811
  }
38812
+ /**
38813
+ * @internal
38814
+ */
38670
38815
  bindEvents() {
38671
38816
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.render);
38672
38817
  }
38673
38818
  isPiPSupported() {
38674
38819
  return document.pictureInPictureEnabled && !!HTMLVideoElement.prototype.requestPictureInPicture;
38675
38820
  }
38821
+ /**
38822
+ * @internal
38823
+ */
38676
38824
  render() {
38677
38825
  if (!this.isPiPSupported()) {
38678
38826
  return this;
@@ -38694,7 +38842,7 @@ class PictureInPicture extends UICorePlugin {
38694
38842
  }
38695
38843
  }
38696
38844
  requestPictureInPicture() {
38697
- trace(`${T$5} requestPictureInPicture`, {
38845
+ trace(`${T$6} requestPictureInPicture`, {
38698
38846
  videoElement: !!this.videoElement,
38699
38847
  });
38700
38848
  this.videoElement.requestPictureInPicture();
@@ -38724,26 +38872,51 @@ const DEFAULT_PLAYBACK_RATES = [
38724
38872
  const DEFAULT_PLAYBACK_RATE = '1.0';
38725
38873
  // TODO
38726
38874
  const MEDIACONTROL_PLAYBACKRATE = 'playbackRate';
38875
+ /**
38876
+ * Allows changing the playback speed of the video.
38877
+ * @beta
38878
+ *
38879
+ * @remarks
38880
+ * Depends on:
38881
+ *
38882
+ * - {@link MediaControl | media_control}
38883
+ *
38884
+ * - {@link BottomGear | bottom_gear}
38885
+ *
38886
+ * It renders a button in the gear menu, which opens a dropdown with the available playback rates.
38887
+ */
38727
38888
  class PlaybackRate extends UICorePlugin {
38728
38889
  currentPlayback = null;
38729
38890
  playbackRates = DEFAULT_PLAYBACK_RATES;
38730
38891
  prevSelectedRate;
38731
38892
  selectedRate = DEFAULT_PLAYBACK_RATE;
38893
+ /**
38894
+ * @internal
38895
+ */
38732
38896
  get name() {
38733
- return 'media_control_playback_rate';
38897
+ return 'playback_rate';
38734
38898
  }
38899
+ /**
38900
+ * @internal
38901
+ */
38735
38902
  get supportedVersion() {
38736
38903
  return { min: CLAPPR_VERSION };
38737
38904
  }
38738
- get template() {
38739
- return tmpl(pluginHtml$3);
38740
- }
38905
+ static template = tmpl(pluginHtml$3);
38906
+ static buttonTemplate = tmpl(buttonHtml);
38907
+ static listTemplate = tmpl(listHtml);
38908
+ /**
38909
+ * @internal
38910
+ */
38741
38911
  get attributes() {
38742
38912
  return {
38743
38913
  'class': this.name,
38744
38914
  'data-playback-rate-select': ''
38745
38915
  };
38746
38916
  }
38917
+ /**
38918
+ * @internal
38919
+ */
38747
38920
  get events() {
38748
38921
  return {
38749
38922
  'click .gear-sub-menu_btn': 'onRateSelect',
@@ -38751,8 +38924,12 @@ class PlaybackRate extends UICorePlugin {
38751
38924
  'click .go-back': 'goBack',
38752
38925
  };
38753
38926
  }
38927
+ /**
38928
+ * @internal
38929
+ */
38754
38930
  bindEvents() {
38755
38931
  this.listenTo(this.core, 'gear:rendered', this.render);
38932
+ // TODO this.core.getPlugin('media_control'), bottom_gear
38756
38933
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.reload);
38757
38934
  this.listenTo(this.core.mediaControl, MEDIACONTROL_PLAYBACKRATE, this.updatePlaybackRate);
38758
38935
  this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
@@ -38806,6 +38983,9 @@ class PlaybackRate extends UICorePlugin {
38806
38983
  this.currentPlayback = this.core.activePlayback;
38807
38984
  return !(this.currentPlayback?.tagName !== 'video' && this.currentPlayback?.tagName !== 'audio');
38808
38985
  }
38986
+ /**
38987
+ * @internal
38988
+ */
38809
38989
  render() {
38810
38990
  const container = this.core.activeContainer;
38811
38991
  if (this.core.getPlaybackType() === Playback.LIVE && !container.isDvrEnabled()) {
@@ -38819,9 +38999,7 @@ class PlaybackRate extends UICorePlugin {
38819
38999
  this.selectedRate = cfg.defaultValue || DEFAULT_PLAYBACK_RATE;
38820
39000
  }
38821
39001
  if (this.shouldRender()) {
38822
- const t = tmpl(buttonHtml);
38823
- // const html = t({ playbackRates: this.playbackRates, title: this.getTitle() });
38824
- const button = t({
39002
+ const button = PlaybackRate.buttonTemplate({
38825
39003
  title: this.getTitle(),
38826
39004
  speedIcon,
38827
39005
  arrowRightIcon,
@@ -38869,8 +39047,7 @@ class PlaybackRate extends UICorePlugin {
38869
39047
  return false;
38870
39048
  }
38871
39049
  onShowMenu() {
38872
- const t = tmpl(listHtml);
38873
- this.$el.html(t({
39050
+ this.$el.html(PlaybackRate.listTemplate({
38874
39051
  playbackRates: this.playbackRates,
38875
39052
  arrowLeftIcon,
38876
39053
  checkIcon,
@@ -38914,7 +39091,7 @@ const posterHTML = "<div class=\"play-wrapper\" data-poster></div>\n";
38914
39091
  //Copyright 2014 Globo.com Player authors. All rights reserved.
38915
39092
  // Use of this source code is governed by a BSD-style
38916
39093
  // license that can be found in the LICENSE file.
38917
- const T$4 = 'plugins.poster_custom';
39094
+ const T$5 = 'plugins.poster_custom';
38918
39095
  /**
38919
39096
  * Displays a poster image in the background and a big play button on top when playback is stopped
38920
39097
  * @beta
@@ -39022,7 +39199,7 @@ class Poster extends UIContainerPlugin {
39022
39199
  super.disable();
39023
39200
  }
39024
39201
  onError(error) {
39025
- trace(`${T$4} onError`, {
39202
+ trace(`${T$5} onError`, {
39026
39203
  enabled: this.enabled,
39027
39204
  });
39028
39205
  this.hasFatalError = error.level === PlayerError.Levels.FATAL;
@@ -39043,7 +39220,7 @@ class Poster extends UIContainerPlugin {
39043
39220
  this.update();
39044
39221
  }
39045
39222
  onStop() {
39046
- trace(`${T$4} onStop`, {
39223
+ trace(`${T$5} onStop`, {
39047
39224
  enabled: this.enabled,
39048
39225
  });
39049
39226
  this.hasStartedPlaying = false;
@@ -39051,7 +39228,7 @@ class Poster extends UIContainerPlugin {
39051
39228
  this.update();
39052
39229
  }
39053
39230
  updatePlayButton(show) {
39054
- trace(`${T$4} updatePlayButton`, {
39231
+ trace(`${T$5} updatePlayButton`, {
39055
39232
  chromeless: this.options.chromeless,
39056
39233
  allowUserInteraction: this.options.allowUserInteraction,
39057
39234
  });
@@ -39079,7 +39256,7 @@ class Poster extends UIContainerPlugin {
39079
39256
  this.$el.removeClass('clickable');
39080
39257
  }
39081
39258
  clicked() {
39082
- trace(`${T$4} clicked`, {
39259
+ trace(`${T$5} clicked`, {
39083
39260
  hasStartedPlaying: this.hasStartedPlaying,
39084
39261
  chromeless: this.options.chromeless,
39085
39262
  allowUserInteraction: this.options.allowUserInteraction,
@@ -39103,7 +39280,7 @@ class Poster extends UIContainerPlugin {
39103
39280
  return !this.container.playback.isAudioOnly;
39104
39281
  }
39105
39282
  update() {
39106
- trace(`${T$4} update`, {
39283
+ trace(`${T$5} update`, {
39107
39284
  shouldRender: this.shouldRender,
39108
39285
  });
39109
39286
  if (!this.shouldRender) {
@@ -39116,7 +39293,7 @@ class Poster extends UIContainerPlugin {
39116
39293
  this.updatePoster();
39117
39294
  }
39118
39295
  updatePoster() {
39119
- trace(`${T$4} updatePoster`, {
39296
+ trace(`${T$5} updatePoster`, {
39120
39297
  hasStartedPlaying: this.hasStartedPlaying,
39121
39298
  });
39122
39299
  if (!this.hasStartedPlaying) {
@@ -39131,7 +39308,7 @@ class Poster extends UIContainerPlugin {
39131
39308
  this.$el.show();
39132
39309
  }
39133
39310
  hidePoster() {
39134
- trace(`${T$4} hidePoster`, {
39311
+ trace(`${T$5} hidePoster`, {
39135
39312
  shouldHideOnPlay: this.shouldHideOnPlay(),
39136
39313
  });
39137
39314
  if (!this.options.disableMediaControl) {
@@ -39185,8 +39362,12 @@ const seekTimeHTML = "<span data-seek-time></span>\n<span data-duration></span>\
39185
39362
 
39186
39363
  // Copyright 2014 Globo.com Player authors. All rights reserved.
39187
39364
  // Use of this source code is governed by a BSD-style
39188
- // license that can be found in the LICENSE file.
39365
+ // license that can be found at https://github.com/clappr/clappr-plugins/blob/master/LICENSE
39189
39366
  const { formatTime } = Utils;
39367
+ /**
39368
+ * The plugin adds a seek time indicator to the media control UI.
39369
+ * @beta
39370
+ */
39190
39371
  class SeekTime extends UICorePlugin {
39191
39372
  get name() {
39192
39373
  return 'media_control_seek_time';
@@ -39343,6 +39524,9 @@ const fbIcon = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"32px\"
39343
39524
 
39344
39525
  const twIcon = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"32px\" height=\"32px\" viewBox=\"0 0 32 32\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <!-- Generator: Sketch 49 (51002) - http://www.bohemiancoding.com/sketch -->\n <title>twitter</title>\n <desc>Created with Sketch.</desc>\n <defs></defs>\n <g id=\"twitter\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <g fill-rule=\"nonzero\" id=\"Shape\">\n <path d=\"M32,30 C32,31.104 31.104,32 30,32 L2,32 C0.896,32 0,31.104 0,30 L0,2 C0,0.896 0.896,0 2,0 L30,0 C31.104,0 32,0.896 32,2 L32,30 Z\" fill=\"#55ACEE\"></path>\n <path class=\"icon-hover\" d=\"M25.987,9.894 C25.251,10.216 24.462,10.431 23.63,10.529 C24.48,10.031 25.13,9.24 25.436,8.298 C24.644,8.759 23.766,9.095 22.831,9.276 C22.083,8.491 21.017,8 19.838,8 C17.572,8 15.738,9.807 15.738,12.038 C15.738,12.352 15.774,12.663 15.842,12.96 C12.435,12.788 9.413,11.181 7.39,8.739 C7.038,9.336 6.834,10.029 6.834,10.771 C6.834,12.17 7.56,13.406 8.658,14.131 C7.987,14.109 7.354,13.928 6.802,13.625 C6.801,13.642 6.801,13.659 6.801,13.677 C6.801,15.632 8.215,17.266 10.091,17.637 C9.748,17.727 9.386,17.779 9.01,17.779 C8.746,17.779 8.49,17.755 8.24,17.707 C8.76,19.311 10.274,20.478 12.068,20.512 C10.67,21.594 8.9,22.24 6.979,22.24 C6.649,22.24 6.321,22.222 6,22.184 C7.814,23.329 9.971,23.997 12.287,23.997 C19.828,23.997 23.953,17.843 23.953,12.506 C23.953,12.333 23.948,12.156 23.941,11.985 C24.741,11.414 25.438,10.703 25.987,9.894 Z\" fill=\"#FFFFFF\"></path>\n </g>\n </g>\n</svg>";
39345
39526
 
39527
+ /**
39528
+ * The plugin adds a share button to the media control UI.
39529
+ */
39346
39530
  class Share extends UICorePlugin {
39347
39531
  hide = false;
39348
39532
  container = null;
@@ -39460,6 +39644,9 @@ class Share extends UICorePlugin {
39460
39644
 
39461
39645
  const pluginHtml$1 = "<div class=\"skip-container\" data-skip-container>\n <div class=\"skip-item\" data-skip-left>\n </div>\n <div class=\"skip-item\" data-skip-mid>\n </div>\n <div class=\"skip-item\" data-skip-right>\n </div>\n</div>\n";
39462
39646
 
39647
+ /**
39648
+ * The plugin adds skip controls to the media control UI.
39649
+ */
39463
39650
  class SkipTime extends UICorePlugin {
39464
39651
  get name() {
39465
39652
  return 'skip_time';
@@ -39568,7 +39755,7 @@ const spinnerHTML = "<div data-bounce1></div>\n<div data-bounce2></div>\n<div da
39568
39755
  // Copyright 2014 Globo.com Player authors. All rights reserved.
39569
39756
  // Use of this source code is governed by a BSD-style
39570
39757
  // license that can be found in the LICENSE file.
39571
- const T$3 = 'plugins.spinner';
39758
+ const T$4 = 'plugins.spinner';
39572
39759
  /**
39573
39760
  * Custom events emitted by the plugin
39574
39761
  */
@@ -39636,7 +39823,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
39636
39823
  this.hide();
39637
39824
  }
39638
39825
  onStop() {
39639
- trace(`${T$3} onStop`, {
39826
+ trace(`${T$4} onStop`, {
39640
39827
  showOnError: this.options.spinner?.showOnError,
39641
39828
  hasFatalError: this.hasFatalError,
39642
39829
  });
@@ -39646,7 +39833,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
39646
39833
  }
39647
39834
  onError(e) {
39648
39835
  this.hasFatalError = e.code === PlaybackErrorCode.MediaSourceUnavailable;
39649
- trace(`${T$3} onError`, {
39836
+ trace(`${T$4} onError`, {
39650
39837
  showOnError: this.options.spinner?.showOnError,
39651
39838
  hasFatalError: this.hasFatalError,
39652
39839
  error: e.code,
@@ -39679,7 +39866,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
39679
39866
  */
39680
39867
  render() {
39681
39868
  const showOnStart = this.options.spinner?.showOnStart;
39682
- trace(`${T$3} render`, {
39869
+ trace(`${T$4} render`, {
39683
39870
  buffering: this.container.buffering});
39684
39871
  this.$el.html(this.template());
39685
39872
  this.el.firstElementChild?.addEventListener('animationiteration', () => {
@@ -39696,128 +39883,192 @@ class SpinnerThreeBounce extends UIContainerPlugin {
39696
39883
  }
39697
39884
  }
39698
39885
 
39699
- // An example implementation of client side performancestatistics
39700
- const CUSTOM_EVENTS_CONTAINER_START = 'container:start';
39701
- const WATCH_CUTOFF = 5;
39702
- const HEATMAP_INTERVAL = 10;
39703
- // TODO rewrite as core plugin
39704
- class Statistics extends ContainerPlugin {
39705
- get name() {
39706
- return 'statistics_gplayer';
39707
- }
39708
- get supportedVersion() {
39709
- return { min: CLAPPR_VERSION };
39710
- }
39711
- started = false;
39712
- timeStart = 0;
39713
- heatmapSent = false;
39714
- heatmapLastTime = 0;
39715
- watchSent = false;
39716
- bufTracking = false;
39717
- lags = 0;
39718
- /**
39719
- * The time when buffering last started.
39886
+ const T$3 = 'plugins.source_controller';
39887
+ const INITIAL_RETRY_DELAY = 1000;
39888
+ const MAX_RETRY_DELAY = 5000;
39889
+ const RETRY_DELAY_BLUR = 500;
39890
+ const VERSION$1 = '0.0.1';
39891
+ function noSync(cb) {
39892
+ queueMicrotask(cb);
39893
+ }
39894
+ /**
39895
+ * This plugin is responsible for managing the automatic failover between sources.
39896
+ * @beta
39897
+ * @remarks
39898
+ * Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
39899
+ * on how sources ordering and selection works.
39900
+ *
39901
+ * This plugin does not expose any public methods apart from required by the Clappr plugin interface.
39902
+ * It is supposed to work autonomously.
39903
+ *
39904
+ * @example
39905
+ * ```ts
39906
+ * import { SourceController } from '@gcorevideo/player'
39907
+ *
39908
+ * Player.registerPlugin(SourceController)
39909
+ * ```
39910
+ */
39911
+ class SourceController extends CorePlugin {
39912
+ /*
39913
+ * The Logic itself is quite simple:
39914
+ * * Here is the short diagram:
39915
+ *
39916
+ * sources_list:
39917
+ * - a.mpd | +--------------------+
39918
+ * - b.m3u8 |--->| init |
39919
+ * - ... | |--------------------|
39920
+ * | current_source = 0 |
39921
+ * +--------------------+
39922
+ * |
39923
+ * | source = a.mpd
39924
+ * | playback = dash.js
39925
+ * v
39926
+ * +------------------+
39927
+ * +-->| load source |
39928
+ * | +---------|--------+
39929
+ * | v
39930
+ * | +------------------+
39931
+ * | | play |
39932
+ * | +---------|--------+
39933
+ * | |
39934
+ * | v
39935
+ * | +-----------------------+
39936
+ * | | on playback_error |
39937
+ * | |-----------------------|
39938
+ * | | current_source = |
39939
+ * | | (current_source + 1) |
39940
+ * | | % len sources_list |
39941
+ * | | |
39942
+ * | | delay 1..3s |
39943
+ * | +---------------|-------+
39944
+ * | |
39945
+ * | source=b.m3u8 |
39946
+ * | playback=hls.js |
39947
+ * +-------------------+
39948
+ *
39720
39949
  */
39721
- bufLastStarted = 0;
39950
+ sourcesList = [];
39951
+ currentSourceIndex = 0;
39952
+ sourcesDelay = {};
39953
+ active = false;
39954
+ sync = noSync;
39722
39955
  /**
39723
- * The accumulated buffering duration.
39956
+ * @internal
39724
39957
  */
39725
- bufAccDuration = 0;
39726
- constructor(container) {
39727
- super(container);
39728
- assert(this.options.statistics &&
39729
- typeof this.options.statistics.send === 'function', 'Statistics plugin requires statistics options');
39730
- }
39731
- bindEvents() {
39732
- // TODO remove this
39733
- this.listenToOnce(this.container, CUSTOM_EVENTS_CONTAINER_START, this.onStart);
39734
- this.listenToOnce(this.container, Events$1.CONTAINER_READY, this.onReady);
39735
- this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERING, this.onBuffering);
39736
- this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERFULL, this.onBufferFull);
39737
- this.listenTo(this.container.playback, Events$1.PLAYBACK_TIMEUPDATE, this.onTimeUpdateLive);
39738
- this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_START, this.startLevelSwitch);
39739
- this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_END, this.stopLevelSwitch);
39740
- }
39741
- startLevelSwitch() {
39742
- this.bufTracking = false;
39958
+ get name() {
39959
+ return 'source_controller';
39743
39960
  }
39744
- stopLevelSwitch() {
39745
- this.bufTracking = true;
39961
+ /**
39962
+ * @internal
39963
+ */
39964
+ get supportedVersion() {
39965
+ return { min: CLAPPR_VERSION };
39746
39966
  }
39747
- onBuffering() {
39748
- if (this.bufTracking) {
39749
- this.bufLastStarted = performance.now();
39967
+ constructor(core) {
39968
+ super(core);
39969
+ this.sourcesList = this.core.options.sources;
39970
+ if (this.core.options.source !== undefined) {
39971
+ // prevent Clappr from loading all sources simultaneously
39972
+ this.core.options.sources = [this.core.options.source];
39750
39973
  }
39751
- }
39752
- onBufferFull() {
39753
- if (this.bufTracking && this.bufLastStarted) {
39754
- this.bufAccDuration += performance.now() - this.bufLastStarted;
39755
- this.lags++;
39974
+ else {
39975
+ this.core.options.sources = this.core.options.sources.slice(0, 1);
39756
39976
  }
39757
- this.bufTracking = true;
39977
+ }
39978
+ /**
39979
+ * @internal
39980
+ */
39981
+ bindEvents() {
39982
+ super.bindEvents();
39983
+ this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, () => this.onReady());
39758
39984
  }
39759
39985
  onReady() {
39760
- this.initEvent();
39761
- if (this.options.autoPlay) {
39762
- this.onStart();
39986
+ trace(`${T$3} onReady`, {
39987
+ retrying: this.active,
39988
+ currentSource: this.sourcesList[this.currentSourceIndex],
39989
+ });
39990
+ const spinner = this.core.activeContainer?.getPlugin('spinner');
39991
+ if (spinner) {
39992
+ this.sync = (cb) => {
39993
+ spinner.once(SpinnerEvents.SYNC, cb);
39994
+ };
39995
+ }
39996
+ else {
39997
+ this.sync = noSync;
39998
+ }
39999
+ this.bindContainerEventListeners();
40000
+ if (this.active) {
40001
+ this.core.activeContainer?.getPlugin('poster_custom')?.disable();
40002
+ spinner?.show();
39763
40003
  }
39764
40004
  }
39765
- initEvent() {
39766
- this.sendMessage('init');
39767
- }
39768
- sendMessage(state) {
39769
- this.send(state, {
39770
- // embed_url: this.options.referer,
39771
- // user_agent: Browser.userAgent
40005
+ bindContainerEventListeners() {
40006
+ this.core.activePlayback.on(Events$1.PLAYBACK_ERROR, (error) => {
40007
+ trace(`${T$3} on PLAYBACK_ERROR`, {
40008
+ error: {
40009
+ code: error?.code,
40010
+ description: error?.description,
40011
+ level: error?.level,
40012
+ },
40013
+ retrying: this.active,
40014
+ currentSource: this.sourcesList[this.currentSourceIndex],
40015
+ });
40016
+ switch (error.code) {
40017
+ case PlaybackErrorCode.MediaSourceUnavailable:
40018
+ this.core.activeContainer?.getPlugin('poster_custom')?.disable();
40019
+ this.retryPlayback();
40020
+ break;
40021
+ }
39772
40022
  });
39773
- }
39774
- send(event, data = {}) {
39775
- this.options.statistics.send({
39776
- event,
39777
- type: this.container.getPlaybackType(),
39778
- ...data,
40023
+ this.core.activePlayback.on(Events$1.PLAYBACK_PLAY, () => {
40024
+ trace(`${T$3} on PLAYBACK_PLAY`, {
40025
+ currentSource: this.sourcesList[this.currentSourceIndex],
40026
+ retrying: this.active,
40027
+ });
40028
+ if (this.active) {
40029
+ this.reset();
40030
+ // TODO make poster reset its state on enable
40031
+ this.core.activeContainer?.getPlugin('poster_custom')?.enable();
40032
+ this.core.activeContainer?.getPlugin('spinner')?.hide();
40033
+ }
39779
40034
  });
39780
40035
  }
39781
- sendHeatmap(time) {
39782
- const res = {
39783
- buffering: Math.round(this.bufAccDuration),
39784
- lags: this.lags,
39785
- };
39786
- this.bufAccDuration = 0;
39787
- this.lags = 0;
39788
- if (this.container.getPlaybackType() === Playback.VOD) {
39789
- res.timestamp = time;
39790
- }
39791
- this.send('heatmap', res);
39792
- this.heatmapSent = true;
39793
- this.heatmapLastTime = time;
40036
+ reset() {
40037
+ this.active = false;
40038
+ this.sourcesDelay = {};
39794
40039
  }
39795
- onTimeUpdateLive({ current }) {
39796
- // TODO check the `current` values for the live streams
39797
- if (!this.timeStart) {
39798
- this.timeStart = current;
39799
- }
39800
- try {
39801
- const elapsed = current - this.timeStart;
39802
- const heatmapElapsed = current - this.heatmapLastTime;
39803
- // TODO check if the heatmap is only needed for the live streams
39804
- if (!this.heatmapSent || heatmapElapsed >= HEATMAP_INTERVAL) {
39805
- this.sendHeatmap(current);
39806
- }
39807
- if (!this.watchSent && elapsed >= WATCH_CUTOFF) {
39808
- this.watchSent = true;
39809
- this.sendMessage('watch');
39810
- }
39811
- }
39812
- catch (error) {
39813
- }
40040
+ retryPlayback() {
40041
+ trace(`${T$3} retryPlayback enter`, {
40042
+ currentSourceIndex: this.currentSourceIndex,
40043
+ currentSource: this.sourcesList[this.currentSourceIndex],
40044
+ });
40045
+ this.active = true;
40046
+ this.getNextMediaSource().then((nextSource) => {
40047
+ const rnd = RETRY_DELAY_BLUR * Math.random();
40048
+ this.sync(() => {
40049
+ this.core.load(nextSource.source, nextSource.mimeType);
40050
+ setTimeout(() => {
40051
+ // this.core.activePlayback.consent()
40052
+ this.core.activePlayback.play();
40053
+ }, rnd);
40054
+ });
40055
+ });
39814
40056
  }
39815
- onStart() {
39816
- if (this.started) {
39817
- return;
39818
- }
39819
- this.started = true;
39820
- this.sendMessage('start');
40057
+ getNextMediaSource() {
40058
+ return new Promise((resolve) => {
40059
+ this.sourcesDelay[this.currentSourceIndex] = Math.min(MAX_RETRY_DELAY, (this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY) * 2);
40060
+ this.currentSourceIndex =
40061
+ (this.currentSourceIndex + 1) % this.sourcesList.length;
40062
+ const delay = this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY;
40063
+ const s = this.sourcesList[this.currentSourceIndex];
40064
+ setTimeout(() => resolve(s), delay);
40065
+ });
40066
+ }
40067
+ /**
40068
+ * @internal
40069
+ */
40070
+ static get version() {
40071
+ return VERSION$1;
39821
40072
  }
39822
40073
  }
39823
40074
 
@@ -39829,7 +40080,7 @@ const comboboxHTML = "<button data-subtitles-button class='media-control-button
39829
40080
 
39830
40081
  const stringHTML = "<div class=\"subtitle-string\">\n <p></p>\n</div>\n";
39831
40082
 
39832
- const VERSION$1 = '2.19.14';
40083
+ const VERSION = '2.19.14';
39833
40084
  const LOCAL_STORAGE_SUBTITLES_ID = 'gplayer.plugins.subtitles.selected';
39834
40085
  const T$2 = 'plugins.subtitles';
39835
40086
  const NO_TRACK = { language: 'off' };
@@ -39883,7 +40134,7 @@ class Subtitles extends UICorePlugin {
39883
40134
  * @internal
39884
40135
  */
39885
40136
  static get version() {
39886
- return VERSION$1;
40137
+ return VERSION;
39887
40138
  }
39888
40139
  static template = tmpl(comboboxHTML);
39889
40140
  static templateString = tmpl(stringHTML);
@@ -40153,40 +40404,217 @@ class Subtitles extends UICorePlugin {
40153
40404
  this.tracks[i].mode = 'hidden';
40154
40405
  }
40155
40406
  }
40156
- }
40157
- setSubtitleText(text) {
40158
- this.$string.find('p').html(text);
40159
- }
40160
- clearSubtitleText() {
40161
- this.setSubtitleText('');
40162
- }
40163
- updateCurrentLevel(track) {
40164
- this.currentLevel = track;
40165
- if (track.language === 'off') {
40166
- this.hide();
40167
- }
40168
- else {
40169
- this.show();
40407
+ }
40408
+ setSubtitleText(text) {
40409
+ this.$string.find('p').html(text);
40410
+ }
40411
+ clearSubtitleText() {
40412
+ this.setSubtitleText('');
40413
+ }
40414
+ updateCurrentLevel(track) {
40415
+ this.currentLevel = track;
40416
+ if (track.language === 'off') {
40417
+ this.hide();
40418
+ }
40419
+ else {
40420
+ this.show();
40421
+ }
40422
+ this.selectSubtitles();
40423
+ this.highlightCurrentSubtitles();
40424
+ }
40425
+ highlightCurrentSubtitles() {
40426
+ this.levelElement().removeClass('current');
40427
+ this.levelElement().find('a').removeClass('gcore-skin-active');
40428
+ if (this.currentLevel) {
40429
+ const currentLevelElement = this.levelElement(this.currentLevel.language);
40430
+ currentLevelElement.addClass('current');
40431
+ currentLevelElement.find('a').addClass('gcore-skin-active');
40432
+ }
40433
+ }
40434
+ renderIcon() {
40435
+ const icon = this.isShowing ? subtitlesOnIcon : subtitlesOffIcon;
40436
+ this.core
40437
+ .getPlugin('media_control')
40438
+ .getElement('subtitlesSelector')
40439
+ ?.find('span.subtitle-text')
40440
+ .html(icon);
40441
+ }
40442
+ }
40443
+
40444
+ // An example implementation of client side performancestatistics
40445
+ const WATCH_CUTOFF = 5;
40446
+ const STALL_MEASURE_PERIOD = 10;
40447
+ const T$1 = 'plugins.telemetry';
40448
+ /**
40449
+ * Telemetry event type
40450
+ * @beta
40451
+ */
40452
+ var TelemetryEvent;
40453
+ (function (TelemetryEvent) {
40454
+ TelemetryEvent[TelemetryEvent["Init"] = 1] = "Init";
40455
+ TelemetryEvent[TelemetryEvent["Start"] = 2] = "Start";
40456
+ TelemetryEvent[TelemetryEvent["Watch"] = 3] = "Watch";
40457
+ TelemetryEvent[TelemetryEvent["Stall"] = 4] = "Stall";
40458
+ })(TelemetryEvent || (TelemetryEvent = {}));
40459
+ /**
40460
+ * Collects and reports the performance statistics.
40461
+ * @beta
40462
+ * @remarks
40463
+ * This plugin is experimental and its API is likely to change.
40464
+ *
40465
+ * Configuration options {@link TelemetryPluginSettings}
40466
+ *
40467
+ * @example
40468
+ * ```ts
40469
+ * import { Statistics } from '@gcorevideo/player'
40470
+ *
40471
+ * Player.registerPlugin(Statistics)
40472
+ *
40473
+ * const player = new Player({
40474
+ * statistics: {
40475
+ * send: (data) => {
40476
+ * fetch('/stats', {
40477
+ * method: 'POST',
40478
+ * body: JSON.stringify(data),
40479
+ * headers: { 'content-type': 'application/json' },
40480
+ * })
40481
+ * },
40482
+ * },
40483
+ * ...
40484
+ * })
40485
+ * ```
40486
+ */
40487
+ class Telemetry extends ContainerPlugin {
40488
+ /**
40489
+ * The name of the plugin.
40490
+ */
40491
+ get name() {
40492
+ return 'telemetry';
40493
+ }
40494
+ /**
40495
+ * The supported version of the plugin.
40496
+ */
40497
+ get supportedVersion() {
40498
+ return { min: CLAPPR_VERSION };
40499
+ }
40500
+ started = false;
40501
+ timeStart = 0;
40502
+ stallSent = false;
40503
+ stallLastTime = 0;
40504
+ watchSent = false;
40505
+ bufTracking = false;
40506
+ numStalls = 0;
40507
+ /**
40508
+ * The time when buffering last started.
40509
+ */
40510
+ bufLastStarted = 0;
40511
+ /**
40512
+ * The accumulated buffering duration.
40513
+ */
40514
+ stallAcc = 0;
40515
+ constructor(container) {
40516
+ super(container);
40517
+ assert(this.options.telemetry &&
40518
+ typeof this.options.telemetry.send === 'function', 'Telemetry plugin configuration is invalid: `send` option is required');
40519
+ }
40520
+ /**
40521
+ * @internal
40522
+ */
40523
+ bindEvents() {
40524
+ // TODO remove this
40525
+ // this.listenToOnce(
40526
+ // this.container,
40527
+ // CUSTOM_EVENTS_CONTAINER_START,
40528
+ // this.onStart,
40529
+ // )
40530
+ this.listenToOnce(this.container, Events$1.CONTAINER_READY, this.onReady);
40531
+ this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERING, this.onBuffering);
40532
+ this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERFULL, this.onBufferFull);
40533
+ this.listenTo(this.container.playback, Events$1.PLAYBACK_TIMEUPDATE, this.onTimeUpdate);
40534
+ this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_START, this.startLevelSwitch);
40535
+ this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_END, this.endLevelSwitch);
40536
+ }
40537
+ startLevelSwitch() {
40538
+ this.bufTracking = false;
40539
+ }
40540
+ endLevelSwitch() {
40541
+ this.bufTracking = true;
40542
+ }
40543
+ onBuffering() {
40544
+ if (this.bufTracking) {
40545
+ this.bufLastStarted = performance.now();
40546
+ }
40547
+ }
40548
+ onBufferFull() {
40549
+ if (this.bufTracking && this.bufLastStarted) {
40550
+ this.stallAcc += performance.now() - this.bufLastStarted;
40551
+ this.numStalls++;
40552
+ }
40553
+ this.bufTracking = true;
40554
+ }
40555
+ onReady() {
40556
+ this.sendInit();
40557
+ trace(`${T$1} onReady`, {
40558
+ autoPlay: this.options.autoPlay,
40559
+ });
40560
+ if (this.options.autoPlay) {
40561
+ this.onStart();
40562
+ }
40563
+ else {
40564
+ this.listenToOnce(this.container.playback, Events$1.PLAYBACK_PLAY_INTENT, this.onStart);
40565
+ }
40566
+ }
40567
+ sendInit() {
40568
+ this.send({ event: TelemetryEvent.Init });
40569
+ }
40570
+ send(event) {
40571
+ this.options.telemetry.send({
40572
+ type: this.container.getPlaybackType(),
40573
+ ...event,
40574
+ });
40575
+ }
40576
+ sendStall(time) {
40577
+ // TODO don't send if no stalls?
40578
+ const res = {
40579
+ event: TelemetryEvent.Stall,
40580
+ count: this.numStalls,
40581
+ time,
40582
+ total_ms: Math.round(this.stallAcc * 1000),
40583
+ };
40584
+ this.stallAcc = 0;
40585
+ this.numStalls = 0;
40586
+ this.send(res);
40587
+ this.stallSent = true;
40588
+ this.stallLastTime = time;
40589
+ }
40590
+ onTimeUpdate({ current }) {
40591
+ if (!this.timeStart) {
40592
+ this.timeStart = current;
40593
+ }
40594
+ try {
40595
+ const elapsed = current - this.timeStart;
40596
+ const stallElapsed = current - this.stallLastTime;
40597
+ if (!this.stallSent || stallElapsed >= STALL_MEASURE_PERIOD) {
40598
+ this.sendStall(current);
40599
+ }
40600
+ if (!this.watchSent && elapsed >= WATCH_CUTOFF) {
40601
+ this.watchSent = true;
40602
+ this.send({
40603
+ event: TelemetryEvent.Watch,
40604
+ });
40605
+ }
40606
+ }
40607
+ catch (error) {
40170
40608
  }
40171
- this.selectSubtitles();
40172
- this.highlightCurrentSubtitles();
40173
40609
  }
40174
- highlightCurrentSubtitles() {
40175
- this.levelElement().removeClass('current');
40176
- this.levelElement().find('a').removeClass('gcore-skin-active');
40177
- if (this.currentLevel) {
40178
- const currentLevelElement = this.levelElement(this.currentLevel.language);
40179
- currentLevelElement.addClass('current');
40180
- currentLevelElement.find('a').addClass('gcore-skin-active');
40610
+ onStart() {
40611
+ if (this.started) {
40612
+ return;
40181
40613
  }
40182
- }
40183
- renderIcon() {
40184
- const icon = this.isShowing ? subtitlesOnIcon : subtitlesOffIcon;
40185
- this.core
40186
- .getPlugin('media_control')
40187
- .getElement('subtitlesSelector')
40188
- ?.find('span.subtitle-text')
40189
- .html(icon);
40614
+ this.started = true;
40615
+ this.send({
40616
+ event: TelemetryEvent.Start,
40617
+ });
40190
40618
  }
40191
40619
  }
40192
40620
 
@@ -40306,7 +40734,29 @@ const parseSRT = /*@__PURE__*/getDefaultExportFromCjs(parseSrtExports);
40306
40734
 
40307
40735
  const pluginHtml = "<div class=\"thumbnails-text\"></div>\n<% if (backdropHeight) { %>\n <div class=\"backdrop\" style=\"height: <%= backdropHeight %>px;\">\n <div class=\"carousel\"></div>\n </div>\n<% }; %>\n<% if (spotlightHeight) { %>\n <div class=\"spotlight\" style=\"height: <%= spotlightHeight %>px;\">\n </div>\n<% }; %>\n";
40308
40736
 
40309
- const T$1 = 'plugins.media_control_thumbnails';
40737
+ const T = 'plugins.thumbnails';
40738
+ /**
40739
+ * Displays the thumbnails of the video when available.
40740
+ * @beta
40741
+ * @example
40742
+ * ```ts
40743
+ * import { Thumbnails } from '@gcorevideo/player'
40744
+ *
40745
+ * Player.registerPlugin(Thumbnails)
40746
+ *
40747
+ * new Player({
40748
+ * thumbnails: {
40749
+ * backdropHeight: 200,
40750
+ * backdropMinOpacity: 0.9,
40751
+ * backdropMaxOpacity: 0.99,
40752
+ * spotlightHeight: 100,
40753
+ * vtt: '1\n00:00:00,000 --> 00:00:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,0,100,56\n\n2\n00:00:10,000 --> 00:00:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,0,100,56\n\n3\n00:00:20,000 --> 00:00:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,0,100,56\n\n4\n00:00:30,000 --> 00:00:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,0,100,56\n\n5\n00:00:40,000 --> 00:00:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,0,100,56\n\n6\n00:00:50,000 --> 00:01:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,0,100,56\n\n7\n00:01:00,000 --> 00:01:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,0,100,56\n\n8\n00:01:10,000 --> 00:01:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,56,100,56\n\n9\n00:01:20,000 --> 00:01:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,56,100,56\n\n10\n00:01:30,000 --> 00:01:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,56,100,56\n\n11\n00:01:40,000 --> 00:01:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,56,100,56\n\n12\n00:01:50,000 --> 00:02:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,56,100,56\n\n13\n00:02:00,000 --> 00:02:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,56,100,56\n\n14\n00:02:10,000 --> 00:02:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,56,100,56\n\n15\n00:02:20,000 --> 00:02:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,112,100,56\n\n16\n00:02:30,000 --> 00:02:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,112,100,56\n\n17\n00:02:40,000 --> 00:02:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,112,100,56\n\n18\n00:02:50,000 --> 00:03:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,112,100,56\n\n19\n00:03:00,000 --> 00:03:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,112,100,56\n\n20\n00:03:10,000 --> 00:03:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,112,100,56\n\n21\n00:03:20,000 --> 00:03:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,112,100,56\n\n22\n00:03:30,000 --> 00:03:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,168,100,56\n\n23\n00:03:40,000 --> 00:03:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,168,100,56\n\n24\n00:03:50,000 --> 00:04:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,168,100,56\n\n25\n00:04:00,000 --> 00:04:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,168,100,56\n\n26\n00:04:10,000 --> 00:04:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,168,100,56\n\n27\n00:04:20,000 --> 00:04:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,168,100,56\n\n28\n00:04:30,000 --> 00:04:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,168,100,56\n\n29\n00:04:40,000 --> 00:04:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,224,100,56\n\n30\n00:04:50,000 --> 00:05:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,224,100,56\n\n31\n00:05:00,000 --> 00:05:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,224,100,56\n\n32\n00:05:10,000 --> 00:05:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,224,100,56\n\n33\n00:05:20,000 --> 00:05:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,224,100,56\n\n34\n00:05:30,000 --> 00:05:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,224,100,56\n\n35\n00:05:40,000 --> 00:05:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,224,100,56\n\n36\n00:05:50,000 --> 00:06:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,280,100,56\n\n37\n00:06:00,000 --> 00:06:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,280,100,56\n\n38\n00:06:10,000 --> 00:06:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,280,100,56\n\n39\n00:06:20,000 --> 00:06:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,280,100,56\n\n40\n00:06:30,000 --> 00:06:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,280,100,56\n\n41\n00:06:40,000 --> 00:06:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,280,100,56\n\n42\n00:06:50,000 --> 00:07:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,280,100,56\n\n43\n00:07:00,000 --> 00:07:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=0,336,100,56\n\n44\n00:07:10,000 --> 00:07:20,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=100,336,100,56\n\n45\n00:07:20,000 --> 00:07:30,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=200,336,100,56\n\n46\n00:07:30,000 --> 00:07:40,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=300,336,100,56\n\n47\n00:07:40,000 --> 00:07:50,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=400,336,100,56\n\n48\n00:07:50,000 --> 00:08:00,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=500,336,100,56\n\n49\n00:08:00,000 --> 00:08:10,000\n3dk4NsRt6vWsffEr_sprite.jpg#xywh=600,336,100,56\n',
40754
+ * sprite:
40755
+ * 'https://static.gvideo.co/videoplatform/sprites/2675/2452164_3dk4NsRt6vWsffEr.mp4_sprite.jpg',
40756
+ * },
40757
+ * })
40758
+ * ```
40759
+ */
40310
40760
  class Thumbnails extends UICorePlugin {
40311
40761
  _$spotlight = null;
40312
40762
  _$backdrop = null;
@@ -40321,20 +40771,27 @@ class Thumbnails extends UICorePlugin {
40321
40771
  _thumbsLoaded = false;
40322
40772
  _oldContainer = null;
40323
40773
  _thumbs = [];
40774
+ /**
40775
+ * @internal
40776
+ */
40324
40777
  get name() {
40325
- return 'media_control_thumbnails';
40778
+ return 'thumbnails';
40326
40779
  }
40780
+ /**
40781
+ * @internal
40782
+ */
40327
40783
  get supportedVersion() {
40328
40784
  return { min: CLAPPR_VERSION };
40329
40785
  }
40786
+ /**
40787
+ * @internal
40788
+ */
40330
40789
  get attributes() {
40331
40790
  return {
40332
- 'class': this.name
40791
+ class: this.name,
40333
40792
  };
40334
40793
  }
40335
- get template() {
40336
- return tmpl(pluginHtml);
40337
- }
40794
+ static template = tmpl(pluginHtml);
40338
40795
  /*
40339
40796
  * Helper to build the "thumbs" property for a sprite sheet.
40340
40797
  *
@@ -40378,6 +40835,9 @@ class Thumbnails extends UICorePlugin {
40378
40835
  return thumbs;
40379
40836
  }
40380
40837
  // TODO check if seek enabled
40838
+ /**
40839
+ * @internal
40840
+ */
40381
40841
  bindEvents() {
40382
40842
  this.listenToOnce(this.core, Events$1.CORE_READY, this._onCoreReady);
40383
40843
  this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_MOUSEMOVE_SEEKBAR, this._onMouseMove);
@@ -40394,7 +40854,9 @@ class Thumbnails extends UICorePlugin {
40394
40854
  }
40395
40855
  _onCoreReady() {
40396
40856
  try {
40397
- if (!this.options.thumbnails || !this.options.thumbnails.sprite || !this.options.thumbnails.vtt) {
40857
+ if (!this.options.thumbnails ||
40858
+ !this.options.thumbnails.sprite ||
40859
+ !this.options.thumbnails.vtt) {
40398
40860
  this.destroy();
40399
40861
  return;
40400
40862
  }
@@ -40444,7 +40906,7 @@ class Thumbnails extends UICorePlugin {
40444
40906
  }
40445
40907
  _getOptions() {
40446
40908
  if (!('thumbnails' in this.core.options)) {
40447
- throw '\'thumbnail property missing from options object.';
40909
+ throw "'thumbnail property missing from options object.";
40448
40910
  }
40449
40911
  return this.core.options.thumbnails;
40450
40912
  }
@@ -40545,7 +41007,7 @@ class Thumbnails extends UICorePlugin {
40545
41007
  this.$img.css({
40546
41008
  height: this.spriteSheetHeight * scaleFactor,
40547
41009
  left: -1 * thumb.x * scaleFactor,
40548
- top: -1 * thumb.y * scaleFactor
41010
+ top: -1 * thumb.y * scaleFactor,
40549
41011
  });
40550
41012
  if (this.$container.find(this.$img).length === 0) {
40551
41013
  this.$container.append(this.$img);
@@ -40576,7 +41038,7 @@ class Thumbnails extends UICorePlugin {
40576
41038
  // calculate how far along the carousel should currently be slid
40577
41039
  // depending on where the user is hovering on the progress bar
40578
41040
  _updateCarousel() {
40579
- trace(`${T$1} _updateCarousel`, {
41041
+ trace(`${T} _updateCarousel`, {
40580
41042
  backdropHeight: this._getOptions().backdropHeight,
40581
41043
  });
40582
41044
  if (!this._getOptions().backdropHeight) {
@@ -40587,7 +41049,7 @@ class Thumbnails extends UICorePlugin {
40587
41049
  const videoDuration = this.core.mediaControl.container.getDuration();
40588
41050
  const startTimeOffset = this.core.mediaControl.container.getStartTimeOffset();
40589
41051
  // the time into the video at the current hover position
40590
- const hoverTime = startTimeOffset + (videoDuration * hoverPosition);
41052
+ const hoverTime = startTimeOffset + videoDuration * hoverPosition;
40591
41053
  const backdropWidth = this._$backdrop.width();
40592
41054
  const $carousel = this._$carousel;
40593
41055
  const carouselWidth = $carousel.width();
@@ -40612,9 +41074,9 @@ class Thumbnails extends UICorePlugin {
40612
41074
  const positionInThumb = timeIntoThumb / thumbDuration;
40613
41075
  const xCoordInThumb = thumbWidth * positionInThumb;
40614
41076
  // now calculate the position along carousel that we want to be above the hover position
40615
- const xCoordInCarousel = (thumbIndex * thumbWidth) + xCoordInThumb;
41077
+ const xCoordInCarousel = thumbIndex * thumbWidth + xCoordInThumb;
40616
41078
  // and finally the position of the carousel when the hover position is taken in to consideration
40617
- const carouselXCoord = xCoordInCarousel - (hoverPosition * backdropWidth);
41079
+ const carouselXCoord = xCoordInCarousel - hoverPosition * backdropWidth;
40618
41080
  $carousel.css('left', -carouselXCoord);
40619
41081
  const maxOpacity = this._getOptions().backdropMaxOpacity || 0.6;
40620
41082
  const minOpacity = this._getOptions().backdropMinOpacity || 0.08;
@@ -40630,12 +41092,12 @@ class Thumbnails extends UICorePlugin {
40630
41092
  distance = Math.min(0, distance + thumbWidth);
40631
41093
  }
40632
41094
  // fade over the width of 2 thumbnails
40633
- const opacity = Math.max(maxOpacity - (Math.abs(distance) / (2 * thumbWidth)), minOpacity);
41095
+ const opacity = Math.max(maxOpacity - Math.abs(distance) / (2 * thumbWidth), minOpacity);
40634
41096
  this._$backdropCarouselImgs[i].css('opacity', opacity);
40635
41097
  }
40636
41098
  }
40637
41099
  _updateSpotlightThumb() {
40638
- trace(`${T$1} _updateSpotlightThumb`, {
41100
+ trace(`${T} _updateSpotlightThumb`, {
40639
41101
  spotlightHeight: this._getOptions().spotlightHeight,
40640
41102
  });
40641
41103
  if (!this._getOptions().spotlightHeight) {
@@ -40646,7 +41108,7 @@ class Thumbnails extends UICorePlugin {
40646
41108
  const videoDuration = this.core.mediaControl.container.getDuration();
40647
41109
  // the time into the video at the current hover position
40648
41110
  const startTimeOffset = this.core.mediaControl.container.getStartTimeOffset();
40649
- const hoverTime = startTimeOffset + (videoDuration * hoverPosition);
41111
+ const hoverTime = startTimeOffset + videoDuration * hoverPosition;
40650
41112
  this.setText(hoverTime);
40651
41113
  // determine which thumbnail applies to the current time
40652
41114
  const thumbIndex = this._getThumbIndexForTime(hoverTime);
@@ -40658,7 +41120,7 @@ class Thumbnails extends UICorePlugin {
40658
41120
  const elWidth = this.$el.width();
40659
41121
  const thumbWidth = $spotlight.width();
40660
41122
  const thumbHeight = $spotlight.height();
40661
- let spotlightXPos = (elWidth * hoverPosition) - (thumbWidth / 2);
41123
+ let spotlightXPos = elWidth * hoverPosition - thumbWidth / 2;
40662
41124
  // adjust so the entire thumbnail is always visible
40663
41125
  spotlightXPos = Math.max(Math.min(spotlightXPos, elWidth - thumbWidth), 0);
40664
41126
  $spotlight.css('left', spotlightXPos);
@@ -40680,7 +41142,7 @@ class Thumbnails extends UICorePlugin {
40680
41142
  return 0;
40681
41143
  }
40682
41144
  _renderPlugin() {
40683
- trace(`${T$1} _renderPlugin`, {
41145
+ trace(`${T} _renderPlugin`, {
40684
41146
  show: this._show,
40685
41147
  thumbsLoaded: this._thumbsLoaded,
40686
41148
  thumbs: this._thumbs.length,
@@ -40698,9 +41160,9 @@ class Thumbnails extends UICorePlugin {
40698
41160
  }
40699
41161
  }
40700
41162
  _createElements() {
40701
- this.$el.html(this.template({
40702
- 'backdropHeight': this._getOptions().backdropHeight,
40703
- 'spotlightHeight': this._getOptions().spotlightHeight
41163
+ this.$el.html(Thumbnails.template({
41164
+ backdropHeight: this._getOptions().backdropHeight,
41165
+ spotlightHeight: this._getOptions().spotlightHeight,
40704
41166
  }));
40705
41167
  // cache dom references
40706
41168
  this._$spotlight = this.$el.find('.spotlight');
@@ -40712,200 +41174,12 @@ class Thumbnails extends UICorePlugin {
40712
41174
  }
40713
41175
  }
40714
41176
 
40715
- const T = 'plugins.source_controller';
40716
- const INITIAL_RETRY_DELAY = 1000;
40717
- const MAX_RETRY_DELAY = 5000;
40718
- const RETRY_DELAY_BLUR = 500;
40719
- const VERSION = '0.0.1';
40720
- function noSync(cb) {
40721
- queueMicrotask(cb);
40722
- }
40723
- /**
40724
- * This plugin is responsible for managing the automatic failover between sources.
40725
- * @beta
40726
- * @remarks
40727
- * Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
40728
- * on how sources ordering and selection works.
40729
- *
40730
- * This plugin does not expose any public methods apart from required by the Clappr plugin interface.
40731
- * It is supposed to work autonomously.
40732
- *
40733
- * @example
40734
- * ```ts
40735
- * import { SourceController } from '@gcorevideo/player'
40736
- *
40737
- * Player.registerPlugin(SourceController)
40738
- * ```
40739
- */
40740
- class SourceController extends CorePlugin {
40741
- /*
40742
- * The Logic itself is quite simple:
40743
- * * Here is the short diagram:
40744
- *
40745
- * sources_list:
40746
- * - a.mpd | +--------------------+
40747
- * - b.m3u8 |--->| init |
40748
- * - ... | |--------------------|
40749
- * | current_source = 0 |
40750
- * +--------------------+
40751
- * |
40752
- * | source = a.mpd
40753
- * | playback = dash.js
40754
- * v
40755
- * +------------------+
40756
- * +-->| load source |
40757
- * | +---------|--------+
40758
- * | v
40759
- * | +------------------+
40760
- * | | play |
40761
- * | +---------|--------+
40762
- * | |
40763
- * | v
40764
- * | +-----------------------+
40765
- * | | on playback_error |
40766
- * | |-----------------------|
40767
- * | | current_source = |
40768
- * | | (current_source + 1) |
40769
- * | | % len sources_list |
40770
- * | | |
40771
- * | | delay 1..3s |
40772
- * | +---------------|-------+
40773
- * | |
40774
- * | source=b.m3u8 |
40775
- * | playback=hls.js |
40776
- * +-------------------+
40777
- *
40778
- */
40779
- sourcesList = [];
40780
- currentSourceIndex = 0;
40781
- sourcesDelay = {};
40782
- active = false;
40783
- sync = noSync;
40784
- /**
40785
- * @internal
40786
- */
40787
- get name() {
40788
- return 'source_controller';
40789
- }
40790
- /**
40791
- * @internal
40792
- */
40793
- get supportedVersion() {
40794
- return { min: CLAPPR_VERSION };
40795
- }
40796
- constructor(core) {
40797
- super(core);
40798
- this.sourcesList = this.core.options.sources;
40799
- if (this.core.options.source !== undefined) {
40800
- // prevent Clappr from loading all sources simultaneously
40801
- this.core.options.sources = [this.core.options.source];
40802
- }
40803
- else {
40804
- this.core.options.sources = this.core.options.sources.slice(0, 1);
40805
- }
40806
- }
40807
- /**
40808
- * @internal
40809
- */
40810
- bindEvents() {
40811
- super.bindEvents();
40812
- this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, () => this.onReady());
40813
- }
40814
- onReady() {
40815
- trace(`${T} onReady`, {
40816
- retrying: this.active,
40817
- currentSource: this.sourcesList[this.currentSourceIndex],
40818
- });
40819
- const spinner = this.core.activeContainer?.getPlugin('spinner');
40820
- if (spinner) {
40821
- this.sync = (cb) => {
40822
- spinner.once(SpinnerEvents.SYNC, cb);
40823
- };
40824
- }
40825
- else {
40826
- this.sync = noSync;
40827
- }
40828
- this.bindContainerEventListeners();
40829
- if (this.active) {
40830
- this.core.activeContainer?.getPlugin('poster_custom')?.disable();
40831
- spinner?.show();
40832
- }
40833
- }
40834
- bindContainerEventListeners() {
40835
- this.core.activePlayback.on(Events$1.PLAYBACK_ERROR, (error) => {
40836
- trace(`${T} on PLAYBACK_ERROR`, {
40837
- error: {
40838
- code: error?.code,
40839
- description: error?.description,
40840
- level: error?.level,
40841
- },
40842
- retrying: this.active,
40843
- currentSource: this.sourcesList[this.currentSourceIndex],
40844
- });
40845
- switch (error.code) {
40846
- case PlaybackErrorCode.MediaSourceUnavailable:
40847
- this.core.activeContainer?.getPlugin('poster_custom')?.disable();
40848
- this.retryPlayback();
40849
- break;
40850
- }
40851
- });
40852
- this.core.activePlayback.on(Events$1.PLAYBACK_PLAY, () => {
40853
- trace(`${T} on PLAYBACK_PLAY`, {
40854
- currentSource: this.sourcesList[this.currentSourceIndex],
40855
- retrying: this.active,
40856
- });
40857
- if (this.active) {
40858
- this.reset();
40859
- // TODO make poster reset its state on enable
40860
- this.core.activeContainer?.getPlugin('poster_custom')?.enable();
40861
- this.core.activeContainer?.getPlugin('spinner')?.hide();
40862
- }
40863
- });
40864
- }
40865
- reset() {
40866
- this.active = false;
40867
- this.sourcesDelay = {};
40868
- }
40869
- retryPlayback() {
40870
- trace(`${T} retryPlayback enter`, {
40871
- currentSourceIndex: this.currentSourceIndex,
40872
- currentSource: this.sourcesList[this.currentSourceIndex],
40873
- });
40874
- this.active = true;
40875
- this.getNextMediaSource().then((nextSource) => {
40876
- const rnd = RETRY_DELAY_BLUR * Math.random();
40877
- this.sync(() => {
40878
- this.core.load(nextSource.source, nextSource.mimeType);
40879
- setTimeout(() => {
40880
- // this.core.activePlayback.consent()
40881
- this.core.activePlayback.play();
40882
- }, rnd);
40883
- });
40884
- });
40885
- }
40886
- getNextMediaSource() {
40887
- return new Promise((resolve) => {
40888
- this.sourcesDelay[this.currentSourceIndex] = Math.min(MAX_RETRY_DELAY, (this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY) * 2);
40889
- this.currentSourceIndex =
40890
- (this.currentSourceIndex + 1) % this.sourcesList.length;
40891
- const delay = this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY;
40892
- const s = this.sourcesList[this.currentSourceIndex];
40893
- setTimeout(() => resolve(s), delay);
40894
- });
40895
- }
40896
- /**
40897
- * @internal
40898
- */
40899
- static get version() {
40900
- return VERSION;
40901
- }
40902
- }
40903
-
40904
41177
  var VolumeFadeEvents;
40905
41178
  (function (VolumeFadeEvents) {
40906
41179
  VolumeFadeEvents["FADE"] = "core:volume:fade";
40907
41180
  })(VolumeFadeEvents || (VolumeFadeEvents = {}));
40908
41181
  /**
41182
+ * Applies fade effect to the player's volume change.
40909
41183
  * @beta
40910
41184
  */
40911
41185
  class VolumeFade extends UICorePlugin {
@@ -40913,15 +41187,22 @@ class VolumeFade extends UICorePlugin {
40913
41187
  container = null;
40914
41188
  delay = 0;
40915
41189
  interval = null;
41190
+ /**
41191
+ * @internal
41192
+ */
40916
41193
  get name() {
40917
41194
  return 'volume_fade';
40918
41195
  }
41196
+ /**
41197
+ * @internal
41198
+ */
40919
41199
  bindEvents() {
41200
+ // TODO on container changed
40920
41201
  this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
40921
41202
  if (this.core.mediaControl) {
40922
41203
  this.listenTo(this.core.mediaControl, 'mediacontrol:volume:user', this._onUserChangeVolume);
40923
41204
  }
40924
- this.listenTo(this.core, 'core:volume:config', this._onVolumeConfig);
41205
+ // this.listenTo(this.core, 'core:volume:config', this._onVolumeConfig);
40925
41206
  }
40926
41207
  unBindEvents() {
40927
41208
  this.core.$el.off('mouseleave.volume');
@@ -40991,4 +41272,4 @@ class VolumeFade extends UICorePlugin {
40991
41272
  }
40992
41273
  }
40993
41274
 
40994
- export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ContextMenu, DisableControls, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, Kibo, LevelSelector, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackRate, Poster, SeekTime, Share, SkipTime, SourceController, SpinnerEvents, SpinnerThreeBounce, Statistics, Subtitles, Thumbnails, VolumeFade, VolumeFadeEvents };
41275
+ export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ContextMenu, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, Kibo, LevelSelector, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackRate, Poster, SeekTime, Share, SkipTime, SourceController, SpinnerEvents, SpinnerThreeBounce, Subtitles, Telemetry, TelemetryEvent, Thumbnails, VolumeFade, VolumeFadeEvents };