@remotion/studio 4.0.521 → 4.0.523

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 (264) hide show
  1. package/dist/api/install-package.js +4 -2
  2. package/dist/components/AssetAudioVolume.d.ts +5 -0
  3. package/dist/components/AssetAudioVolume.js +33 -0
  4. package/dist/components/Canvas.js +5 -6
  5. package/dist/components/CanvasIfSizeIsAvailable.js +7 -0
  6. package/dist/components/CaptionInspector.js +74 -20
  7. package/dist/components/CheckboardToggle.js +8 -6
  8. package/dist/components/Checkbox.d.ts +1 -0
  9. package/dist/components/Checkbox.js +2 -2
  10. package/dist/components/CompositionContextButton.js +4 -1
  11. package/dist/components/CompositionSelectorItem.js +2 -2
  12. package/dist/components/ConfigureLicenseModal.js +1 -1
  13. package/dist/components/CopyButton.js +7 -14
  14. package/dist/components/CurrentAsset.js +40 -6
  15. package/dist/components/Editor.js +6 -5
  16. package/dist/components/EditorContent.js +1 -1
  17. package/dist/components/EditorContexts.js +3 -1
  18. package/dist/components/ElementInstallConfirmation.js +290 -136
  19. package/dist/components/FixComputedValueModal.js +56 -16
  20. package/dist/components/FullscreenToggle.js +9 -8
  21. package/dist/components/GlobalKeybindings.js +50 -49
  22. package/dist/components/HighlightedElementSource.d.ts +5 -0
  23. package/dist/components/HighlightedElementSource.js +78 -0
  24. package/dist/components/InspectorLocationCopy.js +10 -5
  25. package/dist/components/InspectorPanel/MultiSequenceField.d.ts +12 -0
  26. package/dist/components/InspectorPanel/MultiSequenceField.js +131 -0
  27. package/dist/components/InspectorPanel/MultiSequenceInspector.d.ts +8 -0
  28. package/dist/components/InspectorPanel/MultiSequenceInspector.js +102 -0
  29. package/dist/components/InspectorPanel/MultiSequenceNumberField.d.ts +9 -0
  30. package/dist/components/InspectorPanel/MultiSequenceNumberField.js +88 -0
  31. package/dist/components/InspectorPanel.js +4 -0
  32. package/dist/components/InspectorSequenceSection.js +64 -1
  33. package/dist/components/InstallPackage.js +4 -5
  34. package/dist/components/KeyboardShortcutsSettings.js +212 -33
  35. package/dist/components/MenuBuildIndicator.js +7 -2
  36. package/dist/components/MenuCompositionName.js +62 -6
  37. package/dist/components/MenuToolbar.js +7 -5
  38. package/dist/components/ModalContainer.d.ts +1 -0
  39. package/dist/components/ModalContainer.js +2 -2
  40. package/dist/components/Modals.js +3 -1
  41. package/dist/components/ModelManager.d.ts +16 -0
  42. package/dist/components/ModelManager.js +200 -0
  43. package/dist/components/ModelsSettings.d.ts +2 -0
  44. package/dist/components/ModelsSettings.js +133 -0
  45. package/dist/components/NewComposition/DismissableModal.d.ts +1 -0
  46. package/dist/components/NewComposition/DismissableModal.js +2 -2
  47. package/dist/components/NewComposition/InputDragger.d.ts +2 -2
  48. package/dist/components/NewComposition/InputDragger.js +6 -6
  49. package/dist/components/NewComposition/NewFolder.js +11 -8
  50. package/dist/components/NewComposition/RenameFolder.js +17 -10
  51. package/dist/components/OptionalPackageModal.d.ts +11 -0
  52. package/dist/components/OptionalPackageModal.js +155 -0
  53. package/dist/components/PlayPause.js +4 -8
  54. package/dist/components/PlaybackKeyboardShortcutsManager.js +3 -6
  55. package/dist/components/PreviewToolbarOverflowButton.js +11 -2
  56. package/dist/components/QuickSwitcher/ExplorerQuickSwitcherTrigger.js +5 -2
  57. package/dist/components/RadioButton.d.ts +1 -0
  58. package/dist/components/RadioButton.js +2 -2
  59. package/dist/components/RenderButton.js +5 -1
  60. package/dist/components/RenderModal/CliCopyButton.js +13 -27
  61. package/dist/components/RenderModal/NumberSetting.d.ts +6 -1
  62. package/dist/components/RenderModal/NumberSetting.js +2 -2
  63. package/dist/components/RenderModal/RenderModalBasic.js +1 -1
  64. package/dist/components/RenderModal/RenderModalOutputName.d.ts +3 -1
  65. package/dist/components/RenderModal/RenderModalOutputName.js +4 -4
  66. package/dist/components/RenderModal/SeparateAudioOption.js +1 -1
  67. package/dist/components/RenderModal/WebRenderModalBasic.js +1 -1
  68. package/dist/components/RenderQueue/CaptionQueueItem.d.ts +6 -0
  69. package/dist/components/RenderQueue/CaptionQueueItem.js +129 -0
  70. package/dist/components/RenderQueue/CaptionQueueProcessor.d.ts +1 -0
  71. package/dist/components/RenderQueue/CaptionQueueProcessor.js +110 -0
  72. package/dist/components/RenderQueue/CaptionQueueProcessorLoader.d.ts +2 -0
  73. package/dist/components/RenderQueue/CaptionQueueProcessorLoader.js +54 -0
  74. package/dist/components/RenderQueue/RenderQueueCopyToClipboard.js +7 -4
  75. package/dist/components/RenderQueue/RenderQueueItem.js +3 -3
  76. package/dist/components/RenderQueue/VideoMattingQueueItem.d.ts +6 -0
  77. package/dist/components/RenderQueue/VideoMattingQueueItem.js +129 -0
  78. package/dist/components/RenderQueue/VideoMattingQueueProcessor.d.ts +1 -0
  79. package/dist/components/RenderQueue/VideoMattingQueueProcessor.js +105 -0
  80. package/dist/components/RenderQueue/VideoMattingQueueProcessorLoader.d.ts +2 -0
  81. package/dist/components/RenderQueue/VideoMattingQueueProcessorLoader.js +54 -0
  82. package/dist/components/RenderQueue/caption-job-types.d.ts +47 -0
  83. package/dist/components/RenderQueue/caption-job-types.js +7 -0
  84. package/dist/components/RenderQueue/context.d.ts +16 -0
  85. package/dist/components/RenderQueue/context.js +224 -11
  86. package/dist/components/RenderQueue/index.js +34 -10
  87. package/dist/components/RenderQueue/item-style.d.ts +1 -0
  88. package/dist/components/RenderQueue/item-style.js +2 -1
  89. package/dist/components/RenderQueue/load-model-for-job.d.ts +11 -0
  90. package/dist/components/RenderQueue/load-model-for-job.js +14 -0
  91. package/dist/components/RenderQueue/video-matting-job-types.d.ts +38 -0
  92. package/dist/components/RenderQueue/video-matting-job-types.js +5 -0
  93. package/dist/components/RendersTab.js +4 -4
  94. package/dist/components/SegmentedControl.d.ts +2 -2
  95. package/dist/components/SegmentedControl.js +38 -13
  96. package/dist/components/SelectedOutlinePolygon.js +8 -2
  97. package/dist/components/SettingsButton.d.ts +4 -0
  98. package/dist/components/SettingsButton.js +49 -0
  99. package/dist/components/SettingsModal.d.ts +1 -1
  100. package/dist/components/SettingsModal.js +3 -1
  101. package/dist/components/ShowOutlinesProvider.js +12 -0
  102. package/dist/components/SidebarCollapserControls.js +21 -16
  103. package/dist/components/SizeSelector.js +10 -2
  104. package/dist/components/SkillsSettings.js +11 -8
  105. package/dist/components/SnappingToggle.js +5 -2
  106. package/dist/components/Splitter/SplitterContainer.js +63 -10
  107. package/dist/components/Splitter/SplitterContext.d.ts +3 -0
  108. package/dist/components/Splitter/SplitterContext.js +5 -1
  109. package/dist/components/Splitter/SplitterElement.js +11 -2
  110. package/dist/components/Splitter/SplitterHandle.d.ts +1 -0
  111. package/dist/components/Splitter/SplitterHandle.js +55 -25
  112. package/dist/components/Tabs/vertical.d.ts +1 -0
  113. package/dist/components/Tabs/vertical.js +2 -2
  114. package/dist/components/TimeValue.js +2 -3
  115. package/dist/components/Timeline/SequencePropsObserver.js +4 -0
  116. package/dist/components/Timeline/SubscribeToNodePaths.d.ts +2 -1
  117. package/dist/components/Timeline/SubscribeToNodePaths.js +2 -1
  118. package/dist/components/Timeline/Timeline.js +17 -46
  119. package/dist/components/Timeline/TimelineClipboardKeybindings.js +2 -4
  120. package/dist/components/Timeline/TimelineDeleteKeybindings.js +3 -18
  121. package/dist/components/Timeline/TimelineDragHandler.js +11 -6
  122. package/dist/components/Timeline/TimelineExpandedKeyframeRow.js +1 -0
  123. package/dist/components/Timeline/TimelinePinchZoom.js +6 -30
  124. package/dist/components/Timeline/TimelinePlayCursorSyncer.js +1 -7
  125. package/dist/components/Timeline/TimelineRowChrome.js +11 -3
  126. package/dist/components/Timeline/TimelineSchemaField.js +8 -4
  127. package/dist/components/Timeline/TimelineSelection.d.ts +2 -0
  128. package/dist/components/Timeline/TimelineSelection.js +55 -2
  129. package/dist/components/Timeline/TimelineSequence.js +148 -25
  130. package/dist/components/Timeline/TimelineSequenceItem.d.ts +0 -1
  131. package/dist/components/Timeline/TimelineSequenceItem.js +220 -112
  132. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +35 -5
  133. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +233 -138
  134. package/dist/components/Timeline/TimelineSlider.js +1 -4
  135. package/dist/components/Timeline/TimelineTimeIndicators.js +1 -0
  136. package/dist/components/Timeline/TimelineWidthProvider.js +2 -5
  137. package/dist/components/Timeline/TimelineZoomControls.js +20 -20
  138. package/dist/components/Timeline/get-sequence-split-menu-item.d.ts +11 -0
  139. package/dist/components/Timeline/get-sequence-split-menu-item.js +55 -0
  140. package/dist/components/Timeline/use-asset-timeline-context-menu.d.ts +2 -0
  141. package/dist/components/Timeline/use-asset-timeline-context-menu.js +52 -0
  142. package/dist/components/Timeline/use-sequence-props-subscription.d.ts +3 -2
  143. package/dist/components/Timeline/use-sequence-props-subscription.js +4 -10
  144. package/dist/components/TimelineInOutToggle.js +20 -17
  145. package/dist/components/TopPanel.js +3 -19
  146. package/dist/components/Transcription/LazyModels.d.ts +1 -0
  147. package/dist/components/Transcription/LazyModels.js +5 -0
  148. package/dist/components/Transcription/Models.d.ts +6 -0
  149. package/dist/components/Transcription/Models.js +18 -0
  150. package/dist/components/Transcription/TranscriptionModal.d.ts +3 -0
  151. package/dist/components/Transcription/TranscriptionModal.js +428 -0
  152. package/dist/components/Transcription/TranscriptionModalWithOptionalWhisper.d.ts +5 -0
  153. package/dist/components/Transcription/TranscriptionModalWithOptionalWhisper.js +48 -0
  154. package/dist/components/Transcription/caption-output-name.d.ts +2 -0
  155. package/dist/components/Transcription/caption-output-name.js +10 -0
  156. package/dist/components/Transcription/resample-media-to-16-khz.d.ts +6 -0
  157. package/dist/components/Transcription/resample-media-to-16-khz.js +82 -0
  158. package/dist/components/Transcription/whisper-languages.d.ts +2 -0
  159. package/dist/components/Transcription/whisper-languages.js +104 -0
  160. package/dist/components/Transcription/whisper-webgpu-capability.d.ts +2 -0
  161. package/dist/components/Transcription/whisper-webgpu-capability.js +7 -0
  162. package/dist/components/UndoRedoButtons.js +13 -38
  163. package/dist/components/UpdatesSettings.js +17 -17
  164. package/dist/components/VideoMatting/LazyModels.d.ts +1 -0
  165. package/dist/components/VideoMatting/LazyModels.js +5 -0
  166. package/dist/components/VideoMatting/Models.d.ts +6 -0
  167. package/dist/components/VideoMatting/Models.js +18 -0
  168. package/dist/components/VideoMatting/VideoMattingModal.d.ts +3 -0
  169. package/dist/components/VideoMatting/VideoMattingModal.js +207 -0
  170. package/dist/components/VideoMatting/VideoMattingModalWithOptionalPackage.d.ts +5 -0
  171. package/dist/components/VideoMatting/VideoMattingModalWithOptionalPackage.js +46 -0
  172. package/dist/components/VideoMatting/video-matting-capability.d.ts +2 -0
  173. package/dist/components/VideoMatting/video-matting-capability.js +7 -0
  174. package/dist/components/WebMcp.js +439 -22
  175. package/dist/components/ZoomPersistor.js +6 -3
  176. package/dist/components/composition-menu-items.js +1 -1
  177. package/dist/components/import-assets.d.ts +3 -2
  178. package/dist/components/import-assets.js +5 -9
  179. package/dist/components/keyboard-shortcuts.d.ts +17 -1
  180. package/dist/components/keyboard-shortcuts.js +177 -89
  181. package/dist/components/public-output-name.d.ts +5 -0
  182. package/dist/components/public-output-name.js +60 -0
  183. package/dist/components/use-model-cache-status.d.ts +7 -0
  184. package/dist/components/use-model-cache-status.js +35 -0
  185. package/dist/esm/CaptionQueueProcessor-k0yrm3dj.mjs +211 -0
  186. package/dist/esm/HighlightedElementSource-jfc66k4p.mjs +1236 -0
  187. package/dist/esm/LazyModels-2trdm224.mjs +11 -0
  188. package/dist/esm/LazyModels-fjb5ckaq.mjs +11 -0
  189. package/dist/esm/TranscriptionModal-916jqhry.mjs +1011 -0
  190. package/dist/esm/VideoMattingModal-2tm79s9b.mjs +374 -0
  191. package/dist/esm/VideoMattingQueueProcessor-t1hgm2rm.mjs +109 -0
  192. package/dist/esm/index-1x7bsdh6.mjs +261 -0
  193. package/dist/esm/index-3hgr6gjx.mjs +41 -0
  194. package/dist/esm/index-5qddp5h7.mjs +36 -0
  195. package/dist/esm/index-5zrb1ft4.mjs +39 -0
  196. package/dist/esm/index-6cvm9a65.mjs +45923 -0
  197. package/dist/esm/index-7tt71e8n.mjs +36 -0
  198. package/dist/esm/index-9x6e1dq0.mjs +428 -0
  199. package/dist/esm/index-cw0pnpg5.mjs +50 -0
  200. package/dist/esm/index-czwvnn9g.mjs +35 -0
  201. package/dist/esm/index-hy4xcgty.mjs +1366 -0
  202. package/dist/esm/{chunk-je0h1bgt.js → index-jg13hf2g.mjs} +3 -1
  203. package/dist/esm/{chunk-6jf1natv.js → index-rcv7qkt5.mjs} +18 -1
  204. package/dist/esm/index-sgtmgc4h.mjs +423 -0
  205. package/dist/esm/index-te66vvrp.mjs +142 -0
  206. package/dist/esm/index-v4tr1bft.mjs +20 -0
  207. package/dist/esm/index-x7t2y7ws.mjs +54194 -0
  208. package/dist/esm/index-xhe2m2qr.mjs +1146 -0
  209. package/dist/esm/index.mjs +45 -933
  210. package/dist/esm/internals.mjs +13 -114127
  211. package/dist/esm/previewEntry.mjs +387 -114784
  212. package/dist/esm/renderEntry.mjs +3 -3
  213. package/dist/esm/{chunk-m0jqdbkr.js → resolve-composition-component-location-14148845.mjs} +1 -1
  214. package/dist/helpers/copy-text.js +1 -2
  215. package/dist/helpers/drag-aware-double-click.d.ts +2 -1
  216. package/dist/helpers/drag-aware-double-click.js +12 -1
  217. package/dist/helpers/get-asset-metadata.d.ts +1 -0
  218. package/dist/helpers/get-asset-metadata.js +4 -0
  219. package/dist/helpers/hoverable.js +8 -0
  220. package/dist/helpers/inject-css.js +2 -0
  221. package/dist/helpers/optional-package-dependencies.d.ts +3 -0
  222. package/dist/helpers/optional-package-dependencies.js +24 -0
  223. package/dist/helpers/pointer-session.d.ts +6 -0
  224. package/dist/helpers/pointer-session.js +36 -14
  225. package/dist/helpers/prism-tomorrow.d.ts +1 -0
  226. package/dist/helpers/prism-tomorrow.js +151 -0
  227. package/dist/helpers/sequence-node-path-mutations.js +11 -0
  228. package/dist/helpers/slugify-name.d.ts +1 -0
  229. package/dist/helpers/slugify-name.js +14 -0
  230. package/dist/helpers/studio-runtime-config.d.ts +1 -0
  231. package/dist/helpers/studio-runtime-config.js +6 -1
  232. package/dist/helpers/use-copy-feedback.d.ts +4 -0
  233. package/dist/helpers/use-copy-feedback.js +19 -0
  234. package/dist/helpers/use-keybinding.d.ts +9 -3
  235. package/dist/helpers/use-keybinding.js +8 -9
  236. package/dist/helpers/use-keyboard-shortcut-label.d.ts +2 -0
  237. package/dist/helpers/use-keyboard-shortcut-label.js +15 -0
  238. package/dist/helpers/use-menu-structure.js +58 -13
  239. package/dist/icons/copy.d.ts +5 -0
  240. package/dist/icons/copy.js +12 -0
  241. package/dist/icons/input-props.d.ts +1 -1
  242. package/dist/icons/input-props.js +2 -2
  243. package/dist/icons/models.d.ts +4 -0
  244. package/dist/icons/models.js +7 -0
  245. package/dist/icons/separation.d.ts +4 -0
  246. package/dist/icons/separation.js +7 -0
  247. package/dist/icons/transcription.d.ts +4 -0
  248. package/dist/icons/transcription.js +7 -0
  249. package/dist/icons/upload.js +1 -1
  250. package/dist/state/canvas-ref.d.ts +1 -0
  251. package/dist/state/canvas-ref.js +2 -1
  252. package/dist/state/modals.d.ts +14 -2
  253. package/dist/state/sidebar.d.ts +3 -0
  254. package/dist/state/sidebar.js +6 -1
  255. package/dist/state/timeline-zoom.d.ts +1 -1
  256. package/dist/state/timeline-zoom.js +3 -3
  257. package/dist/visual-controls/VisualControls.js +4 -0
  258. package/package.json +34 -20
  259. package/dist/components/UpdateCheck.d.ts +0 -1
  260. package/dist/components/UpdateCheck.js +0 -79
  261. package/dist/esm/chunk-emw4k5b0.js +0 -99527
  262. package/dist/esm/chunk-vkrvnx2h.js +0 -99378
  263. package/dist/helpers/use-max-media-duration.d.ts +0 -2
  264. package/dist/helpers/use-max-media-duration.js +0 -61
@@ -22,10 +22,13 @@ const ZoomPersistor = () => {
22
22
  const { canvasContent } = (0, react_1.useContext)(remotion_1.Internals.CompositionManager);
23
23
  const urlState = (0, load_canvas_content_from_url_1.deriveCanvasContentFromUrl)();
24
24
  const isActive = urlState &&
25
- urlState.type === 'composition' &&
26
25
  canvasContent &&
27
- canvasContent.type === 'composition' &&
28
- urlState.compositionId === canvasContent.compositionId;
26
+ ((urlState.type === 'composition' &&
27
+ canvasContent.type === 'composition' &&
28
+ urlState.compositionId === canvasContent.compositionId) ||
29
+ (urlState.type === 'asset' &&
30
+ canvasContent.type === 'asset' &&
31
+ urlState.asset === canvasContent.asset));
29
32
  (0, react_1.useEffect)(() => {
30
33
  if (!isActive) {
31
34
  return;
@@ -218,7 +218,7 @@ const getCompositionMenuItems = ({ composition, connectionStatus, resolvedLocati
218
218
  navigator.clipboard
219
219
  .writeText(composition.id)
220
220
  .then(() => {
221
- (0, NotificationCenter_1.showNotification)('Copied to clipboard', 1000);
221
+ (0, NotificationCenter_1.showNotification)('Copied composition name', 1000);
222
222
  })
223
223
  .catch((err) => {
224
224
  (0, NotificationCenter_1.showNotification)(`Could not copy to clipboard: ${err.message}`, 1000);
@@ -156,7 +156,8 @@ export declare const insertComposition: ({ composition, compositionFile, composi
156
156
  from: number | null;
157
157
  preferCompositionStart: boolean | null;
158
158
  }) => Promise<void>;
159
- export declare const insertElement: ({ compositionFile, compositionId, element, expectedFileState, position, from, overwriteExisting, }: {
159
+ export declare const insertElement: ({ installationName, compositionFile, compositionId, element, expectedFileState, position, from, overwriteExisting, }: {
160
+ installationName: string | null;
160
161
  compositionFile: string;
161
162
  compositionId: string;
162
163
  element: InstallableElement;
@@ -164,4 +165,4 @@ export declare const insertElement: ({ compositionFile, compositionId, element,
164
165
  position: InsertableCompositionElementPosition | null;
165
166
  from: number | null;
166
167
  overwriteExisting: boolean;
167
- }) => Promise<void>;
168
+ }) => Promise<boolean>;
@@ -479,13 +479,6 @@ const insertCompositionElement = async ({ compositionFile, compositionId, elemen
479
479
  (0, NotificationCenter_1.showNotification)(result.reason, 4000);
480
480
  return false;
481
481
  }
482
- if (result.insertedNodePath !== null) {
483
- (0, inserted_element_selection_1.requestInsertedElementSelection)({
484
- compositionId,
485
- nodePath: result.insertedNodePath,
486
- notification: null,
487
- });
488
- }
489
482
  return true;
490
483
  };
491
484
  const downloadRemoteAsset = (url) => {
@@ -882,12 +875,13 @@ const insertComposition = async ({ composition, compositionFile, compositionId,
882
875
  }
883
876
  };
884
877
  exports.insertComposition = insertComposition;
885
- const insertElement = async ({ compositionFile, compositionId, element, expectedFileState, position, from, overwriteExisting, }) => {
878
+ const insertElement = async ({ installationName, compositionFile, compositionId, element, expectedFileState, position, from, overwriteExisting, }) => {
886
879
  try {
887
880
  if ((0, browser_studio_operations_1.getBrowserStudioOperations)() === null) {
888
881
  await (0, install_required_package_1.installRequiredPackages)(element.dependencies);
889
882
  }
890
883
  const response = await (0, element_install_api_1.installElement)({
884
+ installationName,
891
885
  compositionFile,
892
886
  compositionId,
893
887
  element,
@@ -901,16 +895,18 @@ const insertElement = async ({ compositionFile, compositionId, element, expected
901
895
  ? response.reason
902
896
  : `Element file changed: ${response.conflict.filePath}`;
903
897
  (0, NotificationCenter_1.showNotification)(`Could not add Element: ${reason}`, 4000);
904
- return;
898
+ return false;
905
899
  }
906
900
  (0, inserted_element_selection_1.requestInsertedElementSelection)({
907
901
  compositionId,
908
902
  nodePath: null,
909
903
  notification: `Installed ${element.displayName}`,
910
904
  });
905
+ return true;
911
906
  }
912
907
  catch (error) {
913
908
  (0, NotificationCenter_1.showNotification)(`Could not add Element: ${error instanceof Error ? error.message : String(error)}`, 4000);
909
+ return false;
914
910
  }
915
911
  };
916
912
  exports.insertElement = insertElement;
@@ -1,10 +1,26 @@
1
+ import type { StudioKeyboardShortcut, StudioKeyboardShortcutAction, StudioKeyboardShortcutValue } from '@remotion/studio-shared';
1
2
  export type KeyboardShortcut = {
2
3
  readonly action: string;
3
- readonly chords: readonly (readonly string[])[];
4
+ readonly actionId: StudioKeyboardShortcutAction | null;
5
+ readonly fixedChords?: readonly (readonly string[])[];
6
+ readonly fixedReason?: string;
4
7
  };
5
8
  export type KeyboardShortcutGroup = {
6
9
  readonly name: string;
7
10
  readonly shortcuts: readonly KeyboardShortcut[];
8
11
  };
12
+ export declare const defaultKeyboardShortcuts: Record<StudioKeyboardShortcutAction, readonly StudioKeyboardShortcut[]>;
9
13
  export declare const keyboardShortcutGroups: readonly KeyboardShortcutGroup[];
10
14
  export declare const askAIKeyboardShortcutGroup: KeyboardShortcutGroup;
15
+ export declare const getKeyboardShortcutsForAction: (action: "askAI" | "clearInOutPoints" | "copyEffectsAndValues" | "cutEffects" | "deleteSelection" | "duplicateSequences" | "enterFullscreen" | "goToFrame" | "jumpToBeginning" | "jumpToEnd" | "nextComposition" | "pauseAndReturnToPlaybackStart" | "pausePlayback" | "playForward" | "playPause" | "previousComposition" | "quickSwitcher" | "redo" | "render" | "resetZoom" | "reversePlayback" | "selectAllSequenceRows" | "selectOpacityProp" | "selectRotateProp" | "selectScaleProp" | "selectTranslateProp" | "setInPoint" | "setOutPoint" | "showKeyboardShortcuts" | "toggleBothSidebars" | "toggleCheckerboard" | "toggleLeftSidebar" | "toggleRightSidebar" | "toggleSnapping" | "undo" | "zoomIn" | "zoomOut", configured?: Partial<Record<"askAI" | "clearInOutPoints" | "copyEffectsAndValues" | "cutEffects" | "deleteSelection" | "duplicateSequences" | "enterFullscreen" | "goToFrame" | "jumpToBeginning" | "jumpToEnd" | "nextComposition" | "pauseAndReturnToPlaybackStart" | "pausePlayback" | "playForward" | "playPause" | "previousComposition" | "quickSwitcher" | "redo" | "render" | "resetZoom" | "reversePlayback" | "selectAllSequenceRows" | "selectOpacityProp" | "selectRotateProp" | "selectScaleProp" | "selectTranslateProp" | "setInPoint" | "setOutPoint" | "showKeyboardShortcuts" | "toggleBothSidebars" | "toggleCheckerboard" | "toggleLeftSidebar" | "toggleRightSidebar" | "toggleSnapping" | "undo" | "zoomIn" | "zoomOut", StudioKeyboardShortcutValue>> | null) => readonly StudioKeyboardShortcut[];
16
+ export declare const keyboardEventMatchesShortcut: ({ event, shortcut: value, }: {
17
+ readonly event: KeyboardEvent;
18
+ readonly shortcut: StudioKeyboardShortcut;
19
+ }) => boolean;
20
+ export declare const keyboardShortcutsOverlap: (first: StudioKeyboardShortcut, second: StudioKeyboardShortcut) => boolean;
21
+ export declare const keyboardEventMatchesAction: (event: KeyboardEvent, action: "askAI" | "clearInOutPoints" | "copyEffectsAndValues" | "cutEffects" | "deleteSelection" | "duplicateSequences" | "enterFullscreen" | "goToFrame" | "jumpToBeginning" | "jumpToEnd" | "nextComposition" | "pauseAndReturnToPlaybackStart" | "pausePlayback" | "playForward" | "playPause" | "previousComposition" | "quickSwitcher" | "redo" | "render" | "resetZoom" | "reversePlayback" | "selectAllSequenceRows" | "selectOpacityProp" | "selectRotateProp" | "selectScaleProp" | "selectTranslateProp" | "setInPoint" | "setOutPoint" | "showKeyboardShortcuts" | "toggleBothSidebars" | "toggleCheckerboard" | "toggleLeftSidebar" | "toggleRightSidebar" | "toggleSnapping" | "undo" | "zoomIn" | "zoomOut") => boolean;
22
+ export declare const formatKeyboardShortcut: (value: StudioKeyboardShortcut) => readonly string[];
23
+ export declare const formatKeyboardShortcutForAria: (value: StudioKeyboardShortcut) => string;
24
+ export declare const getKeyboardShortcutLabel: (action: "askAI" | "clearInOutPoints" | "copyEffectsAndValues" | "cutEffects" | "deleteSelection" | "duplicateSequences" | "enterFullscreen" | "goToFrame" | "jumpToBeginning" | "jumpToEnd" | "nextComposition" | "pauseAndReturnToPlaybackStart" | "pausePlayback" | "playForward" | "playPause" | "previousComposition" | "quickSwitcher" | "redo" | "render" | "resetZoom" | "reversePlayback" | "selectAllSequenceRows" | "selectOpacityProp" | "selectRotateProp" | "selectScaleProp" | "selectTranslateProp" | "setInPoint" | "setOutPoint" | "showKeyboardShortcuts" | "toggleBothSidebars" | "toggleCheckerboard" | "toggleLeftSidebar" | "toggleRightSidebar" | "toggleSnapping" | "undo" | "zoomIn" | "zoomOut") => string;
25
+ export declare const getKeyboardShortcutAriaKeyShortcuts: (action: "askAI" | "clearInOutPoints" | "copyEffectsAndValues" | "cutEffects" | "deleteSelection" | "duplicateSequences" | "enterFullscreen" | "goToFrame" | "jumpToBeginning" | "jumpToEnd" | "nextComposition" | "pauseAndReturnToPlaybackStart" | "pausePlayback" | "playForward" | "playPause" | "previousComposition" | "quickSwitcher" | "redo" | "render" | "resetZoom" | "reversePlayback" | "selectAllSequenceRows" | "selectOpacityProp" | "selectRotateProp" | "selectScaleProp" | "selectTranslateProp" | "setInPoint" | "setOutPoint" | "showKeyboardShortcuts" | "toggleBothSidebars" | "toggleCheckerboard" | "toggleLeftSidebar" | "toggleRightSidebar" | "toggleSnapping" | "undo" | "zoomIn" | "zoomOut") => string;
26
+ export declare const shortcutFromKeyboardEvent: (event: KeyboardEvent) => StudioKeyboardShortcut | null;
@@ -1,135 +1,223 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.askAIKeyboardShortcutGroup = exports.keyboardShortcutGroups = void 0;
4
- const ShortcutHint_1 = require("../error-overlay/remotion-overlay/ShortcutHint");
3
+ exports.shortcutFromKeyboardEvent = exports.getKeyboardShortcutAriaKeyShortcuts = exports.getKeyboardShortcutLabel = exports.formatKeyboardShortcutForAria = exports.formatKeyboardShortcut = exports.keyboardEventMatchesAction = exports.keyboardShortcutsOverlap = exports.keyboardEventMatchesShortcut = exports.getKeyboardShortcutsForAction = exports.askAIKeyboardShortcutGroup = exports.keyboardShortcutGroups = exports.defaultKeyboardShortcuts = void 0;
5
4
  const is_mac_1 = require("../helpers/is-mac");
5
+ const studio_runtime_config_1 = require("../helpers/studio-runtime-config");
6
+ const shortcut = (action, actionId) => ({ action, actionId });
7
+ const fixedShortcut = (action, fixedChords, fixedReason) => ({ action, actionId: null, fixedChords, fixedReason });
8
+ exports.defaultKeyboardShortcuts = {
9
+ playPause: [{ key: 'Space' }],
10
+ jumpToBeginning: [{ key: 'a' }],
11
+ jumpToEnd: [{ key: 'e' }],
12
+ reversePlayback: [{ key: 'j' }],
13
+ pausePlayback: [{ key: 'k' }],
14
+ playForward: [{ key: 'l' }],
15
+ goToFrame: [{ key: 'g' }],
16
+ pauseAndReturnToPlaybackStart: [{ key: 'Enter' }],
17
+ toggleLeftSidebar: [{ key: 'b', commandOrControl: true }],
18
+ toggleRightSidebar: [{ key: 'j', commandOrControl: true }],
19
+ toggleBothSidebars: [{ key: 'g', commandOrControl: true }],
20
+ enterFullscreen: [{ key: 'f' }],
21
+ toggleSnapping: [{ key: 'm', shift: true }],
22
+ previousComposition: [{ key: 'PageUp' }],
23
+ nextComposition: [{ key: 'PageDown' }],
24
+ showKeyboardShortcuts: [{ key: '?', shift: true }],
25
+ quickSwitcher: [{ key: 'k', commandOrControl: true }],
26
+ render: [{ key: 'r' }],
27
+ toggleCheckerboard: [{ key: 't' }],
28
+ setInPoint: [{ key: 'i' }],
29
+ setOutPoint: [{ key: 'o' }],
30
+ clearInOutPoints: [{ key: 'x' }],
31
+ zoomIn: [{ key: '+', shift: true }, { key: '+' }],
32
+ zoomOut: [{ key: '-' }],
33
+ resetZoom: [{ key: '0' }],
34
+ undo: [{ key: 'z', commandOrControl: true }],
35
+ redo: [
36
+ ...(is_mac_1.isMac ? [] : [{ key: 'y', commandOrControl: true }]),
37
+ { key: 'z', commandOrControl: true, shift: true },
38
+ ],
39
+ selectAllSequenceRows: [{ key: 'a', commandOrControl: true }],
40
+ selectTranslateProp: [{ key: 'p' }],
41
+ selectOpacityProp: [{ key: 't' }],
42
+ selectRotateProp: [{ key: 'r' }],
43
+ selectScaleProp: [{ key: 's' }],
44
+ duplicateSequences: [{ key: 'd', commandOrControl: true }],
45
+ copyEffectsAndValues: [{ key: 'c', commandOrControl: true }],
46
+ cutEffects: [{ key: 'x', commandOrControl: true }],
47
+ deleteSelection: [{ key: 'Backspace' }, { key: 'Delete' }],
48
+ askAI: [{ key: 'i', commandOrControl: true }],
49
+ };
6
50
  exports.keyboardShortcutGroups = [
7
51
  {
8
52
  name: 'Playback',
9
53
  shortcuts: [
10
- { action: '1 second back', chords: [['Shift', '←']] },
11
- { action: 'Previous frame', chords: [['←']] },
12
- { action: 'Play / Pause', chords: [['Space']] },
13
- { action: 'Next frame', chords: [['→']] },
14
- { action: '1 second forward', chords: [['Shift', '→']] },
15
- { action: 'Jump to beginning', chords: [['A']] },
16
- { action: 'Jump to end', chords: [['E']] },
17
- { action: 'Reverse playback', chords: [['J']] },
18
- { action: 'Pause', chords: [['K']] },
19
- { action: 'Play / Speed up', chords: [['L']] },
20
- { action: 'Go to frame', chords: [['G']] },
21
- {
22
- action: 'Pause & return to playback start',
23
- chords: [['Enter']],
24
- },
54
+ fixedShortcut('1 second back', [['Shift', '←']], 'Context-sensitive timeline control'),
55
+ fixedShortcut('Previous frame', [['←']], 'Context-sensitive timeline control'),
56
+ shortcut('Play / Pause', 'playPause'),
57
+ fixedShortcut('Next frame', [['→']], 'Context-sensitive timeline control'),
58
+ fixedShortcut('1 second forward', [['Shift', '→']], 'Context-sensitive timeline control'),
59
+ shortcut('Jump to beginning', 'jumpToBeginning'),
60
+ shortcut('Jump to end', 'jumpToEnd'),
61
+ shortcut('Reverse playback', 'reversePlayback'),
62
+ shortcut('Pause', 'pausePlayback'),
63
+ shortcut('Play / Speed up', 'playForward'),
64
+ shortcut('Go to frame', 'goToFrame'),
65
+ shortcut('Pause & return to playback start', 'pauseAndReturnToPlaybackStart'),
25
66
  ],
26
67
  },
27
68
  {
28
69
  name: 'Sidebar',
29
70
  shortcuts: [
30
- {
31
- action: 'Toggle left sidebar',
32
- chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'B']],
33
- },
34
- {
35
- action: 'Toggle right sidebar',
36
- chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'J']],
37
- },
38
- {
39
- action: 'Toggle both sidebars',
40
- chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'G']],
41
- },
71
+ shortcut('Toggle left sidebar', 'toggleLeftSidebar'),
72
+ shortcut('Toggle right sidebar', 'toggleRightSidebar'),
73
+ shortcut('Toggle both sidebars', 'toggleBothSidebars'),
42
74
  ],
43
75
  },
44
76
  {
45
77
  name: 'View',
46
78
  shortcuts: [
47
- { action: 'Enter fullscreen', chords: [['F']] },
48
- { action: 'Exit fullscreen', chords: [['Esc']] },
49
- { action: 'Enable snapping', chords: [['Shift', 'M']] },
79
+ shortcut('Enter fullscreen', 'enterFullscreen'),
80
+ fixedShortcut('Exit fullscreen', [['Esc']], 'Handled by the browser'),
81
+ shortcut('Enable snapping', 'toggleSnapping'),
50
82
  ],
51
83
  },
52
84
  {
53
85
  name: 'Navigation',
54
86
  shortcuts: [
55
- { action: 'Previous composition', chords: [['PageUp']] },
56
- { action: 'Next composition', chords: [['PageDown']] },
57
- {
58
- action: 'Render, unless a sequence or prop is selected',
59
- chords: [['R']],
60
- },
61
- {
62
- action: 'Checkerboard, unless a sequence or prop is selected',
63
- chords: [['T']],
64
- },
65
- { action: 'Show keyboard shortcuts', chords: [['?']] },
66
- {
67
- action: 'Quick Switcher',
68
- chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'K']],
69
- },
87
+ shortcut('Previous composition', 'previousComposition'),
88
+ shortcut('Next composition', 'nextComposition'),
89
+ shortcut('Render, unless a sequence or prop is selected', 'render'),
90
+ shortcut('Checkerboard, unless a sequence or prop is selected', 'toggleCheckerboard'),
91
+ shortcut('Show keyboard shortcuts', 'showKeyboardShortcuts'),
92
+ shortcut('Quick Switcher', 'quickSwitcher'),
70
93
  ],
71
94
  },
72
95
  {
73
96
  name: 'Playback range',
74
97
  shortcuts: [
75
- { action: 'Set In Point', chords: [['I']] },
76
- { action: 'Set Out Point', chords: [['O']] },
77
- { action: 'Clear In/Out Points', chords: [['X']] },
98
+ shortcut('Set In Point', 'setInPoint'),
99
+ shortcut('Set Out Point', 'setOutPoint'),
100
+ shortcut('Clear In/Out Points', 'clearInOutPoints'),
78
101
  ],
79
102
  },
80
103
  {
81
104
  name: 'Zoom',
82
105
  shortcuts: [
83
- { action: 'Zoom in', chords: [['+']] },
84
- { action: 'Zoom out', chords: [['-']] },
85
- { action: 'Reset zoom', chords: [['0']] },
106
+ shortcut('Zoom in', 'zoomIn'),
107
+ shortcut('Zoom out', 'zoomOut'),
108
+ shortcut('Reset zoom', 'resetZoom'),
86
109
  ],
87
110
  },
88
111
  {
89
112
  name: 'Props Editor',
90
- shortcuts: [
91
- { action: 'Undo', chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'Z']] },
92
- {
93
- action: 'Redo',
94
- chords: [
95
- is_mac_1.isMac
96
- ? [ShortcutHint_1.cmdOrCtrlCharacter, 'Shift', 'Z']
97
- : [ShortcutHint_1.cmdOrCtrlCharacter, 'Y'],
98
- ],
99
- },
100
- ],
113
+ shortcuts: [shortcut('Undo', 'undo'), shortcut('Redo', 'redo')],
101
114
  },
102
115
  {
103
116
  name: 'Interactivity',
104
117
  shortcuts: [
105
- { action: 'Select range / axis lock drag', chords: [['Shift']] },
106
- { action: 'Toggle selection', chords: [[ShortcutHint_1.cmdOrCtrlCharacter]] },
107
- {
108
- action: 'Select sequence rows',
109
- chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'A']],
110
- },
111
- { action: 'Select translate prop', chords: [['P']] },
112
- { action: 'Select opacity prop', chords: [['T']] },
113
- { action: 'Select rotate prop', chords: [['R']] },
114
- { action: 'Select scale prop', chords: [['S']] },
115
- {
116
- action: 'Duplicate sequences',
117
- chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'D']],
118
- },
119
- {
120
- action: 'Copy effects / values',
121
- chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'C']],
122
- },
123
- { action: 'Cut effects', chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'X']] },
124
- {
125
- action: 'Paste effects / values',
126
- chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'V']],
127
- },
128
- { action: 'Delete / reset selection', chords: [['Del'], ['⌫']] },
118
+ fixedShortcut('Select range / axis lock drag', [['Shift']], 'Gesture modifier'),
119
+ fixedShortcut('Toggle selection', [[is_mac_1.isMac ? '⌘' : 'Ctrl']], 'Gesture modifier'),
120
+ shortcut('Select sequence rows', 'selectAllSequenceRows'),
121
+ shortcut('Select translate prop', 'selectTranslateProp'),
122
+ shortcut('Select opacity prop', 'selectOpacityProp'),
123
+ shortcut('Select rotate prop', 'selectRotateProp'),
124
+ shortcut('Select scale prop', 'selectScaleProp'),
125
+ shortcut('Duplicate sequences', 'duplicateSequences'),
126
+ shortcut('Copy effects / values', 'copyEffectsAndValues'),
127
+ shortcut('Cut effects', 'cutEffects'),
128
+ fixedShortcut('Paste effects / values', [[is_mac_1.isMac ? '⌘' : 'Ctrl', 'V']], 'Handled by the browser clipboard event'),
129
+ shortcut('Delete / reset selection', 'deleteSelection'),
129
130
  ],
130
131
  },
131
132
  ];
132
133
  exports.askAIKeyboardShortcutGroup = {
133
134
  name: 'AI',
134
- shortcuts: [{ action: 'Ask AI', chords: [[ShortcutHint_1.cmdOrCtrlCharacter, 'I']] }],
135
+ shortcuts: [shortcut('Ask AI', 'askAI')],
136
+ };
137
+ const getKeyboardShortcutsForAction = (action, configured = (0, studio_runtime_config_1.getStudioKeyboardShortcuts)()) => {
138
+ if (configured !== null &&
139
+ Object.prototype.hasOwnProperty.call(configured, action)) {
140
+ const value = configured[action];
141
+ if (value === null) {
142
+ return [];
143
+ }
144
+ return Array.isArray(value)
145
+ ? value
146
+ : [
147
+ value,
148
+ ];
149
+ }
150
+ return exports.defaultKeyboardShortcuts[action];
151
+ };
152
+ exports.getKeyboardShortcutsForAction = getKeyboardShortcutsForAction;
153
+ const normalizeKey = (key) => (key === 'Space' ? ' ' : key);
154
+ const keyboardEventMatchesShortcut = ({ event, shortcut: value, }) => {
155
+ var _a;
156
+ const commandOrControl = is_mac_1.isMac ? event.metaKey : event.ctrlKey;
157
+ return (event.key.toLowerCase() === normalizeKey(value.key).toLowerCase() &&
158
+ commandOrControl === ((_a = value.commandOrControl) !== null && _a !== void 0 ? _a : false) &&
159
+ (is_mac_1.isMac ? !event.ctrlKey : !event.metaKey) &&
160
+ (!value.shift || event.shiftKey) &&
161
+ (!value.alt || event.altKey));
162
+ };
163
+ exports.keyboardEventMatchesShortcut = keyboardEventMatchesShortcut;
164
+ const keyboardShortcutsOverlap = (first, second) => {
165
+ var _a, _b;
166
+ return first.key.toLowerCase() === second.key.toLowerCase() &&
167
+ ((_a = first.commandOrControl) !== null && _a !== void 0 ? _a : false) === ((_b = second.commandOrControl) !== null && _b !== void 0 ? _b : false);
168
+ };
169
+ exports.keyboardShortcutsOverlap = keyboardShortcutsOverlap;
170
+ const keyboardEventMatchesAction = (event, action) => (0, exports.getKeyboardShortcutsForAction)(action).some((value) => (0, exports.keyboardEventMatchesShortcut)({ event, shortcut: value }));
171
+ exports.keyboardEventMatchesAction = keyboardEventMatchesAction;
172
+ const displayKey = (keyboardKey) => {
173
+ if (keyboardKey === 'ArrowLeft')
174
+ return '←';
175
+ if (keyboardKey === 'ArrowRight')
176
+ return '→';
177
+ if (keyboardKey === 'Delete')
178
+ return 'Del';
179
+ if (keyboardKey === 'Backspace')
180
+ return '⌫';
181
+ if (keyboardKey === 'Escape')
182
+ return 'Esc';
183
+ return keyboardKey.length === 1 ? keyboardKey.toUpperCase() : keyboardKey;
184
+ };
185
+ const formatKeyboardShortcut = (value) => [
186
+ ...(value.commandOrControl ? [is_mac_1.isMac ? '⌘' : 'Ctrl'] : []),
187
+ ...(value.alt ? [is_mac_1.isMac ? 'Option' : 'Alt'] : []),
188
+ ...(value.shift && !['+', '?'].includes(value.key) ? ['Shift'] : []),
189
+ displayKey(value.key),
190
+ ];
191
+ exports.formatKeyboardShortcut = formatKeyboardShortcut;
192
+ const formatKeyboardShortcutForAria = (value) => [
193
+ ...(value.commandOrControl ? [is_mac_1.isMac ? 'Meta' : 'Control'] : []),
194
+ ...(value.alt ? ['Alt'] : []),
195
+ ...(value.shift ? ['Shift'] : []),
196
+ value.key,
197
+ ].join('+');
198
+ exports.formatKeyboardShortcutForAria = formatKeyboardShortcutForAria;
199
+ const getKeyboardShortcutLabel = (action) => (0, exports.getKeyboardShortcutsForAction)(action)
200
+ .map((value) => (0, exports.formatKeyboardShortcut)(value).join('+'))
201
+ .join(' / ');
202
+ exports.getKeyboardShortcutLabel = getKeyboardShortcutLabel;
203
+ const getKeyboardShortcutAriaKeyShortcuts = (action) => (0, exports.getKeyboardShortcutsForAction)(action)
204
+ .map(exports.formatKeyboardShortcutForAria)
205
+ .join(' ');
206
+ exports.getKeyboardShortcutAriaKeyShortcuts = getKeyboardShortcutAriaKeyShortcuts;
207
+ const shortcutFromKeyboardEvent = (event) => {
208
+ if (['Alt', 'Control', 'Meta', 'Shift'].includes(event.key)) {
209
+ return null;
210
+ }
211
+ if (is_mac_1.isMac ? event.ctrlKey : event.metaKey) {
212
+ return null;
213
+ }
214
+ return {
215
+ key: event.key === ' ' ? 'Space' : event.key,
216
+ ...((is_mac_1.isMac ? event.metaKey : event.ctrlKey)
217
+ ? { commandOrControl: true }
218
+ : {}),
219
+ ...(event.shiftKey ? { shift: true } : {}),
220
+ ...(event.altKey ? { alt: true } : {}),
221
+ };
135
222
  };
223
+ exports.shortcutFromKeyboardEvent = shortcutFromKeyboardEvent;
@@ -0,0 +1,5 @@
1
+ export declare const getDefaultOutputBaseName: (src: string, displayName: string, fallbackName: string) => string;
2
+ export declare const validatePublicOutputName: ({ extension, outName, }: {
3
+ extension: string;
4
+ outName: string;
5
+ }) => string | null;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validatePublicOutputName = exports.getDefaultOutputBaseName = void 0;
4
+ const invalidCharacters = ['?', '*', '+', ':', '%'];
5
+ const getDefaultOutputBaseName = (src, displayName, fallbackName) => {
6
+ var _a;
7
+ let pathname = displayName;
8
+ if (!/^(data|blob):/i.test(src.trimStart())) {
9
+ pathname = (_a = src.split(/[?#]/)[0]) !== null && _a !== void 0 ? _a : src;
10
+ try {
11
+ pathname = new URL(src, typeof window === 'undefined'
12
+ ? 'http://localhost'
13
+ : window.location.href).pathname;
14
+ }
15
+ catch (_b) {
16
+ // Fall back to the source as-is if it cannot be parsed as a URL.
17
+ }
18
+ }
19
+ const lastPathSegment = pathname.split('/').filter(Boolean).at(-1);
20
+ let decoded = lastPathSegment !== null && lastPathSegment !== void 0 ? lastPathSegment : displayName;
21
+ try {
22
+ decoded = decodeURIComponent(decoded);
23
+ }
24
+ catch (_c) {
25
+ // Keep the encoded name if it contains an invalid escape sequence.
26
+ }
27
+ return (decoded
28
+ .replace(/\.[^/.]+$/, '')
29
+ .replace(/[^a-zA-Z0-9-_ ]/g, '-')
30
+ .trim()
31
+ .replace(/\s+/g, '-')
32
+ .replace(/^-+|-+$/g, '') || fallbackName);
33
+ };
34
+ exports.getDefaultOutputBaseName = getDefaultOutputBaseName;
35
+ const validatePublicOutputName = ({ extension, outName, }) => {
36
+ if (outName.trim() === '')
37
+ return 'Enter an output file';
38
+ if (outName !== outName.trim())
39
+ return 'The output file must not start or end with whitespace';
40
+ if (outName.startsWith('/') || /^[a-zA-Z]:/.test(outName))
41
+ return 'The output file must be relative to the public folder';
42
+ if (outName.includes('\\'))
43
+ return 'Use forward slashes in the output file';
44
+ if (outName.includes('\0'))
45
+ return 'The output file must not contain null characters';
46
+ const segments = outName.split('/');
47
+ if (segments.some((segment) => segment === ''))
48
+ return 'The output file must not contain empty path segments';
49
+ if (segments.some((segment) => segment === '.'))
50
+ return 'The output file must not contain "." path segments';
51
+ if (segments.some((segment) => segment.startsWith('..')))
52
+ return 'The output file must stay inside the public folder';
53
+ const invalidCharacter = invalidCharacters.find((character) => outName.includes(character));
54
+ if (invalidCharacter)
55
+ return `The output file must not contain "${invalidCharacter}"`;
56
+ if (!outName.toLowerCase().endsWith(extension))
57
+ return `The output file must end in ${extension}`;
58
+ return null;
59
+ };
60
+ exports.validatePublicOutputName = validatePublicOutputName;
@@ -0,0 +1,7 @@
1
+ export declare const useModelCacheStatus: <Model extends string>({ isModelCached, models, refreshKey, }: {
2
+ readonly isModelCached: (model: Model) => Promise<boolean>;
3
+ readonly models: readonly {
4
+ readonly name: Model;
5
+ }[];
6
+ readonly refreshKey: string;
7
+ }) => ReadonlySet<Model>;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useModelCacheStatus = void 0;
4
+ const react_1 = require("react");
5
+ const useModelCacheStatus = ({ isModelCached, models, refreshKey, }) => {
6
+ const [cachedModels, setCachedModels] = (0, react_1.useState)(new Set());
7
+ (0, react_1.useEffect)(() => {
8
+ let cancelled = false;
9
+ Promise.all(models.map(async ({ name }) => ({
10
+ cached: await isModelCached(name),
11
+ name,
12
+ })))
13
+ .then((results) => {
14
+ if (!cancelled) {
15
+ const nextCachedModels = new Set();
16
+ for (const result of results) {
17
+ if (result.cached) {
18
+ nextCachedModels.add(result.name);
19
+ }
20
+ }
21
+ setCachedModels(nextCachedModels);
22
+ }
23
+ })
24
+ .catch(() => {
25
+ if (!cancelled) {
26
+ setCachedModels(new Set());
27
+ }
28
+ });
29
+ return () => {
30
+ cancelled = true;
31
+ };
32
+ }, [isModelCached, models, refreshKey]);
33
+ return cachedModels;
34
+ };
35
+ exports.useModelCacheStatus = useModelCacheStatus;