@openrails/contentkit-ui 0.0.0-placeholder → 0.68.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (367) hide show
  1. package/README.md +424 -1
  2. package/dist/appearance.d.ts +38 -0
  3. package/dist/appearance.js +15 -0
  4. package/dist/appearance.js.map +1 -0
  5. package/dist/assets/hash.worker-BYfo-7MQ.js.map +1 -0
  6. package/dist/client/aspect.d.ts +6 -0
  7. package/dist/client/aspect.js +17 -0
  8. package/dist/client/aspect.js.map +1 -0
  9. package/dist/client/client.d.ts +51 -0
  10. package/dist/client/client.js +35 -0
  11. package/dist/client/client.js.map +1 -0
  12. package/dist/client/codes.d.ts +12 -0
  13. package/dist/client/codes.js +19 -0
  14. package/dist/client/codes.js.map +1 -0
  15. package/dist/client/content/bans.d.ts +15 -0
  16. package/dist/client/content/bans.js +40 -0
  17. package/dist/client/content/bans.js.map +1 -0
  18. package/dist/client/content/comments.d.ts +36 -0
  19. package/dist/client/content/comments.js +93 -0
  20. package/dist/client/content/comments.js.map +1 -0
  21. package/dist/client/content/favorites.d.ts +14 -0
  22. package/dist/client/content/favorites.js +42 -0
  23. package/dist/client/content/favorites.js.map +1 -0
  24. package/dist/client/content/moderation.d.ts +18 -0
  25. package/dist/client/content/moderation.js +37 -0
  26. package/dist/client/content/moderation.js.map +1 -0
  27. package/dist/client/content/polls.d.ts +47 -0
  28. package/dist/client/content/polls.js +148 -0
  29. package/dist/client/content/polls.js.map +1 -0
  30. package/dist/client/content/posts.d.ts +44 -0
  31. package/dist/client/content/posts.js +91 -0
  32. package/dist/client/content/posts.js.map +1 -0
  33. package/dist/client/content/reactions.d.ts +12 -0
  34. package/dist/client/content/reactions.js +36 -0
  35. package/dist/client/content/reactions.js.map +1 -0
  36. package/dist/client/content/types.d.ts +91 -0
  37. package/dist/client/content/types.js +8 -0
  38. package/dist/client/content/types.js.map +1 -0
  39. package/dist/client/crop.d.ts +32 -0
  40. package/dist/client/crop.js +103 -0
  41. package/dist/client/crop.js.map +1 -0
  42. package/dist/client/errors.d.ts +54 -0
  43. package/dist/client/errors.js +80 -0
  44. package/dist/client/errors.js.map +1 -0
  45. package/dist/client/gallery.d.ts +43 -0
  46. package/dist/client/gallery.js +86 -0
  47. package/dist/client/gallery.js.map +1 -0
  48. package/dist/client/generated/error-codes.d.ts +5 -0
  49. package/dist/client/generated/error-codes.js +131 -0
  50. package/dist/client/generated/error-codes.js.map +1 -0
  51. package/dist/client/generated/routes.d.ts +1086 -0
  52. package/dist/client/generated/routes.js +1400 -0
  53. package/dist/client/generated/routes.js.map +1 -0
  54. package/dist/client/generated/wire.d.ts +630 -0
  55. package/dist/client/generated/wire.js +6 -0
  56. package/dist/client/generated/wire.js.map +1 -0
  57. package/dist/client/http.d.ts +79 -0
  58. package/dist/client/http.js +74 -0
  59. package/dist/client/http.js.map +1 -0
  60. package/dist/client/image.d.ts +24 -0
  61. package/dist/client/image.js +65 -0
  62. package/dist/client/image.js.map +1 -0
  63. package/dist/client/index.d.ts +33 -0
  64. package/dist/client/media/api.d.ts +36 -0
  65. package/dist/client/media/api.js +61 -0
  66. package/dist/client/media/api.js.map +1 -0
  67. package/dist/client/media/client.d.ts +247 -0
  68. package/dist/client/media/client.js +407 -0
  69. package/dist/client/media/client.js.map +1 -0
  70. package/dist/client/media/encode.d.ts +3 -0
  71. package/dist/client/media/encode.js +8 -0
  72. package/dist/client/media/encode.js.map +1 -0
  73. package/dist/client/media/hash-stream.d.ts +6 -0
  74. package/dist/client/media/hash-stream.js +16 -0
  75. package/dist/client/media/hash-stream.js.map +1 -0
  76. package/dist/client/media/hash.d.ts +12 -0
  77. package/dist/client/media/hash.js +48 -0
  78. package/dist/client/media/hash.js.map +1 -0
  79. package/dist/client/media/hash.worker-inline.js +18 -0
  80. package/dist/client/media/hash.worker-inline.js.map +1 -0
  81. package/dist/client/media/pacer.d.ts +21 -0
  82. package/dist/client/media/pacer.js +25 -0
  83. package/dist/client/media/pacer.js.map +1 -0
  84. package/dist/client/media/queue.d.ts +112 -0
  85. package/dist/client/media/queue.js +274 -0
  86. package/dist/client/media/queue.js.map +1 -0
  87. package/dist/client/media/ref.d.ts +6 -0
  88. package/dist/client/media/ref.js +10 -0
  89. package/dist/client/media/ref.js.map +1 -0
  90. package/dist/client/media/rules.d.ts +52 -0
  91. package/dist/client/media/rules.js +139 -0
  92. package/dist/client/media/rules.js.map +1 -0
  93. package/dist/client/media/transport.d.ts +13 -0
  94. package/dist/client/media/transport.js +33 -0
  95. package/dist/client/media/transport.js.map +1 -0
  96. package/dist/client/media/windows.d.ts +15 -0
  97. package/dist/client/media/windows.js +39 -0
  98. package/dist/client/media/windows.js.map +1 -0
  99. package/dist/client/playback.d.ts +200 -0
  100. package/dist/client/playback.js +142 -0
  101. package/dist/client/playback.js.map +1 -0
  102. package/dist/client/player.d.ts +102 -0
  103. package/dist/client/player.js +155 -0
  104. package/dist/client/player.js.map +1 -0
  105. package/dist/client/public.d.ts +25 -0
  106. package/dist/client/public.js +18 -0
  107. package/dist/client/public.js.map +1 -0
  108. package/dist/client/rendition.d.ts +19 -0
  109. package/dist/client/rendition.js +16 -0
  110. package/dist/client/rendition.js.map +1 -0
  111. package/dist/client/route.d.ts +39 -0
  112. package/dist/client/route.js +31 -0
  113. package/dist/client/route.js.map +1 -0
  114. package/dist/client/taxonomy.d.ts +30 -0
  115. package/dist/client/taxonomy.js +77 -0
  116. package/dist/client/taxonomy.js.map +1 -0
  117. package/dist/client.js +33 -0
  118. package/dist/components/encode-progress.d.ts +15 -0
  119. package/dist/components/encode-progress.js +49 -0
  120. package/dist/components/encode-progress.js.map +1 -0
  121. package/dist/components/hover-preview.d.ts +29 -0
  122. package/dist/components/hover-preview.js +49 -0
  123. package/dist/components/hover-preview.js.map +1 -0
  124. package/dist/components/image-crop-dialog.d.ts +48 -0
  125. package/dist/components/image-crop-dialog.js +359 -0
  126. package/dist/components/image-crop-dialog.js.map +1 -0
  127. package/dist/components/lazy-mount.d.ts +10 -0
  128. package/dist/components/lazy-mount.js +22 -0
  129. package/dist/components/lazy-mount.js.map +1 -0
  130. package/dist/components/media-folder-editor.d.ts +45 -0
  131. package/dist/components/media-folder-editor.js +564 -0
  132. package/dist/components/media-folder-editor.js.map +1 -0
  133. package/dist/components/media-gallery.d.ts +54 -0
  134. package/dist/components/media-gallery.js +597 -0
  135. package/dist/components/media-gallery.js.map +1 -0
  136. package/dist/components/media-readiness-notice.d.ts +24 -0
  137. package/dist/components/media-readiness-notice.js +61 -0
  138. package/dist/components/media-readiness-notice.js.map +1 -0
  139. package/dist/components/player-controls.d.ts +71 -0
  140. package/dist/components/player-controls.js +264 -0
  141. package/dist/components/player-controls.js.map +1 -0
  142. package/dist/components/progress.d.ts +5 -0
  143. package/dist/components/progress.js +14 -0
  144. package/dist/components/progress.js.map +1 -0
  145. package/dist/components/rendition-img.d.ts +34 -0
  146. package/dist/components/rendition-img.js +78 -0
  147. package/dist/components/rendition-img.js.map +1 -0
  148. package/dist/components/slot-editor.d.ts +95 -0
  149. package/dist/components/slot-editor.js +182 -0
  150. package/dist/components/slot-editor.js.map +1 -0
  151. package/dist/components/slot-image.d.ts +23 -0
  152. package/dist/components/slot-image.js +48 -0
  153. package/dist/components/slot-image.js.map +1 -0
  154. package/dist/components/slot-upload.d.ts +41 -0
  155. package/dist/components/slot-upload.js +213 -0
  156. package/dist/components/slot-upload.js.map +1 -0
  157. package/dist/components/social/bans.d.ts +42 -0
  158. package/dist/components/social/bans.js +300 -0
  159. package/dist/components/social/bans.js.map +1 -0
  160. package/dist/components/social/comments.d.ts +42 -0
  161. package/dist/components/social/comments.js +517 -0
  162. package/dist/components/social/comments.js.map +1 -0
  163. package/dist/components/social/engagement.d.ts +45 -0
  164. package/dist/components/social/engagement.js +129 -0
  165. package/dist/components/social/engagement.js.map +1 -0
  166. package/dist/components/social/index.d.ts +6 -0
  167. package/dist/components/social/moderation.d.ts +32 -0
  168. package/dist/components/social/moderation.js +383 -0
  169. package/dist/components/social/moderation.js.map +1 -0
  170. package/dist/components/social/parts.d.ts +50 -0
  171. package/dist/components/social/parts.js +106 -0
  172. package/dist/components/social/parts.js.map +1 -0
  173. package/dist/components/social/poll-editor.d.ts +34 -0
  174. package/dist/components/social/poll-editor.js +567 -0
  175. package/dist/components/social/poll-editor.js.map +1 -0
  176. package/dist/components/social/poll.d.ts +30 -0
  177. package/dist/components/social/poll.js +252 -0
  178. package/dist/components/social/poll.js.map +1 -0
  179. package/dist/components/sortable-list.d.ts +29 -0
  180. package/dist/components/sortable-list.js +121 -0
  181. package/dist/components/sortable-list.js.map +1 -0
  182. package/dist/components/video-mini-player.d.ts +35 -0
  183. package/dist/components/video-mini-player.js +236 -0
  184. package/dist/components/video-mini-player.js.map +1 -0
  185. package/dist/components/video-player.d.ts +146 -0
  186. package/dist/components/video-player.js +630 -0
  187. package/dist/components/video-player.js.map +1 -0
  188. package/dist/components/video-poster-picker.d.ts +59 -0
  189. package/dist/components/video-poster-picker.js +335 -0
  190. package/dist/components/video-poster-picker.js.map +1 -0
  191. package/dist/components/video-poster.d.ts +24 -0
  192. package/dist/components/video-poster.js +46 -0
  193. package/dist/components/video-poster.js.map +1 -0
  194. package/dist/i18n/context.d.ts +4 -0
  195. package/dist/i18n/context.js +11 -0
  196. package/dist/i18n/context.js.map +1 -0
  197. package/dist/i18n/messages.d.ts +40 -0
  198. package/dist/i18n/messages.js +94 -0
  199. package/dist/i18n/messages.js.map +1 -0
  200. package/dist/index.d.ts +23 -0
  201. package/dist/index.js +41 -0
  202. package/dist/locales/de.d.ts +2 -0
  203. package/dist/locales/de.js +271 -0
  204. package/dist/locales/de.js.map +1 -0
  205. package/dist/locales/en.d.ts +457 -0
  206. package/dist/locales/en.js +271 -0
  207. package/dist/locales/en.js.map +1 -0
  208. package/dist/locales/es.d.ts +2 -0
  209. package/dist/locales/es.js +271 -0
  210. package/dist/locales/es.js.map +1 -0
  211. package/dist/locales/ja.d.ts +2 -0
  212. package/dist/locales/ja.js +271 -0
  213. package/dist/locales/ja.js.map +1 -0
  214. package/dist/locales/ko.d.ts +2 -0
  215. package/dist/locales/ko.js +271 -0
  216. package/dist/locales/ko.js.map +1 -0
  217. package/dist/locales/social/de.d.ts +2 -0
  218. package/dist/locales/social/de.js +198 -0
  219. package/dist/locales/social/de.js.map +1 -0
  220. package/dist/locales/social/en.d.ts +195 -0
  221. package/dist/locales/social/en.js +198 -0
  222. package/dist/locales/social/en.js.map +1 -0
  223. package/dist/locales/social/es.d.ts +2 -0
  224. package/dist/locales/social/es.js +198 -0
  225. package/dist/locales/social/es.js.map +1 -0
  226. package/dist/locales/social/ja.d.ts +2 -0
  227. package/dist/locales/social/ja.js +198 -0
  228. package/dist/locales/social/ja.js.map +1 -0
  229. package/dist/locales/social/ko.d.ts +2 -0
  230. package/dist/locales/social/ko.js +198 -0
  231. package/dist/locales/social/ko.js.map +1 -0
  232. package/dist/locales/social/zh.d.ts +2 -0
  233. package/dist/locales/social/zh.js +198 -0
  234. package/dist/locales/social/zh.js.map +1 -0
  235. package/dist/locales/zh.d.ts +2 -0
  236. package/dist/locales/zh.js +271 -0
  237. package/dist/locales/zh.js.map +1 -0
  238. package/dist/provider.d.ts +22 -0
  239. package/dist/provider.js +59 -0
  240. package/dist/provider.js.map +1 -0
  241. package/dist/react/canonical.d.ts +33 -0
  242. package/dist/react/canonical.js +88 -0
  243. package/dist/react/canonical.js.map +1 -0
  244. package/dist/react/comments.d.ts +82 -0
  245. package/dist/react/comments.js +147 -0
  246. package/dist/react/comments.js.map +1 -0
  247. package/dist/react/config.d.ts +13 -0
  248. package/dist/react/config.js +14 -0
  249. package/dist/react/config.js.map +1 -0
  250. package/dist/react/context.d.ts +48 -0
  251. package/dist/react/context.js +37 -0
  252. package/dist/react/context.js.map +1 -0
  253. package/dist/react/crop.d.ts +49 -0
  254. package/dist/react/crop.js +107 -0
  255. package/dist/react/crop.js.map +1 -0
  256. package/dist/react/engagement.d.ts +38 -0
  257. package/dist/react/engagement.js +88 -0
  258. package/dist/react/engagement.js.map +1 -0
  259. package/dist/react/folder.d.ts +83 -0
  260. package/dist/react/folder.js +183 -0
  261. package/dist/react/folder.js.map +1 -0
  262. package/dist/react/gallery.d.ts +140 -0
  263. package/dist/react/gallery.js +477 -0
  264. package/dist/react/gallery.js.map +1 -0
  265. package/dist/react/index.d.ts +21 -0
  266. package/dist/react/inline-preview.d.ts +24 -0
  267. package/dist/react/inline-preview.js +76 -0
  268. package/dist/react/inline-preview.js.map +1 -0
  269. package/dist/react/player.d.ts +70 -0
  270. package/dist/react/player.js +214 -0
  271. package/dist/react/player.js.map +1 -0
  272. package/dist/react/polls.d.ts +74 -0
  273. package/dist/react/polls.js +176 -0
  274. package/dist/react/polls.js.map +1 -0
  275. package/dist/react/posts.d.ts +59 -0
  276. package/dist/react/posts.js +149 -0
  277. package/dist/react/posts.js.map +1 -0
  278. package/dist/react/provider.d.ts +23 -0
  279. package/dist/react/provider.js +35 -0
  280. package/dist/react/provider.js.map +1 -0
  281. package/dist/react/public.d.ts +39 -0
  282. package/dist/react/public.js +70 -0
  283. package/dist/react/public.js.map +1 -0
  284. package/dist/react/read.d.ts +52 -0
  285. package/dist/react/read.js +143 -0
  286. package/dist/react/read.js.map +1 -0
  287. package/dist/react/resources.d.ts +70 -0
  288. package/dist/react/resources.js +247 -0
  289. package/dist/react/resources.js.map +1 -0
  290. package/dist/react/slot.d.ts +102 -0
  291. package/dist/react/slot.js +181 -0
  292. package/dist/react/slot.js.map +1 -0
  293. package/dist/react/store.d.ts +51 -0
  294. package/dist/react/store.js +164 -0
  295. package/dist/react/store.js.map +1 -0
  296. package/dist/react/upload.d.ts +85 -0
  297. package/dist/react/upload.js +150 -0
  298. package/dist/react/upload.js.map +1 -0
  299. package/dist/react/use-resource.d.ts +43 -0
  300. package/dist/react/use-resource.js +66 -0
  301. package/dist/react/use-resource.js.map +1 -0
  302. package/dist/react/video.d.ts +118 -0
  303. package/dist/react/video.js +184 -0
  304. package/dist/react/video.js.map +1 -0
  305. package/dist/react/viewport.d.ts +19 -0
  306. package/dist/react/viewport.js +30 -0
  307. package/dist/react/viewport.js.map +1 -0
  308. package/dist/react.js +21 -0
  309. package/dist/scope.d.ts +14 -0
  310. package/dist/scope.js +30 -0
  311. package/dist/scope.js.map +1 -0
  312. package/dist/styles.css +3 -0
  313. package/dist/ui/alert-dialog.d.ts +18 -0
  314. package/dist/ui/alert-dialog.js +86 -0
  315. package/dist/ui/alert-dialog.js.map +1 -0
  316. package/dist/ui/alert.d.ts +10 -0
  317. package/dist/ui/alert.js +38 -0
  318. package/dist/ui/alert.js.map +1 -0
  319. package/dist/ui/avatar.d.ts +11 -0
  320. package/dist/ui/avatar.js +31 -0
  321. package/dist/ui/avatar.js.map +1 -0
  322. package/dist/ui/badge.d.ts +7 -0
  323. package/dist/ui/badge.js +31 -0
  324. package/dist/ui/badge.js.map +1 -0
  325. package/dist/ui/button.d.ts +8 -0
  326. package/dist/ui/button.js +46 -0
  327. package/dist/ui/button.js.map +1 -0
  328. package/dist/ui/dialog.d.ts +17 -0
  329. package/dist/ui/dialog.js +91 -0
  330. package/dist/ui/dialog.js.map +1 -0
  331. package/dist/ui/dropdown-menu.d.ts +15 -0
  332. package/dist/ui/dropdown-menu.js +105 -0
  333. package/dist/ui/dropdown-menu.js.map +1 -0
  334. package/dist/ui/input.d.ts +3 -0
  335. package/dist/ui/input.js +17 -0
  336. package/dist/ui/input.js.map +1 -0
  337. package/dist/ui/label.d.ts +3 -0
  338. package/dist/ui/label.js +15 -0
  339. package/dist/ui/label.js.map +1 -0
  340. package/dist/ui/progress.d.ts +7 -0
  341. package/dist/ui/progress.js +31 -0
  342. package/dist/ui/progress.js.map +1 -0
  343. package/dist/ui/select.d.ts +15 -0
  344. package/dist/ui/select.js +98 -0
  345. package/dist/ui/select.js.map +1 -0
  346. package/dist/ui/skeleton.d.ts +2 -0
  347. package/dist/ui/skeleton.js +14 -0
  348. package/dist/ui/skeleton.js.map +1 -0
  349. package/dist/ui/slider.d.ts +3 -0
  350. package/dist/ui/slider.js +35 -0
  351. package/dist/ui/slider.js.map +1 -0
  352. package/dist/ui/switch.d.ts +5 -0
  353. package/dist/ui/switch.js +20 -0
  354. package/dist/ui/switch.js.map +1 -0
  355. package/dist/ui/tabs.d.ts +10 -0
  356. package/dist/ui/tabs.js +47 -0
  357. package/dist/ui/tabs.js.map +1 -0
  358. package/dist/ui/textarea.d.ts +3 -0
  359. package/dist/ui/textarea.js +15 -0
  360. package/dist/ui/textarea.js.map +1 -0
  361. package/dist/ui/toggle-group.d.ts +5 -0
  362. package/dist/ui/toggle-group.js +23 -0
  363. package/dist/ui/toggle-group.js.map +1 -0
  364. package/dist/urls/index.d.ts +100 -0
  365. package/dist/urls.js +118 -0
  366. package/dist/urls.js.map +1 -0
  367. package/package.json +113 -3
@@ -0,0 +1,39 @@
1
+ //#region src/client/media/windows.ts
2
+ var e = 50;
3
+ function t(e, t, n, r = 50) {
4
+ let i = [], a = n === void 0 ? t : Math.min(t, n);
5
+ if (e >= a) return i;
6
+ for (let t = Math.floor(Math.max(e, 0) / r) * r; t < a; t += r) i.push(t);
7
+ return i;
8
+ }
9
+ function n(e) {
10
+ let t = e.filter((e) => !!e);
11
+ if (t.length === 0) return null;
12
+ if (t.length === 1) return t[0];
13
+ let n = t.reduce((e, t) => t.expires >= e.expires ? t : e), r = /* @__PURE__ */ new Map();
14
+ for (let e of [...t].sort((e, t) => e.expires - t.expires)) for (let t of e.files) t.url && r.set(t.path, t);
15
+ let i = n.files.map((e) => {
16
+ if (e.url || e.locked) return e;
17
+ let t = r.get(e.path);
18
+ return t ? {
19
+ ...e,
20
+ url: t.url,
21
+ ...t.download ? { download: t.download } : {}
22
+ } : e;
23
+ }), a = Math.min(...t.map((e) => e.offset)), o = Math.max(...t.map((e) => e.offset + e.limit));
24
+ return {
25
+ ...n,
26
+ files: i,
27
+ offset: a,
28
+ limit: o - a,
29
+ expires: Math.min(...t.map((e) => e.expires))
30
+ };
31
+ }
32
+ var r = (e) => !!e.upload && !e.failed && (!!e.staged || (e.pending?.length ?? 0) > 0);
33
+ function i(e) {
34
+ return !e || e.full ? !1 : e.state === "processing" || e.files.some(r);
35
+ }
36
+ //#endregion
37
+ export { e as READ_CHUNK, t as chunkOffsets, r as isProcessing, n as mergeReads, i as processing };
38
+
39
+ //# sourceMappingURL=windows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows.js","names":[],"sources":["../../../src/client/media/windows.ts"],"sourcesContent":["import type { FileInfo, ReadResult } from \"../generated/wire.js\";\n\n/** Files per window when a read is split into windows. */\nexport const READ_CHUNK = 50;\n\n/** Offsets of chunk-sized windows covering files [start, end), clipped to total when known. */\nexport function chunkOffsets(start: number, end: number, total?: number, chunk = READ_CHUNK): number[] {\n const out: number[] = [];\n const stop = total === undefined ? end : Math.min(end, total);\n if (start >= stop) return out;\n for (let o = Math.floor(Math.max(start, 0) / chunk) * chunk; o < stop; o += chunk) out.push(o);\n return out;\n}\n\n/**\n * One item's window reads as one read: the newest window's listing and\n * metadata, each file's URL from the newest window that signed it, and the\n * earliest expiry. Every window lists every file; only its range has URLs.\n */\nexport function mergeReads(reads: readonly (ReadResult | null | undefined)[]): ReadResult | null {\n const present = reads.filter((r): r is ReadResult => !!r);\n if (present.length === 0) return null;\n if (present.length === 1) return present[0]!;\n const newest = present.reduce((a, b) => (b.expires >= a.expires ? b : a));\n const urls = new Map<string, FileInfo>();\n for (const r of [...present].sort((a, b) => a.expires - b.expires)) for (const f of r.files) if (f.url) urls.set(f.path, f);\n const files = newest.files.map((f) => {\n if (f.url || f.locked) return f;\n const signed = urls.get(f.path);\n return signed ? { ...f, url: signed.url, ...(signed.download ? { download: signed.download } : {}) } : f;\n });\n const start = Math.min(...present.map((r) => r.offset));\n const end = Math.max(...present.map((r) => r.offset + r.limit));\n return { ...newest, files, offset: start, limit: end - start, expires: Math.min(...present.map((r) => r.expires)) };\n}\n\n/** An upload the worker has not finished: staged, or with work pending, and not failed. */\nexport const isProcessing = (f: FileInfo) => !!f.upload && !f.failed && (!!f.staged || (f.pending?.length ?? 0) > 0);\n\n/** An editor read with uploads still processing (not stalled because the item is full). */\nexport function processing(read: ReadResult | null | undefined): boolean {\n if (!read || read.full) return false;\n return read.state === \"processing\" || read.files.some(isProcessing);\n}\n"],"mappings":";AAGA,IAAa,IAAa;AAG1B,SAAgB,EAAa,GAAe,GAAa,GAAgB,IAAA,IAA8B;CACrG,IAAM,IAAgB,CAAC,GACjB,IAAO,MAAU,KAAA,IAAY,IAAM,KAAK,IAAI,GAAK,CAAK;CAC5D,IAAI,KAAS,GAAM,OAAO;CAC1B,KAAK,IAAI,IAAI,KAAK,MAAM,KAAK,IAAI,GAAO,CAAC,IAAI,CAAK,IAAI,GAAO,IAAI,GAAM,KAAK,GAAO,EAAI,KAAK,CAAC;CAC7F,OAAO;AACT;AAOA,SAAgB,EAAW,GAAsE;CAC/F,IAAM,IAAU,EAAM,QAAQ,MAAuB,CAAC,CAAC,CAAC;CACxD,IAAI,EAAQ,WAAW,GAAG,OAAO;CACjC,IAAI,EAAQ,WAAW,GAAG,OAAO,EAAQ;CACzC,IAAM,IAAS,EAAQ,QAAQ,GAAG,MAAO,EAAE,WAAW,EAAE,UAAU,IAAI,CAAE,GAClE,oBAAO,IAAI,IAAsB;CACvC,KAAK,IAAM,KAAK,CAAC,GAAG,CAAO,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,KAAK,IAAM,KAAK,EAAE,OAAO,AAAI,EAAE,OAAK,EAAK,IAAI,EAAE,MAAM,CAAC;CAC1H,IAAM,IAAQ,EAAO,MAAM,KAAK,MAAM;EACpC,IAAI,EAAE,OAAO,EAAE,QAAQ,OAAO;EAC9B,IAAM,IAAS,EAAK,IAAI,EAAE,IAAI;EAC9B,OAAO,IAAS;GAAE,GAAG;GAAG,KAAK,EAAO;GAAK,GAAI,EAAO,WAAW,EAAE,UAAU,EAAO,SAAS,IAAI,CAAC;EAAG,IAAI;CACzG,CAAC,GACK,IAAQ,KAAK,IAAI,GAAG,EAAQ,KAAK,MAAM,EAAE,MAAM,CAAC,GAChD,IAAM,KAAK,IAAI,GAAG,EAAQ,KAAK,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC;CAC9D,OAAO;EAAE,GAAG;EAAQ;EAAO,QAAQ;EAAO,OAAO,IAAM;EAAO,SAAS,KAAK,IAAI,GAAG,EAAQ,KAAK,MAAM,EAAE,OAAO,CAAC;CAAE;AACpH;AAGA,IAAa,KAAgB,MAAgB,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,UAAU,KAAK;AAGlH,SAAgB,EAAW,GAA8C;CAEvE,OADI,CAAC,KAAQ,EAAK,OAAa,KACxB,EAAK,UAAU,gBAAgB,EAAK,MAAM,KAAK,CAAY;AACpE"}
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Why a video cannot play. `network` covers CORS too: browsers report a blocked
3
+ * cross-origin response exactly like an unreachable server (status 0).
4
+ */
5
+ export type PlaybackErrorKind = "network" | "access" | "not_found" | "rate_limited" | "unsupported" | "stalled" | "unknown";
6
+ export interface PlaybackError {
7
+ kind: PlaybackErrorKind;
8
+ /** Short support code, e.g. "fragLoadError/0" or "media/4". */
9
+ code: string;
10
+ status?: number;
11
+ }
12
+ /** The fields of hls.js ErrorData this reads. */
13
+ export interface HlsErrorLike {
14
+ type?: string;
15
+ details: string;
16
+ fatal?: boolean;
17
+ response?: {
18
+ code?: number;
19
+ } | null;
20
+ networkDetails?: unknown;
21
+ }
22
+ /** HTTP status → kind; 0 (or none) is a blocked or unreachable request. */
23
+ export declare function statusKind(status: number | undefined): PlaybackErrorKind;
24
+ /** Read again this long before the item token expires. */
25
+ export declare const REFRESH_BEFORE_EXPIRY = 60000;
26
+ /**
27
+ * Milliseconds until the read should be fetched again: shortly before
28
+ * `expires` (the read's, unix seconds), never sooner than 30 s; null when
29
+ * the read has no expiry. A read before the expiry answers the same token,
30
+ * so nothing is gained by reading earlier.
31
+ */
32
+ export declare function expiryDelay(expires: number | undefined, now?: number): number | null;
33
+ /**
34
+ * Worth one grant refresh and retry: 401/403, or a 404 — media-gateway answers a
35
+ * missing, expired or wrong token exactly like a missing object. A 429 (the
36
+ * ingress's rate limit) or a blocked request is not: it fails without a loop.
37
+ */
38
+ export declare function refreshable(e: PlaybackError): boolean;
39
+ export declare function classifyHlsError(d: HlsErrorLike): PlaybackError;
40
+ /** A native `<video>` error (Safari's HLS): 2 network, 3 decode, 4 unsupported source. */
41
+ export declare function classifyMediaError(e: {
42
+ code: number;
43
+ } | null | undefined): PlaybackError;
44
+ /** hls.js settings the player uses; spread under your own. */
45
+ export declare const hlsConfig: {
46
+ manifestLoadPolicy: {
47
+ default: {
48
+ maxTimeToFirstByteMs: number;
49
+ maxLoadTimeMs: number;
50
+ timeoutRetry: {
51
+ maxNumRetry: number;
52
+ retryDelayMs: number;
53
+ maxRetryDelayMs: number;
54
+ shouldRetry: (_c: unknown, _n: number, _t: boolean, res: {
55
+ code?: number;
56
+ } | undefined, fallback: boolean) => boolean;
57
+ };
58
+ errorRetry: {
59
+ maxNumRetry: number;
60
+ retryDelayMs: number;
61
+ maxRetryDelayMs: number;
62
+ shouldRetry: (_c: unknown, _n: number, _t: boolean, res: {
63
+ code?: number;
64
+ } | undefined, fallback: boolean) => boolean;
65
+ };
66
+ };
67
+ };
68
+ playlistLoadPolicy: {
69
+ default: {
70
+ maxTimeToFirstByteMs: number;
71
+ maxLoadTimeMs: number;
72
+ timeoutRetry: {
73
+ maxNumRetry: number;
74
+ retryDelayMs: number;
75
+ maxRetryDelayMs: number;
76
+ shouldRetry: (_c: unknown, _n: number, _t: boolean, res: {
77
+ code?: number;
78
+ } | undefined, fallback: boolean) => boolean;
79
+ };
80
+ errorRetry: {
81
+ maxNumRetry: number;
82
+ retryDelayMs: number;
83
+ maxRetryDelayMs: number;
84
+ shouldRetry: (_c: unknown, _n: number, _t: boolean, res: {
85
+ code?: number;
86
+ } | undefined, fallback: boolean) => boolean;
87
+ };
88
+ };
89
+ };
90
+ fragLoadPolicy: {
91
+ default: {
92
+ maxTimeToFirstByteMs: number;
93
+ maxLoadTimeMs: number;
94
+ timeoutRetry: {
95
+ maxNumRetry: number;
96
+ retryDelayMs: number;
97
+ maxRetryDelayMs: number;
98
+ shouldRetry: (_c: unknown, _n: number, _t: boolean, res: {
99
+ code?: number;
100
+ } | undefined, fallback: boolean) => boolean;
101
+ };
102
+ errorRetry: {
103
+ maxNumRetry: number;
104
+ retryDelayMs: number;
105
+ maxRetryDelayMs: number;
106
+ shouldRetry: (_c: unknown, _n: number, _t: boolean, res: {
107
+ code?: number;
108
+ } | undefined, fallback: boolean) => boolean;
109
+ };
110
+ };
111
+ };
112
+ keyLoadPolicy: {
113
+ default: {
114
+ maxTimeToFirstByteMs: number;
115
+ maxLoadTimeMs: number;
116
+ timeoutRetry: {
117
+ maxNumRetry: number;
118
+ retryDelayMs: number;
119
+ maxRetryDelayMs: number;
120
+ shouldRetry: (_c: unknown, _n: number, _t: boolean, res: {
121
+ code?: number;
122
+ } | undefined, fallback: boolean) => boolean;
123
+ };
124
+ errorRetry: {
125
+ maxNumRetry: number;
126
+ retryDelayMs: number;
127
+ maxRetryDelayMs: number;
128
+ shouldRetry: (_c: unknown, _n: number, _t: boolean, res: {
129
+ code?: number;
130
+ } | undefined, fallback: boolean) => boolean;
131
+ };
132
+ };
133
+ };
134
+ };
135
+ /** Non-fatal network failures (hls.js also tries other renditions) before the player gives up. */
136
+ export declare const NETWORK_FAILURES_BEFORE_ERROR = 3;
137
+ /** Adaptive-bitrate policy for the player; every field is optional. */
138
+ export interface AbrPolicy {
139
+ /** Start at, and never cap the display below, the rung of this short side (px) when bandwidth allows. Default 1080. */
140
+ minStartHeight?: number;
141
+ /** Never pick a rung with a larger short side (px). Default unlimited. */
142
+ maxHeight?: number;
143
+ /** false: stock hls.js start (500 kbps guess) and a strict display cap. Default true. */
144
+ preferHighRes?: boolean;
145
+ /** Bits/s assumed when neither a measurement nor `navigator.connection` is available. Default 8 Mbps. */
146
+ defaultEstimate?: number;
147
+ }
148
+ /** A rendition as hls.js levels describe it. */
149
+ export interface Rung {
150
+ width: number;
151
+ height: number;
152
+ /** Peak bits/s (BANDWIDTH). */
153
+ bitrate: number;
154
+ /** AVERAGE-BANDWIDTH when known. */
155
+ averageBitrate?: number;
156
+ }
157
+ /** What the browser says about the connection (Network Information API). */
158
+ export interface ConnectionHint {
159
+ downlink?: number;
160
+ saveData?: boolean;
161
+ }
162
+ export declare const ABR_DEFAULTS: {
163
+ readonly minStartHeight: 1080;
164
+ readonly maxHeight: number;
165
+ readonly preferHighRes: true;
166
+ readonly defaultEstimate: 8000000;
167
+ };
168
+ /**
169
+ * The highest rung index (rungs ascend by bitrate) worth loading for a display
170
+ * of width×height device pixels: the smallest rung covering the video's fitted
171
+ * box (to within 10%), never below the minStartHeight rung, never above maxHeight.
172
+ */
173
+ export declare function capRung(rungs: readonly Rung[], width: number, height: number, policy?: AbrPolicy): number;
174
+ /**
175
+ * Levels to remove (indices, descending) so one codec set remains: the set of
176
+ * the level hls.js lists first, which is the master playlist's first playable
177
+ * codec (AV1 or HEVC before H.264 when the browser decodes them). hls.js never
178
+ * switches codec sets for bandwidth, and the quality menu lists each rung once.
179
+ */
180
+ export declare function otherCodecLevels(levels: readonly {
181
+ codecSet?: string;
182
+ }[], first: number): number[];
183
+ /** Bits/s to seed the estimator with: a measurement from this page, the browser's downlink, else the policy default. */
184
+ export declare function initialEstimate(policy?: AbrPolicy, conn?: ConnectionHint | null, measured?: number): number;
185
+ /** The first rung to load: the lowest under Save-Data, else the highest under cap the estimate sustains. */
186
+ export declare function startRung(rungs: readonly Rung[], estimate: number, cap: number, conn?: ConnectionHint | null): number;
187
+ /** hls.js ABR settings: climb after a couple of good segments, drop before the buffer runs dry. */
188
+ export declare function abrHlsConfig(policy: AbrPolicy | undefined, estimate: number): {
189
+ abrEwmaDefaultEstimate: number;
190
+ abrEwmaDefaultEstimateMax: number;
191
+ abrEwmaFastVoD: number;
192
+ abrEwmaSlowVoD: number;
193
+ abrBandWidthUpFactor: number;
194
+ abrBandWidthFactor: number;
195
+ capLevelToPlayerSize: boolean;
196
+ ignoreDevicePixelRatio: boolean;
197
+ maxBufferLength: number;
198
+ maxMaxBufferLength: number;
199
+ backBufferLength: number;
200
+ };
@@ -0,0 +1,142 @@
1
+ //#region src/client/playback.ts
2
+ var e = /* @__PURE__ */ new Set([
3
+ "manifestParsingError",
4
+ "manifestIncompatibleCodecsError",
5
+ "levelParsingError",
6
+ "levelEmptyError",
7
+ "fragParsingError",
8
+ "bufferAddCodecError",
9
+ "bufferIncompatibleCodecsError",
10
+ "bufferAppendError",
11
+ "attachMediaError"
12
+ ]);
13
+ function t(e) {
14
+ return e === 401 || e === 403 ? "access" : e === 404 || e === 410 ? "not_found" : e === 429 ? "rate_limited" : "network";
15
+ }
16
+ var n = 6e4, r = 3e4;
17
+ function i(e, t = Date.now()) {
18
+ return e ? Math.max(e * 1e3 - n - t, r) : null;
19
+ }
20
+ function a(e) {
21
+ return e.kind === "access" || e.status === 404;
22
+ }
23
+ function o(e) {
24
+ let t = e.response?.code;
25
+ if (typeof t == "number") return t;
26
+ let n = e.networkDetails?.status;
27
+ return typeof n == "number" ? n : void 0;
28
+ }
29
+ function s(n) {
30
+ if (e.has(n.details)) return {
31
+ kind: "unsupported",
32
+ code: n.details
33
+ };
34
+ if (n.type === "networkError" || /Load(Error|TimeOut)$/i.test(n.details)) {
35
+ let e = /TimeOut$/i.test(n.details) ? 0 : o(n) ?? 0;
36
+ return {
37
+ kind: t(e),
38
+ code: `${n.details}/${e}`,
39
+ status: e
40
+ };
41
+ }
42
+ return {
43
+ kind: n.type === "mediaError" && n.fatal ? "unsupported" : "unknown",
44
+ code: n.details
45
+ };
46
+ }
47
+ function c(e) {
48
+ let t = e?.code ?? 0;
49
+ return {
50
+ kind: t === 2 ? "network" : t === 3 || t === 4 ? "unsupported" : "unknown",
51
+ code: `media/${t}`
52
+ };
53
+ }
54
+ var l = /* @__PURE__ */ new Set([
55
+ 401,
56
+ 403,
57
+ 404,
58
+ 410,
59
+ 429
60
+ ]), u = (e) => ({
61
+ maxNumRetry: e,
62
+ retryDelayMs: 500,
63
+ maxRetryDelayMs: 2e3,
64
+ shouldRetry: (e, t, n, r, i) => !l.has(r?.code ?? -1) && i
65
+ }), d = (e, t) => ({ default: {
66
+ maxTimeToFirstByteMs: e,
67
+ maxLoadTimeMs: t,
68
+ timeoutRetry: u(1),
69
+ errorRetry: u(2)
70
+ } }), f = {
71
+ manifestLoadPolicy: d(5e3, 1e4),
72
+ playlistLoadPolicy: d(5e3, 1e4),
73
+ fragLoadPolicy: d(6e3, 3e4),
74
+ keyLoadPolicy: d(5e3, 1e4)
75
+ }, p = 3, m = {
76
+ minStartHeight: 1080,
77
+ maxHeight: Infinity,
78
+ preferHighRes: !0,
79
+ defaultEstimate: 8e6
80
+ }, h = 5e5, g = .75, _ = 1.1, v = (e) => Math.min(e.width, e.height) || e.height || e.width;
81
+ function y(e) {
82
+ return {
83
+ ...m,
84
+ ...Object.fromEntries(Object.entries(e ?? {}).filter(([, e]) => e !== void 0))
85
+ };
86
+ }
87
+ function b(e, t, n, r) {
88
+ let i = y(r), a = e.length;
89
+ if (!a) return -1;
90
+ let o = a - 1;
91
+ if (t > 0 && n > 0) for (let r = 0; r < a; r++) {
92
+ let i = e[r];
93
+ if ((i.width && i.height ? Math.min(t / i.width, n / i.height) : 1) <= _) {
94
+ o = r;
95
+ break;
96
+ }
97
+ }
98
+ if (i.preferHighRes) {
99
+ let t = e.findIndex((e) => v(e) >= i.minStartHeight);
100
+ o = Math.max(o, t === -1 ? a - 1 : t);
101
+ }
102
+ for (; o > 0 && v(e[o]) > i.maxHeight;) o--;
103
+ return o;
104
+ }
105
+ function x(e, t) {
106
+ let n = (e[t] ?? e[0])?.codecSet;
107
+ return e.flatMap((e, t) => e.codecSet === n ? [] : [t]).reverse();
108
+ }
109
+ function S(e, t, n) {
110
+ let r = y(e);
111
+ return t?.saveData ? h : n && n > 0 ? n : t?.downlink && t.downlink > 0 ? t.downlink * 1e6 : r.preferHighRes ? r.defaultEstimate : h;
112
+ }
113
+ function C(e, t, n, r) {
114
+ if (!e.length) return -1;
115
+ if (r?.saveData) return 0;
116
+ let i = 0;
117
+ for (let r = 0; r <= Math.min(n, e.length - 1); r++) {
118
+ let n = e[r];
119
+ (n.averageBitrate || n.bitrate) <= t * g && (i = r);
120
+ }
121
+ return i;
122
+ }
123
+ function w(e, t) {
124
+ let n = y(e);
125
+ return {
126
+ abrEwmaDefaultEstimate: t,
127
+ abrEwmaDefaultEstimateMax: Math.max(t, 5e6),
128
+ abrEwmaFastVoD: n.preferHighRes ? 2 : 3,
129
+ abrEwmaSlowVoD: n.preferHighRes ? 6 : 9,
130
+ abrBandWidthUpFactor: n.preferHighRes ? .8 : .7,
131
+ abrBandWidthFactor: .9,
132
+ capLevelToPlayerSize: !0,
133
+ ignoreDevicePixelRatio: !1,
134
+ maxBufferLength: 30,
135
+ maxMaxBufferLength: 120,
136
+ backBufferLength: 30
137
+ };
138
+ }
139
+ //#endregion
140
+ export { m as ABR_DEFAULTS, p as NETWORK_FAILURES_BEFORE_ERROR, n as REFRESH_BEFORE_EXPIRY, w as abrHlsConfig, b as capRung, s as classifyHlsError, c as classifyMediaError, i as expiryDelay, f as hlsConfig, S as initialEstimate, x as otherCodecLevels, a as refreshable, C as startRung, t as statusKind };
141
+
142
+ //# sourceMappingURL=playback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playback.js","names":[],"sources":["../../src/client/playback.ts"],"sourcesContent":["/**\n * Why a video cannot play. `network` covers CORS too: browsers report a blocked\n * cross-origin response exactly like an unreachable server (status 0).\n */\nexport type PlaybackErrorKind = \"network\" | \"access\" | \"not_found\" | \"rate_limited\" | \"unsupported\" | \"stalled\" | \"unknown\";\n\nexport interface PlaybackError {\n kind: PlaybackErrorKind;\n /** Short support code, e.g. \"fragLoadError/0\" or \"media/4\". */\n code: string;\n status?: number;\n}\n\n/** The fields of hls.js ErrorData this reads. */\nexport interface HlsErrorLike {\n type?: string;\n details: string;\n fatal?: boolean;\n response?: { code?: number } | null;\n networkDetails?: unknown;\n}\n\nconst UNSUPPORTED = new Set([\n \"manifestParsingError\",\n \"manifestIncompatibleCodecsError\",\n \"levelParsingError\",\n \"levelEmptyError\",\n \"fragParsingError\",\n \"bufferAddCodecError\",\n \"bufferIncompatibleCodecsError\",\n \"bufferAppendError\",\n \"attachMediaError\",\n]);\n\n/** HTTP status → kind; 0 (or none) is a blocked or unreachable request. */\nexport function statusKind(status: number | undefined): PlaybackErrorKind {\n if (status === 401 || status === 403) return \"access\";\n if (status === 404 || status === 410) return \"not_found\";\n if (status === 429) return \"rate_limited\";\n return \"network\";\n}\n\n/** Read again this long before the item token expires. */\nexport const REFRESH_BEFORE_EXPIRY = 60_000;\nconst MIN_REFRESH_DELAY = 30_000;\n\n/**\n * Milliseconds until the read should be fetched again: shortly before\n * `expires` (the read's, unix seconds), never sooner than 30 s; null when\n * the read has no expiry. A read before the expiry answers the same token,\n * so nothing is gained by reading earlier.\n */\nexport function expiryDelay(expires: number | undefined, now = Date.now()): number | null {\n if (!expires) return null;\n return Math.max(expires * 1000 - REFRESH_BEFORE_EXPIRY - now, MIN_REFRESH_DELAY);\n}\n\n/**\n * Worth one grant refresh and retry: 401/403, or a 404 — media-gateway answers a\n * missing, expired or wrong token exactly like a missing object. A 429 (the\n * ingress's rate limit) or a blocked request is not: it fails without a loop.\n */\nexport function refreshable(e: PlaybackError): boolean {\n return e.kind === \"access\" || e.status === 404;\n}\n\nfunction hlsStatus(d: HlsErrorLike): number | undefined {\n const code = d.response?.code;\n if (typeof code === \"number\") return code;\n const s = (d.networkDetails as { status?: unknown } | null | undefined)?.status;\n return typeof s === \"number\" ? s : undefined;\n}\n\nexport function classifyHlsError(d: HlsErrorLike): PlaybackError {\n if (UNSUPPORTED.has(d.details)) return { kind: \"unsupported\", code: d.details };\n if (d.type === \"networkError\" || /Load(Error|TimeOut)$/i.test(d.details)) {\n const status = /TimeOut$/i.test(d.details) ? 0 : (hlsStatus(d) ?? 0);\n return { kind: statusKind(status), code: `${d.details}/${status}`, status };\n }\n return { kind: d.type === \"mediaError\" && d.fatal ? \"unsupported\" : \"unknown\", code: d.details };\n}\n\n/** A native `<video>` error (Safari's HLS): 2 network, 3 decode, 4 unsupported source. */\nexport function classifyMediaError(e: { code: number } | null | undefined): PlaybackError {\n const code = e?.code ?? 0;\n const kind: PlaybackErrorKind = code === 2 ? \"network\" : code === 3 || code === 4 ? \"unsupported\" : \"unknown\";\n return { kind, code: `media/${code}` };\n}\n\n// Fail fast: a dead endpoint surfaces in seconds, a blip gets 1–2 quick retries.\nconst noRetryStatus = new Set([401, 403, 404, 410, 429]);\nconst retry = (maxNumRetry: number) => ({\n maxNumRetry,\n retryDelayMs: 500,\n maxRetryDelayMs: 2000,\n shouldRetry: (_c: unknown, _n: number, _t: boolean, res: { code?: number } | undefined, fallback: boolean) =>\n !noRetryStatus.has(res?.code ?? -1) && fallback,\n});\nconst policy = (ttfb: number, load: number) => ({\n default: { maxTimeToFirstByteMs: ttfb, maxLoadTimeMs: load, timeoutRetry: retry(1), errorRetry: retry(2) },\n});\n\n/** hls.js settings the player uses; spread under your own. */\nexport const hlsConfig = {\n manifestLoadPolicy: policy(5_000, 10_000),\n playlistLoadPolicy: policy(5_000, 10_000),\n fragLoadPolicy: policy(6_000, 30_000),\n keyLoadPolicy: policy(5_000, 10_000),\n};\n\n/** Non-fatal network failures (hls.js also tries other renditions) before the player gives up. */\nexport const NETWORK_FAILURES_BEFORE_ERROR = 3;\n\n/** Adaptive-bitrate policy for the player; every field is optional. */\nexport interface AbrPolicy {\n /** Start at, and never cap the display below, the rung of this short side (px) when bandwidth allows. Default 1080. */\n minStartHeight?: number;\n /** Never pick a rung with a larger short side (px). Default unlimited. */\n maxHeight?: number;\n /** false: stock hls.js start (500 kbps guess) and a strict display cap. Default true. */\n preferHighRes?: boolean;\n /** Bits/s assumed when neither a measurement nor `navigator.connection` is available. Default 8 Mbps. */\n defaultEstimate?: number;\n}\n\n/** A rendition as hls.js levels describe it. */\nexport interface Rung {\n width: number;\n height: number;\n /** Peak bits/s (BANDWIDTH). */\n bitrate: number;\n /** AVERAGE-BANDWIDTH when known. */\n averageBitrate?: number;\n}\n\n/** What the browser says about the connection (Network Information API). */\nexport interface ConnectionHint {\n downlink?: number;\n saveData?: boolean;\n}\n\nexport const ABR_DEFAULTS = { minStartHeight: 1080, maxHeight: Infinity, preferHighRes: true, defaultEstimate: 8_000_000 } as const;\nconst STOCK_ESTIMATE = 500_000;\n// Start below the estimate: the first segment also pays for TTFB and decoder startup.\nconst START_FACTOR = 0.75;\n\n// A rung within 10% of the display is sharp enough (a DPR-3 phone's 1170 px vs 1080p).\nconst UPSCALE = 1.1;\n\nconst short = (r: Rung) => Math.min(r.width, r.height) || r.height || r.width;\n\nfunction resolve(p: AbrPolicy | undefined) {\n return { ...ABR_DEFAULTS, ...Object.fromEntries(Object.entries(p ?? {}).filter(([, v]) => v !== undefined)) } as Required<AbrPolicy>;\n}\n\n/**\n * The highest rung index (rungs ascend by bitrate) worth loading for a display\n * of width×height device pixels: the smallest rung covering the video's fitted\n * box (to within 10%), never below the minStartHeight rung, never above maxHeight.\n */\nexport function capRung(rungs: readonly Rung[], width: number, height: number, policy?: AbrPolicy): number {\n const p = resolve(policy);\n const n = rungs.length;\n if (!n) return -1;\n let cap = n - 1;\n if (width > 0 && height > 0) {\n for (let i = 0; i < n; i++) {\n const r = rungs[i]!;\n const scale = r.width && r.height ? Math.min(width / r.width, height / r.height) : 1;\n if (scale <= UPSCALE) {\n cap = i;\n break;\n }\n }\n }\n if (p.preferHighRes) {\n const floor = rungs.findIndex((r) => short(r) >= p.minStartHeight);\n cap = Math.max(cap, floor === -1 ? n - 1 : floor);\n }\n while (cap > 0 && short(rungs[cap]!) > p.maxHeight) cap--;\n return cap;\n}\n\n/**\n * Levels to remove (indices, descending) so one codec set remains: the set of\n * the level hls.js lists first, which is the master playlist's first playable\n * codec (AV1 or HEVC before H.264 when the browser decodes them). hls.js never\n * switches codec sets for bandwidth, and the quality menu lists each rung once.\n */\nexport function otherCodecLevels(levels: readonly { codecSet?: string }[], first: number): number[] {\n const keep = (levels[first] ?? levels[0])?.codecSet;\n return levels.flatMap((l, i) => (l.codecSet === keep ? [] : [i])).reverse();\n}\n\n/** Bits/s to seed the estimator with: a measurement from this page, the browser's downlink, else the policy default. */\nexport function initialEstimate(policy?: AbrPolicy, conn?: ConnectionHint | null, measured?: number): number {\n const p = resolve(policy);\n if (conn?.saveData) return STOCK_ESTIMATE;\n if (measured && measured > 0) return measured;\n if (conn?.downlink && conn.downlink > 0) return conn.downlink * 1_000_000;\n return p.preferHighRes ? p.defaultEstimate : STOCK_ESTIMATE;\n}\n\n/** The first rung to load: the lowest under Save-Data, else the highest under cap the estimate sustains. */\nexport function startRung(rungs: readonly Rung[], estimate: number, cap: number, conn?: ConnectionHint | null): number {\n if (!rungs.length) return -1;\n if (conn?.saveData) return 0;\n let start = 0;\n for (let i = 0; i <= Math.min(cap, rungs.length - 1); i++) {\n const r = rungs[i]!;\n if ((r.averageBitrate || r.bitrate) <= estimate * START_FACTOR) start = i;\n }\n return start;\n}\n\n/** hls.js ABR settings: climb after a couple of good segments, drop before the buffer runs dry. */\nexport function abrHlsConfig(policy: AbrPolicy | undefined, estimate: number) {\n const p = resolve(policy);\n return {\n abrEwmaDefaultEstimate: estimate,\n abrEwmaDefaultEstimateMax: Math.max(estimate, 5_000_000),\n abrEwmaFastVoD: p.preferHighRes ? 2 : 3,\n abrEwmaSlowVoD: p.preferHighRes ? 6 : 9,\n abrBandWidthUpFactor: p.preferHighRes ? 0.8 : 0.7,\n abrBandWidthFactor: 0.9,\n capLevelToPlayerSize: true,\n ignoreDevicePixelRatio: false,\n maxBufferLength: 30,\n maxMaxBufferLength: 120,\n backBufferLength: 30,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ /** What a key does to the player. */
2
+ export type PlayerAction = {
3
+ type: "toggle";
4
+ } | {
5
+ type: "seekBy";
6
+ seconds: number;
7
+ }
8
+ /** A fraction of the duration: Home 0, End 1, digit n n/10. */
9
+ | {
10
+ type: "seekTo";
11
+ fraction: number;
12
+ } | {
13
+ type: "volumeBy";
14
+ delta: number;
15
+ } | {
16
+ type: "mute";
17
+ } | {
18
+ type: "captions";
19
+ } | {
20
+ type: "fullscreen";
21
+ } | {
22
+ type: "theater";
23
+ } | {
24
+ type: "miniPlayer";
25
+ } | {
26
+ type: "speed";
27
+ step: 1 | -1;
28
+ };
29
+ export interface KeyLike {
30
+ key: string;
31
+ altKey?: boolean;
32
+ ctrlKey?: boolean;
33
+ metaKey?: boolean;
34
+ }
35
+ /** Seconds the arrow keys seek; J and L, and a double tap, seek twice as far. */
36
+ export declare const ARROW_SEEK = 5;
37
+ export declare const JUMP_SEEK = 10;
38
+ export declare const VOLUME_STEP = 0.05;
39
+ export declare const PLAYBACK_SPEEDS: readonly [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
40
+ /**
41
+ * The shortcut for a key, as on YouTube: Space/K play, ←/→ 5 s, J/L 10 s,
42
+ * ↑/↓ volume, M mute, C subtitles, F fullscreen, T theater, I mini player,
43
+ * 0–9 a tenth of the way, Home/End, `<`/`>` (or `,`/`.`) speed. Keys with
44
+ * Alt, Ctrl or Meta belong to the browser.
45
+ */
46
+ export declare function playerKeyAction(e: KeyLike): PlayerAction | null;
47
+ /** The next playback speed up or down from rate (a rate off the list snaps to its nearest). */
48
+ export declare function nextSpeed(rate: number, step: 1 | -1): number;
49
+ /**
50
+ * Where playback starts for a resume point: 0 without one, or when it is in
51
+ * the last few seconds (the viewer finished; start over).
52
+ */
53
+ export declare function resumeAt(startAt: number | undefined, duration?: number): number;
54
+ /** One cue of a seek sprite: a tile of the sprite image for [start, end). */
55
+ export interface SpriteCue {
56
+ start: number;
57
+ end: number;
58
+ url: string;
59
+ x: number;
60
+ y: number;
61
+ w: number;
62
+ h: number;
63
+ }
64
+ /** The cues of a sprite.vtt; tile URLs resolve against the cue sheet's. */
65
+ export declare function parseSpriteVtt(text: string, base: string): SpriteCue[];
66
+ /** The cue showing at time t (cues ascend): the last that starts at or before it. */
67
+ export declare function spriteCueAt(cues: readonly SpriteCue[], t: number): SpriteCue | undefined;
68
+ /** A selectable audio or subtitle track. */
69
+ export interface PlayerTrack {
70
+ index: number;
71
+ /** The playlist's NAME, else its language. */
72
+ label: string;
73
+ /** BCP 47. */
74
+ lang?: string;
75
+ forced?: boolean;
76
+ }
77
+ /** The track for a BCP 47 tag: an exact match, else the same primary language; -1 for none. */
78
+ export declare function pickTrack(tracks: readonly {
79
+ lang?: string;
80
+ }[], lang: string | null | undefined): number;
81
+ /** A playhead sample: wall-clock ms and media seconds. */
82
+ export interface PlaySample {
83
+ at: number;
84
+ pos: number;
85
+ }
86
+ /** Seconds actually played between two samples: time that both elapsed and advanced the playhead (a seek adds nothing). */
87
+ export declare function playedBetween(a: PlaySample, b: PlaySample): number;
88
+ export declare const PLAYER_VOLUME_KEY = "ckui.player.volume";
89
+ export declare const PLAYER_TRACKS_KEY = "ckui.player.tracks";
90
+ export interface VolumePrefs {
91
+ volume: number;
92
+ muted: boolean;
93
+ }
94
+ /** Audio and subtitle languages the viewer chose; subtitles "off" when they turned them off. */
95
+ export interface TrackPrefs {
96
+ audio?: string;
97
+ subtitles?: string;
98
+ }
99
+ export declare function readVolume(key: string | null | undefined): VolumePrefs;
100
+ export declare const writeVolume: (key: string | null | undefined, prefs: Partial<VolumePrefs>) => void;
101
+ export declare function readTrackPrefs(key: string | null | undefined): TrackPrefs;
102
+ export declare const writeTrackPrefs: (key: string | null | undefined, prefs: TrackPrefs) => void;
@@ -0,0 +1,155 @@
1
+ var e = .05, t = [
2
+ .25,
3
+ .5,
4
+ .75,
5
+ 1,
6
+ 1.25,
7
+ 1.5,
8
+ 1.75,
9
+ 2
10
+ ];
11
+ function n(t) {
12
+ if (t.altKey || t.ctrlKey || t.metaKey) return null;
13
+ let n = t.key.length === 1 ? t.key.toLowerCase() : t.key;
14
+ switch (n) {
15
+ case " ":
16
+ case "k": return { type: "toggle" };
17
+ case "ArrowLeft": return {
18
+ type: "seekBy",
19
+ seconds: -5
20
+ };
21
+ case "ArrowRight": return {
22
+ type: "seekBy",
23
+ seconds: 5
24
+ };
25
+ case "j": return {
26
+ type: "seekBy",
27
+ seconds: -10
28
+ };
29
+ case "l": return {
30
+ type: "seekBy",
31
+ seconds: 10
32
+ };
33
+ case "ArrowUp": return {
34
+ type: "volumeBy",
35
+ delta: e
36
+ };
37
+ case "ArrowDown": return {
38
+ type: "volumeBy",
39
+ delta: -.05
40
+ };
41
+ case "m": return { type: "mute" };
42
+ case "c": return { type: "captions" };
43
+ case "f": return { type: "fullscreen" };
44
+ case "t": return { type: "theater" };
45
+ case "i": return { type: "miniPlayer" };
46
+ case "Home": return {
47
+ type: "seekTo",
48
+ fraction: 0
49
+ };
50
+ case "End": return {
51
+ type: "seekTo",
52
+ fraction: 1
53
+ };
54
+ case "<":
55
+ case ",": return {
56
+ type: "speed",
57
+ step: -1
58
+ };
59
+ case ">":
60
+ case ".": return {
61
+ type: "speed",
62
+ step: 1
63
+ };
64
+ }
65
+ return /^[0-9]$/.test(n) ? {
66
+ type: "seekTo",
67
+ fraction: Number(n) / 10
68
+ } : null;
69
+ }
70
+ function r(e, n) {
71
+ let r = 0;
72
+ return t.forEach((n, i) => {
73
+ Math.abs(n - e) < Math.abs(t[r] - e) && (r = i);
74
+ }), t[Math.min(t.length - 1, Math.max(0, r + n))];
75
+ }
76
+ function i(e, t) {
77
+ return !e || !Number.isFinite(e) || e <= 0 || t && t > 0 && e >= t - Math.max(3, t * .02) ? 0 : e;
78
+ }
79
+ function a(e) {
80
+ return e.trim().split(":").map(Number).reduce((e, t) => e * 60 + t, 0);
81
+ }
82
+ function o(e, t) {
83
+ let n = [], r = e.split(/\r?\n/);
84
+ for (let e = 0; e < r.length - 1; e++) {
85
+ let i = r[e].match(/^\s*([\d:.]+)\s+-->\s+([\d:.]+)/), o = i && r[e + 1].trim().match(/^(\S+)#xywh=(\d+),(\d+),(\d+),(\d+)$/);
86
+ if (!i || !o) continue;
87
+ let [s, c, l, u] = o.slice(2).map(Number);
88
+ n.push({
89
+ start: a(i[1]),
90
+ end: a(i[2]),
91
+ url: new URL(o[1], t).href,
92
+ x: s,
93
+ y: c,
94
+ w: l,
95
+ h: u
96
+ });
97
+ }
98
+ return n;
99
+ }
100
+ function s(e, t) {
101
+ let n = 0, r = e.length - 1, i;
102
+ for (; n <= r;) {
103
+ let a = n + r >> 1;
104
+ e[a].start <= t ? (i = e[a], n = a + 1) : r = a - 1;
105
+ }
106
+ return i ?? e[0];
107
+ }
108
+ function c(e, t) {
109
+ if (!t) return -1;
110
+ let n = t.toLowerCase(), r = e.findIndex((e) => e.lang?.toLowerCase() === n);
111
+ if (r >= 0) return r;
112
+ let i = n.split("-")[0];
113
+ return e.findIndex((e) => e.lang?.toLowerCase().split("-")[0] === i);
114
+ }
115
+ function l(e, t) {
116
+ return Math.max(0, Math.min((t.at - e.at) / 1e3, t.pos - e.pos));
117
+ }
118
+ var u = "ckui.player.volume", d = "ckui.player.tracks";
119
+ function f(e) {
120
+ if (!e) return {};
121
+ try {
122
+ let t = JSON.parse(globalThis.localStorage?.getItem(e) ?? "{}");
123
+ return t && typeof t == "object" ? t : {};
124
+ } catch {
125
+ return {};
126
+ }
127
+ }
128
+ function p(e, t) {
129
+ if (e) try {
130
+ globalThis.localStorage?.setItem(e, JSON.stringify({
131
+ ...f(e),
132
+ ...t
133
+ }));
134
+ } catch {}
135
+ }
136
+ function m(e) {
137
+ let t = f(e);
138
+ return {
139
+ volume: typeof t.volume == "number" && Number.isFinite(t.volume) ? Math.min(1, Math.max(0, t.volume)) : 1,
140
+ muted: t.muted === !0
141
+ };
142
+ }
143
+ var h = (e, t) => p(e, t);
144
+ function g(e) {
145
+ let t = f(e);
146
+ return {
147
+ audio: typeof t.audio == "string" ? t.audio : void 0,
148
+ subtitles: typeof t.subtitles == "string" ? t.subtitles : void 0
149
+ };
150
+ }
151
+ var _ = (e, t) => p(e, t);
152
+ //#endregion
153
+ export { t as PLAYBACK_SPEEDS, d as PLAYER_TRACKS_KEY, u as PLAYER_VOLUME_KEY, e as VOLUME_STEP, r as nextSpeed, o as parseSpriteVtt, c as pickTrack, l as playedBetween, n as playerKeyAction, g as readTrackPrefs, m as readVolume, i as resumeAt, s as spriteCueAt, _ as writeTrackPrefs, h as writeVolume };
154
+
155
+ //# sourceMappingURL=player.js.map