@rocketium/auto-adapt 2.0.1 → 2.2.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/dist/index.mjs CHANGED
@@ -1,897 +1 @@
1
- // src/constants.ts
2
- var FALLBACK_AUTO_FIT_SIZES = [1, Infinity];
3
- var THRESHOLD_FOR_NOT_SKEWING = 90;
4
- var ASPECT_RATIO_WEIGHT = 0.9;
5
- var SCALE_DISTANCE_WEIGHT = 0.1;
6
- var MIN_MATCH_PERCENTAGE = 20;
7
- var MAX_MATCH_PERCENTAGE = 100;
8
- var DEFAULT_BORDER_PROPERTIES = {
9
- stroke: "rgba(0, 0, 0, 1)",
10
- strokeWidth: 0,
11
- strokeDashArray: [0, 0]
12
- };
13
-
14
- // src/utils/sizeMatching.ts
15
- var getNormalizedSizeValue = (sizeValue) => {
16
- switch (sizeValue) {
17
- case "square":
18
- return "720x720";
19
- case "landscape":
20
- return "1280x720";
21
- case "portrait":
22
- return "720x1280";
23
- default:
24
- return sizeValue;
25
- }
26
- };
27
- var getEuclideanDistanceBetweenPoints = ({
28
- x1,
29
- y1,
30
- x2,
31
- y2
32
- }) => {
33
- const widthDifference = x2 - x1;
34
- const heightDifference = y2 - y1;
35
- return Math.sqrt(widthDifference * widthDifference + heightDifference * heightDifference);
36
- };
37
- var getEuclideanDistanceBetweenSizes = ({ size1, size2 }) => {
38
- const firstSize = getNormalizedSizeValue(size1);
39
- const secondSize = getNormalizedSizeValue(size2);
40
- const [firstSizeWidth, firstSizeHeight] = firstSize.split("x").map(Number);
41
- const [secondSizeWidth, secondSizeHeight] = secondSize.split("x").map(Number);
42
- return getEuclideanDistanceBetweenPoints({
43
- x1: firstSizeWidth ?? 0,
44
- y1: firstSizeHeight ?? 0,
45
- x2: secondSizeWidth ?? 0,
46
- y2: secondSizeHeight ?? 0
47
- });
48
- };
49
- var computeSizeMatchScores = (sizes, adaptSize) => {
50
- const [adaptWidth, adaptHeight] = getNormalizedSizeValue(adaptSize).split("x").map(Number);
51
- const adaptRatio = adaptWidth / adaptHeight;
52
- const sizeDistanceMap = /* @__PURE__ */ new Map();
53
- for (const size of sizes) {
54
- const ratio = size.width / size.height;
55
- if (isNaN(ratio) || isNaN(adaptRatio)) continue;
56
- const aspectRatioDistance = Math.abs(adaptRatio - ratio);
57
- const euclideanDistance = getEuclideanDistanceBetweenPoints({
58
- x1: adaptWidth,
59
- y1: adaptHeight,
60
- x2: size.width,
61
- y2: size.height
62
- });
63
- sizeDistanceMap.set(size.key, { aspectRatioDistance, euclideanDistance });
64
- }
65
- const maxAspectRatioDistance = Math.max(...Array.from(sizeDistanceMap.values()).map((v) => v.aspectRatioDistance));
66
- const maxEuclideanDistance = Math.max(...Array.from(sizeDistanceMap.values()).map((v) => v.euclideanDistance));
67
- const scored = [];
68
- for (const size of sizes) {
69
- const distances = sizeDistanceMap.get(size.key);
70
- if (!distances) {
71
- scored.push({ ...size, matchPercentage: MIN_MATCH_PERCENTAGE });
72
- continue;
73
- }
74
- const normalizedAspectRatio = maxAspectRatioDistance === 0 ? 1 : 1 - distances.aspectRatioDistance / maxAspectRatioDistance;
75
- const normalizedEuclidean = maxEuclideanDistance === 0 ? 1 : 1 - distances.euclideanDistance / maxEuclideanDistance;
76
- const rawScore = normalizedAspectRatio * ASPECT_RATIO_WEIGHT + normalizedEuclidean * SCALE_DISTANCE_WEIGHT;
77
- const matchPercentage = Math.round(
78
- Math.max(MIN_MATCH_PERCENTAGE, Math.min(MAX_MATCH_PERCENTAGE, rawScore * 100))
79
- );
80
- scored.push({ ...size, matchPercentage });
81
- }
82
- scored.sort((a, b) => b.matchPercentage - a.matchPercentage);
83
- return scored;
84
- };
85
- var findClosestSizeWithMatches = ({
86
- availableSizes,
87
- adaptSize
88
- }) => {
89
- const sizeInputs = availableSizes.map((s) => {
90
- const normalized = getNormalizedSizeValue(s);
91
- const [width, height] = normalized.split("x").map(Number);
92
- return { key: s, width, height };
93
- });
94
- const scored = computeSizeMatchScores(sizeInputs, adaptSize);
95
- const [adaptWidth, adaptHeight] = getNormalizedSizeValue(adaptSize).split("x").map(Number);
96
- const adaptRatio = adaptWidth / adaptHeight;
97
- let closestSize = availableSizes[0];
98
- let minAspectRatioDistance = Number.MAX_VALUE;
99
- let minEuclideanDistance = Number.MAX_VALUE;
100
- for (const input of sizeInputs) {
101
- const ratio = input.width / input.height;
102
- if (isNaN(ratio) || isNaN(adaptRatio)) continue;
103
- const aspectRatioDistance = Math.abs(adaptRatio - ratio);
104
- const euclideanDistance = getEuclideanDistanceBetweenPoints({
105
- x1: adaptWidth,
106
- y1: adaptHeight,
107
- x2: input.width,
108
- y2: input.height
109
- });
110
- if (aspectRatioDistance < minAspectRatioDistance || aspectRatioDistance === minAspectRatioDistance && euclideanDistance < minEuclideanDistance) {
111
- minAspectRatioDistance = aspectRatioDistance;
112
- minEuclideanDistance = euclideanDistance;
113
- closestSize = input.key;
114
- }
115
- }
116
- return {
117
- closestSize,
118
- sortedMatches: scored.reduce(
119
- (acc, { key, matchPercentage }) => {
120
- acc[key] = matchPercentage;
121
- return acc;
122
- },
123
- {}
124
- )
125
- };
126
- };
127
- var findClosestSizeObjectsWithMatches = ({
128
- availableSizes,
129
- adaptSize
130
- }) => {
131
- if (Object.keys(availableSizes).length === 0) {
132
- return [];
133
- }
134
- const sizeInputs = Object.entries(availableSizes).map(([key, sizeObj]) => ({
135
- key,
136
- width: sizeObj.width,
137
- height: sizeObj.height
138
- }));
139
- const scored = computeSizeMatchScores(sizeInputs, adaptSize);
140
- return scored.map((s) => ({
141
- _id: s.key,
142
- ...availableSizes[s.key],
143
- matchPercentage: s.matchPercentage
144
- }));
145
- };
146
- var findBestReferenceSize = (availableSizes, targetSize) => {
147
- const sizeKeys = Object.keys(availableSizes);
148
- if (sizeKeys.length === 1) {
149
- return sizeKeys[0];
150
- }
151
- try {
152
- const sortedMatches = findClosestSizeObjectsWithMatches({
153
- availableSizes,
154
- adaptSize: targetSize
155
- });
156
- return sortedMatches[0]?._id || sizeKeys[0];
157
- } catch (error) {
158
- console.warn("Error finding closest size, using first available:", error);
159
- return sizeKeys[0];
160
- }
161
- };
162
-
163
- // src/utils/typeGuards.ts
164
- var isTextJSON = (object) => {
165
- return object.dataType === "TEXT";
166
- };
167
- var isImageJSON = (object) => {
168
- return object.dataType === "IMAGE";
169
- };
170
- var isShapeJSON = (object) => {
171
- return object.dataType === "SHAPE";
172
- };
173
- var isSVGContainerJSON = (object) => {
174
- return object?.type === "svg-container" && object?.dataType === "SHAPE";
175
- };
176
- var isRoundedRectJSON = (object) => {
177
- return object?.type === "rounded-rect" && object?.dataType === "SHAPE";
178
- };
179
- var isGroupJSON = (object) => {
180
- return object?.dataType === "GROUP";
181
- };
182
- var isCreativeBoxJSON = (object) => {
183
- return object?.dataType === "CREATIVE_BOX";
184
- };
185
- var isAudioJSON = (object) => {
186
- return object?.dataType === "AUDIO";
187
- };
188
-
189
- // src/utils/scaling.ts
190
- var num = (obj, key, fallback = 0) => {
191
- if (key in obj) {
192
- const val = obj[key];
193
- return typeof val === "number" ? val : fallback;
194
- }
195
- return fallback;
196
- };
197
- var getAreaPercentageOfElementOnCanvasJSON = ({
198
- element,
199
- canvasDimensions
200
- }) => {
201
- const canvasWidth = typeof canvasDimensions.width === "number" ? canvasDimensions.width : 0;
202
- const canvasHeight = typeof canvasDimensions.height === "number" ? canvasDimensions.height : 0;
203
- const elementWidth = ("width" in element ? element.width : 1) * ("scaleX" in element ? element.scaleX : 1);
204
- const elementHeight = ("height" in element ? element.height : 1) * ("scaleY" in element ? element.scaleY ?? 1 : 1);
205
- const elementTop = "top" in element ? element.top : 0;
206
- const elementLeft = "left" in element ? element.left : 0;
207
- const elementRight = elementLeft + elementWidth;
208
- const elementBottom = elementTop + elementHeight;
209
- const canvasArea = canvasWidth * canvasHeight;
210
- if (canvasArea === 0) {
211
- return 0;
212
- }
213
- const intersectionWidth = Math.min(elementRight, canvasWidth) - Math.max(elementLeft, 0);
214
- const intersectionHeight = Math.min(elementBottom, canvasHeight) - Math.max(elementTop, 0);
215
- const intersectionArea = Math.max(intersectionWidth, 0) * Math.max(intersectionHeight, 0);
216
- return Math.round(intersectionArea / canvasArea * 100);
217
- };
218
- var checkIfElementShouldBeSkewed = ({
219
- areaPercentage,
220
- referenceLengths,
221
- type
222
- }) => {
223
- if (type === "GROUP") return false;
224
- if (areaPercentage > THRESHOLD_FOR_NOT_SKEWING) return true;
225
- const spansFullWidth = Math.floor(referenceLengths.left) <= 0 && Math.floor(referenceLengths.width) >= referenceLengths.canvasWidth;
226
- const spansFullHeight = Math.floor(referenceLengths.top) <= 0 && Math.floor(referenceLengths.height) >= referenceLengths.canvasHeight;
227
- return spansFullWidth || spansFullHeight;
228
- };
229
- var scaleCornerRadius = (cornerRadius, scalingRatio) => {
230
- return {
231
- tl: (cornerRadius?.tl || 0) * scalingRatio,
232
- tr: (cornerRadius?.tr || 0) * scalingRatio,
233
- bl: (cornerRadius?.bl || 0) * scalingRatio,
234
- br: (cornerRadius?.br || 0) * scalingRatio
235
- };
236
- };
237
- var scalePadding = (padding, scalingRatio) => {
238
- const p = padding ?? { top: 0, right: 0, bottom: 0, left: 0 };
239
- return {
240
- ...p,
241
- top: p.top ? p.top * scalingRatio : 0,
242
- right: p.right ? p.right * scalingRatio : 0,
243
- bottom: p.bottom ? p.bottom * scalingRatio : 0,
244
- left: p.left ? p.left * scalingRatio : 0
245
- };
246
- };
247
- var getScaledBorderJSON = ({
248
- object,
249
- scalingRatio
250
- }) => {
251
- if (isCreativeBoxJSON(object) || isGroupJSON(object) || isAudioJSON(object)) {
252
- return {};
253
- }
254
- if (!("border" in object) || !object?.border) return {};
255
- const border = object.border;
256
- if (!border.strokeWidth) return {};
257
- return {
258
- border: {
259
- ...DEFAULT_BORDER_PROPERTIES,
260
- ...border,
261
- strokeWidth: border.strokeWidth * scalingRatio
262
- }
263
- };
264
- };
265
- var adaptWordStyleFontSizes = ({
266
- wordStyle,
267
- scalingRatio
268
- }) => {
269
- if (!wordStyle || wordStyle.length === 0) {
270
- return wordStyle;
271
- }
272
- return wordStyle.map((style) => {
273
- if (!style.data?.styles?.fontSize) {
274
- return style;
275
- }
276
- const currentFontSizeUnit = style.data.styles.fontSizeUnit ?? "%";
277
- const adaptedFontSize = currentFontSizeUnit === "px" ? Math.round(style.data.styles.fontSize * scalingRatio) : style.data.styles.fontSize;
278
- return {
279
- ...style,
280
- data: {
281
- ...style.data,
282
- styles: {
283
- ...style.data.styles,
284
- fontSize: adaptedFontSize,
285
- fontSizeUnit: currentFontSizeUnit
286
- }
287
- }
288
- };
289
- });
290
- };
291
- var scaleAutoFitSizes = (autoFitSizes, scalingRatio, fallbackHeight) => {
292
- if (autoFitSizes && autoFitSizes.length === 2) {
293
- return autoFitSizes.map((size) => Math.ceil((size ?? fallbackHeight) * scalingRatio));
294
- }
295
- return [...FALLBACK_AUTO_FIT_SIZES];
296
- };
297
- var getValuesWithoutSkewingJSON = ({
298
- closestSize,
299
- adaptSize,
300
- object
301
- }) => {
302
- const referenceSize = getNormalizedSizeValue(closestSize);
303
- const [referenceWidth, referenceHeight] = referenceSize.split("x").map(Number);
304
- const [adaptWidth, adaptHeight] = adaptSize.split("x").map(Number);
305
- const top = num(object, "top");
306
- const left = num(object, "left");
307
- const scaleX = num(object, "scaleX", 1);
308
- const scaleY = num(object, "scaleY", 1);
309
- const width = num(object, "width", 1) * scaleX;
310
- const height = num(object, "height", 1) * scaleY;
311
- const widthScaleFactor = adaptWidth / referenceWidth;
312
- const heightScaleFactor = adaptHeight / referenceHeight;
313
- const scaleFactor = Math.min(widthScaleFactor, heightScaleFactor);
314
- const elementWidthInNewSize = Math.ceil(width * scaleFactor);
315
- const elementHeightInNewSize = Math.ceil(height * scaleFactor);
316
- const distanceFromRight = Math.abs(left + width - referenceWidth);
317
- const distanceFromBottom = Math.abs(top + height - referenceHeight);
318
- const distanceFromLeft = Math.abs(left);
319
- const distanceFromTop = Math.abs(top);
320
- const ALIGNMENT_THRESHOLD = 1;
321
- if (distanceFromRight < ALIGNMENT_THRESHOLD || distanceFromLeft < ALIGNMENT_THRESHOLD || distanceFromBottom < ALIGNMENT_THRESHOLD || distanceFromTop < ALIGNMENT_THRESHOLD) {
322
- let elementLeftInNewSize;
323
- let elementTopInNewSize;
324
- if (distanceFromRight < ALIGNMENT_THRESHOLD) {
325
- elementLeftInNewSize = adaptWidth - elementWidthInNewSize;
326
- } else if (distanceFromLeft < ALIGNMENT_THRESHOLD) {
327
- elementLeftInNewSize = 0;
328
- } else {
329
- const elementLeftPercentage = left / referenceWidth;
330
- elementLeftInNewSize = Math.ceil(elementLeftPercentage * adaptWidth);
331
- }
332
- if (distanceFromBottom < ALIGNMENT_THRESHOLD) {
333
- elementTopInNewSize = adaptHeight - elementHeightInNewSize;
334
- } else if (distanceFromTop < ALIGNMENT_THRESHOLD) {
335
- elementTopInNewSize = 0;
336
- } else {
337
- const elementTopPercentage = top / referenceHeight;
338
- elementTopInNewSize = Math.ceil(elementTopPercentage * adaptHeight);
339
- }
340
- return {
341
- left: elementLeftInNewSize,
342
- top: elementTopInNewSize,
343
- width: elementWidthInNewSize / scaleX,
344
- height: elementHeightInNewSize / scaleY
345
- };
346
- }
347
- const elementCenterX = left + width / 2;
348
- const elementCenterY = top + height / 2;
349
- const elementRight = left + width;
350
- const elementBottom = top + height;
351
- const canvasCenterX = referenceWidth / 2;
352
- const canvasCenterY = referenceHeight / 2;
353
- const leftArea = Math.max(0, Math.min(elementRight, canvasCenterX) - Math.max(left, 0)) * Math.max(0, Math.min(elementBottom, referenceHeight) - Math.max(top, 0));
354
- const rightArea = Math.max(0, Math.min(elementRight, referenceWidth) - Math.max(left, canvasCenterX)) * Math.max(0, Math.min(elementBottom, referenceHeight) - Math.max(top, 0));
355
- const totalArea = leftArea + rightArea;
356
- const CENTER_THRESHOLD = 0.05;
357
- const isHorizontallyCentered = Math.abs(leftArea - rightArea) / totalArea < CENTER_THRESHOLD;
358
- if (isHorizontallyCentered) {
359
- const centerXPercentage = elementCenterX / referenceWidth;
360
- const centerYPercentage = elementCenterY / referenceHeight;
361
- const newCenterX = centerXPercentage * adaptWidth;
362
- const newCenterY = centerYPercentage * adaptHeight;
363
- return {
364
- left: newCenterX - elementWidthInNewSize / 2,
365
- top: newCenterY - elementHeightInNewSize / 2,
366
- width: elementWidthInNewSize,
367
- height: elementHeightInNewSize
368
- };
369
- }
370
- const isInRightHalf = elementCenterX > canvasCenterX;
371
- const isInBottomHalf = elementCenterY > canvasCenterY;
372
- const referenceX = isInRightHalf ? elementRight / referenceWidth : left / referenceWidth;
373
- const referenceY = isInBottomHalf ? elementBottom / referenceHeight : top / referenceHeight;
374
- const newX = referenceX * adaptWidth;
375
- const newY = referenceY * adaptHeight;
376
- return {
377
- left: isInRightHalf ? newX - elementWidthInNewSize : newX,
378
- top: isInBottomHalf ? newY - elementHeightInNewSize : newY,
379
- width: elementWidthInNewSize,
380
- height: elementHeightInNewSize
381
- };
382
- };
383
- var adaptTextNoSkew = (object, values, scalingRatio, closestHeight) => {
384
- return {
385
- ...object,
386
- left: values.left,
387
- top: values.top,
388
- width: values.width,
389
- height: values.height,
390
- wordSpacing: object.wordSpacing ? object.wordSpacing * scalingRatio : 0,
391
- padding: scalePadding(object.padding, scalingRatio),
392
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio),
393
- ...getScaledBorderJSON({ object, scalingRatio }),
394
- autoFitSizes: scaleAutoFitSizes(object.autoFitSizes, scalingRatio, closestHeight),
395
- fontSize: object.fontSize * scalingRatio,
396
- wordStyle: adaptWordStyleFontSizes({ wordStyle: object.wordStyle || [], scalingRatio })
397
- };
398
- };
399
- var adaptImageNoSkew = (object, values, scalingRatio, widthRatio, heightRatio) => {
400
- return {
401
- ...object,
402
- left: values.left,
403
- top: values.top,
404
- width: values.width,
405
- height: values.height,
406
- imageScale: (object.imageScale ?? 1) * scalingRatio,
407
- imageLeft: (object.imageLeft ?? 0) * widthRatio,
408
- imageTop: (object.imageTop ?? 0) * heightRatio,
409
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio),
410
- ...getScaledBorderJSON({ object, scalingRatio })
411
- };
412
- };
413
- var adaptSvgNoSkew = (object, values, scalingRatio, widthRatio, heightRatio) => {
414
- return {
415
- ...object,
416
- left: values.left,
417
- top: values.top,
418
- width: values.width,
419
- height: values.height,
420
- imageScale: (object.imageScale ?? 1) * scalingRatio,
421
- imageLeft: (object.imageLeft ?? 0) * widthRatio,
422
- imageTop: (object.imageTop ?? 0) * heightRatio,
423
- ...getScaledBorderJSON({ object, scalingRatio })
424
- };
425
- };
426
- var adaptRoundedRectNoSkew = (object, values, scalingRatio) => {
427
- return {
428
- ...object,
429
- left: values.left,
430
- top: values.top,
431
- width: values.width,
432
- height: values.height,
433
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio),
434
- ...getScaledBorderJSON({ object, scalingRatio })
435
- };
436
- };
437
- var adaptShapeNoSkew = (object, values, scalingRatio) => {
438
- return {
439
- ...object,
440
- left: values.left,
441
- top: values.top,
442
- scaleX: (object.scaleX ?? 1) * scalingRatio,
443
- scaleY: (object.scaleY ?? 1) * scalingRatio,
444
- ...getScaledBorderJSON({ object, scalingRatio })
445
- };
446
- };
447
- var adaptTextSkew = (object, widthRatio, heightRatio, scalingRatio, closestHeight) => {
448
- return {
449
- ...object,
450
- left: object.left * widthRatio,
451
- top: object.top * heightRatio,
452
- width: object.width * widthRatio,
453
- height: object.height * heightRatio,
454
- autoFitSizes: scaleAutoFitSizes(object.autoFitSizes, scalingRatio, closestHeight),
455
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio),
456
- fontSize: object.fontSize * scalingRatio,
457
- wordStyle: adaptWordStyleFontSizes({ wordStyle: object.wordStyle || [], scalingRatio })
458
- };
459
- };
460
- var adaptImageSkew = (object, widthRatio, heightRatio, scalingRatio) => {
461
- return {
462
- ...object,
463
- left: object.left * widthRatio,
464
- top: object.top * heightRatio,
465
- width: object.width * widthRatio,
466
- height: object.height * heightRatio,
467
- imageScale: (object.imageScale ?? 1) * scalingRatio,
468
- imageLeft: (object.imageLeft ?? 0) * widthRatio,
469
- imageTop: (object.imageTop ?? 0) * heightRatio,
470
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio)
471
- };
472
- };
473
- var adaptSvgSkew = (object, widthRatio, heightRatio, scalingRatio) => {
474
- return {
475
- ...object,
476
- left: object.left * widthRatio,
477
- top: object.top * heightRatio,
478
- width: object.width * widthRatio,
479
- height: object.height * heightRatio,
480
- imageScale: (object.imageScale ?? 1) * scalingRatio,
481
- imageLeft: (object.imageLeft ?? 0) * widthRatio,
482
- imageTop: (object.imageTop ?? 0) * heightRatio,
483
- ...getScaledBorderJSON({ object, scalingRatio })
484
- };
485
- };
486
- var adaptRoundedRectSkew = (object, widthRatio, heightRatio, scalingRatio) => {
487
- return {
488
- ...object,
489
- left: object.left * widthRatio,
490
- top: object.top * heightRatio,
491
- width: object.width * widthRatio,
492
- height: object.height * heightRatio,
493
- cornerRadius: scaleCornerRadius(object.cornerRadius, scalingRatio),
494
- ...getScaledBorderJSON({ object, scalingRatio })
495
- };
496
- };
497
- var adaptShapeSkew = (object, widthRatio, heightRatio, scalingRatio) => {
498
- return {
499
- ...object,
500
- left: object.left * widthRatio,
501
- top: object.top * heightRatio,
502
- scaleX: (object.scaleX ?? 1) * widthRatio,
503
- scaleY: (object.scaleY ?? 1) * heightRatio,
504
- ...getScaledBorderJSON({ object, scalingRatio })
505
- };
506
- };
507
- var adaptGroupChildText = (groupObject, scalingRatio, closestHeight, parentObject) => {
508
- return {
509
- ...groupObject,
510
- left: groupObject.left * scalingRatio,
511
- top: groupObject.top * scalingRatio,
512
- width: groupObject.width * scalingRatio,
513
- height: groupObject.height * scalingRatio,
514
- wordSpacing: groupObject.wordSpacing ? groupObject.wordSpacing * scalingRatio : 0,
515
- padding: scalePadding(groupObject.padding, scalingRatio),
516
- cornerRadius: scaleCornerRadius(groupObject.cornerRadius, scalingRatio),
517
- ...getScaledBorderJSON({ object: parentObject, scalingRatio }),
518
- autoFitSizes: scaleAutoFitSizes(groupObject.autoFitSizes, scalingRatio, closestHeight),
519
- fontSize: groupObject.fontSize * scalingRatio,
520
- wordStyle: adaptWordStyleFontSizes({ wordStyle: groupObject.wordStyle || [], scalingRatio })
521
- };
522
- };
523
- var adaptGroupChildImage = (groupObject, scalingRatio, parentObject) => {
524
- return {
525
- ...groupObject,
526
- left: groupObject.left * scalingRatio,
527
- top: groupObject.top * scalingRatio,
528
- width: groupObject.width * scalingRatio,
529
- height: groupObject.height * scalingRatio,
530
- imageScale: (groupObject.imageScale ?? 1) * scalingRatio,
531
- imageLeft: (groupObject.imageLeft ?? 0) * scalingRatio,
532
- imageTop: (groupObject.imageTop ?? 0) * scalingRatio,
533
- cornerRadius: scaleCornerRadius(groupObject.cornerRadius, scalingRatio),
534
- ...getScaledBorderJSON({ object: parentObject, scalingRatio })
535
- };
536
- };
537
- var adaptGroupChildSvg = (svgContainer, scalingRatio, parentObject) => {
538
- return {
539
- ...svgContainer,
540
- left: svgContainer.left * scalingRatio,
541
- top: svgContainer.top * scalingRatio,
542
- width: svgContainer.width * scalingRatio,
543
- height: svgContainer.height * scalingRatio,
544
- imageScale: (svgContainer.imageScale ?? 1) * scalingRatio,
545
- imageLeft: (svgContainer.imageLeft ?? 0) * scalingRatio,
546
- imageTop: (svgContainer.imageTop ?? 0) * scalingRatio,
547
- ...getScaledBorderJSON({ object: parentObject, scalingRatio })
548
- };
549
- };
550
- var adaptGroupChildRoundedRect = (roundedRectObject, scalingRatio, parentObject) => {
551
- return {
552
- ...roundedRectObject,
553
- left: roundedRectObject.left * scalingRatio,
554
- top: roundedRectObject.top * scalingRatio,
555
- width: roundedRectObject.width * scalingRatio,
556
- height: roundedRectObject.height * scalingRatio,
557
- cornerRadius: scaleCornerRadius(roundedRectObject.cornerRadius, scalingRatio),
558
- ...getScaledBorderJSON({ object: parentObject, scalingRatio })
559
- };
560
- };
561
- var adaptGroupChildShape = (groupObject, scalingRatio, parentObject) => {
562
- return {
563
- ...groupObject,
564
- left: num(groupObject, "left") * scalingRatio,
565
- top: num(groupObject, "top") * scalingRatio,
566
- scaleX: num(groupObject, "scaleX", 1) * scalingRatio,
567
- scaleY: num(groupObject, "scaleY", 1) * scalingRatio,
568
- ...getScaledBorderJSON({ object: parentObject, scalingRatio })
569
- };
570
- };
571
-
572
- // src/adapter.ts
573
- var getAdaptedObjectsJSON = ({
574
- adaptSize,
575
- objects,
576
- closestSize
577
- }) => {
578
- const [adaptWidth, adaptHeight] = adaptSize.split("x").map(Number);
579
- const [closestWidth, closestHeight] = closestSize.split("x").map(Number);
580
- const widthRatio = adaptWidth / closestWidth;
581
- const heightRatio = adaptHeight / closestHeight;
582
- const scalingRatio = Math.min(widthRatio, heightRatio);
583
- const newObjects = {};
584
- for (const objectId of Object.keys(objects)) {
585
- const object = objects[objectId];
586
- if (object.dataType === "CREATIVE_BOX") {
587
- newObjects[objectId] = {
588
- ...object,
589
- height: adaptHeight,
590
- width: adaptWidth
591
- };
592
- continue;
593
- }
594
- if (object.dataType === "AUDIO") {
595
- newObjects[objectId] = object;
596
- continue;
597
- }
598
- getAreaPercentageOfElementOnCanvasJSON({
599
- element: object,
600
- canvasDimensions: { width: closestWidth, height: closestHeight }
601
- });
602
- const areaPercentage = getAreaPercentageOfElementOnCanvasJSON({
603
- element: object,
604
- canvasDimensions: { width: closestWidth, height: closestHeight }
605
- });
606
- const shouldSkew = checkIfElementShouldBeSkewed({
607
- areaPercentage,
608
- referenceLengths: {
609
- left: object.left ?? 0,
610
- top: object.top ?? 0,
611
- width: object.width ?? 1,
612
- height: object.height ?? 1,
613
- canvasWidth: closestWidth,
614
- canvasHeight: closestHeight
615
- },
616
- type: object.dataType
617
- });
618
- if (!shouldSkew) {
619
- const values = getValuesWithoutSkewingJSON({ closestSize, adaptSize, object });
620
- if (values.left === 0 && values.height === 0 && values.top === 0 && values.width === 0) {
621
- throw new Error("Invalid values");
622
- }
623
- if ("groupPath" in object && object.groupPath) {
624
- continue;
625
- }
626
- if (isTextJSON(object)) {
627
- newObjects[objectId] = adaptTextNoSkew(object, values, scalingRatio, closestHeight);
628
- continue;
629
- }
630
- if (isImageJSON(object)) {
631
- newObjects[objectId] = adaptImageNoSkew(object, values, scalingRatio, widthRatio, heightRatio);
632
- continue;
633
- }
634
- if (isShapeJSON(object)) {
635
- if (isSVGContainerJSON(object)) {
636
- newObjects[objectId] = adaptSvgNoSkew(object, values, scalingRatio, widthRatio, heightRatio);
637
- continue;
638
- }
639
- if (isRoundedRectJSON(object)) {
640
- newObjects[objectId] = adaptRoundedRectNoSkew(object, values, scalingRatio);
641
- continue;
642
- }
643
- newObjects[objectId] = adaptShapeNoSkew(object, values, scalingRatio);
644
- continue;
645
- }
646
- if (isGroupJSON(object)) {
647
- newObjects[objectId] = {
648
- ...object,
649
- left: values.left,
650
- top: values.top,
651
- width: values.width,
652
- height: values.height
653
- };
654
- for (const groupObjectId of object.objects) {
655
- const groupObject = objects[groupObjectId];
656
- if (!groupObject) continue;
657
- if (isTextJSON(groupObject)) {
658
- newObjects[groupObjectId] = adaptGroupChildText(
659
- groupObject,
660
- scalingRatio,
661
- closestHeight,
662
- object
663
- );
664
- continue;
665
- }
666
- if (isImageJSON(groupObject)) {
667
- newObjects[groupObjectId] = adaptGroupChildImage(groupObject, scalingRatio, object);
668
- continue;
669
- }
670
- if (isShapeJSON(groupObject)) {
671
- if (isSVGContainerJSON(groupObject)) {
672
- newObjects[groupObjectId] = adaptGroupChildSvg(groupObject, scalingRatio, object);
673
- continue;
674
- }
675
- if (isRoundedRectJSON(groupObject)) {
676
- newObjects[groupObjectId] = adaptGroupChildRoundedRect(
677
- groupObject,
678
- scalingRatio,
679
- object
680
- );
681
- continue;
682
- }
683
- newObjects[groupObjectId] = adaptGroupChildShape(groupObject, scalingRatio, object);
684
- continue;
685
- }
686
- }
687
- continue;
688
- }
689
- }
690
- if (isTextJSON(object)) {
691
- newObjects[objectId] = adaptTextSkew(object, widthRatio, heightRatio, scalingRatio, closestHeight);
692
- continue;
693
- }
694
- if (isImageJSON(object)) {
695
- newObjects[objectId] = adaptImageSkew(object, widthRatio, heightRatio, scalingRatio);
696
- continue;
697
- }
698
- if (isShapeJSON(object)) {
699
- if (isSVGContainerJSON(object)) {
700
- newObjects[objectId] = adaptSvgSkew(object, widthRatio, heightRatio, scalingRatio);
701
- continue;
702
- }
703
- if (isRoundedRectJSON(object)) {
704
- newObjects[objectId] = adaptRoundedRectSkew(object, widthRatio, heightRatio, scalingRatio);
705
- continue;
706
- }
707
- newObjects[objectId] = adaptShapeSkew(object, widthRatio, heightRatio, scalingRatio);
708
- continue;
709
- }
710
- newObjects[objectId] = {
711
- ...object,
712
- left: num(object, "left") * widthRatio,
713
- top: num(object, "top") * heightRatio,
714
- width: num(object, "width", 1) * widthRatio,
715
- height: num(object, "height", 1) * heightRatio,
716
- ...getScaledBorderJSON({ object, scalingRatio })
717
- };
718
- }
719
- return newObjects;
720
- };
721
- var resolveObjectsForSize = (objects, sizeId) => {
722
- const resolved = {};
723
- for (const [id, obj] of Object.entries(objects)) {
724
- const sizeOverrides = obj.overrides?.[sizeId] || {};
725
- const { overrides: _overrides, zIndex: _zIndex, ...base } = obj;
726
- resolved[id] = { ...base, ...sizeOverrides };
727
- }
728
- return resolved;
729
- };
730
- var applyAdaptedAsOverrides = (originalObjects, adaptedObjects, newSizeId) => {
731
- const result = JSON.parse(JSON.stringify(originalObjects));
732
- for (const [layerId, adapted] of Object.entries(adaptedObjects)) {
733
- if (!result[layerId]) continue;
734
- const existingOverrides = result[layerId].overrides || {};
735
- result[layerId].overrides = {
736
- ...existingOverrides,
737
- [newSizeId]: {
738
- ...adapted,
739
- zIndex: result[layerId].overrides?.[newSizeId]?.zIndex ?? result[layerId].zIndex ?? 0
740
- }
741
- };
742
- }
743
- return result;
744
- };
745
- var buildNewCapsule = ({
746
- originalCapsule,
747
- updatedObjects,
748
- sizeId,
749
- referenceCreativeId,
750
- sizeToGenerate,
751
- sizeName,
752
- sizeCategory,
753
- videoLength
754
- }) => {
755
- const [widthOfNewSize, heightOfNewSize] = sizeToGenerate.split("x").map(Number);
756
- const canvasData = JSON.parse(JSON.stringify(originalCapsule.canvasData));
757
- canvasData.variant.objects = updatedObjects;
758
- canvasData.variant.sizes[sizeId] = {
759
- width: widthOfNewSize,
760
- height: heightOfNewSize,
761
- id: sizeId,
762
- displayName: sizeName || sizeToGenerate,
763
- rulers: [],
764
- ...videoLength !== void 0 && { videoLength }
765
- };
766
- const creativesOrder = originalCapsule.creativesOrder;
767
- const finalCreativesOrder = creativesOrder && creativesOrder.length > 0 ? [...creativesOrder, sizeId] : [referenceCreativeId, sizeId];
768
- const newSizeData = {
769
- name: sizeName || sizeToGenerate,
770
- width: widthOfNewSize,
771
- height: heightOfNewSize,
772
- active: true,
773
- thumbnail: "",
774
- creativeUrl: "",
775
- ...sizeCategory && { category: sizeCategory }
776
- };
777
- return {
778
- ...originalCapsule,
779
- canvasData,
780
- savedCustomDimensions: {
781
- ...originalCapsule.savedCustomDimensions,
782
- [sizeId]: newSizeData
783
- },
784
- newAddedSizes: {
785
- ...originalCapsule.newAddedSizes,
786
- [sizeId]: newSizeData
787
- },
788
- creativesOrder: finalCreativesOrder
789
- };
790
- };
791
- var generateBaseLayoutForSize = ({
792
- originalCapsule,
793
- capsuleId,
794
- creativeId,
795
- sizeId,
796
- sizeToGenerate,
797
- sizeName,
798
- sizeCategory
799
- }) => {
800
- const availableSizes = originalCapsule.canvasData.variant?.sizes;
801
- if (!availableSizes || Object.keys(availableSizes).length === 0) {
802
- throw new Error(`No sizes available in capsule: ${capsuleId}`);
803
- }
804
- let referenceCreativeId;
805
- if (creativeId && availableSizes[creativeId]) {
806
- referenceCreativeId = creativeId;
807
- console.log(`[BaseLayoutAdapter] Using provided reference size: ${referenceCreativeId}`);
808
- } else {
809
- referenceCreativeId = findBestReferenceSize(availableSizes, sizeToGenerate);
810
- console.log(
811
- `[BaseLayoutAdapter] Found best reference size: ${referenceCreativeId} for target: ${sizeToGenerate}`
812
- );
813
- if (creativeId && !availableSizes[creativeId]) {
814
- console.warn(
815
- `[BaseLayoutAdapter] Provided creativeId ${creativeId} not found, using ${referenceCreativeId}`
816
- );
817
- }
818
- }
819
- const currentSize = availableSizes[referenceCreativeId];
820
- const closestSize = `${currentSize.width}x${currentSize.height}`;
821
- const variantObjects = originalCapsule.canvasData.variant.objects;
822
- const resolvedObjects = resolveObjectsForSize(variantObjects, referenceCreativeId);
823
- const adaptedObjects = getAdaptedObjectsJSON({
824
- adaptSize: sizeToGenerate,
825
- objects: resolvedObjects,
826
- closestSize
827
- });
828
- const updatedObjects = applyAdaptedAsOverrides(variantObjects, adaptedObjects, sizeId);
829
- return buildNewCapsule({
830
- originalCapsule,
831
- updatedObjects,
832
- sizeId,
833
- referenceCreativeId,
834
- sizeToGenerate,
835
- sizeName,
836
- sizeCategory,
837
- videoLength: currentSize?.videoLength
838
- });
839
- };
840
-
841
- // src/types/canvas.ts
842
- var CANVAS_EDITOR_ELEMENT = {
843
- TEXT: "TEXT",
844
- SHAPE: "SHAPE",
845
- IMAGE: "IMAGE",
846
- GROUP: "GROUP",
847
- CREATIVE_BOX: "CREATIVE_BOX",
848
- VIDEO: "VIDEO",
849
- AUDIO: "AUDIO",
850
- CANVAS_MASK: "CANVAS_MASK"
851
- };
852
- var CreativeElementCategory = /* @__PURE__ */ ((CreativeElementCategory2) => {
853
- CreativeElementCategory2["HERO_IMAGE"] = "HERO_IMAGE";
854
- CreativeElementCategory2["PRODUCT_IMAGE"] = "PRODUCT_IMAGE";
855
- CreativeElementCategory2["BACKGROUND"] = "BACKGROUND";
856
- CreativeElementCategory2["LOGO"] = "LOGO";
857
- CreativeElementCategory2["ICON"] = "ICON";
858
- CreativeElementCategory2["HEADLINE"] = "HEADLINE";
859
- CreativeElementCategory2["SUBHEADLINE"] = "SUBHEADLINE";
860
- CreativeElementCategory2["BODY_COPY"] = "BODY_COPY";
861
- CreativeElementCategory2["PRICE"] = "PRICE";
862
- CreativeElementCategory2["CTA"] = "CTA";
863
- CreativeElementCategory2["TERMS_CONDITIONS"] = "TERMS_CONDITIONS";
864
- CreativeElementCategory2["REVIEWS_TESTIMONIALS"] = "REVIEWS_TESTIMONIALS";
865
- CreativeElementCategory2["WARRANTY_INFO"] = "WARRANTY_INFO";
866
- CreativeElementCategory2["BADGE"] = "BADGE";
867
- CreativeElementCategory2["NEW_PRODUCT_LABEL"] = "NEW_PRODUCT_LABEL";
868
- CreativeElementCategory2["OTHER"] = "OTHER";
869
- return CreativeElementCategory2;
870
- })(CreativeElementCategory || {});
871
- var WORD_STYLE_TYPE = /* @__PURE__ */ ((WORD_STYLE_TYPE2) => {
872
- WORD_STYLE_TYPE2["WORD_STYLE"] = "WORD_STYLE";
873
- WORD_STYLE_TYPE2["MISSING_GLYPH"] = "MISSING_GLYPH";
874
- WORD_STYLE_TYPE2["VARIABLES"] = "VARIABLES";
875
- return WORD_STYLE_TYPE2;
876
- })(WORD_STYLE_TYPE || {});
877
- var TextAnimationType = /* @__PURE__ */ ((TextAnimationType2) => {
878
- TextAnimationType2["CHARACTER"] = "character";
879
- TextAnimationType2["WORD"] = "word";
880
- TextAnimationType2["LINE"] = "line";
881
- return TextAnimationType2;
882
- })(TextAnimationType || {});
883
- var AnimationSpecialCase = /* @__PURE__ */ ((AnimationSpecialCase2) => {
884
- AnimationSpecialCase2["TYPING_EFFECT"] = "typing-effect";
885
- AnimationSpecialCase2["NONE"] = "none";
886
- return AnimationSpecialCase2;
887
- })(AnimationSpecialCase || {});
888
-
889
- // src/types/capsule.ts
890
- var RULER_AXIS = {
891
- X: "x",
892
- Y: "y"
893
- };
894
-
895
- export { AnimationSpecialCase, CANVAS_EDITOR_ELEMENT, CreativeElementCategory, RULER_AXIS, TextAnimationType, WORD_STYLE_TYPE, adaptWordStyleFontSizes, applyAdaptedAsOverrides, buildNewCapsule, checkIfElementShouldBeSkewed, findBestReferenceSize, findClosestSizeObjectsWithMatches, findClosestSizeWithMatches, generateBaseLayoutForSize, getAdaptedObjectsJSON, getAreaPercentageOfElementOnCanvasJSON, getEuclideanDistanceBetweenSizes, getNormalizedSizeValue, getScaledBorderJSON, getValuesWithoutSkewingJSON, isAudioJSON, isCreativeBoxJSON, isGroupJSON, isImageJSON, isRoundedRectJSON, isSVGContainerJSON, isShapeJSON, isTextJSON, resolveObjectsForSize, scaleAutoFitSizes, scaleCornerRadius, scalePadding };
896
- //# sourceMappingURL=index.mjs.map
897
- //# sourceMappingURL=index.mjs.map
1
+ var se=[1,1/0],de=90,me=.9,le=.1,W=20,pe=100,ue={stroke:"rgba(0, 0, 0, 1)",strokeWidth:0,strokeDashArray:[0,0]};var y=e=>{switch(e){case "square":return "720x720";case "landscape":return "1280x720";case "portrait":return "720x1280";default:return e}},Y=({x1:e,y1:t,x2:n,y2:r})=>{let a=n-e,d=r-t;return Math.sqrt(a*a+d*d)},Xe=({size1:e,size2:t})=>{let n=y(e),r=y(t),[a,d]=n.split("x").map(Number),[u,l]=r.split("x").map(Number);return Y({x1:a??0,y1:d??0,x2:u??0,y2:l??0})},ce=(e,t)=>{let[n,r]=y(t).split("x").map(Number),a=n/r,d=new Map;for(let o of e){let s=o.width/o.height;if(isNaN(s)||isNaN(a))continue;let p=Math.abs(a-s),i=Y({x1:n,y1:r,x2:o.width,y2:o.height});d.set(o.key,{aspectRatioDistance:p,euclideanDistance:i});}let u=Math.max(...Array.from(d.values()).map(o=>o.aspectRatioDistance)),l=Math.max(...Array.from(d.values()).map(o=>o.euclideanDistance)),m=[];for(let o of e){let s=d.get(o.key);if(!s){m.push({...o,matchPercentage:W});continue}let p=u===0?1:1-s.aspectRatioDistance/u,i=l===0?1:1-s.euclideanDistance/l,S=p*me+i*le,E=Math.round(Math.max(W,Math.min(pe,S*100)));m.push({...o,matchPercentage:E});}return m.sort((o,s)=>s.matchPercentage-o.matchPercentage),m},He=({availableSizes:e,adaptSize:t})=>{let n=e.map(s=>{let p=y(s),[i,S]=p.split("x").map(Number);return {key:s,width:i,height:S}}),r=ce(n,t),[a,d]=y(t).split("x").map(Number),u=a/d,l=e[0],m=Number.MAX_VALUE,o=Number.MAX_VALUE;for(let s of n){let p=s.width/s.height;if(isNaN(p)||isNaN(u))continue;let i=Math.abs(u-p),S=Y({x1:a,y1:d,x2:s.width,y2:s.height});(i<m||i===m&&S<o)&&(m=i,o=S,l=s.key);}return {closestSize:l,sortedMatches:r.reduce((s,{key:p,matchPercentage:i})=>(s[p]=i,s),{})}},Se=({availableSizes:e,adaptSize:t})=>{if(Object.keys(e).length===0)return [];let n=Object.entries(e).map(([a,d])=>({key:a,width:d.width,height:d.height}));return ce(n,t).map(a=>({_id:a.key,...e[a.key],matchPercentage:a.matchPercentage}))},X=(e,t)=>{let n=Object.keys(e);if(n.length===1)return n[0];try{return Se({availableSizes:e,adaptSize:t})[0]?._id||n[0]}catch(r){return console.warn("Error finding closest size, using first available:",r),n[0]}};var R=e=>e.dataType==="TEXT",J=e=>e.dataType==="IMAGE",v=e=>e.dataType==="SHAPE",A=e=>e?.type==="svg-container"&&e?.dataType==="SHAPE",I=e=>e?.type==="rounded-rect"&&e?.dataType==="SHAPE",w=e=>e?.dataType==="GROUP",z=e=>e?.dataType==="CREATIVE_BOX",H=e=>e?.dataType==="VIDEO",P=e=>e?.dataType==="AUDIO";var O=(e,t,n=0)=>{if(t in e){let r=e[t];return typeof r=="number"?r:n}return n},M=({element:e,canvasDimensions:t})=>{let n=typeof t.width=="number"?t.width:0,r=typeof t.height=="number"?t.height:0,a=("width"in e?e.width:1)*("scaleX"in e?e.scaleX:1),d=("height"in e?e.height:1)*("scaleY"in e?e.scaleY??1:1),u="top"in e?e.top:0,l="left"in e?e.left:0,m=l+a,o=u+d,s=n*r;if(s===0)return 0;let p=Math.min(m,n)-Math.max(l,0),i=Math.min(o,r)-Math.max(u,0),S=Math.max(p,0)*Math.max(i,0);return Math.round(S/s*100)},V=({areaPercentage:e,referenceLengths:t,type:n})=>{if(n==="GROUP")return false;if(e>de)return true;let r=Math.floor(t.left)<=0&&Math.floor(t.width)>=t.canvasWidth,a=Math.floor(t.top)<=0&&Math.floor(t.height)>=t.canvasHeight;return r||a},b=(e,t)=>({tl:(e?.tl||0)*t,tr:(e?.tr||0)*t,bl:(e?.bl||0)*t,br:(e?.br||0)*t}),U=(e,t)=>{let n=e??{top:0,right:0,bottom:0,left:0};return {...n,top:n.top?n.top*t:0,right:n.right?n.right*t:0,bottom:n.bottom?n.bottom*t:0,left:n.left?n.left*t:0}},h=({object:e,scalingRatio:t})=>{if(z(e)||w(e)||P(e))return {};if(!("border"in e)||!e?.border)return {};let n=e.border;return n.strokeWidth?{border:{...ue,...n,strokeWidth:n.strokeWidth*t}}:{}},k=({wordStyle:e,scalingRatio:t})=>!e||e.length===0?e:e.map(n=>{if(!n.data?.styles?.fontSize)return n;let r=n.data.styles.fontSizeUnit??"%",a=r==="px"?Math.round(n.data.styles.fontSize*t):n.data.styles.fontSize;return {...n,data:{...n.data,styles:{...n.data.styles,fontSize:a,fontSizeUnit:r}}}}),D=(e,t,n)=>e&&e.length===2?e.map(r=>Math.ceil((r??n)*t)):[...se],K=({closestSize:e,adaptSize:t,object:n})=>{let r=y(e),[a,d]=r.split("x").map(Number),[u,l]=t.split("x").map(Number),m=O(n,"top"),o=O(n,"left"),s=O(n,"scaleX",1),p=O(n,"scaleY",1),i=O(n,"width",1)*s,S=O(n,"height",1)*p,E=u/a,f=l/d,c=Math.min(E,f),g=Math.ceil(i*c),x=Math.ceil(S*c),$=Math.abs(o+i-a),q=Math.abs(m+S-d),Z=Math.abs(o),Q=Math.abs(m),N=1;if($<N||Z<N||q<N||Q<N){let T,C;if($<N)T=u-g;else if(Z<N)T=0;else {let L=o/a;T=Math.ceil(L*u);}if(q<N)C=l-x;else if(Q<N)C=0;else {let L=m/d;C=Math.ceil(L*l);}return {left:T,top:C,width:g/s,height:x/p}}let j=o+i/2,ee=m+S/2,F=o+i,G=m+S,B=a/2,Fe=d/2,te=Math.max(0,Math.min(F,B)-Math.max(o,0))*Math.max(0,Math.min(G,d)-Math.max(m,0)),ne=Math.max(0,Math.min(F,a)-Math.max(o,B))*Math.max(0,Math.min(G,d)-Math.max(m,0)),Ge=te+ne;if(Math.abs(te-ne)/Ge<.05){let T=j/a,C=ee/d,L=T*u,Ye=C*l;return {left:L-g/2,top:Ye-x/2,width:g,height:x}}let re=j>B,ie=ee>Fe,Be=re?F/a:o/a,We=ie?G/d:m/d,ae=Be*u,oe=We*l;return {left:re?ae-g:ae,top:ie?oe-x:oe,width:g,height:x}},ge=(e,t,n,r)=>({...e,left:t.left,top:t.top,width:t.width,height:t.height,wordSpacing:e.wordSpacing?e.wordSpacing*n:0,padding:U(e.padding,n),cornerRadius:b(e.cornerRadius,n),...h({object:e,scalingRatio:n}),autoFitSizes:D(e.autoFitSizes,n,r),fontSize:e.fontSize*n,wordStyle:k({wordStyle:e.wordStyle||[],scalingRatio:n})}),he=(e,t,n,r,a)=>({...e,left:t.left,top:t.top,width:t.width,height:t.height,imageScale:(e.imageScale??1)*n,imageLeft:(e.imageLeft??0)*r,imageTop:(e.imageTop??0)*a,cornerRadius:b(e.cornerRadius,n),...h({object:e,scalingRatio:n})}),fe=(e,t,n,r,a)=>({...e,left:t.left,top:t.top,width:t.width,height:t.height,imageScale:(e.imageScale??1)*n,imageLeft:(e.imageLeft??0)*r,imageTop:(e.imageTop??0)*a,...h({object:e,scalingRatio:n})}),Oe=(e,t,n)=>({...e,left:t.left,top:t.top,width:t.width,height:t.height,cornerRadius:b(e.cornerRadius,n),...h({object:e,scalingRatio:n})}),be=(e,t,n)=>({...e,left:t.left,top:t.top,scaleX:(e.scaleX??1)*n,scaleY:(e.scaleY??1)*n,...h({object:e,scalingRatio:n})}),Ne=(e,t,n,r,a)=>({...e,left:e.left*t,top:e.top*n,width:e.width*t,height:e.height*n,autoFitSizes:D(e.autoFitSizes,r,a),cornerRadius:b(e.cornerRadius,r),...h({object:e,scalingRatio:r}),fontSize:e.fontSize*r,wordStyle:k({wordStyle:e.wordStyle||[],scalingRatio:r})}),ye=(e,t,n,r)=>({...e,left:e.left*t,top:e.top*n,width:e.width*t,height:e.height*n,imageScale:(e.imageScale??1)*r,imageLeft:(e.imageLeft??0)*t,imageTop:(e.imageTop??0)*n,cornerRadius:b(e.cornerRadius,r),...h({object:e,scalingRatio:r})}),Ee=(e,t,n,r)=>({...e,left:e.left*t,top:e.top*n,width:e.width*t,height:e.height*n,imageScale:(e.imageScale??1)*r,imageLeft:(e.imageLeft??0)*t,imageTop:(e.imageTop??0)*n,...h({object:e,scalingRatio:r})}),xe=(e,t,n,r)=>({...e,left:e.left*t,top:e.top*n,width:e.width*t,height:e.height*n,cornerRadius:b(e.cornerRadius,r),...h({object:e,scalingRatio:r})}),Te=(e,t,n,r)=>({...e,left:e.left*t,top:e.top*n,scaleX:(e.scaleX??1)*t,scaleY:(e.scaleY??1)*n,...h({object:e,scalingRatio:r})}),Ce=(e,t,n)=>({...e,left:e.left*t,top:e.top*t,width:e.width*t,height:e.height*t,wordSpacing:e.wordSpacing?e.wordSpacing*t:0,padding:U(e.padding,t),cornerRadius:b(e.cornerRadius,t),...h({object:e,scalingRatio:t}),autoFitSizes:D(e.autoFitSizes,t,n),fontSize:e.fontSize*t,wordStyle:k({wordStyle:e.wordStyle||[],scalingRatio:t})}),Re=(e,t)=>({...e,left:e.left*t,top:e.top*t,width:e.width*t,height:e.height*t,imageScale:(e.imageScale??1)*t,imageLeft:(e.imageLeft??0)*t,imageTop:(e.imageTop??0)*t,cornerRadius:b(e.cornerRadius,t),...h({object:e,scalingRatio:t})}),Je=(e,t)=>({...e,left:e.left*t,top:e.top*t,width:e.width*t,height:e.height*t,imageScale:(e.imageScale??1)*t,imageLeft:(e.imageLeft??0)*t,imageTop:(e.imageTop??0)*t,...h({object:e,scalingRatio:t})}),ve=(e,t)=>({...e,left:e.left*t,top:e.top*t,width:e.width*t,height:e.height*t,cornerRadius:b(e.cornerRadius,t),...h({object:e,scalingRatio:t})}),Ae=(e,t)=>({...e,left:O(e,"left")*t,top:O(e,"top")*t,scaleX:O(e,"scaleX",1)*t,scaleY:O(e,"scaleY",1)*t,...h({object:e,scalingRatio:t})});var Ie=({adaptSize:e,objects:t,closestSize:n})=>{let[r,a]=e.split("x").map(Number),[d,u]=n.split("x").map(Number),l=r/d,m=a/u,o=Math.min(l,m),s={};for(let p of Object.keys(t)){let i=t[p];if(i.dataType==="CREATIVE_BOX"){s[p]={...i,height:a,width:r};continue}if(i.dataType==="AUDIO"){s[p]=i;continue}M({element:i,canvasDimensions:{width:d,height:u}});let S=M({element:i,canvasDimensions:{width:d,height:u}});if(!V({areaPercentage:S,referenceLengths:{left:i.left??0,top:i.top??0,width:i.width??1,height:i.height??1,canvasWidth:d,canvasHeight:u},type:i.dataType})){let f=K({closestSize:n,adaptSize:e,object:i});if(f.left===0&&f.height===0&&f.top===0&&f.width===0)throw new Error("Invalid values");if("groupPath"in i&&i.groupPath)continue;if(R(i)){s[p]=ge(i,f,o,u);continue}if(J(i)){s[p]=he(i,f,o,l,m);continue}if(v(i)){if(A(i)){s[p]=fe(i,f,o,l,m);continue}if(I(i)){s[p]=Oe(i,f,o);continue}s[p]=be(i,f,o);continue}if(w(i)){s[p]={...i,left:f.left,top:f.top,width:f.width,height:f.height};for(let c of i.objects){let g=t[c];if(g){if(R(g)){s[c]=Ce(g,o,u);continue}if(J(g)){s[c]=Re(g,o);continue}if(v(g)){if(A(g)){s[c]=Je(g,o);continue}if(I(g)){s[c]=ve(g,o);continue}s[c]=Ae(g,o);continue}}}continue}}if(R(i)){s[p]=Ne(i,l,m,o,u);continue}if(J(i)){s[p]=ye(i,l,m,o);continue}if(v(i)){if(A(i)){s[p]=Ee(i,l,m,o);continue}if(I(i)){s[p]=xe(i,l,m,o);continue}s[p]=Te(i,l,m,o);continue}s[p]={...i,left:O(i,"left")*l,top:O(i,"top")*m,width:O(i,"width",1)*l,height:O(i,"height",1)*m,...h({object:i,scalingRatio:o})};}return s},we=(e,t)=>{let n={};for(let[r,a]of Object.entries(e)){let d=a.overrides?.[t]||{},{overrides:u,zIndex:l,...m}=a;n[r]={...m,...d};}return n},ze=(e,t,n)=>{let r=JSON.parse(JSON.stringify(e));for(let[a,d]of Object.entries(t)){if(!r[a])continue;let u=r[a].overrides||{};r[a].overrides={...u,[n]:{...d,zIndex:r[a].overrides?.[n]?.zIndex??r[a].zIndex??0}};}return r},_=["left","top","width","height","angle","visible"],Ve=["fontSize","autoFitSizes","padding","wordSpacing"],Ue=["imageScale","imageLeft","imageTop","objectFit","imageOriginX","imageOriginY"],Ke=["imageScale","imageLeft","imageTop","scaleX","scaleY","objectFit","imageOriginX","imageOriginY"],$e=["left","top","angle","visible","scaleX","scaleY"],qe=e=>z(e)||P(e)?[]:R(e)?[..._,...Ve]:J(e)||H(e)?[..._,...Ue]:v(e)?A(e)?[..._,...Ke]:I(e)?_:$e:(w(e),_),Pe=(e,t)=>{if(z(e)||P(e))return e;let n=qe(e),r={...e},a=t;for(let d of n)a[d]!==void 0&&(r[d]=a[d]);return r},Ze=(e,t)=>{let n={};for(let[r,a]of Object.entries(e))t[r]?n[r]=Pe(a,t[r]):n[r]=a;return n},_e=({originalCapsule:e,updatedObjects:t,sizeId:n,referenceCreativeId:r,sizeToGenerate:a,sizeName:d,sizeCategory:u,videoLength:l})=>{let[m,o]=a.split("x").map(Number),s=JSON.parse(JSON.stringify(e.canvasData));s.variant.objects=t,s.variant.sizes[n]={width:m,height:o,id:n,displayName:d||a,rulers:[],...l!==void 0&&{videoLength:l}};let p=e.creativesOrder,i=p&&p.length>0?[...p,n]:[r,n],S={name:d||a,width:m,height:o,active:true,thumbnail:"",creativeUrl:"",...u&&{category:u}};return {...e,canvasData:s,savedCustomDimensions:{...e.savedCustomDimensions,[n]:S},newAddedSizes:{...e.newAddedSizes,[n]:S},creativesOrder:i}},Qe=({originalCapsule:e,capsuleId:t,creativeId:n,sizeId:r,sizeToGenerate:a,sizeName:d,sizeCategory:u})=>{let l=e.canvasData.variant?.sizes;if(!l||Object.keys(l).length===0)throw new Error(`No sizes available in capsule: ${t}`);let m;n&&l[n]?(m=n,console.log(`[BaseLayoutAdapter] Using provided reference size: ${m}`)):(m=X(l,a),console.log(`[BaseLayoutAdapter] Found best reference size: ${m} for target: ${a}`),n&&!l[n]&&console.warn(`[BaseLayoutAdapter] Provided creativeId ${n} not found, using ${m}`));let o=l[m],s=`${o.width}x${o.height}`,p=e.canvasData.variant.objects,i=we(p,m),S=Ie({adaptSize:a,objects:i,closestSize:s}),E=ze(p,S,r);return _e({originalCapsule:e,updatedObjects:E,sizeId:r,referenceCreativeId:m,sizeToGenerate:a,sizeName:d,sizeCategory:u,videoLength:o?.videoLength})};var je={TEXT:"TEXT",SHAPE:"SHAPE",IMAGE:"IMAGE",GROUP:"GROUP",CREATIVE_BOX:"CREATIVE_BOX",VIDEO:"VIDEO",AUDIO:"AUDIO",CANVAS_MASK:"CANVAS_MASK"},Le=(c=>(c.HERO_IMAGE="HERO_IMAGE",c.PRODUCT_IMAGE="PRODUCT_IMAGE",c.BACKGROUND="BACKGROUND",c.LOGO="LOGO",c.ICON="ICON",c.HEADLINE="HEADLINE",c.SUBHEADLINE="SUBHEADLINE",c.BODY_COPY="BODY_COPY",c.PRICE="PRICE",c.CTA="CTA",c.TERMS_CONDITIONS="TERMS_CONDITIONS",c.REVIEWS_TESTIMONIALS="REVIEWS_TESTIMONIALS",c.WARRANTY_INFO="WARRANTY_INFO",c.BADGE="BADGE",c.NEW_PRODUCT_LABEL="NEW_PRODUCT_LABEL",c.OTHER="OTHER",c))(Le||{}),Me=(r=>(r.WORD_STYLE="WORD_STYLE",r.MISSING_GLYPH="MISSING_GLYPH",r.VARIABLES="VARIABLES",r))(Me||{}),ke=(r=>(r.CHARACTER="character",r.WORD="word",r.LINE="line",r))(ke||{}),De=(n=>(n.TYPING_EFFECT="typing-effect",n.NONE="none",n))(De||{});var et={X:"x",Y:"y"};export{De as AnimationSpecialCase,je as CANVAS_EDITOR_ELEMENT,Le as CreativeElementCategory,et as RULER_AXIS,ke as TextAnimationType,Me as WORD_STYLE_TYPE,k as adaptWordStyleFontSizes,ze as applyAdaptedAsOverrides,_e as buildNewCapsule,V as checkIfElementShouldBeSkewed,X as findBestReferenceSize,Se as findClosestSizeObjectsWithMatches,He as findClosestSizeWithMatches,Qe as generateBaseLayoutForSize,Ie as getAdaptedObjectsJSON,M as getAreaPercentageOfElementOnCanvasJSON,Xe as getEuclideanDistanceBetweenSizes,y as getNormalizedSizeValue,h as getScaledBorderJSON,K as getValuesWithoutSkewingJSON,P as isAudioJSON,z as isCreativeBoxJSON,w as isGroupJSON,J as isImageJSON,I as isRoundedRectJSON,A as isSVGContainerJSON,v as isShapeJSON,R as isTextJSON,H as isVideoJSON,Pe as mergeLayoutFromReference,Ze as mergeLayoutFromReferenceObjects,we as resolveObjectsForSize,D as scaleAutoFitSizes,b as scaleCornerRadius,U as scalePadding};