@kvman/kvvideo 0.0.0-stage → 0.1.1

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 (345) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/dist/api.d.ts +105 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +2 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/brand/brand.d.ts +17 -0
  8. package/dist/brand/brand.d.ts.map +1 -0
  9. package/dist/brand/brand.js +44 -0
  10. package/dist/brand/brand.js.map +1 -0
  11. package/dist/browser/channels.d.ts +6 -0
  12. package/dist/browser/channels.d.ts.map +1 -0
  13. package/dist/browser/channels.js +5 -0
  14. package/dist/browser/channels.js.map +1 -0
  15. package/dist/browser/launch.d.ts +6 -0
  16. package/dist/browser/launch.d.ts.map +1 -0
  17. package/dist/browser/launch.js +14 -0
  18. package/dist/browser/launch.js.map +1 -0
  19. package/dist/browser/start-browser.d.ts +5 -0
  20. package/dist/browser/start-browser.d.ts.map +1 -0
  21. package/dist/browser/start-browser.js +17 -0
  22. package/dist/browser/start-browser.js.map +1 -0
  23. package/dist/compose/ass-file.d.ts +17 -0
  24. package/dist/compose/ass-file.d.ts.map +1 -0
  25. package/dist/compose/ass-file.js +65 -0
  26. package/dist/compose/ass-file.js.map +1 -0
  27. package/dist/compose/background.d.ts +23 -0
  28. package/dist/compose/background.d.ts.map +1 -0
  29. package/dist/compose/background.js +31 -0
  30. package/dist/compose/background.js.map +1 -0
  31. package/dist/compose/camera.d.ts +32 -0
  32. package/dist/compose/camera.d.ts.map +1 -0
  33. package/dist/compose/camera.js +98 -0
  34. package/dist/compose/camera.js.map +1 -0
  35. package/dist/compose/caption-font.d.ts +8 -0
  36. package/dist/compose/caption-font.d.ts.map +1 -0
  37. package/dist/compose/caption-font.js +24 -0
  38. package/dist/compose/caption-font.js.map +1 -0
  39. package/dist/compose/compose-drawing.d.ts +19 -0
  40. package/dist/compose/compose-drawing.d.ts.map +1 -0
  41. package/dist/compose/compose-drawing.js +38 -0
  42. package/dist/compose/compose-drawing.js.map +1 -0
  43. package/dist/compose/compose-input.d.ts +187 -0
  44. package/dist/compose/compose-input.d.ts.map +1 -0
  45. package/dist/compose/compose-input.js +76 -0
  46. package/dist/compose/compose-input.js.map +1 -0
  47. package/dist/compose/compose-plan.d.ts +36 -0
  48. package/dist/compose/compose-plan.d.ts.map +1 -0
  49. package/dist/compose/compose-plan.js +55 -0
  50. package/dist/compose/compose-plan.js.map +1 -0
  51. package/dist/compose/compose-size.d.ts +50 -0
  52. package/dist/compose/compose-size.d.ts.map +1 -0
  53. package/dist/compose/compose-size.js +72 -0
  54. package/dist/compose/compose-size.js.map +1 -0
  55. package/dist/compose/drawn-images.d.ts +19 -0
  56. package/dist/compose/drawn-images.d.ts.map +1 -0
  57. package/dist/compose/drawn-images.js +75 -0
  58. package/dist/compose/drawn-images.js.map +1 -0
  59. package/dist/compose/final-pass.d.ts +34 -0
  60. package/dist/compose/final-pass.d.ts.map +1 -0
  61. package/dist/compose/final-pass.js +106 -0
  62. package/dist/compose/final-pass.js.map +1 -0
  63. package/dist/compose/frame-layout.d.ts +30 -0
  64. package/dist/compose/frame-layout.d.ts.map +1 -0
  65. package/dist/compose/frame-layout.js +33 -0
  66. package/dist/compose/frame-layout.js.map +1 -0
  67. package/dist/compose/overlays.d.ts +20 -0
  68. package/dist/compose/overlays.d.ts.map +1 -0
  69. package/dist/compose/overlays.js +30 -0
  70. package/dist/compose/overlays.js.map +1 -0
  71. package/dist/compose/page-again.d.ts +26 -0
  72. package/dist/compose/page-again.d.ts.map +1 -0
  73. package/dist/compose/page-again.js +50 -0
  74. package/dist/compose/page-again.js.map +1 -0
  75. package/dist/compose/player-copies.d.ts +10 -0
  76. package/dist/compose/player-copies.d.ts.map +1 -0
  77. package/dist/compose/player-copies.js +34 -0
  78. package/dist/compose/player-copies.js.map +1 -0
  79. package/dist/compose/register-compose.d.ts +3 -0
  80. package/dist/compose/register-compose.d.ts.map +1 -0
  81. package/dist/compose/register-compose.js +151 -0
  82. package/dist/compose/register-compose.js.map +1 -0
  83. package/dist/compose/render.d.ts +25 -0
  84. package/dist/compose/render.d.ts.map +1 -0
  85. package/dist/compose/render.js +61 -0
  86. package/dist/compose/render.js.map +1 -0
  87. package/dist/compose/scene-args.d.ts +37 -0
  88. package/dist/compose/scene-args.d.ts.map +1 -0
  89. package/dist/compose/scene-args.js +103 -0
  90. package/dist/compose/scene-args.js.map +1 -0
  91. package/dist/compose/scene-look.d.ts +31 -0
  92. package/dist/compose/scene-look.d.ts.map +1 -0
  93. package/dist/compose/scene-look.js +46 -0
  94. package/dist/compose/scene-look.js.map +1 -0
  95. package/dist/compose/scene-plan.d.ts +26 -0
  96. package/dist/compose/scene-plan.d.ts.map +1 -0
  97. package/dist/compose/scene-plan.js +34 -0
  98. package/dist/compose/scene-plan.js.map +1 -0
  99. package/dist/compose/sound-effects.d.ts +23 -0
  100. package/dist/compose/sound-effects.d.ts.map +1 -0
  101. package/dist/compose/sound-effects.js +40 -0
  102. package/dist/compose/sound-effects.js.map +1 -0
  103. package/dist/compose/srt.d.ts +3 -0
  104. package/dist/compose/srt.d.ts.map +1 -0
  105. package/dist/compose/srt.js +10 -0
  106. package/dist/compose/srt.js.map +1 -0
  107. package/dist/compose/transitions.d.ts +16 -0
  108. package/dist/compose/transitions.d.ts.map +1 -0
  109. package/dist/compose/transitions.js +38 -0
  110. package/dist/compose/transitions.js.map +1 -0
  111. package/dist/connector.d.ts +132 -0
  112. package/dist/connector.d.ts.map +1 -0
  113. package/dist/connector.js +63 -0
  114. package/dist/connector.js.map +1 -0
  115. package/dist/files/answer-path.d.ts +3 -0
  116. package/dist/files/answer-path.d.ts.map +1 -0
  117. package/dist/files/answer-path.js +6 -0
  118. package/dist/files/answer-path.js.map +1 -0
  119. package/dist/files/place-output.d.ts +8 -0
  120. package/dist/files/place-output.d.ts.map +1 -0
  121. package/dist/files/place-output.js +24 -0
  122. package/dist/files/place-output.js.map +1 -0
  123. package/dist/files/sidecar.d.ts +209 -0
  124. package/dist/files/sidecar.d.ts.map +1 -0
  125. package/dist/files/sidecar.js +66 -0
  126. package/dist/files/sidecar.js.map +1 -0
  127. package/dist/files/workspace-paths.d.ts +7 -0
  128. package/dist/files/workspace-paths.d.ts.map +1 -0
  129. package/dist/files/workspace-paths.js +48 -0
  130. package/dist/files/workspace-paths.js.map +1 -0
  131. package/dist/fonts/bundled-fonts.d.ts +10 -0
  132. package/dist/fonts/bundled-fonts.d.ts.map +1 -0
  133. package/dist/fonts/bundled-fonts.js +10 -0
  134. package/dist/fonts/bundled-fonts.js.map +1 -0
  135. package/dist/fonts/font-family.d.ts +2 -0
  136. package/dist/fonts/font-family.d.ts.map +1 -0
  137. package/dist/fonts/font-family.js +43 -0
  138. package/dist/fonts/font-family.js.map +1 -0
  139. package/dist/fonts/register-fonts.d.ts +3 -0
  140. package/dist/fonts/register-fonts.d.ts.map +1 -0
  141. package/dist/fonts/register-fonts.js +12 -0
  142. package/dist/fonts/register-fonts.js.map +1 -0
  143. package/dist/guide.d.ts +3 -0
  144. package/dist/guide.d.ts.map +1 -0
  145. package/dist/guide.js +6 -0
  146. package/dist/guide.js.map +1 -0
  147. package/dist/index.d.ts +5 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +30 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/narration/alignment.d.ts +15 -0
  152. package/dist/narration/alignment.d.ts.map +1 -0
  153. package/dist/narration/alignment.js +21 -0
  154. package/dist/narration/alignment.js.map +1 -0
  155. package/dist/narration/captions.d.ts +28 -0
  156. package/dist/narration/captions.d.ts.map +1 -0
  157. package/dist/narration/captions.js +70 -0
  158. package/dist/narration/captions.js.map +1 -0
  159. package/dist/narration/join-args.d.ts +3 -0
  160. package/dist/narration/join-args.d.ts.map +1 -0
  161. package/dist/narration/join-args.js +19 -0
  162. package/dist/narration/join-args.js.map +1 -0
  163. package/dist/narration/narration-cache.d.ts +25 -0
  164. package/dist/narration/narration-cache.d.ts.map +1 -0
  165. package/dist/narration/narration-cache.js +36 -0
  166. package/dist/narration/narration-cache.js.map +1 -0
  167. package/dist/narration/piper.d.ts +4 -0
  168. package/dist/narration/piper.d.ts.map +1 -0
  169. package/dist/narration/piper.js +13 -0
  170. package/dist/narration/piper.js.map +1 -0
  171. package/dist/narration/pronunciations.d.ts +11 -0
  172. package/dist/narration/pronunciations.d.ts.map +1 -0
  173. package/dist/narration/pronunciations.js +40 -0
  174. package/dist/narration/pronunciations.js.map +1 -0
  175. package/dist/narration/register-narration.d.ts +25 -0
  176. package/dist/narration/register-narration.d.ts.map +1 -0
  177. package/dist/narration/register-narration.js +103 -0
  178. package/dist/narration/register-narration.js.map +1 -0
  179. package/dist/narration/register-voice.d.ts +27 -0
  180. package/dist/narration/register-voice.d.ts.map +1 -0
  181. package/dist/narration/register-voice.js +82 -0
  182. package/dist/narration/register-voice.js.map +1 -0
  183. package/dist/narration/sentence-speaker.d.ts +35 -0
  184. package/dist/narration/sentence-speaker.d.ts.map +1 -0
  185. package/dist/narration/sentence-speaker.js +44 -0
  186. package/dist/narration/sentence-speaker.js.map +1 -0
  187. package/dist/narration/speech-services.d.ts +39 -0
  188. package/dist/narration/speech-services.d.ts.map +1 -0
  189. package/dist/narration/speech-services.js +67 -0
  190. package/dist/narration/speech-services.js.map +1 -0
  191. package/dist/narration/voice-args.d.ts +3 -0
  192. package/dist/narration/voice-args.d.ts.map +1 -0
  193. package/dist/narration/voice-args.js +10 -0
  194. package/dist/narration/voice-args.js.map +1 -0
  195. package/dist/problems.d.ts +12 -0
  196. package/dist/problems.d.ts.map +1 -0
  197. package/dist/problems.js +19 -0
  198. package/dist/problems.js.map +1 -0
  199. package/dist/programs/kill-tree.d.ts +16 -0
  200. package/dist/programs/kill-tree.d.ts.map +1 -0
  201. package/dist/programs/kill-tree.js +28 -0
  202. package/dist/programs/kill-tree.js.map +1 -0
  203. package/dist/programs/media-duration.d.ts +22 -0
  204. package/dist/programs/media-duration.d.ts.map +1 -0
  205. package/dist/programs/media-duration.js +23 -0
  206. package/dist/programs/media-duration.js.map +1 -0
  207. package/dist/programs/piped-program.d.ts +7 -0
  208. package/dist/programs/piped-program.d.ts.map +1 -0
  209. package/dist/programs/piped-program.js +45 -0
  210. package/dist/programs/piped-program.js.map +1 -0
  211. package/dist/programs/programs.d.ts +6 -0
  212. package/dist/programs/programs.d.ts.map +1 -0
  213. package/dist/programs/programs.js +6 -0
  214. package/dist/programs/programs.js.map +1 -0
  215. package/dist/programs/run-program.d.ts +23 -0
  216. package/dist/programs/run-program.d.ts.map +1 -0
  217. package/dist/programs/run-program.js +47 -0
  218. package/dist/programs/run-program.js.map +1 -0
  219. package/dist/record/address.d.ts +5 -0
  220. package/dist/record/address.d.ts.map +1 -0
  221. package/dist/record/address.js +26 -0
  222. package/dist/record/address.js.map +1 -0
  223. package/dist/record/cursor-script.d.ts +3 -0
  224. package/dist/record/cursor-script.d.ts.map +1 -0
  225. package/dist/record/cursor-script.js +59 -0
  226. package/dist/record/cursor-script.js.map +1 -0
  227. package/dist/record/encoder-args.d.ts +3 -0
  228. package/dist/record/encoder-args.d.ts.map +1 -0
  229. package/dist/record/encoder-args.js +13 -0
  230. package/dist/record/encoder-args.js.map +1 -0
  231. package/dist/record/frame-writer.d.ts +8 -0
  232. package/dist/record/frame-writer.d.ts.map +1 -0
  233. package/dist/record/frame-writer.js +30 -0
  234. package/dist/record/frame-writer.js.map +1 -0
  235. package/dist/record/motion.d.ts +19 -0
  236. package/dist/record/motion.d.ts.map +1 -0
  237. package/dist/record/motion.js +59 -0
  238. package/dist/record/motion.js.map +1 -0
  239. package/dist/record/narration-cues.d.ts +14 -0
  240. package/dist/record/narration-cues.d.ts.map +1 -0
  241. package/dist/record/narration-cues.js +12 -0
  242. package/dist/record/narration-cues.js.map +1 -0
  243. package/dist/record/own-port.d.ts +2 -0
  244. package/dist/record/own-port.d.ts.map +1 -0
  245. package/dist/record/own-port.js +23 -0
  246. package/dist/record/own-port.js.map +1 -0
  247. package/dist/record/page-ready.d.ts +4 -0
  248. package/dist/record/page-ready.d.ts.map +1 -0
  249. package/dist/record/page-ready.js +15 -0
  250. package/dist/record/page-ready.js.map +1 -0
  251. package/dist/record/page-route.d.ts +13 -0
  252. package/dist/record/page-route.d.ts.map +1 -0
  253. package/dist/record/page-route.js +64 -0
  254. package/dist/record/page-route.js.map +1 -0
  255. package/dist/record/pointer.d.ts +8 -0
  256. package/dist/record/pointer.d.ts.map +1 -0
  257. package/dist/record/pointer.js +24 -0
  258. package/dist/record/pointer.js.map +1 -0
  259. package/dist/record/recorder.d.ts +34 -0
  260. package/dist/record/recorder.d.ts.map +1 -0
  261. package/dist/record/recorder.js +99 -0
  262. package/dist/record/recorder.js.map +1 -0
  263. package/dist/record/register-record.d.ts +3 -0
  264. package/dist/record/register-record.d.ts.map +1 -0
  265. package/dist/record/register-record.js +83 -0
  266. package/dist/record/register-record.js.map +1 -0
  267. package/dist/record/run-step.d.ts +20 -0
  268. package/dist/record/run-step.d.ts.map +1 -0
  269. package/dist/record/run-step.js +69 -0
  270. package/dist/record/run-step.js.map +1 -0
  271. package/dist/record/screencast.d.ts +9 -0
  272. package/dist/record/screencast.d.ts.map +1 -0
  273. package/dist/record/screencast.js +38 -0
  274. package/dist/record/screencast.js.map +1 -0
  275. package/dist/record/steps.d.ts +124 -0
  276. package/dist/record/steps.d.ts.map +1 -0
  277. package/dist/record/steps.js +47 -0
  278. package/dist/record/steps.js.map +1 -0
  279. package/dist/register-with-kvcoder.d.ts +3 -0
  280. package/dist/register-with-kvcoder.d.ts.map +1 -0
  281. package/dist/register-with-kvcoder.js +15 -0
  282. package/dist/register-with-kvcoder.js.map +1 -0
  283. package/dist/review/analysis.d.ts +19 -0
  284. package/dist/review/analysis.d.ts.map +1 -0
  285. package/dist/review/analysis.js +36 -0
  286. package/dist/review/analysis.js.map +1 -0
  287. package/dist/review/frames.d.ts +9 -0
  288. package/dist/review/frames.d.ts.map +1 -0
  289. package/dist/review/frames.js +28 -0
  290. package/dist/review/frames.js.map +1 -0
  291. package/dist/review/register-review.d.ts +24 -0
  292. package/dist/review/register-review.d.ts.map +1 -0
  293. package/dist/review/register-review.js +81 -0
  294. package/dist/review/register-review.js.map +1 -0
  295. package/dist/review/sheet-args.d.ts +11 -0
  296. package/dist/review/sheet-args.d.ts.map +1 -0
  297. package/dist/review/sheet-args.js +24 -0
  298. package/dist/review/sheet-args.js.map +1 -0
  299. package/dist/settings.d.ts +33 -0
  300. package/dist/settings.d.ts.map +1 -0
  301. package/dist/settings.js +29 -0
  302. package/dist/settings.js.map +1 -0
  303. package/dist/setup/browser-readiness.d.ts +14 -0
  304. package/dist/setup/browser-readiness.d.ts.map +1 -0
  305. package/dist/setup/browser-readiness.js +16 -0
  306. package/dist/setup/browser-readiness.js.map +1 -0
  307. package/dist/setup/ffmpeg-readiness.d.ts +19 -0
  308. package/dist/setup/ffmpeg-readiness.d.ts.map +1 -0
  309. package/dist/setup/ffmpeg-readiness.js +33 -0
  310. package/dist/setup/ffmpeg-readiness.js.map +1 -0
  311. package/dist/setup/narration-readiness.d.ts +21 -0
  312. package/dist/setup/narration-readiness.d.ts.map +1 -0
  313. package/dist/setup/narration-readiness.js +18 -0
  314. package/dist/setup/narration-readiness.js.map +1 -0
  315. package/dist/setup/register-setup.d.ts +3 -0
  316. package/dist/setup/register-setup.d.ts.map +1 -0
  317. package/dist/setup/register-setup.js +51 -0
  318. package/dist/setup/register-setup.js.map +1 -0
  319. package/dist/ui.d.ts +3 -0
  320. package/dist/ui.d.ts.map +1 -0
  321. package/dist/ui.js +26 -0
  322. package/dist/ui.js.map +1 -0
  323. package/dist/video-start.d.ts +3 -0
  324. package/dist/video-start.d.ts.map +1 -0
  325. package/dist/video-start.js +28 -0
  326. package/dist/video-start.js.map +1 -0
  327. package/dist/web/components/player.css +2 -0
  328. package/dist/web/components/player.js +55 -0
  329. package/docs/guide.md +28 -0
  330. package/fonts/Amiri-Bold.ttf +0 -0
  331. package/fonts/IBMPlexSansArabic-Bold.ttf +0 -0
  332. package/fonts/Lato-Bold.ttf +0 -0
  333. package/fonts/OFL-Amiri.txt +94 -0
  334. package/fonts/OFL-IBMPlexSansArabic.txt +93 -0
  335. package/fonts/OFL-Lato.txt +93 -0
  336. package/fonts/OFL-Poppins.txt +93 -0
  337. package/fonts/Poppins-Bold.ttf +0 -0
  338. package/locales/ar.json +48 -0
  339. package/locales/en.json +48 -0
  340. package/package.json +73 -3
  341. package/sounds/SOURCES.md +13 -0
  342. package/sounds/click.wav +0 -0
  343. package/sounds/keys.wav +0 -0
  344. package/sounds/pop.wav +0 -0
  345. package/sounds/whoosh.wav +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.js","sourceRoot":"","sources":["../../src/review/frames.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,MAAM,IAAI,GAAG,EAAE,CAAC;AAChB,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC;AAE3B,SAAS,MAAM,CAAC,OAAiC,EAAE,UAAkB;IACnE,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAChI,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC;IACrF,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtG,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,gBAAgB,EAAE,GAAG,QAAQ,CAAC,CAAC;AACxD,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,UAAU,CAAC,OAAiC,EAAE,UAAkB;IAC9E,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAChH,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,GAAG,IAAI,IAAI,OAAO;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACrH,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,QAAQ,CAAC,KAAwB;IAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;AACzI,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { z, type Ctx } from '@kvman/sdk';
2
+ export declare const reviewOutputSchema: z.ZodObject<{
3
+ durationMs: z.ZodNumber;
4
+ loudness: z.ZodNullable<z.ZodObject<{
5
+ integratedLufs: z.ZodNumber;
6
+ truePeakDb: z.ZodNumber;
7
+ }, z.core.$strip>>;
8
+ problems: z.ZodArray<z.ZodObject<{
9
+ kind: z.ZodEnum<{
10
+ silence: "silence";
11
+ black: "black";
12
+ frozen: "frozen";
13
+ loudness: "loudness";
14
+ }>;
15
+ atMs: z.ZodNumber;
16
+ lengthMs: z.ZodNumber;
17
+ }, z.core.$strip>>;
18
+ images: z.ZodArray<z.ZodObject<{
19
+ fileId: z.ZodString;
20
+ name: z.ZodString;
21
+ }, z.core.$strip>>;
22
+ }, z.core.$strip>;
23
+ export declare function registerReview(ctx: Ctx): void;
24
+ //# sourceMappingURL=register-review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-review.d.ts","sourceRoot":"","sources":["../../src/review/register-review.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAsBzC,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;iBAK7B,CAAC;AAQH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CA4C7C"}
@@ -0,0 +1,81 @@
1
+ import { copyFileSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { z } from '@kvman/sdk';
4
+ import { readSidecar } from "../files/sidecar.js";
5
+ import { inputPath } from "../files/workspace-paths.js";
6
+ import { workFolder } from "../files/place-output.js";
7
+ import { bundledFonts, fontsFolder } from "../fonts/bundled-fonts.js";
8
+ import { trimOldest } from "../narration/narration-cache.js";
9
+ import { hasSound, mediaDuration, mediaSize } from "../programs/media-duration.js";
10
+ import { programOf } from "../programs/programs.js";
11
+ import { lastLines, runProgram } from "../programs/run-program.js";
12
+ import { kvvideoProblem } from "../problems.js";
13
+ import { analysisArgs, analysisOf } from "./analysis.js";
14
+ import { frameTimes, sheetsOf } from "./frames.js";
15
+ import { sheetArgs, sheetGraph, tileOf } from "./sheet-args.js";
16
+ // `video review` (plan 16 §16.10; ADR 0115, 20 and 48): measures a video's silences, black and frozen pictures, and
17
+ // loudness, and makes contact sheets of its frames that the model sees through kvcoder (`images: true`). The newest 24
18
+ // sheets of the workspace are kept in the kernel's files.
19
+ const keptSheets = 24;
20
+ const problemSchema = z.object({ kind: z.enum(['silence', 'black', 'frozen', 'loudness']), atMs: z.number().int().nonnegative(), lengthMs: z.number().int().nonnegative() });
21
+ export const reviewOutputSchema = z.object({
22
+ durationMs: z.number().int().nonnegative(),
23
+ loudness: z.object({ integratedLufs: z.number(), truePeakDb: z.number() }).nullable(),
24
+ problems: z.array(problemSchema),
25
+ images: z.array(z.object({ fileId: z.string(), name: z.string() })),
26
+ });
27
+ const sheetRowSchema = z.object({ fileId: z.string(), createdAt: z.string() });
28
+ function failed(reason) {
29
+ return kvvideoProblem('RENDER_FAILED', `ffmpeg couldn't review the video: ${reason}`, { scene: null, reason });
30
+ }
31
+ export function registerReview(ctx) {
32
+ ctx.registerCommand('kvvideo.video.review', {
33
+ description: "Reviews an MP4 of the workspace: its silences, black and frozen pictures, and loudness, and contact sheets of its frames to look at before telling the person it's ready.",
34
+ input: z.strictObject({ file: z.string().min(1).max(1000).describe('The .mp4 file to review, in the workspace.') }),
35
+ output: reviewOutputSchema,
36
+ public: true,
37
+ retries: 0,
38
+ timeoutMs: 600_000,
39
+ handle: async ({ file }) => {
40
+ const video = inputPath(ctx.job.workspace.path, file, ['.mp4']);
41
+ const [ffmpeg, ffprobe] = [await programOf(ctx, 'ffmpeg'), await programOf(ctx, 'ffprobe')];
42
+ const signal = ctx.job.signal;
43
+ const duration = await mediaDuration(ffprobe, video, signal);
44
+ const size = await mediaSize(ffprobe, video, signal);
45
+ if (!duration.ok || !size.ok)
46
+ throw failed(duration.ok ? (size.ok ? '' : size.reason) : duration.reason);
47
+ const sound = await hasSound(ffprobe, video, signal);
48
+ const measured = await runProgram(ffmpeg, analysisArgs(video, sound), { signal });
49
+ if (measured.exitCode !== 0)
50
+ throw failed(lastLines(measured.output));
51
+ const analysis = analysisOf(measured.output, duration.ms, sound);
52
+ const sidecar = readSidecar(video);
53
+ const sheets = sheetsOf(frameTimes(sidecar?.kind === 'video' ? sidecar : undefined, duration.ms)).slice(0, 8);
54
+ const tile = tileOf(size.width, size.height);
55
+ const work = workFolder();
56
+ try {
57
+ copyFileSync(path.join(fontsFolder, bundledFonts.find((font) => font.name === 'Poppins')?.file ?? ''), path.join(work.folder, 'font.ttf'));
58
+ const images = [];
59
+ for (const [index, times] of sheets.entries()) {
60
+ ctx.job.progress({ key: 'kvvideo.progress.sheet', params: { n: index + 1, of: sheets.length } });
61
+ writeFileSync(path.join(work.folder, 'sheet.graph'), sheetGraph(times, tile));
62
+ const made = await runProgram(ffmpeg, sheetArgs(video, times, 'sheet.graph', 'sheet.jpg'), { cwd: work.folder, signal });
63
+ if (made.exitCode !== 0)
64
+ throw failed(lastLines(made.output));
65
+ const name = `review-${String(index + 1)}.jpg`;
66
+ const stored = await ctx.files.write(name, readFileSync(path.join(work.folder, 'sheet.jpg')), 'image/jpeg');
67
+ images.push({ fileId: stored.id, name });
68
+ }
69
+ const rows = ctx.store.collection('reviewSheets', sheetRowSchema);
70
+ for (const image of images)
71
+ await rows.insert({ fileId: image.fileId, createdAt: new Date().toISOString() });
72
+ await trimOldest(rows, ctx.files, keptSheets);
73
+ return { durationMs: duration.ms, loudness: analysis.loudness, problems: analysis.problems, images };
74
+ }
75
+ finally {
76
+ work.remove();
77
+ }
78
+ },
79
+ });
80
+ }
81
+ //# sourceMappingURL=register-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-review.js","sourceRoot":"","sources":["../../src/review/register-review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export type Tile = {
2
+ width: number;
3
+ height: number;
4
+ };
5
+ /** A frame's size on the sheet, for a video of `width` × `height`. */
6
+ export declare function tileOf(width: number, height: number): Tile;
7
+ /** A time as the sheet labels it, `m:ss.s`. */
8
+ export declare function timeLabel(ms: number): string;
9
+ export declare function sheetGraph(times: readonly number[], tile: Tile): string;
10
+ export declare function sheetArgs(video: string, times: readonly number[], graph: string, output: string): string[];
11
+ //# sourceMappingURL=sheet-args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet-args.d.ts","sourceRoot":"","sources":["../../src/review/sheet-args.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,IAAI,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAIrD,sEAAsE;AACtE,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAE1D;AAED,+CAA+C;AAC/C,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAMvE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAE1G"}
@@ -0,0 +1,24 @@
1
+ // ffmpeg's arguments for one contact sheet (plan 16 §16.10; ADR 0115, 48): each frame taken at its time, 480 px on its
2
+ // longer side, labelled with its time (`m:ss.s`) in the bundled font, laid out 3 frames wide, as a JPEG. ffmpeg runs in
3
+ // the work folder, where the font is `font.ttf`.
4
+ const even = (value) => Math.max(2, 2 * Math.round(value / 2));
5
+ /** A frame's size on the sheet, for a video of `width` × `height`. */
6
+ export function tileOf(width, height) {
7
+ return width >= height ? { width: 480, height: even((480 * height) / width) } : { width: even((480 * width) / height), height: 480 };
8
+ }
9
+ /** A time as the sheet labels it, `m:ss.s`. */
10
+ export function timeLabel(ms) {
11
+ const tenths = Math.floor(ms / 100);
12
+ return `${String(Math.floor(tenths / 600))}:${String(Math.floor(tenths / 10) % 60).padStart(2, '0')}.${String(tenths % 10)}`;
13
+ }
14
+ export function sheetGraph(times, tile) {
15
+ const tiles = times.map((at, index) => `[${String(index)}:v]scale=${String(tile.width)}:${String(tile.height)},drawtext=fontfile=font.ttf:text='${timeLabel(at).replace(':', '\\:')}':x=10:y=h-th-10:fontsize=24:fontcolor=white:box=1:boxcolor=black@0.6:boxborderw=6[t${String(index)}]`);
16
+ const labels = times.map((_, index) => `[t${String(index)}]`).join('');
17
+ const layout = times.map((_, index) => `${String((index % 3) * tile.width)}_${String(Math.floor(index / 3) * tile.height)}`).join('|');
18
+ const stack = times.length === 1 ? `${labels}null[sheet]` : `${labels}xstack=inputs=${String(times.length)}:layout=${layout}:fill=black[sheet]`;
19
+ return [...tiles, stack].join(';\n');
20
+ }
21
+ export function sheetArgs(video, times, graph, output) {
22
+ return ['-hide_banner', '-loglevel', 'error', ...times.flatMap((at) => ['-ss', (at / 1000).toFixed(3), '-i', video]), '-filter_complex_script', graph, '-map', '[sheet]', '-frames:v', '1', '-q:v', '4', '-y', output];
23
+ }
24
+ //# sourceMappingURL=sheet-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet-args.js","sourceRoot":"","sources":["../../src/review/sheet-args.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { z, type Ctx } from '@kvman/sdk';
2
+ export declare const narrationServices: readonly ["elevenlabs", "openai", "piper"];
3
+ /** A narration service. */
4
+ export type NarrationService = (typeof narrationServices)[number];
5
+ export declare const browserChoices: readonly ["auto", "chrome", "msedge"];
6
+ /** Which installed browser records. */
7
+ export type BrowserChoice = (typeof browserChoices)[number];
8
+ export declare const programNames: readonly ["ffmpeg", "ffprobe", "piper"];
9
+ /** A program kvvideo runs. */
10
+ export type ProgramName = (typeof programNames)[number];
11
+ export declare const settingSchemas: {
12
+ service: z.ZodNullable<z.ZodEnum<{
13
+ elevenlabs: "elevenlabs";
14
+ openai: "openai";
15
+ piper: "piper";
16
+ }>>;
17
+ voice: z.ZodNullable<z.ZodString>;
18
+ model: z.ZodNullable<z.ZodString>;
19
+ browser: z.ZodEnum<{
20
+ auto: "auto";
21
+ chrome: "chrome";
22
+ msedge: "msedge";
23
+ }>;
24
+ program: z.ZodString;
25
+ pronunciations: z.ZodArray<z.ZodObject<{
26
+ word: z.ZodString;
27
+ say: z.ZodString;
28
+ }, z.core.$strict>>;
29
+ };
30
+ /** The setting that names a program. */
31
+ export declare function programSetting(program: ProgramName): `kvvideo.programs.${ProgramName}`;
32
+ export declare function registerSettings(ctx: Ctx): void;
33
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAKzC,eAAO,MAAM,iBAAiB,4CAA6C,CAAC;AAE5E,2BAA2B;AAC3B,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,eAAO,MAAM,cAAc,uCAAwC,CAAC;AAEpE,uCAAuC;AACvC,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,eAAO,MAAM,YAAY,yCAA0C,CAAC;AAEpE,8BAA8B;AAC9B,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAExD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;CAO1B,CAAC;AAEF,wCAAwC;AACxC,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,oBAAoB,WAAW,EAAE,CAEtF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAS/C"}
@@ -0,0 +1,29 @@
1
+ import { z } from '@kvman/sdk';
2
+ // kvvideo's settings (plan 16 §16.2; ADR 0107, 5 and 20; ADR 0115, 15): no narration service until the person
3
+ // chooses one, the words the narration says differently, and the programs as a name on the PATH or a full path.
4
+ export const narrationServices = ['elevenlabs', 'openai', 'piper'];
5
+ export const browserChoices = ['auto', 'chrome', 'msedge'];
6
+ export const programNames = ['ffmpeg', 'ffprobe', 'piper'];
7
+ export const settingSchemas = {
8
+ service: z.enum(narrationServices).nullable(),
9
+ voice: z.string().min(1).max(500).nullable(),
10
+ model: z.string().min(1).max(100).nullable(),
11
+ browser: z.enum(browserChoices),
12
+ program: z.string().min(1).max(1000),
13
+ pronunciations: z.array(z.strictObject({ word: z.string().min(1).max(100), say: z.string().min(1).max(200) })).max(200),
14
+ };
15
+ /** The setting that names a program. */
16
+ export function programSetting(program) {
17
+ return `kvvideo.programs.${program}`;
18
+ }
19
+ export function registerSettings(ctx) {
20
+ ctx.registerSetting('kvvideo.narration.service', { description: 'The text-to-speech service that narrates; null until the person chooses one.', schema: settingSchemas.service, default: null });
21
+ ctx.registerSetting('kvvideo.narration.voice', { description: "The narration voice: a voice id for ElevenLabs or OpenAI, or the path of a Piper voice's .onnx file; null is the service's default.", schema: settingSchemas.voice, default: null });
22
+ ctx.registerSetting('kvvideo.narration.model', { description: "The narration model of ElevenLabs or OpenAI; null is the service's default.", schema: settingSchemas.model, default: null });
23
+ ctx.registerSetting('kvvideo.narration.pronunciations', { description: 'How the narration says words: each word, as a whole word in any case, is said as its say; captions keep the word as written.', schema: settingSchemas.pronunciations, default: [] });
24
+ ctx.registerSetting('kvvideo.browser', { description: 'The installed browser that records pages: auto tries Chrome, then Edge.', schema: settingSchemas.browser, default: 'auto', scopes: ['global'] });
25
+ for (const program of programNames) {
26
+ ctx.registerSetting(programSetting(program), { description: `The ${program} program: a name on the PATH, or a full path.`, schema: settingSchemas.program, default: program, scopes: ['global'] });
27
+ }
28
+ }
29
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type Channel } from '../browser/channels.ts';
2
+ import type { BrowserChoice } from '../settings.ts';
3
+ /** A started browser. */
4
+ export type Started = {
5
+ close(): Promise<void>;
6
+ };
7
+ /** Starts one channel headless, or rejects when it can't. */
8
+ export type Launch = (channel: Channel) => Promise<Started>;
9
+ export type BrowserReadiness = {
10
+ ready: boolean;
11
+ channel: Channel | null;
12
+ };
13
+ export declare function browserReadiness(choice: BrowserChoice, launch: Launch): Promise<BrowserReadiness>;
14
+ //# sourceMappingURL=browser-readiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-readiness.d.ts","sourceRoot":"","sources":["../../src/setup/browser-readiness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAKpD,yBAAyB;AACzB,MAAM,MAAM,OAAO,GAAG;IAAE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAEjD,6DAA6D;AAC7D,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,CAAC;AAY3E,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAKvG"}
@@ -0,0 +1,16 @@
1
+ import { channelsOf } from "../browser/channels.js";
2
+ async function starts(launch, channel) {
3
+ const browser = await launch(channel).then((started) => started, () => undefined);
4
+ if (browser === undefined)
5
+ return false;
6
+ await browser.close();
7
+ return true;
8
+ }
9
+ export async function browserReadiness(choice, launch) {
10
+ for (const channel of channelsOf(choice)) {
11
+ if (await starts(launch, channel))
12
+ return { ready: true, channel };
13
+ }
14
+ return { ready: false, channel: null };
15
+ }
16
+ //# sourceMappingURL=browser-readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-readiness.js","sourceRoot":"","sources":["../../src/setup/browser-readiness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAgB,MAAM,wBAAwB,CAAC;AAclE,KAAK,UAAU,MAAM,CAAC,MAAc,EAAE,OAAgB;IACpD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CACxC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,EACpB,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;IACF,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxC,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAqB,EAAE,MAAc;IAC1E,KAAK,MAAM,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACzC,IAAI,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACrE,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { ProgramName } from '../settings.ts';
2
+ /** What one program printed with its exit code, or `undefined` when it couldn't run. */
3
+ export type Answer = {
4
+ exitCode: number;
5
+ stdout: string;
6
+ } | undefined;
7
+ /** Runs a program with its arguments, giving it 5 s. */
8
+ export type CheckRun = (program: ProgramName, args: readonly string[]) => Promise<Answer>;
9
+ export type FfmpegReadiness = {
10
+ ready: boolean;
11
+ version: string | null;
12
+ missing: string[];
13
+ };
14
+ /** The names in an `-encoders` or `-filters` listing: each row's second word, after its flags. */
15
+ export declare function listedNames(listing: string): Set<string>;
16
+ /** The version in ffmpeg's first line, `ffmpeg version <version> …`. */
17
+ export declare function versionOf(text: string): string | null;
18
+ export declare function ffmpegReadiness(run: CheckRun): Promise<FfmpegReadiness>;
19
+ //# sourceMappingURL=ffmpeg-readiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ffmpeg-readiness.d.ts","sourceRoot":"","sources":["../../src/setup/ffmpeg-readiness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKlD,wFAAwF;AACxF,MAAM,MAAM,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC;AAEtE,wDAAwD;AACxD,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE1F,MAAM,MAAM,eAAe,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAS5F,kGAAkG;AAClG,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAExD;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGrD;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,CAiB7E"}
@@ -0,0 +1,33 @@
1
+ const encoders = ['libx264', 'aac', 'libmp3lame'];
2
+ const filters = ['subtitles', 'xfade', 'loudnorm', 'afftdn', 'gradients', 'perspective', 'alphamerge', 'drawtext', 'xstack'];
3
+ function succeeded(answer) {
4
+ return answer !== undefined && answer.exitCode === 0;
5
+ }
6
+ /** The names in an `-encoders` or `-filters` listing: each row's second word, after its flags. */
7
+ export function listedNames(listing) {
8
+ return new Set(listing.split('\n').map((line) => line.trim().split(/\s+/)[1]).filter((name) => name !== undefined));
9
+ }
10
+ /** The version in ffmpeg's first line, `ffmpeg version <version> …`. */
11
+ export function versionOf(text) {
12
+ const words = (text.split('\n')[0] ?? '').trim().split(/\s+/);
13
+ return words[0] === 'ffmpeg' && words[1] === 'version' && words[2] !== undefined ? words[2] : null;
14
+ }
15
+ export async function ffmpegReadiness(run) {
16
+ const [version, probe, encoderList, filterList] = await Promise.all([
17
+ run('ffmpeg', ['-hide_banner', '-version']),
18
+ run('ffprobe', ['-hide_banner', '-version']),
19
+ run('ffmpeg', ['-hide_banner', '-encoders']),
20
+ run('ffmpeg', ['-hide_banner', '-filters']),
21
+ ]);
22
+ const ffmpegRuns = succeeded(version);
23
+ const encoderNames = ffmpegRuns && succeeded(encoderList) ? listedNames(encoderList.stdout) : new Set();
24
+ const filterNames = ffmpegRuns && succeeded(filterList) ? listedNames(filterList.stdout) : new Set();
25
+ const missing = [
26
+ ...(ffmpegRuns ? [] : ['ffmpeg']),
27
+ ...(succeeded(probe) ? [] : ['ffprobe']),
28
+ ...encoders.filter((name) => !encoderNames.has(name)),
29
+ ...filters.filter((name) => !filterNames.has(name)),
30
+ ];
31
+ return { ready: missing.length === 0, version: ffmpegRuns ? versionOf(version.stdout) : null, missing };
32
+ }
33
+ //# sourceMappingURL=ffmpeg-readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ffmpeg-readiness.js","sourceRoot":"","sources":["../../src/setup/ffmpeg-readiness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { NarrationService } from '../settings.ts';
2
+ export type NarrationChoice = {
3
+ service: NarrationService | null;
4
+ voice: string | null;
5
+ };
6
+ export type NarrationReadiness = {
7
+ service: NarrationService | null;
8
+ ready: boolean;
9
+ missing: string | null;
10
+ };
11
+ /** The secret a paid service's key is kept in (ADR 0107, 21). */
12
+ export declare const keySecrets: {
13
+ readonly elevenlabs: "elevenlabs.apiKey";
14
+ readonly openai: "openai.apiKey";
15
+ };
16
+ export type NarrationProbe = {
17
+ hasSecret(name: string): Promise<boolean>;
18
+ piperRuns(): Promise<boolean>;
19
+ };
20
+ export declare function narrationReadiness(choice: NarrationChoice, probe: NarrationProbe): Promise<NarrationReadiness>;
21
+ //# sourceMappingURL=narration-readiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narration-readiness.d.ts","sourceRoot":"","sources":["../../src/setup/narration-readiness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAKvD,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEzF,MAAM,MAAM,kBAAkB,GAAG;IAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAE9G,iEAAiE;AACjE,eAAO,MAAM,UAAU;;;CAAwE,CAAC;AAEhG,MAAM,MAAM,cAAc,GAAG;IAAE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC;AAY1G,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAGpH"}
@@ -0,0 +1,18 @@
1
+ /** The secret a paid service's key is kept in (ADR 0107, 21). */
2
+ export const keySecrets = { elevenlabs: 'elevenlabs.apiKey', openai: 'openai.apiKey' };
3
+ async function missingOf(choice, probe) {
4
+ if (choice.service === null)
5
+ return 'kvvideo.narration.service';
6
+ if (choice.service !== 'piper') {
7
+ const secret = keySecrets[choice.service];
8
+ return (await probe.hasSecret(secret)) ? null : secret;
9
+ }
10
+ if (!(await probe.piperRuns()))
11
+ return 'piper';
12
+ return choice.voice === null ? 'kvvideo.narration.voice' : null;
13
+ }
14
+ export async function narrationReadiness(choice, probe) {
15
+ const missing = await missingOf(choice, probe);
16
+ return { service: choice.service, ready: missing === null, missing };
17
+ }
18
+ //# sourceMappingURL=narration-readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narration-readiness.js","sourceRoot":"","sources":["../../src/setup/narration-readiness.ts"],"names":[],"mappings":"AASA,iEAAiE;AACjE,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,EAAE,eAAe,EAAW,CAAC;AAIhG,KAAK,UAAU,SAAS,CAAC,MAAuB,EAAE,KAAqB;IACrE,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI;QAAE,OAAO,2BAA2B,CAAC;IAChE,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1C,OAAO,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACzD,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;QAAE,OAAO,OAAO,CAAC;IAC/C,OAAO,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAuB,EAAE,KAAqB;IACrF,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,EAAE,OAAO,EAAE,CAAC;AACvE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type Ctx } from '@kvman/sdk';
2
+ export declare function registerSetup(ctx: Ctx): void;
3
+ //# sourceMappingURL=register-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-setup.d.ts","sourceRoot":"","sources":["../../src/setup/register-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AA+BzC,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAqB5C"}
@@ -0,0 +1,51 @@
1
+ import { z } from '@kvman/sdk';
2
+ import { launchChannel } from "../browser/launch.js";
3
+ import { programOf } from "../programs/programs.js";
4
+ import { runProgram } from "../programs/run-program.js";
5
+ import { isKvvideoProblem } from "../problems.js";
6
+ import { narrationServices } from "../settings.js";
7
+ import { browserReadiness } from "./browser-readiness.js";
8
+ import { ffmpegReadiness } from "./ffmpeg-readiness.js";
9
+ import { narrationReadiness } from "./narration-readiness.js";
10
+ // `video check` (plan 16 §16.4): what is ready, and what the person still has to install or set. It fails for none of
11
+ // them: a program that can't start, or doesn't answer in 5 s, is reported missing.
12
+ const checkTimeoutMs = 5_000;
13
+ const setupSchema = z.object({
14
+ ffmpeg: z.object({ ready: z.boolean(), version: z.string().nullable(), missing: z.array(z.string()) }),
15
+ browser: z.object({ ready: z.boolean(), channel: z.enum(['chrome', 'msedge']).nullable() }),
16
+ narration: z.object({ service: z.enum(narrationServices).nullable(), ready: z.boolean(), missing: z.string().nullable() }),
17
+ });
18
+ async function answerOf(ctx, name, args) {
19
+ try {
20
+ const run = await runProgram(await programOf(ctx, name), args, { signal: ctx.job.signal, timeoutMs: checkTimeoutMs });
21
+ return run.timedOut ? undefined : { exitCode: run.exitCode, stdout: run.stdout };
22
+ }
23
+ catch (error) {
24
+ if (isKvvideoProblem(error, 'PROGRAM_MISSING'))
25
+ return undefined;
26
+ throw error;
27
+ }
28
+ }
29
+ export function registerSetup(ctx) {
30
+ ctx.registerQuery('kvvideo.setup.get', {
31
+ description: 'Tells what is ready to make videos: ffmpeg, the installed browser, and narration, and what is missing.',
32
+ input: z.object({}),
33
+ output: setupSchema,
34
+ public: true,
35
+ timeoutMs: 60_000,
36
+ handle: async () => {
37
+ const run = (name, args) => answerOf(ctx, name, args);
38
+ const choice = { service: await ctx.settings.get('kvvideo.narration.service'), voice: await ctx.settings.get('kvvideo.narration.voice') };
39
+ const [ffmpeg, browser, narration] = await Promise.all([
40
+ ffmpegReadiness(run),
41
+ browserReadiness(await ctx.settings.get('kvvideo.browser'), launchChannel),
42
+ narrationReadiness(choice, {
43
+ hasSecret: async (name) => (await ctx.secrets.get(name)) !== undefined,
44
+ piperRuns: async () => (await run('piper', ['--help']))?.exitCode === 0,
45
+ }),
46
+ ]);
47
+ return { ffmpeg, browser, narration };
48
+ },
49
+ });
50
+ }
51
+ //# sourceMappingURL=register-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-setup.js","sourceRoot":"","sources":["../../src/setup/register-setup.ts"],"names":[],"mappings":"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"}
package/dist/ui.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { type Ctx } from '@kvman/sdk';
2
+ export declare function registerUi(ctx: Ctx): void;
3
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAqBzC,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAQzC"}
package/dist/ui.js ADDED
@@ -0,0 +1,26 @@
1
+ import { z } from '@kvman/sdk';
2
+ // kvvideo's configuration on its extension page (plan 16 §16.2): four cards of setting rows, and nothing else. The
3
+ // keys' secrets are added in the page's own Secrets section (plan 06 §6.6).
4
+ const settings = (keys) => keys.map((key) => ({ type: 'setting', key }));
5
+ const configuration = {
6
+ type: 'stack',
7
+ direction: 'vertical',
8
+ gap: 'md',
9
+ children: [
10
+ { type: 'card', title: 'kvvideo.config.narration', children: settings(['kvvideo.narration.service', 'kvvideo.narration.voice', 'kvvideo.narration.model', 'kvvideo.narration.pronunciations']) },
11
+ { type: 'card', title: 'kvvideo.config.brand', children: settings(['kvvideo.brand']) },
12
+ { type: 'card', title: 'kvvideo.config.recording', children: settings(['kvvideo.browser']) },
13
+ { type: 'card', title: 'kvvideo.config.programs', children: settings(['kvvideo.programs.ffmpeg', 'kvvideo.programs.ffprobe', 'kvvideo.programs.piper']) },
14
+ ],
15
+ };
16
+ const contributionsSchema = z.object({ pages: z.array(z.json()), nav: z.array(z.json()), panels: z.array(z.json()), status: z.array(z.json()), configuration: z.json() });
17
+ export function registerUi(ctx) {
18
+ ctx.registerQuery('kvvideo.ui.get', {
19
+ description: "Gives kvvideo's UI: its configuration on its extension page.",
20
+ input: z.object({}),
21
+ output: contributionsSchema,
22
+ public: true,
23
+ handle: () => ({ pages: [], nav: [], panels: [], status: [], configuration }),
24
+ });
25
+ }
26
+ //# sourceMappingURL=ui.js.map
package/dist/ui.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAY,MAAM,YAAY,CAAC;AAEzC,mHAAmH;AACnH,4EAA4E;AAE5E,MAAM,QAAQ,GAAG,CAAC,IAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAE5F,MAAM,aAAa,GAAG;IACpB,IAAI,EAAE,OAAO;IACb,SAAS,EAAE,UAAU;IACrB,GAAG,EAAE,IAAI;IACT,QAAQ,EAAE;QACR,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,0BAA0B,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,2BAA2B,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,kCAAkC,CAAC,CAAC,EAAE;QAChM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC,EAAE;QACtF,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,0BAA0B,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE;QAC5F,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,yBAAyB,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,yBAAyB,EAAE,0BAA0B,EAAE,wBAAwB,CAAC,CAAC,EAAE;KAC1J;CACF,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAE1K,MAAM,UAAU,UAAU,CAAC,GAAQ;IACjC,GAAG,CAAC,aAAa,CAAC,gBAAgB,EAAE;QAClC,WAAW,EAAE,8DAA8D;QAC3E,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACnB,MAAM,EAAE,mBAAmB;QAC3B,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC;KAC9E,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type Ctx } from '@kvman/sdk';
2
+ export declare function registerVideoStart(ctx: Ctx): void;
3
+ //# sourceMappingURL=video-start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-start.d.ts","sourceRoot":"","sources":["../src/video-start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAUzC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAmBjD"}
@@ -0,0 +1,28 @@
1
+ import { z } from '@kvman/sdk';
2
+ import { connectorName } from "./connector.js";
3
+ import { readGuide } from "./guide.js";
4
+ // `/video` (plan 16 §16.1): the person starts making videos in a chat. The connector is enabled first, then the guide;
5
+ // the note is added the first time only, known by the guide section being there already.
6
+ const owner = '@kvman/kvvideo';
7
+ export function registerVideoStart(ctx) {
8
+ ctx.registerCommand('kvvideo.video.start', {
9
+ description: "Starts making videos in one chat: gives the chat kvvideo's connector and guide.",
10
+ public: true,
11
+ retries: 0,
12
+ input: z.object({
13
+ sessionId: z.string().min(1).describe('The chat to make videos in.'),
14
+ argument: z.string().describe('The text after /video; the send box sends it as the message.'),
15
+ }),
16
+ output: z.object({}),
17
+ handle: async ({ sessionId }) => {
18
+ await ctx.exec('kvcoder.connector.enable', { sessionId, names: [connectorName] });
19
+ const sections = await ctx.exec('kvcoder.section.list', { sessionId });
20
+ const started = sections.some((section) => section.id === 'guide' && section.owner === owner && section.sessionId === sessionId);
21
+ await ctx.exec('kvcoder.section.set', { id: 'guide', title: 'Making videos', order: 30, sessionId, content: readGuide() });
22
+ if (!started)
23
+ await ctx.exec('kvcoder.note.add', { sessionId, key: 'kvvideo.video.started' });
24
+ return {};
25
+ },
26
+ });
27
+ }
28
+ //# sourceMappingURL=video-start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-start.js","sourceRoot":"","sources":["../src/video-start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAY,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,uHAAuH;AACvH,yFAAyF;AAEzF,MAAM,KAAK,GAAG,gBAAgB,CAAC;AAE/B,MAAM,UAAU,kBAAkB,CAAC,GAAQ;IACzC,GAAG,CAAC,eAAe,CAAC,qBAAqB,EAAE;QACzC,WAAW,EAAE,iFAAiF;QAC9F,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;YACd,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YACpE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC;SAC9F,CAAC;QACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACpB,MAAM,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;YAC9B,MAAM,GAAG,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAClF,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;YACvE,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,OAAO,IAAI,OAAO,CAAC,KAAK,KAAK,KAAK,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;YACjI,MAAM,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;YAC3H,IAAI,CAAC,OAAO;gBAAE,MAAM,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,uBAAuB,EAAE,CAAC,CAAC;YAC9F,OAAO,EAAE,CAAC;QACZ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ .kvvideo-player{padding:var(--kv-space-sm);border:1px solid var(--kv-color-border);border-radius:var(--kv-radius);background:var(--kv-color-surface);max-inline-size:640px;margin:0}.kvvideo-player-head{gap:var(--kv-space-sm);color:var(--kv-color-muted);justify-content:space-between;padding-block-end:var(--kv-space-sm);font-size:.85em;display:flex}.kvvideo-player-file{text-overflow:ellipsis;white-space:nowrap;font-family:var(--kv-font-mono);overflow:hidden}.kvvideo-player-video{border-radius:calc(var(--kv-radius) / 2);background:#000;max-block-size:360px;inline-size:100%;display:block}.kvvideo-player-unavailable{color:var(--kv-color-text);margin:0}.kvvideo-player-others{color:var(--kv-color-muted);font-family:var(--kv-font-mono);margin:0;padding-block-start:var(--kv-space-sm);padding-inline-start:0;font-size:.85em;list-style:none}
2
+ /*$vite$:1*/