@hypit/hypit 0.1.4 → 0.1.6

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 (462) hide show
  1. package/README.md +4 -2
  2. package/dist/public/caption.d.ts +206 -183
  3. package/dist/public/composition.d.ts +25 -3
  4. package/dist/public/endpoint-kit.d.ts +24 -2
  5. package/dist/public/generation.d.ts +5 -1
  6. package/dist/public/hyperframes.d.ts +19 -1
  7. package/dist/public/narrative.d.ts +17 -3
  8. package/dist/public/performance.d.ts +1590 -0
  9. package/dist/public/program-space.d.ts +179 -32
  10. package/dist/public/runtime-kit.d.ts +21 -8
  11. package/dist/public/sound.d.ts +822 -0
  12. package/dist/public/speech.d.ts +41 -0
  13. package/dist/public/studio-adapter.d.ts +77 -15
  14. package/dist/public/temporal-markup.d.ts +9 -44
  15. package/dist/public/temporal.d.ts +37 -28
  16. package/dist/public/{semantic-track.d.ts → timeline.d.ts} +62 -49
  17. package/examples/README.md +18 -10
  18. package/examples/minimal-author-package/packages/example-component/preview/preview.svml +19 -12
  19. package/examples/minimal-author-package/packages/example-component/src/component.ts +5 -5
  20. package/examples/minimal-author-package/packages/example-component/src/fragment.ts +3 -5
  21. package/examples/minimal-author-package/packages/example-component/src/manifest.ts +8 -10
  22. package/examples/minimal-author-package/packages/example-component/src/surface.ts +2 -2
  23. package/examples/provider-package/README.md +78 -0
  24. package/examples/provider-package/hypit.runtime.json +12 -0
  25. package/examples/provider-package/packages/provider-images/package.json +11 -0
  26. package/examples/provider-package/packages/provider-images/src/activation.ts +24 -0
  27. package/examples/provider-package/packages/provider-images/src/provider.ts +122 -0
  28. package/examples/provider-package/packages/provider-images/tsconfig.json +9 -0
  29. package/examples/semantic-composition/README.md +8 -1
  30. package/examples/semantic-composition/chat.svml +6 -5
  31. package/examples/semantic-composition/hypit.runtime.json +1 -1
  32. package/examples/semantic-composition/packages/chat-scene/README.md +3 -3
  33. package/examples/semantic-composition/packages/chat-scene/src/activation.ts +18 -21
  34. package/examples/semantic-composition/packages/chat-scene/src/render.ts +4 -4
  35. package/examples/semantic-composition/packages/performance-styles/README.md +42 -0
  36. package/examples/semantic-composition/packages/performance-styles/package.json +25 -0
  37. package/examples/semantic-composition/packages/performance-styles/src/activation.ts +57 -0
  38. package/examples/semantic-composition/packages/performance-styles/src/render.ts +54 -0
  39. package/examples/semantic-composition/packages/performance-styles/src/studio.ts +28 -0
  40. package/examples/semantic-composition/packages/performance-styles/tsconfig.json +18 -0
  41. package/examples/semantic-composition/packages/responsive-explainer/README.md +16 -9
  42. package/examples/semantic-composition/packages/responsive-explainer/src/activation.ts +12 -12
  43. package/examples/semantic-composition/packages/responsive-explainer/src/render.ts +5 -5
  44. package/examples/semantic-composition/packages/sound-styles/README.md +36 -0
  45. package/examples/semantic-composition/packages/sound-styles/package.json +25 -0
  46. package/examples/semantic-composition/packages/sound-styles/src/activation.ts +53 -0
  47. package/examples/semantic-composition/packages/sound-styles/src/render.ts +14 -0
  48. package/examples/semantic-composition/packages/sound-styles/tsconfig.json +18 -0
  49. package/package.json +35 -15
  50. package/packages/audio-track/README.md +20 -13
  51. package/packages/audio-track/package.json +1 -1
  52. package/packages/audio-track/src/component.ts +4 -4
  53. package/packages/audio-track/src/fragment.ts +6 -5
  54. package/packages/audio-track/src/index.ts +1 -1
  55. package/packages/audio-track/src/manifest.ts +17 -16
  56. package/packages/audio-track/src/program.ts +21 -25
  57. package/packages/audio-track/src/surface.ts +19 -18
  58. package/packages/audio-track-studio/README.md +23 -0
  59. package/packages/audio-track-studio/src/index.ts +28 -17
  60. package/packages/author-kit/README.md +1 -1
  61. package/packages/background-removal/README.md +4 -7
  62. package/packages/browser-capture/package.json +1 -1
  63. package/packages/build-result/README.md +11 -0
  64. package/packages/build-result/src/decode.ts +2 -0
  65. package/packages/build-result/src/execution-log.ts +17 -0
  66. package/packages/build-result/src/index.ts +1 -0
  67. package/packages/build-result/src/store.ts +14 -1
  68. package/packages/build-result/src/types.ts +3 -0
  69. package/packages/build-result-s3/src/repository.ts +4 -0
  70. package/packages/caption/README.md +61 -73
  71. package/packages/caption/package.json +3 -2
  72. package/packages/caption/src/activation.ts +2 -2
  73. package/packages/caption/src/component.ts +20 -5
  74. package/packages/caption/src/display.ts +3 -18
  75. package/packages/caption/src/fragment.ts +3 -7
  76. package/packages/caption/src/index.ts +6 -5
  77. package/packages/caption/src/manifest.ts +29 -46
  78. package/packages/caption/src/style.ts +24 -135
  79. package/packages/caption/src/surface.ts +12 -92
  80. package/packages/caption/src/temporalize.ts +18 -53
  81. package/packages/caption/src/types.ts +8 -35
  82. package/packages/caption/src/visibility.ts +23 -0
  83. package/packages/caption-fine/README.md +21 -9
  84. package/packages/caption-fine/package.json +4 -2
  85. package/packages/caption-fine/src/component.ts +3 -3
  86. package/packages/caption-fine/src/fragment.ts +7 -19
  87. package/packages/caption-fine/src/index.ts +2 -0
  88. package/packages/caption-fine/src/manifest.ts +26 -17
  89. package/packages/caption-fine/src/recipe.ts +7 -0
  90. package/packages/caption-fine/src/render.ts +14 -13
  91. package/packages/caption-fine/src/schedule.ts +39 -35
  92. package/packages/caption-fine/src/style.ts +10 -9
  93. package/packages/caption-fine/src/surface.ts +62 -35
  94. package/packages/caption-fine/src/types.ts +2 -0
  95. package/packages/caption-fine-studio/README.md +24 -2
  96. package/packages/caption-fine-studio/package.json +3 -1
  97. package/packages/caption-fine-studio/src/activation.ts +3 -3
  98. package/packages/caption-fine-studio/src/index.ts +54 -42
  99. package/packages/cli/README.md +57 -4
  100. package/packages/cli/package.json +1 -0
  101. package/packages/cli/src/arguments.ts +25 -6
  102. package/packages/cli/src/build-planning.ts +3 -2
  103. package/packages/cli/src/command.ts +6 -0
  104. package/packages/cli/src/commands/environment.ts +28 -18
  105. package/packages/cli/src/commands/execution.ts +81 -26
  106. package/packages/cli/src/commands/results.ts +7 -11
  107. package/packages/cli/src/index.ts +2 -2
  108. package/packages/cli/src/machine-view.ts +3 -2
  109. package/packages/cli/src/main.ts +34 -42
  110. package/packages/cli/src/observation.ts +7 -1
  111. package/packages/cli/src/output.ts +65 -23
  112. package/packages/cli/src/view.ts +66 -19
  113. package/packages/comment-sticker/README.md +3 -3
  114. package/packages/comment-sticker/package.json +1 -1
  115. package/packages/comment-sticker/src/component.ts +4 -4
  116. package/packages/comment-sticker/src/fragment.ts +5 -4
  117. package/packages/comment-sticker/src/manifest.ts +7 -6
  118. package/packages/comment-sticker/src/program.ts +9 -9
  119. package/packages/comment-sticker/src/surface.ts +6 -7
  120. package/packages/composition/README.md +21 -0
  121. package/packages/composition/src/audio-presentation.ts +44 -0
  122. package/packages/composition/src/index.ts +3 -0
  123. package/packages/composition/src/schema.ts +8 -3
  124. package/packages/composition/src/track.ts +15 -1
  125. package/packages/credential-store-env/README.md +1 -1
  126. package/packages/deck-track/README.md +3 -3
  127. package/packages/deck-track/package.json +1 -1
  128. package/packages/deck-track/src/component.ts +5 -5
  129. package/packages/deck-track/src/fragment.ts +6 -5
  130. package/packages/deck-track/src/lower.ts +12 -12
  131. package/packages/deck-track/src/manifest.ts +8 -7
  132. package/packages/deck-track/src/program.ts +13 -16
  133. package/packages/deck-track/src/surface.ts +9 -10
  134. package/packages/driver-node/src/driver.ts +41 -3
  135. package/packages/elevenlabs-speech/README.md +27 -0
  136. package/packages/{provider-xiaomi-mimo → elevenlabs-speech}/package.json +5 -8
  137. package/packages/elevenlabs-speech/src/activation.ts +26 -0
  138. package/packages/elevenlabs-speech/src/fragment.ts +11 -0
  139. package/packages/elevenlabs-speech/src/index.ts +111 -0
  140. package/packages/elevenlabs-speech/src/surface.ts +167 -0
  141. package/packages/endpoint-kit/README.md +24 -0
  142. package/packages/endpoint-kit/src/index.ts +7 -1
  143. package/packages/film/README.md +12 -7
  144. package/packages/film/package.json +1 -1
  145. package/packages/film/src/component.ts +4 -4
  146. package/packages/film/src/fragment.ts +6 -5
  147. package/packages/film/src/manifest.ts +11 -10
  148. package/packages/film/src/program.ts +5 -5
  149. package/packages/film/src/recipe.ts +2 -1
  150. package/packages/film/src/surface.ts +10 -7
  151. package/packages/film-studio/package.json +1 -1
  152. package/packages/film-studio/src/index.ts +2 -2
  153. package/packages/fishaudio-speech/README.md +33 -0
  154. package/packages/fishaudio-speech/package.json +21 -0
  155. package/packages/fishaudio-speech/src/activation.ts +32 -0
  156. package/packages/fishaudio-speech/src/fragment.ts +11 -0
  157. package/packages/fishaudio-speech/src/index.ts +156 -0
  158. package/packages/fishaudio-speech/src/surface.ts +192 -0
  159. package/packages/generation/README.md +11 -1
  160. package/packages/generation/src/mapping.ts +28 -30
  161. package/packages/gpt-image/README.md +1 -2
  162. package/packages/grok-imagine/README.md +1 -2
  163. package/packages/hyperframes/README.md +7 -3
  164. package/packages/hyperframes/src/browser-program.ts +11 -2
  165. package/packages/hyperframes/src/document.ts +15 -2
  166. package/packages/interview-emoji-reveal/README.md +4 -4
  167. package/packages/interview-emoji-reveal/package.json +1 -1
  168. package/packages/interview-emoji-reveal/src/component.ts +4 -4
  169. package/packages/interview-emoji-reveal/src/fragment.ts +6 -5
  170. package/packages/interview-emoji-reveal/src/manifest.ts +9 -8
  171. package/packages/interview-emoji-reveal/src/program.ts +14 -14
  172. package/packages/interview-emoji-reveal/src/surface.ts +8 -9
  173. package/packages/media-execution/README.md +7 -3
  174. package/packages/media-execution/src/audio-presentation.ts +23 -0
  175. package/packages/media-execution/src/execute.ts +2 -0
  176. package/packages/media-pipeline/README.md +7 -3
  177. package/packages/media-pipeline/src/audio-plan.ts +4 -1
  178. package/packages/media-pipeline/src/component.ts +16 -2
  179. package/packages/media-pipeline/src/manifest.ts +3 -1
  180. package/packages/media-pipeline/src/types.ts +2 -1
  181. package/packages/media-track/README.md +14 -47
  182. package/packages/media-track/package.json +1 -1
  183. package/packages/media-track/preview/preview.svml +5 -5
  184. package/packages/media-track/src/author.ts +12 -6
  185. package/packages/media-track/src/component.ts +10 -16
  186. package/packages/media-track/src/fragment.ts +8 -7
  187. package/packages/media-track/src/index.ts +3 -1
  188. package/packages/media-track/src/lower.ts +7 -7
  189. package/packages/media-track/src/manifest.ts +16 -38
  190. package/packages/media-track/src/program.ts +62 -67
  191. package/packages/media-track/src/sampling.ts +6 -6
  192. package/packages/media-track/src/sequence.ts +8 -8
  193. package/packages/media-track/src/surface.ts +25 -43
  194. package/packages/media-track-studio/README.md +9 -0
  195. package/packages/media-track-studio/src/index.ts +16 -11
  196. package/packages/mimo-speech/README.md +1 -1
  197. package/packages/minimax-h3/README.md +1 -1
  198. package/packages/nano-banana/README.md +1 -1
  199. package/packages/narrative/README.md +23 -1
  200. package/packages/narrative/src/identity.ts +11 -0
  201. package/packages/narrative/src/index.ts +3 -0
  202. package/packages/narrative/src/schema.ts +28 -27
  203. package/packages/narrative/src/selection.ts +52 -0
  204. package/packages/narrative/src/types.ts +2 -0
  205. package/packages/package-loader-node/README.md +30 -0
  206. package/packages/package-loader-node/package.json +5 -2
  207. package/packages/package-loader-node/src/distribution-resolution.ts +10 -3
  208. package/packages/package-loader-node/src/index.ts +1 -0
  209. package/packages/package-loader-node/src/loader.ts +12 -15
  210. package/packages/package-loader-node/src/location.ts +27 -1
  211. package/packages/package-loader-node/src/module-scope.ts +183 -0
  212. package/packages/package-loader-node/src/types.ts +4 -0
  213. package/packages/performance/README.md +83 -0
  214. package/packages/performance/package.json +30 -0
  215. package/packages/performance/src/activation.ts +11 -0
  216. package/packages/performance/src/component.ts +46 -0
  217. package/packages/performance/src/index.ts +6 -0
  218. package/packages/performance/src/manifest.ts +53 -0
  219. package/packages/{media-track/src/performance.ts → performance/src/media.ts} +9 -10
  220. package/packages/performance/src/program.ts +51 -0
  221. package/packages/performance/src/style.ts +35 -0
  222. package/packages/performance/src/surface.ts +99 -0
  223. package/packages/performance-studio/README.md +25 -0
  224. package/packages/performance-studio/package.json +21 -0
  225. package/packages/performance-studio/src/activation.ts +6 -0
  226. package/packages/performance-studio/src/index.ts +84 -0
  227. package/packages/program-space/README.md +9 -18
  228. package/packages/program-space/src/activation.ts +1 -5
  229. package/packages/program-space/src/index.ts +2 -11
  230. package/packages/program-space/src/surface.ts +1 -20
  231. package/packages/project-context-node/README.md +20 -0
  232. package/packages/project-context-node/package.json +10 -0
  233. package/packages/project-context-node/src/index.ts +3 -0
  234. package/packages/{cli → project-context-node}/src/runtime-selection.ts +7 -2
  235. package/packages/provider-hyperframes-local/README.md +43 -15
  236. package/packages/provider-hyperframes-local/src/activation.ts +4 -3
  237. package/packages/provider-hyperframes-local/src/capture-process.ts +26 -4
  238. package/packages/provider-hyperframes-local/src/capture.ts +96 -26
  239. package/packages/provider-hyperframes-local/src/concurrency.ts +86 -0
  240. package/packages/provider-hyperframes-local/src/opaque-capture.ts +92 -0
  241. package/packages/provider-hyperframes-local/src/options.ts +2 -0
  242. package/packages/provider-hyperframes-local/src/program.ts +6 -3
  243. package/packages/provider-hyperframes-local/src/progress.ts +53 -0
  244. package/packages/provider-hyperframes-local/src/provider.ts +18 -5
  245. package/packages/provider-hyperframes-local/src/render.ts +48 -7
  246. package/packages/provider-hypihub/README.md +48 -17
  247. package/packages/provider-hypihub/package.json +2 -0
  248. package/packages/provider-hypihub/src/mapping.ts +31 -7
  249. package/packages/provider-hypihub/src/oauth.ts +6 -0
  250. package/packages/provider-hypihub/src/provider.ts +25 -13
  251. package/packages/provider-hypihub/src/routes.ts +1 -2
  252. package/packages/provider-hypihub/src/upload.ts +2 -0
  253. package/packages/provider-media-local/README.md +3 -4
  254. package/packages/provider-whisperx-local/src/program.ts +1 -0
  255. package/packages/provider-whisperx-local/src/provider.ts +3 -0
  256. package/packages/ranking/README.md +8 -6
  257. package/packages/ranking/package.json +1 -1
  258. package/packages/ranking/src/component.ts +6 -6
  259. package/packages/ranking/src/fragment.ts +11 -7
  260. package/packages/ranking/src/manifest.ts +21 -14
  261. package/packages/ranking/src/render.ts +22 -26
  262. package/packages/ranking/src/schedule.ts +16 -19
  263. package/packages/ranking/src/surface.ts +12 -13
  264. package/packages/ranking-studio/README.md +18 -0
  265. package/packages/ranking-studio/src/index.ts +61 -9
  266. package/packages/render-hyperframes/README.md +7 -7
  267. package/packages/render-hyperframes/package.json +1 -1
  268. package/packages/render-hyperframes/src/component.ts +11 -1
  269. package/packages/render-hyperframes/src/fragment.ts +7 -4
  270. package/packages/render-hyperframes/src/manifest.ts +4 -4
  271. package/packages/render-hyperframes/src/surface.ts +6 -6
  272. package/packages/runtime/README.md +8 -1
  273. package/packages/runtime/src/execution.ts +15 -4
  274. package/packages/runtime/src/index.ts +2 -1
  275. package/packages/runtime/src/log.ts +51 -0
  276. package/packages/runtime/src/types.ts +5 -8
  277. package/packages/runtime-host-node/README.md +30 -0
  278. package/packages/runtime-host-node/package.json +1 -0
  279. package/packages/runtime-host-node/src/index.ts +24 -9
  280. package/packages/runtime-host-node/src/packages.ts +47 -50
  281. package/packages/runtime-kit/README.md +5 -0
  282. package/packages/runtime-kit/src/index.ts +3 -1
  283. package/packages/runtime-local/README.md +109 -4
  284. package/packages/runtime-local/src/config.ts +202 -56
  285. package/packages/runtime-local/src/control.ts +9 -1
  286. package/packages/runtime-local/src/executor.ts +66 -0
  287. package/packages/runtime-local/src/host.ts +37 -17
  288. package/packages/runtime-local/src/log.ts +48 -0
  289. package/packages/runtime-local/src/programs.ts +2 -1
  290. package/packages/runtime-local/src/result-writer.ts +2 -0
  291. package/packages/runtime-local/src/runtime.ts +8 -6
  292. package/packages/runtime-local/src/supervisor.ts +142 -0
  293. package/packages/runtime-local/src/types.ts +9 -2
  294. package/packages/runtime-local/src/worker-process.ts +7 -24
  295. package/packages/runtime-local/src/worker.ts +55 -83
  296. package/packages/screen-overlay/README.md +3 -3
  297. package/packages/screen-overlay/package.json +1 -1
  298. package/packages/screen-overlay/src/component.ts +3 -3
  299. package/packages/screen-overlay/src/fragment.ts +5 -4
  300. package/packages/screen-overlay/src/manifest.ts +7 -6
  301. package/packages/screen-overlay/src/program.ts +9 -9
  302. package/packages/screen-overlay/src/surface.ts +6 -7
  303. package/packages/script/README.md +30 -5
  304. package/packages/script/src/manifest.ts +4 -3
  305. package/packages/script/src/narrative.ts +1 -0
  306. package/packages/script/src/parser.ts +45 -6
  307. package/packages/script/src/surface.ts +4 -3
  308. package/packages/script/src/types.ts +1 -1
  309. package/packages/script-studio/package.json +9 -3
  310. package/packages/script-studio/src/index.ts +2 -0
  311. package/packages/script-studio/src/projection.ts +105 -0
  312. package/packages/seedance/README.md +30 -1
  313. package/packages/seedance/src/index.ts +18 -7
  314. package/packages/seedance/src/surface.ts +17 -4
  315. package/packages/seedance-kits/README.md +7 -1
  316. package/packages/seedream/README.md +1 -1
  317. package/packages/sound/README.md +81 -0
  318. package/packages/sound/package.json +25 -0
  319. package/packages/sound/src/activation.ts +11 -0
  320. package/packages/sound/src/component.ts +28 -0
  321. package/packages/sound/src/index.ts +5 -0
  322. package/packages/sound/src/manifest.ts +47 -0
  323. package/packages/sound/src/program.ts +84 -0
  324. package/packages/sound/src/style.ts +34 -0
  325. package/packages/sound/src/surface.ts +90 -0
  326. package/packages/sound-studio/README.md +22 -0
  327. package/packages/sound-studio/package.json +20 -0
  328. package/packages/sound-studio/src/activation.ts +6 -0
  329. package/packages/sound-studio/src/index.ts +74 -0
  330. package/packages/speech/README.md +2 -2
  331. package/packages/speech-alignment/src/local.ts +8 -0
  332. package/packages/speech-alignment/src/locate.ts +1 -1
  333. package/packages/store-sqlite/README.md +7 -0
  334. package/packages/store-sqlite/src/store.ts +84 -83
  335. package/packages/studio/INSPECTOR.md +15 -2
  336. package/packages/studio/LOCALIZATION.md +98 -0
  337. package/packages/studio/README.md +101 -14
  338. package/packages/studio/locales/en.json +197 -0
  339. package/packages/studio/locales/zh-CN.json +191 -0
  340. package/packages/studio/package.json +8 -7
  341. package/packages/studio/src/companion-assembly.ts +1 -0
  342. package/packages/studio/src/domain.ts +1 -1
  343. package/packages/studio/src/fallback-companions.ts +3 -3
  344. package/packages/studio/src/feedback-server.ts +51 -0
  345. package/packages/studio/src/feedback-store.ts +66 -0
  346. package/packages/studio/src/feedback.ts +60 -0
  347. package/packages/studio/src/localization-node.ts +46 -0
  348. package/packages/studio/src/localization.ts +85 -0
  349. package/packages/studio/src/parameter-values.ts +43 -1
  350. package/packages/studio/src/parameters.ts +114 -24
  351. package/packages/studio/src/preview/render.ts +5 -1
  352. package/packages/studio/src/preview/runtime-shim.ts +49 -3
  353. package/packages/studio/src/programme.ts +14 -30
  354. package/packages/studio/src/server.ts +10 -6
  355. package/packages/studio/src/shared.ts +4 -2
  356. package/packages/studio/src/snapshot.ts +21 -132
  357. package/packages/studio/src/studio-preflight.ts +3 -3
  358. package/packages/studio/src/studio-registry.ts +50 -6
  359. package/packages/studio/src/style.css +223 -50
  360. package/packages/studio/src/ui/artifact-name.ts +8 -6
  361. package/packages/studio/src/ui/artifact-preview.ts +5 -4
  362. package/packages/studio/src/ui/code.ts +17 -16
  363. package/packages/studio/src/ui/comments.ts +234 -0
  364. package/packages/studio/src/ui/dropdown.ts +68 -0
  365. package/packages/studio/src/ui/i18n.ts +109 -0
  366. package/packages/studio/src/ui/icons.ts +6 -0
  367. package/packages/studio/src/ui/library.ts +76 -65
  368. package/packages/studio/src/ui/main.ts +223 -211
  369. package/packages/studio/src/ui/overlay.ts +12 -8
  370. package/packages/studio/src/ui/scrub-preview.ts +110 -0
  371. package/packages/studio/src/ui/stage.ts +93 -29
  372. package/packages/studio/src/ui/timeline.ts +190 -118
  373. package/packages/studio/start.ts +41 -22
  374. package/packages/studio-adapter/README.md +130 -11
  375. package/packages/studio-adapter/src/index.ts +100 -13
  376. package/packages/temporal/README.md +6 -6
  377. package/packages/temporal/package.json +1 -1
  378. package/packages/temporal/src/component.ts +5 -6
  379. package/packages/temporal/src/index.ts +8 -6
  380. package/packages/temporal/src/location.ts +11 -11
  381. package/packages/temporal/src/projection.ts +19 -19
  382. package/packages/temporal/src/rational.ts +4 -4
  383. package/packages/temporal-markup/EDITING.md +2 -2
  384. package/packages/temporal-markup/README.md +27 -11
  385. package/packages/temporal-markup/package.json +1 -1
  386. package/packages/temporal-markup/src/index.ts +20 -25
  387. package/packages/temporal-markup/src/space.ts +10 -41
  388. package/packages/timeline/README.md +31 -0
  389. package/packages/{semantic-track → timeline}/package.json +1 -1
  390. package/packages/timeline/src/activation.ts +8 -0
  391. package/packages/timeline/src/component.ts +24 -0
  392. package/packages/timeline/src/identity.ts +60 -0
  393. package/packages/timeline/src/index.ts +6 -0
  394. package/packages/{semantic-track → timeline}/src/location.ts +20 -20
  395. package/packages/timeline/src/manifest.ts +39 -0
  396. package/packages/{semantic-track → timeline}/src/projection.ts +14 -14
  397. package/packages/timeline/src/types.ts +24 -0
  398. package/packages/timeline-author/README.md +68 -0
  399. package/packages/{speech-track → timeline-author}/package.json +6 -4
  400. package/packages/timeline-author/src/activation.ts +22 -0
  401. package/packages/{speech-track → timeline-author}/src/component.ts +15 -13
  402. package/packages/{speech-track → timeline-author}/src/fragment.ts +14 -23
  403. package/packages/timeline-author/src/index.ts +7 -0
  404. package/packages/timeline-author/src/manifest.ts +78 -0
  405. package/packages/timeline-author/src/program.ts +107 -0
  406. package/packages/timeline-author/src/surface.ts +46 -0
  407. package/packages/timeline-author/src/types.ts +6 -0
  408. package/packages/typography-track/README.md +4 -4
  409. package/packages/typography-track/package.json +1 -1
  410. package/packages/typography-track/src/component.ts +4 -4
  411. package/packages/typography-track/src/fragment.ts +4 -3
  412. package/packages/typography-track/src/manifest.ts +11 -9
  413. package/packages/typography-track/src/program.ts +15 -15
  414. package/packages/typography-track/src/surface.ts +17 -18
  415. package/packages/video-cli/README.md +4 -1
  416. package/packages/video-cli/package.json +2 -1
  417. package/packages/video-cli/src/creation.ts +14 -4
  418. package/packages/video-cli/src/index.ts +1 -1
  419. package/packages/video-cli/src/studio-distribution.ts +2 -1
  420. package/packages/volcengine-matting/README.md +3 -3
  421. package/packages/whisperx/README.md +1 -1
  422. package/services/whisperx/README.md +14 -0
  423. package/services/whisperx/pyproject.toml +2 -0
  424. package/services/whisperx/uv.lock +20 -20
  425. package/packages/provider-hyperframes-aws-lambda/README.md +0 -30
  426. package/packages/provider-hyperframes-aws-lambda/package.json +0 -30
  427. package/packages/provider-hyperframes-aws-lambda/src/activation.ts +0 -97
  428. package/packages/provider-hyperframes-aws-lambda/src/client.ts +0 -114
  429. package/packages/provider-hyperframes-aws-lambda/src/index.ts +0 -21
  430. package/packages/provider-hyperframes-aws-lambda/src/provider.ts +0 -522
  431. package/packages/provider-kie/README.md +0 -134
  432. package/packages/provider-kie/package.json +0 -43
  433. package/packages/provider-kie/src/activation.ts +0 -71
  434. package/packages/provider-kie/src/index.ts +0 -10
  435. package/packages/provider-kie/src/mapping.ts +0 -182
  436. package/packages/provider-kie/src/provider.ts +0 -657
  437. package/packages/provider-kie/src/routes.ts +0 -150
  438. package/packages/provider-xiaomi-mimo/README.md +0 -32
  439. package/packages/provider-xiaomi-mimo/src/activation.ts +0 -57
  440. package/packages/provider-xiaomi-mimo/src/index.ts +0 -5
  441. package/packages/provider-xiaomi-mimo/src/provider.ts +0 -214
  442. package/packages/runtime/src/environment.ts +0 -6
  443. package/packages/semantic-track/README.md +0 -21
  444. package/packages/semantic-track/src/activation.ts +0 -8
  445. package/packages/semantic-track/src/component.ts +0 -24
  446. package/packages/semantic-track/src/identity.ts +0 -58
  447. package/packages/semantic-track/src/index.ts +0 -6
  448. package/packages/semantic-track/src/manifest.ts +0 -38
  449. package/packages/semantic-track/src/types.ts +0 -26
  450. package/packages/speech-track/README.md +0 -51
  451. package/packages/speech-track/src/activation.ts +0 -19
  452. package/packages/speech-track/src/index.ts +0 -7
  453. package/packages/speech-track/src/manifest.ts +0 -73
  454. package/packages/speech-track/src/program.ts +0 -64
  455. package/packages/speech-track/src/surface.ts +0 -35
  456. package/packages/speech-track/src/types.ts +0 -6
  457. package/packages/speech-track-studio/README.md +0 -3
  458. package/packages/speech-track-studio/package.json +0 -14
  459. package/packages/speech-track-studio/src/activation.ts +0 -7
  460. package/packages/speech-track-studio/src/index.ts +0 -40
  461. /package/packages/{cli → project-context-node}/src/project-context.ts +0 -0
  462. /package/packages/{speech-track → timeline-author}/preview/Track.png +0 -0
@@ -20,6 +20,7 @@ export type Overlay = {
20
20
  readonly element: SVGSVGElement;
21
21
  /** The topmost clip drawn at a point, in client coordinates. */
22
22
  hitTest(clientX: number, clientY: number): Clip | undefined;
23
+ hitsAt(clientX: number, clientY: number): readonly Clip[];
23
24
  /** Redraw against the picture, once it has mounted or moved. */
24
25
  refresh(): void;
25
26
  };
@@ -127,19 +128,22 @@ export function createOverlay(store: Store, measure: Measure): Overlay {
127
128
  draw();
128
129
  });
129
130
 
130
- return {
131
- element,
132
- refresh: draw,
133
- hitTest(clientX, clientY) {
131
+ const hitsAt = (clientX: number, clientY: number): readonly Clip[] => {
134
132
  const box = element.getBoundingClientRect();
135
- if (box.width === 0 || box.height === 0) return undefined;
133
+ if (box.width === 0 || box.height === 0) return [];
136
134
  const x = (clientX - box.left) / box.width * canvas.width;
137
135
  const y = (clientY - box.top) / box.height * canvas.height;
138
136
  // Hit individual parts, not the empty space inside a group's union box.
139
- return entities.flatMap((clip) => drawnParts(clip)
137
+ const hits = entities.flatMap((clip) => drawnParts(clip)
140
138
  .filter((part) => inside(part, x, y))
141
139
  .map((part) => ({ clip, order: part.stackOrder })))
142
- .sort((left, right) => right.order - left.order)[0]?.clip;
143
- },
140
+ .sort((left, right) => right.order - left.order);
141
+ return [...new Map(hits.map(({ clip }) => [clip.id, clip])).values()];
142
+ };
143
+ return {
144
+ element,
145
+ refresh: draw,
146
+ hitsAt,
147
+ hitTest: (x, y) => hitsAt(x, y)[0],
144
148
  };
145
149
  }
@@ -0,0 +1,110 @@
1
+ import { uiAttr, uiText, t } from "./i18n.js";
2
+ import type { StudioSnapshot } from "../shared.js";
3
+ import { feedbackClock } from "../feedback.js";
4
+
5
+ type PreviewWindow = Window & {
6
+ __hypitSeekFrame?: (frame: number) => Promise<boolean>;
7
+ __hypitSetMuted?: (muted: boolean) => Promise<boolean>;
8
+ };
9
+
10
+ /** One lazy, muted picture for scrubbing; it never changes the main playhead. */
11
+ export function createScrubPreview(container: HTMLElement) {
12
+ const element = document.createElement("div");
13
+ element.className = "scrub-preview";
14
+ element.hidden = true;
15
+ element.innerHTML = '<div class="scrub-preview-picture"><span></span></div><div class="scrub-preview-time"></div>';
16
+ element.setAttribute("aria-hidden", "true");
17
+ const picture = element.querySelector<HTMLElement>(".scrub-preview-picture")!;
18
+ const status = picture.querySelector<HTMLElement>("span")!;
19
+ uiText(status, "player.frame-loading");
20
+ const time = element.querySelector<HTMLElement>(".scrub-preview-time")!;
21
+ container.append(element);
22
+ let iframe: HTMLIFrameElement | undefined;
23
+ let revision: number | undefined;
24
+ let ready = false;
25
+ let seeking = false;
26
+ let requested: number | undefined;
27
+ let displayed: number | undefined;
28
+
29
+ const seek = async (): Promise<void> => {
30
+ const current = iframe;
31
+ if (!ready || seeking || current === undefined || requested === undefined || requested === displayed) return;
32
+ seeking = true;
33
+ try {
34
+ while (iframe === current && requested !== undefined && requested !== displayed) {
35
+ const frame: number = requested;
36
+ const target = current.contentWindow as PreviewWindow | null;
37
+ const placed = await target?.__hypitSeekFrame?.(frame);
38
+ if (iframe !== current) return;
39
+ if (!placed) throw new Error(t("player.frame-unavailable"));
40
+ displayed = frame;
41
+ if (requested === frame) {
42
+ current.style.visibility = "visible";
43
+ status.hidden = true;
44
+ element.dataset.frame = String(frame);
45
+ }
46
+ }
47
+ } catch {
48
+ if (iframe === current) uiText(status, "player.frame-unavailable");
49
+ } finally {
50
+ if (iframe === current) seeking = false;
51
+ }
52
+ };
53
+ const hide = (): void => { element.hidden = true; requested = undefined; };
54
+ const clear = (): void => {
55
+ hide(); iframe?.remove(); iframe = undefined; revision = undefined;
56
+ ready = false; seeking = false; displayed = undefined;
57
+ delete element.dataset.frame;
58
+ };
59
+ return {
60
+ hide, clear,
61
+ show(snapshot: StudioSnapshot, frame: number, clientX: number): void {
62
+ if (snapshot.revision !== revision) clear();
63
+ if (iframe === undefined) {
64
+ revision = snapshot.revision;
65
+ const { canvasWidth, canvasHeight } = snapshot.space;
66
+ const scale = Math.min(200 / canvasWidth, 170 / canvasHeight);
67
+ picture.style.width = `${canvasWidth * scale}px`;
68
+ picture.style.height = `${canvasHeight * scale}px`;
69
+ const created = document.createElement("iframe");
70
+ uiAttr(created, "title", "player.hovered-frame");
71
+ created.tabIndex = -1;
72
+ created.setAttribute("sandbox", "allow-scripts allow-same-origin");
73
+ created.setAttribute("allow", "autoplay 'none'");
74
+ created.style.width = `${canvasWidth}px`;
75
+ created.style.height = `${canvasHeight}px`;
76
+ created.style.transform = `scale(${scale})`;
77
+ created.style.visibility = "hidden";
78
+ created.addEventListener("load", () => {
79
+ void (async () => {
80
+ const target = created.contentWindow as PreviewWindow | null;
81
+ await target?.__hypitSetMuted?.(true);
82
+ if (iframe !== created) return;
83
+ ready = true;
84
+ await seek();
85
+ })().catch(() => { if (iframe === created) uiText(status, "player.frame-unavailable"); });
86
+ });
87
+ created.srcdoc = snapshot.preview.srcdoc;
88
+ iframe = created;
89
+ picture.prepend(created);
90
+ }
91
+ requested = frame;
92
+ element.hidden = false;
93
+ const room = container.getBoundingClientRect();
94
+ const left = Math.max(0, Math.min(clientX - room.left - element.offsetWidth / 2, room.width - element.offsetWidth));
95
+ element.style.left = `${left}px`;
96
+ time.textContent = feedbackClock(frame * snapshot.space.frameRate.denominator / snapshot.space.frameRate.numerator);
97
+ if (frame !== displayed) {
98
+ iframe.style.visibility = "hidden";
99
+ uiText(status, "player.frame-loading");
100
+ status.hidden = false;
101
+ delete element.dataset.frame;
102
+ } else {
103
+ iframe.style.visibility = "visible";
104
+ status.hidden = true;
105
+ element.dataset.frame = String(frame);
106
+ }
107
+ void seek();
108
+ },
109
+ };
110
+ }
@@ -1,13 +1,20 @@
1
+ import { uiLabel, uiAttribute, uiText, uiAttr, userText } from "./i18n.js";
1
2
  import { createArtifactPreview } from "./artifact-preview.js";
2
3
  import type { StudioArtifactView, StudioSnapshot } from "../shared.js";
3
4
  import { createOverlay } from "./overlay.js";
4
5
  import { icon, setIcon } from "./icons.js";
6
+ import { createScrubPreview } from "./scrub-preview.js";
5
7
  import type { State, Store } from "./selection.js";
6
8
 
7
9
  export type Stage = {
8
10
  readonly element: HTMLElement;
9
11
  /** Start or stop playback, however the request arrived. */
10
12
  toggle(): void;
13
+ pause(): void;
14
+ /** Change picture interaction while preserving Studio's selection. */
15
+ setReviewMode(enabled: boolean): void;
16
+ /** Return from a Result artifact to the composition player. */
17
+ showComposition(): void;
11
18
  openArtifact(artifact: StudioArtifactView): void;
12
19
  renameArtifact(artifact: StudioArtifactView): void;
13
20
  };
@@ -25,29 +32,31 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
25
32
  element.className = "stage";
26
33
  element.innerHTML = `
27
34
  <div class="stage-heading">
28
- <div class="stage-title">${icon("preview")}<strong>Preview</strong></div>
29
- <button type="button" class="stage-return" hidden>Back to composition</button>
35
+ <div class="stage-title">${icon("preview")}<strong>${uiLabel("player.preview")}</strong></div>
36
+ <button type="button" class="stage-return" hidden>${uiLabel("player.back-to-composition")}</button>
30
37
  </div>
31
38
  <div class="stage-viewport">
32
39
  <div class="stage-scaler">
33
- <iframe title="Preview" sandbox="allow-scripts allow-same-origin" allow="autoplay"></iframe>
40
+ <iframe ${uiAttribute("title", "player.preview")} sandbox="allow-scripts allow-same-origin" allow="autoplay"></iframe>
34
41
  </div>
35
42
  </div>
36
- <input class="stage-scrubber" type="range" min="0" max="0" value="0" step="0.01" aria-label="Media time" hidden>
43
+ <div class="stage-progress" hidden>
44
+ <input class="stage-scrubber" type="range" min="0" max="0" value="0" step="0.01" ${uiAttribute("aria-label", "player.media-time")} hidden>
45
+ </div>
37
46
  <div class="stage-bar">
38
47
  <span class="stage-time" hidden></span>
39
48
  <div class="stage-transport">
40
- <button type="button" data-previous aria-label="Previous frame" title="Previous frame">
49
+ <button type="button" data-previous ${uiAttribute("aria-label", "player.previous-frame")} ${uiAttribute("title", "player.previous-frame")}>
41
50
  ${icon("previous")}
42
51
  </button>
43
- <button type="button" data-play aria-label="Play">
52
+ <button type="button" data-play ${uiAttribute("aria-label", "player.play")}>
44
53
  <span data-icon>${icon("play")}</span>
45
54
  </button>
46
- <button type="button" data-next aria-label="Next frame" title="Next frame">
55
+ <button type="button" data-next ${uiAttribute("aria-label", "player.next-frame")} ${uiAttribute("title", "player.next-frame")}>
47
56
  ${icon("next")}
48
57
  </button>
49
58
  </div>
50
- <button type="button" data-mute aria-label="Mute" class="stage-mute">
59
+ <button type="button" data-mute ${uiAttribute("aria-label", "player.mute")} class="stage-mute">
51
60
  <span data-mute-icon>${icon("volume")}</span>
52
61
  </button>
53
62
  </div>`;
@@ -55,6 +64,7 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
55
64
  const viewport = element.querySelector<HTMLElement>(".stage-viewport")!;
56
65
  const scaler = element.querySelector<HTMLElement>(".stage-scaler")!;
57
66
  const iframe = element.querySelector<HTMLIFrameElement>("iframe")!;
67
+ let reviewMode = false;
58
68
  /**
59
69
  * Measure a clip in the rendered picture.
60
70
  *
@@ -99,13 +109,45 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
99
109
  // Clicking the picture selects whatever is drawn under the pointer, which is
100
110
  // the third way into the same selection.
101
111
  scaler.addEventListener("click", (event) => {
112
+ if (reviewMode) { toggle(); return; }
102
113
  const clip = overlay.hitTest(event.clientX, event.clientY);
103
114
  if (clip !== undefined) store.select(clip.id, "video");
104
115
  else store.clearSelection();
105
116
  });
117
+ // A broad component frame can cover smaller elements. Offer all actual
118
+ // Companion hits without special knowledge of captions or any other family.
119
+ let selectionMenu: HTMLElement | undefined;
120
+ const closeSelectionMenu = (): void => { selectionMenu?.remove(); selectionMenu = undefined; };
121
+ scaler.addEventListener("contextmenu", (event) => {
122
+ if (reviewMode) { event.preventDefault(); return; }
123
+ const hits = overlay.hitsAt(event.clientX, event.clientY);
124
+ if (hits.length === 0) return;
125
+ event.preventDefault(); stop(); closeSelectionMenu();
126
+ const menu = document.createElement("div");
127
+ menu.className = "selection-menu";
128
+ menu.setAttribute("role", "menu"); uiAttr(menu, "aria-label", "player.elements-at-this-point");
129
+ for (const hit of hits) {
130
+ const option = document.createElement("button"); option.type = "button";
131
+ option.setAttribute("role", "menuitem"); option.textContent = hit.display.title;
132
+ option.title = hit.id;
133
+ option.addEventListener("click", () => { store.select(hit.id, "video"); closeSelectionMenu(); });
134
+ menu.append(option);
135
+ }
136
+ element.append(menu);
137
+ menu.style.left = `${Math.max(0, Math.min(event.clientX, window.innerWidth - menu.offsetWidth - 8))}px`;
138
+ menu.style.top = `${Math.max(0, Math.min(event.clientY, window.innerHeight - menu.offsetHeight - 8))}px`;
139
+ selectionMenu = menu; menu.querySelector("button")?.focus();
140
+ });
141
+ document.addEventListener("pointerdown", (event) => {
142
+ if (event.target instanceof Node && !selectionMenu?.contains(event.target)) closeSelectionMenu();
143
+ });
144
+ document.addEventListener("keydown", (event) => { if (event.key === "Escape") closeSelectionMenu(); });
106
145
  // The room around the picture is empty in the plainest sense.
107
146
  viewport.addEventListener("click", (event) => {
108
- if (event.target === viewport) store.clearSelection();
147
+ if (event.target === viewport) {
148
+ if (reviewMode) toggle();
149
+ else store.clearSelection();
150
+ }
109
151
  });
110
152
  const play = element.querySelector<HTMLButtonElement>("[data-play]")!;
111
153
  const previous = element.querySelector<HTMLButtonElement>("[data-previous]")!;
@@ -163,7 +205,7 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
163
205
  const wasPlaying = playing;
164
206
  playing = false;
165
207
  setIcon(playIcon, "play");
166
- play.setAttribute("aria-label", "Play");
208
+ uiAttr(play, "aria-label", "player.play");
167
209
  if (raf !== 0) cancelAnimationFrame(raf);
168
210
  raf = 0;
169
211
  // Settle the picture on the frame the transport stopped at.
@@ -178,7 +220,7 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
178
220
  if (playing) { stop(); return; }
179
221
  playing = true;
180
222
  setIcon(playIcon, "pause");
181
- play.setAttribute("aria-label", "Pause");
223
+ uiAttr(play, "aria-label", "player.pause");
182
224
  const total = state.snapshot.space.frameCount;
183
225
  const rate = fps(state.snapshot);
184
226
  fromFrame = state.playhead.frame >= total - 1 ? 0 : state.playhead.frame;
@@ -204,7 +246,7 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
204
246
 
205
247
  const applyMuted = (): void => {
206
248
  setIcon(muteIcon, muted ? "muted" : "volume");
207
- mute.setAttribute("aria-label", muted ? "Unmute" : "Mute");
249
+ uiAttr(mute, "aria-label", muted ? "player.unmute" : "player.mute");
208
250
  if (artifactPreview.media !== undefined) artifactPreview.media.muted = muted;
209
251
  (iframe.contentWindow as SeekWindow | null)?.__hypitSetMuted?.(muted);
210
252
  };
@@ -213,6 +255,18 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
213
255
  const title = element.querySelector<HTMLElement>(".stage-title strong")!;
214
256
  const back = element.querySelector<HTMLButtonElement>(".stage-return")!;
215
257
  const scrubber = element.querySelector<HTMLInputElement>(".stage-scrubber")!;
258
+ const progress = element.querySelector<HTMLElement>(".stage-progress")!;
259
+ const scrubPreview = createScrubPreview(progress);
260
+ scrubber.addEventListener("pointermove", (event) => {
261
+ if (!reviewMode || state === undefined || scrubber.disabled || artifactPreview.selected !== undefined) return;
262
+ const box = scrubber.getBoundingClientRect();
263
+ // Native range thumbs travel between their centers, not the input edges.
264
+ const fraction = Math.max(0, Math.min(1, (event.clientX - box.left - 6) / Math.max(1, box.width - 12)));
265
+ const frame = Math.round(fraction * Math.max(0, state.snapshot.space.frameCount - 1));
266
+ scrubPreview.show(state.snapshot, frame, event.clientX);
267
+ });
268
+ scrubber.addEventListener("pointerleave", scrubPreview.hide);
269
+ scrubber.addEventListener("blur", scrubPreview.hide);
216
270
  const time = element.querySelector<HTMLElement>(".stage-time")!;
217
271
  const transport = element.querySelector<HTMLElement>(".stage-transport")!;
218
272
  const clock = (seconds: number): string => {
@@ -227,29 +281,29 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
227
281
  const duration = media !== undefined && Number.isFinite(media.duration) ? media.duration : 0;
228
282
  transport.hidden = !timed;
229
283
  mute.hidden = !timed;
230
- scrubber.hidden = !timed;
284
+ progress.hidden = scrubber.hidden = !timed;
231
285
  time.hidden = !timed;
232
286
  play.disabled = duration <= 0 || media?.error != null;
233
287
  previous.disabled = next.disabled = play.disabled;
234
288
  scrubber.disabled = duration <= 0;
235
289
  scrubber.step = "0.01";
236
- scrubber.setAttribute("aria-label", "Media time");
290
+ uiAttr(scrubber, "aria-label", "player.media-time");
237
291
  scrubber.max = String(duration);
238
292
  scrubber.value = String(media?.currentTime ?? 0);
239
293
  time.textContent = `${clock(media?.currentTime ?? 0)} / ${clock(duration)}`;
240
294
  setIcon(playIcon, media !== undefined && !media.paused ? "pause" : "play");
241
- play.setAttribute("aria-label", media !== undefined && !media.paused ? "Pause" : "Play");
295
+ uiAttr(play, "aria-label", media !== undefined && !media.paused ? "player.pause" : "player.play");
242
296
  });
243
297
  viewport.append(artifactPreview.element);
244
298
  const compositionTime = (): void => {
245
299
  if (state === undefined || artifactPreview.selected !== undefined) return;
246
300
  const rate = fps(state.snapshot);
247
- scrubber.hidden = time.hidden = false;
301
+ progress.hidden = scrubber.hidden = time.hidden = false;
248
302
  scrubber.disabled = !ready;
249
303
  scrubber.step = String(1 / rate);
250
304
  scrubber.max = String(Math.max(0, state.snapshot.space.frameCount - 1) / rate);
251
305
  scrubber.value = String(state.playhead.frame / rate);
252
- scrubber.setAttribute("aria-label", "Composition time");
306
+ uiAttr(scrubber, "aria-label", "player.composition-time");
253
307
  time.textContent = `${clock(state.playhead.frame / rate)} / ${clock(state.snapshot.space.frameCount / rate)}`;
254
308
  };
255
309
  scrubber.addEventListener("input", () => {
@@ -265,14 +319,14 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
265
319
  compositionTime();
266
320
  transport.hidden = mute.hidden = false;
267
321
  play.disabled = previous.disabled = next.disabled = false;
268
- previous.title = "Previous frame";
269
- previous.setAttribute("aria-label", previous.title);
270
- next.title = "Next frame";
271
- next.setAttribute("aria-label", next.title);
272
- title.textContent = "Preview";
322
+ uiAttr(previous, "title", "player.previous-frame");
323
+ uiAttr(previous, "aria-label", "player.previous-frame");
324
+ uiAttr(next, "title", "player.next-frame");
325
+ uiAttr(next, "aria-label", "player.next-frame");
326
+ uiText(title, "player.preview");
273
327
  title.removeAttribute("title");
274
328
  setIcon(playIcon, "play");
275
- play.setAttribute("aria-label", "Play");
329
+ uiAttr(play, "aria-label", "player.play");
276
330
  fit();
277
331
  if (state !== undefined && ready) seekPicture(state.playhead.frame);
278
332
  };
@@ -282,12 +336,12 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
282
336
  stop();
283
337
  scaler.hidden = true;
284
338
  back.hidden = false;
285
- title.textContent = artifact.displayName ?? artifact.output;
339
+ userText(title, artifact.displayName ?? artifact.output);
286
340
  title.title = artifact.output;
287
- previous.title = "Back 5 seconds";
288
- next.title = "Forward 5 seconds";
289
- previous.setAttribute("aria-label", previous.title);
290
- next.setAttribute("aria-label", next.title);
341
+ uiAttr(previous, "title", "player.back-5-seconds");
342
+ uiAttr(next, "title", "player.forward-5-seconds");
343
+ uiAttr(previous, "aria-label", "player.back-5-seconds");
344
+ uiAttr(next, "aria-label", "player.forward-5-seconds");
291
345
  artifactPreview.open(artifact, muted);
292
346
  selectedArtifact(artifact.id);
293
347
  };
@@ -309,6 +363,7 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
309
363
  state = value;
310
364
  if (moved && value.playhead.origin !== "play" && artifactPreview.selected !== undefined) returnToComposition();
311
365
  if (value.snapshot.revision !== mounted) {
366
+ scrubPreview.clear();
312
367
  mounted = value.snapshot.revision;
313
368
  if (artifactPreview.selected === undefined) stop();
314
369
  ready = false;
@@ -339,9 +394,18 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
339
394
  });
340
395
 
341
396
  return { element, toggle, openArtifact,
397
+ setReviewMode(enabled) {
398
+ reviewMode = enabled;
399
+ element.classList.toggle("stage-review", enabled);
400
+ overlay.element.style.display = enabled ? "none" : "";
401
+ closeSelectionMenu();
402
+ if (!enabled) scrubPreview.clear();
403
+ },
404
+ pause() { stop(); artifactPreview.media?.pause(); },
405
+ showComposition() { if (artifactPreview.selected !== undefined) returnToComposition(); },
342
406
  renameArtifact(artifact) {
343
407
  const selected = artifactPreview.selected;
344
- if (selected?.build === artifact.build && selected.output === artifact.output) title.textContent = artifact.displayName ?? artifact.output;
408
+ if (selected?.build === artifact.build && selected.output === artifact.output) userText(title, artifact.displayName ?? artifact.output);
345
409
  },
346
410
  };
347
411
  }