remotion 4.0.460 → 4.0.462
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/dist/cjs/CompositionManager.d.ts +2 -2
- package/dist/cjs/HtmlInCanvas.d.ts +3 -1
- package/dist/cjs/HtmlInCanvas.js +15 -6
- package/dist/cjs/RemotionRoot.d.ts +0 -1
- package/dist/cjs/RemotionRoot.js +2 -2
- package/dist/cjs/Sequence.d.ts +2 -2
- package/dist/cjs/Sequence.js +3 -6
- package/dist/cjs/SequenceManager.d.ts +40 -19
- package/dist/cjs/SequenceManager.js +78 -46
- package/dist/cjs/bezier.js +5 -4
- package/dist/cjs/delete-nested-key.d.ts +1 -0
- package/dist/cjs/delete-nested-key.js +36 -0
- package/dist/cjs/easing.js +14 -8
- package/dist/cjs/effects/Solid.js +8 -2
- package/dist/cjs/effects/create-effect.d.ts +4 -0
- package/dist/cjs/effects/create-effect.js +24 -0
- package/dist/cjs/effects/define-effect.js +4 -1
- package/dist/cjs/effects/effect-internals.d.ts +3 -4
- package/dist/cjs/effects/effect-internals.js +1 -18
- package/dist/cjs/effects/effect-types.d.ts +16 -5
- package/dist/cjs/effects/index.d.ts +1 -1
- package/dist/cjs/effects/run-effect-chain.d.ts +2 -2
- package/dist/cjs/effects/run-effect-chain.js +1 -2
- package/dist/cjs/effects/use-memoized-effects.d.ts +27 -2
- package/dist/cjs/effects/use-memoized-effects.js +126 -7
- package/dist/cjs/find-props-to-delete.d.ts +6 -0
- package/dist/cjs/find-props-to-delete.js +37 -0
- package/dist/cjs/flatten-schema.js +4 -1
- package/dist/cjs/get-effective-visual-mode-value.d.ts +3 -4
- package/dist/cjs/get-effective-visual-mode-value.js +1 -7
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/internals.d.ts +73 -14
- package/dist/cjs/internals.js +14 -7
- package/dist/cjs/interpolate.d.ts +2 -1
- package/dist/cjs/interpolate.js +32 -3
- package/dist/cjs/no-react.d.ts +66 -3
- package/dist/cjs/no-react.js +6 -1
- package/dist/cjs/sequence-field-schema.d.ts +42 -1
- package/dist/cjs/sequence-field-schema.js +16 -0
- package/dist/cjs/sequence-node-path.d.ts +3 -3
- package/dist/cjs/use-schema.d.ts +14 -7
- package/dist/cjs/use-schema.js +31 -8
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wrap-in-schema.d.ts +2 -1
- package/dist/cjs/wrap-in-schema.js +17 -15
- package/dist/esm/index.mjs +621 -339
- package/dist/esm/no-react.mjs +132 -3
- package/dist/esm/version.mjs +1 -1
- package/package.json +2 -2
- package/dist/cjs/use-sequence-control-override.d.ts +0 -1
- package/dist/cjs/use-sequence-control-override.js +0 -16
|
@@ -3,7 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import type { AnyZodObject } from './any-zod-type.js';
|
|
4
4
|
import type { CalculateMetadataFunction } from './Composition.js';
|
|
5
5
|
import type { DownloadBehavior } from './download-behavior.js';
|
|
6
|
-
import type {
|
|
6
|
+
import type { EffectDefinition } from './effects/effect-types.js';
|
|
7
7
|
import type { NonceHistory } from './nonce.js';
|
|
8
8
|
import type { InferProps, PropsIfHasProps } from './props-if-has-props.js';
|
|
9
9
|
import type { SequenceSchema } from './sequence-field-schema.js';
|
|
@@ -69,7 +69,7 @@ export type TSequence = {
|
|
|
69
69
|
premountDisplay: number | null;
|
|
70
70
|
postmountDisplay: number | null;
|
|
71
71
|
controls: SequenceControls | null;
|
|
72
|
-
effects:
|
|
72
|
+
effects: readonly EffectDefinition<unknown>[];
|
|
73
73
|
} & EnhancedTSequenceData;
|
|
74
74
|
export type AudioOrVideoAsset = {
|
|
75
75
|
type: 'audio' | 'video';
|
|
@@ -42,10 +42,12 @@ export type HtmlInCanvasOnPaintParams = {
|
|
|
42
42
|
readonly elementImage: ElementImage;
|
|
43
43
|
};
|
|
44
44
|
export declare const isHtmlInCanvasSupported: () => boolean;
|
|
45
|
+
/** Shown when {@link isHtmlInCanvasSupported} is false: APIs are absent (old Chrome and/or flag off). */
|
|
46
|
+
export declare const HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = "HTML in Canvas is not supported. Two common causes: Chrome is older than version 148 (update Chrome), or the HTML-in-Canvas flag is disabled at chrome://flags/#canvas-draw-element (enable it and restart Chrome).";
|
|
45
47
|
export type HtmlInCanvasOnPaint = (params: HtmlInCanvasOnPaintParams) => void | Promise<void>;
|
|
46
48
|
export type HtmlInCanvasOnInitCleanup = () => void;
|
|
47
49
|
export type HtmlInCanvasOnInit = (params: HtmlInCanvasOnPaintParams) => HtmlInCanvasOnInitCleanup | Promise<HtmlInCanvasOnInitCleanup>;
|
|
48
|
-
export type HtmlInCanvasProps = Omit<SequenceProps, 'children' | 'durationInFrames' | keyof LayoutAndStyle> & Omit<AbsoluteFillLayout, 'layout' | 'styleWhilePostmounted' | 'postmountFor' | 'premountFor' | 'styleWhilePremounted'> & {
|
|
50
|
+
export type HtmlInCanvasProps = Omit<SequenceProps, 'children' | 'durationInFrames' | keyof LayoutAndStyle | '_experimentalEffects'> & Omit<AbsoluteFillLayout, 'layout' | 'styleWhilePostmounted' | 'postmountFor' | 'premountFor' | 'styleWhilePremounted'> & {
|
|
49
51
|
readonly durationInFrames?: number;
|
|
50
52
|
readonly width: number;
|
|
51
53
|
readonly height: number;
|
package/dist/cjs/HtmlInCanvas.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HtmlInCanvas = exports.isHtmlInCanvasSupported = void 0;
|
|
3
|
+
exports.HtmlInCanvas = exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = exports.isHtmlInCanvasSupported = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const delay_render_js_1 = require("./delay-render.js");
|
|
7
7
|
const run_effect_chain_js_1 = require("./effects/run-effect-chain.js");
|
|
8
8
|
const use_effect_chain_state_js_1 = require("./effects/use-effect-chain-state.js");
|
|
9
|
+
const use_memoized_effects_js_1 = require("./effects/use-memoized-effects.js");
|
|
9
10
|
const enable_sequence_stack_traces_js_1 = require("./enable-sequence-stack-traces.js");
|
|
10
11
|
const sequence_field_schema_js_1 = require("./sequence-field-schema.js");
|
|
11
12
|
const Sequence_js_1 = require("./Sequence.js");
|
|
@@ -33,6 +34,8 @@ const isHtmlInCanvasSupported = () => {
|
|
|
33
34
|
return cachedSupport;
|
|
34
35
|
};
|
|
35
36
|
exports.isHtmlInCanvasSupported = isHtmlInCanvasSupported;
|
|
37
|
+
/** Shown when {@link isHtmlInCanvasSupported} is false: APIs are absent (old Chrome and/or flag off). */
|
|
38
|
+
exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE = 'HTML in Canvas is not supported. Two common causes: Chrome is older than version 148 (update Chrome), or the HTML-in-Canvas flag is disabled at chrome://flags/#canvas-draw-element (enable it and restart Chrome).';
|
|
36
39
|
function assertHtmlInCanvasDimensions(width, height) {
|
|
37
40
|
if (typeof width !== 'number' || typeof height !== 'number') {
|
|
38
41
|
throw new Error(`HtmlInCanvas: \`width\` and \`height\` must be numbers. Received width=${String(width)}, height=${String(height)}.`);
|
|
@@ -56,11 +59,12 @@ const defaultOnPaint = ({ canvas, element, elementImage, }) => {
|
|
|
56
59
|
/* eslint-enable react/require-default-props */
|
|
57
60
|
const HtmlInCanvasAncestorContext = (0, react_1.createContext)(false);
|
|
58
61
|
const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, _experimentalEffects: effects = [], children, onPaint, onInit, _experimentalControls: controls, style, durationInFrames, ...sequenceProps }, ref) => {
|
|
62
|
+
var _a;
|
|
59
63
|
const isInsideAncestorHtmlInCanvas = (0, react_1.useContext)(HtmlInCanvasAncestorContext);
|
|
60
64
|
assertHtmlInCanvasDimensions(width, height);
|
|
61
65
|
const { continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
|
|
62
66
|
if (!(0, exports.isHtmlInCanvasSupported)()) {
|
|
63
|
-
cancelRender(new Error(
|
|
67
|
+
cancelRender(new Error(exports.HTML_IN_CANVAS_UNSUPPORTED_MESSAGE));
|
|
64
68
|
}
|
|
65
69
|
const { durationInFrames: videoDuration } = (0, use_video_config_js_1.useVideoConfig)();
|
|
66
70
|
const resolvedDuration = durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : videoDuration;
|
|
@@ -79,9 +83,14 @@ const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, _experimenta
|
|
|
79
83
|
}, [ref]);
|
|
80
84
|
const [offscreenCanvas] = (0, react_1.useState)(() => new OffscreenCanvas(1, 1));
|
|
81
85
|
const chainState = (0, use_effect_chain_state_js_1.useEffectChainState)();
|
|
86
|
+
const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)({
|
|
87
|
+
effects,
|
|
88
|
+
overrideId: (_a = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _a !== void 0 ? _a : null,
|
|
89
|
+
});
|
|
90
|
+
const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(effects);
|
|
82
91
|
// Refs so the paint handler always reads fresh values.
|
|
83
|
-
const effectsRef = (0, react_1.useRef)(
|
|
84
|
-
effectsRef.current =
|
|
92
|
+
const effectsRef = (0, react_1.useRef)(memoizedEffects);
|
|
93
|
+
effectsRef.current = memoizedEffects;
|
|
85
94
|
const frameRef = (0, react_1.useRef)(frame);
|
|
86
95
|
frameRef.current = frame;
|
|
87
96
|
const onPaintRef = (0, react_1.useRef)(onPaint);
|
|
@@ -198,7 +207,7 @@ const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, _experimenta
|
|
|
198
207
|
return;
|
|
199
208
|
}
|
|
200
209
|
(_a = canvas.requestPaint) === null || _a === void 0 ? void 0 : _a.call(canvas);
|
|
201
|
-
}, [onPaint]);
|
|
210
|
+
}, [onPaint, memoizedEffects]);
|
|
202
211
|
(0, react_1.useLayoutEffect)(() => {
|
|
203
212
|
const canvas = canvas2dRef.current;
|
|
204
213
|
if (!canvas) {
|
|
@@ -221,7 +230,7 @@ const HtmlInCanvasInner = (0, react_1.forwardRef)(({ width, height, _experimenta
|
|
|
221
230
|
if (isInsideAncestorHtmlInCanvas) {
|
|
222
231
|
throw new Error('<HtmlInCanvas> effects cannot be nested together. Chrome will only display the outer effect. Consider merging the effects into one if you can.');
|
|
223
232
|
}
|
|
224
|
-
return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { durationInFrames: resolvedDuration, name: "<HtmlInCanvas>", _experimentalControls: controls, _experimentalEffects:
|
|
233
|
+
return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { durationInFrames: resolvedDuration, name: "<HtmlInCanvas>", _experimentalControls: controls, _experimentalEffects: memoizedEffectDefinitions, layout: "none", ...sequenceProps, children: (0, jsx_runtime_1.jsx)(HtmlInCanvasAncestorContext.Provider, { value: true, children: (0, jsx_runtime_1.jsx)("canvas", { ref: setLayoutCanvasRef, width: width, height: height, style: style, children: (0, jsx_runtime_1.jsx)("div", { ref: divRef, style: innerStyle, children: children }) }) }) }));
|
|
225
234
|
});
|
|
226
235
|
HtmlInCanvasInner.displayName = 'HtmlInCanvas';
|
|
227
236
|
const HtmlInCanvasWrapped = (0, wrap_in_schema_js_1.wrapInSchema)(HtmlInCanvasInner, sequence_field_schema_js_1.sequenceStyleSchema);
|
package/dist/cjs/RemotionRoot.js
CHANGED
|
@@ -13,7 +13,7 @@ const SequenceManager_js_1 = require("./SequenceManager.js");
|
|
|
13
13
|
const TimelineContext_js_1 = require("./TimelineContext.js");
|
|
14
14
|
const use_media_enabled_js_1 = require("./use-media-enabled.js");
|
|
15
15
|
const duration_state_js_1 = require("./video/duration-state.js");
|
|
16
|
-
const RemotionRootContexts = ({ children, numberOfAudioTags, logLevel, audioLatencyHint, videoEnabled, audioEnabled, frameState,
|
|
16
|
+
const RemotionRootContexts = ({ children, numberOfAudioTags, logLevel, audioLatencyHint, videoEnabled, audioEnabled, frameState, }) => {
|
|
17
17
|
const nonceContext = (0, react_1.useMemo)(() => {
|
|
18
18
|
let counter = 0;
|
|
19
19
|
return {
|
|
@@ -23,6 +23,6 @@ const RemotionRootContexts = ({ children, numberOfAudioTags, logLevel, audioLate
|
|
|
23
23
|
const logging = (0, react_1.useMemo)(() => {
|
|
24
24
|
return { logLevel, mountTime: Date.now() };
|
|
25
25
|
}, [logLevel]);
|
|
26
|
-
return ((0, jsx_runtime_1.jsx)(log_level_context_js_1.LogLevelContext.Provider, { value: logging, children: (0, jsx_runtime_1.jsx)(nonce_js_1.NonceContext.Provider, { value: nonceContext, children: (0, jsx_runtime_1.jsx)(TimelineContext_js_1.TimelineContextProvider, { frameState: frameState, children: (0, jsx_runtime_1.jsx)(use_media_enabled_js_1.MediaEnabledProvider, { videoEnabled: videoEnabled, audioEnabled: audioEnabled, children: (0, jsx_runtime_1.jsx)(EditorProps_js_1.EditorPropsProvider, { children: (0, jsx_runtime_1.jsx)(prefetch_state_js_1.PrefetchProvider, { children: (0, jsx_runtime_1.jsx)(SequenceManager_js_1.SequenceManagerProvider, {
|
|
26
|
+
return ((0, jsx_runtime_1.jsx)(log_level_context_js_1.LogLevelContext.Provider, { value: logging, children: (0, jsx_runtime_1.jsx)(nonce_js_1.NonceContext.Provider, { value: nonceContext, children: (0, jsx_runtime_1.jsx)(TimelineContext_js_1.TimelineContextProvider, { frameState: frameState, children: (0, jsx_runtime_1.jsx)(use_media_enabled_js_1.MediaEnabledProvider, { videoEnabled: videoEnabled, audioEnabled: audioEnabled, children: (0, jsx_runtime_1.jsx)(EditorProps_js_1.EditorPropsProvider, { children: (0, jsx_runtime_1.jsx)(prefetch_state_js_1.PrefetchProvider, { children: (0, jsx_runtime_1.jsx)(SequenceManager_js_1.SequenceManagerProvider, { children: (0, jsx_runtime_1.jsx)(duration_state_js_1.DurationsContextProvider, { children: (0, jsx_runtime_1.jsx)(buffering_js_1.BufferingProvider, { children: (0, jsx_runtime_1.jsx)(shared_audio_tags_js_1.SharedAudioContextProvider, { audioLatencyHint: audioLatencyHint, audioEnabled: audioEnabled, children: (0, jsx_runtime_1.jsx)(shared_audio_tags_js_1.SharedAudioTagsContextProvider, { numberOfAudioTags: numberOfAudioTags, children: children }) }) }) }) }) }) }) }) }) }) }));
|
|
27
27
|
};
|
|
28
28
|
exports.RemotionRootContexts = RemotionRootContexts;
|
package/dist/cjs/Sequence.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { LoopDisplay, SequenceControls } from './CompositionManager.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { EffectDefinition } from './effects/effect-types.js';
|
|
4
4
|
import type { BasicMediaInTimelineReturnType } from './use-media-in-timeline.js';
|
|
5
5
|
export type AbsoluteFillLayout = {
|
|
6
6
|
layout?: 'absolute-fill';
|
|
@@ -22,7 +22,7 @@ export type SequencePropsWithoutDuration = {
|
|
|
22
22
|
readonly name?: string;
|
|
23
23
|
readonly showInTimeline?: boolean;
|
|
24
24
|
readonly _experimentalControls?: SequenceControls;
|
|
25
|
-
readonly _experimentalEffects?:
|
|
25
|
+
readonly _experimentalEffects?: readonly EffectDefinition<unknown>[];
|
|
26
26
|
/**
|
|
27
27
|
* @deprecated For internal use only.
|
|
28
28
|
*/
|
package/dist/cjs/Sequence.js
CHANGED
|
@@ -5,8 +5,6 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
6
6
|
const react_1 = require("react");
|
|
7
7
|
const AbsoluteFill_js_1 = require("./AbsoluteFill.js");
|
|
8
|
-
const effect_internals_js_1 = require("./effects/effect-internals.js");
|
|
9
|
-
const use_memoized_effects_js_1 = require("./effects/use-memoized-effects.js");
|
|
10
8
|
const freeze_js_1 = require("./freeze.js");
|
|
11
9
|
const nonce_js_1 = require("./nonce.js");
|
|
12
10
|
const PremountContext_js_1 = require("./PremountContext.js");
|
|
@@ -101,7 +99,6 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Inf
|
|
|
101
99
|
}, [name]);
|
|
102
100
|
const env = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
|
|
103
101
|
const inheritedStack = (_a = other === null || other === void 0 ? void 0 : other.stack) !== null && _a !== void 0 ? _a : null;
|
|
104
|
-
const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)((0, effect_internals_js_1.flattenEffects)(_experimentalEffects !== null && _experimentalEffects !== void 0 ? _experimentalEffects : []));
|
|
105
102
|
(0, react_1.useEffect)(() => {
|
|
106
103
|
var _a, _b;
|
|
107
104
|
if (!env.isStudio) {
|
|
@@ -111,7 +108,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Inf
|
|
|
111
108
|
registerSequence({
|
|
112
109
|
type: isMedia.type,
|
|
113
110
|
controls: controls !== null && controls !== void 0 ? controls : null,
|
|
114
|
-
effects:
|
|
111
|
+
effects: _experimentalEffects !== null && _experimentalEffects !== void 0 ? _experimentalEffects : [],
|
|
115
112
|
displayName: timelineClipName,
|
|
116
113
|
doesVolumeChange: isMedia.data.doesVolumeChange,
|
|
117
114
|
duration: actualDurationInFrames,
|
|
@@ -149,7 +146,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Inf
|
|
|
149
146
|
premountDisplay: premountDisplay !== null && premountDisplay !== void 0 ? premountDisplay : null,
|
|
150
147
|
postmountDisplay: postmountDisplay !== null && postmountDisplay !== void 0 ? postmountDisplay : null,
|
|
151
148
|
controls: controls !== null && controls !== void 0 ? controls : null,
|
|
152
|
-
effects:
|
|
149
|
+
effects: _experimentalEffects !== null && _experimentalEffects !== void 0 ? _experimentalEffects : [],
|
|
153
150
|
});
|
|
154
151
|
return () => {
|
|
155
152
|
unregisterSequence(id);
|
|
@@ -174,7 +171,7 @@ const RegularSequenceRefForwardingFunction = ({ from = 0, durationInFrames = Inf
|
|
|
174
171
|
env.isStudio,
|
|
175
172
|
inheritedStack,
|
|
176
173
|
controls,
|
|
177
|
-
|
|
174
|
+
_experimentalEffects,
|
|
178
175
|
isMedia,
|
|
179
176
|
]);
|
|
180
177
|
// Ceil to support floats
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { TSequence } from './CompositionManager.js';
|
|
3
|
-
import type { CanUpdateSequencePropStatus, CodeValues,
|
|
3
|
+
import type { CanUpdateSequencePropStatus, CodeValues, GetDragOverrides, GetEffectDragOverrides } from './use-schema.js';
|
|
4
4
|
export type SequenceManagerContext = {
|
|
5
5
|
registerSequence: (seq: TSequence) => void;
|
|
6
6
|
unregisterSequence: (id: string) => void;
|
|
@@ -13,33 +13,54 @@ export type SequenceVisibilityToggleState = {
|
|
|
13
13
|
setHidden: React.Dispatch<React.SetStateAction<Record<string, boolean>>>;
|
|
14
14
|
};
|
|
15
15
|
export declare const SequenceVisibilityToggleContext: React.Context<SequenceVisibilityToggleState>;
|
|
16
|
-
export type
|
|
17
|
-
|
|
16
|
+
export type VisualModeCodeValues = {
|
|
17
|
+
codeValues: CodeValues;
|
|
18
|
+
};
|
|
19
|
+
export type VisualModeDragOverrides = {
|
|
18
20
|
getDragOverrides: GetDragOverrides;
|
|
19
|
-
|
|
20
|
-
getIsJsxInMapCallback: (nodePath: SequenceNodePath) => boolean;
|
|
21
|
+
getEffectDragOverrides: GetEffectDragOverrides;
|
|
21
22
|
};
|
|
22
23
|
export type VisualModeSetters = {
|
|
23
|
-
setDragOverrides: (nodePath:
|
|
24
|
-
clearDragOverrides: (nodePath:
|
|
25
|
-
|
|
24
|
+
setDragOverrides: (nodePath: SequencePropsSubscriptionKey, key: string, value: unknown) => void;
|
|
25
|
+
clearDragOverrides: (nodePath: SequencePropsSubscriptionKey) => void;
|
|
26
|
+
setEffectDragOverrides: (nodePath: SequencePropsSubscriptionKey, effectIndex: number, key: string, value: unknown) => void;
|
|
27
|
+
clearEffectDragOverrides: (nodePath: SequencePropsSubscriptionKey, effectIndex: number) => void;
|
|
28
|
+
setCodeValues: (nodePath: SequencePropsSubscriptionKey, values: (prev: CanUpdateSequencePropsResponse) => CanUpdateSequencePropsResponse) => void;
|
|
26
29
|
};
|
|
27
|
-
export type
|
|
30
|
+
export type CanUpdateEffectPropsResponseTrue = {
|
|
28
31
|
canUpdate: true;
|
|
32
|
+
callee: string;
|
|
33
|
+
effectIndex: number;
|
|
29
34
|
props: Record<string, CanUpdateSequencePropStatus>;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
};
|
|
36
|
+
export type CannotUpdateEffectReason = 'not-found' | 'computed' | 'not-call-expression';
|
|
37
|
+
export type CannotUpdateSequenceReason = 'not-found' | 'error';
|
|
38
|
+
export type CanUpdateEffectPropsResponseFalse = {
|
|
39
|
+
canUpdate: false;
|
|
40
|
+
effectIndex: number;
|
|
41
|
+
reason: CannotUpdateEffectReason;
|
|
42
|
+
};
|
|
43
|
+
export type CanUpdateEffectPropsResponse = CanUpdateEffectPropsResponseTrue | CanUpdateEffectPropsResponseFalse;
|
|
44
|
+
export type CanUpdateSequencePropsResponseTrue = {
|
|
45
|
+
canUpdate: true;
|
|
46
|
+
props: Record<string, CanUpdateSequencePropStatus>;
|
|
47
|
+
effects: CanUpdateEffectPropsResponse[];
|
|
48
|
+
};
|
|
49
|
+
export type CanUpdateSequencePropsResponseFalse = {
|
|
34
50
|
canUpdate: false;
|
|
35
|
-
reason:
|
|
51
|
+
reason: CannotUpdateSequenceReason;
|
|
36
52
|
};
|
|
37
|
-
|
|
38
|
-
export
|
|
39
|
-
export declare const
|
|
53
|
+
export type CanUpdateSequencePropsResponse = CanUpdateSequencePropsResponseTrue | CanUpdateSequencePropsResponseFalse;
|
|
54
|
+
export declare const makeSequencePropsSubscriptionKey: (key: SequencePropsSubscriptionKey) => string;
|
|
55
|
+
export declare const VisualModeCodeValuesContext: React.Context<VisualModeCodeValues>;
|
|
56
|
+
export declare const VisualModeDragOverridesContext: React.Context<VisualModeDragOverrides>;
|
|
40
57
|
export declare const VisualModeSettersContext: React.Context<VisualModeSetters>;
|
|
58
|
+
export type SequencePropsSubscriptionKey = {
|
|
59
|
+
absolutePath: string;
|
|
60
|
+
nodePath: SequenceNodePath;
|
|
61
|
+
sequenceKeys: string[];
|
|
62
|
+
effectKeys: string[][];
|
|
63
|
+
};
|
|
41
64
|
export declare const SequenceManagerProvider: React.FC<{
|
|
42
65
|
readonly children: React.ReactNode;
|
|
43
|
-
readonly visualModeEnabled: boolean;
|
|
44
66
|
}>;
|
|
45
|
-
export {};
|
|
@@ -33,12 +33,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.SequenceManagerProvider = exports.VisualModeSettersContext = exports.
|
|
36
|
+
exports.SequenceManagerProvider = exports.VisualModeSettersContext = exports.VisualModeDragOverridesContext = exports.VisualModeCodeValuesContext = exports.makeSequencePropsSubscriptionKey = exports.SequenceVisibilityToggleContext = exports.SequenceManager = void 0;
|
|
37
37
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
38
|
const react_1 = __importStar(require("react"));
|
|
39
|
-
const nodePathToString = (nodePath) => {
|
|
40
|
-
return nodePath.join('.');
|
|
41
|
-
};
|
|
42
39
|
exports.SequenceManager = react_1.default.createContext({
|
|
43
40
|
registerSequence: () => {
|
|
44
41
|
throw new Error('SequenceManagerContext not initialized');
|
|
@@ -54,37 +51,20 @@ exports.SequenceVisibilityToggleContext = react_1.default.createContext({
|
|
|
54
51
|
throw new Error('SequenceVisibilityToggle not initialized');
|
|
55
52
|
},
|
|
56
53
|
});
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
if (!status) {
|
|
60
|
-
return undefined;
|
|
61
|
-
}
|
|
62
|
-
if (!status.canUpdate) {
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
return status.props;
|
|
66
|
-
};
|
|
67
|
-
const getIsJsxInMapCallback = (codeValues, nodePath) => {
|
|
68
|
-
const status = codeValues[nodePathToString(nodePath)];
|
|
69
|
-
if (!status) {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
if (!status.canUpdate) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
return status.jsxInMapCallback;
|
|
54
|
+
const makeSequencePropsSubscriptionKey = (key) => {
|
|
55
|
+
return `${key.nodePath.join('.')}.${key.sequenceKeys.join('.')}.${key.effectKeys.map((keys) => keys.join('.')).join('.')}`;
|
|
76
56
|
};
|
|
77
|
-
exports.
|
|
57
|
+
exports.makeSequencePropsSubscriptionKey = makeSequencePropsSubscriptionKey;
|
|
58
|
+
exports.VisualModeCodeValuesContext = react_1.default.createContext({
|
|
59
|
+
codeValues: {},
|
|
60
|
+
});
|
|
61
|
+
exports.VisualModeDragOverridesContext = react_1.default.createContext({
|
|
78
62
|
getDragOverrides: () => {
|
|
79
|
-
throw new Error('
|
|
80
|
-
},
|
|
81
|
-
getCodeValues: () => {
|
|
82
|
-
throw new Error('VisualModeGettersContext not initialized');
|
|
63
|
+
throw new Error('VisualModeDragOverridesContext not initialized');
|
|
83
64
|
},
|
|
84
|
-
|
|
85
|
-
throw new Error('
|
|
65
|
+
getEffectDragOverrides: () => {
|
|
66
|
+
throw new Error('VisualModeDragOverridesContext not initialized');
|
|
86
67
|
},
|
|
87
|
-
visualModeEnabled: false,
|
|
88
68
|
});
|
|
89
69
|
exports.VisualModeSettersContext = react_1.default.createContext({
|
|
90
70
|
setDragOverrides: () => {
|
|
@@ -93,29 +73,37 @@ exports.VisualModeSettersContext = react_1.default.createContext({
|
|
|
93
73
|
clearDragOverrides: () => {
|
|
94
74
|
throw new Error('VisualModeSettersContext not initialized');
|
|
95
75
|
},
|
|
76
|
+
setEffectDragOverrides: () => {
|
|
77
|
+
throw new Error('VisualModeSettersContext not initialized');
|
|
78
|
+
},
|
|
79
|
+
clearEffectDragOverrides: () => {
|
|
80
|
+
throw new Error('VisualModeSettersContext not initialized');
|
|
81
|
+
},
|
|
96
82
|
setCodeValues: () => {
|
|
97
83
|
throw new Error('VisualModeSettersContext not initialized');
|
|
98
84
|
},
|
|
99
85
|
});
|
|
100
|
-
const
|
|
86
|
+
const effectDragOverridesKey = (nodePath, effectIndex) => `${(0, exports.makeSequencePropsSubscriptionKey)(nodePath)}.effects.${effectIndex}`;
|
|
87
|
+
const SequenceManagerProvider = ({ children }) => {
|
|
101
88
|
const [sequences, setSequences] = (0, react_1.useState)([]);
|
|
102
89
|
const [hidden, setHidden] = (0, react_1.useState)({});
|
|
103
90
|
const [dragOverrides, setControlOverrides] = (0, react_1.useState)({});
|
|
104
91
|
const controlOverridesRef = (0, react_1.useRef)(dragOverrides);
|
|
105
92
|
controlOverridesRef.current = dragOverrides;
|
|
93
|
+
const [effectDragOverridesState, setEffectDragOverridesState] = (0, react_1.useState)({});
|
|
106
94
|
const [codeValues, setCodeValuesMapState] = (0, react_1.useState)({});
|
|
107
95
|
const setDragOverrides = (0, react_1.useCallback)((nodePath, key, value) => {
|
|
108
96
|
setControlOverrides((prev) => ({
|
|
109
97
|
...prev,
|
|
110
|
-
[
|
|
111
|
-
...prev[
|
|
98
|
+
[(0, exports.makeSequencePropsSubscriptionKey)(nodePath)]: {
|
|
99
|
+
...prev[(0, exports.makeSequencePropsSubscriptionKey)(nodePath)],
|
|
112
100
|
[key]: value,
|
|
113
101
|
},
|
|
114
102
|
}));
|
|
115
103
|
}, []);
|
|
116
104
|
const clearDragOverrides = (0, react_1.useCallback)((nodePath) => {
|
|
117
105
|
setControlOverrides((prev) => {
|
|
118
|
-
const key =
|
|
106
|
+
const key = (0, exports.makeSequencePropsSubscriptionKey)(nodePath);
|
|
119
107
|
if (!prev[key]) {
|
|
120
108
|
return prev;
|
|
121
109
|
}
|
|
@@ -124,13 +112,38 @@ const SequenceManagerProvider = ({ children, visualModeEnabled }) => {
|
|
|
124
112
|
return next;
|
|
125
113
|
});
|
|
126
114
|
}, []);
|
|
115
|
+
const setEffectDragOverrides = (0, react_1.useCallback)((nodePath, effectIndex, key, value) => {
|
|
116
|
+
setEffectDragOverridesState((prev) => {
|
|
117
|
+
const mapKey = effectDragOverridesKey(nodePath, effectIndex);
|
|
118
|
+
return {
|
|
119
|
+
...prev,
|
|
120
|
+
[mapKey]: {
|
|
121
|
+
...prev[mapKey],
|
|
122
|
+
[key]: value,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
});
|
|
126
|
+
}, []);
|
|
127
|
+
const clearEffectDragOverrides = (0, react_1.useCallback)((nodePath, effectIndex) => {
|
|
128
|
+
setEffectDragOverridesState((prev) => {
|
|
129
|
+
const mapKey = effectDragOverridesKey(nodePath, effectIndex);
|
|
130
|
+
if (!prev[mapKey]) {
|
|
131
|
+
return prev;
|
|
132
|
+
}
|
|
133
|
+
const next = { ...prev };
|
|
134
|
+
delete next[mapKey];
|
|
135
|
+
return next;
|
|
136
|
+
});
|
|
137
|
+
}, []);
|
|
127
138
|
const setCodeValues = (0, react_1.useCallback)((nodePath, values) => {
|
|
128
139
|
setCodeValuesMapState((prev) => {
|
|
129
|
-
const key =
|
|
130
|
-
|
|
140
|
+
const key = (0, exports.makeSequencePropsSubscriptionKey)(nodePath);
|
|
141
|
+
const prevKey = prev[key];
|
|
142
|
+
const newKey = values(prevKey);
|
|
143
|
+
if (prevKey === newKey) {
|
|
131
144
|
return prev;
|
|
132
145
|
}
|
|
133
|
-
return { ...prev, [key]:
|
|
146
|
+
return { ...prev, [key]: newKey };
|
|
134
147
|
});
|
|
135
148
|
}, []);
|
|
136
149
|
const registerSequence = (0, react_1.useCallback)((seq) => {
|
|
@@ -154,21 +167,40 @@ const SequenceManagerProvider = ({ children, visualModeEnabled }) => {
|
|
|
154
167
|
setHidden,
|
|
155
168
|
};
|
|
156
169
|
}, [hidden]);
|
|
157
|
-
const
|
|
170
|
+
const getDragOverrides = (0, react_1.useCallback)((nodePath) => {
|
|
171
|
+
var _a;
|
|
172
|
+
return (_a = dragOverrides[(0, exports.makeSequencePropsSubscriptionKey)(nodePath)]) !== null && _a !== void 0 ? _a : {};
|
|
173
|
+
}, [dragOverrides]);
|
|
174
|
+
const getEffectDragOverrides = (0, react_1.useCallback)((nodePath, effectIndex) => {
|
|
175
|
+
var _a;
|
|
176
|
+
return ((_a = effectDragOverridesState[effectDragOverridesKey(nodePath, effectIndex)]) !== null && _a !== void 0 ? _a : {});
|
|
177
|
+
}, [effectDragOverridesState]);
|
|
178
|
+
const codeValuesContext = (0, react_1.useMemo)(() => {
|
|
179
|
+
return {
|
|
180
|
+
codeValues,
|
|
181
|
+
};
|
|
182
|
+
}, [codeValues]);
|
|
183
|
+
const dragOverridesContext = (0, react_1.useMemo)(() => {
|
|
158
184
|
return {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
getCodeValues: (nodePath) => getCodeValues(codeValues, nodePath),
|
|
162
|
-
getIsJsxInMapCallback: (nodePath) => getIsJsxInMapCallback(codeValues, nodePath),
|
|
185
|
+
getDragOverrides,
|
|
186
|
+
getEffectDragOverrides,
|
|
163
187
|
};
|
|
164
|
-
}, [
|
|
188
|
+
}, [getDragOverrides, getEffectDragOverrides]);
|
|
165
189
|
const settersContext = (0, react_1.useMemo)(() => {
|
|
166
190
|
return {
|
|
167
191
|
setDragOverrides,
|
|
168
192
|
clearDragOverrides,
|
|
193
|
+
setEffectDragOverrides,
|
|
194
|
+
clearEffectDragOverrides,
|
|
169
195
|
setCodeValues,
|
|
170
196
|
};
|
|
171
|
-
}, [
|
|
172
|
-
|
|
197
|
+
}, [
|
|
198
|
+
setDragOverrides,
|
|
199
|
+
clearDragOverrides,
|
|
200
|
+
setEffectDragOverrides,
|
|
201
|
+
clearEffectDragOverrides,
|
|
202
|
+
setCodeValues,
|
|
203
|
+
]);
|
|
204
|
+
return ((0, jsx_runtime_1.jsx)(exports.SequenceManager.Provider, { value: sequenceContext, children: (0, jsx_runtime_1.jsx)(exports.SequenceVisibilityToggleContext.Provider, { value: hiddenContext, children: (0, jsx_runtime_1.jsx)(exports.VisualModeCodeValuesContext.Provider, { value: codeValuesContext, children: (0, jsx_runtime_1.jsx)(exports.VisualModeDragOverridesContext.Provider, { value: dragOverridesContext, children: (0, jsx_runtime_1.jsx)(exports.VisualModeSettersContext.Provider, { value: settersContext, children: children }) }) }) }) }));
|
|
173
205
|
};
|
|
174
206
|
exports.SequenceManagerProvider = SequenceManagerProvider;
|
package/dist/cjs/bezier.js
CHANGED
|
@@ -98,16 +98,17 @@ function bezier(mX1, mY1, mX2, mY2) {
|
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
100
|
return function (x) {
|
|
101
|
+
const clampedX = Math.min(1, Math.max(0, x));
|
|
101
102
|
if (mX1 === mY1 && mX2 === mY2) {
|
|
102
|
-
return
|
|
103
|
+
return clampedX; // linear
|
|
103
104
|
}
|
|
104
105
|
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
|
|
105
|
-
if (
|
|
106
|
+
if (clampedX === 0) {
|
|
106
107
|
return 0;
|
|
107
108
|
}
|
|
108
|
-
if (
|
|
109
|
+
if (clampedX === 1) {
|
|
109
110
|
return 1;
|
|
110
111
|
}
|
|
111
|
-
return calcBezier(getTForX(
|
|
112
|
+
return calcBezier(getTForX(clampedX), mY1, mY2);
|
|
112
113
|
};
|
|
113
114
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const deleteNestedKey: (obj: Record<string, unknown>, keysToRemove: Set<string>) => Record<string, unknown>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteNestedKey = void 0;
|
|
4
|
+
const deleteNestedKey = (obj, keysToRemove) => {
|
|
5
|
+
for (const key of keysToRemove) {
|
|
6
|
+
const parts = key.split('.');
|
|
7
|
+
const parents = [obj];
|
|
8
|
+
let current = obj;
|
|
9
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
10
|
+
const part = parts[i];
|
|
11
|
+
const next = current[part];
|
|
12
|
+
if (next === undefined || next === null) {
|
|
13
|
+
current = null;
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
current = next;
|
|
17
|
+
parents.push(current);
|
|
18
|
+
}
|
|
19
|
+
if (current === null) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
delete current[parts[parts.length - 1]];
|
|
23
|
+
for (let i = parents.length - 1; i > 0; i--) {
|
|
24
|
+
const parent = parents[i];
|
|
25
|
+
if (Object.keys(parent).length === 0) {
|
|
26
|
+
const parentKey = parts[i - 1];
|
|
27
|
+
delete parents[i - 1][parentKey];
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return obj;
|
|
35
|
+
};
|
|
36
|
+
exports.deleteNestedKey = deleteNestedKey;
|
package/dist/cjs/easing.js
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.Easing = void 0;
|
|
5
5
|
const bezier_js_1 = require("./bezier.js");
|
|
6
|
+
// Some easing curves are only defined on [0, 1] (e.g. quarter circle, bounce segments).
|
|
7
|
+
// `interpolate(..., { extrapolate: 'extend' })` can pass values outside that interval; clamp
|
|
8
|
+
// there so we return endpoints instead of NaN or unintended extrapolation.
|
|
9
|
+
const clampUnit = (t) => Math.min(1, Math.max(0, t));
|
|
6
10
|
/**
|
|
7
11
|
* @description The Easing module implements common easing functions. You can use it with the interpolate() API.
|
|
8
12
|
* @see [Documentation](https://www.remotion.dev/docs/easing)
|
|
@@ -33,7 +37,8 @@ class Easing {
|
|
|
33
37
|
return 1 - Math.cos((t * Math.PI) / 2);
|
|
34
38
|
}
|
|
35
39
|
static circle(t) {
|
|
36
|
-
|
|
40
|
+
const u = clampUnit(t);
|
|
41
|
+
return 1 - Math.sqrt(1 - u * u);
|
|
37
42
|
}
|
|
38
43
|
static exp(t) {
|
|
39
44
|
return 2 ** (10 * (t - 1));
|
|
@@ -46,18 +51,19 @@ class Easing {
|
|
|
46
51
|
return (t) => t * t * ((s + 1) * t - s);
|
|
47
52
|
}
|
|
48
53
|
static bounce(t) {
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
const u = clampUnit(t);
|
|
55
|
+
if (u < 1 / 2.75) {
|
|
56
|
+
return 7.5625 * u * u;
|
|
51
57
|
}
|
|
52
|
-
if (
|
|
53
|
-
const t2_ =
|
|
58
|
+
if (u < 2 / 2.75) {
|
|
59
|
+
const t2_ = u - 1.5 / 2.75;
|
|
54
60
|
return 7.5625 * t2_ * t2_ + 0.75;
|
|
55
61
|
}
|
|
56
|
-
if (
|
|
57
|
-
const t2_ =
|
|
62
|
+
if (u < 2.5 / 2.75) {
|
|
63
|
+
const t2_ = u - 2.25 / 2.75;
|
|
58
64
|
return 7.5625 * t2_ * t2_ + 0.9375;
|
|
59
65
|
}
|
|
60
|
-
const t2 =
|
|
66
|
+
const t2 = u - 2.625 / 2.75;
|
|
61
67
|
return 7.5625 * t2 * t2 + 0.984375;
|
|
62
68
|
}
|
|
63
69
|
static bezier(x1, y1, x2, y2) {
|
|
@@ -7,10 +7,16 @@ const use_current_frame_js_1 = require("../use-current-frame.js");
|
|
|
7
7
|
const use_delay_render_js_1 = require("../use-delay-render.js");
|
|
8
8
|
const run_effect_chain_js_1 = require("./run-effect-chain.js");
|
|
9
9
|
const use_effect_chain_state_js_1 = require("./use-effect-chain-state.js");
|
|
10
|
+
const use_memoized_effects_js_1 = require("./use-memoized-effects.js");
|
|
10
11
|
const Solid = ({ color, width, height, _experimentalEffects: experimentalEffects = [], className, style, pixelRatio = 1, }) => {
|
|
11
12
|
const frame = (0, use_current_frame_js_1.useCurrentFrame)();
|
|
12
13
|
const { delayRender, continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
|
|
13
14
|
const [outputCanvas, setOutputCanvas] = (0, react_1.useState)(null);
|
|
15
|
+
const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)({
|
|
16
|
+
effects: experimentalEffects,
|
|
17
|
+
// TODO: Add schema to Solid
|
|
18
|
+
overrideId: null,
|
|
19
|
+
});
|
|
14
20
|
const sourceCanvas = (0, react_1.useMemo)(() => {
|
|
15
21
|
if (typeof document === 'undefined') {
|
|
16
22
|
return null;
|
|
@@ -43,7 +49,7 @@ const Solid = ({ color, width, height, _experimentalEffects: experimentalEffects
|
|
|
43
49
|
(0, run_effect_chain_js_1.runEffectChain)({
|
|
44
50
|
state: chainState.get(width, height),
|
|
45
51
|
source: sourceCanvas,
|
|
46
|
-
effects:
|
|
52
|
+
effects: memoizedEffects,
|
|
47
53
|
output: outputCanvas,
|
|
48
54
|
frame,
|
|
49
55
|
width,
|
|
@@ -63,7 +69,6 @@ const Solid = ({ color, width, height, _experimentalEffects: experimentalEffects
|
|
|
63
69
|
}, [
|
|
64
70
|
frame,
|
|
65
71
|
color,
|
|
66
|
-
experimentalEffects,
|
|
67
72
|
outputCanvas,
|
|
68
73
|
sourceCanvas,
|
|
69
74
|
chainState,
|
|
@@ -73,6 +78,7 @@ const Solid = ({ color, width, height, _experimentalEffects: experimentalEffects
|
|
|
73
78
|
delayRender,
|
|
74
79
|
continueRender,
|
|
75
80
|
cancelRender,
|
|
81
|
+
memoizedEffects,
|
|
76
82
|
]);
|
|
77
83
|
return ((0, jsx_runtime_1.jsx)("canvas", { ref: setOutputCanvas, width: width, height: height, className: className, style: style }));
|
|
78
84
|
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EffectDefinition, EffectDescriptor } from './effect-types.js';
|
|
2
|
+
type EffectFactory<P> = {} extends P ? (params?: P) => EffectDescriptor<unknown> : (params: P) => EffectDescriptor<unknown>;
|
|
3
|
+
export declare const createEffect: <P, S>(definition: EffectDefinition<P, S>) => EffectFactory<P>;
|
|
4
|
+
export {};
|