@osmo.inc/cli 0.1.15

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 (949) hide show
  1. package/DEPLOY.md +87 -0
  2. package/README.md +243 -0
  3. package/RELEASE.md +164 -0
  4. package/SETUP.md +60 -0
  5. package/THIRD_PARTY_NOTICES.md +18 -0
  6. package/bin/osmo.mjs +12 -0
  7. package/dist/osmo.js +7817 -0
  8. package/node_modules/@esbuild/darwin-arm64/README.md +3 -0
  9. package/node_modules/@esbuild/darwin-arm64/bin/esbuild +0 -0
  10. package/node_modules/@esbuild/darwin-arm64/package.json +20 -0
  11. package/node_modules/esbuild/LICENSE.md +21 -0
  12. package/node_modules/esbuild/README.md +3 -0
  13. package/node_modules/esbuild/bin/esbuild +223 -0
  14. package/node_modules/esbuild/install.js +289 -0
  15. package/node_modules/esbuild/lib/main.d.ts +716 -0
  16. package/node_modules/esbuild/lib/main.js +2532 -0
  17. package/node_modules/esbuild/package.json +49 -0
  18. package/node_modules/fflate/LICENSE +21 -0
  19. package/node_modules/fflate/esm/index.mjs +2710 -0
  20. package/node_modules/fflate/package.json +128 -0
  21. package/node_modules/typescript/LICENSE.txt +55 -0
  22. package/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
  23. package/node_modules/typescript/lib/lib.d.ts +22 -0
  24. package/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
  25. package/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
  26. package/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
  27. package/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
  28. package/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
  29. package/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
  30. package/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
  31. package/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
  32. package/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
  33. package/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
  34. package/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
  35. package/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
  36. package/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
  37. package/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
  38. package/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
  39. package/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
  40. package/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
  41. package/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
  42. package/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
  43. package/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
  44. package/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
  45. package/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
  46. package/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
  47. package/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
  48. package/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
  49. package/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
  50. package/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
  51. package/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
  52. package/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
  53. package/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
  54. package/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
  55. package/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
  56. package/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
  57. package/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
  58. package/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
  59. package/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
  60. package/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
  61. package/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
  62. package/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
  63. package/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
  64. package/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
  65. package/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
  66. package/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
  67. package/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
  68. package/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
  69. package/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
  70. package/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
  71. package/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
  72. package/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
  73. package/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
  74. package/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
  75. package/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
  76. package/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
  77. package/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
  78. package/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
  79. package/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
  80. package/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
  81. package/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
  82. package/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
  83. package/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
  84. package/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
  85. package/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
  86. package/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
  87. package/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
  88. package/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
  89. package/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
  90. package/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
  91. package/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
  92. package/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
  93. package/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
  94. package/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
  95. package/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
  96. package/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
  97. package/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
  98. package/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
  99. package/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
  100. package/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
  101. package/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
  102. package/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
  103. package/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
  104. package/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
  105. package/node_modules/typescript/lib/lib.es6.d.ts +23 -0
  106. package/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
  107. package/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
  108. package/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
  109. package/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
  110. package/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
  111. package/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
  112. package/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
  113. package/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
  114. package/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
  115. package/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
  116. package/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
  117. package/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
  118. package/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
  119. package/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
  120. package/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
  121. package/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
  122. package/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
  123. package/node_modules/typescript/lib/typescript.js +382 -0
  124. package/node_modules/typescript/package.json +57 -0
  125. package/package.json +54 -0
  126. package/release.json +136 -0
  127. package/runtime/apps/native/tools/compile.mjs +217 -0
  128. package/runtime/packages/scene/scripts/validate-strict.mjs +246 -0
  129. package/runtime/packages/scene/src/clip.d.mts +14 -0
  130. package/runtime/packages/scene/src/clip.mjs +15 -0
  131. package/runtime/packages/scene/src/color-value.d.mts +5 -0
  132. package/runtime/packages/scene/src/color-value.mjs +19 -0
  133. package/runtime/packages/scene/src/color.ts +1 -0
  134. package/runtime/packages/scene/src/effects.ts +213 -0
  135. package/runtime/packages/scene/src/elements.ts +491 -0
  136. package/runtime/packages/scene/src/evaluate.ts +919 -0
  137. package/runtime/packages/scene/src/index.ts +69 -0
  138. package/runtime/packages/scene/src/jsx-runtime.ts +73 -0
  139. package/runtime/packages/scene/src/knob-schema.ts +115 -0
  140. package/runtime/packages/scene/src/knobs.ts +118 -0
  141. package/runtime/packages/scene/src/mask.d.mts +6 -0
  142. package/runtime/packages/scene/src/mask.mjs +17 -0
  143. package/runtime/packages/scene/src/metadata.d.mts +23 -0
  144. package/runtime/packages/scene/src/metadata.mjs +44 -0
  145. package/runtime/packages/scene/src/motion-sampling.d.mts +2 -0
  146. package/runtime/packages/scene/src/motion-sampling.mjs +50 -0
  147. package/runtime/packages/scene/src/motion.ts +121 -0
  148. package/runtime/packages/scene/src/shader.ts +57 -0
  149. package/src/resource-examples/example-image/landscape.svg +7 -0
  150. package/src/resource-examples/example-image/resource.json +8 -0
  151. package/src/resource-examples/example-model/gem.glb +0 -0
  152. package/src/resource-examples/example-model/preview.svg +1 -0
  153. package/src/resource-examples/example-model/resource.json +7 -0
  154. package/src/resource-examples/example-scene/resource.json +1 -0
  155. package/src/resource-examples/example-scene/scene.tsx +8 -0
  156. package/src/resource-examples/example-shader/effect.wgsl +7 -0
  157. package/src/resource-examples/example-shader/preview.svg +1 -0
  158. package/src/resource-examples/example-shader/resource.json +27 -0
  159. package/src/resource-examples/example-shader/tint.wgsl +7 -0
  160. package/src/resource-examples/example-video/ambient.mp4 +0 -0
  161. package/src/resource-examples/example-video/resource.json +9 -0
  162. package/src/starter/scene.tsx +20 -0
  163. package/studio/index.html +2 -0
  164. package/studio/public/check-circle-filled.svg +3 -0
  165. package/studio/public/comment-cursor/active-outer.svg +3 -0
  166. package/studio/public/comment-cursor/default.svg +6 -0
  167. package/studio/public/osmo-studio-logo.svg +12 -0
  168. package/studio/public/pencil-simple.svg +5 -0
  169. package/studio/src/active-outer-TVYUEURE.svg +3 -0
  170. package/studio/src/app.css +4 -0
  171. package/studio/src/app.js +705 -0
  172. package/studio/src/default-6CTRH4V5.svg +6 -0
  173. package/studio/src/engine_bg.wasm +0 -0
  174. package/studio/src/inter-cyrillic-ext-wght-normal-IYF56FF6.woff2 +0 -0
  175. package/studio/src/inter-cyrillic-wght-normal-JEOLYBOO.woff2 +0 -0
  176. package/studio/src/inter-greek-ext-wght-normal-EOVOK2B5.woff2 +0 -0
  177. package/studio/src/inter-greek-wght-normal-IRE366VL.woff2 +0 -0
  178. package/studio/src/inter-latin-ext-wght-normal-HA22NDSG.woff2 +0 -0
  179. package/studio/src/inter-latin-wght-normal-NRMW37G5.woff2 +0 -0
  180. package/studio/src/inter-vietnamese-wght-normal-CE5GGD3W.woff2 +0 -0
  181. package/studio/src/osmo-studio-logo-D5R2V77B.svg +12 -0
  182. package/third-party/cargo/adler2@2.0.1/Cargo.toml +91 -0
  183. package/third-party/cargo/adler2@2.0.1/LICENSE-0BSD +12 -0
  184. package/third-party/cargo/adler2@2.0.1/LICENSE-APACHE +201 -0
  185. package/third-party/cargo/adler2@2.0.1/LICENSE-MIT +23 -0
  186. package/third-party/cargo/allocator-api2@0.2.21/Cargo.toml +48 -0
  187. package/third-party/cargo/allocator-api2@0.2.21/LICENSE-APACHE +176 -0
  188. package/third-party/cargo/allocator-api2@0.2.21/LICENSE-MIT +23 -0
  189. package/third-party/cargo/arrayref@0.3.9/Cargo.toml +23 -0
  190. package/third-party/cargo/arrayref@0.3.9/LICENSE +26 -0
  191. package/third-party/cargo/arrayvec@0.7.8/Cargo.toml +112 -0
  192. package/third-party/cargo/arrayvec@0.7.8/LICENSE-APACHE +201 -0
  193. package/third-party/cargo/arrayvec@0.7.8/LICENSE-MIT +25 -0
  194. package/third-party/cargo/ascii@1.1.0/Cargo.toml +41 -0
  195. package/third-party/cargo/ascii@1.1.0/LICENSE-APACHE +201 -0
  196. package/third-party/cargo/ascii@1.1.0/LICENSE-MIT +22 -0
  197. package/third-party/cargo/ash@0.38.0+1.3.281/Cargo.toml +66 -0
  198. package/third-party/cargo/ash@0.38.0+1.3.281/LICENSE-APACHE +67 -0
  199. package/third-party/cargo/ash@0.38.0+1.3.281/LICENSE-MIT +25 -0
  200. package/third-party/cargo/autocfg@1.5.1/Cargo.toml +75 -0
  201. package/third-party/cargo/autocfg@1.5.1/LICENSE-APACHE +201 -0
  202. package/third-party/cargo/autocfg@1.5.1/LICENSE-MIT +25 -0
  203. package/third-party/cargo/base64@0.13.1/Cargo.toml +53 -0
  204. package/third-party/cargo/base64@0.13.1/LICENSE-APACHE +201 -0
  205. package/third-party/cargo/base64@0.13.1/LICENSE-MIT +21 -0
  206. package/third-party/cargo/base64@0.22.1/Cargo.toml +85 -0
  207. package/third-party/cargo/base64@0.22.1/LICENSE-APACHE +201 -0
  208. package/third-party/cargo/base64@0.22.1/LICENSE-MIT +21 -0
  209. package/third-party/cargo/bit-set@0.10.0/Cargo.toml +108 -0
  210. package/third-party/cargo/bit-set@0.10.0/LICENSE-APACHE +201 -0
  211. package/third-party/cargo/bit-set@0.10.0/LICENSE-MIT +25 -0
  212. package/third-party/cargo/bit-vec@0.9.1/Cargo.toml +94 -0
  213. package/third-party/cargo/bit-vec@0.9.1/LICENSE-APACHE +201 -0
  214. package/third-party/cargo/bit-vec@0.9.1/LICENSE-MIT +25 -0
  215. package/third-party/cargo/bitflags@2.13.0/Cargo.toml +120 -0
  216. package/third-party/cargo/bitflags@2.13.0/LICENSE-APACHE +201 -0
  217. package/third-party/cargo/bitflags@2.13.0/LICENSE-MIT +25 -0
  218. package/third-party/cargo/block2@0.6.2/Cargo.toml +115 -0
  219. package/third-party/cargo/block2@0.6.2/MIT-terms.txt +22 -0
  220. package/third-party/cargo/block2@0.6.2/madsmtm-objc2-b4167b582b2f-LICENSE.md +34 -0
  221. package/third-party/cargo/bumpalo@3.20.3/Cargo.toml +99 -0
  222. package/third-party/cargo/bumpalo@3.20.3/LICENSE-APACHE +201 -0
  223. package/third-party/cargo/bumpalo@3.20.3/LICENSE-MIT +25 -0
  224. package/third-party/cargo/bytemuck@1.25.1/Cargo.toml +153 -0
  225. package/third-party/cargo/bytemuck@1.25.1/LICENSE-APACHE +61 -0
  226. package/third-party/cargo/bytemuck@1.25.1/LICENSE-MIT +9 -0
  227. package/third-party/cargo/bytemuck@1.25.1/LICENSE-ZLIB +11 -0
  228. package/third-party/cargo/bytemuck_derive@1.11.0/Cargo.toml +60 -0
  229. package/third-party/cargo/bytemuck_derive@1.11.0/LICENSE-APACHE +61 -0
  230. package/third-party/cargo/bytemuck_derive@1.11.0/LICENSE-MIT +9 -0
  231. package/third-party/cargo/bytemuck_derive@1.11.0/LICENSE-ZLIB +11 -0
  232. package/third-party/cargo/byteorder-lite@0.1.0/Cargo.toml +57 -0
  233. package/third-party/cargo/byteorder-lite@0.1.0/LICENSE-MIT +21 -0
  234. package/third-party/cargo/byteorder-lite@0.1.0/UNLICENSE +24 -0
  235. package/third-party/cargo/byteorder@1.5.0/COPYING +3 -0
  236. package/third-party/cargo/byteorder@1.5.0/Cargo.toml +54 -0
  237. package/third-party/cargo/byteorder@1.5.0/LICENSE-MIT +21 -0
  238. package/third-party/cargo/byteorder@1.5.0/UNLICENSE +24 -0
  239. package/third-party/cargo/cfg-if@1.0.4/Cargo.toml +47 -0
  240. package/third-party/cargo/cfg-if@1.0.4/LICENSE-APACHE +201 -0
  241. package/third-party/cargo/cfg-if@1.0.4/LICENSE-MIT +25 -0
  242. package/third-party/cargo/cfg_aliases@0.2.1/Cargo.toml +43 -0
  243. package/third-party/cargo/cfg_aliases@0.2.1/LICENSE +9 -0
  244. package/third-party/cargo/chunked_transfer@1.5.0/Cargo.toml +27 -0
  245. package/third-party/cargo/chunked_transfer@1.5.0/LICENSE-APACHE +201 -0
  246. package/third-party/cargo/chunked_transfer@1.5.0/LICENSE-MIT +22 -0
  247. package/third-party/cargo/codespan-reporting@0.13.1/Cargo.toml +115 -0
  248. package/third-party/cargo/codespan-reporting@0.13.1/LICENSE +201 -0
  249. package/third-party/cargo/color_quant@1.1.0/Cargo.toml +20 -0
  250. package/third-party/cargo/color_quant@1.1.0/LICENSE +21 -0
  251. package/third-party/cargo/console_error_panic_hook@0.1.7/Cargo.toml +27 -0
  252. package/third-party/cargo/console_error_panic_hook@0.1.7/LICENSE-APACHE +201 -0
  253. package/third-party/cargo/console_error_panic_hook@0.1.7/LICENSE-MIT +25 -0
  254. package/third-party/cargo/core_maths@0.1.1/Cargo.toml +37 -0
  255. package/third-party/cargo/core_maths@0.1.1/LICENSE +21 -0
  256. package/third-party/cargo/cosmic-text@0.19.0/Cargo.toml +214 -0
  257. package/third-party/cargo/cosmic-text@0.19.0/LICENSE-APACHE +201 -0
  258. package/third-party/cargo/cosmic-text@0.19.0/LICENSE-MIT +21 -0
  259. package/third-party/cargo/crc32fast@1.5.0/Cargo.toml +68 -0
  260. package/third-party/cargo/crc32fast@1.5.0/LICENSE-APACHE +202 -0
  261. package/third-party/cargo/crc32fast@1.5.0/LICENSE-MIT +21 -0
  262. package/third-party/cargo/data-url@0.3.2/Cargo.toml +63 -0
  263. package/third-party/cargo/data-url@0.3.2/LICENSE-APACHE +201 -0
  264. package/third-party/cargo/data-url@0.3.2/LICENSE-MIT +25 -0
  265. package/third-party/cargo/dispatch2@0.3.1/Cargo.toml +122 -0
  266. package/third-party/cargo/dispatch2@0.3.1/MIT-terms.txt +22 -0
  267. package/third-party/cargo/dispatch2@0.3.1/madsmtm-objc2-8852b424193c-LICENSE.md +34 -0
  268. package/third-party/cargo/dlib@0.5.3/Cargo.toml +43 -0
  269. package/third-party/cargo/dlib@0.5.3/LICENSE.txt +19 -0
  270. package/third-party/cargo/document-features@0.2.12/Cargo.toml +51 -0
  271. package/third-party/cargo/document-features@0.2.12/LICENSE-APACHE +73 -0
  272. package/third-party/cargo/document-features@0.2.12/LICENSE-MIT +19 -0
  273. package/third-party/cargo/equivalent@1.0.2/Cargo.toml +37 -0
  274. package/third-party/cargo/equivalent@1.0.2/LICENSE-APACHE +201 -0
  275. package/third-party/cargo/equivalent@1.0.2/LICENSE-MIT +25 -0
  276. package/third-party/cargo/errno@0.3.14/Cargo.toml +67 -0
  277. package/third-party/cargo/errno@0.3.14/LICENSE-APACHE +201 -0
  278. package/third-party/cargo/errno@0.3.14/LICENSE-MIT +25 -0
  279. package/third-party/cargo/etagere@0.3.0/Cargo.toml +57 -0
  280. package/third-party/cargo/etagere@0.3.0/LICENSE-APACHE +13 -0
  281. package/third-party/cargo/etagere@0.3.0/LICENSE-MIT +20 -0
  282. package/third-party/cargo/euclid@0.22.14/COPYRIGHT +5 -0
  283. package/third-party/cargo/euclid@0.22.14/Cargo.toml +66 -0
  284. package/third-party/cargo/euclid@0.22.14/LICENSE-APACHE +201 -0
  285. package/third-party/cargo/euclid@0.22.14/LICENSE-MIT +25 -0
  286. package/third-party/cargo/fastrand@2.5.0/Cargo.toml +89 -0
  287. package/third-party/cargo/fastrand@2.5.0/LICENSE-APACHE +201 -0
  288. package/third-party/cargo/fastrand@2.5.0/LICENSE-MIT +23 -0
  289. package/third-party/cargo/fdeflate@0.3.7/Cargo.toml +55 -0
  290. package/third-party/cargo/fdeflate@0.3.7/LICENSE-APACHE +177 -0
  291. package/third-party/cargo/fdeflate@0.3.7/LICENSE-MIT +25 -0
  292. package/third-party/cargo/flate2@1.1.9/Cargo.toml +274 -0
  293. package/third-party/cargo/flate2@1.1.9/LICENSE-APACHE +201 -0
  294. package/third-party/cargo/flate2@1.1.9/LICENSE-MIT +25 -0
  295. package/third-party/cargo/float-cmp@0.9.0/Cargo.toml +39 -0
  296. package/third-party/cargo/float-cmp@0.9.0/LICENSE +19 -0
  297. package/third-party/cargo/float_next_after@1.0.0/Cargo.toml +43 -0
  298. package/third-party/cargo/float_next_after@1.0.0/LICENSE +23 -0
  299. package/third-party/cargo/foldhash@0.2.0/Cargo.toml +80 -0
  300. package/third-party/cargo/foldhash@0.2.0/LICENSE +19 -0
  301. package/third-party/cargo/font-types@0.11.3/Cargo.toml +55 -0
  302. package/third-party/cargo/font-types@0.11.3/LICENSE-APACHE +67 -0
  303. package/third-party/cargo/font-types@0.11.3/LICENSE-MIT +25 -0
  304. package/third-party/cargo/fontdb@0.23.0/Cargo.toml +83 -0
  305. package/third-party/cargo/fontdb@0.23.0/LICENSE +21 -0
  306. package/third-party/cargo/futures-core@0.3.32/Cargo.toml +66 -0
  307. package/third-party/cargo/futures-core@0.3.32/LICENSE-APACHE +202 -0
  308. package/third-party/cargo/futures-core@0.3.32/LICENSE-MIT +26 -0
  309. package/third-party/cargo/futures-task@0.3.32/Cargo.toml +58 -0
  310. package/third-party/cargo/futures-task@0.3.32/LICENSE-APACHE +202 -0
  311. package/third-party/cargo/futures-task@0.3.32/LICENSE-MIT +26 -0
  312. package/third-party/cargo/futures-util@0.3.32/Cargo.toml +181 -0
  313. package/third-party/cargo/futures-util@0.3.32/LICENSE-APACHE +202 -0
  314. package/third-party/cargo/futures-util@0.3.32/LICENSE-MIT +26 -0
  315. package/third-party/cargo/getrandom@0.4.3/Cargo.toml +165 -0
  316. package/third-party/cargo/getrandom@0.4.3/LICENSE-APACHE +201 -0
  317. package/third-party/cargo/getrandom@0.4.3/LICENSE-MIT +26 -0
  318. package/third-party/cargo/gif@0.14.2/Cargo.toml +84 -0
  319. package/third-party/cargo/gif@0.14.2/LICENSE-APACHE +201 -0
  320. package/third-party/cargo/gif@0.14.2/LICENSE-MIT +21 -0
  321. package/third-party/cargo/glam@0.33.2/Cargo.toml +354 -0
  322. package/third-party/cargo/glam@0.33.2/LICENSE-APACHE +201 -0
  323. package/third-party/cargo/glam@0.33.2/LICENSE-MIT +23 -0
  324. package/third-party/cargo/glow@0.17.0/Cargo.toml +122 -0
  325. package/third-party/cargo/glow@0.17.0/LICENSE-APACHE +201 -0
  326. package/third-party/cargo/glow@0.17.0/LICENSE-MIT +23 -0
  327. package/third-party/cargo/glow@0.17.0/LICENSE-ZLIB +15 -0
  328. package/third-party/cargo/gltf-derive@1.4.1/Cargo.toml +34 -0
  329. package/third-party/cargo/gltf-derive@1.4.1/LICENSE-APACHE +202 -0
  330. package/third-party/cargo/gltf-derive@1.4.1/LICENSE-MIT +26 -0
  331. package/third-party/cargo/gltf-json@1.4.1/Cargo.toml +50 -0
  332. package/third-party/cargo/gltf-json@1.4.1/LICENSE-APACHE +202 -0
  333. package/third-party/cargo/gltf-json@1.4.1/LICENSE-MIT +26 -0
  334. package/third-party/cargo/gltf@1.4.1/Cargo.toml +122 -0
  335. package/third-party/cargo/gltf@1.4.1/LICENSE-APACHE +202 -0
  336. package/third-party/cargo/gltf@1.4.1/LICENSE-MIT +26 -0
  337. package/third-party/cargo/glyphon@0.12.0/Cargo.toml +35 -0
  338. package/third-party/cargo/glyphon@0.12.0/LICENSE-APACHE +201 -0
  339. package/third-party/cargo/glyphon@0.12.0/LICENSE-MIT +23 -0
  340. package/third-party/cargo/glyphon@0.12.0/LICENSE-ZLIB +15 -0
  341. package/third-party/cargo/gpu-allocator@0.28.0/Cargo.toml +180 -0
  342. package/third-party/cargo/gpu-allocator@0.28.0/LICENSE-APACHE +201 -0
  343. package/third-party/cargo/gpu-allocator@0.28.0/LICENSE-MIT +7 -0
  344. package/third-party/cargo/grid@1.0.1/Cargo.toml +77 -0
  345. package/third-party/cargo/grid@1.0.1/LICENSE +21 -0
  346. package/third-party/cargo/half@2.7.1/Cargo.toml +137 -0
  347. package/third-party/cargo/half@2.7.1/LICENSE-APACHE +176 -0
  348. package/third-party/cargo/half@2.7.1/LICENSE-MIT +19 -0
  349. package/third-party/cargo/harfrust@0.5.2/Cargo.toml +115 -0
  350. package/third-party/cargo/harfrust@0.5.2/harfbuzz-harfrust-efdae3142ab7-LICENSE +22 -0
  351. package/third-party/cargo/hashbrown@0.16.1/Cargo.toml +180 -0
  352. package/third-party/cargo/hashbrown@0.16.1/LICENSE-APACHE +201 -0
  353. package/third-party/cargo/hashbrown@0.16.1/LICENSE-MIT +25 -0
  354. package/third-party/cargo/hashbrown@0.17.1/Cargo.toml +201 -0
  355. package/third-party/cargo/hashbrown@0.17.1/LICENSE-APACHE +201 -0
  356. package/third-party/cargo/hashbrown@0.17.1/LICENSE-MIT +25 -0
  357. package/third-party/cargo/httpdate@1.0.3/Cargo.toml +35 -0
  358. package/third-party/cargo/httpdate@1.0.3/LICENSE-APACHE +201 -0
  359. package/third-party/cargo/httpdate@1.0.3/LICENSE-MIT +19 -0
  360. package/third-party/cargo/image-webp@0.2.4/Cargo.toml +63 -0
  361. package/third-party/cargo/image-webp@0.2.4/LICENSE-APACHE +177 -0
  362. package/third-party/cargo/image-webp@0.2.4/LICENSE-MIT +25 -0
  363. package/third-party/cargo/image@0.25.10/Cargo.toml +248 -0
  364. package/third-party/cargo/image@0.25.10/LICENSE-APACHE +177 -0
  365. package/third-party/cargo/image@0.25.10/LICENSE-MIT +25 -0
  366. package/third-party/cargo/imagesize@0.14.0/Cargo.toml +104 -0
  367. package/third-party/cargo/imagesize@0.14.0/LICENSE +21 -0
  368. package/third-party/cargo/indexmap@2.14.0/Cargo.toml +167 -0
  369. package/third-party/cargo/indexmap@2.14.0/LICENSE-APACHE +201 -0
  370. package/third-party/cargo/indexmap@2.14.0/LICENSE-MIT +25 -0
  371. package/third-party/cargo/inflections@1.1.1/Cargo.toml +21 -0
  372. package/third-party/cargo/inflections@1.1.1/LICENSE +20 -0
  373. package/third-party/cargo/itoa@1.0.18/Cargo.toml +66 -0
  374. package/third-party/cargo/itoa@1.0.18/LICENSE-APACHE +176 -0
  375. package/third-party/cargo/itoa@1.0.18/LICENSE-MIT +23 -0
  376. package/third-party/cargo/js-sys@0.3.103/Cargo.toml +98 -0
  377. package/third-party/cargo/js-sys@0.3.103/LICENSE-APACHE +201 -0
  378. package/third-party/cargo/js-sys@0.3.103/LICENSE-MIT +25 -0
  379. package/third-party/cargo/khronos-egl@6.0.0/Cargo.toml +82 -0
  380. package/third-party/cargo/khronos-egl@6.0.0/LICENSE-APACHE +201 -0
  381. package/third-party/cargo/khronos-egl@6.0.0/LICENSE-MIT +23 -0
  382. package/third-party/cargo/kurbo@0.13.1/Cargo.toml +230 -0
  383. package/third-party/cargo/kurbo@0.13.1/LICENSE-APACHE +202 -0
  384. package/third-party/cargo/kurbo@0.13.1/LICENSE-MIT +25 -0
  385. package/third-party/cargo/lazy_static@1.5.0/Cargo.toml +46 -0
  386. package/third-party/cargo/lazy_static@1.5.0/LICENSE-APACHE +201 -0
  387. package/third-party/cargo/lazy_static@1.5.0/LICENSE-MIT +25 -0
  388. package/third-party/cargo/libc@0.2.186/Cargo.toml +229 -0
  389. package/third-party/cargo/libc@0.2.186/LICENSE-APACHE +176 -0
  390. package/third-party/cargo/libc@0.2.186/LICENSE-MIT +25 -0
  391. package/third-party/cargo/libloading@0.8.9/Cargo.toml +90 -0
  392. package/third-party/cargo/libloading@0.8.9/LICENSE +12 -0
  393. package/third-party/cargo/libm@0.2.16/Cargo.toml +61 -0
  394. package/third-party/cargo/libm@0.2.16/LICENSE.txt +258 -0
  395. package/third-party/cargo/linebender_resource_handle@0.1.1/Cargo.toml +107 -0
  396. package/third-party/cargo/linebender_resource_handle@0.1.1/LICENSE-APACHE +176 -0
  397. package/third-party/cargo/linebender_resource_handle@0.1.1/LICENSE-MIT +19 -0
  398. package/third-party/cargo/litrs@1.0.0/Cargo.toml +63 -0
  399. package/third-party/cargo/litrs@1.0.0/LICENSE-APACHE +176 -0
  400. package/third-party/cargo/litrs@1.0.0/LICENSE-MIT +25 -0
  401. package/third-party/cargo/lock_api@0.4.14/Cargo.toml +68 -0
  402. package/third-party/cargo/lock_api@0.4.14/LICENSE-APACHE +201 -0
  403. package/third-party/cargo/lock_api@0.4.14/LICENSE-MIT +25 -0
  404. package/third-party/cargo/log@0.4.33/Cargo.toml +152 -0
  405. package/third-party/cargo/log@0.4.33/LICENSE-APACHE +201 -0
  406. package/third-party/cargo/log@0.4.33/LICENSE-MIT +25 -0
  407. package/third-party/cargo/lru@0.16.4/Cargo.toml +47 -0
  408. package/third-party/cargo/lru@0.16.4/LICENSE +21 -0
  409. package/third-party/cargo/lyon_geom@1.0.19/Cargo.toml +69 -0
  410. package/third-party/cargo/lyon_geom@1.0.19/nical-lyon-56219c95c658-LICENSE-APACHE +13 -0
  411. package/third-party/cargo/lyon_geom@1.0.19/nical-lyon-56219c95c658-LICENSE-MIT +20 -0
  412. package/third-party/cargo/lyon_path@1.0.19/Cargo.toml +58 -0
  413. package/third-party/cargo/lyon_path@1.0.19/nical-lyon-56219c95c658-LICENSE-APACHE +13 -0
  414. package/third-party/cargo/lyon_path@1.0.19/nical-lyon-56219c95c658-LICENSE-MIT +20 -0
  415. package/third-party/cargo/lyon_tessellation@1.0.20/Cargo.toml +71 -0
  416. package/third-party/cargo/lyon_tessellation@1.0.20/nical-lyon-7fa75ea8eea3-LICENSE-APACHE +13 -0
  417. package/third-party/cargo/lyon_tessellation@1.0.20/nical-lyon-7fa75ea8eea3-LICENSE-MIT +20 -0
  418. package/third-party/cargo/memchr@2.8.3/COPYING +3 -0
  419. package/third-party/cargo/memchr@2.8.3/Cargo.toml +89 -0
  420. package/third-party/cargo/memchr@2.8.3/LICENSE-MIT +21 -0
  421. package/third-party/cargo/memchr@2.8.3/UNLICENSE +24 -0
  422. package/third-party/cargo/memmap2@0.9.11/Cargo.toml +59 -0
  423. package/third-party/cargo/memmap2@0.9.11/LICENSE-APACHE +201 -0
  424. package/third-party/cargo/memmap2@0.9.11/LICENSE-MIT +26 -0
  425. package/third-party/cargo/miniz_oxide@0.8.9/Cargo.toml +91 -0
  426. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE +25 -0
  427. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE-APACHE.md +177 -0
  428. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE-MIT.md +24 -0
  429. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE-ZLIB.md +14 -0
  430. package/third-party/cargo/moxcms@0.8.1/Cargo.toml +113 -0
  431. package/third-party/cargo/moxcms@0.8.1/LICENSE-APACHE.md +201 -0
  432. package/third-party/cargo/moxcms@0.8.1/LICENSE.md +26 -0
  433. package/third-party/cargo/naga-types@30.0.0/Cargo.toml +94 -0
  434. package/third-party/cargo/naga-types@30.0.0/LICENSE.APACHE +176 -0
  435. package/third-party/cargo/naga-types@30.0.0/LICENSE.MIT +21 -0
  436. package/third-party/cargo/naga@30.0.0/Cargo.toml +246 -0
  437. package/third-party/cargo/naga@30.0.0/LICENSE.APACHE +176 -0
  438. package/third-party/cargo/naga@30.0.0/LICENSE.MIT +21 -0
  439. package/third-party/cargo/num-traits@0.2.19/Cargo.toml +54 -0
  440. package/third-party/cargo/num-traits@0.2.19/LICENSE-APACHE +201 -0
  441. package/third-party/cargo/num-traits@0.2.19/LICENSE-MIT +25 -0
  442. package/third-party/cargo/objc2-core-foundation@0.3.2/Cargo.toml +221 -0
  443. package/third-party/cargo/objc2-core-foundation@0.3.2/MIT-terms.txt +22 -0
  444. package/third-party/cargo/objc2-core-foundation@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  445. package/third-party/cargo/objc2-core-graphics@0.3.2/Cargo.toml +331 -0
  446. package/third-party/cargo/objc2-core-graphics@0.3.2/MIT-terms.txt +22 -0
  447. package/third-party/cargo/objc2-core-graphics@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  448. package/third-party/cargo/objc2-encode@4.1.0/Cargo.toml +81 -0
  449. package/third-party/cargo/objc2-encode@4.1.0/MIT-terms.txt +22 -0
  450. package/third-party/cargo/objc2-encode@4.1.0/madsmtm-objc2-8d214f547736-LICENSE.md +34 -0
  451. package/third-party/cargo/objc2-foundation@0.3.2/Cargo.toml +529 -0
  452. package/third-party/cargo/objc2-foundation@0.3.2/MIT-terms.txt +22 -0
  453. package/third-party/cargo/objc2-foundation@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  454. package/third-party/cargo/objc2-io-surface@0.3.2/Cargo.toml +139 -0
  455. package/third-party/cargo/objc2-io-surface@0.3.2/MIT-terms.txt +22 -0
  456. package/third-party/cargo/objc2-io-surface@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  457. package/third-party/cargo/objc2-metal@0.3.2/Cargo.toml +601 -0
  458. package/third-party/cargo/objc2-metal@0.3.2/MIT-terms.txt +22 -0
  459. package/third-party/cargo/objc2-metal@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  460. package/third-party/cargo/objc2-quartz-core@0.3.2/Cargo.toml +302 -0
  461. package/third-party/cargo/objc2-quartz-core@0.3.2/MIT-terms.txt +22 -0
  462. package/third-party/cargo/objc2-quartz-core@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  463. package/third-party/cargo/objc2@0.6.4/Cargo.toml +232 -0
  464. package/third-party/cargo/objc2@0.6.4/MIT-terms.txt +22 -0
  465. package/third-party/cargo/objc2@0.6.4/madsmtm-objc2-8852b424193c-LICENSE.md +34 -0
  466. package/third-party/cargo/once_cell@1.21.4/Cargo.toml +119 -0
  467. package/third-party/cargo/once_cell@1.21.4/LICENSE-APACHE +201 -0
  468. package/third-party/cargo/once_cell@1.21.4/LICENSE-MIT +23 -0
  469. package/third-party/cargo/ordered-float@5.3.0/Cargo.toml +162 -0
  470. package/third-party/cargo/ordered-float@5.3.0/LICENSE-MIT +25 -0
  471. package/third-party/cargo/parking_lot@0.12.5/Cargo.toml +87 -0
  472. package/third-party/cargo/parking_lot@0.12.5/LICENSE-APACHE +201 -0
  473. package/third-party/cargo/parking_lot@0.12.5/LICENSE-MIT +25 -0
  474. package/third-party/cargo/parking_lot_core@0.9.12/Cargo.toml +72 -0
  475. package/third-party/cargo/parking_lot_core@0.9.12/LICENSE-APACHE +201 -0
  476. package/third-party/cargo/parking_lot_core@0.9.12/LICENSE-MIT +25 -0
  477. package/third-party/cargo/pico-args@0.5.0/Cargo.toml +32 -0
  478. package/third-party/cargo/pico-args@0.5.0/LICENSE +20 -0
  479. package/third-party/cargo/pin-project-lite@0.2.17/Cargo.toml +198 -0
  480. package/third-party/cargo/pin-project-lite@0.2.17/LICENSE-APACHE +177 -0
  481. package/third-party/cargo/pin-project-lite@0.2.17/LICENSE-MIT +23 -0
  482. package/third-party/cargo/pkg-config@0.3.33/Cargo.toml +43 -0
  483. package/third-party/cargo/pkg-config@0.3.33/LICENSE-APACHE +201 -0
  484. package/third-party/cargo/pkg-config@0.3.33/LICENSE-MIT +25 -0
  485. package/third-party/cargo/png@0.18.1/Cargo.toml +130 -0
  486. package/third-party/cargo/png@0.18.1/LICENSE-APACHE +201 -0
  487. package/third-party/cargo/png@0.18.1/LICENSE-MIT +25 -0
  488. package/third-party/cargo/pollster@0.4.0/Cargo.toml +53 -0
  489. package/third-party/cargo/pollster@0.4.0/LICENSE-APACHE +201 -0
  490. package/third-party/cargo/pollster@0.4.0/LICENSE-MIT +25 -0
  491. package/third-party/cargo/polycool@0.4.0/Cargo.toml +83 -0
  492. package/third-party/cargo/polycool@0.4.0/LICENSE-APACHE +202 -0
  493. package/third-party/cargo/polycool@0.4.0/LICENSE-MIT +25 -0
  494. package/third-party/cargo/pp-rs@0.2.1/Cargo.toml +23 -0
  495. package/third-party/cargo/pp-rs@0.2.1/LICENSE +29 -0
  496. package/third-party/cargo/presser@0.3.1/Cargo.toml +58 -0
  497. package/third-party/cargo/presser@0.3.1/LICENSE-APACHE +201 -0
  498. package/third-party/cargo/presser@0.3.1/LICENSE-MIT +25 -0
  499. package/third-party/cargo/proc-macro2@1.0.106/Cargo.toml +105 -0
  500. package/third-party/cargo/proc-macro2@1.0.106/LICENSE-APACHE +176 -0
  501. package/third-party/cargo/proc-macro2@1.0.106/LICENSE-MIT +23 -0
  502. package/third-party/cargo/profiling@1.0.18/Cargo.toml +96 -0
  503. package/third-party/cargo/profiling@1.0.18/aclysma-profiling-8271551172eb-LICENSE-APACHE +201 -0
  504. package/third-party/cargo/profiling@1.0.18/aclysma-profiling-8271551172eb-LICENSE-MIT +21 -0
  505. package/third-party/cargo/pxfm@0.1.30/Cargo.toml +53 -0
  506. package/third-party/cargo/pxfm@0.1.30/LICENSE-APACHE.md +201 -0
  507. package/third-party/cargo/pxfm@0.1.30/LICENSE.md +26 -0
  508. package/third-party/cargo/quick-error@2.0.1/Cargo.toml +24 -0
  509. package/third-party/cargo/quick-error@2.0.1/LICENSE-APACHE +202 -0
  510. package/third-party/cargo/quick-error@2.0.1/LICENSE-MIT +19 -0
  511. package/third-party/cargo/quote@1.0.46/Cargo.toml +70 -0
  512. package/third-party/cargo/quote@1.0.46/LICENSE-APACHE +176 -0
  513. package/third-party/cargo/quote@1.0.46/LICENSE-MIT +23 -0
  514. package/third-party/cargo/rangemap@1.7.1/Cargo.toml +91 -0
  515. package/third-party/cargo/rangemap@1.7.1/LICENSE-APACHE +191 -0
  516. package/third-party/cargo/rangemap@1.7.1/LICENSE-MIT +7 -0
  517. package/third-party/cargo/raw-window-handle@0.6.2/Cargo.toml +56 -0
  518. package/third-party/cargo/raw-window-handle@0.6.2/LICENSE-APACHE.md +177 -0
  519. package/third-party/cargo/raw-window-handle@0.6.2/LICENSE-MIT.md +21 -0
  520. package/third-party/cargo/raw-window-handle@0.6.2/LICENSE-ZLIB.md +11 -0
  521. package/third-party/cargo/raw-window-metal@1.1.0/Cargo.toml +111 -0
  522. package/third-party/cargo/raw-window-metal@1.1.0/LICENSE-APACHE +202 -0
  523. package/third-party/cargo/raw-window-metal@1.1.0/LICENSE-MIT +17 -0
  524. package/third-party/cargo/read-fonts@0.37.0/Cargo.toml +95 -0
  525. package/third-party/cargo/read-fonts@0.37.0/LICENSE-APACHE +67 -0
  526. package/third-party/cargo/read-fonts@0.37.0/LICENSE-MIT +25 -0
  527. package/third-party/cargo/read-fonts@0.39.2/Cargo.toml +96 -0
  528. package/third-party/cargo/read-fonts@0.39.2/LICENSE-APACHE +67 -0
  529. package/third-party/cargo/read-fonts@0.39.2/LICENSE-MIT +25 -0
  530. package/third-party/cargo/renderdoc-sys@1.1.0/Cargo.toml +39 -0
  531. package/third-party/cargo/renderdoc-sys@1.1.0/LICENSE-APACHE +201 -0
  532. package/third-party/cargo/renderdoc-sys@1.1.0/LICENSE-MIT +25 -0
  533. package/third-party/cargo/resvg@0.47.0/Cargo.toml +112 -0
  534. package/third-party/cargo/resvg@0.47.0/LICENSE-APACHE +176 -0
  535. package/third-party/cargo/resvg@0.47.0/LICENSE-MIT +25 -0
  536. package/third-party/cargo/rgb@0.8.53/Cargo.toml +110 -0
  537. package/third-party/cargo/rgb@0.8.53/LICENSE +21 -0
  538. package/third-party/cargo/roxmltree@0.21.1/Cargo.toml +75 -0
  539. package/third-party/cargo/roxmltree@0.21.1/LICENSE-APACHE +201 -0
  540. package/third-party/cargo/roxmltree@0.21.1/LICENSE-MIT +21 -0
  541. package/third-party/cargo/rustc-hash@1.1.0/Cargo.toml +25 -0
  542. package/third-party/cargo/rustc-hash@1.1.0/LICENSE-APACHE +201 -0
  543. package/third-party/cargo/rustc-hash@1.1.0/LICENSE-MIT +23 -0
  544. package/third-party/cargo/rustc-hash@2.1.3/Cargo.toml +50 -0
  545. package/third-party/cargo/rustc-hash@2.1.3/LICENSE-APACHE +176 -0
  546. package/third-party/cargo/rustc-hash@2.1.3/LICENSE-MIT +23 -0
  547. package/third-party/cargo/rustix@1.1.4/COPYRIGHT +29 -0
  548. package/third-party/cargo/rustix@1.1.4/Cargo.toml +292 -0
  549. package/third-party/cargo/rustix@1.1.4/LICENSE-APACHE +201 -0
  550. package/third-party/cargo/rustix@1.1.4/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  551. package/third-party/cargo/rustix@1.1.4/LICENSE-MIT +23 -0
  552. package/third-party/cargo/rustversion@1.0.23/Cargo.toml +69 -0
  553. package/third-party/cargo/rustversion@1.0.23/LICENSE-APACHE +176 -0
  554. package/third-party/cargo/rustversion@1.0.23/LICENSE-MIT +23 -0
  555. package/third-party/cargo/rustybuzz@0.20.1/Cargo.toml +110 -0
  556. package/third-party/cargo/rustybuzz@0.20.1/LICENSE +22 -0
  557. package/third-party/cargo/scopeguard@1.2.0/Cargo.toml +43 -0
  558. package/third-party/cargo/scopeguard@1.2.0/LICENSE-APACHE +201 -0
  559. package/third-party/cargo/scopeguard@1.2.0/LICENSE-MIT +25 -0
  560. package/third-party/cargo/self_cell@1.2.2/Cargo.toml +33 -0
  561. package/third-party/cargo/self_cell@1.2.2/LICENSE-APACHE +201 -0
  562. package/third-party/cargo/self_cell@1.2.2/LICENSE-GPLv2 +339 -0
  563. package/third-party/cargo/self_cell@1.3.0/Cargo.toml +33 -0
  564. package/third-party/cargo/self_cell@1.3.0/LICENSE-APACHE +201 -0
  565. package/third-party/cargo/self_cell@1.3.0/LICENSE-GPLv2 +339 -0
  566. package/third-party/cargo/serde@1.0.228/Cargo.toml +84 -0
  567. package/third-party/cargo/serde@1.0.228/LICENSE-APACHE +176 -0
  568. package/third-party/cargo/serde@1.0.228/LICENSE-MIT +23 -0
  569. package/third-party/cargo/serde_core@1.0.228/Cargo.toml +87 -0
  570. package/third-party/cargo/serde_core@1.0.228/LICENSE-APACHE +176 -0
  571. package/third-party/cargo/serde_core@1.0.228/LICENSE-MIT +23 -0
  572. package/third-party/cargo/serde_derive@1.0.228/Cargo.toml +87 -0
  573. package/third-party/cargo/serde_derive@1.0.228/LICENSE-APACHE +176 -0
  574. package/third-party/cargo/serde_derive@1.0.228/LICENSE-MIT +23 -0
  575. package/third-party/cargo/serde_json@1.0.150/Cargo.toml +162 -0
  576. package/third-party/cargo/serde_json@1.0.150/LICENSE-APACHE +176 -0
  577. package/third-party/cargo/serde_json@1.0.150/LICENSE-MIT +23 -0
  578. package/third-party/cargo/simd-adler32@0.3.10/Cargo.toml +68 -0
  579. package/third-party/cargo/simd-adler32@0.3.10/LICENSE.md +21 -0
  580. package/third-party/cargo/simplecss@0.2.2/Cargo.toml +146 -0
  581. package/third-party/cargo/simplecss@0.2.2/LICENSE-APACHE +201 -0
  582. package/third-party/cargo/simplecss@0.2.2/LICENSE-MIT +21 -0
  583. package/third-party/cargo/siphasher@1.0.3/COPYING +7 -0
  584. package/third-party/cargo/siphasher@1.0.3/Cargo.toml +64 -0
  585. package/third-party/cargo/skrifa@0.40.0/Cargo.toml +86 -0
  586. package/third-party/cargo/skrifa@0.40.0/LICENSE-APACHE +67 -0
  587. package/third-party/cargo/skrifa@0.40.0/LICENSE-MIT +25 -0
  588. package/third-party/cargo/skrifa@0.42.1/Cargo.toml +86 -0
  589. package/third-party/cargo/skrifa@0.42.1/LICENSE-APACHE +67 -0
  590. package/third-party/cargo/skrifa@0.42.1/LICENSE-MIT +25 -0
  591. package/third-party/cargo/slab@0.4.12/Cargo.toml +67 -0
  592. package/third-party/cargo/slab@0.4.12/LICENSE +25 -0
  593. package/third-party/cargo/slotmap@1.1.1/Cargo.toml +83 -0
  594. package/third-party/cargo/slotmap@1.1.1/LICENSE +19 -0
  595. package/third-party/cargo/smallvec@1.15.2/Cargo.toml +103 -0
  596. package/third-party/cargo/smallvec@1.15.2/LICENSE-APACHE +201 -0
  597. package/third-party/cargo/smallvec@1.15.2/LICENSE-MIT +25 -0
  598. package/third-party/cargo/smol_str@0.3.6/Cargo.toml +155 -0
  599. package/third-party/cargo/smol_str@0.3.6/LICENSE-APACHE +201 -0
  600. package/third-party/cargo/smol_str@0.3.6/LICENSE-MIT +23 -0
  601. package/third-party/cargo/spirv@0.4.0+sdk-1.4.341.0/Cargo.toml +56 -0
  602. package/third-party/cargo/spirv@0.4.0+sdk-1.4.341.0/gfx-rs-rspirv-8afc3d0ac8e1-LICENSE +202 -0
  603. package/third-party/cargo/static_assertions@1.1.0/Cargo.toml +39 -0
  604. package/third-party/cargo/static_assertions@1.1.0/LICENSE-APACHE +202 -0
  605. package/third-party/cargo/static_assertions@1.1.0/LICENSE-MIT +21 -0
  606. package/third-party/cargo/strict-num@0.1.1/Cargo.toml +35 -0
  607. package/third-party/cargo/strict-num@0.1.1/LICENSE +19 -0
  608. package/third-party/cargo/svgtypes@0.16.1/Cargo.toml +57 -0
  609. package/third-party/cargo/svgtypes@0.16.1/LICENSE-APACHE +201 -0
  610. package/third-party/cargo/svgtypes@0.16.1/LICENSE-MIT +20 -0
  611. package/third-party/cargo/swash@0.2.9/Cargo.toml +93 -0
  612. package/third-party/cargo/swash@0.2.9/LICENSE-APACHE +201 -0
  613. package/third-party/cargo/swash@0.2.9/LICENSE-MIT +25 -0
  614. package/third-party/cargo/syn@2.0.118/Cargo.toml +272 -0
  615. package/third-party/cargo/syn@2.0.118/LICENSE-APACHE +176 -0
  616. package/third-party/cargo/syn@2.0.118/LICENSE-MIT +23 -0
  617. package/third-party/cargo/sys-locale@0.3.2/Cargo.toml +73 -0
  618. package/third-party/cargo/sys-locale@0.3.2/LICENSE-APACHE +201 -0
  619. package/third-party/cargo/sys-locale@0.3.2/LICENSE-MIT +21 -0
  620. package/third-party/cargo/taffy@0.12.1/Cargo.toml +171 -0
  621. package/third-party/cargo/taffy@0.12.1/DioxusLabs-taffy-1c9e37a0a1cf-LICENSE.md +25 -0
  622. package/third-party/cargo/tempfile@3.27.0/Cargo.toml +105 -0
  623. package/third-party/cargo/tempfile@3.27.0/LICENSE-APACHE +201 -0
  624. package/third-party/cargo/tempfile@3.27.0/LICENSE-MIT +25 -0
  625. package/third-party/cargo/termcolor@1.4.1/COPYING +3 -0
  626. package/third-party/cargo/termcolor@1.4.1/Cargo.toml +40 -0
  627. package/third-party/cargo/termcolor@1.4.1/LICENSE-MIT +21 -0
  628. package/third-party/cargo/termcolor@1.4.1/UNLICENSE +24 -0
  629. package/third-party/cargo/thiserror-impl@2.0.18/Cargo.toml +52 -0
  630. package/third-party/cargo/thiserror-impl@2.0.18/LICENSE-APACHE +176 -0
  631. package/third-party/cargo/thiserror-impl@2.0.18/LICENSE-MIT +23 -0
  632. package/third-party/cargo/thiserror@2.0.18/Cargo.toml +119 -0
  633. package/third-party/cargo/thiserror@2.0.18/LICENSE-APACHE +176 -0
  634. package/third-party/cargo/thiserror@2.0.18/LICENSE-MIT +23 -0
  635. package/third-party/cargo/tiny-skia-path@0.12.0/Cargo.toml +58 -0
  636. package/third-party/cargo/tiny-skia-path@0.12.0/LICENSE +30 -0
  637. package/third-party/cargo/tiny-skia@0.12.0/Cargo.toml +116 -0
  638. package/third-party/cargo/tiny-skia@0.12.0/LICENSE +30 -0
  639. package/third-party/cargo/tiny_http@0.12.0/Cargo.toml +82 -0
  640. package/third-party/cargo/tiny_http@0.12.0/LICENSE-APACHE +201 -0
  641. package/third-party/cargo/tiny_http@0.12.0/LICENSE-MIT +25 -0
  642. package/third-party/cargo/tinyvec@1.12.0/Cargo.toml +184 -0
  643. package/third-party/cargo/tinyvec@1.12.0/LICENSE-APACHE.md +202 -0
  644. package/third-party/cargo/tinyvec@1.12.0/LICENSE-MIT.md +5 -0
  645. package/third-party/cargo/tinyvec@1.12.0/LICENSE-ZLIB.md +11 -0
  646. package/third-party/cargo/tinyvec_macros@0.1.1/Cargo.toml +19 -0
  647. package/third-party/cargo/tinyvec_macros@0.1.1/LICENSE-APACHE.md +202 -0
  648. package/third-party/cargo/tinyvec_macros@0.1.1/LICENSE-MIT.md +21 -0
  649. package/third-party/cargo/tinyvec_macros@0.1.1/LICENSE-ZLIB.md +20 -0
  650. package/third-party/cargo/ttf-parser@0.25.1/Cargo.toml +101 -0
  651. package/third-party/cargo/ttf-parser@0.25.1/LICENSE-APACHE +201 -0
  652. package/third-party/cargo/ttf-parser@0.25.1/LICENSE-MIT +20 -0
  653. package/third-party/cargo/unicode-bidi-mirroring@0.4.0/Cargo.toml +22 -0
  654. package/third-party/cargo/unicode-bidi-mirroring@0.4.0/LICENSE-APACHE +201 -0
  655. package/third-party/cargo/unicode-bidi-mirroring@0.4.0/LICENSE-MIT +21 -0
  656. package/third-party/cargo/unicode-bidi@0.3.18/COPYRIGHT +8 -0
  657. package/third-party/cargo/unicode-bidi@0.3.18/Cargo.toml +90 -0
  658. package/third-party/cargo/unicode-bidi@0.3.18/LICENSE-APACHE +201 -0
  659. package/third-party/cargo/unicode-bidi@0.3.18/LICENSE-MIT +25 -0
  660. package/third-party/cargo/unicode-ccc@0.4.0/Cargo.toml +22 -0
  661. package/third-party/cargo/unicode-ccc@0.4.0/LICENSE-APACHE +201 -0
  662. package/third-party/cargo/unicode-ccc@0.4.0/LICENSE-MIT +21 -0
  663. package/third-party/cargo/unicode-ident@1.0.24/Cargo.toml +84 -0
  664. package/third-party/cargo/unicode-ident@1.0.24/LICENSE-APACHE +176 -0
  665. package/third-party/cargo/unicode-ident@1.0.24/LICENSE-MIT +23 -0
  666. package/third-party/cargo/unicode-ident@1.0.24/LICENSE-UNICODE +39 -0
  667. package/third-party/cargo/unicode-linebreak@0.1.5/Cargo.toml +32 -0
  668. package/third-party/cargo/unicode-linebreak@0.1.5/LICENSE +201 -0
  669. package/third-party/cargo/unicode-properties@0.1.4/COPYRIGHT +7 -0
  670. package/third-party/cargo/unicode-properties@0.1.4/Cargo.toml +65 -0
  671. package/third-party/cargo/unicode-properties@0.1.4/LICENSE-APACHE +201 -0
  672. package/third-party/cargo/unicode-properties@0.1.4/LICENSE-MIT +25 -0
  673. package/third-party/cargo/unicode-script@0.5.8/Cargo.toml +63 -0
  674. package/third-party/cargo/unicode-script@0.5.8/LICENSE-APACHE +201 -0
  675. package/third-party/cargo/unicode-script@0.5.8/LICENSE-MIT +27 -0
  676. package/third-party/cargo/unicode-segmentation@1.13.3/COPYRIGHT +7 -0
  677. package/third-party/cargo/unicode-segmentation@1.13.3/Cargo.toml +91 -0
  678. package/third-party/cargo/unicode-segmentation@1.13.3/LICENSE-APACHE +201 -0
  679. package/third-party/cargo/unicode-segmentation@1.13.3/LICENSE-MIT +25 -0
  680. package/third-party/cargo/unicode-vo@0.1.0/Cargo.toml +22 -0
  681. package/third-party/cargo/unicode-vo@0.1.0/LICENSE-APACHE +201 -0
  682. package/third-party/cargo/unicode-vo@0.1.0/LICENSE-MIT +21 -0
  683. package/third-party/cargo/unicode-width@0.2.2/COPYRIGHT +7 -0
  684. package/third-party/cargo/unicode-width@0.2.2/Cargo.toml +77 -0
  685. package/third-party/cargo/unicode-width@0.2.2/LICENSE-APACHE +201 -0
  686. package/third-party/cargo/unicode-width@0.2.2/LICENSE-MIT +25 -0
  687. package/third-party/cargo/unicode-xid@0.2.6/COPYRIGHT +7 -0
  688. package/third-party/cargo/unicode-xid@0.2.6/Cargo.toml +65 -0
  689. package/third-party/cargo/unicode-xid@0.2.6/LICENSE-APACHE +201 -0
  690. package/third-party/cargo/unicode-xid@0.2.6/LICENSE-MIT +25 -0
  691. package/third-party/cargo/urlencoding@2.1.3/Cargo.toml +41 -0
  692. package/third-party/cargo/urlencoding@2.1.3/LICENSE +20 -0
  693. package/third-party/cargo/usvg@0.47.0/Cargo.toml +138 -0
  694. package/third-party/cargo/usvg@0.47.0/LICENSE-APACHE +176 -0
  695. package/third-party/cargo/usvg@0.47.0/LICENSE-MIT +25 -0
  696. package/third-party/cargo/version_check@0.9.5/Cargo.toml +38 -0
  697. package/third-party/cargo/version_check@0.9.5/LICENSE-APACHE +201 -0
  698. package/third-party/cargo/version_check@0.9.5/LICENSE-MIT +19 -0
  699. package/third-party/cargo/wasm-bindgen-futures@0.4.76/Cargo.toml +88 -0
  700. package/third-party/cargo/wasm-bindgen-futures@0.4.76/LICENSE-APACHE +201 -0
  701. package/third-party/cargo/wasm-bindgen-futures@0.4.76/LICENSE-MIT +25 -0
  702. package/third-party/cargo/wasm-bindgen-macro-support@0.2.126/Cargo.toml +83 -0
  703. package/third-party/cargo/wasm-bindgen-macro-support@0.2.126/LICENSE-APACHE +201 -0
  704. package/third-party/cargo/wasm-bindgen-macro-support@0.2.126/LICENSE-MIT +25 -0
  705. package/third-party/cargo/wasm-bindgen-macro@0.2.126/Cargo.toml +73 -0
  706. package/third-party/cargo/wasm-bindgen-macro@0.2.126/LICENSE-APACHE +201 -0
  707. package/third-party/cargo/wasm-bindgen-macro@0.2.126/LICENSE-MIT +25 -0
  708. package/third-party/cargo/wasm-bindgen-shared@0.2.126/Cargo.toml +66 -0
  709. package/third-party/cargo/wasm-bindgen-shared@0.2.126/LICENSE-APACHE +201 -0
  710. package/third-party/cargo/wasm-bindgen-shared@0.2.126/LICENSE-MIT +25 -0
  711. package/third-party/cargo/wasm-bindgen@0.2.126/Cargo.toml +122 -0
  712. package/third-party/cargo/wasm-bindgen@0.2.126/LICENSE-APACHE +201 -0
  713. package/third-party/cargo/wasm-bindgen@0.2.126/LICENSE-MIT +25 -0
  714. package/third-party/cargo/wayland-sys@0.31.11/Cargo.toml +81 -0
  715. package/third-party/cargo/wayland-sys@0.31.11/LICENSE.txt +19 -0
  716. package/third-party/cargo/web-sys@0.3.103/Cargo.toml +2823 -0
  717. package/third-party/cargo/web-sys@0.3.103/LICENSE-APACHE +201 -0
  718. package/third-party/cargo/web-sys@0.3.103/LICENSE-MIT +25 -0
  719. package/third-party/cargo/weezl@0.1.12/Cargo.toml +120 -0
  720. package/third-party/cargo/weezl@0.1.12/LICENSE-APACHE +201 -0
  721. package/third-party/cargo/weezl@0.1.12/LICENSE-MIT +22 -0
  722. package/third-party/cargo/wgpu-core-deps-apple@30.0.0/Cargo.toml +53 -0
  723. package/third-party/cargo/wgpu-core-deps-apple@30.0.0/LICENSE.APACHE +176 -0
  724. package/third-party/cargo/wgpu-core-deps-apple@30.0.0/LICENSE.MIT +21 -0
  725. package/third-party/cargo/wgpu-core@30.0.0/Cargo.toml +237 -0
  726. package/third-party/cargo/wgpu-core@30.0.0/LICENSE.APACHE +176 -0
  727. package/third-party/cargo/wgpu-core@30.0.0/LICENSE.MIT +21 -0
  728. package/third-party/cargo/wgpu-hal@30.0.0/Cargo.toml +541 -0
  729. package/third-party/cargo/wgpu-hal@30.0.0/LICENSE.APACHE +176 -0
  730. package/third-party/cargo/wgpu-hal@30.0.0/LICENSE.MIT +21 -0
  731. package/third-party/cargo/wgpu-naga-bridge@30.0.0/Cargo.toml +46 -0
  732. package/third-party/cargo/wgpu-naga-bridge@30.0.0/LICENSE.APACHE +176 -0
  733. package/third-party/cargo/wgpu-naga-bridge@30.0.0/LICENSE.MIT +21 -0
  734. package/third-party/cargo/wgpu-types@30.0.0/Cargo.toml +161 -0
  735. package/third-party/cargo/wgpu-types@30.0.0/LICENSE.APACHE +176 -0
  736. package/third-party/cargo/wgpu-types@30.0.0/LICENSE.MIT +21 -0
  737. package/third-party/cargo/wgpu@30.0.0/Cargo.toml +278 -0
  738. package/third-party/cargo/wgpu@30.0.0/LICENSE.APACHE +176 -0
  739. package/third-party/cargo/wgpu@30.0.0/LICENSE.MIT +21 -0
  740. package/third-party/cargo/xmlwriter@0.1.0/Cargo.toml +23 -0
  741. package/third-party/cargo/xmlwriter@0.1.0/LICENSE +21 -0
  742. package/third-party/cargo/yazi@0.2.1/Cargo.toml +45 -0
  743. package/third-party/cargo/yazi@0.2.1/LICENSE-APACHE +201 -0
  744. package/third-party/cargo/yazi@0.2.1/LICENSE-MIT +19 -0
  745. package/third-party/cargo/zeno@0.3.3/Cargo.toml +65 -0
  746. package/third-party/cargo/zeno@0.3.3/LICENSE-APACHE +201 -0
  747. package/third-party/cargo/zeno@0.3.3/LICENSE-MIT +25 -0
  748. package/third-party/cargo/zerocopy-derive@0.8.54/Cargo.toml +209 -0
  749. package/third-party/cargo/zerocopy-derive@0.8.54/LICENSE-APACHE +202 -0
  750. package/third-party/cargo/zerocopy-derive@0.8.54/LICENSE-BSD +24 -0
  751. package/third-party/cargo/zerocopy-derive@0.8.54/LICENSE-MIT +26 -0
  752. package/third-party/cargo/zerocopy@0.8.54/Cargo.toml +419 -0
  753. package/third-party/cargo/zerocopy@0.8.54/LICENSE-APACHE +202 -0
  754. package/third-party/cargo/zerocopy@0.8.54/LICENSE-BSD +24 -0
  755. package/third-party/cargo/zerocopy@0.8.54/LICENSE-MIT +26 -0
  756. package/third-party/cargo/zmij@1.0.23/Cargo.toml +90 -0
  757. package/third-party/cargo/zmij@1.0.23/LICENSE-MIT +23 -0
  758. package/third-party/cargo/zune-core@0.5.1/Cargo.toml +47 -0
  759. package/third-party/cargo/zune-core@0.5.1/LICENSE-APACHE +201 -0
  760. package/third-party/cargo/zune-core@0.5.1/LICENSE-MIT +21 -0
  761. package/third-party/cargo/zune-core@0.5.1/LICENSE-ZLIB +19 -0
  762. package/third-party/cargo/zune-jpeg@0.5.15/Cargo.toml +67 -0
  763. package/third-party/cargo/zune-jpeg@0.5.15/LICENSE-APACHE +201 -0
  764. package/third-party/cargo/zune-jpeg@0.5.15/LICENSE-MIT +21 -0
  765. package/third-party/cargo/zune-jpeg@0.5.15/LICENSE-ZLIB +19 -0
  766. package/third-party/inventory.json +3614 -0
  767. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/esbuild-0.27.4-LICENSE.md +21 -0
  768. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/go-LICENSE +27 -0
  769. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/golang-x-sys-c0bba94af5f8-LICENSE +27 -0
  770. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/package.json +20 -0
  771. package/third-party/npm/@floating-ui__core@1.7.5/LICENSE +20 -0
  772. package/third-party/npm/@floating-ui__core@1.7.5/package.json +63 -0
  773. package/third-party/npm/@floating-ui__dom@1.7.6/LICENSE +20 -0
  774. package/third-party/npm/@floating-ui__dom@1.7.6/package.json +71 -0
  775. package/third-party/npm/@floating-ui__react-dom@2.1.8/LICENSE +20 -0
  776. package/third-party/npm/@floating-ui__react-dom@2.1.8/package.json +76 -0
  777. package/third-party/npm/@floating-ui__utils@0.2.11/LICENSE +20 -0
  778. package/third-party/npm/@floating-ui__utils@0.2.11/package.json +70 -0
  779. package/third-party/npm/@radix-ui__primitive@1.1.7/LICENSE +21 -0
  780. package/third-party/npm/@radix-ui__primitive@1.1.7/package.json +79 -0
  781. package/third-party/npm/@radix-ui__react-arrow@1.1.15/LICENSE +21 -0
  782. package/third-party/npm/@radix-ui__react-arrow@1.1.15/package.json +68 -0
  783. package/third-party/npm/@radix-ui__react-collection@1.1.15/LICENSE +21 -0
  784. package/third-party/npm/@radix-ui__react-collection@1.1.15/package.json +71 -0
  785. package/third-party/npm/@radix-ui__react-compose-refs@1.1.5/LICENSE +21 -0
  786. package/third-party/npm/@radix-ui__react-compose-refs@1.1.5/package.json +60 -0
  787. package/third-party/npm/@radix-ui__react-context-menu@2.3.7/LICENSE +21 -0
  788. package/third-party/npm/@radix-ui__react-context-menu@2.3.7/package.json +73 -0
  789. package/third-party/npm/@radix-ui__react-context@1.2.2/LICENSE +21 -0
  790. package/third-party/npm/@radix-ui__react-context@1.2.2/package.json +60 -0
  791. package/third-party/npm/@radix-ui__react-direction@1.1.4/LICENSE +21 -0
  792. package/third-party/npm/@radix-ui__react-direction@1.1.4/package.json +60 -0
  793. package/third-party/npm/@radix-ui__react-dismissable-layer@1.1.19/LICENSE +21 -0
  794. package/third-party/npm/@radix-ui__react-dismissable-layer@1.1.19/package.json +74 -0
  795. package/third-party/npm/@radix-ui__react-focus-guards@1.1.6/LICENSE +21 -0
  796. package/third-party/npm/@radix-ui__react-focus-guards@1.1.6/package.json +60 -0
  797. package/third-party/npm/@radix-ui__react-focus-scope@1.1.16/LICENSE +21 -0
  798. package/third-party/npm/@radix-ui__react-focus-scope@1.1.16/package.json +71 -0
  799. package/third-party/npm/@radix-ui__react-id@1.1.4/LICENSE +21 -0
  800. package/third-party/npm/@radix-ui__react-id@1.1.4/package.json +63 -0
  801. package/third-party/npm/@radix-ui__react-menu@2.1.24/LICENSE +21 -0
  802. package/third-party/npm/@radix-ui__react-menu@2.1.24/package.json +86 -0
  803. package/third-party/npm/@radix-ui__react-popper@1.3.7/LICENSE +21 -0
  804. package/third-party/npm/@radix-ui__react-popper@1.3.7/package.json +78 -0
  805. package/third-party/npm/@radix-ui__react-portal@1.1.17/LICENSE +21 -0
  806. package/third-party/npm/@radix-ui__react-portal@1.1.17/package.json +69 -0
  807. package/third-party/npm/@radix-ui__react-presence@1.1.10/LICENSE +21 -0
  808. package/third-party/npm/@radix-ui__react-presence@1.1.10/package.json +68 -0
  809. package/third-party/npm/@radix-ui__react-primitive@2.1.10/LICENSE +21 -0
  810. package/third-party/npm/@radix-ui__react-primitive@2.1.10/package.json +68 -0
  811. package/third-party/npm/@radix-ui__react-roving-focus@1.1.19/LICENSE +21 -0
  812. package/third-party/npm/@radix-ui__react-roving-focus@1.1.19/package.json +78 -0
  813. package/third-party/npm/@radix-ui__react-slot@1.3.3/LICENSE +21 -0
  814. package/third-party/npm/@radix-ui__react-slot@1.3.3/package.json +63 -0
  815. package/third-party/npm/@radix-ui__react-use-callback-ref@1.1.4/LICENSE +21 -0
  816. package/third-party/npm/@radix-ui__react-use-callback-ref@1.1.4/package.json +60 -0
  817. package/third-party/npm/@radix-ui__react-use-controllable-state@1.2.6/LICENSE +21 -0
  818. package/third-party/npm/@radix-ui__react-use-controllable-state@1.2.6/package.json +65 -0
  819. package/third-party/npm/@radix-ui__react-use-effect-event@0.0.5/LICENSE +21 -0
  820. package/third-party/npm/@radix-ui__react-use-effect-event@0.0.5/package.json +65 -0
  821. package/third-party/npm/@radix-ui__react-use-is-hydrated@0.1.3/LICENSE +21 -0
  822. package/third-party/npm/@radix-ui__react-use-is-hydrated@0.1.3/package.json +61 -0
  823. package/third-party/npm/@radix-ui__react-use-layout-effect@1.1.4/LICENSE +21 -0
  824. package/third-party/npm/@radix-ui__react-use-layout-effect@1.1.4/package.json +60 -0
  825. package/third-party/npm/@radix-ui__react-use-size@1.1.4/LICENSE +21 -0
  826. package/third-party/npm/@radix-ui__react-use-size@1.1.4/package.json +63 -0
  827. package/third-party/npm/aria-hidden@1.2.6/LICENSE +21 -0
  828. package/third-party/npm/aria-hidden@1.2.6/package.json +71 -0
  829. package/third-party/npm/detect-node-es@1.1.0/LICENSE +21 -0
  830. package/third-party/npm/detect-node-es@1.1.0/package.json +29 -0
  831. package/third-party/npm/esbuild@0.27.4/LICENSE.md +21 -0
  832. package/third-party/npm/esbuild@0.27.4/package.json +49 -0
  833. package/third-party/npm/fflate@0.8.3/LICENSE +21 -0
  834. package/third-party/npm/fflate@0.8.3/package.json +128 -0
  835. package/third-party/npm/get-nonce@1.0.1/LICENSE +21 -0
  836. package/third-party/npm/get-nonce@1.0.1/package.json +68 -0
  837. package/third-party/npm/mediabunny@1.52.2/LICENSE +373 -0
  838. package/third-party/npm/mediabunny@1.52.2/package.json +136 -0
  839. package/third-party/npm/mediabunny@1.52.2/source/LICENSE +373 -0
  840. package/third-party/npm/mediabunny@1.52.2/source/package.json +136 -0
  841. package/third-party/npm/mediabunny@1.52.2/source/src/adts/adts-demuxer.ts +400 -0
  842. package/third-party/npm/mediabunny@1.52.2/source/src/adts/adts-muxer.ts +124 -0
  843. package/third-party/npm/mediabunny@1.52.2/source/src/adts/adts-reader.ts +85 -0
  844. package/third-party/npm/mediabunny@1.52.2/source/src/aes.ts +307 -0
  845. package/third-party/npm/mediabunny@1.52.2/source/src/codec-data.ts +3178 -0
  846. package/third-party/npm/mediabunny@1.52.2/source/src/codec.ts +1154 -0
  847. package/third-party/npm/mediabunny@1.52.2/source/src/conversion.ts +2042 -0
  848. package/third-party/npm/mediabunny@1.52.2/source/src/custom-coder.ts +212 -0
  849. package/third-party/npm/mediabunny@1.52.2/source/src/decode.ts +263 -0
  850. package/third-party/npm/mediabunny@1.52.2/source/src/demuxer.ts +43 -0
  851. package/third-party/npm/mediabunny@1.52.2/source/src/encode.ts +1412 -0
  852. package/third-party/npm/mediabunny@1.52.2/source/src/flac/flac-demuxer.ts +813 -0
  853. package/third-party/npm/mediabunny@1.52.2/source/src/flac/flac-misc.ts +165 -0
  854. package/third-party/npm/mediabunny@1.52.2/source/src/flac/flac-muxer.ts +350 -0
  855. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-demuxer.ts +995 -0
  856. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-misc.ts +81 -0
  857. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-muxer.ts +1529 -0
  858. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-segmented-input.ts +772 -0
  859. package/third-party/npm/mediabunny@1.52.2/source/src/id3.ts +972 -0
  860. package/third-party/npm/mediabunny@1.52.2/source/src/index.ts +319 -0
  861. package/third-party/npm/mediabunny@1.52.2/source/src/input-format.ts +819 -0
  862. package/third-party/npm/mediabunny@1.52.2/source/src/input-track.ts +1141 -0
  863. package/third-party/npm/mediabunny@1.52.2/source/src/input.ts +571 -0
  864. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-boxes.ts +1911 -0
  865. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-demuxer.ts +3953 -0
  866. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-misc.ts +90 -0
  867. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-muxer.ts +1595 -0
  868. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-reader.ts +91 -0
  869. package/third-party/npm/mediabunny@1.52.2/source/src/logging.ts +120 -0
  870. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/ebml.ts +770 -0
  871. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/matroska-demuxer.ts +2598 -0
  872. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/matroska-misc.ts +29 -0
  873. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/matroska-muxer.ts +1360 -0
  874. package/third-party/npm/mediabunny@1.52.2/source/src/media-sink.ts +2589 -0
  875. package/third-party/npm/mediabunny@1.52.2/source/src/media-source.ts +3041 -0
  876. package/third-party/npm/mediabunny@1.52.2/source/src/metadata.ts +335 -0
  877. package/third-party/npm/mediabunny@1.52.2/source/src/misc.ts +1336 -0
  878. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-demuxer.ts +469 -0
  879. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-muxer.ts +169 -0
  880. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-reader.ts +61 -0
  881. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-writer.ts +121 -0
  882. package/third-party/npm/mediabunny@1.52.2/source/src/mpeg-ts/mpeg-ts-demuxer.ts +2519 -0
  883. package/third-party/npm/mediabunny@1.52.2/source/src/mpeg-ts/mpeg-ts-misc.ts +32 -0
  884. package/third-party/npm/mediabunny@1.52.2/source/src/mpeg-ts/mpeg-ts-muxer.ts +842 -0
  885. package/third-party/npm/mediabunny@1.52.2/source/src/muxer.ts +80 -0
  886. package/third-party/npm/mediabunny@1.52.2/source/src/node.ts +11 -0
  887. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-demuxer.ts +1087 -0
  888. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-misc.ts +116 -0
  889. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-muxer.ts +527 -0
  890. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-reader.ts +93 -0
  891. package/third-party/npm/mediabunny@1.52.2/source/src/output-format.ts +1425 -0
  892. package/third-party/npm/mediabunny@1.52.2/source/src/output.ts +940 -0
  893. package/third-party/npm/mediabunny@1.52.2/source/src/packet.ts +287 -0
  894. package/third-party/npm/mediabunny@1.52.2/source/src/pcm.ts +112 -0
  895. package/third-party/npm/mediabunny@1.52.2/source/src/reader.ts +391 -0
  896. package/third-party/npm/mediabunny@1.52.2/source/src/resample.ts +287 -0
  897. package/third-party/npm/mediabunny@1.52.2/source/src/sample.ts +3231 -0
  898. package/third-party/npm/mediabunny@1.52.2/source/src/segmented-input.ts +575 -0
  899. package/third-party/npm/mediabunny@1.52.2/source/src/source.ts +2588 -0
  900. package/third-party/npm/mediabunny@1.52.2/source/src/subtitles.ts +131 -0
  901. package/third-party/npm/mediabunny@1.52.2/source/src/target.ts +871 -0
  902. package/third-party/npm/mediabunny@1.52.2/source/src/tsconfig.json +16 -0
  903. package/third-party/npm/mediabunny@1.52.2/source/src/wave/riff-writer.ts +36 -0
  904. package/third-party/npm/mediabunny@1.52.2/source/src/wave/wave-demuxer.ts +583 -0
  905. package/third-party/npm/mediabunny@1.52.2/source/src/wave/wave-muxer.ts +375 -0
  906. package/third-party/npm/mediabunny@1.52.2/source/src/writer.ts +128 -0
  907. package/third-party/npm/react-dom@19.3.0/LICENSE +21 -0
  908. package/third-party/npm/react-dom@19.3.0/package.json +117 -0
  909. package/third-party/npm/react-remove-scroll-bar@2.3.8/package.json +85 -0
  910. package/third-party/npm/react-remove-scroll-bar@2.3.8/react-remove-scroll-bar-LICENSE +21 -0
  911. package/third-party/npm/react-remove-scroll@2.7.2/LICENSE +21 -0
  912. package/third-party/npm/react-remove-scroll@2.7.2/package.json +98 -0
  913. package/third-party/npm/react-style-singleton@2.2.3/LICENSE +21 -0
  914. package/third-party/npm/react-style-singleton@2.2.3/package.json +90 -0
  915. package/third-party/npm/react@19.3.0/LICENSE +21 -0
  916. package/third-party/npm/react@19.3.0/package.json +51 -0
  917. package/third-party/npm/scheduler@0.28.0/LICENSE +21 -0
  918. package/third-party/npm/scheduler@0.28.0/package.json +27 -0
  919. package/third-party/npm/tslib@2.8.1/LICENSE.txt +12 -0
  920. package/third-party/npm/tslib@2.8.1/package.json +47 -0
  921. package/third-party/npm/typescript@5.9.3/LICENSE.txt +55 -0
  922. package/third-party/npm/typescript@5.9.3/ThirdPartyNoticeText.txt +193 -0
  923. package/third-party/npm/typescript@5.9.3/package.json +120 -0
  924. package/third-party/npm/use-callback-ref@1.3.3/LICENSE +21 -0
  925. package/third-party/npm/use-callback-ref@1.3.3/package.json +85 -0
  926. package/third-party/npm/use-sidecar@1.1.3/LICENSE +21 -0
  927. package/third-party/npm/use-sidecar@1.1.3/package.json +93 -0
  928. package/third-party/packages/render-engine/assets/OFL.txt +93 -0
  929. package/third-party/packages/studio/public/fonts/OFL.txt +93 -0
  930. package/third-party/packages/studio/vendor/osmo-icons/LICENSE +21 -0
  931. package/third-party/packages/studio/vendor/shadcn/LICENSE +21 -0
  932. package/third-party/repository-notices.md +41 -0
  933. package/third-party/rust-standard-library/COPYRIGHT-library.html +5556 -0
  934. package/third-party/rust-standard-library/licenses/Apache-2.0.txt +73 -0
  935. package/third-party/rust-standard-library/licenses/BSD-2-Clause.txt +9 -0
  936. package/third-party/rust-standard-library/licenses/CC-BY-SA-4.0.txt +427 -0
  937. package/third-party/rust-standard-library/licenses/GCC-exception-3.1.txt +30 -0
  938. package/third-party/rust-standard-library/licenses/GPL-2.0-only.txt +133 -0
  939. package/third-party/rust-standard-library/licenses/GPL-3.0-or-later.txt +202 -0
  940. package/third-party/rust-standard-library/licenses/ISC.txt +7 -0
  941. package/third-party/rust-standard-library/licenses/LLVM-exception.txt +15 -0
  942. package/third-party/rust-standard-library/licenses/MIT.txt +9 -0
  943. package/third-party/rust-standard-library/licenses/NCSA.txt +29 -0
  944. package/third-party/rust-standard-library/licenses/OFL-1.1.txt +43 -0
  945. package/third-party/rust-standard-library/licenses/Unicode-3.0.txt +39 -0
  946. package/third-party/rust-standard-library/version.txt +1 -0
  947. package/vendor/osmo-lite +0 -0
  948. package/vendor/osmo-scene-0.1.0.tgz +0 -0
  949. package/vendor/platform.json +1 -0
@@ -0,0 +1,1529 @@
1
+ /*!
2
+ * Copyright (c) 2026-present, Vanilagy and contributors
3
+ *
4
+ * This Source Code Form is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
+ */
8
+
9
+ import { MediaCodec, validateAudioChunkMetadata, validateVideoChunkMetadata } from '../codec';
10
+ import { Logging } from '../logging';
11
+ import { EncodedAudioPacketSource, EncodedVideoPacketSource } from '../media-source';
12
+ import {
13
+ arrayArgmax,
14
+ assert,
15
+ AsyncMutex,
16
+ findLastIndex,
17
+ joinPaths,
18
+ textEncoder,
19
+ toArray,
20
+ UNDETERMINED_LANGUAGE,
21
+ } from '../misc';
22
+ import { Muxer } from '../muxer';
23
+ import {
24
+ Output,
25
+ OutputAudioTrack,
26
+ OutputSubtitleTrack,
27
+ OutputTrack,
28
+ OutputVideoTrack,
29
+ TrackType,
30
+ } from '../output';
31
+ import {
32
+ HlsOutputFormat,
33
+ HlsOutputFormatOptions,
34
+ HlsOutputPlaylistInfo,
35
+ HlsOutputSegmentInfo,
36
+ OutputFormat,
37
+ } from '../output-format';
38
+ import { Writer } from '../writer';
39
+ import { EncodedPacket } from '../packet';
40
+ import { SubtitleCue, SubtitleMetadata } from '../subtitles';
41
+ import { NullTarget, PathedTarget, Target, TargetRequest } from '../target';
42
+ import { HLS_MIME_TYPE } from './hls-misc';
43
+
44
+ type HlsTrackData = {
45
+ track: OutputTrack;
46
+ packets: EncodedPacket[];
47
+ playlist: Playlist;
48
+ // We must store it on the TrackData, reading it directly from the track leads to async race conditions!
49
+ closed: boolean;
50
+ info: {
51
+ type: 'video';
52
+ decoderConfig: VideoDecoderConfig;
53
+ } | {
54
+ type: 'audio';
55
+ decoderConfig: AudioDecoderConfig;
56
+ };
57
+ };
58
+ type HlsVideoTrackData = HlsTrackData & { info: { type: 'video' } };
59
+ type HlsAudioTrackData = HlsTrackData & { info: { type: 'audio' } };
60
+
61
+ type PlaylistSegment = {
62
+ path: string;
63
+ duration: number;
64
+ timestamp: number;
65
+ byteSize: number;
66
+ byteOffset: number | null;
67
+ info: HlsOutputSegmentInfo | null;
68
+ };
69
+
70
+ type Playlist = {
71
+ id: number;
72
+ path: string;
73
+ tracks: OutputTrack[];
74
+ segmentFormat: OutputFormat;
75
+
76
+ currentSegmentStartTimestamp: number | null;
77
+ currentSegmentStartTimestampIsFixed: boolean;
78
+ nextSegmentId: number;
79
+ initSegment: PlaylistSegment | null;
80
+ writtenSegments: PlaylistSegment[];
81
+ peakBitrate: number | null;
82
+ averageBitrate: number | null;
83
+ mediaSequence: number;
84
+ done: boolean;
85
+
86
+ singleFile: {
87
+ target: Target;
88
+ path: string;
89
+ nextOffset: number;
90
+ info: HlsOutputSegmentInfo;
91
+ } | null;
92
+
93
+ // For HLS, having a single mutex is too coarse. Every playlist is basically independent and therefore we can have
94
+ // a per-playlist mutex instead of a per-muxer one. This means two packets from different playlists coming in don't
95
+ // block each other.
96
+ mutex: AsyncMutex;
97
+ };
98
+
99
+ type PlaylistDeclaration = {
100
+ playlist: Playlist;
101
+ groupId: string | null;
102
+ noUri: boolean;
103
+ references: PlaylistDeclaration[];
104
+ };
105
+
106
+ export class HlsMuxer extends Muxer {
107
+ format: HlsOutputFormat;
108
+ getPlaylistPath: NonNullable<HlsOutputFormatOptions['getPlaylistPath']>;
109
+ getSegmentPath: NonNullable<HlsOutputFormatOptions['getSegmentPath']>;
110
+ getInitPath: NonNullable<HlsOutputFormatOptions['getInitPath']>;
111
+
112
+ targetSegmentDuration: number;
113
+ trackDatas: HlsTrackData[] = [];
114
+ singleFilePerPlaylist: boolean;
115
+ isLive: boolean;
116
+ maxLiveSegmentCount: number;
117
+ isRelativeToUnixEpoch = false;
118
+ globalTargetDuration: number;
119
+ numWrittenMasterPlaylists = 0;
120
+
121
+ playlists: Playlist[] = [];
122
+ playlistDeclarations: PlaylistDeclaration[] = [];
123
+
124
+ constructor(output: Output, format: HlsOutputFormat) {
125
+ if (!(output._target instanceof PathedTarget)) {
126
+ throw new TypeError('HLS outputs require `OutputOptions.target` to be a PathedTarget.');
127
+ }
128
+
129
+ super(output);
130
+
131
+ this.format = format;
132
+ this.targetSegmentDuration = format._options.targetDuration ?? 2;
133
+ this.singleFilePerPlaylist = format._options.singleFilePerPlaylist ?? false;
134
+ this.isLive = format._options.live ?? false;
135
+ this.maxLiveSegmentCount = format._options.maxLiveSegmentCount ?? Infinity;
136
+ this.globalTargetDuration = this.targetSegmentDuration;
137
+
138
+ this.getPlaylistPath = format._options.getPlaylistPath
139
+ ?? (({ n }) => `playlist-${n}.m3u8`);
140
+ this.getSegmentPath = format._options.getSegmentPath
141
+ ?? (info => info.isSingleFile
142
+ ? `segments-${info.playlist.n}${info.format.fileExtension}`
143
+ : `segment-${info.playlist.n}-${info.n}${info.format.fileExtension}`);
144
+ this.getInitPath = format._options.getInitPath
145
+ ?? (playlist => `init-${playlist.n}${playlist.segmentFormat.fileExtension}`);
146
+ }
147
+
148
+ async start(): Promise<void> {
149
+ const release = await this.mutex.acquire();
150
+
151
+ const someRelative = this.output.tracks.some(t => t.metadata.isRelativeToUnixEpoch);
152
+ const someNotRelative = this.output.tracks.some(t => !t.metadata.isRelativeToUnixEpoch);
153
+ if (someRelative && someNotRelative) {
154
+ throw new Error(
155
+ 'All tracks must agree on `relativeToUnixEpoch`: some tracks are relative to the Unix epoch and some'
156
+ + ' are not.',
157
+ );
158
+ }
159
+ this.isRelativeToUnixEpoch = someRelative;
160
+
161
+ // Upon starting, we now need to assign the tracks to separate playlists. This assignment will make use of the
162
+ // track pairability information provided by the user as well as other metadata specified on the tracks. The
163
+ // resulting master playlist should preserve track pairability; meaning that all tracks that are pairable
164
+ // remain pairable, and no two tracks become pairable that are meant to be mutually exclusive.
165
+ // The algorithm determines "groups" by enumerating all pairable tracks for each track, and then materializes
166
+ // each group either as #EXT-X-MEDIA tags or top-level #EXT-X-STREAM-INF tags. The algorithm is biased towards
167
+ // video being the top-level grouping, since that's the standard practice.
168
+
169
+ const groupAssignment = new Map<OutputTrack, string[]>();
170
+ const groups: {
171
+ name: string;
172
+ key: string;
173
+ tracks: OutputTrack[];
174
+ needsEmit: boolean;
175
+ firstNoUri: boolean;
176
+ }[] = [];
177
+
178
+ let hasVideo = false;
179
+ let illegalPairingDetected = false;
180
+ let keyPacketsOnlyPairingWarned = false;
181
+
182
+ // First, let's build the "sibling" groups induced by track pairability
183
+ for (const track of this.output.tracks) {
184
+ if (track.type === 'video') {
185
+ hasVideo = true;
186
+ }
187
+
188
+ const pairableGroups = new Map<MediaCodec, OutputTrack[]>();
189
+
190
+ for (const otherTrack of this.output.tracks) {
191
+ if (track === otherTrack) {
192
+ continue;
193
+ }
194
+
195
+ if (!track.canBePairedWith(otherTrack)) {
196
+ continue;
197
+ }
198
+
199
+ if (track.type === otherTrack.type) {
200
+ if (!illegalPairingDetected) {
201
+ Logging._warn(
202
+ `Illegal pairing of two ${track.type} tracks detected, which is not possible in HLS;`
203
+ + ` treating them as unpaired.`,
204
+ );
205
+ illegalPairingDetected = true;
206
+ }
207
+
208
+ continue;
209
+ }
210
+
211
+ // Key-packets-only tracks can neither pair with nor be paired with other tracks
212
+ if (
213
+ (track.isVideoTrack() && track.metadata.hasOnlyKeyPackets)
214
+ || (otherTrack.isVideoTrack() && otherTrack.metadata.hasOnlyKeyPackets)
215
+ ) {
216
+ if (!keyPacketsOnlyPairingWarned) {
217
+ Logging._warn(
218
+ `A key-packets-only video track is pairable with another track, which is not`
219
+ + ` possible in HLS; treating them as unpaired.`,
220
+ );
221
+ keyPacketsOnlyPairingWarned = true;
222
+ }
223
+
224
+ continue;
225
+ }
226
+
227
+ let groupTracks = pairableGroups.get(otherTrack.source._codec);
228
+ if (!groupTracks) {
229
+ pairableGroups.set(otherTrack.source._codec, groupTracks = []);
230
+ }
231
+
232
+ groupTracks.push(otherTrack);
233
+ }
234
+
235
+ for (const [, pairableTracks] of pairableGroups) {
236
+ const key = pairableTracks.map(x => x.id).join('-');
237
+ const group = groups.find(x => x.key === key);
238
+ if (!group) {
239
+ groups.push({
240
+ name: pairableTracks[0]!.type + '-' + (groups.length + 1),
241
+ key,
242
+ tracks: pairableTracks,
243
+ needsEmit: false,
244
+ firstNoUri: false,
245
+ });
246
+ }
247
+
248
+ let assignedGroups = groupAssignment.get(track);
249
+ if (!assignedGroups) {
250
+ groupAssignment.set(track, assignedGroups = []);
251
+ }
252
+ assignedGroups.push(key);
253
+ }
254
+ }
255
+
256
+ const mainType: TrackType = hasVideo ? 'video' : 'audio';
257
+
258
+ const variantStreams: {
259
+ tracks: OutputTrack[];
260
+ linkedGroup: typeof groups[number] | null;
261
+ }[] = [];
262
+
263
+ const unpairedVideoTracks: OutputTrack[] = [];
264
+ const unpairedAudioTracks: OutputTrack[] = [];
265
+
266
+ // Now, create the top-level variant streams
267
+ for (const track of this.output.tracks) {
268
+ const assignedGroupKeys = groupAssignment.get(track);
269
+ if (assignedGroupKeys) {
270
+ assert(assignedGroupKeys.length > 0);
271
+
272
+ if (track.type !== mainType) {
273
+ continue;
274
+ }
275
+
276
+ for (const key of assignedGroupKeys) {
277
+ const group = groups.find(x => x.key === key);
278
+ assert(group);
279
+
280
+ if (assignedGroupKeys.length === 1 && group.tracks.length === 1) {
281
+ const otherGroupKeys = groupAssignment.get(group.tracks[0]!);
282
+ assert(otherGroupKeys !== undefined);
283
+
284
+ if (otherGroupKeys.length === 1) {
285
+ const otherGroup = groups.find(x => x.key === otherGroupKeys[0]!)!;
286
+
287
+ if (otherGroup.tracks.length === 1) {
288
+ assert(otherGroup.tracks[0] === track);
289
+
290
+ variantStreams.push({
291
+ tracks: [track, group.tracks[0]!],
292
+ linkedGroup: null,
293
+ });
294
+ continue;
295
+ }
296
+ }
297
+ }
298
+
299
+ variantStreams.push({
300
+ tracks: [track],
301
+ linkedGroup: group,
302
+ });
303
+ group.needsEmit = true;
304
+ }
305
+ } else {
306
+ if (track.type === 'video') {
307
+ unpairedVideoTracks.push(track);
308
+ } else if (track.type === 'audio') {
309
+ unpairedAudioTracks.push(track);
310
+ }
311
+ }
312
+ }
313
+
314
+ const getMetadataKeyForTrack = ({ metadata }: OutputTrack) => {
315
+ let key = '';
316
+ key += `${metadata.languageCode ?? UNDETERMINED_LANGUAGE}-`;
317
+ key += `${metadata.name ?? ''}-`;
318
+ key += `${metadata.disposition?.default ?? true}-`;
319
+ key += `${metadata.disposition?.primary ?? false}-`;
320
+ key += `${metadata.disposition?.forced ?? false}-`;
321
+
322
+ return key;
323
+ };
324
+
325
+ // Video tracks that can't be paired with any other track always live on the top-level, the question is just if
326
+ // they need to be separated into #EXT-X-MEDIA tags or not
327
+ if (unpairedVideoTracks.length > 0) {
328
+ const uniqueMetadata = new Set(unpairedVideoTracks.map(getMetadataKeyForTrack));
329
+
330
+ if (uniqueMetadata.size > 1) {
331
+ // They differ in metadata, emit as group
332
+ const group: typeof groups[number] = {
333
+ key: unpairedVideoTracks.map(x => x.id).join('-'),
334
+ name: 'video-' + (groups.length + 1),
335
+ tracks: unpairedVideoTracks,
336
+ needsEmit: true,
337
+ firstNoUri: true,
338
+ };
339
+ groups.push(group);
340
+
341
+ variantStreams.push({
342
+ tracks: [unpairedVideoTracks[0]!],
343
+ linkedGroup: group,
344
+ });
345
+ } else {
346
+ for (const track of unpairedVideoTracks) {
347
+ variantStreams.push({
348
+ tracks: [track],
349
+ linkedGroup: null,
350
+ });
351
+ }
352
+ }
353
+ }
354
+
355
+ // Audio tracks that can't be paired with any other track always live on the top-level, the question is just if
356
+ // they need to be separated into #EXT-X-MEDIA tags or not
357
+ if (unpairedAudioTracks.length > 0) {
358
+ const uniqueMetadata = new Set(unpairedAudioTracks.map(getMetadataKeyForTrack));
359
+
360
+ if (uniqueMetadata.size > 1) {
361
+ // They differ in metadata, emit as group
362
+ const group: typeof groups[number] = {
363
+ key: unpairedAudioTracks.map(x => x.id).join('-'),
364
+ name: 'audio-' + (groups.length + 1),
365
+ tracks: unpairedAudioTracks,
366
+ needsEmit: true,
367
+ firstNoUri: true,
368
+ };
369
+ groups.push(group);
370
+
371
+ variantStreams.push({
372
+ tracks: [unpairedAudioTracks[0]!],
373
+ linkedGroup: group,
374
+ });
375
+ } else {
376
+ for (const track of unpairedAudioTracks) {
377
+ variantStreams.push({
378
+ tracks: [track],
379
+ linkedGroup: null,
380
+ });
381
+ }
382
+ }
383
+ }
384
+
385
+ const deduceSegmentFormat = (tracks: OutputTrack[]) => {
386
+ const codecs: MediaCodec[] = [];
387
+ let videoCount = 0;
388
+ let audioCount = 0;
389
+ let requiresRotationMetadata = false;
390
+
391
+ let candidate: OutputFormat | null = null;
392
+ let candidateScore = -Infinity;
393
+
394
+ for (const track of tracks) {
395
+ if (track.isVideoTrack()) {
396
+ videoCount++;
397
+ requiresRotationMetadata ||= (track.metadata.rotation ?? 0) !== 0;
398
+ } else if (track.isAudioTrack()) {
399
+ audioCount++;
400
+ }
401
+
402
+ codecs.push(track.source._codec);
403
+ }
404
+
405
+ for (const format of toArray(this.format._options.segmentFormat)) {
406
+ const supportedCodecs = format.getSupportedCodecs();
407
+ const trackCounts = format.getSupportedTrackCounts();
408
+
409
+ if (codecs.some(codec => !supportedCodecs.includes(codec))) {
410
+ continue;
411
+ }
412
+
413
+ if (videoCount < trackCounts.video.min || videoCount > trackCounts.video.max) {
414
+ continue;
415
+ }
416
+
417
+ if (audioCount < trackCounts.audio.min || audioCount > trackCounts.audio.max) {
418
+ continue;
419
+ }
420
+
421
+ let score = 0;
422
+ if (requiresRotationMetadata && format.supportsVideoRotationMetadata) {
423
+ score++;
424
+ }
425
+
426
+ if (score > candidateScore) {
427
+ candidate = format;
428
+ candidateScore = score;
429
+ }
430
+ }
431
+
432
+ // We must find a format. If no format is found, that means we incorrectly gated track creation and
433
+ // assignment at an earlier step.
434
+ assert(candidate);
435
+
436
+ return candidate;
437
+ };
438
+
439
+ const registerPlaylist = async (tracks: OutputTrack[]) => {
440
+ if (tracks.some(track => this.playlists.some(playlist => playlist.tracks.includes(track)))) {
441
+ throw new Error('Internal error: track is already registered in a playlist.'); // Should be unreachable
442
+ }
443
+
444
+ const format = deduceSegmentFormat(tracks);
445
+
446
+ const id = this.playlists.length + 1;
447
+ const path = await this.getPlaylistPath({
448
+ n: id,
449
+ tracks,
450
+ segmentFormat: format,
451
+ });
452
+ validatePlaylistPath(path);
453
+
454
+ const playlist: Playlist = {
455
+ id: this.playlists.length + 1,
456
+ path,
457
+ tracks,
458
+ segmentFormat: format,
459
+ currentSegmentStartTimestamp: null,
460
+ currentSegmentStartTimestampIsFixed: false,
461
+ nextSegmentId: 1,
462
+ initSegment: null,
463
+ writtenSegments: [],
464
+ peakBitrate: null,
465
+ averageBitrate: null,
466
+ mediaSequence: 0,
467
+ done: false,
468
+ singleFile: null,
469
+ mutex: new AsyncMutex(),
470
+ };
471
+ this.playlists.push(playlist);
472
+
473
+ return playlist;
474
+ };
475
+
476
+ // Now, finally let's create all declarations. Each declaration maps to one #EXT-X-MEDIA or #EXT-X-STREAM-INF
477
+ // tag in the final master playlist.
478
+ for (const group of groups) {
479
+ if (!group.needsEmit) {
480
+ continue;
481
+ }
482
+
483
+ for (let i = 0; i < group.tracks.length; i++) {
484
+ const track = group.tracks[i]!;
485
+
486
+ let playlist = this.playlists.find(x => x.tracks[0]!.id === track.id);
487
+ playlist ??= await registerPlaylist([track]);
488
+
489
+ this.playlistDeclarations.push({
490
+ playlist,
491
+ groupId: group.name,
492
+ noUri: group.firstNoUri && i === 0,
493
+ references: [],
494
+ });
495
+ }
496
+ }
497
+
498
+ for (const variant of variantStreams) {
499
+ // Since tracks can only be assigned to one playlist, the first track's ID acts as a "playlist key"
500
+ let playlist = this.playlists.find(x => x.tracks[0]!.id === variant.tracks[0]!.id);
501
+ playlist ??= await registerPlaylist(variant.tracks);
502
+
503
+ this.playlistDeclarations.push({
504
+ playlist,
505
+ groupId: null,
506
+ noUri: false,
507
+ references: variant.linkedGroup
508
+ ? this.playlistDeclarations.filter(x => x.groupId === variant.linkedGroup!.name)
509
+ : [],
510
+ });
511
+ }
512
+
513
+ release();
514
+ }
515
+
516
+ async getMimeType(): Promise<string> {
517
+ return HLS_MIME_TYPE;
518
+ }
519
+
520
+ private allTracksAreKnown(playlist: Playlist) {
521
+ for (const track of playlist.tracks) {
522
+ if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) {
523
+ return false; // We haven't seen a sample from this open track yet
524
+ }
525
+ }
526
+
527
+ return true;
528
+ }
529
+
530
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
531
+ override async onTrackClose(track: OutputTrack) {
532
+ const trackData = this.trackDatas.find(x => x.track === track);
533
+ if (trackData) {
534
+ trackData.closed = true;
535
+ }
536
+
537
+ const playlist = this.playlists.find(x => x.tracks.includes(track));
538
+ assert(playlist); // If there isn't one then the assignment algo failed innit
539
+
540
+ const release = await playlist.mutex.acquire();
541
+
542
+ try {
543
+ await this.advancePlaylist(playlist);
544
+ } finally {
545
+ release();
546
+ }
547
+ }
548
+
549
+ getVideoTrackData(track: OutputVideoTrack, meta?: EncodedVideoChunkMetadata) {
550
+ let trackData = this.trackDatas.find(x => x.track === track) as HlsVideoTrackData;
551
+ if (trackData) {
552
+ return trackData;
553
+ }
554
+
555
+ validateVideoChunkMetadata(meta);
556
+
557
+ assert(meta);
558
+ assert(meta?.decoderConfig);
559
+
560
+ const playlists = this.playlists.filter(x => x.tracks.includes(track));
561
+ assert(playlists.length === 1);
562
+
563
+ trackData = {
564
+ track,
565
+ packets: [],
566
+ playlist: playlists[0]!,
567
+ closed: false,
568
+ info: {
569
+ type: 'video',
570
+ decoderConfig: meta.decoderConfig,
571
+ },
572
+ };
573
+ this.trackDatas.push(trackData);
574
+
575
+ return trackData;
576
+ }
577
+
578
+ getAudioTrackData(track: OutputAudioTrack, meta?: EncodedAudioChunkMetadata) {
579
+ let trackData = this.trackDatas.find(x => x.track === track) as HlsAudioTrackData;
580
+ if (trackData) {
581
+ return trackData;
582
+ }
583
+
584
+ validateAudioChunkMetadata(meta);
585
+
586
+ assert(meta);
587
+ assert(meta?.decoderConfig);
588
+
589
+ const playlists = this.playlists.filter(x => x.tracks.includes(track));
590
+ assert(playlists.length === 1);
591
+
592
+ trackData = {
593
+ track,
594
+ packets: [],
595
+ playlist: playlists[0]!,
596
+ closed: false,
597
+ info: {
598
+ type: 'audio',
599
+ decoderConfig: meta.decoderConfig,
600
+ },
601
+ };
602
+ this.trackDatas.push(trackData);
603
+
604
+ return trackData;
605
+ }
606
+
607
+ async addEncodedVideoPacket(
608
+ track: OutputVideoTrack,
609
+ packet: EncodedPacket,
610
+ meta?: EncodedVideoChunkMetadata,
611
+ ) {
612
+ const trackData = this.getVideoTrackData(track, meta);
613
+ const playlist = trackData.playlist;
614
+
615
+ const release = await playlist.mutex.acquire();
616
+
617
+ try {
618
+ this.validateTimestamp(track, packet.timestamp, packet.type === 'key');
619
+ trackData.packets.push(packet);
620
+
621
+ if (playlist.currentSegmentStartTimestamp === null) {
622
+ playlist.currentSegmentStartTimestamp = packet.timestamp;
623
+ } else if (!playlist.currentSegmentStartTimestampIsFixed) {
624
+ playlist.currentSegmentStartTimestamp = Math.min(
625
+ playlist.currentSegmentStartTimestamp,
626
+ packet.timestamp,
627
+ );
628
+ }
629
+
630
+ await this.advancePlaylist(playlist);
631
+ } finally {
632
+ release();
633
+ }
634
+ }
635
+
636
+ async addEncodedAudioPacket(
637
+ track: OutputAudioTrack,
638
+ packet: EncodedPacket,
639
+ meta?: EncodedAudioChunkMetadata,
640
+ ) {
641
+ const trackData = this.getAudioTrackData(track, meta);
642
+ const playlist = trackData.playlist;
643
+
644
+ const release = await playlist.mutex.acquire();
645
+
646
+ try {
647
+ this.validateTimestamp(track, packet.timestamp, packet.type === 'key');
648
+ trackData.packets.push(packet);
649
+
650
+ if (playlist.currentSegmentStartTimestamp === null) {
651
+ playlist.currentSegmentStartTimestamp = packet.timestamp;
652
+ } else if (!playlist.currentSegmentStartTimestampIsFixed) {
653
+ playlist.currentSegmentStartTimestamp = Math.min(
654
+ playlist.currentSegmentStartTimestamp,
655
+ packet.timestamp,
656
+ );
657
+ }
658
+
659
+ await this.advancePlaylist(playlist);
660
+ } finally {
661
+ release();
662
+ }
663
+ }
664
+
665
+ async addSubtitleCue(
666
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
667
+ track: OutputSubtitleTrack,
668
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
669
+ cue: SubtitleCue,
670
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
671
+ meta?: SubtitleMetadata,
672
+ ) {
673
+ throw new Error('Unreachable.');
674
+ }
675
+
676
+ async advancePlaylist(playlist: Playlist) {
677
+ assert(!playlist.done);
678
+
679
+ if (!this.allTracksAreKnown(playlist)) {
680
+ return;
681
+ }
682
+
683
+ if (playlist.currentSegmentStartTimestamp === null) {
684
+ // All tracks are known but we never received any data - all tracks must be closed already
685
+ await this.onPlaylistDone(playlist);
686
+
687
+ return;
688
+ }
689
+
690
+ const trackDatas = this.trackDatas.filter(x => playlist.tracks.includes(x.track));
691
+ const videoTrack = trackDatas.find(x => x.info.type === 'video') as HlsVideoTrackData | undefined;
692
+ const audioTrack = trackDatas.find(x => x.info.type === 'audio') as HlsAudioTrackData | undefined;
693
+
694
+ // Loop in case we can finalize multiple segments
695
+ while (true) {
696
+ // This here is the core segmentation logic. The segmentation logic figures out which packets are to be
697
+ // written into the next segment, and if we can write a segment at all. If tracks are still open and have
698
+ // not provided sufficient media data, no segment will be written. The packets will be added to the segment
699
+ // to maximize its duration AND keep it from exceeding the target duration. This condition is extended with
700
+ // a key frame rule for video, meaning the algorithm must guarantee that every segment with video data
701
+ // begins with a video key frame.
702
+ //
703
+ // The logic is quite complex but is solved in a straight-forward way: all possible permutations of the
704
+ // problem are checked in a nested if-else structure, making sure all cases behave correctly. This was the
705
+ // easiest, least error-prone way I found to express this behavior.
706
+
707
+ const currentSegmentEndTimestamp = playlist.currentSegmentStartTimestamp + this.targetSegmentDuration;
708
+
709
+ // These store the index (exclusive) until when packets can be added to the next segment
710
+ let videoEndIndex = 0;
711
+ let audioEndIndex = 0;
712
+
713
+ if (videoTrack && (!videoTrack.closed || videoTrack.packets.length > 0)) {
714
+ // A video track is active (and maybe an audio track too)
715
+ const allBelow = videoTrack.packets.every(x => x.timestamp < currentSegmentEndTimestamp);
716
+
717
+ let bestKeyPacket: EncodedPacket | null = null;
718
+ let bestKeyPacketIndex: number | null = null;
719
+
720
+ if (allBelow) {
721
+ if (!videoTrack.closed) {
722
+ // Not enough data yet
723
+ return;
724
+ }
725
+ } else {
726
+ // Find the best key packet timestamp
727
+ for (let i = 0; i < videoTrack.packets.length; i++) {
728
+ const packet = videoTrack.packets[i]!;
729
+
730
+ if (bestKeyPacket !== null && packet.timestamp > currentSegmentEndTimestamp) {
731
+ break;
732
+ }
733
+
734
+ if (i > 0 && packet.type === 'key') {
735
+ bestKeyPacket = packet;
736
+ bestKeyPacketIndex = i;
737
+ }
738
+ }
739
+ }
740
+
741
+ if (bestKeyPacketIndex !== null) {
742
+ videoEndIndex = bestKeyPacketIndex;
743
+
744
+ if (audioTrack) {
745
+ // The audio track must go at least until the video key frame
746
+ const index = audioTrack.packets.findIndex(x => x.timestamp >= bestKeyPacket!.timestamp);
747
+ if (index !== -1) {
748
+ audioEndIndex = index;
749
+ } else {
750
+ if (audioTrack.closed) {
751
+ audioEndIndex = audioTrack.packets.length;
752
+ } else {
753
+ return;
754
+ }
755
+ }
756
+ }
757
+ } else {
758
+ if (!videoTrack.closed) {
759
+ return;
760
+ }
761
+
762
+ // Include the entire rest of the video (since there's no key frame to split it on)
763
+ videoEndIndex = videoTrack.packets.length;
764
+ const maxIndex = arrayArgmax(videoTrack.packets, x => x.timestamp);
765
+ const maxPacket = videoTrack.packets[maxIndex];
766
+ assert(maxPacket);
767
+
768
+ if (audioTrack) {
769
+ if (maxPacket.timestamp < currentSegmentEndTimestamp) {
770
+ // The audio must go until at least the start of the next segment
771
+ const index = audioTrack.packets.findIndex(x => x.timestamp >= currentSegmentEndTimestamp);
772
+ if (index !== -1) {
773
+ audioEndIndex = index;
774
+ } else {
775
+ if (audioTrack.closed) {
776
+ audioEndIndex = audioTrack.packets.length;
777
+ } else {
778
+ return;
779
+ }
780
+ }
781
+ } else {
782
+ // The audio must go beyond the last video packet
783
+ const index = audioTrack.packets.findIndex(x => x.timestamp > maxPacket.timestamp);
784
+ if (index !== -1) {
785
+ audioEndIndex = index;
786
+ } else {
787
+ if (audioTrack.closed) {
788
+ audioEndIndex = audioTrack.packets.length;
789
+ } else {
790
+ return;
791
+ }
792
+ }
793
+ }
794
+ }
795
+ }
796
+ } else if (audioTrack && (!audioTrack.closed || audioTrack.packets.length > 0)) {
797
+ // There's only an audio track active
798
+
799
+ const allBelow = audioTrack.packets.every(x => x.timestamp < currentSegmentEndTimestamp);
800
+
801
+ if (allBelow) {
802
+ if (audioTrack.closed) {
803
+ // We can write all packets since they're all below
804
+ audioEndIndex = audioTrack.packets.length;
805
+ } else {
806
+ // We don't know enough packets yet
807
+ return;
808
+ }
809
+ } else {
810
+ // Aim to make the segment at most as long as desired
811
+ const index = findLastIndex(audioTrack.packets, x => x.timestamp <= currentSegmentEndTimestamp);
812
+ audioEndIndex = Math.max(index, 1); // Always include at least the first packet
813
+ }
814
+ }
815
+
816
+ if (videoEndIndex === 0 && audioEndIndex === 0) {
817
+ // No more segments to write - if all tracks are closed, this playlist is done
818
+ const allClosed = trackDatas.every(x => x.closed);
819
+ if (allClosed) {
820
+ await this.onPlaylistDone(playlist);
821
+ }
822
+
823
+ return;
824
+ }
825
+
826
+ // We can finalize a new segment!
827
+
828
+ let segmentInfo: HlsOutputSegmentInfo | null = null;
829
+ let relativeSegmentPath: string;
830
+ let fullSegmentPath: string;
831
+
832
+ assert(this.output._target instanceof PathedTarget);
833
+ const pathedTarget = this.output._target;
834
+
835
+ if (this.singleFilePerPlaylist) {
836
+ if (playlist.singleFile === null) {
837
+ // INTENTIONALLY shadow the outside `segmentInfo` because we don't want to set it.
838
+ // In single-file mode, onSegment is called once in onPlaylistDone instead of per-segment,
839
+ // so the outer `segmentInfo` intentionally stays null in this case.
840
+ const segmentInfo: HlsOutputSegmentInfo = {
841
+ n: playlist.nextSegmentId,
842
+ format: playlist.segmentFormat,
843
+ isSingleFile: true,
844
+ playlist: toPlaylistInfo(playlist),
845
+ };
846
+
847
+ relativeSegmentPath = await this.getSegmentPath(segmentInfo);
848
+ validateSegmentPath(relativeSegmentPath);
849
+
850
+ fullSegmentPath = joinPaths(
851
+ joinPaths(pathedTarget.rootPath, playlist.path),
852
+ relativeSegmentPath,
853
+ );
854
+
855
+ const target = await this.output._getTarget({
856
+ path: fullSegmentPath,
857
+ isRoot: false,
858
+ mimeType: playlist.segmentFormat.mimeType,
859
+ });
860
+ target._start();
861
+
862
+ playlist.singleFile = {
863
+ target,
864
+ path: relativeSegmentPath,
865
+ nextOffset: 0,
866
+ info: segmentInfo,
867
+ };
868
+ } else {
869
+ relativeSegmentPath = playlist.singleFile.path;
870
+ fullSegmentPath = joinPaths(
871
+ joinPaths(pathedTarget.rootPath, playlist.path),
872
+ relativeSegmentPath,
873
+ );
874
+ }
875
+ } else {
876
+ segmentInfo = {
877
+ n: playlist.nextSegmentId,
878
+ format: playlist.segmentFormat,
879
+ isSingleFile: false,
880
+ playlist: toPlaylistInfo(playlist),
881
+ };
882
+
883
+ relativeSegmentPath = await this.getSegmentPath(segmentInfo);
884
+ validateSegmentPath(relativeSegmentPath);
885
+
886
+ fullSegmentPath = joinPaths(joinPaths(pathedTarget.rootPath, playlist.path), relativeSegmentPath);
887
+ playlist.nextSegmentId++;
888
+ }
889
+
890
+ let segmentSize = 0;
891
+ let outputTarget: Target | null = null;
892
+
893
+ const output = new Output({
894
+ format: playlist.segmentFormat,
895
+ target: new PathedTarget(
896
+ fullSegmentPath,
897
+ async (request: TargetRequest) => {
898
+ const proxiedRequest: TargetRequest = {
899
+ ...request,
900
+ isRoot: false,
901
+ };
902
+
903
+ if (request.isRoot) {
904
+ if (playlist.singleFile) {
905
+ const slice = playlist.singleFile.target.slice(playlist.singleFile.nextOffset);
906
+ slice.on('write', ({ end }) => segmentSize = Math.max(segmentSize, end));
907
+
908
+ return slice;
909
+ } else {
910
+ const target = await this.output._getTarget(proxiedRequest);
911
+ outputTarget = target;
912
+ target.on('write', ({ end }) => segmentSize = Math.max(segmentSize, end));
913
+
914
+ return target;
915
+ }
916
+ }
917
+
918
+ return this.output._getTarget(proxiedRequest);
919
+ },
920
+ ),
921
+ initTarget: async () => {
922
+ if (playlist.initSegment) {
923
+ // We already have an init segment from a previous segment
924
+ return new NullTarget();
925
+ }
926
+
927
+ if (playlist.singleFile) {
928
+ playlist.initSegment = {
929
+ path: playlist.singleFile.path,
930
+ duration: 0,
931
+ timestamp: 0,
932
+ byteSize: 0,
933
+ byteOffset: 0,
934
+ info: null,
935
+ };
936
+
937
+ const slice = playlist.singleFile.target.slice(playlist.singleFile.nextOffset);
938
+ slice.on('write', ({ end }) => {
939
+ playlist.initSegment!.byteSize = Math.max(playlist.initSegment!.byteSize, end);
940
+ });
941
+ slice.on('finalized', () => {
942
+ playlist.singleFile!.nextOffset = playlist.initSegment!.byteSize;
943
+ });
944
+
945
+ return slice;
946
+ } else {
947
+ const playlistInfo = toPlaylistInfo(playlist);
948
+ const initPath = await this.getInitPath(playlistInfo);
949
+ validateInitPath(initPath);
950
+
951
+ playlist.initSegment = {
952
+ path: initPath,
953
+ duration: 0,
954
+ timestamp: 0,
955
+ byteSize: 0,
956
+ byteOffset: null,
957
+ info: null,
958
+ };
959
+
960
+ const fullInitPath = joinPaths(
961
+ joinPaths(pathedTarget.rootPath, playlist.path),
962
+ initPath,
963
+ );
964
+ const target = await this.output._getTarget({
965
+ path: fullInitPath,
966
+ isRoot: false,
967
+ mimeType: playlist.segmentFormat.mimeType,
968
+ });
969
+ target.on('write', ({ end }) => {
970
+ playlist.initSegment!.byteSize = Math.max(playlist.initSegment!.byteSize, end);
971
+ });
972
+ target.on('finalized', () => {
973
+ this.format._options.onInit?.(target, playlistInfo);
974
+ });
975
+
976
+ return target;
977
+ }
978
+ },
979
+ });
980
+
981
+ let maxEndTimestamp = -Infinity;
982
+
983
+ try {
984
+ let videoSource: EncodedVideoPacketSource | null = null;
985
+ let audioSource: EncodedAudioPacketSource | null = null;
986
+
987
+ if (videoTrack) {
988
+ // Always add the track, no matter if it has packets or not (maintains underlying IDs)
989
+ videoSource = new EncodedVideoPacketSource((videoTrack.track as OutputVideoTrack).source._codec);
990
+ output.addVideoTrack(videoSource, videoTrack.track.metadata);
991
+ }
992
+
993
+ if (audioTrack) {
994
+ // Always add the track, no matter if it has packets or not (maintains underlying IDs)
995
+ audioSource = new EncodedAudioPacketSource((audioTrack.track as OutputAudioTrack).source._codec);
996
+ output.addAudioTrack(audioSource, audioTrack.track.metadata);
997
+ }
998
+
999
+ await output.start();
1000
+
1001
+ // Add all of the packets
1002
+
1003
+ if (videoTrack) {
1004
+ assert(videoSource);
1005
+ const meta = { decoderConfig: videoTrack.info.decoderConfig };
1006
+
1007
+ for (let i = 0; i < videoEndIndex; i++) {
1008
+ const packet = videoTrack.packets[i]!;
1009
+
1010
+ await videoSource.add(packet, meta);
1011
+ maxEndTimestamp = Math.max(maxEndTimestamp, packet.timestamp + packet.duration);
1012
+ }
1013
+ }
1014
+
1015
+ if (audioTrack) {
1016
+ assert(audioSource);
1017
+ const meta = { decoderConfig: audioTrack.info.decoderConfig };
1018
+
1019
+ for (let i = 0; i < audioEndIndex; i++) {
1020
+ const packet = audioTrack.packets[i]!;
1021
+
1022
+ await audioSource.add(packet, meta);
1023
+ maxEndTimestamp = Math.max(maxEndTimestamp, packet.timestamp + packet.duration);
1024
+ }
1025
+ }
1026
+
1027
+ await output.finalize();
1028
+ } catch (e) {
1029
+ await output.cancel();
1030
+ throw e;
1031
+ }
1032
+
1033
+ if (segmentInfo) {
1034
+ assert(outputTarget);
1035
+ this.format._options.onSegment?.(outputTarget, segmentInfo);
1036
+ }
1037
+
1038
+ if (videoEndIndex > 0) {
1039
+ assert(videoTrack);
1040
+ videoTrack.packets.splice(0, videoEndIndex);
1041
+ }
1042
+ if (audioEndIndex > 0) {
1043
+ assert(audioTrack);
1044
+ audioTrack.packets.splice(0, audioEndIndex);
1045
+ }
1046
+
1047
+ let minNextTimestamp = Infinity;
1048
+ if (videoTrack && videoTrack.packets.length > 0) {
1049
+ minNextTimestamp = videoTrack.packets[0]!.timestamp;
1050
+ }
1051
+ if (audioTrack && audioTrack.packets.length > 0) {
1052
+ minNextTimestamp = Math.min(minNextTimestamp, audioTrack.packets[0]!.timestamp);
1053
+ }
1054
+
1055
+ const nextSegmentStartTimestamp = minNextTimestamp < Infinity
1056
+ ? minNextTimestamp
1057
+ : maxEndTimestamp; // Happens for the last segment for example
1058
+ assert(Number.isFinite(nextSegmentStartTimestamp));
1059
+
1060
+ const segmentDuration = nextSegmentStartTimestamp - playlist.currentSegmentStartTimestamp;
1061
+ assert(segmentDuration >= 0);
1062
+
1063
+ playlist.writtenSegments.push({
1064
+ path: relativeSegmentPath,
1065
+ duration: segmentDuration,
1066
+ timestamp: playlist.currentSegmentStartTimestamp,
1067
+ byteSize: segmentSize,
1068
+ byteOffset: playlist.singleFile
1069
+ ? playlist.singleFile.nextOffset
1070
+ : null,
1071
+ info: segmentInfo ?? null,
1072
+ });
1073
+
1074
+ this.globalTargetDuration = Math.max(this.globalTargetDuration, segmentDuration);
1075
+
1076
+ playlist.currentSegmentStartTimestamp = nextSegmentStartTimestamp;
1077
+ playlist.currentSegmentStartTimestampIsFixed = true; // After the first segment, the timestamp is now fixed
1078
+
1079
+ if (playlist.singleFile) {
1080
+ playlist.singleFile.nextOffset += segmentSize;
1081
+ }
1082
+
1083
+ if (this.isLive) {
1084
+ while (playlist.writtenSegments.length > this.maxLiveSegmentCount) {
1085
+ const popped = playlist.writtenSegments.shift()!;
1086
+ playlist.mediaSequence++;
1087
+
1088
+ if (!this.singleFilePerPlaylist) {
1089
+ assert(popped.info);
1090
+ this.format._options.onSegmentPopped?.(popped.path, popped.info);
1091
+ }
1092
+ }
1093
+
1094
+ await this.writePlaylist(playlist);
1095
+ await this.tryWriteMasterPlaylist();
1096
+ }
1097
+ }
1098
+ }
1099
+
1100
+ private async onPlaylistDone(playlist: Playlist) {
1101
+ assert(!playlist.done);
1102
+ playlist.done = true;
1103
+
1104
+ if (playlist.singleFile) {
1105
+ await playlist.singleFile.target._flush();
1106
+ await playlist.singleFile.target._finalize();
1107
+
1108
+ this.format._options.onSegment?.(playlist.singleFile.target, playlist.singleFile.info);
1109
+ }
1110
+
1111
+ await this.writePlaylist(playlist);
1112
+
1113
+ if (this.isLive && playlist.writtenSegments.length === 0) {
1114
+ await this.tryWriteMasterPlaylist();
1115
+ }
1116
+ }
1117
+
1118
+ private updatePlaylistBitrates(playlist: Playlist) {
1119
+ const segments = playlist.writtenSegments;
1120
+
1121
+ let peakBitrate = 0;
1122
+ let totalBits = 0;
1123
+ let totalDuration = 0;
1124
+
1125
+ // Per spec, peak bitrate is the largest bit rate of any contiguous set of segments whose total duration is
1126
+ // between 0.5 and 1.5 times the target duration
1127
+ for (let i = 0; i < segments.length; i++) {
1128
+ totalDuration += segments[i]!.duration;
1129
+
1130
+ let windowBytes = 0;
1131
+ let windowDuration = 0;
1132
+
1133
+ for (let j = i; j < segments.length; j++) {
1134
+ windowBytes += segments[j]!.byteSize;
1135
+ windowDuration += segments[j]!.duration;
1136
+
1137
+ if (
1138
+ windowDuration >= 0.5 * this.globalTargetDuration
1139
+ && windowDuration <= 1.5 * this.globalTargetDuration
1140
+ ) {
1141
+ peakBitrate = Math.max(peakBitrate, 8 * windowBytes / windowDuration);
1142
+ }
1143
+
1144
+ if (windowDuration > 1.5 * this.globalTargetDuration) {
1145
+ break;
1146
+ }
1147
+ }
1148
+ }
1149
+
1150
+ // Fallback: if no contiguous set falls within the range, use per-segment max
1151
+ if (peakBitrate === 0) {
1152
+ for (const segment of segments) {
1153
+ const segmentDuration = segment.duration || 1; // To catch 0-duration segments which can happen
1154
+ peakBitrate = Math.max(peakBitrate, 8 * segment.byteSize / segmentDuration);
1155
+ }
1156
+ }
1157
+
1158
+ for (const segment of segments) {
1159
+ totalBits += 8 * segment.byteSize;
1160
+ }
1161
+
1162
+ playlist.peakBitrate = peakBitrate;
1163
+ playlist.averageBitrate = totalBits / (totalDuration || 1);
1164
+ }
1165
+
1166
+ private async writePlaylist(playlist: Playlist) {
1167
+ assert(this.output._target instanceof PathedTarget);
1168
+ const pathedTarget = this.output._target;
1169
+
1170
+ this.updatePlaylistBitrates(playlist);
1171
+
1172
+ let hasByteOffsets = false;
1173
+ for (const segment of playlist.writtenSegments) {
1174
+ hasByteOffsets ||= segment.byteOffset !== null;
1175
+ }
1176
+
1177
+ const isKeyPacketsOnly = playlist.tracks[0]!.isVideoTrack()
1178
+ && playlist.tracks[0].metadata.hasOnlyKeyPackets;
1179
+
1180
+ let version = 3;
1181
+ if (isKeyPacketsOnly || hasByteOffsets) {
1182
+ version = 4;
1183
+ }
1184
+ if (playlist.initSegment) {
1185
+ version = 5;
1186
+ }
1187
+ if (playlist.initSegment && !isKeyPacketsOnly) {
1188
+ // "if it contains the EXT-X-MAP tag in a Media Playlist that does not contain EXT-X-I-FRAMES-ONLY"
1189
+ version = 6;
1190
+ }
1191
+
1192
+ // In live mode, target duration is not allowed to change, so we use the nominal value
1193
+ const targetDuration = this.isLive ? this.targetSegmentDuration : this.globalTargetDuration;
1194
+
1195
+ const playlistPath = joinPaths(pathedTarget.rootPath, playlist.path);
1196
+ const playlistText = '#EXTM3U\n'
1197
+ + `#EXT-X-VERSION:${version}\n`
1198
+ + (!this.isLive ? '#EXT-X-PLAYLIST-TYPE:VOD\n' : '')
1199
+ + `#EXT-X-TARGETDURATION:${Math.ceil(targetDuration)}\n` // Must be a "decimal-integer"
1200
+ + (Number.isFinite(this.maxLiveSegmentCount) ? `#EXT-X-MEDIA-SEQUENCE:${playlist.mediaSequence}\n` : '')
1201
+ + '#EXT-X-INDEPENDENT-SEGMENTS\n'
1202
+ + (isKeyPacketsOnly ? '#EXT-X-I-FRAMES-ONLY\n' : '')
1203
+ + (playlist.initSegment
1204
+ ? (`#EXT-X-MAP:URI="${playlist.initSegment.path}"`
1205
+ + (playlist.initSegment.byteOffset !== null
1206
+ ? `,BYTERANGE="${playlist.initSegment.byteSize}@${playlist.initSegment.byteOffset}"`
1207
+ : '')
1208
+ + '\n')
1209
+ : '')
1210
+ + '\n'
1211
+ + (playlist.writtenSegments
1212
+ .map(segment => (
1213
+ `#EXTINF:${+segment.duration.toFixed(12)},\n` // Trailing comma mandated by spec
1214
+ + (this.isRelativeToUnixEpoch
1215
+ ? `#EXT-X-PROGRAM-DATE-TIME:${new Date(1000 * segment.timestamp).toISOString()}\n`
1216
+ : '')
1217
+ + (segment.byteOffset !== null
1218
+ ? `#EXT-X-BYTERANGE:${segment.byteSize}@${segment.byteOffset}\n`
1219
+ : '')
1220
+ + `${segment.path}\n`
1221
+ ))
1222
+ .join(''))
1223
+ + (playlist.done
1224
+ ? (playlist.writtenSegments.length > 0 ? '\n' : '') + '#EXT-X-ENDLIST\n'
1225
+ : '');
1226
+
1227
+ this.format._options.onPlaylist?.(playlistText, toPlaylistInfo(playlist));
1228
+
1229
+ const target = await this.output._getTarget({
1230
+ path: playlistPath,
1231
+ isRoot: false,
1232
+ mimeType: HLS_MIME_TYPE,
1233
+ });
1234
+ const writer = new Writer(target, true);
1235
+ writer.start();
1236
+ writer.write(textEncoder.encode(playlistText));
1237
+
1238
+ await writer.flush();
1239
+ await writer.finalize();
1240
+ }
1241
+
1242
+ private async writeMasterPlaylist() {
1243
+ assert(this.output._target instanceof PathedTarget);
1244
+ const pathedTarget = this.output._target;
1245
+
1246
+ let masterPlaylistText = '#EXTM3U\n';
1247
+ let firstVariantWritten = false;
1248
+
1249
+ let lastGroupId: string | null = null;
1250
+ let groupIdTrackCount = 0;
1251
+ let hasHadDefaultTrackInGroup = false;
1252
+
1253
+ for (const decl of this.playlistDeclarations) {
1254
+ if (decl.groupId === null) {
1255
+ const isKeyPacketsOnly = decl.playlist.tracks[0]!.isVideoTrack()
1256
+ && decl.playlist.tracks[0].metadata.hasOnlyKeyPackets;
1257
+
1258
+ const codecs: string[] = [];
1259
+ for (const track of decl.playlist.tracks) {
1260
+ const trackData = this.trackDatas.find(x => x.track === track);
1261
+ const codecString = trackData?.info.decoderConfig.codec ?? track.source._codec;
1262
+ codecs.push(codecString);
1263
+ }
1264
+
1265
+ let peakDeclBitrate = 0;
1266
+ let maxRefAverageBitrate = 0;
1267
+
1268
+ if (decl.references.length > 0) {
1269
+ const firstRef = decl.references[0]!;
1270
+ const firstTrack = firstRef.playlist.tracks[0]!;
1271
+ const trackData = this.trackDatas.find(x => x.track === firstTrack);
1272
+ const codecString = trackData?.info.decoderConfig.codec ?? firstTrack.source._codec;
1273
+ codecs.push(codecString);
1274
+
1275
+ for (const ref of decl.references) {
1276
+ assert(ref.playlist.peakBitrate !== null);
1277
+ peakDeclBitrate = Math.max(peakDeclBitrate, ref.playlist.peakBitrate);
1278
+ maxRefAverageBitrate = Math.max(maxRefAverageBitrate, ref.playlist.averageBitrate ?? 0);
1279
+ }
1280
+ }
1281
+
1282
+ assert(decl.playlist.peakBitrate !== null);
1283
+ const totalPeakBitrate = decl.playlist.peakBitrate + peakDeclBitrate;
1284
+ const totalAverageBitrate = (decl.playlist.averageBitrate ?? 0) + maxRefAverageBitrate;
1285
+
1286
+ if (!firstVariantWritten) {
1287
+ masterPlaylistText += '\n';
1288
+ firstVariantWritten = true;
1289
+ }
1290
+
1291
+ if (isKeyPacketsOnly) {
1292
+ masterPlaylistText += `#EXT-X-I-FRAME-STREAM-INF:`;
1293
+ } else {
1294
+ masterPlaylistText += `#EXT-X-STREAM-INF:`;
1295
+ }
1296
+
1297
+ masterPlaylistText += `BANDWIDTH=${Math.ceil(totalPeakBitrate)}`;
1298
+
1299
+ if (totalAverageBitrate > 0) {
1300
+ masterPlaylistText += `,AVERAGE-BANDWIDTH=${Math.ceil(totalAverageBitrate)}`;
1301
+ }
1302
+
1303
+ masterPlaylistText += `,CODECS="${codecs.join(',')}"`;
1304
+
1305
+ const videoTrack = decl.playlist.tracks.find(x => x.isVideoTrack());
1306
+ if (videoTrack?.isVideoTrack()) {
1307
+ const trackData = this.trackDatas.find(x => x.track === videoTrack) as
1308
+ HlsVideoTrackData | undefined;
1309
+ const decoderConfig = trackData?.info.decoderConfig;
1310
+ if (decoderConfig) {
1311
+ let width = decoderConfig.displayAspectWidth ?? decoderConfig.codedWidth;
1312
+ let height = decoderConfig.displayAspectHeight ?? decoderConfig.codedHeight;
1313
+
1314
+ if (width !== undefined && height !== undefined) {
1315
+ if (
1316
+ videoTrack.metadata.rotation !== undefined
1317
+ && videoTrack.metadata.rotation % 180 === 90
1318
+ ) {
1319
+ [width, height] = [height, width];
1320
+ }
1321
+
1322
+ masterPlaylistText += `,RESOLUTION=${width}x${height}`;
1323
+ }
1324
+ }
1325
+
1326
+ // FRAME-RATE is not defined for EXT-X-I-FRAME-STREAM-INF
1327
+ if (!isKeyPacketsOnly && videoTrack.metadata.frameRate !== undefined) {
1328
+ // Spec requires that frame rate be rounded to 3 decimal places
1329
+ masterPlaylistText += `,FRAME-RATE=${+videoTrack.metadata.frameRate.toFixed(3)}`;
1330
+ }
1331
+ }
1332
+
1333
+ if (!isKeyPacketsOnly) {
1334
+ const groupIdForType = new Map<string, string>();
1335
+ for (const ref of decl.references) {
1336
+ assert(ref.groupId !== null);
1337
+ const type = ref.playlist.tracks[0]!.type;
1338
+ groupIdForType.set(type, ref.groupId);
1339
+ }
1340
+
1341
+ for (const [type, id] of groupIdForType) {
1342
+ masterPlaylistText += `,${type.toUpperCase()}="${id}"`;
1343
+ }
1344
+ }
1345
+
1346
+ if (isKeyPacketsOnly) {
1347
+ // EXT-X-I-FRAME-STREAM-INF is standalone with a URI attribute
1348
+ masterPlaylistText += `,URI="${decl.playlist.path}"`;
1349
+ masterPlaylistText += '\n';
1350
+ } else {
1351
+ masterPlaylistText += '\n';
1352
+ masterPlaylistText += `${decl.playlist.path}\n`;
1353
+ }
1354
+ } else {
1355
+ assert(decl.playlist.tracks.length === 1);
1356
+
1357
+ const track = decl.playlist.tracks[0]!;
1358
+ const type = track.type;
1359
+ let name = track.metadata.name ?? null;
1360
+ const languageCode = track.metadata.languageCode;
1361
+ const disposition = track.metadata.disposition;
1362
+
1363
+ if (lastGroupId === null || decl.groupId !== lastGroupId) {
1364
+ groupIdTrackCount = 0;
1365
+ masterPlaylistText += '\n';
1366
+ hasHadDefaultTrackInGroup = false;
1367
+ }
1368
+ lastGroupId = decl.groupId;
1369
+ groupIdTrackCount++;
1370
+
1371
+ masterPlaylistText += `#EXT-X-MEDIA:TYPE=${type.toUpperCase()},GROUP-ID="${decl.groupId}"`;
1372
+
1373
+ if (name !== null && /[\n\r"]/.test(name)) {
1374
+ Logging._warn(
1375
+ 'Dropping track name since it includes a line feed, carriage return, or double quote'
1376
+ + ' character, which are not allowed in HLS playlist attributes.',
1377
+ );
1378
+ name = null;
1379
+ }
1380
+
1381
+ // Name is required, so we have to set it to SOMETHING
1382
+ name ??= `${languageCode ?? decl.groupId}-${groupIdTrackCount}`;
1383
+
1384
+ masterPlaylistText += `,NAME="${name}"`;
1385
+
1386
+ if (languageCode !== undefined) {
1387
+ masterPlaylistText += `,LANGUAGE="${languageCode}"`;
1388
+ }
1389
+
1390
+ const dispositionPrimary = disposition?.primary ?? false;
1391
+ const dispositionDefault = disposition?.default ?? true;
1392
+ const dispositionForced = disposition?.forced ?? false;
1393
+
1394
+ if (dispositionPrimary && !hasHadDefaultTrackInGroup) {
1395
+ // HLS's "DEFAULT" behaves like our "primary"
1396
+ masterPlaylistText += ',DEFAULT=YES';
1397
+ hasHadDefaultTrackInGroup = true; // Only one DEFAULT label per group allowed
1398
+ }
1399
+
1400
+ if (dispositionPrimary || dispositionDefault) {
1401
+ masterPlaylistText += ',AUTOSELECT=YES';
1402
+ }
1403
+
1404
+ if (dispositionForced) {
1405
+ masterPlaylistText += ',FORCED=YES';
1406
+ }
1407
+
1408
+ if (type === 'audio') {
1409
+ const trackData = this.trackDatas.find(x => x.track === track) as
1410
+ HlsAudioTrackData | undefined;
1411
+ const decoderConfig = trackData?.info.decoderConfig;
1412
+
1413
+ if (decoderConfig) {
1414
+ masterPlaylistText += `,CHANNELS="${decoderConfig.numberOfChannels}"`;
1415
+ }
1416
+ }
1417
+
1418
+ if (!decl.noUri) {
1419
+ masterPlaylistText += `,URI="${decl.playlist.path}"`;
1420
+ }
1421
+
1422
+ masterPlaylistText += '\n';
1423
+ }
1424
+ }
1425
+
1426
+ this.format._options.onMaster?.(masterPlaylistText);
1427
+
1428
+ const release = await this.mutex.acquire();
1429
+
1430
+ try {
1431
+ let writer: Writer;
1432
+ if (this.numWrittenMasterPlaylists === 0) {
1433
+ // For the first master playlist write, we use the normal root writer getter, so that the target
1434
+ // returned by Output.target emits valid write events.
1435
+ writer = await this.output._getRootWriter(true);
1436
+ } else {
1437
+ // For subsequent master playlist writes, we *must* obtain a different target in order to overwrite
1438
+ // the file.
1439
+ const target = await this.output._getTarget({
1440
+ path: pathedTarget.rootPath,
1441
+ isRoot: true,
1442
+ mimeType: HLS_MIME_TYPE,
1443
+ });
1444
+ writer = new Writer(target, true);
1445
+ writer.start();
1446
+ }
1447
+
1448
+ writer.write(textEncoder.encode(masterPlaylistText));
1449
+
1450
+ await writer.flush();
1451
+ await writer.finalize();
1452
+
1453
+ this.numWrittenMasterPlaylists++;
1454
+ } finally {
1455
+ release();
1456
+ }
1457
+ }
1458
+
1459
+ private async tryWriteMasterPlaylist() {
1460
+ assert(this.isLive);
1461
+
1462
+ // The master playlist is written once all playlists have either produced at least one segment or are done
1463
+ for (const playlist of this.playlists) {
1464
+ if (playlist.writtenSegments.length === 0 && !playlist.done) {
1465
+ return;
1466
+ }
1467
+ }
1468
+
1469
+ await this.writeMasterPlaylist();
1470
+ }
1471
+
1472
+ async finalize() {
1473
+ const releases = await Promise.all(this.playlists.map(p => p.mutex.acquire()));
1474
+ releases.forEach(release => release());
1475
+
1476
+ for (const trackData of this.trackDatas) {
1477
+ trackData.closed = true;
1478
+ }
1479
+
1480
+ await Promise.all(this.playlists.map(playlist => (
1481
+ playlist.done ? Promise.resolve() : this.advancePlaylist(playlist)
1482
+ )));
1483
+
1484
+ if (!this.isLive) {
1485
+ await this.writeMasterPlaylist();
1486
+ }
1487
+ }
1488
+ }
1489
+
1490
+ const validatePlaylistPath = (path: string) => {
1491
+ if (typeof path !== 'string') {
1492
+ throw new TypeError('options.getPlaylistPath must return or resolve to a string');
1493
+ }
1494
+ if (/[\n\r"]/.test(path)) {
1495
+ throw new TypeError(
1496
+ 'Playlist paths cannot contain line feed, carriage return, or double quote characters.',
1497
+ );
1498
+ }
1499
+ };
1500
+
1501
+ const validateSegmentPath = (path: string) => {
1502
+ if (typeof path !== 'string') {
1503
+ throw new TypeError('options.getSegmentPath must return or resolve to a string');
1504
+ }
1505
+ if (/[\n\r"]/.test(path)) {
1506
+ throw new TypeError(
1507
+ 'Segment paths cannot contain line feed or carriage return characters.',
1508
+ );
1509
+ }
1510
+ };
1511
+
1512
+ const validateInitPath = (path: string) => {
1513
+ if (typeof path !== 'string') {
1514
+ throw new TypeError('options.getInitPath must return or resolve to a string');
1515
+ }
1516
+ if (/[\n\r"]/.test(path)) {
1517
+ throw new TypeError(
1518
+ 'Init paths cannot contain line feed, carriage return, or double quote characters.',
1519
+ );
1520
+ }
1521
+ };
1522
+
1523
+ const toPlaylistInfo = (playlist: Playlist): HlsOutputPlaylistInfo => {
1524
+ return {
1525
+ n: playlist.id,
1526
+ tracks: playlist.tracks,
1527
+ segmentFormat: playlist.segmentFormat,
1528
+ };
1529
+ };