remotion 4.0.538 → 4.0.539

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.
@@ -59,7 +59,7 @@ const hasTailwindClassName = ({ className, classPrefix, type, }) => {
59
59
  };
60
60
  const AbsoluteFillElementRefForwarding = (props, ref) => {
61
61
  const { style, ...other } = props;
62
- const actualStyle = (0, react_1.useMemo)(() => {
62
+ const defaultStyle = (0, react_1.useMemo)(() => {
63
63
  // Make TailwindCSS classes get accepted
64
64
  return {
65
65
  position: 'absolute',
@@ -136,9 +136,14 @@ const AbsoluteFillElementRefForwarding = (props, ref) => {
136
136
  })
137
137
  ? undefined
138
138
  : 'column',
139
+ };
140
+ }, [other.className]);
141
+ const actualStyle = (0, react_1.useMemo)(() => {
142
+ return {
143
+ ...defaultStyle,
139
144
  ...style,
140
145
  };
141
- }, [other.className, style]);
146
+ }, [defaultStyle, style]);
142
147
  return (0, jsx_runtime_1.jsx)("div", { ref: ref, style: actualStyle, ...other });
143
148
  };
144
149
  exports.AbsoluteFillElement = react_1.default.memo((0, react_1.forwardRef)(AbsoluteFillElementRefForwarding));
@@ -45,6 +45,7 @@ const decodeImage = async ({ resolvedSrc, signal, requestInit, currentTime, init
45
45
  };
46
46
  };
47
47
  const clearCache = (closeToTimeInSec) => {
48
+ var _a;
48
49
  const itemsInCache = cache.filter((c) => c.frame);
49
50
  const sortByClosestToCurrentTime = itemsInCache.sort((a, b) => {
50
51
  const aDiff = Math.abs(a.timeInSeconds - closeToTimeInSec);
@@ -56,6 +57,7 @@ const decodeImage = async ({ resolvedSrc, signal, requestInit, currentTime, init
56
57
  continue;
57
58
  }
58
59
  const item = sortByClosestToCurrentTime[i];
60
+ (_a = item.frame) === null || _a === void 0 ? void 0 : _a.close();
59
61
  item.frame = null;
60
62
  }
61
63
  };
@@ -0,0 +1 @@
1
+ export declare const createCurveSampler: (points: readonly (readonly [number, number])[], interpolation: 'smooth' | 'linear') => ((input: number) => number);
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCurveSampler = void 0;
4
+ // Shared by the Curves renderer and Studio so the graph matches the pixels.
5
+ // Points are validated by the effect: at least two, with increasing inputs.
6
+ const createCurveSampler = (points, interpolation) => {
7
+ // Parameterize by distance along the graph so a steep segment gets room
8
+ // to bend, even when its input values are close together.
9
+ const distances = points
10
+ .slice(1)
11
+ .map((point, index) => Math.hypot(point[0] - points[index][0], point[1] - points[index][1]));
12
+ const tangents = points.map(() => [0, 0]);
13
+ if (interpolation === 'smooth' && points.length > 2) {
14
+ for (let axis = 0; axis < 2; axis++) {
15
+ const slopes = distances.map((distance, index) => (points[index + 1][axis] - points[index][axis]) / distance);
16
+ const curvatures = new Array(points.length).fill(0);
17
+ const upper = new Array(points.length).fill(0);
18
+ // Solve the natural cubic spline for each coordinate.
19
+ for (let index = 1; index < points.length - 1; index++) {
20
+ const diagonal = 2 * (distances[index - 1] + distances[index]) -
21
+ distances[index - 1] * upper[index - 1];
22
+ upper[index] = distances[index] / diagonal;
23
+ curvatures[index] =
24
+ (6 * (slopes[index] - slopes[index - 1]) -
25
+ distances[index - 1] * curvatures[index - 1]) /
26
+ diagonal;
27
+ }
28
+ for (let index = points.length - 2; index > 0; index--) {
29
+ curvatures[index] -= upper[index] * curvatures[index + 1];
30
+ }
31
+ for (let index = 0; index < points.length; index++) {
32
+ tangents[index][axis] =
33
+ index === 0
34
+ ? slopes[0] - (distances[0] * curvatures[1]) / 6
35
+ : slopes[index - 1] +
36
+ (distances[index - 1] *
37
+ (curvatures[index - 1] + 2 * curvatures[index])) /
38
+ 6;
39
+ }
40
+ }
41
+ for (let index = 0; index < points.length; index++) {
42
+ // Keep both Bezier handles within their segment's input range so
43
+ // the curve never doubles back and every input has one output.
44
+ const maxTangent = 3 *
45
+ Math.min(index === 0
46
+ ? Infinity
47
+ : (points[index][0] - points[index - 1][0]) / distances[index - 1], index === points.length - 1
48
+ ? Infinity
49
+ : (points[index + 1][0] - points[index][0]) / distances[index]);
50
+ if (tangents[index][0] > maxTangent) {
51
+ tangents[index][1] *= maxTangent / tangents[index][0];
52
+ }
53
+ tangents[index][0] = Math.max(0, Math.min(maxTangent, tangents[index][0]));
54
+ }
55
+ }
56
+ return (input) => {
57
+ if (input <= points[0][0])
58
+ return points[0][1];
59
+ if (input >= points[points.length - 1][0]) {
60
+ return points[points.length - 1][1];
61
+ }
62
+ const index = points.findIndex((point) => point[0] > input) - 1;
63
+ const start = points[index];
64
+ const end = points[index + 1];
65
+ if (input === start[0])
66
+ return start[1];
67
+ if (interpolation === 'linear' || points.length === 2) {
68
+ return (start[1] +
69
+ (end[1] - start[1]) * ((input - start[0]) / (end[0] - start[0])));
70
+ }
71
+ const handleLength = distances[index] / 3;
72
+ const firstX = start[0] + handleLength * tangents[index][0];
73
+ const secondX = end[0] - handleLength * tangents[index + 1][0];
74
+ let low = 0;
75
+ let high = 1;
76
+ // Invert the monotonic Bezier input coordinate before sampling output.
77
+ for (let iteration = 0; iteration < 32; iteration++) {
78
+ const candidate = (low + high) / 2;
79
+ const inverse = 1 - candidate;
80
+ const x = inverse ** 3 * start[0] +
81
+ 3 * inverse ** 2 * candidate * firstX +
82
+ 3 * inverse * candidate ** 2 * secondX +
83
+ candidate ** 3 * end[0];
84
+ if (x < input)
85
+ low = candidate;
86
+ else
87
+ high = candidate;
88
+ }
89
+ const progress = (low + high) / 2;
90
+ const remaining = 1 - progress;
91
+ const firstY = start[1] + handleLength * tangents[index][1];
92
+ const secondY = end[1] - handleLength * tangents[index + 1][1];
93
+ const value = remaining ** 3 * start[1] +
94
+ 3 * remaining ** 2 * progress * firstY +
95
+ 3 * remaining * progress ** 2 * secondY +
96
+ progress ** 3 * end[1];
97
+ return Math.max(0, Math.min(1, value));
98
+ };
99
+ };
100
+ exports.createCurveSampler = createCurveSampler;
@@ -0,0 +1,13 @@
1
+ import type { EffectDefinitionAndStack } from './effect-types.js';
2
+ import type { EffectChainState } from './run-effect-chain.js';
3
+ type SourceListener = (source: CanvasImageSource | null) => void;
4
+ /** Studio-only inspection. The source is borrowed and must be consumed synchronously. */
5
+ export declare const subscribeToEffectSource: ({ sequenceKey, effectIndex, onSource, }: {
6
+ readonly sequenceKey: string;
7
+ readonly effectIndex: number;
8
+ readonly onSource: SourceListener;
9
+ }) => (() => void);
10
+ export declare const publishEffectSource: (effect: EffectDefinitionAndStack<unknown>, source: CanvasImageSource, chain: EffectChainState) => void;
11
+ export declare const invalidateEffectChainSources: (chain: EffectChainState) => void;
12
+ export declare const useEffectSourceInspection: (effects: EffectDefinitionAndStack<unknown>[], sequenceKey: string | null) => EffectDefinitionAndStack<unknown>[];
13
+ export {};
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var _a;
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.useEffectSourceInspection = exports.invalidateEffectChainSources = exports.publishEffectSource = exports.subscribeToEffectSource = void 0;
38
+ const react_1 = __importStar(require("react"));
39
+ const observers = new Map();
40
+ const redrawListeners = new Map();
41
+ const identities = new WeakMap();
42
+ const inspectedChains = new WeakMap();
43
+ const sourceChainOwners = new Map();
44
+ const useIdentityCommitEffect = (_a = react_1.default.useInsertionEffect) !== null && _a !== void 0 ? _a : react_1.useLayoutEffect;
45
+ /** Studio-only inspection. The source is borrowed and must be consumed synchronously. */
46
+ const subscribeToEffectSource = ({ sequenceKey, effectIndex, onSource, }) => {
47
+ var _a;
48
+ let sequence = observers.get(sequenceKey);
49
+ if (!sequence) {
50
+ sequence = new Map();
51
+ observers.set(sequenceKey, sequence);
52
+ }
53
+ let listeners = sequence.get(effectIndex);
54
+ if (!listeners) {
55
+ listeners = new Set();
56
+ sequence.set(effectIndex, listeners);
57
+ }
58
+ listeners.add(onSource);
59
+ // Repaint once when the inspector opens, including while playback is paused.
60
+ (_a = redrawListeners.get(sequenceKey)) === null || _a === void 0 ? void 0 : _a.forEach((redraw) => redraw());
61
+ return () => {
62
+ listeners.delete(onSource);
63
+ if (listeners.size === 0) {
64
+ sequence.delete(effectIndex);
65
+ }
66
+ if (sequence.size === 0) {
67
+ observers.delete(sequenceKey);
68
+ }
69
+ };
70
+ };
71
+ exports.subscribeToEffectSource = subscribeToEffectSource;
72
+ const publishEffectSource = (effect, source, chain) => {
73
+ var _a;
74
+ if (observers.size === 0) {
75
+ return;
76
+ }
77
+ const identity = identities.get(effect);
78
+ if (!identity) {
79
+ return;
80
+ }
81
+ const listeners = (_a = observers
82
+ .get(identity.sequenceKey)) === null || _a === void 0 ? void 0 : _a.get(identity.effectIndex);
83
+ if (!listeners || listeners.size === 0) {
84
+ return;
85
+ }
86
+ let inspected = inspectedChains.get(chain);
87
+ if (!inspected) {
88
+ inspected = new Map();
89
+ inspectedChains.set(chain, inspected);
90
+ }
91
+ const key = `${identity.sequenceKey}\0${identity.effectIndex}`;
92
+ inspected.set(key, identity);
93
+ sourceChainOwners.set(key, chain);
94
+ listeners.forEach((listener) => {
95
+ try {
96
+ listener(source);
97
+ }
98
+ catch (_a) {
99
+ // Optional inspector readback must never interrupt rendering.
100
+ }
101
+ });
102
+ };
103
+ exports.publishEffectSource = publishEffectSource;
104
+ const invalidateEffectChainSources = (chain) => {
105
+ const inspected = inspectedChains.get(chain);
106
+ inspectedChains.delete(chain);
107
+ inspected === null || inspected === void 0 ? void 0 : inspected.forEach((identity, key) => {
108
+ var _a, _b;
109
+ // A replacement canvas may already have painted before the old canvas's
110
+ // passive cleanup. Only the current owner can invalidate its histogram.
111
+ if (sourceChainOwners.get(key) !== chain) {
112
+ return;
113
+ }
114
+ sourceChainOwners.delete(key);
115
+ (_b = (_a = observers
116
+ .get(identity.sequenceKey)) === null || _a === void 0 ? void 0 : _a.get(identity.effectIndex)) === null || _b === void 0 ? void 0 : _b.forEach((listener) => {
117
+ try {
118
+ listener(null);
119
+ }
120
+ catch (_a) {
121
+ // Optional inspection must not interfere with canvas cleanup.
122
+ }
123
+ });
124
+ });
125
+ };
126
+ exports.invalidateEffectChainSources = invalidateEffectChainSources;
127
+ const useEffectSourceInspection = (effects, sequenceKey) => {
128
+ const [revision, setRevision] = (0, react_1.useState)(0);
129
+ (0, react_1.useLayoutEffect)(() => {
130
+ if (sequenceKey === null) {
131
+ return;
132
+ }
133
+ let listeners = redrawListeners.get(sequenceKey);
134
+ if (!listeners) {
135
+ listeners = new Set();
136
+ redrawListeners.set(sequenceKey, listeners);
137
+ }
138
+ const redraw = () => setRevision((previous) => previous + 1);
139
+ listeners.add(redraw);
140
+ if (observers.has(sequenceKey)) {
141
+ redraw();
142
+ }
143
+ return () => {
144
+ var _a;
145
+ listeners.delete(redraw);
146
+ if (listeners.size === 0) {
147
+ redrawListeners.delete(sequenceKey);
148
+ (_a = observers.get(sequenceKey)) === null || _a === void 0 ? void 0 : _a.forEach((sourceListeners) => {
149
+ sourceListeners.forEach((listener) => {
150
+ try {
151
+ listener(null);
152
+ }
153
+ catch (_a) {
154
+ // An inspector must not interfere with source cleanup.
155
+ }
156
+ });
157
+ });
158
+ }
159
+ };
160
+ }, [sequenceKey]);
161
+ useIdentityCommitEffect(() => {
162
+ if (sequenceKey === null) {
163
+ return;
164
+ }
165
+ effects.forEach((effect, effectIndex) => {
166
+ identities.set(effect, { sequenceKey, effectIndex });
167
+ });
168
+ return () => {
169
+ effects.forEach((effect) => identities.delete(effect));
170
+ };
171
+ }, [effects, sequenceKey]);
172
+ // Source components already repaint when their effect array changes.
173
+ return (0, react_1.useMemo)(() => {
174
+ return sequenceKey === null || revision === 0 ? effects : effects.slice();
175
+ }, [effects, revision, sequenceKey]);
176
+ };
177
+ exports.useEffectSourceInspection = useEffectSourceInspection;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runEffectChain = exports.cleanupEffectChainState = exports.createEffectChainState = void 0;
4
4
  const canvas_pool_js_1 = require("./canvas-pool.js");
5
5
  const effect_internals_js_1 = require("./effect-internals.js");
6
+ const effect_source_observer_js_1 = require("./effect-source-observer.js");
6
7
  const gpu_device_js_1 = require("./gpu-device.js");
7
8
  const createEffectChainState = (width, height) => {
8
9
  const state = {
@@ -35,6 +36,7 @@ exports.createEffectChainState = createEffectChainState;
35
36
  // canvases and contexts. The state must not be used afterwards.
36
37
  const cleanupEffectChainState = (state) => {
37
38
  state.currentRunId++;
39
+ (0, effect_source_observer_js_1.invalidateEffectChainSources)(state);
38
40
  try {
39
41
  for (const entry of state.cleanupRegistry) {
40
42
  entry.definition.cleanup(entry.state);
@@ -119,6 +121,7 @@ const runEffectChainWithoutResize = async ({ state, source, effects, output, wid
119
121
  state.pool.assertContextNotLost(dst);
120
122
  }
121
123
  const setupState = ensureSetup(state, def, dst);
124
+ (0, effect_source_observer_js_1.publishEffectSource)(eff, currentImage, state);
122
125
  def.apply({
123
126
  source: currentImage,
124
127
  target: dst,
@@ -45,6 +45,8 @@ const sequence_activity_context_js_1 = require("../sequence-activity-context.js"
45
45
  const sequence_node_path_js_1 = require("../sequence-node-path.js");
46
46
  const SequenceManager_js_1 = require("../SequenceManager.js");
47
47
  const use_current_frame_js_1 = require("../use-current-frame.js");
48
+ const use_remotion_environment_js_1 = require("../use-remotion-environment.js");
49
+ const effect_source_observer_js_1 = require("./effect-source-observer.js");
48
50
  const emptyDragOverrides = {};
49
51
  const useCacheCommitEffect = (_a = react_1.default.useInsertionEffect) !== null && _a !== void 0 ? _a : react_1.useLayoutEffect;
50
52
  const areEffectParamsEqual = (previous, next) => {
@@ -227,6 +229,7 @@ exports.getPropStatusesCtx = getPropStatusesCtx;
227
229
  const useMemoizedEffects = ({ effects, overrideId, videoConfigValues, }) => {
228
230
  var _a;
229
231
  const previousRef = (0, react_1.useRef)(null);
232
+ const { isStudio } = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
230
233
  const { overrideIdToNodePathMappings } = (0, react_1.useContext)(sequence_node_path_js_1.OverrideIdsToNodePathsGettersContext);
231
234
  const previous = previousRef.current;
232
235
  const nodePath = overrideId
@@ -308,6 +311,8 @@ const useMemoizedEffects = ({ effects, overrideId, videoConfigValues, }) => {
308
311
  useCacheCommitEffect(() => {
309
312
  previousRef.current = { prepared, effects: next };
310
313
  }, [next, prepared]);
311
- return next;
314
+ return (0, effect_source_observer_js_1.useEffectSourceInspection)(next, isStudio && nodePath !== null
315
+ ? (0, SequenceManager_js_1.makeSequencePropsSubscriptionKey)({ ...nodePath, videoConfigValues })
316
+ : null);
312
317
  };
313
318
  exports.useMemoizedEffects = useMemoizedEffects;
@@ -15,7 +15,9 @@ import type { CompositionManagerContext } from './CompositionManagerContext.js';
15
15
  import { CompositionManagerProvider } from './CompositionManagerProvider.js';
16
16
  import { createElementSourceProxy } from './create-element-source-proxy.js';
17
17
  import * as CSSUtils from './default-css.js';
18
+ import { createCurveSampler } from './effects/create-curve-sampler.js';
18
19
  import { createEffect } from './effects/create-effect.js';
20
+ import { subscribeToEffectSource } from './effects/effect-source-observer.js';
19
21
  import { cleanupEffectChainState, createEffectChainState, runEffectChain } from './effects/run-effect-chain.js';
20
22
  import { useEffectChainState } from './effects/use-effect-chain-state.js';
21
23
  import { getEffectPropStatusesCtx, getPropStatusesCtx, useMemoizedEffectDefinitions, useMemoizedEffects } from './effects/use-memoized-effects.js';
@@ -1197,8 +1199,10 @@ export declare const Internals: {
1197
1199
  readonly cleanupEffectChainState: typeof cleanupEffectChainState;
1198
1200
  readonly runEffectChain: typeof runEffectChain;
1199
1201
  readonly useMemoizedEffects: typeof useMemoizedEffects;
1202
+ readonly subscribeToEffectSource: typeof subscribeToEffectSource;
1200
1203
  readonly useMemoizedEffectDefinitions: typeof useMemoizedEffectDefinitions;
1201
1204
  readonly createEffect: typeof createEffect;
1205
+ readonly createCurveSampler: typeof createCurveSampler;
1202
1206
  readonly createWebGLContextError: typeof createWebGLContextError;
1203
1207
  readonly createWebGL2ContextError: typeof createWebGL2ContextError;
1204
1208
  readonly computeEffectiveSchemaValuesDotNotation: typeof computeEffectiveSchemaValuesDotNotation;
@@ -58,7 +58,9 @@ const CSSUtils = __importStar(require("./default-css.js"));
58
58
  const default_css_js_1 = require("./default-css.js");
59
59
  const DefaultPremountContext_js_1 = require("./DefaultPremountContext.js");
60
60
  const EditorProps_js_1 = require("./EditorProps.js");
61
+ const create_curve_sampler_js_1 = require("./effects/create-curve-sampler.js");
61
62
  const create_effect_js_1 = require("./effects/create-effect.js");
63
+ const effect_source_observer_js_1 = require("./effects/effect-source-observer.js");
62
64
  const run_effect_chain_js_1 = require("./effects/run-effect-chain.js");
63
65
  const use_effect_chain_state_js_1 = require("./effects/use-effect-chain-state.js");
64
66
  const use_memoized_effects_js_1 = require("./effects/use-memoized-effects.js");
@@ -338,8 +340,10 @@ exports.Internals = {
338
340
  cleanupEffectChainState: run_effect_chain_js_1.cleanupEffectChainState,
339
341
  runEffectChain: run_effect_chain_js_1.runEffectChain,
340
342
  useMemoizedEffects: use_memoized_effects_js_1.useMemoizedEffects,
343
+ subscribeToEffectSource: effect_source_observer_js_1.subscribeToEffectSource,
341
344
  useMemoizedEffectDefinitions: use_memoized_effects_js_1.useMemoizedEffectDefinitions,
342
345
  createEffect: create_effect_js_1.createEffect,
346
+ createCurveSampler: create_curve_sampler_js_1.createCurveSampler,
343
347
  createWebGLContextError: webgl2_context_error_js_1.createWebGLContextError,
344
348
  createWebGL2ContextError: webgl2_context_error_js_1.createWebGL2ContextError,
345
349
  computeEffectiveSchemaValuesDotNotation: use_schema_js_1.computeEffectiveSchemaValuesDotNotation,
@@ -138,15 +138,19 @@ function parseModernComponent(str, percentScale) {
138
138
  function parseHueAngle(str) {
139
139
  if (str === 'none')
140
140
  return 0;
141
- if (str.endsWith('rad')) {
142
- return (Number.parseFloat(str) * 180) / Math.PI;
141
+ let degrees = Number.parseFloat(str);
142
+ if (str.endsWith('grad')) {
143
+ degrees *= 0.9;
144
+ }
145
+ else if (str.endsWith('rad')) {
146
+ degrees = (degrees * 180) / Math.PI;
147
+ }
148
+ else if (str.endsWith('turn')) {
149
+ degrees *= 360;
143
150
  }
144
- if (str.endsWith('grad'))
145
- return Number.parseFloat(str) * 0.9;
146
- if (str.endsWith('turn'))
147
- return Number.parseFloat(str) * 360;
148
151
  // 'deg' suffix or plain number = degrees
149
- return Number.parseFloat(str);
152
+ const normalized = degrees % 360;
153
+ return normalized < 0 ? (normalized + 360) % 360 : normalized;
150
154
  }
151
155
  function parseModernAlpha(str) {
152
156
  if (str === undefined || str === 'none')
@@ -456,6 +456,21 @@ const interpolateSegment = ({ input, inputRange, outputRange, easing, extrapolat
456
456
  output,
457
457
  });
458
458
  };
459
+ const getInputForInterpolation = ({ input, inputRange, options, }) => {
460
+ const posterizedInput = (options === null || options === void 0 ? void 0 : options.posterize) === undefined
461
+ ? input
462
+ : Math.floor(input / options.posterize) * options.posterize;
463
+ const inputMin = inputRange[0];
464
+ const inputMax = inputRange[inputRange.length - 1];
465
+ if (inputRange.length === 1 ||
466
+ !((posterizedInput < inputMin && (options === null || options === void 0 ? void 0 : options.extrapolateLeft) === 'wrap') ||
467
+ (posterizedInput > inputMax && (options === null || options === void 0 ? void 0 : options.extrapolateRight) === 'wrap'))) {
468
+ return posterizedInput;
469
+ }
470
+ // Wrap before choosing a segment so the entire keyframe range repeats.
471
+ const range = inputMax - inputMin;
472
+ return ((((posterizedInput - inputMin) % range) + range) % range) + inputMin;
473
+ };
459
474
  const interpolateNumber = ({ input, inputRange, outputRange, options, }) => {
460
475
  const output = resolveOutputOption(options === null || options === void 0 ? void 0 : options.output);
461
476
  if (inputRange.length === 1) {
@@ -470,16 +485,18 @@ const interpolateNumber = ({ input, inputRange, outputRange, options, }) => {
470
485
  if ((options === null || options === void 0 ? void 0 : options.extrapolateRight) !== undefined) {
471
486
  extrapolateRight = options.extrapolateRight;
472
487
  }
473
- const posterizedInput = (options === null || options === void 0 ? void 0 : options.posterize) === undefined
474
- ? input
475
- : Math.floor(input / options.posterize) * options.posterize;
476
- const range = findRange(posterizedInput, inputRange);
488
+ const resolvedInput = getInputForInterpolation({
489
+ input,
490
+ inputRange,
491
+ options: options !== null && options !== void 0 ? options : null,
492
+ });
493
+ const range = findRange(resolvedInput, inputRange);
477
494
  const easing = resolveEasingForSegment({
478
495
  easing: easingOption,
479
496
  segmentIndex: range,
480
497
  });
481
498
  let result = interpolateSegment({
482
- input: posterizedInput,
499
+ input: resolvedInput,
483
500
  inputRange: [inputRange[range], inputRange[range + 1]],
484
501
  outputRange: [outputRange[range], outputRange[range + 1]],
485
502
  easing,
@@ -496,11 +513,11 @@ const interpolateNumber = ({ input, inputRange, outputRange, options, }) => {
496
513
  continue;
497
514
  }
498
515
  const previousSegmentEnd = inputRange[segmentIndex + 1];
499
- if (posterizedInput <= previousSegmentEnd) {
516
+ if (resolvedInput <= previousSegmentEnd) {
500
517
  continue;
501
518
  }
502
519
  const continuedSegmentValue = interpolateSegment({
503
- input: posterizedInput,
520
+ input: resolvedInput,
504
521
  inputRange: [inputRange[segmentIndex], previousSegmentEnd],
505
522
  outputRange: [outputRange[segmentIndex], outputRange[segmentIndex + 1]],
506
523
  easing: previousEasing,
@@ -516,10 +533,12 @@ const interpolateString = ({ input, inputRange, outputRange, options, outputType
516
533
  var _a;
517
534
  const initiallyParsedOutputRange = outputRange.map((output) => parseStringInterpolationValue(output, outputType));
518
535
  const hasAxisRotation = initiallyParsedOutputRange.some((parsed) => parsed.axisRotation);
519
- const posterizedInput = (options === null || options === void 0 ? void 0 : options.posterize) === undefined
520
- ? input
521
- : Math.floor(input / options.posterize) * options.posterize;
522
- const segmentIndex = inputRange.length === 1 ? 0 : findRange(posterizedInput, inputRange);
536
+ const resolvedInput = getInputForInterpolation({
537
+ input,
538
+ inputRange,
539
+ options: options !== null && options !== void 0 ? options : null,
540
+ });
541
+ const segmentIndex = inputRange.length === 1 ? 0 : findRange(resolvedInput, inputRange);
523
542
  const parsedOutputRange = hasAxisRotation
524
543
  ? initiallyParsedOutputRange.map((parsed, index) => {
525
544
  if (parsed.kind !== 'rotate') {
@@ -658,27 +677,20 @@ const interpolateDiscreteValue = ({ input, inputRange, outputRange, options, })
658
677
  : 'Non-numeric strings can only be interpolated using Easing.step1');
659
678
  }
660
679
  }
661
- const posterizedInput = (options === null || options === void 0 ? void 0 : options.posterize) === undefined
662
- ? input
663
- : Math.floor(input / options.posterize) * options.posterize;
680
+ const resolvedInput = getInputForInterpolation({
681
+ input,
682
+ inputRange,
683
+ options: options !== null && options !== void 0 ? options : null,
684
+ });
664
685
  const inputMin = inputRange[0];
665
686
  const inputMax = inputRange[inputRange.length - 1];
666
- let resolvedInput = posterizedInput;
667
687
  if (resolvedInput < inputMin) {
668
688
  if ((options === null || options === void 0 ? void 0 : options.extrapolateLeft) === 'identity') {
669
689
  throw new TypeError(typeof outputRange[0] === 'boolean'
670
690
  ? 'extrapolateLeft: "identity" is not supported for booleans'
671
691
  : 'extrapolateLeft: "identity" is not supported for non-numeric strings');
672
692
  }
673
- if ((options === null || options === void 0 ? void 0 : options.extrapolateLeft) === 'wrap') {
674
- const wrapRange = inputMax - inputMin;
675
- resolvedInput =
676
- ((((resolvedInput - inputMin) % wrapRange) + wrapRange) % wrapRange) +
677
- inputMin;
678
- }
679
- else {
680
- return outputRange[0];
681
- }
693
+ return outputRange[0];
682
694
  }
683
695
  if (resolvedInput > inputMax) {
684
696
  if ((options === null || options === void 0 ? void 0 : options.extrapolateRight) === 'identity') {
@@ -686,15 +698,7 @@ const interpolateDiscreteValue = ({ input, inputRange, outputRange, options, })
686
698
  ? 'extrapolateRight: "identity" is not supported for booleans'
687
699
  : 'extrapolateRight: "identity" is not supported for non-numeric strings');
688
700
  }
689
- if ((options === null || options === void 0 ? void 0 : options.extrapolateRight) === 'wrap') {
690
- const wrapRange = inputMax - inputMin;
691
- resolvedInput =
692
- ((((resolvedInput - inputMin) % wrapRange) + wrapRange) % wrapRange) +
693
- inputMin;
694
- }
695
- else {
696
- return outputRange[outputRange.length - 1];
697
- }
701
+ return outputRange[outputRange.length - 1];
698
702
  }
699
703
  const range = findRange(resolvedInput, inputRange);
700
704
  return resolvedInput >= inputRange[range + 1]
@@ -0,0 +1,11 @@
1
+ export type TNonceContext = {
2
+ getNonce: () => number;
3
+ };
4
+ type NonceHistoryItem = [number, number];
5
+ export type NonceHistory = NonceHistoryItem[];
6
+ export type NonceHistoryContext = {
7
+ get: () => NonceHistory;
8
+ };
9
+ export declare const NonceContext: import("react").Context<TNonceContext>;
10
+ export declare const useNonce: () => NonceHistoryContext;
11
+ export {};
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useNonce = exports.NonceContext = void 0;
4
+ const react_1 = require("react");
5
+ exports.NonceContext = (0, react_1.createContext)({
6
+ getNonce: () => 0,
7
+ });
8
+ let fastRefreshNonce = 0;
9
+ try {
10
+ if (typeof __webpack_module__ !== 'undefined') {
11
+ if (__webpack_module__.hot) {
12
+ __webpack_module__.hot.addStatusHandler((status) => {
13
+ if (status === 'idle') {
14
+ fastRefreshNonce++;
15
+ }
16
+ });
17
+ }
18
+ }
19
+ }
20
+ catch (_a) {
21
+ // __webpack_module__ may throw ReferenceError in some environments
22
+ }
23
+ const useNonce = () => {
24
+ const context = (0, react_1.useContext)(exports.NonceContext);
25
+ const nonce = context.getNonce();
26
+ const nonceRef = (0, react_1.useRef)(nonce);
27
+ nonceRef.current = nonce;
28
+ const history = (0, react_1.useRef)([[fastRefreshNonce, nonce]]);
29
+ const get = (0, react_1.useCallback)(() => {
30
+ if (fastRefreshNonce !== history.current[history.current.length - 1][0]) {
31
+ history.current = [
32
+ ...history.current,
33
+ [fastRefreshNonce, nonceRef.current],
34
+ ];
35
+ }
36
+ return history.current;
37
+ }, [history]);
38
+ return (0, react_1.useMemo)(() => {
39
+ return { get };
40
+ }, [get]);
41
+ };
42
+ exports.useNonce = useNonce;