@lalalic/markcut 1.1.1 → 2.0.0
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/AGENTS.md +39 -15
- package/README.md +7 -3
- package/SKILL.md +26 -172
- package/docs/edit-mode.md +1 -1
- package/docs/label-mode.md +6 -4
- package/docs/markdown-descriptive.md +46 -1
- package/docs/system-prompt-edit.md +16 -0
- package/package.json +1 -1
- package/src/config.mjs +8 -3
- package/src/descriptive/compiler.test.ts +42 -42
- package/src/descriptive/compiler.ts +41 -52
- package/src/descriptive/markdown.ts +8 -4
- package/src/descriptive/resolve.test.ts +14 -7
- package/src/descriptive/resolve.ts +148 -20
- package/src/entry.tsx +8 -2
- package/src/player/browser.tsx +178 -54
- package/src/player/bundle/player.js +1168 -566
- package/src/player/components/EditControls.tsx +92 -0
- package/src/player/components/HeaderBar.tsx +60 -0
- package/src/player/components/LabelControls.tsx +367 -0
- package/src/player/components/SceneThumbnails.tsx +87 -0
- package/src/player/components/VariantBar.tsx +39 -0
- package/src/player/components/index.ts +5 -0
- package/src/player/pipeline.mjs +130 -66
- package/src/player/pipeline.ts +3 -1
- package/src/player/server-shared.mjs +5 -7
- package/src/player/server.mjs +194 -187
- package/src/render/cli.mjs +66 -13
- package/src/schema/index.ts +20 -23
- package/src/types/Audio.tsx +25 -33
- package/src/types/Component.tsx +18 -24
- package/src/types/Effect.tsx +31 -39
- package/src/types/Image.tsx +23 -30
- package/src/types/Include.tsx +70 -76
- package/src/types/Map.tsx +48 -44
- package/src/types/Rhythm.tsx +19 -27
- package/src/types/Video.tsx +40 -47
- package/src/utils/component-import-map.ts +93 -0
- package/src/utils/index.ts +23 -10
- package/src/vision/cli.mjs +6 -6
- package/templates/courseware/TEMPLATE.md +317 -0
- package/templates/courseware/agents/reviewer.md +84 -0
- package/templates/courseware/prompts/fix.md +30 -0
- package/templates/courseware/prompts/outline.md +53 -0
- package/templates/courseware/prompts/scene.md +64 -0
- package/tests/fixtures/audio.json +4 -2
- package/tests/fixtures/basic.json +2 -1
- package/tests/fixtures/component-all.json +4 -2
- package/tests/fixtures/components.json +4 -2
- package/tests/fixtures/effects.json +12 -6
- package/tests/fixtures/full.json +8 -4
- package/tests/fixtures/map.json +2 -1
- package/tests/fixtures/md/dialogue.md +12 -0
- package/tests/fixtures/md/edge-cases.md +9 -0
- package/tests/fixtures/scenes.json +4 -2
- package/tests/fixtures/subtitle.json +6 -3
- package/tests/fixtures/subvideo.json +11 -6
- package/tests/fixtures/templates/courseware.md +61 -4
- package/tests/fixtures/tween-visual.json +2 -6
- package/tests/fixtures/video-series.json +6 -14
- package/tests/md-descriptive.test.ts +170 -0
- package/tests/render.test.ts +32 -16
- package/tests/schema.test.ts +6 -3
- package/tests/server.test.ts +9 -6
- package/tests/utils.ts +4 -4
- package/docs/dynamic-components.md +0 -191
- package/docs/templates.md +0 -52
- package/scripts/artlist-dl.mjs +0 -190
- package/src/player/label-server.mjs +0 -599
|
@@ -416,8 +416,8 @@ var require_react_production = __commonJS({
|
|
|
416
416
|
exports.use = function(usable) {
|
|
417
417
|
return ReactSharedInternals.H.use(usable);
|
|
418
418
|
};
|
|
419
|
-
exports.useActionState = function(
|
|
420
|
-
return ReactSharedInternals.H.useActionState(
|
|
419
|
+
exports.useActionState = function(action, initialState, permalink) {
|
|
420
|
+
return ReactSharedInternals.H.useActionState(action, initialState, permalink);
|
|
421
421
|
};
|
|
422
422
|
exports.useCallback = function(callback, deps) {
|
|
423
423
|
return ReactSharedInternals.H.useCallback(callback, deps);
|
|
@@ -778,7 +778,7 @@ var require_scheduler = __commonJS({
|
|
|
778
778
|
var require_react_dom_production = __commonJS({
|
|
779
779
|
"node_modules/react-dom/cjs/react-dom.production.js"(exports) {
|
|
780
780
|
"use strict";
|
|
781
|
-
var
|
|
781
|
+
var React56 = require_react();
|
|
782
782
|
function formatProdErrorMessage(code) {
|
|
783
783
|
var url2 = "https://react.dev/errors/" + code;
|
|
784
784
|
if (1 < arguments.length) {
|
|
@@ -818,7 +818,7 @@ var require_react_dom_production = __commonJS({
|
|
|
818
818
|
implementation
|
|
819
819
|
};
|
|
820
820
|
}
|
|
821
|
-
var ReactSharedInternals =
|
|
821
|
+
var ReactSharedInternals = React56.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
822
822
|
function getCrossOriginStringAs(as, input) {
|
|
823
823
|
if ("font" === as) return "";
|
|
824
824
|
if ("string" === typeof input)
|
|
@@ -913,8 +913,8 @@ var require_react_dom_production = __commonJS({
|
|
|
913
913
|
exports.unstable_batchedUpdates = function(fn, a2) {
|
|
914
914
|
return fn(a2);
|
|
915
915
|
};
|
|
916
|
-
exports.useFormState = function(
|
|
917
|
-
return ReactSharedInternals.H.useFormState(
|
|
916
|
+
exports.useFormState = function(action, initialState, permalink) {
|
|
917
|
+
return ReactSharedInternals.H.useFormState(action, initialState, permalink);
|
|
918
918
|
};
|
|
919
919
|
exports.useFormStatus = function() {
|
|
920
920
|
return ReactSharedInternals.H.useHostTransitionStatus();
|
|
@@ -954,8 +954,8 @@ var require_react_dom_client_production = __commonJS({
|
|
|
954
954
|
"node_modules/react-dom/cjs/react-dom-client.production.js"(exports) {
|
|
955
955
|
"use strict";
|
|
956
956
|
var Scheduler = require_scheduler();
|
|
957
|
-
var
|
|
958
|
-
var
|
|
957
|
+
var React56 = require_react();
|
|
958
|
+
var ReactDOM3 = require_react_dom();
|
|
959
959
|
function formatProdErrorMessage(code) {
|
|
960
960
|
var url2 = "https://react.dev/errors/" + code;
|
|
961
961
|
if (1 < arguments.length) {
|
|
@@ -1145,8 +1145,8 @@ var require_react_dom_client_production = __commonJS({
|
|
|
1145
1145
|
return null;
|
|
1146
1146
|
}
|
|
1147
1147
|
var isArrayImpl = Array.isArray;
|
|
1148
|
-
var ReactSharedInternals =
|
|
1149
|
-
var ReactDOMSharedInternals =
|
|
1148
|
+
var ReactSharedInternals = React56.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
1149
|
+
var ReactDOMSharedInternals = ReactDOM3.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
1150
1150
|
var sharedNotPendingObject = {
|
|
1151
1151
|
pending: false,
|
|
1152
1152
|
data: null,
|
|
@@ -4323,8 +4323,8 @@ var require_react_dom_client_production = __commonJS({
|
|
|
4323
4323
|
memoCache.index++;
|
|
4324
4324
|
return updateQueue;
|
|
4325
4325
|
}
|
|
4326
|
-
function basicStateReducer(state,
|
|
4327
|
-
return "function" === typeof
|
|
4326
|
+
function basicStateReducer(state, action) {
|
|
4327
|
+
return "function" === typeof action ? action(state) : action;
|
|
4328
4328
|
}
|
|
4329
4329
|
function updateReducer(reducer) {
|
|
4330
4330
|
var hook = updateWorkInProgressHook();
|
|
@@ -4541,12 +4541,12 @@ var require_react_dom_client_production = __commonJS({
|
|
|
4541
4541
|
}
|
|
4542
4542
|
}
|
|
4543
4543
|
function runActionStateAction(actionQueue, node) {
|
|
4544
|
-
var
|
|
4544
|
+
var action = node.action, payload = node.payload, prevState = actionQueue.state;
|
|
4545
4545
|
if (node.isTransition) {
|
|
4546
4546
|
var prevTransition = ReactSharedInternals.T, currentTransition = {};
|
|
4547
4547
|
ReactSharedInternals.T = currentTransition;
|
|
4548
4548
|
try {
|
|
4549
|
-
var returnValue =
|
|
4549
|
+
var returnValue = action(prevState, payload), onStartTransitionFinish = ReactSharedInternals.S;
|
|
4550
4550
|
null !== onStartTransitionFinish && onStartTransitionFinish(currentTransition, returnValue);
|
|
4551
4551
|
handleActionReturnValue(actionQueue, node, returnValue);
|
|
4552
4552
|
} catch (error49) {
|
|
@@ -4556,7 +4556,7 @@ var require_react_dom_client_production = __commonJS({
|
|
|
4556
4556
|
}
|
|
4557
4557
|
} else
|
|
4558
4558
|
try {
|
|
4559
|
-
prevTransition =
|
|
4559
|
+
prevTransition = action(prevState, payload), handleActionReturnValue(actionQueue, node, prevTransition);
|
|
4560
4560
|
} catch (error$66) {
|
|
4561
4561
|
onActionError(actionQueue, node, error$66);
|
|
4562
4562
|
}
|
|
@@ -4597,7 +4597,7 @@ var require_react_dom_client_production = __commonJS({
|
|
|
4597
4597
|
function actionStateReducer(oldState, newState) {
|
|
4598
4598
|
return newState;
|
|
4599
4599
|
}
|
|
4600
|
-
function mountActionState(
|
|
4600
|
+
function mountActionState(action, initialStateProp) {
|
|
4601
4601
|
if (isHydrating) {
|
|
4602
4602
|
var ssrFormState = workInProgressRoot.formState;
|
|
4603
4603
|
if (null !== ssrFormState) {
|
|
@@ -4665,7 +4665,7 @@ var require_react_dom_client_production = __commonJS({
|
|
|
4665
4665
|
JSCompiler_inline_result$jscomp$0 = {
|
|
4666
4666
|
state: initialStateProp,
|
|
4667
4667
|
dispatch: null,
|
|
4668
|
-
action
|
|
4668
|
+
action,
|
|
4669
4669
|
pending: null
|
|
4670
4670
|
};
|
|
4671
4671
|
JSCompiler_inline_result.queue = JSCompiler_inline_result$jscomp$0;
|
|
@@ -4677,14 +4677,14 @@ var require_react_dom_client_production = __commonJS({
|
|
|
4677
4677
|
ssrFormState
|
|
4678
4678
|
);
|
|
4679
4679
|
JSCompiler_inline_result$jscomp$0.dispatch = ssrFormState;
|
|
4680
|
-
JSCompiler_inline_result.memoizedState =
|
|
4680
|
+
JSCompiler_inline_result.memoizedState = action;
|
|
4681
4681
|
return [initialStateProp, ssrFormState, false];
|
|
4682
4682
|
}
|
|
4683
|
-
function updateActionState(
|
|
4683
|
+
function updateActionState(action) {
|
|
4684
4684
|
var stateHook = updateWorkInProgressHook();
|
|
4685
|
-
return updateActionStateImpl(stateHook, currentHook,
|
|
4685
|
+
return updateActionStateImpl(stateHook, currentHook, action);
|
|
4686
4686
|
}
|
|
4687
|
-
function updateActionStateImpl(stateHook, currentStateHook,
|
|
4687
|
+
function updateActionStateImpl(stateHook, currentStateHook, action) {
|
|
4688
4688
|
currentStateHook = updateReducerImpl(
|
|
4689
4689
|
stateHook,
|
|
4690
4690
|
currentStateHook,
|
|
@@ -4701,26 +4701,26 @@ var require_react_dom_client_production = __commonJS({
|
|
|
4701
4701
|
else state = currentStateHook;
|
|
4702
4702
|
currentStateHook = updateWorkInProgressHook();
|
|
4703
4703
|
var actionQueue = currentStateHook.queue, dispatch = actionQueue.dispatch;
|
|
4704
|
-
|
|
4704
|
+
action !== currentStateHook.memoizedState && (currentlyRenderingFiber.flags |= 2048, pushSimpleEffect(
|
|
4705
4705
|
9,
|
|
4706
4706
|
{ destroy: void 0 },
|
|
4707
|
-
actionStateActionEffect.bind(null, actionQueue,
|
|
4707
|
+
actionStateActionEffect.bind(null, actionQueue, action),
|
|
4708
4708
|
null
|
|
4709
4709
|
));
|
|
4710
4710
|
return [state, dispatch, stateHook];
|
|
4711
4711
|
}
|
|
4712
|
-
function actionStateActionEffect(actionQueue,
|
|
4713
|
-
actionQueue.action =
|
|
4712
|
+
function actionStateActionEffect(actionQueue, action) {
|
|
4713
|
+
actionQueue.action = action;
|
|
4714
4714
|
}
|
|
4715
|
-
function rerenderActionState(
|
|
4715
|
+
function rerenderActionState(action) {
|
|
4716
4716
|
var stateHook = updateWorkInProgressHook(), currentStateHook = currentHook;
|
|
4717
4717
|
if (null !== currentStateHook)
|
|
4718
|
-
return updateActionStateImpl(stateHook, currentStateHook,
|
|
4718
|
+
return updateActionStateImpl(stateHook, currentStateHook, action);
|
|
4719
4719
|
updateWorkInProgressHook();
|
|
4720
4720
|
stateHook = stateHook.memoizedState;
|
|
4721
4721
|
currentStateHook = updateWorkInProgressHook();
|
|
4722
4722
|
var dispatch = currentStateHook.queue.dispatch;
|
|
4723
|
-
currentStateHook.memoizedState =
|
|
4723
|
+
currentStateHook.memoizedState = action;
|
|
4724
4724
|
return [stateHook, dispatch, false];
|
|
4725
4725
|
}
|
|
4726
4726
|
function pushSimpleEffect(tag, inst, create, deps) {
|
|
@@ -4892,7 +4892,7 @@ var require_react_dom_client_production = __commonJS({
|
|
|
4892
4892
|
}
|
|
4893
4893
|
function noop2() {
|
|
4894
4894
|
}
|
|
4895
|
-
function startHostTransition(formFiber, pendingState,
|
|
4895
|
+
function startHostTransition(formFiber, pendingState, action, formData) {
|
|
4896
4896
|
if (5 !== formFiber.tag) throw Error(formatProdErrorMessage(476));
|
|
4897
4897
|
var queue = ensureFormComponentIsStateful(formFiber).queue;
|
|
4898
4898
|
startTransition(
|
|
@@ -4900,9 +4900,9 @@ var require_react_dom_client_production = __commonJS({
|
|
|
4900
4900
|
queue,
|
|
4901
4901
|
pendingState,
|
|
4902
4902
|
sharedNotPendingObject,
|
|
4903
|
-
null ===
|
|
4903
|
+
null === action ? noop2 : function() {
|
|
4904
4904
|
requestFormReset$1(formFiber);
|
|
4905
|
-
return
|
|
4905
|
+
return action(formData);
|
|
4906
4906
|
}
|
|
4907
4907
|
);
|
|
4908
4908
|
}
|
|
@@ -4976,29 +4976,29 @@ var require_react_dom_client_production = __commonJS({
|
|
|
4976
4976
|
provider = provider.return;
|
|
4977
4977
|
}
|
|
4978
4978
|
}
|
|
4979
|
-
function dispatchReducerAction(fiber, queue,
|
|
4979
|
+
function dispatchReducerAction(fiber, queue, action) {
|
|
4980
4980
|
var lane = requestUpdateLane();
|
|
4981
|
-
|
|
4981
|
+
action = {
|
|
4982
4982
|
lane,
|
|
4983
4983
|
revertLane: 0,
|
|
4984
4984
|
gesture: null,
|
|
4985
|
-
action
|
|
4985
|
+
action,
|
|
4986
4986
|
hasEagerState: false,
|
|
4987
4987
|
eagerState: null,
|
|
4988
4988
|
next: null
|
|
4989
4989
|
};
|
|
4990
|
-
isRenderPhaseUpdate(fiber) ? enqueueRenderPhaseUpdate(queue,
|
|
4990
|
+
isRenderPhaseUpdate(fiber) ? enqueueRenderPhaseUpdate(queue, action) : (action = enqueueConcurrentHookUpdate(fiber, queue, action, lane), null !== action && (scheduleUpdateOnFiber(action, fiber, lane), entangleTransitionUpdate(action, queue, lane)));
|
|
4991
4991
|
}
|
|
4992
|
-
function dispatchSetState(fiber, queue,
|
|
4992
|
+
function dispatchSetState(fiber, queue, action) {
|
|
4993
4993
|
var lane = requestUpdateLane();
|
|
4994
|
-
dispatchSetStateInternal(fiber, queue,
|
|
4994
|
+
dispatchSetStateInternal(fiber, queue, action, lane);
|
|
4995
4995
|
}
|
|
4996
|
-
function dispatchSetStateInternal(fiber, queue,
|
|
4996
|
+
function dispatchSetStateInternal(fiber, queue, action, lane) {
|
|
4997
4997
|
var update = {
|
|
4998
4998
|
lane,
|
|
4999
4999
|
revertLane: 0,
|
|
5000
5000
|
gesture: null,
|
|
5001
|
-
action
|
|
5001
|
+
action,
|
|
5002
5002
|
hasEagerState: false,
|
|
5003
5003
|
eagerState: null,
|
|
5004
5004
|
next: null
|
|
@@ -5008,7 +5008,7 @@ var require_react_dom_client_production = __commonJS({
|
|
|
5008
5008
|
var alternate = fiber.alternate;
|
|
5009
5009
|
if (0 === fiber.lanes && (null === alternate || 0 === alternate.lanes) && (alternate = queue.lastRenderedReducer, null !== alternate))
|
|
5010
5010
|
try {
|
|
5011
|
-
var currentState = queue.lastRenderedState, eagerState = alternate(currentState,
|
|
5011
|
+
var currentState = queue.lastRenderedState, eagerState = alternate(currentState, action);
|
|
5012
5012
|
update.hasEagerState = true;
|
|
5013
5013
|
update.eagerState = eagerState;
|
|
5014
5014
|
if (objectIs(eagerState, currentState))
|
|
@@ -5016,18 +5016,18 @@ var require_react_dom_client_production = __commonJS({
|
|
|
5016
5016
|
} catch (error49) {
|
|
5017
5017
|
} finally {
|
|
5018
5018
|
}
|
|
5019
|
-
|
|
5020
|
-
if (null !==
|
|
5021
|
-
return scheduleUpdateOnFiber(
|
|
5019
|
+
action = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
|
|
5020
|
+
if (null !== action)
|
|
5021
|
+
return scheduleUpdateOnFiber(action, fiber, lane), entangleTransitionUpdate(action, queue, lane), true;
|
|
5022
5022
|
}
|
|
5023
5023
|
return false;
|
|
5024
5024
|
}
|
|
5025
|
-
function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue,
|
|
5026
|
-
|
|
5025
|
+
function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) {
|
|
5026
|
+
action = {
|
|
5027
5027
|
lane: 2,
|
|
5028
5028
|
revertLane: requestTransitionLane(),
|
|
5029
5029
|
gesture: null,
|
|
5030
|
-
action
|
|
5030
|
+
action,
|
|
5031
5031
|
hasEagerState: false,
|
|
5032
5032
|
eagerState: null,
|
|
5033
5033
|
next: null
|
|
@@ -5038,7 +5038,7 @@ var require_react_dom_client_production = __commonJS({
|
|
|
5038
5038
|
throwIfDuringRender = enqueueConcurrentHookUpdate(
|
|
5039
5039
|
fiber,
|
|
5040
5040
|
queue,
|
|
5041
|
-
|
|
5041
|
+
action,
|
|
5042
5042
|
2
|
|
5043
5043
|
), null !== throwIfDuringRender && scheduleUpdateOnFiber(throwIfDuringRender, fiber, 2);
|
|
5044
5044
|
}
|
|
@@ -9816,10 +9816,10 @@ var require_react_dom_client_production = __commonJS({
|
|
|
9816
9816
|
}
|
|
9817
9817
|
function extractEvents$1(dispatchQueue, domEventName, maybeTargetInst, nativeEvent, nativeEventTarget) {
|
|
9818
9818
|
if ("submit" === domEventName && maybeTargetInst && maybeTargetInst.stateNode === nativeEventTarget) {
|
|
9819
|
-
var
|
|
9819
|
+
var action = coerceFormActionProp(
|
|
9820
9820
|
(nativeEventTarget[internalPropsKey] || null).action
|
|
9821
9821
|
), submitter = nativeEvent.submitter;
|
|
9822
|
-
submitter && (domEventName = (domEventName = submitter[internalPropsKey] || null) ? coerceFormActionProp(domEventName.formAction) : submitter.getAttribute("formAction"), null !== domEventName && (
|
|
9822
|
+
submitter && (domEventName = (domEventName = submitter[internalPropsKey] || null) ? coerceFormActionProp(domEventName.formAction) : submitter.getAttribute("formAction"), null !== domEventName && (action = domEventName, submitter = null));
|
|
9823
9823
|
var event = new SyntheticEvent(
|
|
9824
9824
|
"action",
|
|
9825
9825
|
"action",
|
|
@@ -9842,22 +9842,22 @@ var require_react_dom_client_production = __commonJS({
|
|
|
9842
9842
|
pending: true,
|
|
9843
9843
|
data: formData,
|
|
9844
9844
|
method: nativeEventTarget.method,
|
|
9845
|
-
action
|
|
9845
|
+
action
|
|
9846
9846
|
},
|
|
9847
9847
|
null,
|
|
9848
9848
|
formData
|
|
9849
9849
|
);
|
|
9850
9850
|
}
|
|
9851
9851
|
} else
|
|
9852
|
-
"function" === typeof
|
|
9852
|
+
"function" === typeof action && (event.preventDefault(), formData = submitter ? createFormDataWithSubmitter(nativeEventTarget, submitter) : new FormData(nativeEventTarget), startHostTransition(
|
|
9853
9853
|
maybeTargetInst,
|
|
9854
9854
|
{
|
|
9855
9855
|
pending: true,
|
|
9856
9856
|
data: formData,
|
|
9857
9857
|
method: nativeEventTarget.method,
|
|
9858
|
-
action
|
|
9858
|
+
action
|
|
9859
9859
|
},
|
|
9860
|
-
|
|
9860
|
+
action,
|
|
9861
9861
|
formData
|
|
9862
9862
|
));
|
|
9863
9863
|
},
|
|
@@ -12506,15 +12506,15 @@ var require_react_dom_client_production = __commonJS({
|
|
|
12506
12506
|
if ("function" === typeof submitterOrAction)
|
|
12507
12507
|
formProps || scheduleReplayQueueIfNeeded(i3);
|
|
12508
12508
|
else if (formProps) {
|
|
12509
|
-
var
|
|
12509
|
+
var action = null;
|
|
12510
12510
|
if (submitterOrAction && submitterOrAction.hasAttribute("formAction"))
|
|
12511
12511
|
if (form = submitterOrAction, formProps = submitterOrAction[internalPropsKey] || null)
|
|
12512
|
-
|
|
12512
|
+
action = formProps.formAction;
|
|
12513
12513
|
else {
|
|
12514
12514
|
if (null !== findInstanceBlockingTarget(form)) continue;
|
|
12515
12515
|
}
|
|
12516
|
-
else
|
|
12517
|
-
"function" === typeof
|
|
12516
|
+
else action = formProps.action;
|
|
12517
|
+
"function" === typeof action ? i3[queuedTarget + 1] = action : (i3.splice(queuedTarget, 3), queuedTarget -= 3);
|
|
12518
12518
|
scheduleReplayQueueIfNeeded(i3);
|
|
12519
12519
|
}
|
|
12520
12520
|
}
|
|
@@ -12591,7 +12591,7 @@ var require_react_dom_client_production = __commonJS({
|
|
|
12591
12591
|
0 === i3 && attemptExplicitHydrationTarget(target);
|
|
12592
12592
|
}
|
|
12593
12593
|
};
|
|
12594
|
-
var isomorphicReactPackageVersion$jscomp$inline_1840 =
|
|
12594
|
+
var isomorphicReactPackageVersion$jscomp$inline_1840 = React56.version;
|
|
12595
12595
|
if ("19.2.5" !== isomorphicReactPackageVersion$jscomp$inline_1840)
|
|
12596
12596
|
throw Error(
|
|
12597
12597
|
formatProdErrorMessage(
|
|
@@ -12794,9 +12794,9 @@ var require_fast_deep_equal = __commonJS({
|
|
|
12794
12794
|
});
|
|
12795
12795
|
|
|
12796
12796
|
// src/player/browser.tsx
|
|
12797
|
-
var
|
|
12797
|
+
var React55 = __toESM(require_react(), 1);
|
|
12798
12798
|
var import_client = __toESM(require_client(), 1);
|
|
12799
|
-
var
|
|
12799
|
+
var ReactDOM2 = __toESM(require_react_dom(), 1);
|
|
12800
12800
|
|
|
12801
12801
|
// node_modules/remotion/dist/esm/index.mjs
|
|
12802
12802
|
var esm_exports = {};
|
|
@@ -17159,16 +17159,16 @@ var resolveTrimProps = ({
|
|
|
17159
17159
|
const trimAfterValue = trimAfter ?? endAt ?? void 0;
|
|
17160
17160
|
return { trimBeforeValue, trimAfterValue };
|
|
17161
17161
|
};
|
|
17162
|
-
var durationReducer = (state,
|
|
17163
|
-
switch (
|
|
17162
|
+
var durationReducer = (state, action) => {
|
|
17163
|
+
switch (action.type) {
|
|
17164
17164
|
case "got-duration": {
|
|
17165
|
-
const absoluteSrc = getAbsoluteSrc(
|
|
17166
|
-
if (state[absoluteSrc] ===
|
|
17165
|
+
const absoluteSrc = getAbsoluteSrc(action.src);
|
|
17166
|
+
if (state[absoluteSrc] === action.durationInSeconds) {
|
|
17167
17167
|
return state;
|
|
17168
17168
|
}
|
|
17169
17169
|
return {
|
|
17170
17170
|
...state,
|
|
17171
|
-
[absoluteSrc]:
|
|
17171
|
+
[absoluteSrc]: action.durationInSeconds
|
|
17172
17172
|
};
|
|
17173
17173
|
}
|
|
17174
17174
|
default:
|
|
@@ -27936,15 +27936,84 @@ var forward2 = import_react110.forwardRef;
|
|
|
27936
27936
|
var Thumbnail = forward2(ThumbnailFn);
|
|
27937
27937
|
|
|
27938
27938
|
// src/entry.tsx
|
|
27939
|
-
var
|
|
27939
|
+
var React47 = __toESM(require_react(), 1);
|
|
27940
|
+
|
|
27941
|
+
// src/utils/component-import-map.ts
|
|
27942
|
+
var React8 = __toESM(require_react(), 1);
|
|
27943
|
+
var ReactDOM = __toESM(require_react_dom(), 1);
|
|
27944
|
+
function ensureSharedImportMap() {
|
|
27945
|
+
var _a3, _b, _c;
|
|
27946
|
+
if (typeof document === "undefined") return;
|
|
27947
|
+
if (document.querySelector("#rmtr-import-map")) return;
|
|
27948
|
+
const g2 = globalThis;
|
|
27949
|
+
g2.__remotionShared ?? (g2.__remotionShared = {});
|
|
27950
|
+
(_a3 = g2.__remotionShared)["react"] ?? (_a3["react"] = React8);
|
|
27951
|
+
(_b = g2.__remotionShared)["react-dom"] ?? (_b["react-dom"] = ReactDOM);
|
|
27952
|
+
(_c = g2.__remotionShared)["remotion"] ?? (_c["remotion"] = esm_exports);
|
|
27953
|
+
if (!g2.__nodeModuleStub) {
|
|
27954
|
+
const nodeModuleStubCode = `export function createRequire() { return () => ({ resolve: () => { throw new Error("node:module.createRequire is not available in the browser"); } }); }`;
|
|
27955
|
+
g2.__nodeModuleStub = URL.createObjectURL(
|
|
27956
|
+
new Blob([nodeModuleStubCode], { type: "application/javascript" })
|
|
27957
|
+
);
|
|
27958
|
+
}
|
|
27959
|
+
try {
|
|
27960
|
+
const imports = {};
|
|
27961
|
+
for (const spec of ["node:module", "node:fs", "node:path", "node:os"]) {
|
|
27962
|
+
imports[spec] = g2.__nodeModuleStub;
|
|
27963
|
+
}
|
|
27964
|
+
for (const [specifier, mod] of Object.entries(g2.__remotionShared)) {
|
|
27965
|
+
const lines = [
|
|
27966
|
+
`const _mod = globalThis.__remotionShared[${JSON.stringify(specifier)}];`
|
|
27967
|
+
];
|
|
27968
|
+
for (const name of Object.keys(mod)) {
|
|
27969
|
+
if (name === "default") continue;
|
|
27970
|
+
lines.push(
|
|
27971
|
+
`const __${name} = _mod[${JSON.stringify(name)}];`,
|
|
27972
|
+
`export { __${name} as ${name} };`
|
|
27973
|
+
);
|
|
27974
|
+
}
|
|
27975
|
+
if ("default" in mod) lines.push("export default _mod.default;");
|
|
27976
|
+
imports[specifier] = URL.createObjectURL(
|
|
27977
|
+
new Blob([lines.join("\n")], { type: "application/javascript" })
|
|
27978
|
+
);
|
|
27979
|
+
}
|
|
27980
|
+
const blobJsx = new Blob(
|
|
27981
|
+
[
|
|
27982
|
+
`
|
|
27983
|
+
const R = globalThis.__remotionShared["react"];
|
|
27984
|
+
const { createElement, Fragment } = R;
|
|
27985
|
+
export { Fragment };
|
|
27986
|
+
export function jsx(type, props, key) {
|
|
27987
|
+
return createElement(type, key != null ? { ...props, key } : props);
|
|
27988
|
+
}
|
|
27989
|
+
export function jsxs(type, props, key) {
|
|
27990
|
+
return createElement(type, key != null ? { ...props, key } : props);
|
|
27991
|
+
}
|
|
27992
|
+
export function jsxDEV(type, props, key, isStaticChildren, source, self) {
|
|
27993
|
+
return createElement(type, key != null ? { ...props, key } : props);
|
|
27994
|
+
}
|
|
27995
|
+
`
|
|
27996
|
+
],
|
|
27997
|
+
{ type: "application/javascript" }
|
|
27998
|
+
);
|
|
27999
|
+
imports["react/jsx-runtime"] = URL.createObjectURL(blobJsx);
|
|
28000
|
+
const script = document.createElement("script");
|
|
28001
|
+
script.type = "importmap";
|
|
28002
|
+
script.id = "rmtr-import-map";
|
|
28003
|
+
script.textContent = JSON.stringify({ imports });
|
|
28004
|
+
document.head.appendChild(script);
|
|
28005
|
+
} catch (e) {
|
|
28006
|
+
console.warn("Failed to create shared module import map:", e);
|
|
28007
|
+
}
|
|
28008
|
+
}
|
|
27940
28009
|
|
|
27941
28010
|
// src/context/index.tsx
|
|
27942
|
-
var
|
|
28011
|
+
var React15 = __toESM(require_react(), 1);
|
|
27943
28012
|
|
|
27944
28013
|
// src/context/EventContext.tsx
|
|
27945
|
-
var
|
|
28014
|
+
var React9 = __toESM(require_react(), 1);
|
|
27946
28015
|
var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
|
|
27947
|
-
var EventContext =
|
|
28016
|
+
var EventContext = React9.createContext(null);
|
|
27948
28017
|
function createComponentProxy(target, setState) {
|
|
27949
28018
|
return new Proxy(target, {
|
|
27950
28019
|
set(obj, prop, value) {
|
|
@@ -27959,8 +28028,8 @@ function createComponentProxy(target, setState) {
|
|
|
27959
28028
|
});
|
|
27960
28029
|
}
|
|
27961
28030
|
function EventProvider({ children }) {
|
|
27962
|
-
const registryRef =
|
|
27963
|
-
const register =
|
|
28031
|
+
const registryRef = React9.useRef(/* @__PURE__ */ new Map());
|
|
28032
|
+
const register = React9.useCallback(
|
|
27964
28033
|
(id, setState) => {
|
|
27965
28034
|
const target = {};
|
|
27966
28035
|
const proxy = createComponentProxy(target, setState);
|
|
@@ -27968,10 +28037,10 @@ function EventProvider({ children }) {
|
|
|
27968
28037
|
},
|
|
27969
28038
|
[]
|
|
27970
28039
|
);
|
|
27971
|
-
const unregister =
|
|
28040
|
+
const unregister = React9.useCallback((id) => {
|
|
27972
28041
|
registryRef.current.delete(id);
|
|
27973
28042
|
}, []);
|
|
27974
|
-
const evaluate =
|
|
28043
|
+
const evaluate = React9.useCallback((code) => {
|
|
27975
28044
|
const scope = {};
|
|
27976
28045
|
for (const [id, reg] of registryRef.current) {
|
|
27977
28046
|
scope[id] = reg.proxy;
|
|
@@ -27986,14 +28055,14 @@ function EventProvider({ children }) {
|
|
|
27986
28055
|
console.warn(`Event evaluation failed: "${code}"`, err);
|
|
27987
28056
|
}
|
|
27988
28057
|
}, []);
|
|
27989
|
-
const value =
|
|
28058
|
+
const value = React9.useMemo(
|
|
27990
28059
|
() => ({ register, unregister, evaluate }),
|
|
27991
28060
|
[register, unregister, evaluate]
|
|
27992
28061
|
);
|
|
27993
28062
|
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(EventContext.Provider, { value, children });
|
|
27994
28063
|
}
|
|
27995
28064
|
function useEventContext() {
|
|
27996
|
-
const ctx =
|
|
28065
|
+
const ctx = React9.useContext(EventContext);
|
|
27997
28066
|
if (!ctx) {
|
|
27998
28067
|
throw new Error("useEventContext must be used within an EventProvider");
|
|
27999
28068
|
}
|
|
@@ -28017,8 +28086,8 @@ function useFrameEvents(on, durationInFrames) {
|
|
|
28017
28086
|
const frame = useCurrentFrame();
|
|
28018
28087
|
const { fps } = useVideoConfig();
|
|
28019
28088
|
const { evaluate } = useEventContext();
|
|
28020
|
-
const handledRef =
|
|
28021
|
-
|
|
28089
|
+
const handledRef = React9.useRef(false);
|
|
28090
|
+
React9.useEffect(() => {
|
|
28022
28091
|
if (!on || durationInFrames <= 0) return;
|
|
28023
28092
|
const targetFrame = resolveWhenToFrame(on.when, durationInFrames, fps);
|
|
28024
28093
|
if (frame === targetFrame && !handledRef.current) {
|
|
@@ -28032,13 +28101,13 @@ function useFrameEvents(on, durationInFrames) {
|
|
|
28032
28101
|
// src/context/index.tsx
|
|
28033
28102
|
var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
|
|
28034
28103
|
var DefaultContainer = ({ children, style: style2 }) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { style: { position: "absolute", inset: 0, ...style2 }, children });
|
|
28035
|
-
var ComposeContext =
|
|
28104
|
+
var ComposeContext = React15.createContext({
|
|
28036
28105
|
Container: DefaultContainer
|
|
28037
28106
|
});
|
|
28038
|
-
var AudioContext2 =
|
|
28107
|
+
var AudioContext2 = React15.createContext(null);
|
|
28039
28108
|
|
|
28040
28109
|
// src/types/Folder.tsx
|
|
28041
|
-
var
|
|
28110
|
+
var React45 = __toESM(require_react(), 1);
|
|
28042
28111
|
|
|
28043
28112
|
// node_modules/@remotion/transitions/dist/esm/index.mjs
|
|
28044
28113
|
var import_react113 = __toESM(require_react(), 1);
|
|
@@ -30316,6 +30385,12 @@ function cssJS(css) {
|
|
|
30316
30385
|
}
|
|
30317
30386
|
return out;
|
|
30318
30387
|
}
|
|
30388
|
+
function leafEnd(stream2) {
|
|
30389
|
+
if (typeof stream2.end === "number") return stream2.end;
|
|
30390
|
+
const s2 = stream2.start ?? 0;
|
|
30391
|
+
if (typeof stream2.duration === "number") return s2 + stream2.duration;
|
|
30392
|
+
return 0;
|
|
30393
|
+
}
|
|
30319
30394
|
function getDurationInSeconds(stream2, update = true) {
|
|
30320
30395
|
if (!stream2) return 0;
|
|
30321
30396
|
if (stream2.type === "rhythm") {
|
|
@@ -30323,8 +30398,7 @@ function getDurationInSeconds(stream2, update = true) {
|
|
|
30323
30398
|
}
|
|
30324
30399
|
if (stream2.type === "include") {
|
|
30325
30400
|
if (stream2.src) {
|
|
30326
|
-
const
|
|
30327
|
-
const d2 = last?.end ?? 0;
|
|
30401
|
+
const d2 = leafEnd(stream2);
|
|
30328
30402
|
if (update) stream2.durationInSeconds = d2;
|
|
30329
30403
|
return d2;
|
|
30330
30404
|
}
|
|
@@ -30344,8 +30418,7 @@ function getDurationInSeconds(stream2, update = true) {
|
|
|
30344
30418
|
return total2;
|
|
30345
30419
|
}
|
|
30346
30420
|
if (!stream2.children?.length) {
|
|
30347
|
-
const
|
|
30348
|
-
const d2 = last?.end ?? 0;
|
|
30421
|
+
const d2 = leafEnd(stream2);
|
|
30349
30422
|
if (update) stream2.durationInSeconds = d2;
|
|
30350
30423
|
return d2;
|
|
30351
30424
|
}
|
|
@@ -30394,10 +30467,10 @@ function parseVTT(src) {
|
|
|
30394
30467
|
}
|
|
30395
30468
|
|
|
30396
30469
|
// src/types/Video.tsx
|
|
30397
|
-
var
|
|
30470
|
+
var React19 = __toESM(require_react(), 1);
|
|
30398
30471
|
|
|
30399
30472
|
// src/types/FrameSyncStyle.tsx
|
|
30400
|
-
var
|
|
30473
|
+
var React18 = __toESM(require_react(), 1);
|
|
30401
30474
|
var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1);
|
|
30402
30475
|
function FrameSyncStyle({
|
|
30403
30476
|
style: style2,
|
|
@@ -30406,7 +30479,7 @@ function FrameSyncStyle({
|
|
|
30406
30479
|
const frame = useCurrentFrame();
|
|
30407
30480
|
const { fps } = useVideoConfig();
|
|
30408
30481
|
const hasAnimation = "animation" in style2;
|
|
30409
|
-
const mergedStyle =
|
|
30482
|
+
const mergedStyle = React18.useMemo(() => {
|
|
30410
30483
|
if (!hasAnimation) return style2;
|
|
30411
30484
|
const currentTime = frame / fps;
|
|
30412
30485
|
return {
|
|
@@ -30437,60 +30510,57 @@ function resolveVideoSrc(src) {
|
|
|
30437
30510
|
}
|
|
30438
30511
|
function VideoLeaf({ stream: stream2 }) {
|
|
30439
30512
|
const { fps } = useVideoConfig();
|
|
30440
|
-
const audio2 =
|
|
30441
|
-
const
|
|
30513
|
+
const audio2 = React19.useContext(AudioContext2);
|
|
30514
|
+
const start = stream2.start ?? 0;
|
|
30515
|
+
const end = stream2.end ?? start + (stream2.duration ?? 1);
|
|
30516
|
+
const totalDur = stream2.durationInSeconds ?? end;
|
|
30442
30517
|
useFrameEvents(stream2.on, Math.max(1, Math.floor(totalDur * fps)));
|
|
30443
30518
|
if (!stream2.src) return null;
|
|
30444
30519
|
const resolvedSrc = resolveVideoSrc(stream2.src);
|
|
30445
|
-
|
|
30446
|
-
|
|
30447
|
-
|
|
30448
|
-
|
|
30449
|
-
|
|
30450
|
-
|
|
30451
|
-
|
|
30452
|
-
|
|
30453
|
-
|
|
30454
|
-
|
|
30455
|
-
|
|
30456
|
-
|
|
30457
|
-
|
|
30458
|
-
|
|
30459
|
-
|
|
30460
|
-
|
|
30461
|
-
|
|
30462
|
-
|
|
30463
|
-
|
|
30464
|
-
|
|
30465
|
-
|
|
30466
|
-
|
|
30467
|
-
|
|
30468
|
-
|
|
30469
|
-
|
|
30470
|
-
|
|
30471
|
-
|
|
30472
|
-
|
|
30473
|
-
|
|
30474
|
-
|
|
30475
|
-
|
|
30476
|
-
|
|
30477
|
-
|
|
30478
|
-
|
|
30479
|
-
|
|
30480
|
-
|
|
30481
|
-
|
|
30482
|
-
|
|
30483
|
-
|
|
30484
|
-
|
|
30485
|
-
)
|
|
30486
|
-
},
|
|
30487
|
-
a2.id
|
|
30488
|
-
);
|
|
30489
|
-
}) });
|
|
30520
|
+
const startFrom = stream2.startFrom ?? 0;
|
|
30521
|
+
const endAt = stream2.endAt ?? totalDur;
|
|
30522
|
+
const volume = stream2.volume ?? 1;
|
|
30523
|
+
const playbackRate = stream2.loop ? 1 : Math.min(1, toPlaybackRate((endAt - startFrom) / (end - start)));
|
|
30524
|
+
const streamStyle = cssJS(stream2.style);
|
|
30525
|
+
const hasAnimation = "animation" in streamStyle;
|
|
30526
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
30527
|
+
Sequence,
|
|
30528
|
+
{
|
|
30529
|
+
durationInFrames: Math.max(1, Math.floor(fps * (end - start))),
|
|
30530
|
+
from: Math.floor(fps * start),
|
|
30531
|
+
layout: "none",
|
|
30532
|
+
showInTimeline: false,
|
|
30533
|
+
children: hasAnimation ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(FrameSyncStyle, { style: streamStyle, children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
30534
|
+
OffthreadVideo,
|
|
30535
|
+
{
|
|
30536
|
+
src: resolvedSrc,
|
|
30537
|
+
startFrom: Math.floor(startFrom * fps),
|
|
30538
|
+
endAt: Math.floor(startFrom * fps) + Math.floor((endAt - startFrom) * fps / playbackRate),
|
|
30539
|
+
muted: volume === 0 || !!audio2?.foreground,
|
|
30540
|
+
volume,
|
|
30541
|
+
playbackRate,
|
|
30542
|
+
showInTimeline: false,
|
|
30543
|
+
style: { width: "100%", height: "100%" }
|
|
30544
|
+
}
|
|
30545
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
30546
|
+
OffthreadVideo,
|
|
30547
|
+
{
|
|
30548
|
+
src: resolvedSrc,
|
|
30549
|
+
startFrom: Math.floor(startFrom * fps),
|
|
30550
|
+
endAt: Math.floor(startFrom * fps) + Math.floor((endAt - startFrom) * fps / playbackRate),
|
|
30551
|
+
muted: volume === 0 || !!audio2?.foreground,
|
|
30552
|
+
volume,
|
|
30553
|
+
playbackRate,
|
|
30554
|
+
showInTimeline: false,
|
|
30555
|
+
style: { width: "100%", height: "100%", ...streamStyle }
|
|
30556
|
+
}
|
|
30557
|
+
)
|
|
30558
|
+
}
|
|
30559
|
+
);
|
|
30490
30560
|
}
|
|
30491
30561
|
|
|
30492
30562
|
// src/types/Audio.tsx
|
|
30493
|
-
var
|
|
30563
|
+
var React25 = __toESM(require_react(), 1);
|
|
30494
30564
|
var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1);
|
|
30495
30565
|
function resolveAudioSrc(src) {
|
|
30496
30566
|
if (/^(https?:|data:|blob:|file:|\/)/.test(src)) return src;
|
|
@@ -30499,44 +30569,41 @@ function resolveAudioSrc(src) {
|
|
|
30499
30569
|
function AudioLeaf({ stream: stream2 }) {
|
|
30500
30570
|
const { fps } = useVideoConfig();
|
|
30501
30571
|
const environment = useRemotionEnvironment();
|
|
30502
|
-
const ctx =
|
|
30503
|
-
const
|
|
30572
|
+
const ctx = React25.useContext(AudioContext2);
|
|
30573
|
+
const start = stream2.start ?? 0;
|
|
30574
|
+
const end = stream2.end ?? start + (stream2.duration ?? 1);
|
|
30575
|
+
const totalDur = stream2.durationInSeconds ?? end;
|
|
30504
30576
|
useFrameEvents(stream2.on, Math.max(1, Math.floor(totalDur * fps)));
|
|
30505
30577
|
if (!stream2.src) return null;
|
|
30506
30578
|
if (environment.isStudio) return null;
|
|
30507
30579
|
const resolvedSrc = resolveAudioSrc(stream2.src);
|
|
30508
|
-
|
|
30509
|
-
|
|
30510
|
-
|
|
30511
|
-
|
|
30512
|
-
|
|
30513
|
-
|
|
30514
|
-
|
|
30515
|
-
|
|
30516
|
-
|
|
30517
|
-
|
|
30518
|
-
|
|
30519
|
-
|
|
30520
|
-
|
|
30521
|
-
|
|
30522
|
-
|
|
30523
|
-
|
|
30524
|
-
|
|
30525
|
-
|
|
30526
|
-
|
|
30527
|
-
|
|
30528
|
-
|
|
30529
|
-
|
|
30530
|
-
|
|
30531
|
-
|
|
30532
|
-
|
|
30533
|
-
|
|
30534
|
-
|
|
30535
|
-
)
|
|
30536
|
-
},
|
|
30537
|
-
a2.id
|
|
30538
|
-
);
|
|
30539
|
-
}) });
|
|
30580
|
+
const startFrom = stream2.startFrom ?? 0;
|
|
30581
|
+
const endAt = stream2.endAt ?? totalDur;
|
|
30582
|
+
const volume = stream2.volume ?? 1;
|
|
30583
|
+
const playbackRate = stream2.loop ? 1 : toPlaybackRate((endAt - startFrom) / (end - start));
|
|
30584
|
+
return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
30585
|
+
Sequence,
|
|
30586
|
+
{
|
|
30587
|
+
name: stream2.src ?? "audio",
|
|
30588
|
+
durationInFrames: Math.max(1, Math.floor(fps * (end - start))),
|
|
30589
|
+
from: Math.floor(fps * start),
|
|
30590
|
+
layout: "none",
|
|
30591
|
+
showInTimeline: false,
|
|
30592
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
30593
|
+
Audio,
|
|
30594
|
+
{
|
|
30595
|
+
src: resolvedSrc,
|
|
30596
|
+
startFrom: Math.floor(startFrom * fps),
|
|
30597
|
+
endAt: Math.floor(startFrom * fps) + Math.floor((endAt - startFrom) * fps / playbackRate),
|
|
30598
|
+
muted: volume === 0 || !!ctx?.foreground,
|
|
30599
|
+
volume,
|
|
30600
|
+
loop: (stream2.loop ?? 1) > 1,
|
|
30601
|
+
playbackRate,
|
|
30602
|
+
showInTimeline: false
|
|
30603
|
+
}
|
|
30604
|
+
)
|
|
30605
|
+
}
|
|
30606
|
+
);
|
|
30540
30607
|
}
|
|
30541
30608
|
|
|
30542
30609
|
// src/types/Image.tsx
|
|
@@ -30547,42 +30614,39 @@ function resolveImageSrc(src) {
|
|
|
30547
30614
|
}
|
|
30548
30615
|
function ImageLeaf({ stream: stream2 }) {
|
|
30549
30616
|
const { fps } = useVideoConfig();
|
|
30550
|
-
const
|
|
30617
|
+
const start = stream2.start ?? 0;
|
|
30618
|
+
const end = stream2.end ?? start + (stream2.duration ?? 1);
|
|
30619
|
+
const totalDur = stream2.durationInSeconds ?? end;
|
|
30551
30620
|
useFrameEvents(stream2.on, Math.max(1, Math.floor(totalDur * fps)));
|
|
30552
30621
|
if (!stream2.src) return null;
|
|
30553
30622
|
const resolvedSrc = resolveImageSrc(stream2.src);
|
|
30554
|
-
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
30555
|
-
|
|
30556
|
-
|
|
30557
|
-
|
|
30558
|
-
|
|
30559
|
-
|
|
30560
|
-
|
|
30561
|
-
|
|
30562
|
-
|
|
30563
|
-
|
|
30564
|
-
|
|
30565
|
-
|
|
30566
|
-
|
|
30567
|
-
|
|
30568
|
-
|
|
30569
|
-
|
|
30570
|
-
|
|
30571
|
-
|
|
30572
|
-
onDragStart: (e) => {
|
|
30573
|
-
e.stopPropagation();
|
|
30574
|
-
return false;
|
|
30575
|
-
}
|
|
30623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
30624
|
+
Sequence,
|
|
30625
|
+
{
|
|
30626
|
+
durationInFrames: Math.max(1, Math.floor(fps * (end - start))),
|
|
30627
|
+
from: Math.floor(fps * start),
|
|
30628
|
+
layout: "none",
|
|
30629
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(FrameSyncStyle, { style: cssJS(stream2.style), children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
30630
|
+
Img,
|
|
30631
|
+
{
|
|
30632
|
+
src: resolvedSrc,
|
|
30633
|
+
style: {
|
|
30634
|
+
width: "100%",
|
|
30635
|
+
height: "100%",
|
|
30636
|
+
objectFit: stream2.fit
|
|
30637
|
+
},
|
|
30638
|
+
onDragStart: (e) => {
|
|
30639
|
+
e.stopPropagation();
|
|
30640
|
+
return false;
|
|
30576
30641
|
}
|
|
30577
|
-
|
|
30578
|
-
}
|
|
30579
|
-
|
|
30580
|
-
|
|
30581
|
-
}) });
|
|
30642
|
+
}
|
|
30643
|
+
) })
|
|
30644
|
+
}
|
|
30645
|
+
);
|
|
30582
30646
|
}
|
|
30583
30647
|
|
|
30584
30648
|
// src/types/Component.tsx
|
|
30585
|
-
var
|
|
30649
|
+
var React30 = __toESM(require_react(), 1);
|
|
30586
30650
|
|
|
30587
30651
|
// node_modules/react-jsx-parser/dist/react-jsx-parser.min.js
|
|
30588
30652
|
var import_react125 = __toESM(require_react());
|
|
@@ -41616,11 +41680,11 @@ var JsxParser = class extends import_react125.default.Component {
|
|
|
41616
41680
|
constructor() {
|
|
41617
41681
|
super(...arguments);
|
|
41618
41682
|
__publicField(this, "ParsedChildren", null);
|
|
41619
|
-
__privateAdd(this, _parseJSX, (
|
|
41683
|
+
__privateAdd(this, _parseJSX, (jsx76) => {
|
|
41620
41684
|
const parser = Parser.extend(AcornJSX.default({
|
|
41621
41685
|
autoCloseVoidElements: this.props.autoCloseVoidElements
|
|
41622
41686
|
}));
|
|
41623
|
-
const wrappedJsx = `<root>${
|
|
41687
|
+
const wrappedJsx = `<root>${jsx76}</root>`;
|
|
41624
41688
|
let parsed = [];
|
|
41625
41689
|
try {
|
|
41626
41690
|
parsed = parser.parse(wrappedJsx, { ecmaVersion: "latest" });
|
|
@@ -41918,8 +41982,8 @@ var JsxParser = class extends import_react125.default.Component {
|
|
|
41918
41982
|
});
|
|
41919
41983
|
}
|
|
41920
41984
|
render() {
|
|
41921
|
-
const
|
|
41922
|
-
this.ParsedChildren = __privateGet(this, _parseJSX).call(this,
|
|
41985
|
+
const jsx76 = (this.props.jsx || "").trim().replace(/<!DOCTYPE([^>]*)>/g, "");
|
|
41986
|
+
this.ParsedChildren = __privateGet(this, _parseJSX).call(this, jsx76);
|
|
41923
41987
|
const className2 = [.../* @__PURE__ */ new Set(["jsx-parser", ...String(this.props.className).split(" ")])].filter(Boolean).join(" ");
|
|
41924
41988
|
return this.props.renderInWrapper ? /* @__PURE__ */ import_react125.default.createElement("div", {
|
|
41925
41989
|
className: className2
|
|
@@ -41955,7 +42019,7 @@ __publicField(JsxParser, "defaultProps", {
|
|
|
41955
42019
|
var source_default = JsxParser;
|
|
41956
42020
|
|
|
41957
42021
|
// src/utils/tween.ts
|
|
41958
|
-
var
|
|
42022
|
+
var React27 = __toESM(require_react(), 1);
|
|
41959
42023
|
var EASING_MAP = {
|
|
41960
42024
|
linear: void 0,
|
|
41961
42025
|
ease: Easing.ease,
|
|
@@ -41976,16 +42040,16 @@ function hexToNumber(hex3) {
|
|
|
41976
42040
|
function lerp(a2, b3, t) {
|
|
41977
42041
|
return a2 + (b3 - a2) * t;
|
|
41978
42042
|
}
|
|
41979
|
-
function useTweenBindings(
|
|
42043
|
+
function useTweenBindings(action) {
|
|
41980
42044
|
const frame = useCurrentFrame();
|
|
41981
|
-
const actionDurationFrames = Math.max(1, Math.floor(((
|
|
41982
|
-
const cacheRef =
|
|
41983
|
-
const prevFrameRef =
|
|
42045
|
+
const actionDurationFrames = Math.max(1, Math.floor(((action.end ?? 1) - (action.start ?? 0)) * 30));
|
|
42046
|
+
const cacheRef = React27.useRef(/* @__PURE__ */ new Map());
|
|
42047
|
+
const prevFrameRef = React27.useRef(frame);
|
|
41984
42048
|
if (prevFrameRef.current !== frame) {
|
|
41985
42049
|
cacheRef.current = /* @__PURE__ */ new Map();
|
|
41986
42050
|
prevFrameRef.current = frame;
|
|
41987
42051
|
}
|
|
41988
|
-
const tween =
|
|
42052
|
+
const tween = React27.useCallback(
|
|
41989
42053
|
(from, to, easing) => {
|
|
41990
42054
|
const key = `${from},${to},${easing || "linear"}`;
|
|
41991
42055
|
const cached2 = cacheRef.current.get(key);
|
|
@@ -42027,18 +42091,18 @@ function useTweenBindings(action2) {
|
|
|
42027
42091
|
// src/types/Component.tsx
|
|
42028
42092
|
var import_jsx_runtime81 = __toESM(require_jsx_runtime(), 1);
|
|
42029
42093
|
function TweenedJsxParser({
|
|
42030
|
-
jsx:
|
|
42094
|
+
jsx: jsx76,
|
|
42031
42095
|
components,
|
|
42032
42096
|
data: data2,
|
|
42033
|
-
action
|
|
42097
|
+
action
|
|
42034
42098
|
}) {
|
|
42035
|
-
const tweenBindings = useTweenBindings(
|
|
42099
|
+
const tweenBindings = useTweenBindings(action);
|
|
42036
42100
|
return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_jsx_runtime81.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
42037
42101
|
source_default,
|
|
42038
42102
|
{
|
|
42039
42103
|
components,
|
|
42040
|
-
bindings:
|
|
42041
|
-
jsx:
|
|
42104
|
+
bindings: React30.useMemo(() => ({ ...data2, ...tweenBindings }), [data2, tweenBindings]),
|
|
42105
|
+
jsx: jsx76,
|
|
42042
42106
|
renderInWrapper: false,
|
|
42043
42107
|
blacklistedAttrs: [],
|
|
42044
42108
|
disableKeyGeneration: true,
|
|
@@ -42048,10 +42112,10 @@ function TweenedJsxParser({
|
|
|
42048
42112
|
}
|
|
42049
42113
|
function ComponentLeaf({ stream: stream2 }) {
|
|
42050
42114
|
const { fps } = useVideoConfig();
|
|
42051
|
-
const { components } =
|
|
42115
|
+
const { components } = React30.useContext(ComposeContext);
|
|
42052
42116
|
const eventCtx = useEventContext();
|
|
42053
|
-
const [eventState, setEventState] =
|
|
42054
|
-
|
|
42117
|
+
const [eventState, setEventState] = React30.useState({});
|
|
42118
|
+
React30.useLayoutEffect(() => {
|
|
42055
42119
|
if (stream2.id) {
|
|
42056
42120
|
eventCtx.register(
|
|
42057
42121
|
stream2.id,
|
|
@@ -42060,42 +42124,39 @@ function ComponentLeaf({ stream: stream2 }) {
|
|
|
42060
42124
|
return () => eventCtx.unregister(stream2.id);
|
|
42061
42125
|
}
|
|
42062
42126
|
}, [stream2.id, eventCtx]);
|
|
42063
|
-
const bindings =
|
|
42127
|
+
const bindings = React30.useMemo(
|
|
42064
42128
|
() => ({ ...components, ...stream2.data, ...eventState }),
|
|
42065
42129
|
[stream2.data, components, eventState]
|
|
42066
42130
|
);
|
|
42067
42131
|
if (!stream2.jsx) return null;
|
|
42068
|
-
|
|
42069
|
-
|
|
42070
|
-
|
|
42071
|
-
|
|
42072
|
-
|
|
42073
|
-
|
|
42074
|
-
|
|
42075
|
-
|
|
42076
|
-
|
|
42077
|
-
|
|
42078
|
-
|
|
42079
|
-
|
|
42080
|
-
|
|
42081
|
-
|
|
42082
|
-
|
|
42083
|
-
|
|
42084
|
-
|
|
42085
|
-
|
|
42086
|
-
|
|
42087
|
-
|
|
42088
|
-
|
|
42089
|
-
|
|
42090
|
-
a2.id
|
|
42091
|
-
);
|
|
42092
|
-
}) });
|
|
42132
|
+
const start = stream2.start ?? 0;
|
|
42133
|
+
const end = stream2.end ?? start + (stream2.duration ?? 1);
|
|
42134
|
+
const durFrames = Math.max(1, Math.floor(fps * (end - start)));
|
|
42135
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
42136
|
+
Sequence,
|
|
42137
|
+
{
|
|
42138
|
+
durationInFrames: durFrames,
|
|
42139
|
+
from: Math.floor(fps * start),
|
|
42140
|
+
layout: "none",
|
|
42141
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
42142
|
+
EventAwareComponent,
|
|
42143
|
+
{
|
|
42144
|
+
jsx: stream2.jsx,
|
|
42145
|
+
components,
|
|
42146
|
+
data: bindings,
|
|
42147
|
+
action: { start, end },
|
|
42148
|
+
durFrames,
|
|
42149
|
+
on: stream2.on
|
|
42150
|
+
}
|
|
42151
|
+
)
|
|
42152
|
+
}
|
|
42153
|
+
);
|
|
42093
42154
|
}
|
|
42094
42155
|
function EventAwareComponent({
|
|
42095
|
-
jsx:
|
|
42156
|
+
jsx: jsx76,
|
|
42096
42157
|
components,
|
|
42097
42158
|
data: data2,
|
|
42098
|
-
action
|
|
42159
|
+
action,
|
|
42099
42160
|
durFrames,
|
|
42100
42161
|
on
|
|
42101
42162
|
}) {
|
|
@@ -42103,10 +42164,10 @@ function EventAwareComponent({
|
|
|
42103
42164
|
return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
42104
42165
|
TweenedJsxParser,
|
|
42105
42166
|
{
|
|
42106
|
-
jsx:
|
|
42167
|
+
jsx: jsx76,
|
|
42107
42168
|
components,
|
|
42108
42169
|
data: data2,
|
|
42109
|
-
action
|
|
42170
|
+
action
|
|
42110
42171
|
}
|
|
42111
42172
|
);
|
|
42112
42173
|
}
|
|
@@ -42120,43 +42181,40 @@ function resolveAudioSrc2(src) {
|
|
|
42120
42181
|
function RhythmLeaf({ stream: stream2 }) {
|
|
42121
42182
|
const { fps } = useVideoConfig();
|
|
42122
42183
|
const environment = useRemotionEnvironment();
|
|
42123
|
-
const
|
|
42184
|
+
const start = stream2.start ?? 0;
|
|
42185
|
+
const end = stream2.end ?? start + (stream2.duration ?? 1);
|
|
42186
|
+
const totalDur = stream2.durationInSeconds ?? end;
|
|
42124
42187
|
useFrameEvents(stream2.on, Math.max(1, Math.floor(totalDur * fps)));
|
|
42125
42188
|
if (!stream2.src || environment.isStudio) return null;
|
|
42126
42189
|
const resolvedSrc = resolveAudioSrc2(stream2.src);
|
|
42127
|
-
|
|
42128
|
-
|
|
42129
|
-
|
|
42130
|
-
|
|
42131
|
-
|
|
42132
|
-
|
|
42133
|
-
|
|
42134
|
-
|
|
42135
|
-
|
|
42136
|
-
|
|
42137
|
-
|
|
42138
|
-
|
|
42139
|
-
|
|
42140
|
-
|
|
42141
|
-
|
|
42142
|
-
|
|
42143
|
-
|
|
42144
|
-
|
|
42145
|
-
|
|
42146
|
-
|
|
42147
|
-
|
|
42148
|
-
)
|
|
42149
|
-
},
|
|
42150
|
-
a2.id
|
|
42151
|
-
);
|
|
42152
|
-
}) });
|
|
42190
|
+
const volume = stream2.volume ?? 1;
|
|
42191
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
42192
|
+
Sequence,
|
|
42193
|
+
{
|
|
42194
|
+
name: stream2.src ?? "rhythm",
|
|
42195
|
+
durationInFrames: Math.max(1, Math.floor(fps * (end - start))),
|
|
42196
|
+
from: Math.floor(fps * start),
|
|
42197
|
+
layout: "none",
|
|
42198
|
+
showInTimeline: false,
|
|
42199
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
42200
|
+
Audio,
|
|
42201
|
+
{
|
|
42202
|
+
src: resolvedSrc,
|
|
42203
|
+
muted: volume === 0,
|
|
42204
|
+
volume,
|
|
42205
|
+
loop: true,
|
|
42206
|
+
showInTimeline: false
|
|
42207
|
+
}
|
|
42208
|
+
)
|
|
42209
|
+
}
|
|
42210
|
+
);
|
|
42153
42211
|
}
|
|
42154
42212
|
|
|
42155
42213
|
// src/types/Map.tsx
|
|
42156
42214
|
var import_react127 = __toESM(require_react(), 1);
|
|
42157
42215
|
|
|
42158
42216
|
// node_modules/@vis.gl/react-google-maps/dist/index.modern.mjs
|
|
42159
|
-
var
|
|
42217
|
+
var React35 = __toESM(require_react(), 1);
|
|
42160
42218
|
var import_react126 = __toESM(require_react(), 1);
|
|
42161
42219
|
var import_react_dom3 = __toESM(require_react_dom(), 1);
|
|
42162
42220
|
var import_fast_deep_equal = __toESM(require_fast_deep_equal(), 1);
|
|
@@ -42343,8 +42401,8 @@ function useMap3DInstances() {
|
|
|
42343
42401
|
function useGoogleMapsApiLoader(props) {
|
|
42344
42402
|
const { onLoad, onError, apiKey, version: version4, libraries = [], region, language, authReferrerPolicy, channel, solutionChannel, fetchAppCheckToken } = props;
|
|
42345
42403
|
const [status, setStatus] = (0, import_react126.useState)(loadingStatus);
|
|
42346
|
-
const [loadedLibraries, addLoadedLibrary] = (0, import_react126.useReducer)((loadedLibraries2,
|
|
42347
|
-
return loadedLibraries2[
|
|
42404
|
+
const [loadedLibraries, addLoadedLibrary] = (0, import_react126.useReducer)((loadedLibraries2, action) => {
|
|
42405
|
+
return loadedLibraries2[action.name] ? loadedLibraries2 : Object.assign(Object.assign({}, loadedLibraries2), { [action.name]: action.value });
|
|
42348
42406
|
}, {});
|
|
42349
42407
|
const currentSerializedParams = (0, import_react126.useMemo)(() => {
|
|
42350
42408
|
const params = {
|
|
@@ -43100,8 +43158,8 @@ function useMapsLibrary(name) {
|
|
|
43100
43158
|
return (ctx === null || ctx === void 0 ? void 0 : ctx.loadedLibraries[name]) || null;
|
|
43101
43159
|
}
|
|
43102
43160
|
var _a;
|
|
43103
|
-
var { useLayoutEffect: useLayoutEffect16, useRef: useRef31 } =
|
|
43104
|
-
var useBeforeEffect = (_a =
|
|
43161
|
+
var { useLayoutEffect: useLayoutEffect16, useRef: useRef31 } = React35;
|
|
43162
|
+
var useBeforeEffect = (_a = React35.useInsertionEffect) !== null && _a !== void 0 ? _a : useLayoutEffect16;
|
|
43105
43163
|
function forbiddenInRender() {
|
|
43106
43164
|
throw new Error("useEffectEvent: invalid call during rendering.");
|
|
43107
43165
|
}
|
|
@@ -44476,55 +44534,59 @@ Rectangle.displayName = "Rectangle";
|
|
|
44476
44534
|
|
|
44477
44535
|
// src/types/Map.tsx
|
|
44478
44536
|
var import_jsx_runtime83 = __toESM(require_jsx_runtime(), 1);
|
|
44479
|
-
|
|
44537
|
+
function resolveApiKey(stream2) {
|
|
44538
|
+
if (stream2.googleMapsApiKey) return stream2.googleMapsApiKey;
|
|
44539
|
+
if (typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.GOOGLE_MAPS_API_KEY) {
|
|
44540
|
+
return process.env.GOOGLE_MAPS_API_KEY;
|
|
44541
|
+
}
|
|
44542
|
+
return "";
|
|
44543
|
+
}
|
|
44480
44544
|
function MapLeaf({ stream: stream2 }) {
|
|
44481
44545
|
const { fps } = useVideoConfig();
|
|
44482
44546
|
const waypoints = stream2.waypoints ?? [];
|
|
44483
|
-
const
|
|
44547
|
+
const start = stream2.start ?? 0;
|
|
44548
|
+
const end = stream2.end ?? start + (stream2.duration ?? 1);
|
|
44549
|
+
const totalDur = stream2.durationInSeconds ?? end;
|
|
44550
|
+
const apiKey = resolveApiKey(stream2);
|
|
44484
44551
|
useFrameEvents(stream2.on, Math.max(1, Math.floor(totalDur * fps)));
|
|
44485
44552
|
if (waypoints.length === 0) return null;
|
|
44486
|
-
|
|
44487
|
-
|
|
44488
|
-
|
|
44489
|
-
|
|
44490
|
-
|
|
44491
|
-
|
|
44492
|
-
|
|
44493
|
-
|
|
44494
|
-
|
|
44495
|
-
|
|
44496
|
-
|
|
44497
|
-
|
|
44498
|
-
|
|
44499
|
-
|
|
44500
|
-
|
|
44501
|
-
|
|
44502
|
-
|
|
44503
|
-
|
|
44504
|
-
|
|
44505
|
-
|
|
44506
|
-
|
|
44507
|
-
|
|
44508
|
-
|
|
44509
|
-
|
|
44510
|
-
|
|
44511
|
-
|
|
44512
|
-
|
|
44513
|
-
|
|
44514
|
-
|
|
44515
|
-
|
|
44516
|
-
|
|
44517
|
-
|
|
44518
|
-
|
|
44519
|
-
|
|
44520
|
-
|
|
44521
|
-
|
|
44522
|
-
|
|
44523
|
-
) })
|
|
44524
|
-
},
|
|
44525
|
-
a2.id ?? i3
|
|
44526
|
-
);
|
|
44527
|
-
}) });
|
|
44553
|
+
const durFrames = Math.max(1, Math.floor(fps * (end - start)));
|
|
44554
|
+
const center = stream2.center ?? { lat: waypoints[0].lat, lng: waypoints[0].lng };
|
|
44555
|
+
const zoom = stream2.zoom ?? 10;
|
|
44556
|
+
const mapType = stream2.mapType ?? "roadmap";
|
|
44557
|
+
const travelMode = stream2.travelMode ?? "DRIVING";
|
|
44558
|
+
const markerEmoji = stream2.routeMarker ?? "\u{1F697}";
|
|
44559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
44560
|
+
Sequence,
|
|
44561
|
+
{
|
|
44562
|
+
durationInFrames: durFrames,
|
|
44563
|
+
from: Math.floor(fps * start),
|
|
44564
|
+
layout: "none",
|
|
44565
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(APIProvider, { apiKey, children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
44566
|
+
Map2,
|
|
44567
|
+
{
|
|
44568
|
+
mapId: String(stream2.id ?? "map"),
|
|
44569
|
+
defaultCenter: center,
|
|
44570
|
+
defaultZoom: zoom,
|
|
44571
|
+
defaultOptions: {
|
|
44572
|
+
mapTypeId: mapType,
|
|
44573
|
+
disableDefaultUI: true,
|
|
44574
|
+
zoomControl: false
|
|
44575
|
+
},
|
|
44576
|
+
style: { width: "100%", height: "100%", position: "absolute" },
|
|
44577
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
44578
|
+
RouteWithMarker,
|
|
44579
|
+
{
|
|
44580
|
+
waypoints,
|
|
44581
|
+
travelMode,
|
|
44582
|
+
markerEmoji,
|
|
44583
|
+
actionDuration: end - start
|
|
44584
|
+
}
|
|
44585
|
+
)
|
|
44586
|
+
}
|
|
44587
|
+
) })
|
|
44588
|
+
}
|
|
44589
|
+
);
|
|
44528
44590
|
}
|
|
44529
44591
|
function RouteWithMarker({
|
|
44530
44592
|
waypoints,
|
|
@@ -44647,7 +44709,7 @@ function getCurrentStep(leg, currentInSecond) {
|
|
|
44647
44709
|
}
|
|
44648
44710
|
|
|
44649
44711
|
// src/types/Include.tsx
|
|
44650
|
-
var
|
|
44712
|
+
var React41 = __toESM(require_react(), 1);
|
|
44651
44713
|
var import_jsx_runtime84 = __toESM(require_jsx_runtime(), 1);
|
|
44652
44714
|
var ASPECT_DIMS = {
|
|
44653
44715
|
"16x9": { width: 1920, height: 1080 },
|
|
@@ -44666,10 +44728,10 @@ function resolveIncludeSrc(src) {
|
|
|
44666
44728
|
return staticFile(src);
|
|
44667
44729
|
}
|
|
44668
44730
|
function useSubVideoRegistry(importsUrl) {
|
|
44669
|
-
const [registry2, setRegistry] =
|
|
44670
|
-
const [loaded, setLoaded] =
|
|
44671
|
-
const handleRef =
|
|
44672
|
-
|
|
44731
|
+
const [registry2, setRegistry] = React41.useState(null);
|
|
44732
|
+
const [loaded, setLoaded] = React41.useState(false);
|
|
44733
|
+
const handleRef = React41.useRef(null);
|
|
44734
|
+
React41.useEffect(() => {
|
|
44673
44735
|
if (!importsUrl) {
|
|
44674
44736
|
setRegistry(null);
|
|
44675
44737
|
setLoaded(true);
|
|
@@ -44701,18 +44763,21 @@ function useSubVideoRegistry(importsUrl) {
|
|
|
44701
44763
|
}
|
|
44702
44764
|
function IncludeLeaf({ stream: stream2 }) {
|
|
44703
44765
|
const { fps: parentFps, width: parentWidth, height: parentHeight } = useVideoConfig();
|
|
44704
|
-
const parentCompose =
|
|
44766
|
+
const parentCompose = React41.useContext(ComposeContext);
|
|
44705
44767
|
const { Container } = parentCompose;
|
|
44706
|
-
const parentAudio =
|
|
44707
|
-
const
|
|
44768
|
+
const parentAudio = React41.useContext(AudioContext2);
|
|
44769
|
+
const start = stream2.start ?? 0;
|
|
44770
|
+
const end = stream2.end ?? (stream2.durationInSeconds ?? start + (stream2.duration ?? 1));
|
|
44771
|
+
const totalDur = stream2.durationInSeconds ?? end;
|
|
44708
44772
|
useFrameEvents(stream2.on, Math.max(1, Math.floor(totalDur * parentFps)));
|
|
44709
|
-
|
|
44710
|
-
|
|
44711
|
-
const [
|
|
44712
|
-
const [
|
|
44773
|
+
const hasContent = !!stream2.src || (stream2.children?.length ?? 0) > 0;
|
|
44774
|
+
if (!hasContent) return null;
|
|
44775
|
+
const [externalData, setExternalData] = React41.useState(null);
|
|
44776
|
+
const [loadError, setLoadError] = React41.useState(null);
|
|
44777
|
+
const [handle] = React41.useState(
|
|
44713
44778
|
() => stream2.src ? delayRender(`Loading include: ${stream2.src}`) : null
|
|
44714
44779
|
);
|
|
44715
|
-
|
|
44780
|
+
React41.useEffect(() => {
|
|
44716
44781
|
if (!stream2.src || !handle) return;
|
|
44717
44782
|
let active = true;
|
|
44718
44783
|
const url2 = resolveIncludeSrc(stream2.src);
|
|
@@ -44736,18 +44801,18 @@ function IncludeLeaf({ stream: stream2 }) {
|
|
|
44736
44801
|
active = false;
|
|
44737
44802
|
};
|
|
44738
44803
|
}, [stream2.src, handle]);
|
|
44739
|
-
|
|
44804
|
+
React41.useMemo(() => {
|
|
44740
44805
|
if (!stream2.src) {
|
|
44741
44806
|
getDurationInSeconds(stream2, true);
|
|
44742
44807
|
}
|
|
44743
44808
|
}, [stream2, stream2.src]);
|
|
44744
|
-
const subImportsUrl =
|
|
44809
|
+
const subImportsUrl = React41.useMemo(() => {
|
|
44745
44810
|
if (!externalData) return void 0;
|
|
44746
44811
|
const root2 = externalData.root ?? externalData;
|
|
44747
44812
|
return root2?.imports;
|
|
44748
44813
|
}, [externalData]);
|
|
44749
44814
|
const { registry: subRegistry, loaded: subRegistryLoaded } = useSubVideoRegistry(subImportsUrl);
|
|
44750
|
-
const mergedCompose =
|
|
44815
|
+
const mergedCompose = React41.useMemo(() => {
|
|
44751
44816
|
const parentComponents = parentCompose.components;
|
|
44752
44817
|
if (!subRegistry) return parentCompose;
|
|
44753
44818
|
return {
|
|
@@ -44758,11 +44823,11 @@ function IncludeLeaf({ stream: stream2 }) {
|
|
|
44758
44823
|
}
|
|
44759
44824
|
};
|
|
44760
44825
|
}, [parentCompose, subRegistry]);
|
|
44761
|
-
const audioCtx =
|
|
44826
|
+
const audioCtx = React41.useMemo(
|
|
44762
44827
|
() => ({ id: stream2.id, foreground: true, parent: parentAudio }),
|
|
44763
44828
|
[stream2.id, parentAudio]
|
|
44764
44829
|
);
|
|
44765
|
-
const renderExternalContent =
|
|
44830
|
+
const renderExternalContent = React41.useCallback(() => {
|
|
44766
44831
|
if (!externalData) return null;
|
|
44767
44832
|
if (loadError) {
|
|
44768
44833
|
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { style: { color: "#ff4444", fontSize: 24, padding: 40 }, children: [
|
|
@@ -44779,12 +44844,12 @@ function IncludeLeaf({ stream: stream2 }) {
|
|
|
44779
44844
|
vj.bgm && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(Audio, { src: vj.bgm.src, volume: vj.bgm.baseVolume }),
|
|
44780
44845
|
vj.scenes.map((scene2) => {
|
|
44781
44846
|
const startFrame = Math.round((scene2.start ?? 0) * vjFps);
|
|
44782
|
-
const
|
|
44847
|
+
const durFrames2 = Math.round((scene2.duration ?? 1) * vjFps);
|
|
44783
44848
|
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
44784
44849
|
Sequence,
|
|
44785
44850
|
{
|
|
44786
44851
|
from: startFrame,
|
|
44787
|
-
durationInFrames:
|
|
44852
|
+
durationInFrames: durFrames2,
|
|
44788
44853
|
name: `${scene2.id}:${scene2.component}`,
|
|
44789
44854
|
children: [
|
|
44790
44855
|
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
@@ -44855,82 +44920,72 @@ function IncludeLeaf({ stream: stream2 }) {
|
|
|
44855
44920
|
}
|
|
44856
44921
|
);
|
|
44857
44922
|
}, [externalData, loadError, parentFps, parentWidth, parentHeight]);
|
|
44858
|
-
const
|
|
44859
|
-
|
|
44860
|
-
|
|
44861
|
-
|
|
44862
|
-
|
|
44863
|
-
|
|
44864
|
-
|
|
44865
|
-
|
|
44866
|
-
|
|
44867
|
-
|
|
44868
|
-
|
|
44869
|
-
|
|
44870
|
-
|
|
44871
|
-
|
|
44872
|
-
|
|
44873
|
-
{
|
|
44874
|
-
id: stream2.id,
|
|
44875
|
-
type: "include",
|
|
44876
|
-
style: {
|
|
44877
|
-
...cssJS(stream2.style),
|
|
44878
|
-
width: parentWidth,
|
|
44879
|
-
height: parentHeight,
|
|
44880
|
-
overflow: "hidden",
|
|
44881
|
-
position: "relative"
|
|
44882
|
-
},
|
|
44883
|
-
className: `include ${toClassName(stream2.id ?? "")}`,
|
|
44884
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(FolderLeaf, { stream: stream2 })
|
|
44885
|
-
}
|
|
44886
|
-
)
|
|
44923
|
+
const dur = Math.max(0.1, end - start);
|
|
44924
|
+
const durFrames = Math.max(1, Math.floor(parentFps * dur));
|
|
44925
|
+
let innerNode;
|
|
44926
|
+
if (!stream2.src && stream2.children?.length) {
|
|
44927
|
+
innerNode = /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
44928
|
+
Container,
|
|
44929
|
+
{
|
|
44930
|
+
id: stream2.id,
|
|
44931
|
+
type: "include",
|
|
44932
|
+
style: {
|
|
44933
|
+
...cssJS(stream2.style),
|
|
44934
|
+
width: parentWidth,
|
|
44935
|
+
height: parentHeight,
|
|
44936
|
+
overflow: "hidden",
|
|
44937
|
+
position: "relative"
|
|
44887
44938
|
},
|
|
44888
|
-
|
|
44889
|
-
|
|
44890
|
-
|
|
44891
|
-
|
|
44892
|
-
|
|
44939
|
+
className: `include ${toClassName(stream2.id ?? "")}`,
|
|
44940
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(FolderLeaf, { stream: stream2 })
|
|
44941
|
+
}
|
|
44942
|
+
);
|
|
44943
|
+
} else if (externalData || loadError) {
|
|
44944
|
+
innerNode = /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
44945
|
+
"div",
|
|
44893
44946
|
{
|
|
44894
|
-
|
|
44895
|
-
|
|
44896
|
-
|
|
44897
|
-
|
|
44898
|
-
|
|
44899
|
-
|
|
44900
|
-
|
|
44901
|
-
|
|
44902
|
-
width: parentWidth,
|
|
44903
|
-
height: parentHeight,
|
|
44904
|
-
overflow: "hidden",
|
|
44905
|
-
position: "relative"
|
|
44906
|
-
},
|
|
44907
|
-
children: renderExternalContent()
|
|
44908
|
-
}
|
|
44909
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
44910
|
-
"div",
|
|
44911
|
-
{
|
|
44912
|
-
style: {
|
|
44913
|
-
width: parentWidth,
|
|
44914
|
-
height: parentHeight,
|
|
44915
|
-
display: "flex",
|
|
44916
|
-
alignItems: "center",
|
|
44917
|
-
justifyContent: "center",
|
|
44918
|
-
color: "#666",
|
|
44919
|
-
fontSize: 20,
|
|
44920
|
-
fontFamily: "monospace"
|
|
44921
|
-
},
|
|
44922
|
-
children: [
|
|
44923
|
-
"Loading\u2026 ",
|
|
44924
|
-
stream2.src
|
|
44925
|
-
]
|
|
44926
|
-
}
|
|
44927
|
-
)
|
|
44928
|
-
},
|
|
44929
|
-
a2.id
|
|
44947
|
+
style: {
|
|
44948
|
+
width: parentWidth,
|
|
44949
|
+
height: parentHeight,
|
|
44950
|
+
overflow: "hidden",
|
|
44951
|
+
position: "relative"
|
|
44952
|
+
},
|
|
44953
|
+
children: renderExternalContent()
|
|
44954
|
+
}
|
|
44930
44955
|
);
|
|
44931
|
-
}
|
|
44956
|
+
} else {
|
|
44957
|
+
innerNode = /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
44958
|
+
"div",
|
|
44959
|
+
{
|
|
44960
|
+
style: {
|
|
44961
|
+
width: parentWidth,
|
|
44962
|
+
height: parentHeight,
|
|
44963
|
+
display: "flex",
|
|
44964
|
+
alignItems: "center",
|
|
44965
|
+
justifyContent: "center",
|
|
44966
|
+
color: "#666",
|
|
44967
|
+
fontSize: 20,
|
|
44968
|
+
fontFamily: "monospace"
|
|
44969
|
+
},
|
|
44970
|
+
children: [
|
|
44971
|
+
"Loading\u2026 ",
|
|
44972
|
+
stream2.src
|
|
44973
|
+
]
|
|
44974
|
+
}
|
|
44975
|
+
);
|
|
44976
|
+
}
|
|
44977
|
+
const sequence = /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
44978
|
+
Sequence,
|
|
44979
|
+
{
|
|
44980
|
+
durationInFrames: durFrames,
|
|
44981
|
+
from: Math.floor(parentFps * start),
|
|
44982
|
+
layout: "none",
|
|
44983
|
+
showInTimeline: false,
|
|
44984
|
+
children: innerNode
|
|
44985
|
+
}
|
|
44986
|
+
);
|
|
44932
44987
|
const needsNestedContext = subRegistry !== null && subRegistry !== parentCompose.components;
|
|
44933
|
-
const inner2 = /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(AudioContext2.Provider, { value: audioCtx, children:
|
|
44988
|
+
const inner2 = /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(AudioContext2.Provider, { value: audioCtx, children: sequence });
|
|
44934
44989
|
if (needsNestedContext && subRegistryLoaded) {
|
|
44935
44990
|
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(ComposeContext.Provider, { value: mergedCompose, children: inner2 });
|
|
44936
44991
|
}
|
|
@@ -44938,14 +44993,14 @@ function IncludeLeaf({ stream: stream2 }) {
|
|
|
44938
44993
|
}
|
|
44939
44994
|
|
|
44940
44995
|
// src/types/Scene.tsx
|
|
44941
|
-
var
|
|
44996
|
+
var React43 = __toESM(require_react(), 1);
|
|
44942
44997
|
var import_jsx_runtime85 = __toESM(require_jsx_runtime(), 1);
|
|
44943
44998
|
function SceneLeaf({ stream: stream2 }) {
|
|
44944
|
-
const { Container } =
|
|
44945
|
-
const parentAudio =
|
|
44999
|
+
const { Container } = React43.useContext(ComposeContext);
|
|
45000
|
+
const parentAudio = React43.useContext(AudioContext2);
|
|
44946
45001
|
const totalDur = stream2.durationInSeconds ?? 1;
|
|
44947
45002
|
useFrameEvents(stream2.on, Math.max(1, Math.floor(totalDur * 30)));
|
|
44948
|
-
const audioCtx =
|
|
45003
|
+
const audioCtx = React43.useMemo(
|
|
44949
45004
|
() => ({ id: stream2.id, parent: parentAudio }),
|
|
44950
45005
|
[stream2.id, parentAudio]
|
|
44951
45006
|
);
|
|
@@ -44962,7 +45017,7 @@ function SceneLeaf({ stream: stream2 }) {
|
|
|
44962
45017
|
}
|
|
44963
45018
|
|
|
44964
45019
|
// src/types/Effect.tsx
|
|
44965
|
-
var
|
|
45020
|
+
var React44 = __toESM(require_react(), 1);
|
|
44966
45021
|
|
|
44967
45022
|
// src/types/keyframes.ts
|
|
44968
45023
|
function parseKeyframeData(data2) {
|
|
@@ -45355,47 +45410,42 @@ function EffectWrapper({
|
|
|
45355
45410
|
}) {
|
|
45356
45411
|
const frame = useCurrentFrame();
|
|
45357
45412
|
const { fps, width, height } = useVideoConfig();
|
|
45358
|
-
const
|
|
45413
|
+
const startSec = stream2.start ?? 0;
|
|
45414
|
+
const endSec = stream2.end ?? startSec + (stream2.duration ?? 1);
|
|
45415
|
+
const totalDur = stream2.durationInSeconds ?? endSec;
|
|
45359
45416
|
useFrameEvents(stream2.on, Math.max(1, Math.floor(totalDur * fps)));
|
|
45360
|
-
const
|
|
45361
|
-
|
|
45362
|
-
const
|
|
45363
|
-
|
|
45364
|
-
|
|
45365
|
-
|
|
45366
|
-
|
|
45367
|
-
|
|
45368
|
-
|
|
45369
|
-
|
|
45370
|
-
|
|
45371
|
-
const
|
|
45372
|
-
|
|
45373
|
-
|
|
45374
|
-
|
|
45375
|
-
|
|
45376
|
-
|
|
45377
|
-
|
|
45378
|
-
|
|
45379
|
-
|
|
45380
|
-
|
|
45381
|
-
|
|
45382
|
-
|
|
45383
|
-
|
|
45384
|
-
|
|
45385
|
-
|
|
45386
|
-
|
|
45387
|
-
timingFunction: timingFn
|
|
45388
|
-
});
|
|
45389
|
-
if (animStyle) Object.assign(style2, animStyle);
|
|
45390
|
-
}
|
|
45391
|
-
}
|
|
45392
|
-
if (Object.keys(style2).length > 0) {
|
|
45393
|
-
result.push(style2);
|
|
45417
|
+
const styles = React44.useMemo(() => {
|
|
45418
|
+
const start = Math.ceil(startSec * fps);
|
|
45419
|
+
const end = Math.ceil(endSec * fps);
|
|
45420
|
+
const durationInFrames = end - start;
|
|
45421
|
+
if (durationInFrames <= 0) return [];
|
|
45422
|
+
const animation = stream2.animation;
|
|
45423
|
+
const timingFn = stream2.animationTimingFunction;
|
|
45424
|
+
const iterCount = stream2.animationIterationCount ?? 1;
|
|
45425
|
+
const style2 = cssJS(stream2.style) ?? {};
|
|
45426
|
+
let currentFrame = frame;
|
|
45427
|
+
if (iterCount > 0 && durationInFrames > 0) {
|
|
45428
|
+
const iteration = Math.floor((frame - start) / durationInFrames);
|
|
45429
|
+
if (iteration < iterCount) {
|
|
45430
|
+
currentFrame = start + (frame - start) % durationInFrames;
|
|
45431
|
+
}
|
|
45432
|
+
}
|
|
45433
|
+
if (currentFrame >= start && currentFrame < end) {
|
|
45434
|
+
const actionFrame = currentFrame - start;
|
|
45435
|
+
if (animation) {
|
|
45436
|
+
const config2 = resolveAnimation(animation, stream2.customKeyframes);
|
|
45437
|
+
if (config2) {
|
|
45438
|
+
const animStyle = interpolateKeyframes(config2, actionFrame, {
|
|
45439
|
+
fps,
|
|
45440
|
+
durationInSeconds: durationInFrames / fps,
|
|
45441
|
+
timingFunction: timingFn
|
|
45442
|
+
});
|
|
45443
|
+
if (animStyle) Object.assign(style2, animStyle);
|
|
45394
45444
|
}
|
|
45395
45445
|
}
|
|
45396
45446
|
}
|
|
45397
|
-
return
|
|
45398
|
-
}, [frame, fps,
|
|
45447
|
+
return Object.keys(style2).length > 0 ? [style2] : [];
|
|
45448
|
+
}, [frame, fps, startSec, endSec, stream2.animation, stream2.animationTimingFunction, stream2.animationIterationCount, stream2.customKeyframes, stream2.style]);
|
|
45399
45449
|
if (styles.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(import_jsx_runtime86.Fragment, { children });
|
|
45400
45450
|
return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
45401
45451
|
"div",
|
|
@@ -45430,8 +45480,8 @@ var NotSeries = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
|
45430
45480
|
NotSeries.Sequence = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(import_jsx_runtime87.Fragment, { children });
|
|
45431
45481
|
function FolderLeaf({ stream: stream2 }) {
|
|
45432
45482
|
const { fps, width, height } = useVideoConfig();
|
|
45433
|
-
const { Container } =
|
|
45434
|
-
const parentAudio =
|
|
45483
|
+
const { Container } = React45.useContext(ComposeContext);
|
|
45484
|
+
const parentAudio = React45.useContext(AudioContext2);
|
|
45435
45485
|
const totalDur = stream2.durationInSeconds ?? 1;
|
|
45436
45486
|
useFrameEvents(stream2.on, Math.max(1, Math.floor(totalDur * fps)));
|
|
45437
45487
|
const isSeries = !!stream2.isSeries;
|
|
@@ -45443,11 +45493,11 @@ function FolderLeaf({ stream: stream2 }) {
|
|
|
45443
45493
|
const seriesChildren = isSeries ? visibleChildren.filter((c3) => !c3.isBackground) : visibleChildren;
|
|
45444
45494
|
const allAudio = seriesChildren.length > 0 && seriesChildren.every((c3) => c3.type === "audio");
|
|
45445
45495
|
const effectiveTransition = allAudio ? void 0 : transition;
|
|
45446
|
-
const TypedSeries =
|
|
45496
|
+
const TypedSeries = React45.useMemo(() => {
|
|
45447
45497
|
if (!isSeries) return NotSeries;
|
|
45448
45498
|
return effectiveTransition ? TransitionSeries : Series;
|
|
45449
45499
|
}, [isSeries, effectiveTransition]);
|
|
45450
|
-
const transEl =
|
|
45500
|
+
const transEl = React45.useMemo(() => {
|
|
45451
45501
|
if (!isSeries || !effectiveTransition) return null;
|
|
45452
45502
|
const presentation = TransitionPresets[transition]?.(
|
|
45453
45503
|
transition === "clockWipe" ? { width, height } : void 0
|
|
@@ -45465,7 +45515,7 @@ function FolderLeaf({ stream: stream2 }) {
|
|
|
45465
45515
|
const durFrames = Math.max(1, Math.floor(dur * fps));
|
|
45466
45516
|
const SequenceWrap = TypedSeries.Sequence ?? Sequence;
|
|
45467
45517
|
const isLeaf = child.type !== "folder" && child.type !== "root" && child.type !== "effect";
|
|
45468
|
-
const childContent = isLeaf ?
|
|
45518
|
+
const childContent = isLeaf ? React45.createElement(Leaves[child.type] ?? (() => null), { stream: child }) : child.type === "effect" ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(EffectWrapper, { stream: child, children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(FolderLeaf, { stream: child }) }) : React45.createElement(FolderLeaf, { stream: child });
|
|
45469
45519
|
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(SequenceWrap, { durationInFrames: durFrames, layout: "none", children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
45470
45520
|
Container,
|
|
45471
45521
|
{
|
|
@@ -45481,7 +45531,7 @@ function FolderLeaf({ stream: stream2 }) {
|
|
|
45481
45531
|
const dur = child.durationInSeconds ?? 0;
|
|
45482
45532
|
const durFrames = Math.max(1, Math.floor(dur * fps));
|
|
45483
45533
|
const isLeaf = child.type !== "folder" && child.type !== "root" && child.type !== "effect";
|
|
45484
|
-
const childContent = isLeaf ?
|
|
45534
|
+
const childContent = isLeaf ? React45.createElement(Leaves[child.type] ?? (() => null), { stream: child }) : child.type === "effect" ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(EffectWrapper, { stream: child, children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(FolderLeaf, { stream: child }) }) : React45.createElement(FolderLeaf, { stream: child });
|
|
45485
45535
|
const wrapped = /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
45486
45536
|
Container,
|
|
45487
45537
|
{
|
|
@@ -45497,10 +45547,10 @@ function FolderLeaf({ stream: stream2 }) {
|
|
|
45497
45547
|
}) });
|
|
45498
45548
|
if (isSeries && transEl) {
|
|
45499
45549
|
for (let i3 = 1; i3 < sequences.length; i3 += 2) {
|
|
45500
|
-
sequences.splice(i3, 0,
|
|
45550
|
+
sequences.splice(i3, 0, React45.cloneElement(transEl, { key: `t${i3}` }));
|
|
45501
45551
|
}
|
|
45502
45552
|
}
|
|
45503
|
-
const audioCtx =
|
|
45553
|
+
const audioCtx = React45.useMemo(
|
|
45504
45554
|
() => stream2.type !== "folder" ? { id: stream2.id, parent: parentAudio } : parentAudio,
|
|
45505
45555
|
[stream2.id, stream2.type, parentAudio]
|
|
45506
45556
|
);
|
|
@@ -45523,7 +45573,7 @@ function FolderLeaf({ stream: stream2 }) {
|
|
|
45523
45573
|
}
|
|
45524
45574
|
|
|
45525
45575
|
// src/types/Subtitle.tsx
|
|
45526
|
-
var
|
|
45576
|
+
var React46 = __toESM(require_react(), 1);
|
|
45527
45577
|
|
|
45528
45578
|
// node_modules/remotion-subtitle/dist/index.esm.js
|
|
45529
45579
|
var index_esm_exports = {};
|
|
@@ -45849,8 +45899,8 @@ function CueFrame({
|
|
|
45849
45899
|
}) {
|
|
45850
45900
|
const durationInFrames = Math.max(1, Math.floor((cue.endAt - cue.startFrom) * fps));
|
|
45851
45901
|
const from = Math.floor(cue.startFrom * fps);
|
|
45852
|
-
const captionText =
|
|
45853
|
-
const textStyle =
|
|
45902
|
+
const captionText = React46.useMemo(() => supportHtml(cue.text), [cue.text]);
|
|
45903
|
+
const textStyle = React46.useMemo(
|
|
45854
45904
|
() => ({
|
|
45855
45905
|
...DEFAULT_TEXT_STYLE,
|
|
45856
45906
|
fontSize: subtitle.fontSize ?? DEFAULT_TEXT_STYLE.fontSize,
|
|
@@ -45863,12 +45913,12 @@ function CueFrame({
|
|
|
45863
45913
|
}
|
|
45864
45914
|
function SubtitleOverlay({ subtitle }) {
|
|
45865
45915
|
const { fps } = useVideoConfig();
|
|
45866
|
-
const [cues, setCues] =
|
|
45867
|
-
const CaptionComponent =
|
|
45916
|
+
const [cues, setCues] = React46.useState(null);
|
|
45917
|
+
const CaptionComponent = React46.useMemo(
|
|
45868
45918
|
() => resolveCaption(subtitle.type),
|
|
45869
45919
|
[subtitle.type]
|
|
45870
45920
|
);
|
|
45871
|
-
|
|
45921
|
+
React46.useEffect(() => {
|
|
45872
45922
|
const { src } = subtitle;
|
|
45873
45923
|
if (src.includes("-->")) {
|
|
45874
45924
|
setCues(parseVTT(src));
|
|
@@ -59686,17 +59736,6 @@ function date4(params) {
|
|
|
59686
59736
|
config(en_default());
|
|
59687
59737
|
|
|
59688
59738
|
// src/schema/index.ts
|
|
59689
|
-
var action = external_exports.object({
|
|
59690
|
-
id: external_exports.string().default(() => uid()),
|
|
59691
|
-
start: external_exports.number().min(0).default(0).describe("seconds, relative to parent"),
|
|
59692
|
-
end: external_exports.number().min(0).default(1).describe("seconds, relative to parent"),
|
|
59693
|
-
startFrom: external_exports.number().optional().describe("trim seconds from source start"),
|
|
59694
|
-
endAt: external_exports.number().optional().describe("trim seconds at source end"),
|
|
59695
|
-
loop: external_exports.number().int().min(1).optional().describe(">1 = loop count"),
|
|
59696
|
-
effectId: external_exports.string().optional(),
|
|
59697
|
-
style: external_exports.string().optional().describe("inline css"),
|
|
59698
|
-
volume: external_exports.number().min(0).max(1).optional()
|
|
59699
|
-
});
|
|
59700
59739
|
var eventSpec = external_exports.object({
|
|
59701
59740
|
when: external_exports.string().describe("'start' | 'end' | '50%' | '2.5s'"),
|
|
59702
59741
|
state: external_exports.string().describe("JS expression evaluated with registered components in scope")
|
|
@@ -59708,6 +59747,11 @@ var BaseShape = {
|
|
|
59708
59747
|
style: external_exports.string().optional().describe("inline css"),
|
|
59709
59748
|
visible: external_exports.boolean().default(true),
|
|
59710
59749
|
isBackground: external_exports.boolean().optional(),
|
|
59750
|
+
start: external_exports.number().min(0).default(0).describe("seconds, relative to parent timeline (0 inside series parents)"),
|
|
59751
|
+
end: external_exports.number().min(0).optional().describe("seconds, relative to parent timeline \u2014 source of truth for duration"),
|
|
59752
|
+
duration: external_exports.number().min(0).optional().describe("convenience; normalized to end = start + duration when end is absent"),
|
|
59753
|
+
startFrom: external_exports.number().min(0).optional().describe("trim seconds from source start (video/audio)"),
|
|
59754
|
+
endAt: external_exports.number().min(0).optional().describe("trim seconds at source end (video/audio)"),
|
|
59711
59755
|
durationInSeconds: external_exports.number().optional().describe("set by engine; do not edit by hand"),
|
|
59712
59756
|
on: eventSpec.optional().describe("event that fires at a specific frame, mutating registered component state")
|
|
59713
59757
|
};
|
|
@@ -59760,26 +59804,25 @@ var video = base.extend({
|
|
|
59760
59804
|
playbackRate: external_exports.number().optional(),
|
|
59761
59805
|
width: external_exports.number().default(1080),
|
|
59762
59806
|
height: external_exports.number().default(1920),
|
|
59763
|
-
|
|
59807
|
+
loop: external_exports.number().int().min(1).optional().describe(">1 = loop count")
|
|
59764
59808
|
});
|
|
59765
59809
|
var audio = base.extend({
|
|
59766
59810
|
type: external_exports.literal("audio").default("audio"),
|
|
59767
59811
|
src: external_exports.string().optional(),
|
|
59768
59812
|
volume: external_exports.number().min(0).max(1).default(1),
|
|
59769
59813
|
foreground: external_exports.boolean().optional().describe("ducks parent video audio while playing"),
|
|
59770
|
-
|
|
59814
|
+
loop: external_exports.number().int().min(1).optional().describe(">1 = loop count"),
|
|
59815
|
+
speaker: external_exports.string().optional().describe("speaker name for multi-turn dialogue; set by resolveDialogue")
|
|
59771
59816
|
});
|
|
59772
59817
|
var image = base.extend({
|
|
59773
59818
|
type: external_exports.literal("image").default("image"),
|
|
59774
59819
|
src: external_exports.string().optional(),
|
|
59775
|
-
fit: external_exports.enum(["contain", "cover", "fill"]).default("contain")
|
|
59776
|
-
actions: external_exports.array(action).min(1).default(() => [action.parse({})])
|
|
59820
|
+
fit: external_exports.enum(["contain", "cover", "fill"]).default("contain")
|
|
59777
59821
|
});
|
|
59778
59822
|
var component = base.extend({
|
|
59779
59823
|
type: external_exports.literal("component").default("component"),
|
|
59780
59824
|
jsx: external_exports.string().describe("usage JSX expression compiled at runtime; tag names resolved from imports"),
|
|
59781
|
-
data: external_exports.record(external_exports.string(), external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])).optional().describe("extra variables (e.g. from ~~~md source code fences) available in JSX scope")
|
|
59782
|
-
actions: external_exports.array(action).min(1).default(() => [action.parse({})])
|
|
59825
|
+
data: external_exports.record(external_exports.string(), external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])).optional().describe("extra variables (e.g. from ~~~md source code fences) available in JSX scope")
|
|
59783
59826
|
});
|
|
59784
59827
|
var effect = base.extend({
|
|
59785
59828
|
type: external_exports.literal("effect").default("effect"),
|
|
@@ -59787,23 +59830,20 @@ var effect = base.extend({
|
|
|
59787
59830
|
animationTimingFunction: external_exports.enum(["linear", "ease", "ease-in", "ease-out", "ease-in-out"]).optional(),
|
|
59788
59831
|
animationIterationCount: external_exports.number().default(1),
|
|
59789
59832
|
customKeyframes: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.string())).optional().describe('inline keyframes: { "0": { opacity: "0" }, "100": { opacity: "1" } }'),
|
|
59790
|
-
children: external_exports.array(external_exports.lazy(() => stream)).default(() => [])
|
|
59791
|
-
actions: external_exports.array(action).min(1).default(() => [action.parse({})])
|
|
59833
|
+
children: external_exports.array(external_exports.lazy(() => stream)).default(() => [])
|
|
59792
59834
|
});
|
|
59793
59835
|
var rhythm = base.extend({
|
|
59794
59836
|
type: external_exports.literal("rhythm").default("rhythm"),
|
|
59795
59837
|
src: external_exports.string().optional().describe("audio file for beat playback"),
|
|
59796
59838
|
volume: external_exports.number().min(0).max(1).default(1),
|
|
59797
59839
|
spots: external_exports.array(external_exports.number()).optional().describe("pre-computed beat timestamps in seconds"),
|
|
59798
|
-
children: external_exports.array(external_exports.lazy(() => stream)).default(() => [])
|
|
59799
|
-
actions: external_exports.array(action).min(1).default(() => [action.parse({})])
|
|
59840
|
+
children: external_exports.array(external_exports.lazy(() => stream)).default(() => [])
|
|
59800
59841
|
});
|
|
59801
59842
|
var include = base.extend({
|
|
59802
59843
|
type: external_exports.literal("include").default("include"),
|
|
59803
59844
|
src: external_exports.string().optional().describe("path or URL to video JSON file (stream tree or scene-based)"),
|
|
59804
59845
|
volume: external_exports.number().min(0).max(1).default(1),
|
|
59805
59846
|
children: external_exports.array(external_exports.lazy(() => stream)).default(() => []),
|
|
59806
|
-
actions: external_exports.array(action).min(1).default(() => [action.parse({})]),
|
|
59807
59847
|
imports: external_exports.string().optional().describe("component bundle URL for sub-video (set by engine)")
|
|
59808
59848
|
});
|
|
59809
59849
|
var scene = base.extend({
|
|
@@ -59830,7 +59870,7 @@ var mapStream = base.extend({
|
|
|
59830
59870
|
mapType: external_exports.enum(["roadmap", "satellite", "hybrid", "terrain"]).default("roadmap").describe("Google Maps style"),
|
|
59831
59871
|
travelMode: external_exports.enum(["DRIVING", "WALKING", "BICYCLING", "TRANSIT"]).default("DRIVING").describe("Directions API travel mode"),
|
|
59832
59872
|
routeMarker: external_exports.string().default("\u{1F697}").describe("emoji/character for the animated traveling marker"),
|
|
59833
|
-
|
|
59873
|
+
googleMapsApiKey: external_exports.string().optional().describe("injected by compiler from GOOGLE_MAPS_API_KEY env var")
|
|
59834
59874
|
});
|
|
59835
59875
|
var stream = external_exports.discriminatedUnion("type", [
|
|
59836
59876
|
root,
|
|
@@ -59850,9 +59890,9 @@ var stream = external_exports.discriminatedUnion("type", [
|
|
|
59850
59890
|
var import_jsx_runtime89 = __toESM(require_jsx_runtime(), 1);
|
|
59851
59891
|
var DefaultContainer2 = ({ children, style: style2, className: className2 }) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: className2, style: { position: "absolute", inset: 0, ...style2 }, children });
|
|
59852
59892
|
function useComponentRegistry(imports) {
|
|
59853
|
-
const [registry2, setRegistry] =
|
|
59854
|
-
const handleRef =
|
|
59855
|
-
|
|
59893
|
+
const [registry2, setRegistry] = React47.useState(null);
|
|
59894
|
+
const handleRef = React47.useRef(null);
|
|
59895
|
+
React47.useEffect(() => {
|
|
59856
59896
|
if (!imports) {
|
|
59857
59897
|
setRegistry(null);
|
|
59858
59898
|
return;
|
|
@@ -59865,9 +59905,11 @@ function useComponentRegistry(imports) {
|
|
|
59865
59905
|
if (!handleRef.current) {
|
|
59866
59906
|
handleRef.current = delayRender("Loading component registry: " + imports);
|
|
59867
59907
|
}
|
|
59908
|
+
const moduleUrl = /^(https?:|data:|blob:|\/)/.test(imports) ? imports : staticFile(imports);
|
|
59909
|
+
ensureSharedImportMap();
|
|
59868
59910
|
import(
|
|
59869
59911
|
/* webpackIgnore: true */
|
|
59870
|
-
|
|
59912
|
+
moduleUrl
|
|
59871
59913
|
).then((mod) => {
|
|
59872
59914
|
setRegistry(mod.default ?? mod);
|
|
59873
59915
|
if (handleRef.current) {
|
|
@@ -59889,7 +59931,7 @@ function useComponentRegistry(imports) {
|
|
|
59889
59931
|
return registry2;
|
|
59890
59932
|
}
|
|
59891
59933
|
function MarkCut({ root: root2, compose, background = "#000" }) {
|
|
59892
|
-
const parsed =
|
|
59934
|
+
const parsed = React47.useMemo(() => {
|
|
59893
59935
|
if (!root2) {
|
|
59894
59936
|
return {
|
|
59895
59937
|
id: "root",
|
|
@@ -59906,8 +59948,8 @@ function MarkCut({ root: root2, compose, background = "#000" }) {
|
|
|
59906
59948
|
return root.parse(root2);
|
|
59907
59949
|
}, [root2]);
|
|
59908
59950
|
const registry2 = useComponentRegistry(parsed.imports);
|
|
59909
|
-
|
|
59910
|
-
const value =
|
|
59951
|
+
React47.useMemo(() => getDurationInSeconds(parsed, true), [parsed]);
|
|
59952
|
+
const value = React47.useMemo(
|
|
59911
59953
|
() => ({
|
|
59912
59954
|
Container: compose?.Container ?? DefaultContainer2,
|
|
59913
59955
|
onError: compose?.onError,
|
|
@@ -59922,11 +59964,471 @@ function MarkCut({ root: root2, compose, background = "#000" }) {
|
|
|
59922
59964
|
] }) }) });
|
|
59923
59965
|
}
|
|
59924
59966
|
|
|
59967
|
+
// src/player/components/HeaderBar.tsx
|
|
59968
|
+
var React48 = __toESM(require_react(), 1);
|
|
59969
|
+
var import_jsx_runtime90 = __toESM(require_jsx_runtime(), 1);
|
|
59970
|
+
function HeaderBar({ mode, sceneInfo, editStatus, sseConnected }) {
|
|
59971
|
+
const handleClose = React48.useCallback(() => {
|
|
59972
|
+
navigator.sendBeacon("/api/shutdown", "{}");
|
|
59973
|
+
document.body.innerHTML = "<div style='display:flex;align-items:center;justify-content:center;height:100vh;background:#0a0a0a;color:#555;font-family:sans-serif;font-size:16px'>\u2B61 player closed \u2014 return to terminal</div>";
|
|
59974
|
+
}, []);
|
|
59975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { id: "header", children: [
|
|
59976
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("span", { style: { flex: 1, display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
59977
|
+
mode === "label" && sceneInfo && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { id: "scene-info", children: sceneInfo }),
|
|
59978
|
+
mode === "edit" && editStatus && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { id: "edit-status", children: editStatus }),
|
|
59979
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
59980
|
+
"span",
|
|
59981
|
+
{
|
|
59982
|
+
id: "sse-indicator",
|
|
59983
|
+
title: sseConnected ? "Connected \u2014 auto-reload ready" : "Disconnected",
|
|
59984
|
+
style: {
|
|
59985
|
+
display: "inline-block",
|
|
59986
|
+
width: 8,
|
|
59987
|
+
height: 8,
|
|
59988
|
+
borderRadius: "50%",
|
|
59989
|
+
background: sseConnected ? "#4ade80" : "#555",
|
|
59990
|
+
flexShrink: 0
|
|
59991
|
+
}
|
|
59992
|
+
}
|
|
59993
|
+
)
|
|
59994
|
+
] }),
|
|
59995
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { id: "header-actions", children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { id: "close-btn", title: "Close player and return to terminal", onClick: handleClose, children: "\u2715" }) })
|
|
59996
|
+
] });
|
|
59997
|
+
}
|
|
59998
|
+
|
|
59999
|
+
// src/player/components/EditControls.tsx
|
|
60000
|
+
var React49 = __toESM(require_react(), 1);
|
|
60001
|
+
var import_jsx_runtime91 = __toESM(require_jsx_runtime(), 1);
|
|
60002
|
+
function EditControls({ onStatusChange, suppressReloadRef, currentTime, activeScene }) {
|
|
60003
|
+
const [busy, setBusy] = React49.useState(false);
|
|
60004
|
+
const inputRef = React49.useRef(null);
|
|
60005
|
+
const handleApplyEdit = React49.useCallback(
|
|
60006
|
+
async (text) => {
|
|
60007
|
+
if (!text || busy) return;
|
|
60008
|
+
setBusy(true);
|
|
60009
|
+
onStatusChange?.("\u231B editing...");
|
|
60010
|
+
if (inputRef.current) inputRef.current.value = "";
|
|
60011
|
+
if (suppressReloadRef) suppressReloadRef.current = true;
|
|
60012
|
+
try {
|
|
60013
|
+
const res = await fetch("/api/edit", {
|
|
60014
|
+
method: "POST",
|
|
60015
|
+
headers: { "Content-Type": "application/json" },
|
|
60016
|
+
body: JSON.stringify({ text, currentTime, activeScene })
|
|
60017
|
+
});
|
|
60018
|
+
const data2 = await res.json();
|
|
60019
|
+
if (res.ok) {
|
|
60020
|
+
const summary = (data2.output || "done").split("\n")[0].slice(0, 65);
|
|
60021
|
+
onStatusChange?.(summary);
|
|
60022
|
+
setTimeout(() => {
|
|
60023
|
+
if (suppressReloadRef) suppressReloadRef.current = false;
|
|
60024
|
+
window.dispatchEvent(new Event("refresh-player"));
|
|
60025
|
+
}, 4e3);
|
|
60026
|
+
} else {
|
|
60027
|
+
onStatusChange?.("\u274C " + (data2.error || "failed"));
|
|
60028
|
+
if (suppressReloadRef) suppressReloadRef.current = false;
|
|
60029
|
+
}
|
|
60030
|
+
} catch {
|
|
60031
|
+
onStatusChange?.("\u274C error");
|
|
60032
|
+
if (suppressReloadRef) suppressReloadRef.current = false;
|
|
60033
|
+
}
|
|
60034
|
+
setBusy(false);
|
|
60035
|
+
},
|
|
60036
|
+
[busy, onStatusChange, suppressReloadRef]
|
|
60037
|
+
);
|
|
60038
|
+
const handleKeyDown = React49.useCallback(
|
|
60039
|
+
(e) => {
|
|
60040
|
+
if (e.key === "Enter") {
|
|
60041
|
+
e.preventDefault();
|
|
60042
|
+
handleApplyEdit(e.target.value);
|
|
60043
|
+
}
|
|
60044
|
+
},
|
|
60045
|
+
[handleApplyEdit]
|
|
60046
|
+
);
|
|
60047
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { id: "bottom-bar", children: [
|
|
60048
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
60049
|
+
"input",
|
|
60050
|
+
{
|
|
60051
|
+
ref: inputRef,
|
|
60052
|
+
id: "edit-input",
|
|
60053
|
+
placeholder: "What should change? e.g. make text bigger",
|
|
60054
|
+
onKeyDown: handleKeyDown
|
|
60055
|
+
}
|
|
60056
|
+
),
|
|
60057
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
60058
|
+
"button",
|
|
60059
|
+
{
|
|
60060
|
+
id: "edit-btn",
|
|
60061
|
+
title: "Apply edit",
|
|
60062
|
+
disabled: busy,
|
|
60063
|
+
onClick: () => handleApplyEdit(inputRef.current?.value || ""),
|
|
60064
|
+
children: "\u2728"
|
|
60065
|
+
}
|
|
60066
|
+
)
|
|
60067
|
+
] });
|
|
60068
|
+
}
|
|
60069
|
+
|
|
60070
|
+
// src/player/components/LabelControls.tsx
|
|
60071
|
+
var React50 = __toESM(require_react(), 1);
|
|
60072
|
+
var import_jsx_runtime92 = __toESM(require_jsx_runtime(), 1);
|
|
60073
|
+
var VIDEO_EXT = {
|
|
60074
|
+
".mov": 1,
|
|
60075
|
+
".mp4": 1,
|
|
60076
|
+
".avi": 1,
|
|
60077
|
+
".mkv": 1,
|
|
60078
|
+
".webm": 1,
|
|
60079
|
+
".m4v": 1,
|
|
60080
|
+
".wmv": 1
|
|
60081
|
+
};
|
|
60082
|
+
function escHtml(s2) {
|
|
60083
|
+
return s2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
60084
|
+
}
|
|
60085
|
+
function formatTime2(sec) {
|
|
60086
|
+
const mm = Math.floor(sec / 60);
|
|
60087
|
+
const ss = Math.floor(sec % 60);
|
|
60088
|
+
return mm + ":" + String(ss).padStart(2, "0");
|
|
60089
|
+
}
|
|
60090
|
+
function LabelControls({ playerRef, currentTime, onSceneChange }) {
|
|
60091
|
+
const [videoInfo, setVideoInfo] = React50.useState(null);
|
|
60092
|
+
const [labelData, setLabelData] = React50.useState({});
|
|
60093
|
+
const [currentSceneIdx, setCurrentSceneIdx] = React50.useState(0);
|
|
60094
|
+
const [selectedOverride, setSelectedOverride] = React50.useState(-1);
|
|
60095
|
+
const [inputText, setInputText] = React50.useState("");
|
|
60096
|
+
const [saving, setSaving] = React50.useState(false);
|
|
60097
|
+
const inputRef = React50.useRef(null);
|
|
60098
|
+
React50.useEffect(() => {
|
|
60099
|
+
fetch("/api/video-info").then((r) => r.json()).then((info2) => {
|
|
60100
|
+
setVideoInfo(info2);
|
|
60101
|
+
if (info2.scenes?.[0]) {
|
|
60102
|
+
onSceneChange?.(info2.scenes[0].name + " (0.0s)");
|
|
60103
|
+
}
|
|
60104
|
+
}).catch(() => {
|
|
60105
|
+
});
|
|
60106
|
+
fetch("/api/labels").then((r) => r.ok ? r.json() : null).then((tree) => {
|
|
60107
|
+
if (!tree) return;
|
|
60108
|
+
const root2 = tree.root || tree;
|
|
60109
|
+
const children = root2.children || [];
|
|
60110
|
+
const loaded = {};
|
|
60111
|
+
for (let i3 = 0; i3 < children.length; i3++) {
|
|
60112
|
+
const media = (children[i3].children || [])[0];
|
|
60113
|
+
if (media && media.userHints) {
|
|
60114
|
+
loaded[i3] = {
|
|
60115
|
+
overall: media.userHints.overall || "",
|
|
60116
|
+
timed: media.userHints.timed || {}
|
|
60117
|
+
};
|
|
60118
|
+
} else if (media && media.description) {
|
|
60119
|
+
loaded[i3] = { overall: media.description, timed: {} };
|
|
60120
|
+
}
|
|
60121
|
+
}
|
|
60122
|
+
setLabelData(loaded);
|
|
60123
|
+
}).catch(() => {
|
|
60124
|
+
});
|
|
60125
|
+
}, [onSceneChange]);
|
|
60126
|
+
const scenes = videoInfo?.scenes || [];
|
|
60127
|
+
const effectiveIdx = selectedOverride >= 0 ? selectedOverride : currentSceneIdx;
|
|
60128
|
+
const currentScene = scenes[effectiveIdx];
|
|
60129
|
+
React50.useEffect(() => {
|
|
60130
|
+
if (selectedOverride >= 0) return;
|
|
60131
|
+
for (let i3 = 0; i3 < scenes.length; i3++) {
|
|
60132
|
+
if (currentTime >= scenes[i3].start && currentTime < scenes[i3].end) {
|
|
60133
|
+
setCurrentSceneIdx(i3);
|
|
60134
|
+
break;
|
|
60135
|
+
}
|
|
60136
|
+
}
|
|
60137
|
+
}, [currentTime, scenes, selectedOverride]);
|
|
60138
|
+
React50.useEffect(() => {
|
|
60139
|
+
if (selectedOverride >= 0 && currentScene) {
|
|
60140
|
+
const scene2 = scenes[selectedOverride];
|
|
60141
|
+
if (scene2 && (currentTime < scene2.start || currentTime >= scene2.end)) {
|
|
60142
|
+
setSelectedOverride(-1);
|
|
60143
|
+
}
|
|
60144
|
+
}
|
|
60145
|
+
}, [currentTime, selectedOverride, scenes, currentScene]);
|
|
60146
|
+
React50.useEffect(() => {
|
|
60147
|
+
if (!currentScene) {
|
|
60148
|
+
onSceneChange?.(currentTime.toFixed(1) + "s");
|
|
60149
|
+
} else if (selectedOverride >= 0) {
|
|
60150
|
+
onSceneChange?.(currentScene.name + " (selected)");
|
|
60151
|
+
} else {
|
|
60152
|
+
onSceneChange?.(currentScene.name + " (" + currentTime.toFixed(1) + "s)");
|
|
60153
|
+
}
|
|
60154
|
+
}, [currentScene, currentTime, selectedOverride, onSceneChange]);
|
|
60155
|
+
const seekToScene = React50.useCallback(
|
|
60156
|
+
(index) => {
|
|
60157
|
+
setSelectedOverride(index);
|
|
60158
|
+
setCurrentSceneIdx(index);
|
|
60159
|
+
const scene2 = scenes[index];
|
|
60160
|
+
if (scene2 && playerRef.current) {
|
|
60161
|
+
const frame = Math.round(scene2.start * 30);
|
|
60162
|
+
playerRef.current.seekTo(frame);
|
|
60163
|
+
}
|
|
60164
|
+
},
|
|
60165
|
+
[scenes, playerRef]
|
|
60166
|
+
);
|
|
60167
|
+
React50.useEffect(() => {
|
|
60168
|
+
const entry = labelData[effectiveIdx];
|
|
60169
|
+
setInputText(entry && entry.overall || "");
|
|
60170
|
+
}, [effectiveIdx, labelData]);
|
|
60171
|
+
const saveLabel = React50.useCallback(() => {
|
|
60172
|
+
const text = inputText.trim();
|
|
60173
|
+
if (!text || saving) return;
|
|
60174
|
+
setSaving(true);
|
|
60175
|
+
const sceneIdx = effectiveIdx;
|
|
60176
|
+
const timeMs = Math.round(currentTime * 1e3);
|
|
60177
|
+
const scene2 = scenes[sceneIdx];
|
|
60178
|
+
const isImage = scene2 && scene2.mediaType === "image";
|
|
60179
|
+
const sceneStart = scene2 ? scene2.start * 1e3 : 0;
|
|
60180
|
+
const isOverall = isImage || timeMs - sceneStart < 1e3;
|
|
60181
|
+
setLabelData((prev) => {
|
|
60182
|
+
const next = { ...prev };
|
|
60183
|
+
if (!next[sceneIdx]) next[sceneIdx] = { overall: "", timed: {} };
|
|
60184
|
+
if (isOverall) {
|
|
60185
|
+
next[sceneIdx] = { ...next[sceneIdx], overall: text };
|
|
60186
|
+
} else {
|
|
60187
|
+
next[sceneIdx] = {
|
|
60188
|
+
...next[sceneIdx],
|
|
60189
|
+
timed: { ...next[sceneIdx].timed, ["at_" + timeMs]: text }
|
|
60190
|
+
};
|
|
60191
|
+
}
|
|
60192
|
+
return next;
|
|
60193
|
+
});
|
|
60194
|
+
fetch("/api/labels", {
|
|
60195
|
+
method: "POST",
|
|
60196
|
+
headers: { "Content-Type": "application/json" },
|
|
60197
|
+
body: JSON.stringify({
|
|
60198
|
+
sceneIndex: sceneIdx,
|
|
60199
|
+
description: text,
|
|
60200
|
+
time: currentTime,
|
|
60201
|
+
overall: isOverall || void 0
|
|
60202
|
+
})
|
|
60203
|
+
}).then(() => {
|
|
60204
|
+
setInputText("");
|
|
60205
|
+
const toast = document.getElementById("saved-toast");
|
|
60206
|
+
if (toast) {
|
|
60207
|
+
toast.classList.add("show");
|
|
60208
|
+
setTimeout(() => toast.classList.remove("show"), 2e3);
|
|
60209
|
+
}
|
|
60210
|
+
}).catch(() => {
|
|
60211
|
+
}).finally(() => setSaving(false));
|
|
60212
|
+
}, [inputText, saving, effectiveIdx, currentTime, scenes]);
|
|
60213
|
+
const deleteTimed = React50.useCallback(
|
|
60214
|
+
(key) => {
|
|
60215
|
+
const sceneIdx = effectiveIdx;
|
|
60216
|
+
setLabelData((prev) => {
|
|
60217
|
+
const entry = prev[sceneIdx];
|
|
60218
|
+
if (!entry || !entry.timed[key]) return prev;
|
|
60219
|
+
const next = { ...prev };
|
|
60220
|
+
const nextEntry = { ...entry, timed: { ...entry.timed } };
|
|
60221
|
+
delete nextEntry.timed[key];
|
|
60222
|
+
next[sceneIdx] = nextEntry;
|
|
60223
|
+
return next;
|
|
60224
|
+
});
|
|
60225
|
+
fetch("/api/labels", {
|
|
60226
|
+
method: "POST",
|
|
60227
|
+
headers: { "Content-Type": "application/json" },
|
|
60228
|
+
body: JSON.stringify({
|
|
60229
|
+
sceneIndex: sceneIdx,
|
|
60230
|
+
description: "",
|
|
60231
|
+
removeTimed: key
|
|
60232
|
+
})
|
|
60233
|
+
}).catch(() => {
|
|
60234
|
+
});
|
|
60235
|
+
},
|
|
60236
|
+
[effectiveIdx]
|
|
60237
|
+
);
|
|
60238
|
+
const renderThumbnails = () => {
|
|
60239
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { id: "thumbnails", children: scenes.map((scene2, i3) => {
|
|
60240
|
+
const isActive = i3 === effectiveIdx;
|
|
60241
|
+
const entry = labelData[i3];
|
|
60242
|
+
const hasLabel = entry && (entry.overall || Object.keys(entry.timed).length > 0);
|
|
60243
|
+
let thumbContent;
|
|
60244
|
+
const ext = scene2.src.substring(scene2.src.lastIndexOf(".")).toLowerCase();
|
|
60245
|
+
const isVideo = !!VIDEO_EXT[ext];
|
|
60246
|
+
if (scene2.src && !isVideo) {
|
|
60247
|
+
thumbContent = /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("img", { src: scene2.src, alt: "", loading: "lazy" });
|
|
60248
|
+
} else if (scene2.src && isVideo) {
|
|
60249
|
+
thumbContent = /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
60250
|
+
"video",
|
|
60251
|
+
{
|
|
60252
|
+
src: scene2.src,
|
|
60253
|
+
muted: true,
|
|
60254
|
+
preload: "metadata",
|
|
60255
|
+
style: { width: "100%", height: "100%", objectFit: "cover" }
|
|
60256
|
+
}
|
|
60257
|
+
);
|
|
60258
|
+
} else {
|
|
60259
|
+
thumbContent = /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
60260
|
+
"div",
|
|
60261
|
+
{
|
|
60262
|
+
style: {
|
|
60263
|
+
width: "100%",
|
|
60264
|
+
height: "100%",
|
|
60265
|
+
display: "flex",
|
|
60266
|
+
alignItems: "center",
|
|
60267
|
+
justifyContent: "center",
|
|
60268
|
+
background: "rgba(255,255,255,.08)",
|
|
60269
|
+
color: "rgba(255,255,255,.3)",
|
|
60270
|
+
fontSize: 16,
|
|
60271
|
+
fontWeight: 600
|
|
60272
|
+
},
|
|
60273
|
+
children: (scene2.name || "S" + (i3 + 1)).slice(0, 2).toUpperCase()
|
|
60274
|
+
}
|
|
60275
|
+
);
|
|
60276
|
+
}
|
|
60277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
|
|
60278
|
+
"div",
|
|
60279
|
+
{
|
|
60280
|
+
className: "thumb-item" + (isActive ? " active" : ""),
|
|
60281
|
+
"data-index": i3,
|
|
60282
|
+
onClick: () => seekToScene(i3),
|
|
60283
|
+
children: [
|
|
60284
|
+
thumbContent,
|
|
60285
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: "thumb-badge" + (hasLabel ? " has-label" : "") })
|
|
60286
|
+
]
|
|
60287
|
+
},
|
|
60288
|
+
i3
|
|
60289
|
+
);
|
|
60290
|
+
}) });
|
|
60291
|
+
};
|
|
60292
|
+
const renderTimedLabels = () => {
|
|
60293
|
+
const entry = labelData[effectiveIdx];
|
|
60294
|
+
const timed = entry && entry.timed || {};
|
|
60295
|
+
const keys = Object.keys(timed).sort();
|
|
60296
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { id: "timed-labels", children: keys.map((k2) => {
|
|
60297
|
+
const sec = parseInt(k2.replace("at_", "")) / 1e3;
|
|
60298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: "timed-label", "data-key": k2, children: [
|
|
60299
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { className: "tl-time", children: formatTime2(sec) }),
|
|
60300
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { className: "tl-text", dangerouslySetInnerHTML: { __html: escHtml(timed[k2]) } }),
|
|
60301
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("button", { className: "tl-del", title: "Remove", onClick: () => deleteTimed(k2), children: "\xD7" })
|
|
60302
|
+
] }, k2);
|
|
60303
|
+
}) });
|
|
60304
|
+
};
|
|
60305
|
+
let sceneInfoText = currentTime.toFixed(1) + "s";
|
|
60306
|
+
if (currentScene) {
|
|
60307
|
+
if (selectedOverride >= 0) {
|
|
60308
|
+
sceneInfoText = currentScene.name + " (selected)";
|
|
60309
|
+
} else {
|
|
60310
|
+
sceneInfoText = currentScene.name + " (" + currentTime.toFixed(1) + "s)";
|
|
60311
|
+
}
|
|
60312
|
+
}
|
|
60313
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(import_jsx_runtime92.Fragment, { children: [
|
|
60314
|
+
renderThumbnails(),
|
|
60315
|
+
renderTimedLabels(),
|
|
60316
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { id: "saved-toast", children: "\u2713 Label saved" }),
|
|
60317
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { id: "bottom-bar", children: [
|
|
60318
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
60319
|
+
"input",
|
|
60320
|
+
{
|
|
60321
|
+
ref: inputRef,
|
|
60322
|
+
id: "label-input",
|
|
60323
|
+
placeholder: "Add label for current scene\u2026",
|
|
60324
|
+
value: inputText,
|
|
60325
|
+
onChange: (e) => setInputText(e.target.value),
|
|
60326
|
+
onKeyDown: (e) => {
|
|
60327
|
+
if (e.key === "Enter") {
|
|
60328
|
+
e.preventDefault();
|
|
60329
|
+
saveLabel();
|
|
60330
|
+
}
|
|
60331
|
+
}
|
|
60332
|
+
}
|
|
60333
|
+
),
|
|
60334
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
60335
|
+
"button",
|
|
60336
|
+
{
|
|
60337
|
+
id: "label-btn",
|
|
60338
|
+
title: "Save label",
|
|
60339
|
+
disabled: saving || !inputText.trim(),
|
|
60340
|
+
onClick: saveLabel,
|
|
60341
|
+
children: "\u{1F4DD}"
|
|
60342
|
+
}
|
|
60343
|
+
)
|
|
60344
|
+
] })
|
|
60345
|
+
] });
|
|
60346
|
+
}
|
|
60347
|
+
|
|
60348
|
+
// src/player/components/SceneThumbnails.tsx
|
|
60349
|
+
var React51 = __toESM(require_react(), 1);
|
|
60350
|
+
var import_jsx_runtime93 = __toESM(require_jsx_runtime(), 1);
|
|
60351
|
+
var VIDEO_EXT2 = {
|
|
60352
|
+
".mov": 1,
|
|
60353
|
+
".mp4": 1,
|
|
60354
|
+
".avi": 1,
|
|
60355
|
+
".mkv": 1,
|
|
60356
|
+
".webm": 1,
|
|
60357
|
+
".m4v": 1,
|
|
60358
|
+
".wmv": 1
|
|
60359
|
+
};
|
|
60360
|
+
function SceneThumbnails({ currentTime, onSeek }) {
|
|
60361
|
+
const [scenes, setScenes] = React51.useState([]);
|
|
60362
|
+
React51.useEffect(() => {
|
|
60363
|
+
fetch("/api/video-info").then((r) => r.json()).then((info2) => {
|
|
60364
|
+
if (info2.scenes) setScenes(info2.scenes);
|
|
60365
|
+
}).catch(() => {
|
|
60366
|
+
});
|
|
60367
|
+
}, []);
|
|
60368
|
+
if (scenes.length === 0) return null;
|
|
60369
|
+
let activeIdx = -1;
|
|
60370
|
+
for (let i3 = 0; i3 < scenes.length; i3++) {
|
|
60371
|
+
if (currentTime >= scenes[i3].start && currentTime < scenes[i3].end) {
|
|
60372
|
+
activeIdx = i3;
|
|
60373
|
+
break;
|
|
60374
|
+
}
|
|
60375
|
+
}
|
|
60376
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { id: "scene-thumbnails", children: scenes.map((scene2, i3) => {
|
|
60377
|
+
const isActive = i3 === activeIdx;
|
|
60378
|
+
const ext = scene2.src.substring(scene2.src.lastIndexOf(".")).toLowerCase();
|
|
60379
|
+
const isVideo = !!VIDEO_EXT2[ext];
|
|
60380
|
+
const hasMedia = !!scene2.src;
|
|
60381
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
|
|
60382
|
+
"div",
|
|
60383
|
+
{
|
|
60384
|
+
className: "sthumb-item" + (isActive ? " active" : ""),
|
|
60385
|
+
onClick: () => onSeek?.(scene2.start),
|
|
60386
|
+
children: [
|
|
60387
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "sthumb-media", children: [
|
|
60388
|
+
hasMedia && !isVideo && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("img", { src: scene2.src, alt: "", loading: "lazy" }),
|
|
60389
|
+
hasMedia && isVideo && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("video", { src: scene2.src, muted: true, preload: "metadata" }),
|
|
60390
|
+
!hasMedia && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("span", { className: "sthumb-fallback", children: (scene2.name || "S" + (i3 + 1)).slice(0, 2).toUpperCase() })
|
|
60391
|
+
] }),
|
|
60392
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("span", { className: "sthumb-name", children: scene2.name || "Scene " + (i3 + 1) })
|
|
60393
|
+
]
|
|
60394
|
+
},
|
|
60395
|
+
i3
|
|
60396
|
+
);
|
|
60397
|
+
}) });
|
|
60398
|
+
}
|
|
60399
|
+
|
|
60400
|
+
// src/player/components/VariantBar.tsx
|
|
60401
|
+
var React54 = __toESM(require_react(), 1);
|
|
60402
|
+
var import_jsx_runtime94 = __toESM(require_jsx_runtime(), 1);
|
|
60403
|
+
function VariantBar() {
|
|
60404
|
+
const [variants, setVariants] = React54.useState([]);
|
|
60405
|
+
const currentVariant = (typeof window !== "undefined" ? window.VARIANT : null) || "default";
|
|
60406
|
+
React54.useEffect(() => {
|
|
60407
|
+
fetch("/api/video-info").then((r) => r.json()).then((info2) => {
|
|
60408
|
+
if (info2.variants && info2.variants.length > 1) {
|
|
60409
|
+
setVariants(info2.variants);
|
|
60410
|
+
}
|
|
60411
|
+
}).catch(() => {
|
|
60412
|
+
});
|
|
60413
|
+
}, []);
|
|
60414
|
+
if (variants.length <= 1) return null;
|
|
60415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("div", { id: "variant-bar", children: variants.map((v2) => /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
|
|
60416
|
+
"a",
|
|
60417
|
+
{
|
|
60418
|
+
href: `/${v2 === "default" ? "" : v2}`,
|
|
60419
|
+
className: "variant-link" + (v2 === currentVariant ? " active" : ""),
|
|
60420
|
+
children: v2
|
|
60421
|
+
},
|
|
60422
|
+
v2
|
|
60423
|
+
)) });
|
|
60424
|
+
}
|
|
60425
|
+
|
|
59925
60426
|
// src/player/browser.tsx
|
|
60427
|
+
var import_jsx_runtime95 = __toESM(require_jsx_runtime(), 1);
|
|
59926
60428
|
if (typeof window !== "undefined") {
|
|
59927
60429
|
globalThis.__remotionShared = {
|
|
59928
|
-
"react":
|
|
59929
|
-
"react-dom":
|
|
60430
|
+
"react": React55,
|
|
60431
|
+
"react-dom": ReactDOM2,
|
|
59930
60432
|
"remotion": esm_exports,
|
|
59931
60433
|
"@remotion/player": { Player }
|
|
59932
60434
|
};
|
|
@@ -59988,59 +60490,90 @@ if (typeof window !== "undefined") {
|
|
|
59988
60490
|
}
|
|
59989
60491
|
}
|
|
59990
60492
|
function PlayerApp() {
|
|
59991
|
-
const playerRef =
|
|
59992
|
-
const [ready, setReady] =
|
|
59993
|
-
const [error49, setError] =
|
|
59994
|
-
const [data2, setData] =
|
|
59995
|
-
const [
|
|
59996
|
-
const [
|
|
59997
|
-
const
|
|
59998
|
-
const
|
|
59999
|
-
const
|
|
60493
|
+
const playerRef = React55.useRef(null);
|
|
60494
|
+
const [ready, setReady] = React55.useState(false);
|
|
60495
|
+
const [error49, setError] = React55.useState(null);
|
|
60496
|
+
const [data2, setData] = React55.useState(null);
|
|
60497
|
+
const [muted, setMuted] = React55.useState(false);
|
|
60498
|
+
const [volume, setVolume] = React55.useState(1);
|
|
60499
|
+
const mountedRef = React55.useRef(true);
|
|
60500
|
+
const currentFrameRef = React55.useRef(0);
|
|
60501
|
+
const [currentTime, setCurrentTime] = React55.useState(0);
|
|
60502
|
+
const [activeScene, setActiveScene] = React55.useState("");
|
|
60503
|
+
React55.useEffect(() => {
|
|
60504
|
+
fetch("/api/video-info").then((r) => r.json()).then((info2) => {
|
|
60505
|
+
if (info2.scenes) {
|
|
60506
|
+
window.__scenes = info2.scenes;
|
|
60507
|
+
}
|
|
60508
|
+
}).catch(() => {
|
|
60509
|
+
});
|
|
60510
|
+
}, []);
|
|
60511
|
+
React55.useEffect(() => {
|
|
60512
|
+
const scenes = window.__scenes;
|
|
60513
|
+
if (!scenes) return;
|
|
60514
|
+
let found = "";
|
|
60515
|
+
for (const s2 of scenes) {
|
|
60516
|
+
if (currentTime >= s2.start && currentTime < s2.end) {
|
|
60517
|
+
found = s2.name || "";
|
|
60518
|
+
break;
|
|
60519
|
+
}
|
|
60520
|
+
}
|
|
60521
|
+
setActiveScene(found);
|
|
60522
|
+
}, [currentTime]);
|
|
60523
|
+
const pendingSeekRef = React55.useRef(null);
|
|
60000
60524
|
const urlParams = new URLSearchParams(typeof window !== "undefined" ? window.location.search : "");
|
|
60001
60525
|
const autoPlay = urlParams.get("autoplay") === "true";
|
|
60002
60526
|
const startAt = parseFloat(urlParams.get("start") || urlParams.get("t") || "0") || 0;
|
|
60003
60527
|
const fps = data2?.fps ?? 30;
|
|
60004
60528
|
const durationInSeconds = data2 ? getDurationInSeconds(data2, true) || 5 : 5;
|
|
60005
60529
|
const durationInFrames = Math.max(1, Math.ceil(durationInSeconds * fps));
|
|
60006
|
-
const loadData =
|
|
60007
|
-
setReady(false);
|
|
60530
|
+
const loadData = React55.useCallback((initial = false) => {
|
|
60531
|
+
if (initial) setReady(false);
|
|
60008
60532
|
const variant = window.VARIANT || "default";
|
|
60009
60533
|
const url2 = variant !== "default" ? `/api/video-data?variant=${variant}` : "/api/video-data";
|
|
60010
60534
|
fetch(url2).then((r) => r.json()).then((json2) => {
|
|
60011
60535
|
const root2 = json2.root || json2;
|
|
60012
60536
|
setData(root2);
|
|
60013
|
-
setReady(true);
|
|
60537
|
+
if (initial) setReady(true);
|
|
60014
60538
|
}).catch((e) => setError(e.message));
|
|
60015
60539
|
}, []);
|
|
60016
|
-
|
|
60017
|
-
loadData();
|
|
60018
|
-
const handler = () => {
|
|
60019
|
-
setRefreshKey((k2) => k2 + 1);
|
|
60020
|
-
};
|
|
60021
|
-
window.addEventListener("refresh-player", handler);
|
|
60540
|
+
React55.useEffect(() => {
|
|
60541
|
+
loadData(true);
|
|
60022
60542
|
return () => {
|
|
60023
60543
|
mountedRef.current = false;
|
|
60024
|
-
window.removeEventListener("refresh-player", handler);
|
|
60025
60544
|
};
|
|
60026
60545
|
}, [loadData]);
|
|
60027
|
-
|
|
60028
|
-
|
|
60029
|
-
|
|
60030
|
-
|
|
60031
|
-
|
|
60032
|
-
|
|
60546
|
+
React55.useEffect(() => {
|
|
60547
|
+
const handler = () => {
|
|
60548
|
+
if (playerRef.current) {
|
|
60549
|
+
pendingSeekRef.current = playerRef.current.getCurrentFrame();
|
|
60550
|
+
}
|
|
60551
|
+
loadData(false);
|
|
60552
|
+
};
|
|
60553
|
+
window.addEventListener("refresh-player", handler);
|
|
60554
|
+
return () => window.removeEventListener("refresh-player", handler);
|
|
60555
|
+
}, [loadData]);
|
|
60556
|
+
React55.useEffect(() => {
|
|
60557
|
+
if (!ready || !data2 || !playerRef.current) return;
|
|
60558
|
+
const targetFrame = pendingSeekRef.current ?? Math.round(startAt * fps);
|
|
60559
|
+
if (targetFrame > 0) {
|
|
60033
60560
|
const timer = setTimeout(() => {
|
|
60034
60561
|
if (!mountedRef.current || !playerRef.current) return;
|
|
60035
|
-
|
|
60036
|
-
|
|
60037
|
-
seekAttemptedRef.current = true;
|
|
60562
|
+
playerRef.current.seekTo(targetFrame);
|
|
60563
|
+
pendingSeekRef.current = null;
|
|
60038
60564
|
}, 100);
|
|
60039
60565
|
return () => clearTimeout(timer);
|
|
60040
60566
|
}
|
|
60041
|
-
|
|
60567
|
+
pendingSeekRef.current = null;
|
|
60042
60568
|
}, [ready, data2, startAt, fps]);
|
|
60043
|
-
|
|
60569
|
+
const handleFrameUpdate = React55.useCallback((frame) => {
|
|
60570
|
+
currentFrameRef.current = frame;
|
|
60571
|
+
setCurrentTime((prev) => {
|
|
60572
|
+
const newTime = frame / (data2?.fps ?? 30);
|
|
60573
|
+
return Math.abs(newTime - prev) > 0.5 ? newTime : prev;
|
|
60574
|
+
});
|
|
60575
|
+
}, [data2?.fps]);
|
|
60576
|
+
React55.useEffect(() => {
|
|
60044
60577
|
if (!ready || !playerRef.current) return;
|
|
60045
60578
|
const FWD_SECONDS = 5;
|
|
60046
60579
|
const BACK_SECONDS = 5;
|
|
@@ -60150,55 +60683,124 @@ function PlayerApp() {
|
|
|
60150
60683
|
window.addEventListener("keydown", onKey);
|
|
60151
60684
|
return () => window.removeEventListener("keydown", onKey);
|
|
60152
60685
|
}, [ready, data2, fps, durationInFrames, volume]);
|
|
60153
|
-
|
|
60154
|
-
|
|
60155
|
-
|
|
60156
|
-
|
|
60157
|
-
|
|
60686
|
+
const mode = (typeof window !== "undefined" ? window.MODE : null) || "preview";
|
|
60687
|
+
const [editStatus, setEditStatus] = React55.useState("");
|
|
60688
|
+
const [sseConnected, setSseConnected] = React55.useState(false);
|
|
60689
|
+
const [labelSceneInfo, setLabelSceneInfo] = React55.useState("");
|
|
60690
|
+
const suppressReloadRef = React55.useRef(false);
|
|
60691
|
+
React55.useEffect(() => {
|
|
60692
|
+
let evtSource = null;
|
|
60693
|
+
try {
|
|
60694
|
+
evtSource = new EventSource("/api/events");
|
|
60695
|
+
evtSource.onopen = () => setSseConnected(true);
|
|
60696
|
+
evtSource.onmessage = (e) => {
|
|
60697
|
+
try {
|
|
60698
|
+
const msg = JSON.parse(e.data);
|
|
60699
|
+
if (msg.type === "reload" && !suppressReloadRef.current) {
|
|
60700
|
+
window.dispatchEvent(new Event("refresh-player"));
|
|
60701
|
+
}
|
|
60702
|
+
} catch {
|
|
60703
|
+
}
|
|
60704
|
+
};
|
|
60705
|
+
evtSource.onerror = () => setSseConnected(false);
|
|
60706
|
+
} catch {
|
|
60707
|
+
setSseConnected(false);
|
|
60708
|
+
}
|
|
60709
|
+
return () => {
|
|
60710
|
+
evtSource?.close();
|
|
60711
|
+
setSseConnected(false);
|
|
60158
60712
|
};
|
|
60159
|
-
});
|
|
60713
|
+
}, []);
|
|
60160
60714
|
if (error49) {
|
|
60161
|
-
return
|
|
60162
|
-
|
|
60163
|
-
|
|
60715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { style: { color: "red", padding: 40, fontFamily: "sans-serif" }, children: [
|
|
60716
|
+
"Error: ",
|
|
60717
|
+
error49
|
|
60718
|
+
] });
|
|
60164
60719
|
}
|
|
60165
60720
|
if (!ready) {
|
|
60166
|
-
return
|
|
60167
|
-
style: { color: "#888", padding: 40, fontFamily: "sans-serif" }
|
|
60168
|
-
}, "Loading...");
|
|
60721
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { style: { color: "#888", padding: 40, fontFamily: "sans-serif" }, children: "Loading..." });
|
|
60169
60722
|
}
|
|
60170
60723
|
const width = data2.width || 1080;
|
|
60171
60724
|
const height = data2.height || 1920;
|
|
60172
|
-
return
|
|
60725
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
60173
60726
|
"div",
|
|
60174
60727
|
{
|
|
60175
|
-
style: {
|
|
60176
|
-
|
|
60177
|
-
|
|
60178
|
-
|
|
60179
|
-
|
|
60180
|
-
|
|
60181
|
-
|
|
60182
|
-
compose: {}
|
|
60728
|
+
style: {
|
|
60729
|
+
width: "100%",
|
|
60730
|
+
height: "100%",
|
|
60731
|
+
background: "#0a0a0a",
|
|
60732
|
+
display: "flex",
|
|
60733
|
+
flexDirection: "column",
|
|
60734
|
+
alignItems: "center"
|
|
60183
60735
|
},
|
|
60184
|
-
|
|
60185
|
-
|
|
60186
|
-
|
|
60187
|
-
|
|
60188
|
-
|
|
60189
|
-
|
|
60190
|
-
|
|
60191
|
-
|
|
60192
|
-
|
|
60193
|
-
|
|
60194
|
-
|
|
60195
|
-
|
|
60736
|
+
children: [
|
|
60737
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
60738
|
+
HeaderBar,
|
|
60739
|
+
{
|
|
60740
|
+
mode,
|
|
60741
|
+
editStatus,
|
|
60742
|
+
sseConnected,
|
|
60743
|
+
sceneInfo: mode === "label" ? labelSceneInfo : void 0
|
|
60744
|
+
}
|
|
60745
|
+
),
|
|
60746
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(VariantBar, {}),
|
|
60747
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { id: "player-frame", style: { flex: 1, width: "100%", maxWidth: 480, minHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
60748
|
+
Player,
|
|
60749
|
+
{
|
|
60750
|
+
ref: playerRef,
|
|
60751
|
+
component: MarkCut,
|
|
60752
|
+
inputProps: { root: data2, compose: {} },
|
|
60753
|
+
durationInFrames,
|
|
60754
|
+
fps,
|
|
60755
|
+
compositionWidth: width,
|
|
60756
|
+
compositionHeight: height,
|
|
60757
|
+
style: { width: "100%", height: "100%" },
|
|
60758
|
+
controls: true,
|
|
60759
|
+
showPlaybackRateControl: true,
|
|
60760
|
+
allowFullscreen: true,
|
|
60761
|
+
clickToPlay: false,
|
|
60762
|
+
doubleClickToFullscreen: true,
|
|
60763
|
+
autoPlay,
|
|
60764
|
+
onFrameUpdate: handleFrameUpdate
|
|
60765
|
+
}
|
|
60766
|
+
) }),
|
|
60767
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
60768
|
+
SceneThumbnails,
|
|
60769
|
+
{
|
|
60770
|
+
currentTime,
|
|
60771
|
+
onSeek: (t) => {
|
|
60772
|
+
if (playerRef.current) {
|
|
60773
|
+
const frame = Math.round(t * (data2?.fps ?? 30));
|
|
60774
|
+
playerRef.current.seekTo(frame);
|
|
60775
|
+
}
|
|
60776
|
+
}
|
|
60777
|
+
}
|
|
60778
|
+
),
|
|
60779
|
+
mode === "edit" && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
60780
|
+
EditControls,
|
|
60781
|
+
{
|
|
60782
|
+
onStatusChange: setEditStatus,
|
|
60783
|
+
suppressReloadRef,
|
|
60784
|
+
currentTime,
|
|
60785
|
+
activeScene
|
|
60786
|
+
}
|
|
60787
|
+
),
|
|
60788
|
+
mode === "label" && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
60789
|
+
LabelControls,
|
|
60790
|
+
{
|
|
60791
|
+
playerRef,
|
|
60792
|
+
currentTime,
|
|
60793
|
+
onSceneChange: setLabelSceneInfo
|
|
60794
|
+
}
|
|
60795
|
+
)
|
|
60796
|
+
]
|
|
60797
|
+
}
|
|
60196
60798
|
);
|
|
60197
60799
|
}
|
|
60198
60800
|
var container2 = document.getElementById("root");
|
|
60199
60801
|
if (container2) {
|
|
60200
60802
|
const root2 = (0, import_client.createRoot)(container2);
|
|
60201
|
-
root2.render(
|
|
60803
|
+
root2.render(React55.createElement(PlayerApp));
|
|
60202
60804
|
}
|
|
60203
60805
|
/*! Bundled license information:
|
|
60204
60806
|
|