@remotion/web-renderer 4.0.448 → 4.0.450
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/audio.d.ts +1 -1
- package/dist/drawing/calculate-transforms.d.ts +0 -1
- package/dist/drawing/clip-path.d.ts +43 -0
- package/dist/esm/index.mjs +237 -33
- package/package.json +10 -7
package/dist/audio.d.ts
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
type ClipPathNone = {
|
|
2
|
+
type: 'none';
|
|
3
|
+
};
|
|
4
|
+
type ClipPathPolygon = {
|
|
5
|
+
type: 'polygon';
|
|
6
|
+
points: {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
}[];
|
|
10
|
+
};
|
|
11
|
+
type ClipPathPath = {
|
|
12
|
+
type: 'path';
|
|
13
|
+
d: string;
|
|
14
|
+
fillRule: CanvasFillRule;
|
|
15
|
+
};
|
|
16
|
+
type ClipPathCircle = {
|
|
17
|
+
type: 'circle';
|
|
18
|
+
radius: number;
|
|
19
|
+
cx: number;
|
|
20
|
+
cy: number;
|
|
21
|
+
};
|
|
22
|
+
type ClipPathEllipse = {
|
|
23
|
+
type: 'ellipse';
|
|
24
|
+
rx: number;
|
|
25
|
+
ry: number;
|
|
26
|
+
cx: number;
|
|
27
|
+
cy: number;
|
|
28
|
+
};
|
|
29
|
+
type ClipPathInset = {
|
|
30
|
+
type: 'inset';
|
|
31
|
+
top: number;
|
|
32
|
+
right: number;
|
|
33
|
+
bottom: number;
|
|
34
|
+
left: number;
|
|
35
|
+
};
|
|
36
|
+
type ParsedClipPath = ClipPathNone | ClipPathPolygon | ClipPathPath | ClipPathCircle | ClipPathEllipse | ClipPathInset;
|
|
37
|
+
export declare function parseClipPath(clipPath: string, rect: DOMRect): ParsedClipPath;
|
|
38
|
+
export declare function setClipPath({ ctx, clipPath, rect }: {
|
|
39
|
+
ctx: OffscreenCanvasRenderingContext2D;
|
|
40
|
+
clipPath: string;
|
|
41
|
+
rect: DOMRect;
|
|
42
|
+
}): () => void;
|
|
43
|
+
export {};
|
package/dist/esm/index.mjs
CHANGED
|
@@ -671,6 +671,9 @@ var handleArtifacts = () => {
|
|
|
671
671
|
// src/audio.ts
|
|
672
672
|
var TARGET_NUMBER_OF_CHANNELS = 2;
|
|
673
673
|
function mixAudio(waves, length) {
|
|
674
|
+
if (waves.length === 0) {
|
|
675
|
+
return new Int16Array(length);
|
|
676
|
+
}
|
|
674
677
|
if (waves.length === 1 && waves[0].length === length) {
|
|
675
678
|
return waves[0];
|
|
676
679
|
}
|
|
@@ -694,9 +697,6 @@ var onlyInlineAudio = ({
|
|
|
694
697
|
sampleRate
|
|
695
698
|
}) => {
|
|
696
699
|
const inlineAudio = assets.filter((asset) => asset.type === "inline-audio");
|
|
697
|
-
if (inlineAudio.length === 0) {
|
|
698
|
-
return null;
|
|
699
|
-
}
|
|
700
700
|
const expectedLength = Math.round(TARGET_NUMBER_OF_CHANNELS * sampleRate / fps);
|
|
701
701
|
for (const asset of inlineAudio) {
|
|
702
702
|
if (asset.toneFrequency !== 1) {
|
|
@@ -2058,7 +2058,6 @@ var calculateTransforms = ({
|
|
|
2058
2058
|
let opacity = 1;
|
|
2059
2059
|
let elementComputedStyle = null;
|
|
2060
2060
|
let maskImageInfo = null;
|
|
2061
|
-
let filterValue = null;
|
|
2062
2061
|
while (parent) {
|
|
2063
2062
|
const computedStyle = getComputedStyle(parent);
|
|
2064
2063
|
if (parent === element) {
|
|
@@ -2066,16 +2065,6 @@ var calculateTransforms = ({
|
|
|
2066
2065
|
opacity = parseFloat(computedStyle.opacity);
|
|
2067
2066
|
const maskImageValue = getMaskImageValue(computedStyle);
|
|
2068
2067
|
maskImageInfo = maskImageValue ? parseMaskImage(maskImageValue) : null;
|
|
2069
|
-
const computedFilter = computedStyle.filter;
|
|
2070
|
-
if (computedFilter && computedFilter !== "none") {
|
|
2071
|
-
filterValue = computedFilter;
|
|
2072
|
-
const originalFilter = parent.style.filter;
|
|
2073
|
-
parent.style.filter = "none";
|
|
2074
|
-
const parentRefFilter = parent;
|
|
2075
|
-
toReset.push(() => {
|
|
2076
|
-
parentRefFilter.style.filter = originalFilter;
|
|
2077
|
-
});
|
|
2078
|
-
}
|
|
2079
2068
|
const originalMaskImage = parent.style.maskImage;
|
|
2080
2069
|
const originalWebkitMaskImage = parent.style.webkitMaskImage;
|
|
2081
2070
|
parent.style.maskImage = "none";
|
|
@@ -2139,7 +2128,6 @@ var calculateTransforms = ({
|
|
|
2139
2128
|
}
|
|
2140
2129
|
const needs3DTransformViaWebGL = !totalMatrix.is2D;
|
|
2141
2130
|
const needsMaskImage = maskImageInfo !== null;
|
|
2142
|
-
const needsFilter = filterValue !== null;
|
|
2143
2131
|
return {
|
|
2144
2132
|
dimensions,
|
|
2145
2133
|
totalMatrix,
|
|
@@ -2155,8 +2143,7 @@ var calculateTransforms = ({
|
|
|
2155
2143
|
precompositing: {
|
|
2156
2144
|
needs3DTransformViaWebGL,
|
|
2157
2145
|
needsMaskImage: maskImageInfo,
|
|
2158
|
-
|
|
2159
|
-
needsPrecompositing: Boolean(needs3DTransformViaWebGL || needsMaskImage || needsFilter)
|
|
2146
|
+
needsPrecompositing: Boolean(needs3DTransformViaWebGL || needsMaskImage)
|
|
2160
2147
|
}
|
|
2161
2148
|
};
|
|
2162
2149
|
};
|
|
@@ -2406,6 +2393,233 @@ function setBorderRadius({
|
|
|
2406
2393
|
};
|
|
2407
2394
|
}
|
|
2408
2395
|
|
|
2396
|
+
// src/drawing/clip-path.ts
|
|
2397
|
+
function resolveLength(value, reference) {
|
|
2398
|
+
value = value.trim();
|
|
2399
|
+
if (value.endsWith("%")) {
|
|
2400
|
+
return parseFloat(value) / 100 * reference;
|
|
2401
|
+
}
|
|
2402
|
+
if (value.endsWith("px")) {
|
|
2403
|
+
return parseFloat(value);
|
|
2404
|
+
}
|
|
2405
|
+
return parseFloat(value);
|
|
2406
|
+
}
|
|
2407
|
+
function parsePosition(parts, width, height) {
|
|
2408
|
+
if (parts.length === 0) {
|
|
2409
|
+
return { x: width / 2, y: height / 2 };
|
|
2410
|
+
}
|
|
2411
|
+
if (parts.length === 1) {
|
|
2412
|
+
return { x: resolveLength(parts[0], width), y: height / 2 };
|
|
2413
|
+
}
|
|
2414
|
+
return {
|
|
2415
|
+
x: resolveLength(parts[0], width),
|
|
2416
|
+
y: resolveLength(parts[1], height)
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2419
|
+
function parsePolygon(args, rect) {
|
|
2420
|
+
const pointStrings = args.split(",");
|
|
2421
|
+
const points = pointStrings.map((pointStr) => {
|
|
2422
|
+
const coords = pointStr.trim().split(/\s+/);
|
|
2423
|
+
return {
|
|
2424
|
+
x: resolveLength(coords[0], rect.width) + rect.left,
|
|
2425
|
+
y: resolveLength(coords[1], rect.height) + rect.top
|
|
2426
|
+
};
|
|
2427
|
+
});
|
|
2428
|
+
return { type: "polygon", points };
|
|
2429
|
+
}
|
|
2430
|
+
function parsePath(args) {
|
|
2431
|
+
const match = args.match(/^(?:(nonzero|evenodd)\s*,\s*)?["'](.+)["']$/);
|
|
2432
|
+
if (!match) {
|
|
2433
|
+
return {
|
|
2434
|
+
type: "path",
|
|
2435
|
+
d: args.replace(/["']/g, ""),
|
|
2436
|
+
fillRule: "nonzero"
|
|
2437
|
+
};
|
|
2438
|
+
}
|
|
2439
|
+
const fillRule = match[1] === "evenodd" ? "evenodd" : "nonzero";
|
|
2440
|
+
return { type: "path", d: match[2], fillRule };
|
|
2441
|
+
}
|
|
2442
|
+
function parseCircle(args, rect) {
|
|
2443
|
+
const atIndex = args.indexOf(" at ");
|
|
2444
|
+
let radiusStr;
|
|
2445
|
+
let positionParts;
|
|
2446
|
+
if (atIndex !== -1) {
|
|
2447
|
+
radiusStr = args.slice(0, atIndex).trim();
|
|
2448
|
+
positionParts = args.slice(atIndex + 4).trim().split(/\s+/);
|
|
2449
|
+
} else {
|
|
2450
|
+
radiusStr = args.trim();
|
|
2451
|
+
positionParts = [];
|
|
2452
|
+
}
|
|
2453
|
+
const closestSide = Math.min(rect.width, rect.height) / 2;
|
|
2454
|
+
const farthestSide = Math.max(rect.width, rect.height) / 2;
|
|
2455
|
+
let radius;
|
|
2456
|
+
if (radiusStr === "closest-side" || radiusStr === "") {
|
|
2457
|
+
radius = closestSide;
|
|
2458
|
+
} else if (radiusStr === "farthest-side") {
|
|
2459
|
+
radius = farthestSide;
|
|
2460
|
+
} else {
|
|
2461
|
+
const refSize = Math.sqrt(rect.width * rect.width + rect.height * rect.height) / Math.SQRT2;
|
|
2462
|
+
radius = resolveLength(radiusStr, refSize);
|
|
2463
|
+
}
|
|
2464
|
+
const position = parsePosition(positionParts, rect.width, rect.height);
|
|
2465
|
+
return {
|
|
2466
|
+
type: "circle",
|
|
2467
|
+
radius,
|
|
2468
|
+
cx: position.x + rect.left,
|
|
2469
|
+
cy: position.y + rect.top
|
|
2470
|
+
};
|
|
2471
|
+
}
|
|
2472
|
+
function parseEllipse(args, rect) {
|
|
2473
|
+
const atIndex = args.indexOf(" at ");
|
|
2474
|
+
let radiiStr;
|
|
2475
|
+
let positionParts;
|
|
2476
|
+
if (atIndex !== -1) {
|
|
2477
|
+
radiiStr = args.slice(0, atIndex).trim();
|
|
2478
|
+
positionParts = args.slice(atIndex + 4).trim().split(/\s+/);
|
|
2479
|
+
} else {
|
|
2480
|
+
radiiStr = args.trim();
|
|
2481
|
+
positionParts = [];
|
|
2482
|
+
}
|
|
2483
|
+
const radiiParts = radiiStr.split(/\s+/);
|
|
2484
|
+
let rx;
|
|
2485
|
+
let ry;
|
|
2486
|
+
if (radiiParts.length >= 2) {
|
|
2487
|
+
rx = resolveLength(radiiParts[0], rect.width);
|
|
2488
|
+
ry = resolveLength(radiiParts[1], rect.height);
|
|
2489
|
+
} else {
|
|
2490
|
+
rx = rect.width / 2;
|
|
2491
|
+
ry = rect.height / 2;
|
|
2492
|
+
}
|
|
2493
|
+
const position = parsePosition(positionParts, rect.width, rect.height);
|
|
2494
|
+
return {
|
|
2495
|
+
type: "ellipse",
|
|
2496
|
+
rx,
|
|
2497
|
+
ry,
|
|
2498
|
+
cx: position.x + rect.left,
|
|
2499
|
+
cy: position.y + rect.top
|
|
2500
|
+
};
|
|
2501
|
+
}
|
|
2502
|
+
function parseInset(args, rect) {
|
|
2503
|
+
const [insetPart] = args.split(/\s+round\s+/);
|
|
2504
|
+
const parts = insetPart.split(/\s+/);
|
|
2505
|
+
let top;
|
|
2506
|
+
let right;
|
|
2507
|
+
let bottom;
|
|
2508
|
+
let left;
|
|
2509
|
+
if (parts.length === 1) {
|
|
2510
|
+
const val = resolveLength(parts[0], rect.height);
|
|
2511
|
+
top = val;
|
|
2512
|
+
right = val;
|
|
2513
|
+
bottom = val;
|
|
2514
|
+
left = val;
|
|
2515
|
+
} else if (parts.length === 2) {
|
|
2516
|
+
top = resolveLength(parts[0], rect.height);
|
|
2517
|
+
bottom = resolveLength(parts[0], rect.height);
|
|
2518
|
+
right = resolveLength(parts[1], rect.width);
|
|
2519
|
+
left = resolveLength(parts[1], rect.width);
|
|
2520
|
+
} else if (parts.length === 3) {
|
|
2521
|
+
top = resolveLength(parts[0], rect.height);
|
|
2522
|
+
right = resolveLength(parts[1], rect.width);
|
|
2523
|
+
left = resolveLength(parts[1], rect.width);
|
|
2524
|
+
bottom = resolveLength(parts[2], rect.height);
|
|
2525
|
+
} else {
|
|
2526
|
+
top = resolveLength(parts[0], rect.height);
|
|
2527
|
+
right = resolveLength(parts[1], rect.width);
|
|
2528
|
+
bottom = resolveLength(parts[2], rect.height);
|
|
2529
|
+
left = resolveLength(parts[3], rect.width);
|
|
2530
|
+
}
|
|
2531
|
+
return { type: "inset", top, right, bottom, left };
|
|
2532
|
+
}
|
|
2533
|
+
function parseClipPath(clipPath, rect) {
|
|
2534
|
+
if (clipPath === "none" || clipPath === "") {
|
|
2535
|
+
return { type: "none" };
|
|
2536
|
+
}
|
|
2537
|
+
const polygonMatch = clipPath.match(/^polygon\((.+)\)$/);
|
|
2538
|
+
if (polygonMatch) {
|
|
2539
|
+
return parsePolygon(polygonMatch[1], rect);
|
|
2540
|
+
}
|
|
2541
|
+
const pathMatch = clipPath.match(/^path\((.+)\)$/);
|
|
2542
|
+
if (pathMatch) {
|
|
2543
|
+
return parsePath(pathMatch[1]);
|
|
2544
|
+
}
|
|
2545
|
+
const circleMatch = clipPath.match(/^circle\((.+)\)$/);
|
|
2546
|
+
if (circleMatch) {
|
|
2547
|
+
return parseCircle(circleMatch[1], rect);
|
|
2548
|
+
}
|
|
2549
|
+
const ellipseMatch = clipPath.match(/^ellipse\((.+)\)$/);
|
|
2550
|
+
if (ellipseMatch) {
|
|
2551
|
+
return parseEllipse(ellipseMatch[1], rect);
|
|
2552
|
+
}
|
|
2553
|
+
const insetMatch = clipPath.match(/^inset\((.+)\)$/);
|
|
2554
|
+
if (insetMatch) {
|
|
2555
|
+
return parseInset(insetMatch[1], rect);
|
|
2556
|
+
}
|
|
2557
|
+
return { type: "none" };
|
|
2558
|
+
}
|
|
2559
|
+
function setClipPath({
|
|
2560
|
+
ctx,
|
|
2561
|
+
clipPath,
|
|
2562
|
+
rect
|
|
2563
|
+
}) {
|
|
2564
|
+
const parsed = parseClipPath(clipPath, rect);
|
|
2565
|
+
if (parsed.type === "none") {
|
|
2566
|
+
return () => {};
|
|
2567
|
+
}
|
|
2568
|
+
ctx.save();
|
|
2569
|
+
switch (parsed.type) {
|
|
2570
|
+
case "polygon": {
|
|
2571
|
+
ctx.beginPath();
|
|
2572
|
+
for (let i = 0;i < parsed.points.length; i++) {
|
|
2573
|
+
const point = parsed.points[i];
|
|
2574
|
+
if (i === 0) {
|
|
2575
|
+
ctx.moveTo(point.x, point.y);
|
|
2576
|
+
} else {
|
|
2577
|
+
ctx.lineTo(point.x, point.y);
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
ctx.closePath();
|
|
2581
|
+
ctx.clip();
|
|
2582
|
+
break;
|
|
2583
|
+
}
|
|
2584
|
+
case "path": {
|
|
2585
|
+
const path2d = new Path2D;
|
|
2586
|
+
const offsetMatrix = new DOMMatrix().translate(rect.left, rect.top);
|
|
2587
|
+
path2d.addPath(new Path2D(parsed.d), offsetMatrix);
|
|
2588
|
+
ctx.clip(path2d, parsed.fillRule);
|
|
2589
|
+
break;
|
|
2590
|
+
}
|
|
2591
|
+
case "circle": {
|
|
2592
|
+
ctx.beginPath();
|
|
2593
|
+
ctx.arc(parsed.cx, parsed.cy, parsed.radius, 0, Math.PI * 2);
|
|
2594
|
+
ctx.closePath();
|
|
2595
|
+
ctx.clip();
|
|
2596
|
+
break;
|
|
2597
|
+
}
|
|
2598
|
+
case "ellipse": {
|
|
2599
|
+
ctx.beginPath();
|
|
2600
|
+
ctx.ellipse(parsed.cx, parsed.cy, parsed.rx, parsed.ry, 0, 0, Math.PI * 2);
|
|
2601
|
+
ctx.closePath();
|
|
2602
|
+
ctx.clip();
|
|
2603
|
+
break;
|
|
2604
|
+
}
|
|
2605
|
+
case "inset": {
|
|
2606
|
+
const x = rect.left + parsed.left;
|
|
2607
|
+
const y = rect.top + parsed.top;
|
|
2608
|
+
const w = rect.width - parsed.left - parsed.right;
|
|
2609
|
+
const h = rect.height - parsed.top - parsed.bottom;
|
|
2610
|
+
ctx.beginPath();
|
|
2611
|
+
ctx.rect(x, y, w, h);
|
|
2612
|
+
ctx.clip();
|
|
2613
|
+
break;
|
|
2614
|
+
}
|
|
2615
|
+
default:
|
|
2616
|
+
break;
|
|
2617
|
+
}
|
|
2618
|
+
return () => {
|
|
2619
|
+
ctx.restore();
|
|
2620
|
+
};
|
|
2621
|
+
}
|
|
2622
|
+
|
|
2409
2623
|
// src/drawing/get-background-fill.ts
|
|
2410
2624
|
var isColorTransparent = (color) => {
|
|
2411
2625
|
return color === "transparent" || color.startsWith("rgba") && (color.endsWith(", 0)") || color.endsWith(",0"));
|
|
@@ -3122,6 +3336,11 @@ var drawElement = async ({
|
|
|
3122
3336
|
parentRect,
|
|
3123
3337
|
scale
|
|
3124
3338
|
});
|
|
3339
|
+
const finishClipPath = setClipPath({
|
|
3340
|
+
ctx: context,
|
|
3341
|
+
clipPath: computedStyle.clipPath,
|
|
3342
|
+
rect
|
|
3343
|
+
});
|
|
3125
3344
|
const finishOpacity = setOpacity({
|
|
3126
3345
|
ctx: context,
|
|
3127
3346
|
opacity
|
|
@@ -3186,6 +3405,7 @@ var drawElement = async ({
|
|
|
3186
3405
|
cleanupAfterChildren: () => {
|
|
3187
3406
|
finishFilter();
|
|
3188
3407
|
finishOpacity();
|
|
3408
|
+
finishClipPath();
|
|
3189
3409
|
finishOverflowHidden();
|
|
3190
3410
|
}
|
|
3191
3411
|
};
|
|
@@ -3523,11 +3743,6 @@ var handle3dTransform = ({
|
|
|
3523
3743
|
return transformed;
|
|
3524
3744
|
};
|
|
3525
3745
|
|
|
3526
|
-
// src/drawing/handle-filter.ts
|
|
3527
|
-
var getPrecomposeRectForFilter = (element) => {
|
|
3528
|
-
return getBiggestBoundingClientRect(element);
|
|
3529
|
-
};
|
|
3530
|
-
|
|
3531
3746
|
// src/drawing/handle-mask.ts
|
|
3532
3747
|
var getPrecomposeRectForMask = (element) => {
|
|
3533
3748
|
const boundingRect = getBiggestBoundingClientRect(element);
|
|
@@ -3615,12 +3830,6 @@ var processNode = async ({
|
|
|
3615
3830
|
if (precompositing.needsMaskImage) {
|
|
3616
3831
|
precomposeRect = roundToExpandRect(getPrecomposeRectForMask(element));
|
|
3617
3832
|
}
|
|
3618
|
-
if (precompositing.needsFilter) {
|
|
3619
|
-
precomposeRect = roundToExpandRect(getWiderRectAndExpand({
|
|
3620
|
-
firstRect: precomposeRect,
|
|
3621
|
-
secondRect: getPrecomposeRectForFilter(element)
|
|
3622
|
-
}));
|
|
3623
|
-
}
|
|
3624
3833
|
if (precompositing.needs3DTransformViaWebGL) {
|
|
3625
3834
|
const tentativePrecomposeRect = getPrecomposeRectFor3DTransform({
|
|
3626
3835
|
element,
|
|
@@ -3683,13 +3892,8 @@ var processNode = async ({
|
|
|
3683
3892
|
}
|
|
3684
3893
|
}
|
|
3685
3894
|
const previousTransform = context.getTransform();
|
|
3686
|
-
const previousFilter = context.filter;
|
|
3687
3895
|
context.setTransform(new DOMMatrix);
|
|
3688
|
-
if (precompositing.needsFilter) {
|
|
3689
|
-
context.filter = precompositing.needsFilter;
|
|
3690
|
-
}
|
|
3691
3896
|
context.drawImage(drawable, 0, drawable.height - rectAfterTransforms.height, rectAfterTransforms.width, rectAfterTransforms.height, rectAfterTransforms.left - parentRect.x, rectAfterTransforms.top - parentRect.y, rectAfterTransforms.width, rectAfterTransforms.height);
|
|
3692
|
-
context.filter = previousFilter;
|
|
3693
3897
|
context.setTransform(previousTransform);
|
|
3694
3898
|
Internals6.Log.trace({
|
|
3695
3899
|
logLevel,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/web-renderer"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/web-renderer",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.450",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"scripts": {
|
|
@@ -22,16 +22,19 @@
|
|
|
22
22
|
"@mediabunny/mp3-encoder": "1.39.2",
|
|
23
23
|
"@mediabunny/aac-encoder": "1.39.2",
|
|
24
24
|
"@mediabunny/flac-encoder": "1.39.2",
|
|
25
|
-
"@remotion/licensing": "4.0.
|
|
26
|
-
"remotion": "4.0.
|
|
25
|
+
"@remotion/licensing": "4.0.449",
|
|
26
|
+
"remotion": "4.0.449",
|
|
27
27
|
"mediabunny": "1.39.2"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@react-three/fiber": "9.2.0",
|
|
31
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
32
|
-
"@remotion/
|
|
33
|
-
"@remotion/
|
|
34
|
-
"@remotion/
|
|
31
|
+
"@remotion/eslint-config-internal": "4.0.449",
|
|
32
|
+
"@remotion/paths": "4.0.449",
|
|
33
|
+
"@remotion/player": "4.0.449",
|
|
34
|
+
"@remotion/media": "4.0.449",
|
|
35
|
+
"@remotion/shapes": "4.0.449",
|
|
36
|
+
"@remotion/three": "4.0.449",
|
|
37
|
+
"@remotion/transitions": "4.0.449",
|
|
35
38
|
"@types/three": "0.170.0",
|
|
36
39
|
"@typescript/native-preview": "7.0.0-dev.20260217.1",
|
|
37
40
|
"@vitejs/plugin-react": "4.3.4",
|