@remotion/studio 4.0.408 → 4.0.410

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.
@@ -10,7 +10,7 @@ import { Internals as Internals66 } from "remotion";
10
10
 
11
11
  // src/components/Editor.tsx
12
12
  import { PlayerInternals as PlayerInternals19 } from "@remotion/player";
13
- import React177, { useCallback as useCallback135, useEffect as useEffect85, useMemo as useMemo136 } from "react";
13
+ import React177, { useCallback as useCallback135, useEffect as useEffect84, useMemo as useMemo136 } from "react";
14
14
  import { Internals as Internals62 } from "remotion";
15
15
 
16
16
  // src/helpers/colors.ts
@@ -3246,7 +3246,7 @@ var writeStaticFile = async ({
3246
3246
  if (window.remotion_isReadOnlyStudio) {
3247
3247
  throw new Error("writeStaticFile() is not available in read-only Studio");
3248
3248
  }
3249
- const url = new URL("/api/add-asset", window.location.origin);
3249
+ const url = new URL(`${window.remotion_staticBase}/api/add-asset`, window.location.origin);
3250
3250
  if (filePath.includes("\\")) {
3251
3251
  return Promise.reject(new Error("File path cannot contain backslashes"));
3252
3252
  }
@@ -7525,10 +7525,10 @@ var MenuBuildIndicator = () => {
7525
7525
  };
7526
7526
 
7527
7527
  // src/components/SidebarCollapserControls.tsx
7528
- import { useCallback as useCallback91, useContext as useContext59, useEffect as useEffect62 } from "react";
7528
+ import { useCallback as useCallback91, useContext as useContext59, useEffect as useEffect61 } from "react";
7529
7529
 
7530
7530
  // src/components/TopPanel.tsx
7531
- import { useCallback as useCallback90, useContext as useContext58, useEffect as useEffect61, useMemo as useMemo96 } from "react";
7531
+ import { useCallback as useCallback90, useContext as useContext58, useEffect as useEffect60, useMemo as useMemo96 } from "react";
7532
7532
 
7533
7533
  // src/helpers/use-breakpoint.ts
7534
7534
  import { useEffect as useEffect25, useState as useState30 } from "react";
@@ -17309,7 +17309,7 @@ var OptionsPanel = ({ readOnlyStudio }) => {
17309
17309
  };
17310
17310
 
17311
17311
  // src/components/PreviewToolbar.tsx
17312
- import { useContext as useContext55, useEffect as useEffect59, useRef as useRef32, useState as useState60 } from "react";
17312
+ import { useContext as useContext55, useEffect as useEffect58, useRef as useRef32, useState as useState60 } from "react";
17313
17313
  import { Internals as Internals45 } from "remotion";
17314
17314
 
17315
17315
  // src/helpers/should-show-render-button.ts
@@ -18126,14 +18126,7 @@ var PlaybackRateSelector = ({ playbackRate, setPlaybackRate }) => {
18126
18126
 
18127
18127
  // src/components/RenderButton.tsx
18128
18128
  import { PlayerInternals as PlayerInternals14 } from "@remotion/player";
18129
- import {
18130
- useCallback as useCallback88,
18131
- useContext as useContext53,
18132
- useEffect as useEffect58,
18133
- useMemo as useMemo93,
18134
- useRef as useRef31,
18135
- useState as useState59
18136
- } from "react";
18129
+ import { useCallback as useCallback88, useContext as useContext53, useMemo as useMemo93, useRef as useRef31, useState as useState59 } from "react";
18137
18130
  import ReactDOM8 from "react-dom";
18138
18131
  import { Internals as Internals43 } from "remotion";
18139
18132
  import { jsx as jsx174, jsxs as jsxs81, Fragment as Fragment23 } from "react/jsx-runtime";
@@ -18215,6 +18208,34 @@ var RenderButton = ({
18215
18208
  shouldApplyCssTransforms: true
18216
18209
  });
18217
18210
  const refresh = size4?.refresh;
18211
+ const onPointerDown = useCallback88(() => {
18212
+ setDropdownOpened((o) => {
18213
+ if (!o) {
18214
+ refresh?.();
18215
+ }
18216
+ return !o;
18217
+ });
18218
+ }, [refresh]);
18219
+ const onClickDropdown = useCallback88((e) => {
18220
+ e.stopPropagation();
18221
+ const isKeyboardInitiated = e.detail === 0;
18222
+ if (!isKeyboardInitiated) {
18223
+ return;
18224
+ }
18225
+ setDropdownOpened((o) => {
18226
+ if (!o) {
18227
+ refresh?.();
18228
+ window.addEventListener("pointerup", (evt) => {
18229
+ if (!isMenuItem(evt.target)) {
18230
+ setDropdownOpened(false);
18231
+ }
18232
+ }, {
18233
+ once: true
18234
+ });
18235
+ }
18236
+ return !o;
18237
+ });
18238
+ }, [refresh]);
18218
18239
  const connectionStatus = useContext53(StudioServerConnectionCtx).previewServerState.type;
18219
18240
  const shortcut = areKeyboardShortcutsDisabled() ? "" : "(R)";
18220
18241
  const tooltip = connectionStatus === "connected" ? "Export the current composition " + shortcut : "Connect to the Studio server to render";
@@ -18355,46 +18376,6 @@ var RenderButton = ({
18355
18376
  }
18356
18377
  ];
18357
18378
  }, [handleRenderTypeChange]);
18358
- useEffect58(() => {
18359
- const { current } = dropdownRef;
18360
- if (!current) {
18361
- return;
18362
- }
18363
- const onPointerDown = () => {
18364
- return setDropdownOpened((o) => {
18365
- if (!o) {
18366
- refresh?.();
18367
- }
18368
- return !o;
18369
- });
18370
- };
18371
- const onClickDropdown = (e) => {
18372
- e.stopPropagation();
18373
- const isKeyboardInitiated = e.detail === 0;
18374
- if (!isKeyboardInitiated) {
18375
- return;
18376
- }
18377
- return setDropdownOpened((o) => {
18378
- if (!o) {
18379
- refresh?.();
18380
- window.addEventListener("pointerup", (evt) => {
18381
- if (!isMenuItem(evt.target)) {
18382
- setDropdownOpened(false);
18383
- }
18384
- }, {
18385
- once: true
18386
- });
18387
- }
18388
- return !o;
18389
- });
18390
- };
18391
- current.addEventListener("pointerdown", onPointerDown);
18392
- current.addEventListener("click", onClickDropdown);
18393
- return () => {
18394
- current.removeEventListener("pointerdown", onPointerDown);
18395
- current.removeEventListener("click", onClickDropdown);
18396
- };
18397
- }, [refresh]);
18398
18379
  const spaceToBottom = useMemo93(() => {
18399
18380
  const margin2 = 10;
18400
18381
  if (size4 && dropdownOpened) {
@@ -18462,7 +18443,6 @@ var RenderButton = ({
18462
18443
  /* @__PURE__ */ jsx174("button", {
18463
18444
  style: { display: "none" },
18464
18445
  id: "render-modal-button-client",
18465
- disabled: connectionStatus !== "connected" && renderType === "server-render",
18466
18446
  onClick: openClientRenderModal,
18467
18447
  type: "button"
18468
18448
  }),
@@ -18506,6 +18486,8 @@ var RenderButton = ({
18506
18486
  style: dropdownTriggerStyle,
18507
18487
  disabled: connectionStatus !== "connected",
18508
18488
  className: MENU_INITIATOR_CLASSNAME,
18489
+ onPointerDown,
18490
+ onClick: onClickDropdown,
18509
18491
  children: /* @__PURE__ */ jsx174(CaretDown, {})
18510
18492
  })
18511
18493
  ]
@@ -18708,7 +18690,7 @@ var PreviewToolbar = ({ readOnlyStudio, bufferStateDelayInMilliseconds }) => {
18708
18690
  const [loop, setLoop] = useState60(loadLoopOption());
18709
18691
  const isFullscreenSupported = checkFullscreenSupport();
18710
18692
  const isMobileLayout = useMobileLayout();
18711
- useEffect59(() => {
18693
+ useEffect58(() => {
18712
18694
  if (isMobileLayout && previewToolbarRef.current) {
18713
18695
  const updateScrollableIndicatorProps = (target) => {
18714
18696
  const boundingBox = target.getBoundingClientRect();
@@ -18988,7 +18970,7 @@ var SplitterElement = ({ children, type, sticky }) => {
18988
18970
 
18989
18971
  // src/components/Splitter/SplitterHandle.tsx
18990
18972
  import { PlayerInternals as PlayerInternals15 } from "@remotion/player";
18991
- import { useContext as useContext57, useEffect as useEffect60, useRef as useRef34, useState as useState62 } from "react";
18973
+ import { useContext as useContext57, useEffect as useEffect59, useRef as useRef34, useState as useState62 } from "react";
18992
18974
  import { jsx as jsx180 } from "react/jsx-runtime";
18993
18975
  var SPLITTER_HANDLE_SIZE = 3;
18994
18976
  var containerRow2 = {
@@ -19004,7 +18986,7 @@ var SplitterHandle = ({ allowToCollapse, onCollapse }) => {
19004
18986
  }
19005
18987
  const [lastPointerUp, setLastPointerUp] = useState62(() => Date.now());
19006
18988
  const ref = useRef34(null);
19007
- useEffect60(() => {
18989
+ useEffect59(() => {
19008
18990
  if (context.isDragging.current) {
19009
18991
  return;
19010
18992
  }
@@ -19087,7 +19069,7 @@ var SplitterHandle = ({ allowToCollapse, onCollapse }) => {
19087
19069
  }
19088
19070
  };
19089
19071
  }, [allowToCollapse, context, context.flexValue, lastPointerUp, onCollapse]);
19090
- useEffect60(() => {
19072
+ useEffect59(() => {
19091
19073
  const { current } = ref;
19092
19074
  if (!current) {
19093
19075
  return;
@@ -19174,7 +19156,7 @@ var TopPanel = ({ readOnlyStudio, onMounted, drawRef: drawRef2, bufferStateDelay
19174
19156
  }
19175
19157
  return "expanded";
19176
19158
  }, [sidebarCollapsedStateRight]);
19177
- useEffect61(() => {
19159
+ useEffect60(() => {
19178
19160
  onMounted();
19179
19161
  }, [onMounted]);
19180
19162
  const canvasContainerStyle = useMemo96(() => ({
@@ -19344,7 +19326,7 @@ var SidebarCollapserControls = () => {
19344
19326
  toggleLeft,
19345
19327
  toggleRight
19346
19328
  ]);
19347
- useEffect62(() => {
19329
+ useEffect61(() => {
19348
19330
  const left3 = keybindings.registerKeybinding({
19349
19331
  event: "keydown",
19350
19332
  key: "b",
@@ -19422,7 +19404,7 @@ var SidebarCollapserControls = () => {
19422
19404
  import {
19423
19405
  useCallback as useCallback92,
19424
19406
  useContext as useContext60,
19425
- useEffect as useEffect63,
19407
+ useEffect as useEffect62,
19426
19408
  useMemo as useMemo97,
19427
19409
  useState as useState63
19428
19410
  } from "react";
@@ -19474,7 +19456,7 @@ var UpdateCheck = () => {
19474
19456
  });
19475
19457
  return controller;
19476
19458
  }, []);
19477
- useEffect63(() => {
19459
+ useEffect62(() => {
19478
19460
  const abortUpdate = checkForUpdates();
19479
19461
  const abortBugs = checkForBugs();
19480
19462
  return () => {
@@ -19839,7 +19821,7 @@ import { PlayerInternals as PlayerInternals16 } from "@remotion/player";
19839
19821
  import {
19840
19822
  useCallback as useCallback94,
19841
19823
  useContext as useContext63,
19842
- useEffect as useEffect64,
19824
+ useEffect as useEffect63,
19843
19825
  useMemo as useMemo100,
19844
19826
  useRef as useRef35,
19845
19827
  useState as useState65
@@ -20270,7 +20252,7 @@ var Inner2 = () => {
20270
20252
  videoConfig,
20271
20253
  width
20272
20254
  ]);
20273
- useEffect64(() => {
20255
+ useEffect63(() => {
20274
20256
  if (!dragging.dragging) {
20275
20257
  return;
20276
20258
  }
@@ -20281,7 +20263,7 @@ var Inner2 = () => {
20281
20263
  window.removeEventListener("pointerup", onPointerUpScrubbing);
20282
20264
  };
20283
20265
  }, [dragging.dragging, onPointerMoveScrubbing, onPointerUpScrubbing]);
20284
- useEffect64(() => {
20266
+ useEffect63(() => {
20285
20267
  if (inOutDragging.dragging === false) {
20286
20268
  return;
20287
20269
  }
@@ -20457,7 +20439,7 @@ import { SOURCE_MAP_ENDPOINT } from "@remotion/studio-shared";
20457
20439
  import {
20458
20440
  useCallback as useCallback96,
20459
20441
  useContext as useContext64,
20460
- useEffect as useEffect65,
20442
+ useEffect as useEffect64,
20461
20443
  useMemo as useMemo101,
20462
20444
  useState as useState66
20463
20445
  } from "react";
@@ -20546,7 +20528,7 @@ var TimelineStack = ({ isCompact, sequence }) => {
20546
20528
  window.open(getGitRefUrl(window.remotion_gitSource, originalLocation), "_blank");
20547
20529
  }
20548
20530
  }, [canOpenInEditor, canOpenInGitHub, openEditor, originalLocation]);
20549
- useEffect65(() => {
20531
+ useEffect64(() => {
20550
20532
  if (!sequence.stack) {
20551
20533
  return;
20552
20534
  }
@@ -20694,14 +20676,14 @@ var TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
20694
20676
  };
20695
20677
 
20696
20678
  // src/components/Timeline/TimelineTimeIndicators.tsx
20697
- import { useContext as useContext66, useEffect as useEffect67, useMemo as useMemo103, useRef as useRef37 } from "react";
20679
+ import { useContext as useContext66, useEffect as useEffect66, useMemo as useMemo103, useRef as useRef37 } from "react";
20698
20680
  import { Internals as Internals50 } from "remotion";
20699
20681
 
20700
20682
  // src/components/TimeValue.tsx
20701
20683
  import { PlayerInternals as PlayerInternals17 } from "@remotion/player";
20702
20684
  import {
20703
20685
  useCallback as useCallback98,
20704
- useEffect as useEffect66,
20686
+ useEffect as useEffect65,
20705
20687
  useImperativeHandle as useImperativeHandle13,
20706
20688
  useRef as useRef36
20707
20689
  } from "react";
@@ -20754,7 +20736,7 @@ var TimeValue = () => {
20754
20736
  pause,
20755
20737
  toggle
20756
20738
  }), [seek, play, pause, toggle]);
20757
- useEffect66(() => {
20739
+ useEffect65(() => {
20758
20740
  const gKey = keybindings.registerKeybinding({
20759
20741
  event: "keypress",
20760
20742
  key: "g",
@@ -20867,7 +20849,7 @@ var TimelineTimeIndicators = () => {
20867
20849
  };
20868
20850
  var Inner3 = ({ windowWidth, durationInFrames, fps }) => {
20869
20851
  const ref = useRef37(null);
20870
- useEffect67(() => {
20852
+ useEffect66(() => {
20871
20853
  const currentRef = ref.current;
20872
20854
  if (!currentRef) {
20873
20855
  return;
@@ -20974,7 +20956,7 @@ var TimelineList = ({ timeline }) => {
20974
20956
  };
20975
20957
 
20976
20958
  // src/components/Timeline/TimelinePlayCursorSyncer.tsx
20977
- import { useContext as useContext67, useEffect as useEffect68 } from "react";
20959
+ import { useContext as useContext67, useEffect as useEffect67 } from "react";
20978
20960
  import { Internals as Internals51 } from "remotion";
20979
20961
  var lastTimelinePositionWhileScrolling = null;
20980
20962
  var TimelinePlayCursorSyncer = () => {
@@ -20992,7 +20974,7 @@ var TimelinePlayCursorSyncer = () => {
20992
20974
  setCurrentFps(video.fps);
20993
20975
  }
20994
20976
  const playing = timelineContext.playing ?? false;
20995
- useEffect68(() => {
20977
+ useEffect67(() => {
20996
20978
  if (!video) {
20997
20979
  return;
20998
20980
  }
@@ -21005,7 +20987,7 @@ var TimelinePlayCursorSyncer = () => {
21005
20987
  frame: timelinePosition
21006
20988
  });
21007
20989
  }, [playing, timelineContext, timelinePosition, video]);
21008
- useEffect68(() => {
20990
+ useEffect67(() => {
21009
20991
  const { current } = scrollableRef;
21010
20992
  if (!current) {
21011
20993
  return;
@@ -36008,7 +35990,7 @@ var readAscii = (slice, length) => {
36008
35990
  */
36009
35991
 
36010
35992
  // src/helpers/use-max-media-duration.ts
36011
- import { useEffect as useEffect69, useState as useState67 } from "react";
35993
+ import { useEffect as useEffect68, useState as useState67 } from "react";
36012
35994
  var cache = new Map;
36013
35995
  var getSrc = (s) => {
36014
35996
  if (s.type === "video") {
@@ -36022,7 +36004,7 @@ var getSrc = (s) => {
36022
36004
  var useMaxMediaDuration = (s, fps) => {
36023
36005
  const src = getSrc(s);
36024
36006
  const [maxMediaDuration, setMaxMediaDuration] = useState67(src ? cache.get(src) ?? null : Infinity);
36025
- useEffect69(() => {
36007
+ useEffect68(() => {
36026
36008
  if (!src) {
36027
36009
  return;
36028
36010
  }
@@ -36052,7 +36034,7 @@ var useMaxMediaDuration = (s, fps) => {
36052
36034
 
36053
36035
  // src/components/AudioWaveform.tsx
36054
36036
  import { getAudioData, getWaveformPortion } from "@remotion/media-utils";
36055
- import { useEffect as useEffect70, useMemo as useMemo106, useRef as useRef39, useState as useState68 } from "react";
36037
+ import { useEffect as useEffect69, useMemo as useMemo106, useRef as useRef39, useState as useState68 } from "react";
36056
36038
  import { Internals as Internals52 } from "remotion";
36057
36039
 
36058
36040
  // src/components/AudioWaveformBar.tsx
@@ -36117,14 +36099,14 @@ var AudioWaveform = ({
36117
36099
  throw new Error("Expected video config");
36118
36100
  }
36119
36101
  const canvas = useRef39(null);
36120
- useEffect70(() => {
36102
+ useEffect69(() => {
36121
36103
  const { current } = mountState;
36122
36104
  current.isMounted = true;
36123
36105
  return () => {
36124
36106
  current.isMounted = false;
36125
36107
  };
36126
36108
  }, []);
36127
- useEffect70(() => {
36109
+ useEffect69(() => {
36128
36110
  if (!canvas.current) {
36129
36111
  return;
36130
36112
  }
@@ -36151,7 +36133,7 @@ var AudioWaveform = ({
36151
36133
  context.strokeStyle = LIGHT_TRANSPARENT;
36152
36134
  context.stroke();
36153
36135
  }, [visualizationWidth, metadata, startFrom, volume, doesVolumeChange]);
36154
- useEffect70(() => {
36136
+ useEffect69(() => {
36155
36137
  setError(null);
36156
36138
  getAudioData(src).then((data) => {
36157
36139
  if (mountState.current.isMounted) {
@@ -36326,7 +36308,7 @@ var TimelineSequenceFrame = ({ roundedFrame, premounted, postmounted }) => {
36326
36308
  };
36327
36309
 
36328
36310
  // src/components/Timeline/TimelineVideoInfo.tsx
36329
- import { useEffect as useEffect71, useRef as useRef40, useState as useState69 } from "react";
36311
+ import { useEffect as useEffect70, useRef as useRef40, useState as useState69 } from "react";
36330
36312
  import { useVideoConfig as useVideoConfig5 } from "remotion";
36331
36313
 
36332
36314
  // src/helpers/extract-frames.ts
@@ -36644,12 +36626,12 @@ var TimelineVideoInfo = ({ src, visualizationWidth, startFrom, durationInFrames
36644
36626
  const ref = useRef40(null);
36645
36627
  const [error, setError] = useState69(null);
36646
36628
  const aspectRatio = useRef40(getAspectRatioFromCache(src));
36647
- useEffect71(() => {
36629
+ useEffect70(() => {
36648
36630
  return () => {
36649
36631
  clearFramesForSrc(src);
36650
36632
  };
36651
36633
  }, [src]);
36652
- useEffect71(() => {
36634
+ useEffect70(() => {
36653
36635
  if (error) {
36654
36636
  return;
36655
36637
  }
@@ -37102,13 +37084,13 @@ var EditorContent = ({ readOnlyStudio, children }) => {
37102
37084
  };
37103
37085
 
37104
37086
  // src/components/GlobalKeybindings.tsx
37105
- import { useContext as useContext71, useEffect as useEffect72 } from "react";
37087
+ import { useContext as useContext71, useEffect as useEffect71 } from "react";
37106
37088
  var GlobalKeybindings = () => {
37107
37089
  const keybindings = useKeybinding();
37108
37090
  const { setSelectedModal } = useContext71(ModalsContext);
37109
37091
  const { setCheckerboard } = useContext71(CheckerboardContext);
37110
37092
  const { navigateToNextComposition, navigateToPreviousComposition } = useCompositionNavigation();
37111
- useEffect72(() => {
37093
+ useEffect71(() => {
37112
37094
  const nKey = keybindings.registerKeybinding({
37113
37095
  event: "keypress",
37114
37096
  key: "n",
@@ -37213,8 +37195,13 @@ var GlobalKeybindings = () => {
37213
37195
  import { useContext as useContext85 } from "react";
37214
37196
 
37215
37197
  // src/components/InstallPackage.tsx
37216
- import { apiDocs, descriptions, installableMap } from "@remotion/studio-shared";
37217
- import React144, { useCallback as useCallback100, useContext as useContext73, useEffect as useEffect73 } from "react";
37198
+ import {
37199
+ apiDocs,
37200
+ descriptions,
37201
+ extraPackages,
37202
+ installableMap
37203
+ } from "@remotion/studio-shared";
37204
+ import React144, { useCallback as useCallback100, useContext as useContext73, useEffect as useEffect72 } from "react";
37218
37205
  import { VERSION as VERSION2 } from "remotion";
37219
37206
 
37220
37207
  // src/api/install-package.ts
@@ -37348,7 +37335,7 @@ var InstallPackageModal = ({ packageManager }) => {
37348
37335
  const canSelectPackages = state.type === "idle" && ctx.type === "connected";
37349
37336
  const disabled = !(canSelectPackages || state.type === "done") || selectedPackages.length === 0;
37350
37337
  const { registerKeybinding } = useKeybinding();
37351
- useEffect73(() => {
37338
+ useEffect72(() => {
37352
37339
  if (disabled) {
37353
37340
  return;
37354
37341
  }
@@ -37393,42 +37380,72 @@ var InstallPackageModal = ({ packageManager }) => {
37393
37380
  selectedPackages.length === 1 ? "" : "s",
37394
37381
  ". Check your terminal for progress."
37395
37382
  ]
37396
- }) : /* @__PURE__ */ jsx209("div", {
37383
+ }) : /* @__PURE__ */ jsxs103("div", {
37397
37384
  style: text2,
37398
- children: Object.entries(installableMap).filter(([, install]) => install).map(([pkgShort]) => {
37399
- const pkg = pkgShort === "core" ? "remotion" : `@remotion/${pkgShort}`;
37400
- const isInstalled = window.remotion_installedPackages?.includes(pkg) ?? false;
37401
- const link = apiDocs[pkgShort];
37402
- const description = descriptions[pkgShort];
37403
- if (!link) {
37404
- throw new Error("No link for " + pkg);
37405
- }
37406
- if (!description) {
37407
- throw new Error("No description for " + pkg);
37408
- }
37409
- return /* @__PURE__ */ jsxs103(Row, {
37410
- align: "center",
37411
- children: [
37412
- /* @__PURE__ */ jsx209(Checkbox, {
37413
- checked: map[pkg],
37414
- name: pkg,
37415
- onChange: () => {
37416
- setMap((prev) => ({ ...prev, [pkg]: !prev[pkg] }));
37417
- },
37418
- disabled: !canSelectPackages || isInstalled
37419
- }),
37420
- /* @__PURE__ */ jsx209(Spacing, {
37421
- x: 1.5
37422
- }),
37423
- /* @__PURE__ */ jsx209(InstallablePackageComp, {
37424
- description,
37425
- isInstalled,
37426
- link,
37427
- pkg
37428
- })
37429
- ]
37430
- }, pkg);
37431
- })
37385
+ children: [
37386
+ Object.entries(installableMap).filter(([, install]) => install).map(([pkgShort]) => {
37387
+ const pkg = pkgShort === "core" ? "remotion" : `@remotion/${pkgShort}`;
37388
+ const isInstalled = window.remotion_installedPackages?.includes(pkg) ?? false;
37389
+ const link = apiDocs[pkgShort];
37390
+ const description = descriptions[pkgShort];
37391
+ if (!link) {
37392
+ throw new Error("No link for " + pkg);
37393
+ }
37394
+ if (!description) {
37395
+ throw new Error("No description for " + pkg);
37396
+ }
37397
+ return /* @__PURE__ */ jsxs103(Row, {
37398
+ align: "center",
37399
+ children: [
37400
+ /* @__PURE__ */ jsx209(Checkbox, {
37401
+ checked: map[pkg],
37402
+ name: pkg,
37403
+ onChange: () => {
37404
+ setMap((prev) => ({ ...prev, [pkg]: !prev[pkg] }));
37405
+ },
37406
+ disabled: !canSelectPackages || isInstalled
37407
+ }),
37408
+ /* @__PURE__ */ jsx209(Spacing, {
37409
+ x: 1.5
37410
+ }),
37411
+ /* @__PURE__ */ jsx209(InstallablePackageComp, {
37412
+ description,
37413
+ isInstalled,
37414
+ link,
37415
+ pkg
37416
+ })
37417
+ ]
37418
+ }, pkg);
37419
+ }),
37420
+ extraPackages.map((extraPkg) => {
37421
+ const isInstalled = window.remotion_installedPackages?.includes(extraPkg.name) ?? false;
37422
+ return /* @__PURE__ */ jsxs103(Row, {
37423
+ align: "center",
37424
+ children: [
37425
+ /* @__PURE__ */ jsx209(Checkbox, {
37426
+ checked: map[extraPkg.name],
37427
+ name: extraPkg.name,
37428
+ onChange: () => {
37429
+ setMap((prev) => ({
37430
+ ...prev,
37431
+ [extraPkg.name]: !prev[extraPkg.name]
37432
+ }));
37433
+ },
37434
+ disabled: !canSelectPackages || isInstalled
37435
+ }),
37436
+ /* @__PURE__ */ jsx209(Spacing, {
37437
+ x: 1.5
37438
+ }),
37439
+ /* @__PURE__ */ jsx209(InstallablePackageComp, {
37440
+ description: extraPkg.description,
37441
+ isInstalled,
37442
+ link: extraPkg.docsUrl,
37443
+ pkg: `${extraPkg.name}@${extraPkg.version}`
37444
+ })
37445
+ ]
37446
+ }, extraPkg.name);
37447
+ })
37448
+ ]
37432
37449
  })
37433
37450
  }),
37434
37451
  /* @__PURE__ */ jsx209(ModalFooterContainer, {
@@ -37472,7 +37489,7 @@ var InstallPackageModal = ({ packageManager }) => {
37472
37489
  import { useCallback as useCallback102, useContext as useContext76, useMemo as useMemo112 } from "react";
37473
37490
 
37474
37491
  // src/components/RenderModal/ResolveCompositionBeforeModal.tsx
37475
- import React145, { useContext as useContext74, useEffect as useEffect74, useMemo as useMemo111 } from "react";
37492
+ import React145, { useContext as useContext74, useEffect as useEffect73, useMemo as useMemo111 } from "react";
37476
37493
  import { Internals as Internals56 } from "remotion";
37477
37494
  import { jsx as jsx210, jsxs as jsxs104 } from "react/jsx-runtime";
37478
37495
  var loaderContainer2 = {
@@ -37496,7 +37513,7 @@ var ResolveCompositionBeforeModal = ({ compositionId, children }) => {
37496
37513
  const resolved = Internals56.useResolvedVideoConfig(compositionId);
37497
37514
  const unresolvedContext = useContext74(Internals56.CompositionManager);
37498
37515
  const unresolved = unresolvedContext.compositions.find((c) => compositionId === c.id);
37499
- useEffect74(() => {
37516
+ useEffect73(() => {
37500
37517
  const { current } = Internals56.resolveCompositionsRef;
37501
37518
  if (!current) {
37502
37519
  throw new Error("No ref to trigger composition calc");
@@ -37554,7 +37571,7 @@ var ResolveCompositionBeforeModal = ({ compositionId, children }) => {
37554
37571
  };
37555
37572
 
37556
37573
  // src/components/NewComposition/CodemodFooter.tsx
37557
- import { useCallback as useCallback101, useContext as useContext75, useEffect as useEffect75, useState as useState70 } from "react";
37574
+ import { useCallback as useCallback101, useContext as useContext75, useEffect as useEffect74, useState as useState70 } from "react";
37558
37575
 
37559
37576
  // src/components/NewComposition/DiffPreview.tsx
37560
37577
  import { jsx as jsx211, jsxs as jsxs105 } from "react/jsx-runtime";
@@ -37619,7 +37636,7 @@ var CodemodFooter = ({
37619
37636
  type: "loading"
37620
37637
  });
37621
37638
  const [projectInfo, setProjectInfo] = useState70(null);
37622
- useEffect75(() => {
37639
+ useEffect74(() => {
37623
37640
  const controller = new AbortController;
37624
37641
  getProjectInfo(controller.signal).then((info) => {
37625
37642
  setProjectInfo(info.projectInfo);
@@ -37665,7 +37682,7 @@ var CodemodFooter = ({
37665
37682
  });
37666
37683
  }
37667
37684
  }, [codemod]);
37668
- useEffect75(() => {
37685
+ useEffect74(() => {
37669
37686
  const abortController = new AbortController;
37670
37687
  let aborted = false;
37671
37688
  getCanApplyCodemod(abortController.signal).then(() => {
@@ -37683,7 +37700,7 @@ var CodemodFooter = ({
37683
37700
  }, [codemodStatus, getCanApplyCodemod, setSelectedModal]);
37684
37701
  const disabled = !valid || submitting || projectInfo === null || codemodStatus.type !== "success";
37685
37702
  const { registerKeybinding } = useKeybinding();
37686
- useEffect75(() => {
37703
+ useEffect74(() => {
37687
37704
  if (disabled) {
37688
37705
  return;
37689
37706
  }
@@ -38505,7 +38522,7 @@ var OverrideInputPropsModal = () => {
38505
38522
  import {
38506
38523
  useCallback as useCallback107,
38507
38524
  useContext as useContext80,
38508
- useEffect as useEffect77,
38525
+ useEffect as useEffect76,
38509
38526
  useMemo as useMemo117,
38510
38527
  useRef as useRef42,
38511
38528
  useState as useState75
@@ -39305,7 +39322,7 @@ var QuickSwitcherNoResults = ({ query, mode }) => {
39305
39322
  };
39306
39323
 
39307
39324
  // src/components/QuickSwitcher/QuickSwitcherResult.tsx
39308
- import { useEffect as useEffect76, useMemo as useMemo116, useRef as useRef41, useState as useState74 } from "react";
39325
+ import { useEffect as useEffect75, useMemo as useMemo116, useRef as useRef41, useState as useState74 } from "react";
39309
39326
  import { jsx as jsx221, jsxs as jsxs114, Fragment as Fragment35 } from "react/jsx-runtime";
39310
39327
  var container49 = {
39311
39328
  paddingLeft: 16,
@@ -39337,7 +39354,7 @@ var QuickSwitcherResult = ({ result, selected }) => {
39337
39354
  const [hovered, setIsHovered] = useState74(false);
39338
39355
  const ref = useRef41(null);
39339
39356
  const keybindings = useKeybinding();
39340
- useEffect76(() => {
39357
+ useEffect75(() => {
39341
39358
  const { current } = ref;
39342
39359
  if (!current) {
39343
39360
  return;
@@ -39351,7 +39368,7 @@ var QuickSwitcherResult = ({ result, selected }) => {
39351
39368
  current.removeEventListener("mouseleave", onMouseLeave);
39352
39369
  };
39353
39370
  }, []);
39354
- useEffect76(() => {
39371
+ useEffect75(() => {
39355
39372
  if (!selected) {
39356
39373
  return;
39357
39374
  }
@@ -39368,7 +39385,7 @@ var QuickSwitcherResult = ({ result, selected }) => {
39368
39385
  binding.unregister();
39369
39386
  };
39370
39387
  }, [keybindings, result.onSelected, selected]);
39371
- useEffect76(() => {
39388
+ useEffect75(() => {
39372
39389
  if (selected) {
39373
39390
  ref.current?.scrollIntoView({
39374
39391
  block: "nearest",
@@ -39582,7 +39599,7 @@ var QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio }
39582
39599
  selectedIndex: 0
39583
39600
  };
39584
39601
  });
39585
- useEffect77(() => {
39602
+ useEffect76(() => {
39586
39603
  setState({
39587
39604
  query: mapModeToQuery(initialMode),
39588
39605
  selectedIndex: 0
@@ -39656,7 +39673,7 @@ var QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio }
39656
39673
  };
39657
39674
  });
39658
39675
  }, []);
39659
- useEffect77(() => {
39676
+ useEffect76(() => {
39660
39677
  const binding = keybindings.registerKeybinding({
39661
39678
  key: "ArrowUp",
39662
39679
  callback: onArrowUp,
@@ -39670,7 +39687,7 @@ var QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio }
39670
39687
  binding.unregister();
39671
39688
  };
39672
39689
  }, [keybindings, onArrowDown, onArrowUp]);
39673
- useEffect77(() => {
39690
+ useEffect76(() => {
39674
39691
  if (mode !== "docs") {
39675
39692
  return;
39676
39693
  }
@@ -39695,7 +39712,7 @@ var QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio }
39695
39712
  cancelled = true;
39696
39713
  };
39697
39714
  }, [actualQuery, mode]);
39698
- useEffect77(() => {
39715
+ useEffect76(() => {
39699
39716
  const binding = keybindings.registerKeybinding({
39700
39717
  key: "ArrowDown",
39701
39718
  callback: onArrowDown,
@@ -40349,7 +40366,7 @@ import { getDefaultOutLocation } from "@remotion/studio-shared";
40349
40366
  import {
40350
40367
  useCallback as useCallback127,
40351
40368
  useContext as useContext83,
40352
- useEffect as useEffect80,
40369
+ useEffect as useEffect79,
40353
40370
  useMemo as useMemo128,
40354
40371
  useReducer as useReducer2,
40355
40372
  useRef as useRef44,
@@ -40519,7 +40536,7 @@ import { useCallback as useCallback112 } from "react";
40519
40536
  import { BrowserSafeApis } from "@remotion/renderer/client";
40520
40537
 
40521
40538
  // src/components/RenderModal/CliCopyButton.tsx
40522
- import { useCallback as useCallback111, useEffect as useEffect78, useMemo as useMemo121, useState as useState78 } from "react";
40539
+ import { useCallback as useCallback111, useEffect as useEffect77, useMemo as useMemo121, useState as useState78 } from "react";
40523
40540
  import { jsx as jsx234 } from "react/jsx-runtime";
40524
40541
  var svgStyle2 = {
40525
40542
  width: 16,
@@ -40570,7 +40587,7 @@ var CliCopyButton = ({
40570
40587
  const onPointerLeave = useCallback111(() => {
40571
40588
  setHovered(false);
40572
40589
  }, []);
40573
- useEffect78(() => {
40590
+ useEffect77(() => {
40574
40591
  if (!copied) {
40575
40592
  return;
40576
40593
  }
@@ -41892,14 +41909,14 @@ import { BrowserSafeApis as BrowserSafeApis4 } from "@remotion/renderer/client";
41892
41909
  import { useCallback as useCallback119, useMemo as useMemo123 } from "react";
41893
41910
 
41894
41911
  // src/helpers/use-file-existence.ts
41895
- import { useContext as useContext82, useEffect as useEffect79, useRef as useRef43, useState as useState80 } from "react";
41912
+ import { useContext as useContext82, useEffect as useEffect78, useRef as useRef43, useState as useState80 } from "react";
41896
41913
  var useFileExistence = (outName) => {
41897
41914
  const [exists, setExists] = useState80(false);
41898
41915
  const { previewServerState: state, subscribeToEvent } = useContext82(StudioServerConnectionCtx);
41899
41916
  const clientId = state.type === "connected" ? state.clientId : undefined;
41900
41917
  const currentOutName = useRef43("");
41901
41918
  currentOutName.current = outName;
41902
- useEffect79(() => {
41919
+ useEffect78(() => {
41903
41920
  if (!clientId) {
41904
41921
  return;
41905
41922
  }
@@ -41915,7 +41932,7 @@ var useFileExistence = (outName) => {
41915
41932
  unsubscribeFromFileExistenceWatcher({ file: outName, clientId });
41916
41933
  };
41917
41934
  }, [clientId, outName]);
41918
- useEffect79(() => {
41935
+ useEffect78(() => {
41919
41936
  const listener = (event) => {
41920
41937
  if (event.type !== "watched-file-deleted") {
41921
41938
  return;
@@ -41932,7 +41949,7 @@ var useFileExistence = (outName) => {
41932
41949
  unsub();
41933
41950
  };
41934
41951
  }, [outName, subscribeToEvent]);
41935
- useEffect79(() => {
41952
+ useEffect78(() => {
41936
41953
  const listener = (event) => {
41937
41954
  if (event.type !== "watched-file-undeleted") {
41938
41955
  return;
@@ -43984,7 +44001,7 @@ var RenderModal = ({
43984
44001
  offthreadVideoThreads,
43985
44002
  mediaCacheSizeInBytes
43986
44003
  ]);
43987
- useEffect80(() => {
44004
+ useEffect79(() => {
43988
44005
  return () => {
43989
44006
  isMounted.current = false;
43990
44007
  };
@@ -44153,7 +44170,7 @@ var RenderModal = ({
44153
44170
  onClickVideo();
44154
44171
  }
44155
44172
  }, [renderMode, onClickStill, onClickSequence, onClickVideo]);
44156
- useEffect80(() => {
44173
+ useEffect79(() => {
44157
44174
  if (renderDisabled) {
44158
44175
  return;
44159
44176
  }
@@ -44481,7 +44498,7 @@ import {
44481
44498
  getEncodableAudioCodecs,
44482
44499
  getSupportedAudioCodecsForContainer
44483
44500
  } from "@remotion/web-renderer";
44484
- import { useEffect as useEffect81, useRef as useRef45, useState as useState82 } from "react";
44501
+ import { useEffect as useEffect80, useRef as useRef45, useState as useState82 } from "react";
44485
44502
  var useEncodableAudioCodecs = (container60) => {
44486
44503
  const cacheRef = useRef45({});
44487
44504
  const [codecsByContainer, setCodecsByContainer] = useState82(() => {
@@ -44489,7 +44506,7 @@ var useEncodableAudioCodecs = (container60) => {
44489
44506
  [container60]: getSupportedAudioCodecsForContainer(container60)
44490
44507
  };
44491
44508
  });
44492
- useEffect81(() => {
44509
+ useEffect80(() => {
44493
44510
  const cached = cacheRef.current[container60];
44494
44511
  if (cached) {
44495
44512
  return;
@@ -44523,7 +44540,7 @@ import {
44523
44540
  getEncodableVideoCodecs,
44524
44541
  getSupportedVideoCodecsForContainer
44525
44542
  } from "@remotion/web-renderer";
44526
- import { useEffect as useEffect82, useRef as useRef46, useState as useState83 } from "react";
44543
+ import { useEffect as useEffect81, useRef as useRef46, useState as useState83 } from "react";
44527
44544
  var useEncodableVideoCodecs = (container60) => {
44528
44545
  const cacheRef = useRef46({});
44529
44546
  const [codecsByContainer, setCodecsByContainer] = useState83(() => {
@@ -44531,7 +44548,7 @@ var useEncodableVideoCodecs = (container60) => {
44531
44548
  [container60]: getSupportedVideoCodecsForContainer(container60)
44532
44549
  };
44533
44550
  });
44534
- useEffect82(() => {
44551
+ useEffect81(() => {
44535
44552
  const cached = cacheRef.current[container60];
44536
44553
  if (cached) {
44537
44554
  return;
@@ -45170,7 +45187,7 @@ var WebRenderModalBasic = ({
45170
45187
  };
45171
45188
 
45172
45189
  // src/components/RenderModal/WebRenderModalLicense.tsx
45173
- import { useCallback as useCallback129, useEffect as useEffect83, useState as useState84 } from "react";
45190
+ import { useCallback as useCallback129, useEffect as useEffect82, useState as useState84 } from "react";
45174
45191
 
45175
45192
  // src/icons/check-circle-filled.tsx
45176
45193
  import { jsx as jsx264 } from "react/jsx-runtime";
@@ -45392,7 +45409,7 @@ var WebRenderModalLicense = ({
45392
45409
  }) => {
45393
45410
  const [licenseValidation, setLicenseValidation] = useState84({ valid: true, message: null, details: null });
45394
45411
  const [isLoading, setIsLoading] = useState84(false);
45395
- useEffect83(() => {
45412
+ useEffect82(() => {
45396
45413
  if (licenseKey === null || licenseKey === "free-license") {
45397
45414
  return setLicenseValidation({
45398
45415
  valid: true,
@@ -46226,7 +46243,7 @@ var WebRenderModalWithLoader = (props) => {
46226
46243
  import { useCallback as useCallback134, useMemo as useMemo135 } from "react";
46227
46244
 
46228
46245
  // src/components/CopyButton.tsx
46229
- import { useCallback as useCallback132, useEffect as useEffect84, useState as useState86 } from "react";
46246
+ import { useCallback as useCallback132, useEffect as useEffect83, useState as useState86 } from "react";
46230
46247
  import { jsx as jsx269, jsxs as jsxs145 } from "react/jsx-runtime";
46231
46248
  var iconStyle8 = {
46232
46249
  width: 16,
@@ -46264,7 +46281,7 @@ var CopyButton = ({ textToCopy, label: label12, labelWhenCopied }) => {
46264
46281
  showNotification(`Could not copy: ${err.message}`, 2000);
46265
46282
  });
46266
46283
  }, [textToCopy]);
46267
- useEffect84(() => {
46284
+ useEffect83(() => {
46268
46285
  if (!copied) {
46269
46286
  return;
46270
46287
  }
@@ -46616,7 +46633,7 @@ var Editor = ({ Root, readOnlyStudio }) => {
46616
46633
  triggerOnWindowResize: false,
46617
46634
  shouldApplyCssTransforms: true
46618
46635
  });
46619
- useEffect85(() => {
46636
+ useEffect84(() => {
46620
46637
  if (readOnlyStudio) {
46621
46638
  return;
46622
46639
  }
@@ -46814,7 +46831,7 @@ var ModalsProvider = ({ children }) => {
46814
46831
 
46815
46832
  // src/components/RenderQueue/ClientRenderQueueProcessor.tsx
46816
46833
  import { renderMediaOnWeb, renderStillOnWeb } from "@remotion/web-renderer";
46817
- import { useCallback as useCallback138, useContext as useContext87, useEffect as useEffect86 } from "react";
46834
+ import { useCallback as useCallback138, useContext as useContext87, useEffect as useEffect85 } from "react";
46818
46835
  var downloadBlob = (blob, filename) => {
46819
46836
  const url = URL.createObjectURL(blob);
46820
46837
  const a = document.createElement("a");
@@ -46950,7 +46967,7 @@ var ClientRenderQueueProcessor = () => {
46950
46967
  markClientJobFailed,
46951
46968
  markClientJobCancelled
46952
46969
  ]);
46953
- useEffect86(() => {
46970
+ useEffect85(() => {
46954
46971
  setProcessJobCallback(processJob);
46955
46972
  return () => setProcessJobCallback(null);
46956
46973
  }, [processJob, setProcessJobCallback]);
@@ -46958,7 +46975,7 @@ var ClientRenderQueueProcessor = () => {
46958
46975
  };
46959
46976
 
46960
46977
  // src/components/SetTimelineInOutProvider.tsx
46961
- import { useEffect as useEffect87, useMemo as useMemo141, useState as useState92 } from "react";
46978
+ import { useEffect as useEffect86, useMemo as useMemo141, useState as useState92 } from "react";
46962
46979
 
46963
46980
  // src/state/marks.ts
46964
46981
  var localStorageKey5 = () => `remotion.editor.marksv2`;
@@ -46982,7 +46999,7 @@ var SetTimelineInOutProvider = ({ children }) => {
46982
46999
  setInAndOutFrames
46983
47000
  };
46984
47001
  }, []);
46985
- useEffect87(() => {
47002
+ useEffect86(() => {
46986
47003
  persistMarks(inAndOutFrames);
46987
47004
  }, [inAndOutFrames]);
46988
47005
  return /* @__PURE__ */ jsx279(TimelineInOutContext.Provider, {