@hypit/hypit 0.1.4 → 0.1.5
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.
- package/README.md +4 -2
- package/dist/public/caption.d.ts +206 -183
- package/dist/public/composition.d.ts +25 -3
- package/dist/public/endpoint-kit.d.ts +24 -2
- package/dist/public/generation.d.ts +5 -1
- package/dist/public/hyperframes.d.ts +19 -1
- package/dist/public/narrative.d.ts +17 -3
- package/dist/public/performance.d.ts +1590 -0
- package/dist/public/program-space.d.ts +179 -32
- package/dist/public/runtime-kit.d.ts +21 -8
- package/dist/public/sound.d.ts +822 -0
- package/dist/public/speech.d.ts +41 -0
- package/dist/public/studio-adapter.d.ts +77 -15
- package/dist/public/temporal-markup.d.ts +9 -44
- package/dist/public/temporal.d.ts +37 -28
- package/dist/public/{semantic-track.d.ts → timeline.d.ts} +62 -49
- package/examples/README.md +18 -10
- package/examples/minimal-author-package/packages/example-component/preview/preview.svml +19 -12
- package/examples/minimal-author-package/packages/example-component/src/component.ts +5 -5
- package/examples/minimal-author-package/packages/example-component/src/fragment.ts +3 -5
- package/examples/minimal-author-package/packages/example-component/src/manifest.ts +8 -10
- package/examples/minimal-author-package/packages/example-component/src/surface.ts +2 -2
- package/examples/provider-package/README.md +78 -0
- package/examples/provider-package/hypit.runtime.json +12 -0
- package/examples/provider-package/packages/provider-images/package.json +11 -0
- package/examples/provider-package/packages/provider-images/src/activation.ts +24 -0
- package/examples/provider-package/packages/provider-images/src/provider.ts +122 -0
- package/examples/provider-package/packages/provider-images/tsconfig.json +9 -0
- package/examples/semantic-composition/README.md +6 -0
- package/examples/semantic-composition/chat.svml +6 -5
- package/examples/semantic-composition/packages/chat-scene/README.md +3 -3
- package/examples/semantic-composition/packages/chat-scene/src/activation.ts +18 -21
- package/examples/semantic-composition/packages/chat-scene/src/render.ts +4 -4
- package/examples/semantic-composition/packages/performance-styles/README.md +42 -0
- package/examples/semantic-composition/packages/performance-styles/package.json +25 -0
- package/examples/semantic-composition/packages/performance-styles/src/activation.ts +57 -0
- package/examples/semantic-composition/packages/performance-styles/src/render.ts +54 -0
- package/examples/semantic-composition/packages/performance-styles/src/studio.ts +28 -0
- package/examples/semantic-composition/packages/performance-styles/tsconfig.json +18 -0
- package/examples/semantic-composition/packages/responsive-explainer/README.md +16 -9
- package/examples/semantic-composition/packages/responsive-explainer/src/activation.ts +12 -12
- package/examples/semantic-composition/packages/responsive-explainer/src/render.ts +5 -5
- package/examples/semantic-composition/packages/sound-styles/README.md +36 -0
- package/examples/semantic-composition/packages/sound-styles/package.json +25 -0
- package/examples/semantic-composition/packages/sound-styles/src/activation.ts +53 -0
- package/examples/semantic-composition/packages/sound-styles/src/render.ts +14 -0
- package/examples/semantic-composition/packages/sound-styles/tsconfig.json +18 -0
- package/package.json +32 -15
- package/packages/audio-track/README.md +20 -13
- package/packages/audio-track/package.json +1 -1
- package/packages/audio-track/src/component.ts +4 -4
- package/packages/audio-track/src/fragment.ts +6 -5
- package/packages/audio-track/src/index.ts +1 -1
- package/packages/audio-track/src/manifest.ts +17 -16
- package/packages/audio-track/src/program.ts +21 -25
- package/packages/audio-track/src/surface.ts +19 -18
- package/packages/audio-track-studio/README.md +23 -0
- package/packages/audio-track-studio/src/index.ts +28 -17
- package/packages/author-kit/README.md +1 -1
- package/packages/background-removal/README.md +4 -7
- package/packages/browser-capture/package.json +1 -1
- package/packages/build-result/README.md +11 -0
- package/packages/build-result/src/decode.ts +2 -0
- package/packages/build-result/src/execution-log.ts +17 -0
- package/packages/build-result/src/index.ts +1 -0
- package/packages/build-result/src/store.ts +14 -1
- package/packages/build-result/src/types.ts +3 -0
- package/packages/build-result-s3/src/repository.ts +4 -0
- package/packages/caption/README.md +61 -73
- package/packages/caption/package.json +3 -2
- package/packages/caption/src/activation.ts +2 -2
- package/packages/caption/src/component.ts +20 -5
- package/packages/caption/src/display.ts +3 -18
- package/packages/caption/src/fragment.ts +3 -7
- package/packages/caption/src/index.ts +6 -5
- package/packages/caption/src/manifest.ts +29 -46
- package/packages/caption/src/style.ts +24 -135
- package/packages/caption/src/surface.ts +12 -92
- package/packages/caption/src/temporalize.ts +18 -53
- package/packages/caption/src/types.ts +8 -35
- package/packages/caption/src/visibility.ts +23 -0
- package/packages/caption-fine/README.md +14 -9
- package/packages/caption-fine/package.json +4 -2
- package/packages/caption-fine/src/component.ts +3 -3
- package/packages/caption-fine/src/fragment.ts +7 -19
- package/packages/caption-fine/src/index.ts +2 -0
- package/packages/caption-fine/src/manifest.ts +26 -17
- package/packages/caption-fine/src/recipe.ts +7 -0
- package/packages/caption-fine/src/render.ts +14 -13
- package/packages/caption-fine/src/schedule.ts +39 -35
- package/packages/caption-fine/src/style.ts +10 -9
- package/packages/caption-fine/src/surface.ts +62 -35
- package/packages/caption-fine/src/types.ts +2 -0
- package/packages/caption-fine-studio/README.md +24 -2
- package/packages/caption-fine-studio/package.json +3 -1
- package/packages/caption-fine-studio/src/activation.ts +3 -3
- package/packages/caption-fine-studio/src/index.ts +54 -42
- package/packages/cli/README.md +57 -4
- package/packages/cli/package.json +1 -0
- package/packages/cli/src/arguments.ts +25 -6
- package/packages/cli/src/build-planning.ts +3 -2
- package/packages/cli/src/command.ts +6 -0
- package/packages/cli/src/commands/environment.ts +28 -18
- package/packages/cli/src/commands/execution.ts +81 -26
- package/packages/cli/src/commands/results.ts +7 -11
- package/packages/cli/src/index.ts +2 -2
- package/packages/cli/src/machine-view.ts +3 -2
- package/packages/cli/src/main.ts +34 -42
- package/packages/cli/src/observation.ts +7 -1
- package/packages/cli/src/output.ts +65 -23
- package/packages/cli/src/view.ts +64 -18
- package/packages/comment-sticker/README.md +3 -3
- package/packages/comment-sticker/package.json +1 -1
- package/packages/comment-sticker/src/component.ts +4 -4
- package/packages/comment-sticker/src/fragment.ts +5 -4
- package/packages/comment-sticker/src/manifest.ts +7 -6
- package/packages/comment-sticker/src/program.ts +9 -9
- package/packages/comment-sticker/src/surface.ts +6 -7
- package/packages/composition/README.md +21 -0
- package/packages/composition/src/audio-presentation.ts +44 -0
- package/packages/composition/src/index.ts +3 -0
- package/packages/composition/src/schema.ts +8 -3
- package/packages/composition/src/track.ts +15 -1
- package/packages/credential-store-env/README.md +1 -1
- package/packages/deck-track/README.md +3 -3
- package/packages/deck-track/package.json +1 -1
- package/packages/deck-track/src/component.ts +5 -5
- package/packages/deck-track/src/fragment.ts +6 -5
- package/packages/deck-track/src/lower.ts +12 -12
- package/packages/deck-track/src/manifest.ts +8 -7
- package/packages/deck-track/src/program.ts +13 -16
- package/packages/deck-track/src/surface.ts +9 -10
- package/packages/driver-node/src/driver.ts +41 -3
- package/packages/elevenlabs-speech/README.md +27 -0
- package/packages/{provider-xiaomi-mimo → elevenlabs-speech}/package.json +5 -8
- package/packages/elevenlabs-speech/src/activation.ts +26 -0
- package/packages/elevenlabs-speech/src/fragment.ts +11 -0
- package/packages/elevenlabs-speech/src/index.ts +111 -0
- package/packages/elevenlabs-speech/src/surface.ts +167 -0
- package/packages/endpoint-kit/README.md +24 -0
- package/packages/endpoint-kit/src/index.ts +7 -1
- package/packages/film/README.md +12 -7
- package/packages/film/package.json +1 -1
- package/packages/film/src/component.ts +4 -4
- package/packages/film/src/fragment.ts +6 -5
- package/packages/film/src/manifest.ts +11 -10
- package/packages/film/src/program.ts +5 -5
- package/packages/film/src/recipe.ts +2 -1
- package/packages/film/src/surface.ts +6 -6
- package/packages/film-studio/package.json +1 -1
- package/packages/film-studio/src/index.ts +2 -2
- package/packages/fishaudio-speech/README.md +33 -0
- package/packages/fishaudio-speech/package.json +21 -0
- package/packages/fishaudio-speech/src/activation.ts +32 -0
- package/packages/fishaudio-speech/src/fragment.ts +11 -0
- package/packages/fishaudio-speech/src/index.ts +156 -0
- package/packages/fishaudio-speech/src/surface.ts +192 -0
- package/packages/generation/README.md +11 -1
- package/packages/generation/src/mapping.ts +28 -30
- package/packages/gpt-image/README.md +1 -2
- package/packages/grok-imagine/README.md +1 -2
- package/packages/hyperframes/README.md +7 -3
- package/packages/hyperframes/src/browser-program.ts +11 -2
- package/packages/hyperframes/src/document.ts +15 -2
- package/packages/interview-emoji-reveal/README.md +4 -4
- package/packages/interview-emoji-reveal/package.json +1 -1
- package/packages/interview-emoji-reveal/src/component.ts +4 -4
- package/packages/interview-emoji-reveal/src/fragment.ts +6 -5
- package/packages/interview-emoji-reveal/src/manifest.ts +9 -8
- package/packages/interview-emoji-reveal/src/program.ts +14 -14
- package/packages/interview-emoji-reveal/src/surface.ts +8 -9
- package/packages/media-execution/README.md +7 -3
- package/packages/media-execution/src/audio-presentation.ts +23 -0
- package/packages/media-execution/src/execute.ts +2 -0
- package/packages/media-pipeline/README.md +7 -3
- package/packages/media-pipeline/src/audio-plan.ts +4 -1
- package/packages/media-pipeline/src/component.ts +16 -2
- package/packages/media-pipeline/src/manifest.ts +3 -1
- package/packages/media-pipeline/src/types.ts +2 -1
- package/packages/media-track/README.md +14 -47
- package/packages/media-track/package.json +1 -1
- package/packages/media-track/preview/preview.svml +5 -5
- package/packages/media-track/src/author.ts +12 -6
- package/packages/media-track/src/component.ts +10 -16
- package/packages/media-track/src/fragment.ts +8 -7
- package/packages/media-track/src/index.ts +3 -1
- package/packages/media-track/src/lower.ts +7 -7
- package/packages/media-track/src/manifest.ts +16 -38
- package/packages/media-track/src/program.ts +62 -67
- package/packages/media-track/src/sampling.ts +6 -6
- package/packages/media-track/src/sequence.ts +8 -8
- package/packages/media-track/src/surface.ts +25 -43
- package/packages/media-track-studio/README.md +9 -0
- package/packages/media-track-studio/src/index.ts +16 -11
- package/packages/mimo-speech/README.md +1 -1
- package/packages/minimax-h3/README.md +1 -1
- package/packages/nano-banana/README.md +1 -1
- package/packages/narrative/README.md +23 -1
- package/packages/narrative/src/identity.ts +11 -0
- package/packages/narrative/src/index.ts +3 -0
- package/packages/narrative/src/schema.ts +28 -27
- package/packages/narrative/src/selection.ts +52 -0
- package/packages/narrative/src/types.ts +2 -0
- package/packages/package-loader-node/README.md +30 -0
- package/packages/package-loader-node/package.json +5 -2
- package/packages/package-loader-node/src/distribution-resolution.ts +10 -3
- package/packages/package-loader-node/src/index.ts +1 -0
- package/packages/package-loader-node/src/loader.ts +12 -15
- package/packages/package-loader-node/src/location.ts +27 -1
- package/packages/package-loader-node/src/module-scope.ts +183 -0
- package/packages/package-loader-node/src/types.ts +4 -0
- package/packages/performance/README.md +83 -0
- package/packages/performance/package.json +30 -0
- package/packages/performance/src/activation.ts +11 -0
- package/packages/performance/src/component.ts +46 -0
- package/packages/performance/src/index.ts +6 -0
- package/packages/performance/src/manifest.ts +53 -0
- package/packages/{media-track/src/performance.ts → performance/src/media.ts} +9 -10
- package/packages/performance/src/program.ts +51 -0
- package/packages/performance/src/style.ts +35 -0
- package/packages/performance/src/surface.ts +99 -0
- package/packages/performance-studio/README.md +25 -0
- package/packages/performance-studio/package.json +21 -0
- package/packages/performance-studio/src/activation.ts +6 -0
- package/packages/performance-studio/src/index.ts +84 -0
- package/packages/program-space/README.md +9 -18
- package/packages/program-space/src/activation.ts +1 -5
- package/packages/program-space/src/index.ts +2 -11
- package/packages/program-space/src/surface.ts +1 -20
- package/packages/project-context-node/README.md +20 -0
- package/packages/project-context-node/package.json +10 -0
- package/packages/project-context-node/src/index.ts +3 -0
- package/packages/{cli → project-context-node}/src/runtime-selection.ts +7 -2
- package/packages/provider-hyperframes-local/README.md +43 -15
- package/packages/provider-hyperframes-local/src/activation.ts +4 -3
- package/packages/provider-hyperframes-local/src/capture-process.ts +26 -4
- package/packages/provider-hyperframes-local/src/capture.ts +96 -26
- package/packages/provider-hyperframes-local/src/concurrency.ts +86 -0
- package/packages/provider-hyperframes-local/src/opaque-capture.ts +92 -0
- package/packages/provider-hyperframes-local/src/options.ts +2 -0
- package/packages/provider-hyperframes-local/src/program.ts +6 -3
- package/packages/provider-hyperframes-local/src/progress.ts +53 -0
- package/packages/provider-hyperframes-local/src/provider.ts +18 -5
- package/packages/provider-hyperframes-local/src/render.ts +48 -7
- package/packages/provider-hypihub/README.md +48 -17
- package/packages/provider-hypihub/package.json +2 -0
- package/packages/provider-hypihub/src/mapping.ts +31 -7
- package/packages/provider-hypihub/src/oauth.ts +6 -0
- package/packages/provider-hypihub/src/provider.ts +25 -13
- package/packages/provider-hypihub/src/routes.ts +1 -2
- package/packages/provider-hypihub/src/upload.ts +2 -0
- package/packages/provider-media-local/README.md +3 -4
- package/packages/provider-whisperx-local/src/program.ts +1 -0
- package/packages/provider-whisperx-local/src/provider.ts +3 -0
- package/packages/ranking/README.md +8 -6
- package/packages/ranking/package.json +1 -1
- package/packages/ranking/src/component.ts +6 -6
- package/packages/ranking/src/fragment.ts +11 -7
- package/packages/ranking/src/manifest.ts +21 -14
- package/packages/ranking/src/render.ts +22 -26
- package/packages/ranking/src/schedule.ts +16 -19
- package/packages/ranking/src/surface.ts +12 -13
- package/packages/ranking-studio/README.md +18 -0
- package/packages/ranking-studio/src/index.ts +61 -9
- package/packages/render-hyperframes/README.md +7 -7
- package/packages/render-hyperframes/package.json +1 -1
- package/packages/render-hyperframes/src/component.ts +11 -1
- package/packages/render-hyperframes/src/fragment.ts +7 -4
- package/packages/render-hyperframes/src/manifest.ts +4 -4
- package/packages/render-hyperframes/src/surface.ts +6 -6
- package/packages/runtime/README.md +8 -1
- package/packages/runtime/src/execution.ts +15 -4
- package/packages/runtime/src/index.ts +2 -1
- package/packages/runtime/src/log.ts +51 -0
- package/packages/runtime/src/types.ts +5 -8
- package/packages/runtime-host-node/README.md +30 -0
- package/packages/runtime-host-node/package.json +1 -0
- package/packages/runtime-host-node/src/index.ts +24 -9
- package/packages/runtime-host-node/src/packages.ts +47 -50
- package/packages/runtime-kit/README.md +5 -0
- package/packages/runtime-kit/src/index.ts +3 -1
- package/packages/runtime-local/README.md +92 -4
- package/packages/runtime-local/src/config.ts +202 -56
- package/packages/runtime-local/src/control.ts +9 -1
- package/packages/runtime-local/src/executor.ts +66 -0
- package/packages/runtime-local/src/host.ts +37 -17
- package/packages/runtime-local/src/log.ts +48 -0
- package/packages/runtime-local/src/programs.ts +2 -1
- package/packages/runtime-local/src/result-writer.ts +2 -0
- package/packages/runtime-local/src/runtime.ts +8 -6
- package/packages/runtime-local/src/supervisor.ts +142 -0
- package/packages/runtime-local/src/types.ts +9 -2
- package/packages/runtime-local/src/worker-process.ts +7 -24
- package/packages/runtime-local/src/worker.ts +55 -83
- package/packages/screen-overlay/README.md +3 -3
- package/packages/screen-overlay/package.json +1 -1
- package/packages/screen-overlay/src/component.ts +3 -3
- package/packages/screen-overlay/src/fragment.ts +5 -4
- package/packages/screen-overlay/src/manifest.ts +7 -6
- package/packages/screen-overlay/src/program.ts +9 -9
- package/packages/screen-overlay/src/surface.ts +6 -7
- package/packages/script/README.md +15 -2
- package/packages/script/src/manifest.ts +2 -2
- package/packages/script/src/narrative.ts +1 -0
- package/packages/script/src/surface.ts +4 -3
- package/packages/script/src/types.ts +1 -1
- package/packages/script-studio/package.json +9 -3
- package/packages/script-studio/src/index.ts +2 -0
- package/packages/script-studio/src/projection.ts +105 -0
- package/packages/seedance/README.md +30 -1
- package/packages/seedance/src/index.ts +18 -7
- package/packages/seedance/src/surface.ts +17 -4
- package/packages/seedance-kits/README.md +7 -1
- package/packages/seedream/README.md +1 -1
- package/packages/sound/README.md +81 -0
- package/packages/sound/package.json +25 -0
- package/packages/sound/src/activation.ts +11 -0
- package/packages/sound/src/component.ts +28 -0
- package/packages/sound/src/index.ts +5 -0
- package/packages/sound/src/manifest.ts +47 -0
- package/packages/sound/src/program.ts +84 -0
- package/packages/sound/src/style.ts +34 -0
- package/packages/sound/src/surface.ts +90 -0
- package/packages/sound-studio/README.md +22 -0
- package/packages/sound-studio/package.json +20 -0
- package/packages/sound-studio/src/activation.ts +6 -0
- package/packages/sound-studio/src/index.ts +74 -0
- package/packages/speech/README.md +2 -2
- package/packages/speech-alignment/src/local.ts +8 -0
- package/packages/speech-alignment/src/locate.ts +1 -1
- package/packages/store-sqlite/README.md +7 -0
- package/packages/store-sqlite/src/store.ts +84 -83
- package/packages/studio/INSPECTOR.md +15 -2
- package/packages/studio/README.md +88 -14
- package/packages/studio/package.json +8 -7
- package/packages/studio/src/companion-assembly.ts +1 -0
- package/packages/studio/src/domain.ts +1 -1
- package/packages/studio/src/fallback-companions.ts +3 -3
- package/packages/studio/src/feedback-server.ts +51 -0
- package/packages/studio/src/feedback-store.ts +66 -0
- package/packages/studio/src/feedback.ts +60 -0
- package/packages/studio/src/parameter-values.ts +43 -1
- package/packages/studio/src/parameters.ts +114 -24
- package/packages/studio/src/preview/render.ts +5 -1
- package/packages/studio/src/preview/runtime-shim.ts +49 -3
- package/packages/studio/src/programme.ts +14 -30
- package/packages/studio/src/server.ts +10 -6
- package/packages/studio/src/shared.ts +4 -2
- package/packages/studio/src/snapshot.ts +21 -132
- package/packages/studio/src/studio-preflight.ts +3 -3
- package/packages/studio/src/studio-registry.ts +50 -6
- package/packages/studio/src/style.css +209 -48
- package/packages/studio/src/ui/comments.ts +233 -0
- package/packages/studio/src/ui/icons.ts +5 -0
- package/packages/studio/src/ui/main.ts +145 -86
- package/packages/studio/src/ui/overlay.ts +12 -8
- package/packages/studio/src/ui/scrub-preview.ts +108 -0
- package/packages/studio/src/ui/stage.ts +67 -4
- package/packages/studio/src/ui/timeline.ts +177 -108
- package/packages/studio/start.ts +4 -2
- package/packages/studio-adapter/README.md +130 -11
- package/packages/studio-adapter/src/index.ts +100 -13
- package/packages/temporal/README.md +6 -6
- package/packages/temporal/package.json +1 -1
- package/packages/temporal/src/component.ts +5 -6
- package/packages/temporal/src/index.ts +8 -6
- package/packages/temporal/src/location.ts +11 -11
- package/packages/temporal/src/projection.ts +19 -19
- package/packages/temporal/src/rational.ts +4 -4
- package/packages/temporal-markup/EDITING.md +2 -2
- package/packages/temporal-markup/README.md +27 -11
- package/packages/temporal-markup/package.json +1 -1
- package/packages/temporal-markup/src/index.ts +20 -25
- package/packages/temporal-markup/src/space.ts +10 -41
- package/packages/timeline/README.md +31 -0
- package/packages/{semantic-track → timeline}/package.json +1 -1
- package/packages/timeline/src/activation.ts +8 -0
- package/packages/timeline/src/component.ts +24 -0
- package/packages/timeline/src/identity.ts +60 -0
- package/packages/timeline/src/index.ts +6 -0
- package/packages/{semantic-track → timeline}/src/location.ts +20 -20
- package/packages/timeline/src/manifest.ts +39 -0
- package/packages/{semantic-track → timeline}/src/projection.ts +14 -14
- package/packages/timeline/src/types.ts +24 -0
- package/packages/timeline-author/README.md +68 -0
- package/packages/{speech-track → timeline-author}/package.json +6 -4
- package/packages/timeline-author/src/activation.ts +22 -0
- package/packages/{speech-track → timeline-author}/src/component.ts +15 -13
- package/packages/{speech-track → timeline-author}/src/fragment.ts +14 -23
- package/packages/timeline-author/src/index.ts +7 -0
- package/packages/timeline-author/src/manifest.ts +78 -0
- package/packages/timeline-author/src/program.ts +107 -0
- package/packages/timeline-author/src/surface.ts +46 -0
- package/packages/timeline-author/src/types.ts +6 -0
- package/packages/typography-track/README.md +4 -4
- package/packages/typography-track/package.json +1 -1
- package/packages/typography-track/src/component.ts +4 -4
- package/packages/typography-track/src/fragment.ts +4 -3
- package/packages/typography-track/src/manifest.ts +11 -9
- package/packages/typography-track/src/program.ts +15 -15
- package/packages/typography-track/src/surface.ts +17 -18
- package/packages/video-cli/README.md +4 -1
- package/packages/video-cli/package.json +2 -1
- package/packages/video-cli/src/creation.ts +14 -4
- package/packages/video-cli/src/index.ts +1 -1
- package/packages/video-cli/src/studio-distribution.ts +2 -1
- package/packages/volcengine-matting/README.md +3 -3
- package/packages/whisperx/README.md +1 -1
- package/services/whisperx/README.md +14 -0
- package/services/whisperx/pyproject.toml +2 -0
- package/services/whisperx/uv.lock +20 -20
- package/packages/provider-hyperframes-aws-lambda/README.md +0 -30
- package/packages/provider-hyperframes-aws-lambda/package.json +0 -30
- package/packages/provider-hyperframes-aws-lambda/src/activation.ts +0 -97
- package/packages/provider-hyperframes-aws-lambda/src/client.ts +0 -114
- package/packages/provider-hyperframes-aws-lambda/src/index.ts +0 -21
- package/packages/provider-hyperframes-aws-lambda/src/provider.ts +0 -522
- package/packages/provider-kie/README.md +0 -134
- package/packages/provider-kie/package.json +0 -43
- package/packages/provider-kie/src/activation.ts +0 -71
- package/packages/provider-kie/src/index.ts +0 -10
- package/packages/provider-kie/src/mapping.ts +0 -182
- package/packages/provider-kie/src/provider.ts +0 -657
- package/packages/provider-kie/src/routes.ts +0 -150
- package/packages/provider-xiaomi-mimo/README.md +0 -32
- package/packages/provider-xiaomi-mimo/src/activation.ts +0 -57
- package/packages/provider-xiaomi-mimo/src/index.ts +0 -5
- package/packages/provider-xiaomi-mimo/src/provider.ts +0 -214
- package/packages/runtime/src/environment.ts +0 -6
- package/packages/semantic-track/README.md +0 -21
- package/packages/semantic-track/src/activation.ts +0 -8
- package/packages/semantic-track/src/component.ts +0 -24
- package/packages/semantic-track/src/identity.ts +0 -58
- package/packages/semantic-track/src/index.ts +0 -6
- package/packages/semantic-track/src/manifest.ts +0 -38
- package/packages/semantic-track/src/types.ts +0 -26
- package/packages/speech-track/README.md +0 -51
- package/packages/speech-track/src/activation.ts +0 -19
- package/packages/speech-track/src/index.ts +0 -7
- package/packages/speech-track/src/manifest.ts +0 -73
- package/packages/speech-track/src/program.ts +0 -64
- package/packages/speech-track/src/surface.ts +0 -35
- package/packages/speech-track/src/types.ts +0 -6
- package/packages/speech-track-studio/README.md +0 -3
- package/packages/speech-track-studio/package.json +0 -14
- package/packages/speech-track-studio/src/activation.ts +0 -7
- package/packages/speech-track-studio/src/index.ts +0 -40
- /package/packages/{cli → project-context-node}/src/project-context.ts +0 -0
- /package/packages/{speech-track → timeline-author}/preview/Track.png +0 -0
|
@@ -2,12 +2,18 @@ import { createArtifactPreview } from "./artifact-preview.js";
|
|
|
2
2
|
import type { StudioArtifactView, StudioSnapshot } from "../shared.js";
|
|
3
3
|
import { createOverlay } from "./overlay.js";
|
|
4
4
|
import { icon, setIcon } from "./icons.js";
|
|
5
|
+
import { createScrubPreview } from "./scrub-preview.js";
|
|
5
6
|
import type { State, Store } from "./selection.js";
|
|
6
7
|
|
|
7
8
|
export type Stage = {
|
|
8
9
|
readonly element: HTMLElement;
|
|
9
10
|
/** Start or stop playback, however the request arrived. */
|
|
10
11
|
toggle(): void;
|
|
12
|
+
pause(): void;
|
|
13
|
+
/** Change picture interaction while preserving Studio's selection. */
|
|
14
|
+
setReviewMode(enabled: boolean): void;
|
|
15
|
+
/** Return from a Result artifact to the composition player. */
|
|
16
|
+
showComposition(): void;
|
|
11
17
|
openArtifact(artifact: StudioArtifactView): void;
|
|
12
18
|
renameArtifact(artifact: StudioArtifactView): void;
|
|
13
19
|
};
|
|
@@ -33,7 +39,9 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
|
|
|
33
39
|
<iframe title="Preview" sandbox="allow-scripts allow-same-origin" allow="autoplay"></iframe>
|
|
34
40
|
</div>
|
|
35
41
|
</div>
|
|
36
|
-
<
|
|
42
|
+
<div class="stage-progress" hidden>
|
|
43
|
+
<input class="stage-scrubber" type="range" min="0" max="0" value="0" step="0.01" aria-label="Media time" hidden>
|
|
44
|
+
</div>
|
|
37
45
|
<div class="stage-bar">
|
|
38
46
|
<span class="stage-time" hidden></span>
|
|
39
47
|
<div class="stage-transport">
|
|
@@ -55,6 +63,7 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
|
|
|
55
63
|
const viewport = element.querySelector<HTMLElement>(".stage-viewport")!;
|
|
56
64
|
const scaler = element.querySelector<HTMLElement>(".stage-scaler")!;
|
|
57
65
|
const iframe = element.querySelector<HTMLIFrameElement>("iframe")!;
|
|
66
|
+
let reviewMode = false;
|
|
58
67
|
/**
|
|
59
68
|
* Measure a clip in the rendered picture.
|
|
60
69
|
*
|
|
@@ -99,13 +108,45 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
|
|
|
99
108
|
// Clicking the picture selects whatever is drawn under the pointer, which is
|
|
100
109
|
// the third way into the same selection.
|
|
101
110
|
scaler.addEventListener("click", (event) => {
|
|
111
|
+
if (reviewMode) { toggle(); return; }
|
|
102
112
|
const clip = overlay.hitTest(event.clientX, event.clientY);
|
|
103
113
|
if (clip !== undefined) store.select(clip.id, "video");
|
|
104
114
|
else store.clearSelection();
|
|
105
115
|
});
|
|
116
|
+
// A broad component frame can cover smaller elements. Offer all actual
|
|
117
|
+
// Companion hits without special knowledge of captions or any other family.
|
|
118
|
+
let selectionMenu: HTMLElement | undefined;
|
|
119
|
+
const closeSelectionMenu = (): void => { selectionMenu?.remove(); selectionMenu = undefined; };
|
|
120
|
+
scaler.addEventListener("contextmenu", (event) => {
|
|
121
|
+
if (reviewMode) { event.preventDefault(); return; }
|
|
122
|
+
const hits = overlay.hitsAt(event.clientX, event.clientY);
|
|
123
|
+
if (hits.length === 0) return;
|
|
124
|
+
event.preventDefault(); stop(); closeSelectionMenu();
|
|
125
|
+
const menu = document.createElement("div");
|
|
126
|
+
menu.className = "selection-menu";
|
|
127
|
+
menu.setAttribute("role", "menu"); menu.setAttribute("aria-label", "Elements at this point");
|
|
128
|
+
for (const hit of hits) {
|
|
129
|
+
const option = document.createElement("button"); option.type = "button";
|
|
130
|
+
option.setAttribute("role", "menuitem"); option.textContent = hit.display.title;
|
|
131
|
+
option.title = hit.id;
|
|
132
|
+
option.addEventListener("click", () => { store.select(hit.id, "video"); closeSelectionMenu(); });
|
|
133
|
+
menu.append(option);
|
|
134
|
+
}
|
|
135
|
+
element.append(menu);
|
|
136
|
+
menu.style.left = `${Math.max(0, Math.min(event.clientX, window.innerWidth - menu.offsetWidth - 8))}px`;
|
|
137
|
+
menu.style.top = `${Math.max(0, Math.min(event.clientY, window.innerHeight - menu.offsetHeight - 8))}px`;
|
|
138
|
+
selectionMenu = menu; menu.querySelector("button")?.focus();
|
|
139
|
+
});
|
|
140
|
+
document.addEventListener("pointerdown", (event) => {
|
|
141
|
+
if (event.target instanceof Node && !selectionMenu?.contains(event.target)) closeSelectionMenu();
|
|
142
|
+
});
|
|
143
|
+
document.addEventListener("keydown", (event) => { if (event.key === "Escape") closeSelectionMenu(); });
|
|
106
144
|
// The room around the picture is empty in the plainest sense.
|
|
107
145
|
viewport.addEventListener("click", (event) => {
|
|
108
|
-
if (event.target === viewport)
|
|
146
|
+
if (event.target === viewport) {
|
|
147
|
+
if (reviewMode) toggle();
|
|
148
|
+
else store.clearSelection();
|
|
149
|
+
}
|
|
109
150
|
});
|
|
110
151
|
const play = element.querySelector<HTMLButtonElement>("[data-play]")!;
|
|
111
152
|
const previous = element.querySelector<HTMLButtonElement>("[data-previous]")!;
|
|
@@ -213,6 +254,18 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
|
|
|
213
254
|
const title = element.querySelector<HTMLElement>(".stage-title strong")!;
|
|
214
255
|
const back = element.querySelector<HTMLButtonElement>(".stage-return")!;
|
|
215
256
|
const scrubber = element.querySelector<HTMLInputElement>(".stage-scrubber")!;
|
|
257
|
+
const progress = element.querySelector<HTMLElement>(".stage-progress")!;
|
|
258
|
+
const scrubPreview = createScrubPreview(progress);
|
|
259
|
+
scrubber.addEventListener("pointermove", (event) => {
|
|
260
|
+
if (!reviewMode || state === undefined || scrubber.disabled || artifactPreview.selected !== undefined) return;
|
|
261
|
+
const box = scrubber.getBoundingClientRect();
|
|
262
|
+
// Native range thumbs travel between their centers, not the input edges.
|
|
263
|
+
const fraction = Math.max(0, Math.min(1, (event.clientX - box.left - 6) / Math.max(1, box.width - 12)));
|
|
264
|
+
const frame = Math.round(fraction * Math.max(0, state.snapshot.space.frameCount - 1));
|
|
265
|
+
scrubPreview.show(state.snapshot, frame, event.clientX);
|
|
266
|
+
});
|
|
267
|
+
scrubber.addEventListener("pointerleave", scrubPreview.hide);
|
|
268
|
+
scrubber.addEventListener("blur", scrubPreview.hide);
|
|
216
269
|
const time = element.querySelector<HTMLElement>(".stage-time")!;
|
|
217
270
|
const transport = element.querySelector<HTMLElement>(".stage-transport")!;
|
|
218
271
|
const clock = (seconds: number): string => {
|
|
@@ -227,7 +280,7 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
|
|
|
227
280
|
const duration = media !== undefined && Number.isFinite(media.duration) ? media.duration : 0;
|
|
228
281
|
transport.hidden = !timed;
|
|
229
282
|
mute.hidden = !timed;
|
|
230
|
-
scrubber.hidden = !timed;
|
|
283
|
+
progress.hidden = scrubber.hidden = !timed;
|
|
231
284
|
time.hidden = !timed;
|
|
232
285
|
play.disabled = duration <= 0 || media?.error != null;
|
|
233
286
|
previous.disabled = next.disabled = play.disabled;
|
|
@@ -244,7 +297,7 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
|
|
|
244
297
|
const compositionTime = (): void => {
|
|
245
298
|
if (state === undefined || artifactPreview.selected !== undefined) return;
|
|
246
299
|
const rate = fps(state.snapshot);
|
|
247
|
-
scrubber.hidden = time.hidden = false;
|
|
300
|
+
progress.hidden = scrubber.hidden = time.hidden = false;
|
|
248
301
|
scrubber.disabled = !ready;
|
|
249
302
|
scrubber.step = String(1 / rate);
|
|
250
303
|
scrubber.max = String(Math.max(0, state.snapshot.space.frameCount - 1) / rate);
|
|
@@ -309,6 +362,7 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
|
|
|
309
362
|
state = value;
|
|
310
363
|
if (moved && value.playhead.origin !== "play" && artifactPreview.selected !== undefined) returnToComposition();
|
|
311
364
|
if (value.snapshot.revision !== mounted) {
|
|
365
|
+
scrubPreview.clear();
|
|
312
366
|
mounted = value.snapshot.revision;
|
|
313
367
|
if (artifactPreview.selected === undefined) stop();
|
|
314
368
|
ready = false;
|
|
@@ -339,6 +393,15 @@ export function createStage(store: Store, selectedArtifact: (id: string | undefi
|
|
|
339
393
|
});
|
|
340
394
|
|
|
341
395
|
return { element, toggle, openArtifact,
|
|
396
|
+
setReviewMode(enabled) {
|
|
397
|
+
reviewMode = enabled;
|
|
398
|
+
element.classList.toggle("stage-review", enabled);
|
|
399
|
+
overlay.element.style.display = enabled ? "none" : "";
|
|
400
|
+
closeSelectionMenu();
|
|
401
|
+
if (!enabled) scrubPreview.clear();
|
|
402
|
+
},
|
|
403
|
+
pause() { stop(); artifactPreview.media?.pause(); },
|
|
404
|
+
showComposition() { if (artifactPreview.selected !== undefined) returnToComposition(); },
|
|
342
405
|
renameArtifact(artifact) {
|
|
343
406
|
const selected = artifactPreview.selected;
|
|
344
407
|
if (selected?.build === artifact.build && selected.output === artifact.output) title.textContent = artifact.displayName ?? artifact.output;
|
|
@@ -147,11 +147,20 @@ export function createTimeline(store: Store): Timeline {
|
|
|
147
147
|
let paintFrame = 0;
|
|
148
148
|
let rebuildFrame = 0;
|
|
149
149
|
const readableWordLabels = new Set<string>();
|
|
150
|
+
let selectedWord: string | undefined;
|
|
151
|
+
let overlapMenu: HTMLElement | undefined;
|
|
152
|
+
const closeOverlapMenu = () => { overlapMenu?.remove(); overlapMenu = undefined; };
|
|
153
|
+
element.addEventListener("pointerdown", event => {
|
|
154
|
+
if (!overlapMenu?.contains(event.target as Node)) closeOverlapMenu();
|
|
155
|
+
});
|
|
156
|
+
element.addEventListener("keydown", event => { if (event.key === "Escape") closeOverlapMenu(); });
|
|
157
|
+
body.addEventListener("scroll", closeOverlapMenu);
|
|
150
158
|
let clipNodes: readonly {
|
|
151
159
|
readonly node: HTMLElement;
|
|
152
160
|
readonly start: number;
|
|
153
161
|
readonly end: number;
|
|
154
162
|
readonly id: string;
|
|
163
|
+
readonly selectionGroup?: string;
|
|
155
164
|
}[] = [];
|
|
156
165
|
let semanticNodes: readonly {
|
|
157
166
|
readonly node: HTMLElement;
|
|
@@ -301,7 +310,7 @@ export function createTimeline(store: Store): Timeline {
|
|
|
301
310
|
const from = place(preview.startFrame, state.snapshot.space.frameCount, zoom.window());
|
|
302
311
|
const to = place(preview.endFrameExclusive, state.snapshot.space.frameCount, zoom.window());
|
|
303
312
|
activeEdit.node.style.left = `${from * 100}%`;
|
|
304
|
-
activeEdit.node.style.width = `max(2px,
|
|
313
|
+
activeEdit.node.style.width = `max(2px, ${Math.max(0, to - from) * 100}%)`;
|
|
305
314
|
}
|
|
306
315
|
return;
|
|
307
316
|
}
|
|
@@ -479,29 +488,32 @@ export function createTimeline(store: Store): Timeline {
|
|
|
479
488
|
.sort((left, right) => (left.binding.lane.order ?? 0) - (right.binding.lane.order ?? 0));
|
|
480
489
|
|
|
481
490
|
const buildSemanticLane = (snapshot: StudioSnapshot): void => {
|
|
482
|
-
if (snapshot.semantic === undefined) {
|
|
491
|
+
if (snapshot.semantic === undefined || snapshot.semantic.segments.length === 0) {
|
|
483
492
|
return;
|
|
484
493
|
}
|
|
485
494
|
const presentation = snapshot.semantic.presentation;
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
495
|
+
const bandHeight = Math.max(1, (presentation.lane.heightPx - itemMetrics.insetYPx * 2) / 3);
|
|
496
|
+
const bands = [
|
|
497
|
+
{ kind: "segment", height: bandHeight },
|
|
498
|
+
...(snapshot.semantic.tokens.length > 0 ? [{ kind: "word", height: bandHeight }] : []),
|
|
499
|
+
...(snapshot.semantic.selections.length + snapshot.semantic.moments.length > 0
|
|
500
|
+
? [{ kind: "intent", height: bandHeight }] : []),
|
|
501
|
+
];
|
|
502
|
+
const laneHeight = bands.reduce((height, band) => height + band.height, itemMetrics.insetYPx * 2);
|
|
491
503
|
const label = createTrackLabel(
|
|
492
|
-
presentation.label ?? "
|
|
504
|
+
presentation.label ?? "Timeline",
|
|
493
505
|
presentation.tone,
|
|
494
506
|
presentation.icon,
|
|
495
|
-
`${snapshot.semantic.segments.length}
|
|
507
|
+
`${snapshot.semantic.segments.length} segment${snapshot.semantic.segments.length === 1 ? "" : "s"}`,
|
|
496
508
|
laneHeight,
|
|
497
509
|
);
|
|
498
510
|
label.classList.add("track-label-semantic");
|
|
511
|
+
label.style.height = `calc(var(--timeline-ruler-height) + ${laneHeight}px)`;
|
|
499
512
|
labels.append(label);
|
|
500
513
|
|
|
501
514
|
const lane = document.createElement("div");
|
|
502
515
|
lane.className = `lane semantic-lane track-tone-${presentation.tone}`;
|
|
503
516
|
lane.style.height = `${laneHeight}px`;
|
|
504
|
-
lane.style.setProperty("--semantic-band-height", `${bandHeight}px`);
|
|
505
517
|
const laneWidth = lanes.clientWidth;
|
|
506
518
|
const nextSemanticNodes: {
|
|
507
519
|
node: HTMLElement;
|
|
@@ -511,12 +523,15 @@ export function createTimeline(store: Store): Timeline {
|
|
|
511
523
|
kind: "segment" | "word" | "selection" | "moment";
|
|
512
524
|
}[] = [];
|
|
513
525
|
|
|
514
|
-
|
|
515
|
-
for (const
|
|
526
|
+
let bandTop = itemMetrics.insetYPx;
|
|
527
|
+
for (const { kind, height } of bands) {
|
|
516
528
|
const band = document.createElement("div");
|
|
517
529
|
band.className = `semantic-band semantic-band-${kind}`;
|
|
518
|
-
band.style.top = `${
|
|
530
|
+
band.style.top = `${bandTop}px`;
|
|
531
|
+
band.style.setProperty("--semantic-band-height", `${height}px`);
|
|
532
|
+
band.setAttribute("aria-label", kind === "intent" ? "Selections and Moments" : kind === "word" ? "Words" : "Segments");
|
|
519
533
|
lane.append(band);
|
|
534
|
+
bandTop += height;
|
|
520
535
|
}
|
|
521
536
|
const segmentBand = lane.querySelector<HTMLElement>(".semantic-band-segment")!;
|
|
522
537
|
const wordBand = lane.querySelector<HTMLElement>(".semantic-band-word")!;
|
|
@@ -535,7 +550,7 @@ export function createTimeline(store: Store): Timeline {
|
|
|
535
550
|
node.dataset.semanticSegment = segment.id;
|
|
536
551
|
node.style.left = `${from * 100}%`;
|
|
537
552
|
const segmentWidth = Math.max(0, to - from) * 100;
|
|
538
|
-
node.style.width = `max(2px,
|
|
553
|
+
node.style.width = `max(2px, ${segmentWidth}%)`;
|
|
539
554
|
node.title = segment.id;
|
|
540
555
|
const segmentLabel = document.createElement("span");
|
|
541
556
|
segmentLabel.className = "semantic-segment-label";
|
|
@@ -575,12 +590,12 @@ export function createTimeline(store: Store): Timeline {
|
|
|
575
590
|
word.setAttribute("aria-label", token.text);
|
|
576
591
|
word.style.left = `${wordFrom * 100}%`;
|
|
577
592
|
const wordWidth = Math.max(0, wordTo - wordFrom);
|
|
578
|
-
word.style.width = `max(1px,
|
|
593
|
+
word.style.width = `max(1px, ${wordWidth * 100}%)`;
|
|
579
594
|
word.title = token.text;
|
|
580
595
|
const text = document.createElement("span");
|
|
581
596
|
text.className = "semantic-word-label";
|
|
582
597
|
text.textContent = token.text;
|
|
583
|
-
const wordWidthPx = Math.max(1, wordWidth * laneWidth
|
|
598
|
+
const wordWidthPx = Math.max(1, wordWidth * laneWidth);
|
|
584
599
|
const textWidthPx = measuredText(token.text);
|
|
585
600
|
const contentWidthPx = Math.max(0, wordWidthPx - wordLabelPaddingPx * 2);
|
|
586
601
|
const wasReadable = readableWordLabels.has(token.id);
|
|
@@ -596,6 +611,8 @@ export function createTimeline(store: Store): Timeline {
|
|
|
596
611
|
word.append(wordContent);
|
|
597
612
|
word.addEventListener("click", (event) => {
|
|
598
613
|
event.stopPropagation();
|
|
614
|
+
store.clearSelection();
|
|
615
|
+
selectedWord = token.id;
|
|
599
616
|
store.seek(token.startFrame, "timeline");
|
|
600
617
|
});
|
|
601
618
|
nextSemanticNodes.push({ node: word, id: token.id, start: token.startFrame, end: token.endFrameExclusive, kind: "word" });
|
|
@@ -611,7 +628,7 @@ export function createTimeline(store: Store): Timeline {
|
|
|
611
628
|
node.tabIndex = 0;
|
|
612
629
|
node.setAttribute("aria-label", `Selection ${selection.id}`);
|
|
613
630
|
node.style.left = `${from * 100}%`;
|
|
614
|
-
node.style.width = `max(2px,
|
|
631
|
+
node.style.width = `max(2px, ${Math.max(0, to - from) * 100}%)`;
|
|
615
632
|
node.title = selection.id;
|
|
616
633
|
const selectionLabel = document.createElement("span");
|
|
617
634
|
selectionLabel.className = "semantic-selection-label";
|
|
@@ -645,6 +662,33 @@ export function createTimeline(store: Store): Timeline {
|
|
|
645
662
|
intentBand.append(node);
|
|
646
663
|
nextSemanticNodes.push({ node, id: moment.id, start: moment.frame, end: moment.frame + 1, kind: "moment" });
|
|
647
664
|
}
|
|
665
|
+
lane.addEventListener("contextmenu", event => {
|
|
666
|
+
const hits = nextSemanticNodes.filter(({ node }) => {
|
|
667
|
+
const rect = node.getBoundingClientRect();
|
|
668
|
+
return event.clientX >= rect.left && event.clientX < rect.right
|
|
669
|
+
&& event.clientY >= rect.top && event.clientY < rect.bottom;
|
|
670
|
+
});
|
|
671
|
+
if (hits.length < 2) return;
|
|
672
|
+
event.preventDefault();
|
|
673
|
+
closeOverlapMenu();
|
|
674
|
+
const menu = document.createElement("div");
|
|
675
|
+
menu.className = "timeline-overlap-menu";
|
|
676
|
+
menu.setAttribute("role", "menu");
|
|
677
|
+
menu.setAttribute("aria-label", "Overlapping timeline objects");
|
|
678
|
+
for (const hit of [...hits].reverse()) {
|
|
679
|
+
const option = document.createElement("button");
|
|
680
|
+
option.type = "button";
|
|
681
|
+
option.setAttribute("role", "menuitem");
|
|
682
|
+
option.textContent = hit.node.getAttribute("aria-label") ?? hit.id;
|
|
683
|
+
option.addEventListener("click", () => { closeOverlapMenu(); hit.node.click(); });
|
|
684
|
+
menu.append(option);
|
|
685
|
+
}
|
|
686
|
+
element.append(menu);
|
|
687
|
+
menu.style.left = `${Math.max(0, Math.min(event.clientX, window.innerWidth - menu.offsetWidth - 8))}px`;
|
|
688
|
+
menu.style.top = `${Math.max(0, Math.min(event.clientY, window.innerHeight - menu.offsetHeight - 8))}px`;
|
|
689
|
+
overlapMenu = menu;
|
|
690
|
+
menu.querySelector("button")?.focus();
|
|
691
|
+
});
|
|
648
692
|
rows.append(lane);
|
|
649
693
|
semanticNodes = nextSemanticNodes;
|
|
650
694
|
};
|
|
@@ -652,118 +696,139 @@ export function createTimeline(store: Store): Timeline {
|
|
|
652
696
|
const buildTrack = (
|
|
653
697
|
snapshot: StudioSnapshot,
|
|
654
698
|
track: StudioSnapshot["tracks"][number],
|
|
655
|
-
nextClipNodes: { node: HTMLElement; start: number; end: number; id: string }[],
|
|
699
|
+
nextClipNodes: { node: HTMLElement; start: number; end: number; id: string; selectionGroup?: string }[],
|
|
656
700
|
attached = false,
|
|
657
701
|
): void => {
|
|
702
|
+
const trackBands = track.binding.bands ?? [];
|
|
703
|
+
const banded = trackBands.length > 0;
|
|
704
|
+
const layout = [
|
|
705
|
+
...trackBands.filter(band => band.placement === "before"),
|
|
706
|
+
{ id: undefined, heightPx: track.binding.lane.heightPx, display: "content" as const, tone: track.binding.tone },
|
|
707
|
+
...trackBands.filter(band => band.placement === "after"),
|
|
708
|
+
];
|
|
709
|
+
const totalHeight = layout.reduce((sum, band) => sum + band.heightPx, 0)
|
|
710
|
+
+ (banded ? 2 * itemMetrics.insetYPx : 0);
|
|
658
711
|
const tone = track.binding.tone;
|
|
659
|
-
const laneHeight = track.binding.lane.heightPx;
|
|
660
712
|
const displayedItems = track.clips.length;
|
|
661
713
|
const label = createTrackLabel(
|
|
662
714
|
displayTrackName(track),
|
|
663
715
|
tone,
|
|
664
716
|
track.binding.icon,
|
|
665
717
|
`${displayedItems} item${displayedItems === 1 ? "" : "s"}`,
|
|
666
|
-
|
|
718
|
+
totalHeight,
|
|
667
719
|
attached,
|
|
668
720
|
);
|
|
669
721
|
label.classList.add(`track-facet-${track.binding.facet}`);
|
|
670
722
|
labels.append(label);
|
|
671
723
|
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
const laneWidth = lanes.clientWidth;
|
|
724
|
+
const trackBody = document.createElement("div");
|
|
725
|
+
trackBody.className = banded ? "timeline-track timeline-track-banded" : "timeline-track";
|
|
726
|
+
trackBody.dataset.track = track.id;
|
|
727
|
+
trackBody.style.height = `${totalHeight}px`;
|
|
677
728
|
const materialMounts: {
|
|
678
729
|
readonly target: HTMLElement;
|
|
679
730
|
readonly preview: Extract<StudioSnapshot["tracks"][number]["clips"][number]["display"]["layers"][number], { readonly kind: "preview" }>["preview"];
|
|
680
731
|
}[] = [];
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
const
|
|
684
|
-
const
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
732
|
+
for (const band of layout) {
|
|
733
|
+
const tone = band.tone ?? track.binding.tone;
|
|
734
|
+
const laneHeight = band.heightPx;
|
|
735
|
+
const lane = document.createElement("div");
|
|
736
|
+
lane.className = `lane track-tone-${tone} track-facet-${track.binding.facet}${attached ? " lane-attached" : ""}`;
|
|
737
|
+
lane.style.height = `${laneHeight}px`;
|
|
738
|
+
if (banded) lane.classList.add("track-band", `track-band-${band.display}`);
|
|
739
|
+
if (band.id !== undefined) lane.dataset.band = band.id;
|
|
740
|
+
lane.style.setProperty("--lane-height", `${laneHeight}px`);
|
|
741
|
+
const laneWidth = lanes.clientWidth;
|
|
742
|
+
// Stable order preserves Companion projection order when stack levels tie.
|
|
743
|
+
for (const clip of track.clips.filter(clip => clip.band === band.id).sort((a, b) => a.stackOrder - b.stackOrder)) {
|
|
744
|
+
const from = place(clip.startFrame, snapshot.space.frameCount, zoom.window());
|
|
745
|
+
const to = place(clip.endFrameExclusive, snapshot.space.frameCount, zoom.window());
|
|
746
|
+
if (to <= 0 || from >= 1) continue;
|
|
747
|
+
const node = document.createElement("button");
|
|
748
|
+
node.type = "button";
|
|
749
|
+
node.className = `clip clip-tone-${tone} clip-facet-${track.binding.facet} clip-chrome-${clip.presentation.chrome}`;
|
|
750
|
+
node.classList.toggle("clip-editable", clip.editHandles.some((handle) => handle.enabled));
|
|
751
|
+
node.dataset.clip = clip.id;
|
|
752
|
+
node.setAttribute("aria-label", clip.display.title);
|
|
753
|
+
node.style.left = `${from * 100}%`;
|
|
754
|
+
node.style.width = `max(2px, ${Math.max(0, to - from) * 100}%)`;
|
|
755
|
+
const visibleWidthPx = visibleItemWidth(from, to, laneWidth);
|
|
756
|
+
node.classList.toggle("clip-preview-wide", visibleWidthPx >= 92);
|
|
757
|
+
node.title = `${clip.display.title} · ${clip.startFrame}-${clip.endFrameExclusive}f`;
|
|
758
|
+
node.innerHTML = `<span class="clip-head"><span class="clip-name"></span><span class="clip-meta"></span></span><span class="clip-body"><span class="clip-layers" aria-hidden="true"></span><span class="clip-phases"></span></span><span class="clip-boundary" aria-hidden="true"></span><span class="clip-selection" aria-hidden="true"></span>`;
|
|
759
|
+
const layers = node.querySelector<HTMLElement>(".clip-layers")!;
|
|
760
|
+
clip.display.layers.forEach((layer, index) => {
|
|
761
|
+
const layerNode = document.createElement("span");
|
|
762
|
+
layerNode.className = `clip-layer clip-layer-${layer.kind} clip-layer-role-${layer.role}`;
|
|
763
|
+
layerNode.style.zIndex = String(index + 1);
|
|
764
|
+
if (layer.kind === "text") {
|
|
765
|
+
layerNode.textContent = layer.text;
|
|
766
|
+
} else {
|
|
767
|
+
layerNode.classList.add(`clip-layer-layout-${layer.layout}`);
|
|
768
|
+
materialMounts.push({ target: layerNode, preview: layer.preview });
|
|
769
|
+
}
|
|
770
|
+
layers.append(layerNode);
|
|
771
|
+
});
|
|
772
|
+
const phaseLayer = node.querySelector<HTMLElement>(".clip-phases")!;
|
|
773
|
+
for (const phase of clip.temporal?.phases ?? []) {
|
|
774
|
+
if (phase.endFrameExclusive <= clip.startFrame || phase.startFrame >= clip.endFrameExclusive) continue;
|
|
775
|
+
const phaseNode = document.createElement("span");
|
|
776
|
+
phaseNode.className = `clip-phase clip-phase-${phase.role}`;
|
|
777
|
+
phaseNode.style.left = `${(phase.startFrame - clip.startFrame) / Math.max(1, clip.endFrameExclusive - clip.startFrame) * 100}%`;
|
|
778
|
+
phaseNode.style.width = `${(phase.endFrameExclusive - phase.startFrame) / Math.max(1, clip.endFrameExclusive - clip.startFrame) * 100}%`;
|
|
779
|
+
phaseLayer.append(phaseNode);
|
|
708
780
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
startFrame: pointerFrame,
|
|
746
|
-
pointerId: event.pointerId,
|
|
747
|
-
node,
|
|
748
|
-
originalLeft: node.style.left,
|
|
749
|
-
originalWidth: node.style.width,
|
|
750
|
-
};
|
|
751
|
-
node.classList.add("editing");
|
|
752
|
-
try { lanes.setPointerCapture(event.pointerId); } catch { /* local pointer */ }
|
|
781
|
+
const metaText = clip.presentation.chrome === "point"
|
|
782
|
+
? `${(clip.startFrame / fps(snapshot)).toFixed(2)}s`
|
|
783
|
+
: `${((clip.endFrameExclusive - clip.startFrame) / fps(snapshot)).toFixed(2)}s`;
|
|
784
|
+
const headerLabel = node.querySelector<HTMLElement>(".clip-name")!;
|
|
785
|
+
node.querySelector(".clip-meta")!.textContent = metaText;
|
|
786
|
+
headerLabel.textContent = clip.display.title;
|
|
787
|
+
node.addEventListener("pointerdown", (event) => {
|
|
788
|
+
const rect = node.getBoundingClientRect();
|
|
789
|
+
const edge = Math.min(8, Math.max(4, rect.width / 3));
|
|
790
|
+
const nearStart = event.clientX - rect.left <= edge;
|
|
791
|
+
const nearEnd = rect.right - event.clientX <= edge;
|
|
792
|
+
const handle = clip.editHandles.find((candidate) =>
|
|
793
|
+
candidate.enabled
|
|
794
|
+
&& ((candidate.gesture === "trim-start" && nearStart)
|
|
795
|
+
|| (candidate.gesture === "trim-end" && nearEnd)
|
|
796
|
+
|| (candidate.gesture === "move" && !nearStart && !nearEnd)));
|
|
797
|
+
if (handle !== undefined
|
|
798
|
+
&& (handle.gesture === "move" || handle.gesture === "trim-start" || handle.gesture === "trim-end")) {
|
|
799
|
+
event.stopPropagation();
|
|
800
|
+
const pointerFrame = handle.coordinate === "semantic-anchor"
|
|
801
|
+
? rawFrameAt(event.clientX)
|
|
802
|
+
: frameAt(event.clientX);
|
|
803
|
+
activeEdit = {
|
|
804
|
+
clip,
|
|
805
|
+
handle,
|
|
806
|
+
startFrame: pointerFrame,
|
|
807
|
+
pointerId: event.pointerId,
|
|
808
|
+
node,
|
|
809
|
+
originalLeft: node.style.left,
|
|
810
|
+
originalWidth: node.style.width,
|
|
811
|
+
};
|
|
812
|
+
node.classList.add("editing");
|
|
813
|
+
try { lanes.setPointerCapture(event.pointerId); } catch { /* local pointer */ }
|
|
814
|
+
store.select(clip.id, "timeline");
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
753
817
|
store.select(clip.id, "timeline");
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
lane.append(node);
|
|
818
|
+
});
|
|
819
|
+
node.addEventListener("dblclick", () => store.seek(clip.startFrame, "timeline"));
|
|
820
|
+
nextClipNodes.push({ node, start: clip.startFrame, end: clip.endFrameExclusive, id: clip.id, ...(clip.selectionGroup === undefined ? {} : { selectionGroup: clip.selectionGroup }) });
|
|
821
|
+
lane.append(node);
|
|
822
|
+
}
|
|
823
|
+
trackBody.append(lane);
|
|
761
824
|
}
|
|
762
|
-
rows.append(
|
|
825
|
+
rows.append(trackBody);
|
|
826
|
+
// Cached storyboards render synchronously and need connected, measurable targets.
|
|
763
827
|
for (const item of materialMounts) mountMaterialPreview(item.target, item.preview);
|
|
764
828
|
};
|
|
765
829
|
|
|
766
830
|
const build = (snapshot: StudioSnapshot): void => {
|
|
831
|
+
closeOverlapMenu();
|
|
767
832
|
const scrollTop = body.scrollTop;
|
|
768
833
|
labels.replaceChildren();
|
|
769
834
|
rows.replaceChildren();
|
|
@@ -771,9 +836,9 @@ export function createTimeline(store: Store): Timeline {
|
|
|
771
836
|
const corner = document.createElement("div");
|
|
772
837
|
corner.className = "label-corner";
|
|
773
838
|
corner.textContent = "";
|
|
774
|
-
labels.append(corner);
|
|
839
|
+
if (snapshot.semantic === undefined || snapshot.semantic.segments.length === 0) labels.append(corner);
|
|
775
840
|
buildSemanticLane(snapshot);
|
|
776
|
-
const nextClipNodes: { node: HTMLElement; start: number; end: number; id: string }[] = [];
|
|
841
|
+
const nextClipNodes: { node: HTMLElement; start: number; end: number; id: string; selectionGroup?: string }[] = [];
|
|
777
842
|
for (const track of snapshot.tracks) {
|
|
778
843
|
const attachedTo = track.binding.lane.attachedTo;
|
|
779
844
|
if (attachedTo !== undefined) continue;
|
|
@@ -804,8 +869,10 @@ export function createTimeline(store: Store): Timeline {
|
|
|
804
869
|
playhead.classList.toggle("outside", position < 0 || position > lanes.clientWidth);
|
|
805
870
|
playheadGrip.classList.toggle("outside", position < 0 || position > lanes.clientWidth);
|
|
806
871
|
timelineTime.textContent = frameTimecode(snapshot, head.frame);
|
|
872
|
+
const chosen = selection.kind === "clip" ? store.clip(selection.clipId) : undefined;
|
|
807
873
|
for (const item of clipNodes) {
|
|
808
|
-
const selected =
|
|
874
|
+
const selected = chosen !== undefined && (chosen.id === item.id
|
|
875
|
+
|| (chosen.selectionGroup !== undefined && chosen.selectionGroup === item.selectionGroup));
|
|
809
876
|
item.node.classList.toggle("selected", selected);
|
|
810
877
|
item.node.setAttribute("aria-pressed", String(selected));
|
|
811
878
|
item.node.classList.toggle("live", head.frame >= item.start && head.frame < item.end);
|
|
@@ -815,7 +882,8 @@ export function createTimeline(store: Store): Timeline {
|
|
|
815
882
|
(item.kind === "segment" || item.kind === "selection")
|
|
816
883
|
&& head.frame >= item.start && head.frame < item.end);
|
|
817
884
|
item.node.classList.toggle("current", item.kind === "word" && head.frame >= item.start && head.frame < item.end);
|
|
818
|
-
const selected = (item.kind === "
|
|
885
|
+
const selected = (item.kind === "word" && selectedWord === item.id && selection.kind === "none")
|
|
886
|
+
|| (item.kind === "segment"
|
|
819
887
|
&& selection.kind === "semantic-segment" && selection.segmentId === item.id)
|
|
820
888
|
|| (item.kind === "selection"
|
|
821
889
|
&& selection.kind === "semantic-selection" && selection.selectionId === item.id)
|
|
@@ -862,6 +930,7 @@ export function createTimeline(store: Store): Timeline {
|
|
|
862
930
|
zoom.subscribe(scheduleBuild);
|
|
863
931
|
store.subscribe((value) => {
|
|
864
932
|
state = value;
|
|
933
|
+
if (value.selection.kind !== "none") selectedWord = undefined;
|
|
865
934
|
if (value.snapshot.revision !== built) {
|
|
866
935
|
built = value.snapshot.revision;
|
|
867
936
|
build(value.snapshot);
|
package/packages/studio/start.ts
CHANGED
|
@@ -50,7 +50,7 @@ export async function runStudio(argv: readonly string[], io: Pick<CliIo, "write"
|
|
|
50
50
|
const runArgument = values.get("run");
|
|
51
51
|
if (runArgument === undefined || runArgument.trim().length === 0) invalidArguments("Missing --run");
|
|
52
52
|
const { createServer } = await import("vite");
|
|
53
|
-
const { findRuntimeProfile, resolveProjectRoot } = await import("@hypit/
|
|
53
|
+
const { findRuntimeProfile, resolveProjectRoot } = await import("@hypit/project-context-node");
|
|
54
54
|
const { resolveDistributionPackageImport } = await import("@hypit/package-loader-node");
|
|
55
55
|
const { videoCliDistribution, videoStudioCompanionPackages } = await import("@hypit/video-cli");
|
|
56
56
|
const { openStudioBuildLibrary } = await import("./src/build-library.js");
|
|
@@ -58,6 +58,7 @@ export async function runStudio(argv: readonly string[], io: Pick<CliIo, "write"
|
|
|
58
58
|
const { loadStudioDomain } = await import("./src/domain.js");
|
|
59
59
|
const { loadStudioRun } = await import("./src/run.js");
|
|
60
60
|
const { studioPlugin } = await import("./src/server.js");
|
|
61
|
+
const { studioFeedbackPlugin } = await import("./src/feedback-server.js");
|
|
61
62
|
const { inspectStudioRun } = await import("./src/studio-preflight.js");
|
|
62
63
|
const runPath = resolve(invokedFrom, runArgument);
|
|
63
64
|
const packageRootArgument = values.get("package-root");
|
|
@@ -136,7 +137,7 @@ export async function runStudio(argv: readonly string[], io: Pick<CliIo, "write"
|
|
|
136
137
|
// available for Source and material previews.
|
|
137
138
|
fs: { allow: [workspaceRoot, packageRoot, distributionPackageRoot, here] },
|
|
138
139
|
},
|
|
139
|
-
plugins: [distributionImports, studioPlugin({
|
|
140
|
+
plugins: [distributionImports, studioFeedbackPlugin(workspaceRoot, runPath), studioPlugin({
|
|
140
141
|
source,
|
|
141
142
|
runPath,
|
|
142
143
|
workspaceRoot,
|
|
@@ -152,4 +153,5 @@ export async function runStudio(argv: readonly string[], io: Pick<CliIo, "write"
|
|
|
152
153
|
});
|
|
153
154
|
await server.listen();
|
|
154
155
|
server.printUrls();
|
|
156
|
+
for (const url of server.resolvedUrls?.local ?? []) io.write(` Comments ${url}#comments\n`);
|
|
155
157
|
}
|