hyperframes 0.8.103 → 0.8.104

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.
Files changed (80) hide show
  1. package/dist/{add-7YNDDJZM.js → add-KXAWOEZJ.js} +5 -5
  2. package/dist/{asset-QQGUOKN7.js → asset-QAIWASUI.js} +2 -2
  3. package/dist/{auth-ITO2U4DF.js → auth-2FQGBN5W.js} +1 -1
  4. package/dist/{autoUpdate-YA7T35TP.js → autoUpdate-UXMPQYUO.js} +2 -2
  5. package/dist/{backgroundChecks-C6JEBKPE.js → backgroundChecks-RPBCDLBU.js} +3 -3
  6. package/dist/backgroundChecksWorker.js +3 -3
  7. package/dist/{beats-P6S6UEOR.js → beats-F4PZIT7L.js} +4 -4
  8. package/dist/{benchmark-JIZAHWG4.js → benchmark-AIGZ6NZT.js} +5 -5
  9. package/dist/{browser-GFQ45FKN.js → browser-AQTVWA2I.js} +3 -3
  10. package/dist/{catalog-RPJ3NWVH.js → catalog-LVB5GLIS.js} +5 -5
  11. package/dist/{check-BJU7NGBL.js → check-ZMENBYIU.js} +9 -9
  12. package/dist/{checkBrowser-OXJCECZI.js → checkBrowser-26NJ47DY.js} +7 -7
  13. package/dist/{chunk-3XNY2WK4.js → chunk-2M6YQAMV.js} +1 -1
  14. package/dist/{chunk-IHMR2L3L.js → chunk-4V63UZIV.js} +1 -1
  15. package/dist/{chunk-E3JCMLAF.js → chunk-6CPVF7DM.js} +1 -1
  16. package/dist/{chunk-PQL3VANN.js → chunk-IEBXD6Y6.js} +2 -2
  17. package/dist/{chunk-J5MQ3GPK.js → chunk-JUDUP2IC.js} +2 -2
  18. package/dist/{chunk-2DHH45NV.js → chunk-MZWGD4IR.js} +1 -1
  19. package/dist/{chunk-P77GUHVY.js → chunk-PRWBZGQ5.js} +1 -1
  20. package/dist/{chunk-A4UUULN3.js → chunk-RUQUOWIV.js} +2 -2
  21. package/dist/{chunk-A5QSC7DM.js → chunk-S4EZWGRD.js} +2 -2
  22. package/dist/{chunk-CDLT2S5Y.js → chunk-SA4HX7OJ.js} +2 -2
  23. package/dist/{chunk-SFXDX5F6.js → chunk-TKZAN2AY.js} +2 -2
  24. package/dist/{chunk-ASSVFGUL.js → chunk-TVKKKJQT.js} +1 -1
  25. package/dist/{chunk-VQOZ3JO6.js → chunk-VAFKQ546.js} +1 -1
  26. package/dist/{chunk-G4WCIV45.js → chunk-XOBW5TFB.js} +2 -2
  27. package/dist/{chunk-2QRIIMGS.js → chunk-ZASIQRKO.js} +2 -2
  28. package/dist/{clean-FPXQNQQ2.js → clean-4NIBDW2Y.js} +3 -3
  29. package/dist/cli.js +44 -44
  30. package/dist/{cloud-BFMMRGJL.js → cloud-XONUMPVD.js} +4 -4
  31. package/dist/{compare-IKBMRXHF.js → compare-PLEGE2AB.js} +4 -4
  32. package/dist/{component-RN32W42O.js → component-YODSQLKS.js} +3 -3
  33. package/dist/{compositions-O2WKG7BC.js → compositions-ZYGETZWE.js} +5 -5
  34. package/dist/{delete-EF2RARRV.js → delete-2YR5ZDZI.js} +2 -2
  35. package/dist/{doctor-L6CV6YXV.js → doctor-WS4BOIAN.js} +3 -3
  36. package/dist/{events-M76TNXYH.js → events-AWJJTVYV.js} +2 -2
  37. package/dist/{events-ZCO6M2G6.js → events-QEEFQ76R.js} +3 -3
  38. package/dist/{feedback-2ACKQBUF.js → feedback-32I2DS3H.js} +4 -4
  39. package/dist/{figma-KZC2I2K7.js → figma-THXKL7C3.js} +3 -3
  40. package/dist/fontLocalizeCli.js +1 -1
  41. package/dist/{get-HSREOXQC.js → get-2RK36VX3.js} +2 -2
  42. package/dist/{grade-compare-HN5IRGL5.js → grade-compare-4R5XDPJU.js} +4 -4
  43. package/dist/{help-ACSFM5ZX.js → help-YKZ5HPQO.js} +1 -1
  44. package/dist/{history-THD5S55X.js → history-2IPTBA55.js} +5 -5
  45. package/dist/hyperframes-player.global.js +1 -1
  46. package/dist/{info-JGRSYW7U.js → info-H2ZIL5YN.js} +5 -5
  47. package/dist/{init-WULQFAB7.js → init-2ZEQAKSE.js} +6 -6
  48. package/dist/{inspect-QPT6PESN.js → inspect-FQEXVZUP.js} +6 -6
  49. package/dist/{keyframes-MD5JHEQG.js → keyframes-GHCATB4L.js} +5 -5
  50. package/dist/{layout-SAA5WUEQ.js → layout-JUAYXDNX.js} +6 -6
  51. package/dist/{lint-3TPZORDF.js → lint-45XP4TUK.js} +6 -6
  52. package/dist/{list-AURXVOVG.js → list-CKALQL3O.js} +2 -2
  53. package/dist/{login-GTLUEY2W.js → login-QQDJUIGO.js} +4 -4
  54. package/dist/{media-treatment-5S22MP33.js → media-treatment-CBQ2DANK.js} +5 -5
  55. package/dist/{normalize-audio-JSYJFSDX.js → normalize-audio-OVVPWEUL.js} +4 -4
  56. package/dist/{play-HVM27UXW.js → play-YIHX3DZX.js} +4 -4
  57. package/dist/{present-UKH4JT6K.js → present-FWJNW3Z3.js} +4 -4
  58. package/dist/{preview-IJ27BKQK.js → preview-TAICDDJL.js} +5 -5
  59. package/dist/{render-Q4IVNLDA.js → render-LHTKQD2G.js} +5 -5
  60. package/dist/{render-7QYVDEZ3.js → render-TSOLZGAK.js} +5 -5
  61. package/dist/{skills-2UKBANDP.js → skills-4M2LBGYL.js} +5 -5
  62. package/dist/{skillsUpdateCheck-Z7D7NR3G.js → skillsUpdateCheck-WDI32JU4.js} +3 -3
  63. package/dist/{snapshot-CJCGJCK2.js → snapshot-33SGYIF6.js} +4 -4
  64. package/dist/studio/assets/{hyperframes-player-DG795Hwu.js → hyperframes-player-DAoaajuM.js} +1 -1
  65. package/dist/studio/assets/{index-BiEtDkae.js → index-BDK4rTMb.js} +1 -1
  66. package/dist/studio/assets/{index-BPJRf2X9.js → index-De2aO4XM.js} +178 -178
  67. package/dist/studio/assets/{index-DuCZ3pQw.js → index-WV9LroAD.js} +1 -1
  68. package/dist/studio/index.d.ts +181 -168
  69. package/dist/studio/index.html +1 -1
  70. package/dist/studio/index.js +428 -305
  71. package/dist/studio/index.js.map +1 -1
  72. package/dist/{studioServer-DBBVNNRM.js → studioServer-CTDEYU7Q.js} +4 -4
  73. package/dist/{telemetry-36QQ3MV6.js → telemetry-7P3TXR5K.js} +3 -3
  74. package/dist/{timeline-JFW5OBO4.js → timeline-WOBSPT6V.js} +5 -5
  75. package/dist/{tokens-A3UY3JEB.js → tokens-2A4LMJYJ.js} +2 -2
  76. package/dist/{transcribe-C3KOJRCZ.js → transcribe-7VKKNU5N.js} +3 -3
  77. package/dist/{updateCheck-CM5G6C4C.js → updateCheck-5UKKIEDG.js} +2 -2
  78. package/dist/{upgrade-BHLYQC6T.js → upgrade-QZIZVUIX.js} +2 -2
  79. package/dist/{validate-SKGTQ6MA.js → validate-D2YZV5KV.js} +6 -6
  80. package/package.json +1 -1
@@ -31840,15 +31840,6 @@ function applyStudioRotation(element, rotation) {
31840
31840
  composeStudioRotationValue(element, `var(${STUDIO_ROTATION_PROP}, 0deg)`)
31841
31841
  );
31842
31842
  }
31843
- function applyStudioRotationDraft(element, rotation) {
31844
- promoteInlineForTransform(element);
31845
- writeStudioRotationVars(element, rotation, { updateBase: false });
31846
- element.setAttribute(STUDIO_ROTATION_DRAFT_ATTR, "true");
31847
- element.style.setProperty(
31848
- "rotate",
31849
- composeStudioRotationValue(element, `${roundTo3(rotation.angle)}deg`)
31850
- );
31851
- }
31852
31843
 
31853
31844
  // src/components/editor/manualEditsSeekReapply.ts
31854
31845
  function queryStudioElements(doc, attr) {
@@ -31986,6 +31977,8 @@ function captureStudioBoxSize(element) {
31986
31977
  function captureStudioRotation(element) {
31987
31978
  return {
31988
31979
  rotate: element.style.getPropertyValue("rotate"),
31980
+ transform: element.style.getPropertyValue("transform"),
31981
+ display: element.style.getPropertyValue("display"),
31989
31982
  transformOrigin: element.style.getPropertyValue("transform-origin"),
31990
31983
  studioRotation: element.style.getPropertyValue(STUDIO_ROTATION_PROP),
31991
31984
  marker: element.getAttribute(STUDIO_ROTATION_ATTR),
@@ -32381,6 +32374,29 @@ function installStudioManualEditSeekReapply(win, apply) {
32381
32374
  }
32382
32375
 
32383
32376
  // src/hooks/draggedGsapPosition.ts
32377
+ var cssValue = (style, prop) => {
32378
+ const value = style.getPropertyValue(prop).trim();
32379
+ return value === "none" ? "" : value;
32380
+ };
32381
+ function readCssRotation(element, withRotate = true) {
32382
+ const view = element.ownerDocument.defaultView;
32383
+ if (!view) return 0;
32384
+ const style = view.getComputedStyle(element);
32385
+ const rotate2 = withRotate ? cssValue(style, "rotate") : "";
32386
+ const scale = cssValue(style, "scale");
32387
+ const transform = cssValue(style, "transform");
32388
+ const angle = (list) => {
32389
+ if (!list) return 0;
32390
+ const m = new view.DOMMatrix(list);
32391
+ return Math.atan2(m.b, m.a) * 180 / Math.PI;
32392
+ };
32393
+ const folded = [rotate2 && `rotate(${rotate2})`, scale && `scale(${scale.split(/\s+/).join(",")})`];
32394
+ try {
32395
+ return angle([...folded, transform].join(" ").trim());
32396
+ } catch {
32397
+ return angle(transform);
32398
+ }
32399
+ }
32384
32400
  function computeDraggedGsapPosition(element, studioOffset, fallbackBase) {
32385
32401
  const rotStyle = element.style.getPropertyValue("--hf-studio-rotation");
32386
32402
  const rotDeg = Number.parseFloat(rotStyle) || 0;
@@ -32407,6 +32423,144 @@ function computeDraggedGsapPosition(element, studioOffset, fallbackBase) {
32407
32423
 
32408
32424
  // src/hooks/gsapRuntimeKeyframes.ts
32409
32425
  import { buildArcPath } from "@hyperframes/core/gsap-parser-acorn";
32426
+
32427
+ // src/components/editor/manualEditsDomPatches.ts
32428
+ function collectInlineStyleOps(element, properties, ops) {
32429
+ for (const prop of properties) {
32430
+ const val = element.style.getPropertyValue(prop);
32431
+ if (val) ops.push({ type: "inline-style", property: prop, value: val });
32432
+ }
32433
+ }
32434
+ function collectAttributeOps(element, attrNames, ops) {
32435
+ for (const attr of attrNames) {
32436
+ const val = element.getAttribute(attr);
32437
+ if (val !== null) ops.push({ type: "attribute", property: attr, value: val });
32438
+ }
32439
+ }
32440
+ function appendTransformDisplayOps(element, ops) {
32441
+ const val = element.getAttribute(STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR);
32442
+ if (val !== null) {
32443
+ ops.push({ type: "inline-style", property: "display", value: val || null });
32444
+ ops.push({ type: "attribute", property: STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR, value: null });
32445
+ }
32446
+ }
32447
+ function buildPathOffsetPatches(element) {
32448
+ const ops = [];
32449
+ collectInlineStyleOps(element, [STUDIO_OFFSET_X_PROP, STUDIO_OFFSET_Y_PROP], ops);
32450
+ const inlineTranslate = element.style.getPropertyValue("translate");
32451
+ const hasOffsetVars = element.style.getPropertyValue(STUDIO_OFFSET_X_PROP) || element.style.getPropertyValue(STUDIO_OFFSET_Y_PROP);
32452
+ const translateValue = inlineTranslate && inlineTranslate !== "none" ? inlineTranslate : hasOffsetVars ? `var(${STUDIO_OFFSET_X_PROP}, 0px) var(${STUDIO_OFFSET_Y_PROP}, 0px)` : null;
32453
+ if (translateValue) {
32454
+ ops.push({ type: "inline-style", property: "translate", value: translateValue });
32455
+ }
32456
+ ops.push({ type: "attribute", property: STUDIO_PATH_OFFSET_ATTR, value: "true" });
32457
+ collectAttributeOps(
32458
+ element,
32459
+ [STUDIO_ORIGINAL_TRANSLATE_ATTR, STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR],
32460
+ ops
32461
+ );
32462
+ collectInlineStyleOps(element, ["display"], ops);
32463
+ collectAttributeOps(element, [STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR], ops);
32464
+ return ops;
32465
+ }
32466
+ function buildClearPathOffsetPatches(element) {
32467
+ const originalInlineTranslate = element.getAttribute(STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR);
32468
+ const ops = [
32469
+ { type: "inline-style", property: STUDIO_OFFSET_X_PROP, value: null },
32470
+ { type: "inline-style", property: STUDIO_OFFSET_Y_PROP, value: null },
32471
+ { type: "inline-style", property: "translate", value: originalInlineTranslate || null },
32472
+ { type: "attribute", property: STUDIO_PATH_OFFSET_ATTR, value: null },
32473
+ { type: "attribute", property: STUDIO_ORIGINAL_TRANSLATE_ATTR, value: null },
32474
+ { type: "attribute", property: STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR, value: null }
32475
+ ];
32476
+ appendTransformDisplayOps(element, ops);
32477
+ return ops;
32478
+ }
32479
+ var BOX_SIZE_STYLE_PROPS = [
32480
+ "width",
32481
+ "height",
32482
+ "min-width",
32483
+ "min-height",
32484
+ "max-width",
32485
+ "max-height",
32486
+ "flex-basis",
32487
+ "flex-grow",
32488
+ "flex-shrink",
32489
+ "box-sizing",
32490
+ "scale",
32491
+ "transform-origin",
32492
+ "display"
32493
+ ];
32494
+ var BOX_SIZE_ORIG_ATTRS = [
32495
+ [STUDIO_ORIGINAL_WIDTH_ATTR, "width"],
32496
+ [STUDIO_ORIGINAL_HEIGHT_ATTR, "height"],
32497
+ // Records a measurement rather than a style, so it restores nothing.
32498
+ [STUDIO_ORIGINAL_BOX_WIDTH_ATTR, ""],
32499
+ [STUDIO_ORIGINAL_BOX_HEIGHT_ATTR, ""],
32500
+ [STUDIO_ORIGINAL_MIN_WIDTH_ATTR, "min-width"],
32501
+ [STUDIO_ORIGINAL_MIN_HEIGHT_ATTR, "min-height"],
32502
+ [STUDIO_ORIGINAL_MAX_WIDTH_ATTR, "max-width"],
32503
+ [STUDIO_ORIGINAL_MAX_HEIGHT_ATTR, "max-height"],
32504
+ [STUDIO_ORIGINAL_FLEX_BASIS_ATTR, "flex-basis"],
32505
+ [STUDIO_ORIGINAL_FLEX_GROW_ATTR, "flex-grow"],
32506
+ [STUDIO_ORIGINAL_FLEX_SHRINK_ATTR, "flex-shrink"],
32507
+ [STUDIO_ORIGINAL_BOX_SIZING_ATTR, "box-sizing"],
32508
+ [STUDIO_ORIGINAL_SCALE_ATTR, "scale"],
32509
+ [STUDIO_ORIGINAL_TRANSFORM_ORIGIN_ATTR, "transform-origin"],
32510
+ [STUDIO_ORIGINAL_DISPLAY_ATTR, "display"],
32511
+ [STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR, ""]
32512
+ ];
32513
+ function buildBoxSizePatches(element) {
32514
+ const ops = [];
32515
+ collectInlineStyleOps(element, [STUDIO_WIDTH_PROP, STUDIO_HEIGHT_PROP], ops);
32516
+ collectInlineStyleOps(element, BOX_SIZE_STYLE_PROPS, ops);
32517
+ ops.push({ type: "attribute", property: STUDIO_BOX_SIZE_ATTR, value: "true" });
32518
+ collectAttributeOps(
32519
+ element,
32520
+ BOX_SIZE_ORIG_ATTRS.map(([attr]) => attr),
32521
+ ops
32522
+ );
32523
+ return ops;
32524
+ }
32525
+ function buildClearBoxSizePatches(element) {
32526
+ const ops = [
32527
+ { type: "inline-style", property: STUDIO_WIDTH_PROP, value: null },
32528
+ { type: "inline-style", property: STUDIO_HEIGHT_PROP, value: null },
32529
+ { type: "attribute", property: STUDIO_BOX_SIZE_ATTR, value: null }
32530
+ ];
32531
+ for (const [attrName, styleProp] of BOX_SIZE_ORIG_ATTRS) {
32532
+ const origVal = element.getAttribute(attrName);
32533
+ if (origVal !== null && styleProp) {
32534
+ ops.push({ type: "inline-style", property: styleProp, value: origVal || null });
32535
+ }
32536
+ ops.push({ type: "attribute", property: attrName, value: null });
32537
+ }
32538
+ return ops;
32539
+ }
32540
+ function buildClearRotationPatches(element) {
32541
+ const origInlineRotate = element.getAttribute(STUDIO_ORIGINAL_INLINE_ROTATE_ATTR);
32542
+ const origRotationTransformOrigin = element.getAttribute(
32543
+ STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR
32544
+ );
32545
+ const ops = [
32546
+ { type: "inline-style", property: STUDIO_ROTATION_PROP, value: null },
32547
+ { type: "inline-style", property: "rotate", value: origInlineRotate || null },
32548
+ {
32549
+ type: "inline-style",
32550
+ property: "transform-origin",
32551
+ value: origRotationTransformOrigin !== null ? origRotationTransformOrigin || null : null
32552
+ },
32553
+ { type: "attribute", property: STUDIO_ROTATION_ATTR, value: null },
32554
+ { type: "attribute", property: STUDIO_ROTATION_DRAFT_ATTR, value: null },
32555
+ { type: "attribute", property: STUDIO_ORIGINAL_ROTATE_ATTR, value: null },
32556
+ { type: "attribute", property: STUDIO_ORIGINAL_INLINE_ROTATE_ATTR, value: null },
32557
+ { type: "attribute", property: STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR, value: null }
32558
+ ];
32559
+ appendTransformDisplayOps(element, ops);
32560
+ return ops;
32561
+ }
32562
+
32563
+ // src/hooks/gsapRuntimeKeyframes.ts
32410
32564
  var FLAT_SKIP_KEYS = /* @__PURE__ */ new Set([
32411
32565
  "ease",
32412
32566
  "duration",
@@ -32621,9 +32775,32 @@ function gsapWritesChannels(el, channels) {
32621
32775
  )
32622
32776
  );
32623
32777
  }
32778
+ var ROTATION_CHANNELS = [
32779
+ ...["rotation", "rotationX", "rotationY", "rotationZ"],
32780
+ ...["rotate", "rotateX", "rotateY", "rotateZ"]
32781
+ ];
32782
+ var gsapRendersTransform = (el) => !!el._gsap?.renderTransform;
32624
32783
  function gsapWritesPosition(el) {
32784
+ return gsapRendersTransform(el) || gsapWritesChannels(el, MOVE_CHANNELS);
32785
+ }
32786
+ function gsapWritesRotation(el) {
32787
+ return gsapRendersTransform(el) || gsapWritesChannels(el, ROTATION_CHANNELS);
32788
+ }
32789
+ function gsapHoldsTranslate(el) {
32625
32790
  const cache2 = el._gsap;
32626
- return !!cache2?.renderTransform || gsapWritesChannels(el, MOVE_CHANNELS);
32791
+ return ["x", "y", "xPercent", "yPercent"].some(
32792
+ (key2) => !!Number.parseFloat(String(cache2?.[key2]))
32793
+ );
32794
+ }
32795
+ var BOX_CHANNELS = [
32796
+ ...BOX_SIZE_STYLE_PROPS.map(
32797
+ (prop) => prop.replace(/-([a-z])/g, (_, c) => c.toUpperCase())
32798
+ ),
32799
+ "scaleX",
32800
+ "scaleY"
32801
+ ];
32802
+ function gsapWritesBox(el) {
32803
+ return gsapWritesPosition(el) || gsapWritesChannels(el, BOX_CHANNELS);
32627
32804
  }
32628
32805
  function elementHasNonHoldTween(el, channels) {
32629
32806
  const win = el.ownerDocument.defaultView;
@@ -32760,8 +32937,11 @@ function translatePatch(p) {
32760
32937
  function writeTranslatePx(el, p) {
32761
32938
  el.style.setProperty("translate", formatTranslatePx(p));
32762
32939
  }
32763
- function readMoveOffset(el) {
32764
- return gsapWritesPosition(el) ? readStudioPathOffset(el) : readTranslatePx(el);
32940
+ function readMoveOffset(el, plainTranslate = !gsapWritesPosition(el)) {
32941
+ return plainTranslate ? readTranslatePx(el) : readStudioPathOffset(el);
32942
+ }
32943
+ function readShownRotation(el) {
32944
+ return gsapWritesRotation(el) ? readStudioRotation(el) : { angle: roundTo3(readCssRotation(el)) };
32765
32945
  }
32766
32946
 
32767
32947
  // src/components/editor/manualOffsetDrag.ts
@@ -32778,17 +32958,6 @@ function applyOffsetDragDraftViaGsap(element, offset, baseGsap) {
32778
32958
  gsap3.set(element, { x: newX, y: newY });
32779
32959
  return true;
32780
32960
  }
32781
- function applyRotationDraftViaGsap(element, angle) {
32782
- const gsap3 = getOffsetDragGsap(element);
32783
- if (!gsap3) return false;
32784
- element.style.setProperty("rotate", "none");
32785
- gsap3.set(element, { rotation: angle });
32786
- return true;
32787
- }
32788
- function readGsapRotation(element) {
32789
- const gsap3 = getOffsetDragGsap(element);
32790
- return gsap3 ? Number(gsap3.getProperty(element, "rotation")) || 0 : 0;
32791
- }
32792
32961
  var DEFAULT_OFFSET_PROBE_PX = 100;
32793
32962
  var MIN_PROBE_VECTOR_LENGTH_PX = 0.01;
32794
32963
  var MIN_MATRIX_DETERMINANT = 1e-6;
@@ -32936,7 +33105,8 @@ function resolveManualOffsetForPointerDelta(input) {
32936
33105
  };
32937
33106
  }
32938
33107
  function createManualOffsetDragMember(input) {
32939
- const plainTranslate = !!input.gesture && !gsapWritesPosition(input.element);
33108
+ const gsapOwns = input.gesture === "resize" ? gsapWritesBox : gsapWritesPosition;
33109
+ const plainTranslate = !!input.gesture && !gsapOwns(input.element);
32940
33110
  const initialOffset = plainTranslate ? readTranslatePx(input.element) : readAppliedStudioPathOffset(input.element);
32941
33111
  if (!finitePoint(initialOffset))
32942
33112
  return { ok: false, reason: UNREADABLE_TRANSLATE, selection: input.selection };
@@ -33102,6 +33272,94 @@ function resumeGsapTimelines(element) {
33102
33272
  win.__player?.seek?.(t);
33103
33273
  }
33104
33274
 
33275
+ // src/components/editor/rotationDraft.ts
33276
+ function lastRuleTransform(element) {
33277
+ let value = "";
33278
+ for (const sheet of Array.from(element.ownerDocument.styleSheets)) {
33279
+ let rules = [];
33280
+ try {
33281
+ rules = Array.from(sheet.cssRules);
33282
+ } catch {
33283
+ }
33284
+ for (const rule of rules) {
33285
+ const declared = rule.style?.getPropertyValue("transform");
33286
+ if (declared && element.matches(rule.selectorText)) value = declared;
33287
+ }
33288
+ }
33289
+ return value;
33290
+ }
33291
+ function translatingTransform(element) {
33292
+ const view = element.ownerDocument.defaultView;
33293
+ const computed = view?.getComputedStyle(element).transform ?? "none";
33294
+ const m = computed === "none" ? null : new view.DOMMatrix(computed);
33295
+ if (!m || m.m41 === 0 && m.m42 === 0) return "";
33296
+ const value = element.style.getPropertyValue("transform") || lastRuleTransform(element);
33297
+ return value === "none" ? "" : value;
33298
+ }
33299
+ var TRANSLATE = /^translate(?:3d|X|Y|Z)?\(/i;
33300
+ var OWN_TURN = /^rotate\(\s*-?[\d.]+(?:e[+-]?\d+)?deg\s*\)$/i;
33301
+ function readCssRotationTarget(element) {
33302
+ const style = element.ownerDocument.defaultView?.getComputedStyle(element);
33303
+ const inline = style?.display === "inline";
33304
+ const transform = translatingTransform(element);
33305
+ if (!transform) {
33306
+ const share2 = readCssRotation(element, false);
33307
+ return { property: "rotate", before: "", after: "", share: share2, sign: 1, inline };
33308
+ }
33309
+ const parts = splitTopLevelWhitespace(transform);
33310
+ const lead = parts.findIndex((part) => !TRANSLATE.test(part));
33311
+ const split = lead < 0 ? parts.length : lead;
33312
+ const rest = parts.slice(split);
33313
+ if (OWN_TURN.test(rest[0] ?? "")) rest.shift();
33314
+ const [before, after] = [parts.slice(0, split).join(" "), rest.join(" ")];
33315
+ const [sx = 1, sy = sx] = splitTopLevelWhitespace(style?.getPropertyValue("scale") ?? "").map(
33316
+ Number.parseFloat
33317
+ );
33318
+ const inlineStyle = element.style;
33319
+ const saved2 = [
33320
+ inlineStyle.getPropertyValue("transform"),
33321
+ inlineStyle.getPropertyPriority("transform")
33322
+ ];
33323
+ inlineStyle.setProperty("transform", `${before} ${after}`.trim() || "none");
33324
+ const share = readCssRotation(element);
33325
+ inlineStyle.setProperty("transform", saved2[0] ?? "", saved2[1] ?? "");
33326
+ return { property: "transform", before, after, share, sign: sx * sy < 0 ? -1 : 1, inline };
33327
+ }
33328
+ function applyCssRotation(element, angle, target = readCssRotationTarget(element)) {
33329
+ const turn = `${roundTo3(target.sign * (angle - target.share))}deg`;
33330
+ const value = target.property === "rotate" ? turn : [target.before, `rotate(${turn})`, target.after].filter(Boolean).join(" ");
33331
+ const patches = [
33332
+ { type: "inline-style", property: target.property, value }
33333
+ ];
33334
+ if (target.inline) {
33335
+ patches.unshift({ type: "inline-style", property: "display", value: "inline-block" });
33336
+ }
33337
+ for (const patch of patches) element.style.setProperty(patch.property, patch.value);
33338
+ return patches;
33339
+ }
33340
+ function restorePlainRotation(element, snapshot3) {
33341
+ restoreStudioRotation(element, snapshot3);
33342
+ element.style.setProperty("transform", snapshot3.transform);
33343
+ element.style.setProperty("display", snapshot3.display);
33344
+ }
33345
+ function applyRotationDraft(element, angle, plain) {
33346
+ if (plain) return void applyCssRotation(element, angle, plain);
33347
+ element.style.setProperty("rotate", "none");
33348
+ getOffsetDragGsap(element)?.set(element, { rotation: angle });
33349
+ }
33350
+ function restoreRotationDraft(element, angle, snapshot3, plain) {
33351
+ if (plain) return restorePlainRotation(element, snapshot3);
33352
+ getOffsetDragGsap(element)?.set(element, {
33353
+ rotation: angle - (Number.parseFloat(snapshot3.studioRotation) || 0)
33354
+ });
33355
+ restoreStudioRotation(element, snapshot3);
33356
+ }
33357
+ function readRotationBase(element, plain) {
33358
+ if (plain) return readCssRotation(element);
33359
+ const gsapRotation = Number(getOffsetDragGsap(element)?.getProperty(element, "rotation") ?? 0);
33360
+ return gsapRotation + readStudioRotation(element).angle;
33361
+ }
33362
+
33105
33363
  // src/components/editor/domEditResizeLocal.ts
33106
33364
  var MIN_RESIZE_LOCAL_PX = 1;
33107
33365
  var DEGENERATE_START_DIST_PX = 3;
@@ -33215,27 +33473,6 @@ function resolveResizeDraftRect(g, element, overlayEl, iframe, measureOrientedRe
33215
33473
  };
33216
33474
  }
33217
33475
 
33218
- // src/utils/elementGsap.ts
33219
- function gsapOf(element) {
33220
- return element.ownerDocument.defaultView?.gsap;
33221
- }
33222
- function setElementGsapPosition(element, x, y) {
33223
- const gsap3 = gsapOf(element);
33224
- if (!gsap3?.set) return false;
33225
- gsap3.set(element, { x, y });
33226
- return true;
33227
- }
33228
- function setElementGsapScale(element, x, y) {
33229
- const gsap3 = gsapOf(element);
33230
- if (!gsap3?.set) return false;
33231
- gsap3.set(element, { scaleX: x, scaleY: y });
33232
- return true;
33233
- }
33234
- function readElementGsapNumber(element, prop) {
33235
- const value = Number(gsapOf(element)?.getProperty?.(element, prop));
33236
- return Number.isFinite(value) ? value : null;
33237
- }
33238
-
33239
33476
  // src/components/editor/snapEngine.ts
33240
33477
  var SNAP_THRESHOLD_PX = 6;
33241
33478
  var SNAP_ENGAGE_TRAVEL_PX = 4;
@@ -33806,18 +34043,6 @@ function startGesture(kind, e, opts, options) {
33806
34043
  const rawContentScaleY = rect.height / (rect.editScaleY * actualHeight);
33807
34044
  const contentScaleX = Number.isFinite(rawContentScaleX) && rawContentScaleX > 0 ? rawContentScaleX : 1;
33808
34045
  const contentScaleY = Number.isFinite(rawContentScaleY) && rawContentScaleY > 0 ? rawContentScaleY : 1;
33809
- let resizeAnchor;
33810
- if (kind === "resize") {
33811
- const startBcr = sel.element.getBoundingClientRect();
33812
- resizeAnchor = {
33813
- anchorX: startBcr.x,
33814
- anchorY: startBcr.y,
33815
- baseGsapX: readElementGsapNumber(sel.element, "x") ?? 0,
33816
- baseGsapY: readElementGsapNumber(sel.element, "y") ?? 0,
33817
- pinX: 0,
33818
- pinY: 0
33819
- };
33820
- }
33821
34046
  let initialPathOffset = captureStudioPathOffset(sel.element);
33822
34047
  let manualEditDragToken;
33823
34048
  let pathOffsetMember;
@@ -33845,12 +34070,14 @@ function startGesture(kind, e, opts, options) {
33845
34070
  key: selectionCacheKey(sel),
33846
34071
  selection: sel,
33847
34072
  element: sel.element,
33848
- rect
34073
+ rect,
34074
+ gesture: "resize"
33849
34075
  });
33850
34076
  if (result.ok) {
33851
34077
  pathOffsetMember = result.member;
33852
34078
  initialPathOffset = result.member.initialPathOffset;
33853
34079
  manualEditDragToken = result.member.gestureToken;
34080
+ if (result.member.plainTranslate) applyManualOffsetDragDraft(result.member, 0, 0);
33854
34081
  } else {
33855
34082
  manualEditDragToken = beginStudioManualEditGesture(sel.element);
33856
34083
  }
@@ -33858,8 +34085,9 @@ function startGesture(kind, e, opts, options) {
33858
34085
  manualEditDragToken = beginStudioManualEditGesture(sel.element);
33859
34086
  }
33860
34087
  }
33861
- const gsapRotation = pathOffsetMember?.plainTranslate ? 0 : readGsapRotation(sel.element);
33862
- const rotation = { angle: gsapRotation + readStudioRotation(sel.element).angle };
34088
+ const plain = !!pathOffsetMember?.plainTranslate || !gsapWritesRotation(sel.element);
34089
+ const plainRotation = plain && kind === "rotate" ? readCssRotationTarget(sel.element) : null;
34090
+ const rotation = { angle: readRotationBase(sel.element, plain) };
33863
34091
  const overlayBounds = overlayEl?.getBoundingClientRect();
33864
34092
  const centerX = (overlayBounds?.left ?? 0) + rect.left + rect.width / 2;
33865
34093
  const centerY = (overlayBounds?.top ?? 0) + rect.top + rect.height / 2;
@@ -33897,11 +34125,11 @@ function startGesture(kind, e, opts, options) {
33897
34125
  actualWidth,
33898
34126
  actualHeight,
33899
34127
  actualRotation: rotation.angle,
34128
+ plainRotation,
33900
34129
  editScaleX: rect.editScaleX,
33901
34130
  editScaleY: rect.editScaleY,
33902
34131
  contentScaleX,
33903
34132
  contentScaleY,
33904
- resizeAnchor,
33905
34133
  manualEditDragToken,
33906
34134
  snapContext,
33907
34135
  resizeHandle: kind === "resize" ? options?.resizeHandle ?? "se" : void 0,
@@ -34156,9 +34384,7 @@ function createDomEditOverlayGestureHandlers(opts) {
34156
34384
  actualAngle: g.actualRotation,
34157
34385
  snap: e.shiftKey
34158
34386
  });
34159
- if (!applyRotationDraftViaGsap(sel.element, rotated.angle)) {
34160
- applyStudioRotationDraft(sel.element, rotated);
34161
- }
34387
+ applyRotationDraft(sel.element, rotated.angle, g.plainRotation);
34162
34388
  return;
34163
34389
  }
34164
34390
  if (g.kind === "drag") {
@@ -34293,7 +34519,8 @@ function createDomEditOverlayGestureHandlers(opts) {
34293
34519
  );
34294
34520
  const updates = groupG.members.map((member) => ({
34295
34521
  selection: member.selection,
34296
- next: applyManualOffsetDragCommit(member, dx, dy)
34522
+ next: applyManualOffsetDragCommit(member, dx, dy),
34523
+ plainTranslate: member.plainTranslate
34297
34524
  }));
34298
34525
  logDrag("drop", {
34299
34526
  pointer: `${Math.round(rawDx)},${Math.round(rawDy)}`,
@@ -34366,20 +34593,20 @@ function createDomEditOverlayGestureHandlers(opts) {
34366
34593
  actualAngle: g.actualRotation,
34367
34594
  snap: e.shiftKey
34368
34595
  });
34369
- const restoreRotation = () => {
34370
- if (!applyRotationDraftViaGsap(sel.element, g.actualRotation)) {
34371
- restoreStudioRotation(sel.element, g.initialRotation);
34372
- }
34373
- };
34596
+ const restoreRotation = () => restoreRotationDraft(
34597
+ sel.element,
34598
+ g.actualRotation,
34599
+ g.initialRotation,
34600
+ g.plainRotation !== null
34601
+ );
34374
34602
  if (!hasDomEditRotationChanged(g.actualRotation, finalRotation.angle)) {
34375
34603
  restoreRotation();
34376
34604
  endStudioManualEditGesture(sel.element, g.manualEditDragToken);
34377
34605
  return;
34378
34606
  }
34379
- if (!applyRotationDraftViaGsap(sel.element, finalRotation.angle)) {
34380
- applyStudioRotation(sel.element, finalRotation);
34381
- }
34382
- void Promise.resolve(opts.onRotationCommitRef.current(sel, finalRotation)).catch((error) => {
34607
+ applyRotationDraft(sel.element, finalRotation.angle, g.plainRotation);
34608
+ const commit = g.plainRotation ? { ...finalRotation, plain: g.plainRotation } : finalRotation;
34609
+ void Promise.resolve(opts.onRotationCommitRef.current(sel, commit)).catch((error) => {
34383
34610
  logGestureCommitFailure("rotate commit failed", error);
34384
34611
  if (g.manualEditDragToken && isStudioManualEditGestureCurrent(sel.element, g.manualEditDragToken))
34385
34612
  restoreRotation();
@@ -34408,7 +34635,10 @@ function createDomEditOverlayGestureHandlers(opts) {
34408
34635
  box.style.top = `${nextBoxTop}px`;
34409
34636
  }
34410
34637
  void Promise.resolve(
34411
- opts.onPathOffsetCommitRef.current(sel, finalOffset, { altKey: e.altKey })
34638
+ opts.onPathOffsetCommitRef.current(sel, finalOffset, {
34639
+ altKey: e.altKey,
34640
+ plainTranslate: g.pathOffsetMember.plainTranslate
34641
+ })
34412
34642
  ).catch(() => {
34413
34643
  if (g.pathOffsetMember?.gestureToken && isStudioManualEditGestureCurrent(sel.element, g.pathOffsetMember.gestureToken))
34414
34644
  restoreStudioPathOffset(sel.element, g.initialPathOffset);
@@ -34466,11 +34696,12 @@ function createDomEditOverlayGestureHandlers(opts) {
34466
34696
  restoreGestureOverlayRect(g);
34467
34697
  }
34468
34698
  if (g?.mode === "rotation" && sel) {
34469
- applyRotationDraftViaGsap(
34699
+ restoreRotationDraft(
34470
34700
  sel.element,
34471
- g.actualRotation - (Number.parseFloat(g.initialRotation.studioRotation) || 0)
34701
+ g.actualRotation,
34702
+ g.initialRotation,
34703
+ g.plainRotation !== null
34472
34704
  );
34473
- restoreStudioRotation(sel.element, g.initialRotation);
34474
34705
  endStudioManualEditGesture(sel.element, g.manualEditDragToken);
34475
34706
  }
34476
34707
  opts.blockedMoveRef.current = null;
@@ -34549,10 +34780,13 @@ function useDomEditNudge(params) {
34549
34780
  if (session.timer) clearTimeout(session.timer);
34550
34781
  const updates = session.members.map((member) => ({
34551
34782
  selection: member.selection,
34552
- next: applyManualOffsetNudgeCommit(member, session.accum)
34783
+ next: applyManualOffsetNudgeCommit(member, session.accum),
34784
+ plainTranslate: member.plainTranslate
34553
34785
  }));
34554
34786
  const p = paramsRef.current;
34555
- const commit = session.isGroup ? p.onGroupPathOffsetCommitRef.current(updates) : p.onPathOffsetCommitRef.current(updates[0].selection, updates[0].next);
34787
+ const commit = session.isGroup ? p.onGroupPathOffsetCommitRef.current(updates) : p.onPathOffsetCommitRef.current(updates[0].selection, updates[0].next, {
34788
+ plainTranslate: updates[0].plainTranslate
34789
+ });
34556
34790
  void Promise.resolve(commit).catch(() => {
34557
34791
  for (const member of session.members) {
34558
34792
  if (isStudioManualEditGestureCurrent(member.element, member.gestureToken)) {
@@ -36340,7 +36574,7 @@ function useInlineTextEdit({
36340
36574
  }
36341
36575
  if (event.key === "Escape") {
36342
36576
  event.preventDefault();
36343
- cancel();
36577
+ commit();
36344
36578
  }
36345
36579
  };
36346
36580
  const onBlur = () => commit();
@@ -36368,7 +36602,7 @@ function useInlineTextEdit({
36368
36602
  element.removeEventListener("dragover", onDragOver);
36369
36603
  element.removeEventListener("drop", onDrop);
36370
36604
  };
36371
- }, [session, commit, cancel]);
36605
+ }, [session, commit]);
36372
36606
  const commitRef = useRef66(commit);
36373
36607
  commitRef.current = commit;
36374
36608
  useEffect46(() => () => commitRef.current(), []);
@@ -42566,7 +42800,6 @@ function getAnimationsForElement(animations, target, element) {
42566
42800
 
42567
42801
  // src/hooks/gsapRuntimeBridge.ts
42568
42802
  var POSITION_CHANNEL_SET = new Set(POSITION_CHANNELS);
42569
- var ROTATION_CHANNELS = ["rotation", "rotationX", "rotationY", "rotationZ"];
42570
42803
  var ROTATION_CHANNEL_SET = new Set(ROTATION_CHANNELS);
42571
42804
  async function resolveGroupTween(group, animations, selection, commitMutation, fetchFallbackAnimations) {
42572
42805
  const groupAnims = animations.filter((a) => a.propertyGroup === group);
@@ -48023,14 +48256,16 @@ function createTransformCommitHandlers({
48023
48256
  "This element's position can't be edited here yet \u2014 it is driven by its animation"
48024
48257
  ))
48025
48258
  return;
48026
- const current = readMoveOffset(element.element);
48259
+ const plainTranslate = !gsapWritesPosition(element.element);
48260
+ const current = readMoveOffset(element.element, plainTranslate);
48027
48261
  if (!Number.isFinite(current.x) || !Number.isFinite(current.y))
48028
48262
  return void showToast?.(UNREADABLE_TRANSLATE);
48029
48263
  await Promise.resolve(
48030
- onSetManualOffset(element, {
48031
- x: axis === "x" ? parsed : current.x,
48032
- y: axis === "y" ? parsed : current.y
48033
- })
48264
+ onSetManualOffset(
48265
+ element,
48266
+ { x: axis === "x" ? parsed : current.x, y: axis === "y" ? parsed : current.y },
48267
+ { plainTranslate }
48268
+ )
48034
48269
  );
48035
48270
  };
48036
48271
  const commitManualSize = async (axis, nextValue) => {
@@ -65119,7 +65354,7 @@ var PropertyPanel = memo36(function PropertyPanel2(props) {
65119
65354
  const manualSize = readStudioBoxSize(element.element);
65120
65355
  const resolvedWidth = manualSize.width > 0 ? manualSize.width : parsePxMetricValue(styles.width ?? "") ?? element.boundingBox.width;
65121
65356
  const resolvedHeight = manualSize.height > 0 ? manualSize.height : parsePxMetricValue(styles.height ?? "") ?? element.boundingBox.height;
65122
- const manualRotation = readStudioRotation(element.element);
65357
+ const manualRotation = readShownRotation(element.element);
65123
65358
  const elStart = Number.parseFloat(element?.dataAttributes?.start ?? "0") || 0;
65124
65359
  const elDuration = Number.parseFloat(element?.dataAttributes?.duration ?? "1") || 0;
65125
65360
  const currentPct = elDuration > 0 ? (currentTime - elStart) / elDuration * 100 : 0;
@@ -74448,16 +74683,26 @@ function applyElementPositionOffset(el, gestureOffset) {
74448
74683
  }
74449
74684
 
74450
74685
  // src/hooks/elementOffsetStager.ts
74686
+ var GSAP_TOOK_OVER = "The animation took over this layer's position during the move, so it was not saved.";
74451
74687
  var ELEMENT_OFFSET_REFUSED = {
74452
74688
  anchored: "This layer is anchored from its right or bottom edge. Move it in the Code tab.",
74453
74689
  percent: "This layer's position is set in percent. Move it in the Code tab."
74454
74690
  };
74691
+ function gsapOf(el) {
74692
+ return el.ownerDocument.defaultView?.gsap;
74693
+ }
74455
74694
  function settleGsapDraftAtGestureStart(el) {
74456
- const gsap3 = el.ownerDocument.defaultView?.gsap;
74695
+ const gsap3 = gsapOf(el);
74457
74696
  const x = Number.parseFloat(el.getAttribute("data-hf-drag-gsap-base-x") ?? "");
74458
74697
  const y = Number.parseFloat(el.getAttribute("data-hf-drag-gsap-base-y") ?? "");
74459
74698
  if (gsap3 && Number.isFinite(x) && Number.isFinite(y)) gsap3.set(el, { x, y });
74460
74699
  }
74700
+ function refuseGsapTakeover(el, showToast) {
74701
+ if (!gsapHoldsTranslate(el)) return;
74702
+ gsapOf(el)?.set(el, { x: 0, y: 0, xPercent: 0, yPercent: 0 });
74703
+ showToast(GSAP_TOOK_OVER, "error");
74704
+ throw markStudioSaveErrorAlreadyToasted(new Error(GSAP_TOOK_OVER));
74705
+ }
74461
74706
  var plainMoveCounter = 0;
74462
74707
  function stagePlainTranslate(commitPositionPatchToHtml, selection, next, coalesceKey) {
74463
74708
  const style = selection.element.style;
@@ -74475,10 +74720,11 @@ function stagePlainTranslate(commitPositionPatchToHtml, selection, next, coalesc
74475
74720
  });
74476
74721
  return { save, rollback };
74477
74722
  }
74478
- function stageElementOffset({ commitPositionPatchToHtml, showToast, readOnlyPreview }, selection, next, coalesceKey) {
74723
+ function stageElementOffset({ commitPositionPatchToHtml, showToast, readOnlyPreview }, selection, next, plainTranslate, coalesceKey) {
74479
74724
  const el = selection.element;
74480
74725
  if (readOnlyPreview) return { save: () => Promise.resolve(), rollback: () => void 0 };
74481
- if (!gsapWritesPosition(el)) {
74726
+ if (plainTranslate) {
74727
+ refuseGsapTakeover(el, showToast);
74482
74728
  return stagePlainTranslate(commitPositionPatchToHtml, selection, next, coalesceKey);
74483
74729
  }
74484
74730
  const previous = { position: el.style.position, left: el.style.left, top: el.style.top };
@@ -74504,159 +74750,27 @@ function stageElementOffset({ commitPositionPatchToHtml, showToast, readOnlyPrev
74504
74750
  return { save, rollback };
74505
74751
  }
74506
74752
 
74507
- // src/components/editor/manualEditsDomPatches.ts
74508
- function collectInlineStyleOps(element, properties, ops) {
74509
- for (const prop of properties) {
74510
- const val = element.style.getPropertyValue(prop);
74511
- if (val) ops.push({ type: "inline-style", property: prop, value: val });
74512
- }
74513
- }
74514
- function collectAttributeOps(element, attrNames, ops) {
74515
- for (const attr of attrNames) {
74516
- const val = element.getAttribute(attr);
74517
- if (val !== null) ops.push({ type: "attribute", property: attr, value: val });
74518
- }
74519
- }
74520
- function appendTransformDisplayOps(element, ops) {
74521
- const val = element.getAttribute(STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR);
74522
- if (val !== null) {
74523
- ops.push({ type: "inline-style", property: "display", value: val || null });
74524
- ops.push({ type: "attribute", property: STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR, value: null });
74525
- }
74526
- }
74527
- function buildPathOffsetPatches(element) {
74528
- const ops = [];
74529
- collectInlineStyleOps(element, [STUDIO_OFFSET_X_PROP, STUDIO_OFFSET_Y_PROP], ops);
74530
- const inlineTranslate = element.style.getPropertyValue("translate");
74531
- const hasOffsetVars = element.style.getPropertyValue(STUDIO_OFFSET_X_PROP) || element.style.getPropertyValue(STUDIO_OFFSET_Y_PROP);
74532
- const translateValue = inlineTranslate && inlineTranslate !== "none" ? inlineTranslate : hasOffsetVars ? `var(${STUDIO_OFFSET_X_PROP}, 0px) var(${STUDIO_OFFSET_Y_PROP}, 0px)` : null;
74533
- if (translateValue) {
74534
- ops.push({ type: "inline-style", property: "translate", value: translateValue });
74535
- }
74536
- ops.push({ type: "attribute", property: STUDIO_PATH_OFFSET_ATTR, value: "true" });
74537
- collectAttributeOps(
74538
- element,
74539
- [STUDIO_ORIGINAL_TRANSLATE_ATTR, STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR],
74540
- ops
74541
- );
74542
- collectInlineStyleOps(element, ["display"], ops);
74543
- collectAttributeOps(element, [STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR], ops);
74544
- return ops;
74545
- }
74546
- function buildClearPathOffsetPatches(element) {
74547
- const originalInlineTranslate = element.getAttribute(STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR);
74548
- const ops = [
74549
- { type: "inline-style", property: STUDIO_OFFSET_X_PROP, value: null },
74550
- { type: "inline-style", property: STUDIO_OFFSET_Y_PROP, value: null },
74551
- { type: "inline-style", property: "translate", value: originalInlineTranslate || null },
74552
- { type: "attribute", property: STUDIO_PATH_OFFSET_ATTR, value: null },
74553
- { type: "attribute", property: STUDIO_ORIGINAL_TRANSLATE_ATTR, value: null },
74554
- { type: "attribute", property: STUDIO_ORIGINAL_INLINE_TRANSLATE_ATTR, value: null }
74555
- ];
74556
- appendTransformDisplayOps(element, ops);
74557
- return ops;
74558
- }
74559
- var BOX_SIZE_STYLE_PROPS = [
74560
- "width",
74561
- "height",
74562
- "min-width",
74563
- "min-height",
74564
- "max-width",
74565
- "max-height",
74566
- "flex-basis",
74567
- "flex-grow",
74568
- "flex-shrink",
74569
- "box-sizing",
74570
- "scale",
74571
- "transform-origin",
74572
- "display"
74573
- ];
74574
- var BOX_SIZE_ORIG_ATTRS = [
74575
- [STUDIO_ORIGINAL_WIDTH_ATTR, "width"],
74576
- [STUDIO_ORIGINAL_HEIGHT_ATTR, "height"],
74577
- // Records a measurement rather than a style, so it restores nothing.
74578
- [STUDIO_ORIGINAL_BOX_WIDTH_ATTR, ""],
74579
- [STUDIO_ORIGINAL_BOX_HEIGHT_ATTR, ""],
74580
- [STUDIO_ORIGINAL_MIN_WIDTH_ATTR, "min-width"],
74581
- [STUDIO_ORIGINAL_MIN_HEIGHT_ATTR, "min-height"],
74582
- [STUDIO_ORIGINAL_MAX_WIDTH_ATTR, "max-width"],
74583
- [STUDIO_ORIGINAL_MAX_HEIGHT_ATTR, "max-height"],
74584
- [STUDIO_ORIGINAL_FLEX_BASIS_ATTR, "flex-basis"],
74585
- [STUDIO_ORIGINAL_FLEX_GROW_ATTR, "flex-grow"],
74586
- [STUDIO_ORIGINAL_FLEX_SHRINK_ATTR, "flex-shrink"],
74587
- [STUDIO_ORIGINAL_BOX_SIZING_ATTR, "box-sizing"],
74588
- [STUDIO_ORIGINAL_SCALE_ATTR, "scale"],
74589
- [STUDIO_ORIGINAL_TRANSFORM_ORIGIN_ATTR, "transform-origin"],
74590
- [STUDIO_ORIGINAL_DISPLAY_ATTR, "display"],
74591
- [STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR, ""]
74592
- ];
74593
- function buildBoxSizePatches(element) {
74594
- const ops = [];
74595
- collectInlineStyleOps(element, [STUDIO_WIDTH_PROP, STUDIO_HEIGHT_PROP], ops);
74596
- collectInlineStyleOps(element, BOX_SIZE_STYLE_PROPS, ops);
74597
- ops.push({ type: "attribute", property: STUDIO_BOX_SIZE_ATTR, value: "true" });
74598
- collectAttributeOps(
74599
- element,
74600
- BOX_SIZE_ORIG_ATTRS.map(([attr]) => attr),
74601
- ops
74602
- );
74603
- return ops;
74604
- }
74605
- function buildClearBoxSizePatches(element) {
74606
- const ops = [
74607
- { type: "inline-style", property: STUDIO_WIDTH_PROP, value: null },
74608
- { type: "inline-style", property: STUDIO_HEIGHT_PROP, value: null },
74609
- { type: "attribute", property: STUDIO_BOX_SIZE_ATTR, value: null }
74610
- ];
74611
- for (const [attrName, styleProp] of BOX_SIZE_ORIG_ATTRS) {
74612
- const origVal = element.getAttribute(attrName);
74613
- if (origVal !== null && styleProp) {
74614
- ops.push({ type: "inline-style", property: styleProp, value: origVal || null });
74753
+ // src/hooks/plainRotation.ts
74754
+ var plainRotateCounter = 0;
74755
+ function savePlainRotation({ commitPositionPatchToHtml, readOnlyPreview }, selection, next) {
74756
+ if (readOnlyPreview) return Promise.resolve();
74757
+ const { element } = selection;
74758
+ const before = captureStudioRotation(element);
74759
+ const patches = element.hasAttribute(STUDIO_ROTATION_ATTR) ? buildClearRotationPatches(element) : [];
74760
+ if (patches.length) clearStudioRotation(element);
74761
+ const drawn = applyCssRotation(element, next.angle, patches.length ? void 0 : next.plain);
74762
+ patches.push(...drawn);
74763
+ const turn = drawn.at(-1);
74764
+ return commitPositionPatchToHtml(selection, patches, {
74765
+ label: "Rotate layer",
74766
+ coalesceKey: `rotate:${++plainRotateCounter}`,
74767
+ coalesceMs: Number.POSITIVE_INFINITY
74768
+ }).catch((error) => {
74769
+ if (element.style.getPropertyValue(turn.property) === turn.value) {
74770
+ restorePlainRotation(element, before);
74615
74771
  }
74616
- ops.push({ type: "attribute", property: attrName, value: null });
74617
- }
74618
- return ops;
74619
- }
74620
- var ROTATION_STYLE_PROPS = [
74621
- STUDIO_ROTATION_PROP,
74622
- "rotate",
74623
- "transform-origin",
74624
- "display"
74625
- ];
74626
- var ROTATION_ORIG_ATTRS = [
74627
- STUDIO_ORIGINAL_ROTATE_ATTR,
74628
- STUDIO_ORIGINAL_INLINE_ROTATE_ATTR,
74629
- STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR,
74630
- STUDIO_ORIGINAL_TRANSFORM_DISPLAY_ATTR
74631
- ];
74632
- function buildRotationPatches(element) {
74633
- const ops = [];
74634
- collectInlineStyleOps(element, ROTATION_STYLE_PROPS, ops);
74635
- ops.push({ type: "attribute", property: STUDIO_ROTATION_ATTR, value: "true" });
74636
- collectAttributeOps(element, ROTATION_ORIG_ATTRS, ops);
74637
- return ops;
74638
- }
74639
- function buildClearRotationPatches(element) {
74640
- const origInlineRotate = element.getAttribute(STUDIO_ORIGINAL_INLINE_ROTATE_ATTR);
74641
- const origRotationTransformOrigin = element.getAttribute(
74642
- STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR
74643
- );
74644
- const ops = [
74645
- { type: "inline-style", property: STUDIO_ROTATION_PROP, value: null },
74646
- { type: "inline-style", property: "rotate", value: origInlineRotate || null },
74647
- {
74648
- type: "inline-style",
74649
- property: "transform-origin",
74650
- value: origRotationTransformOrigin !== null ? origRotationTransformOrigin || null : null
74651
- },
74652
- { type: "attribute", property: STUDIO_ROTATION_ATTR, value: null },
74653
- { type: "attribute", property: STUDIO_ROTATION_DRAFT_ATTR, value: null },
74654
- { type: "attribute", property: STUDIO_ORIGINAL_ROTATE_ATTR, value: null },
74655
- { type: "attribute", property: STUDIO_ORIGINAL_INLINE_ROTATE_ATTR, value: null },
74656
- { type: "attribute", property: STUDIO_ORIGINAL_ROTATION_TRANSFORM_ORIGIN_ATTR, value: null }
74657
- ];
74658
- appendTransformDisplayOps(element, ops);
74659
- return ops;
74772
+ throw error;
74773
+ });
74660
74774
  }
74661
74775
 
74662
74776
  // src/hooks/gsapTargetCache.ts
@@ -74722,10 +74836,11 @@ function useDomGeometryCommits({
74722
74836
  readOnlyPreview
74723
74837
  }) {
74724
74838
  const stageElementPositionOffset = useCallback125(
74725
- (selection, next, coalesceKey) => stageElementOffset(
74839
+ (selection, next, plainTranslate, coalesceKey) => stageElementOffset(
74726
74840
  { commitPositionPatchToHtml, showToast, readOnlyPreview },
74727
74841
  selection,
74728
74842
  next,
74843
+ plainTranslate,
74729
74844
  coalesceKey
74730
74845
  ),
74731
74846
  [commitPositionPatchToHtml, readOnlyPreview, showToast]
@@ -74748,49 +74863,36 @@ function useDomGeometryCommits({
74748
74863
  [commitPositionPatchToHtml, previewIframeRef, showToast, readOnlyPreview]
74749
74864
  );
74750
74865
  const handleDomBoxSizeCommit = useCallback125(
74751
- (selection, next, offset) => {
74866
+ (selection, next, offset, restore) => {
74752
74867
  if (readOnlyPreview) return Promise.resolve();
74753
- const gsapFallback = rejectGsapCssFallback(selection, previewIframeRef, showToast);
74754
- if (gsapFallback) return gsapFallback;
74755
- const beforeSize = captureStudioBoxSize(selection.element);
74756
- const beforeOffset = offset ? captureStudioPathOffset(selection.element) : null;
74757
- const stageCrop = prepareCropResize(selection.element);
74758
- applyStudioBoxSize(selection.element, next);
74868
+ const element = selection.element;
74869
+ const beforeSize = captureStudioBoxSize(element);
74870
+ const beforeTranslate = element.style.getPropertyValue("translate");
74871
+ const stageCrop = prepareCropResize(element);
74872
+ applyStudioBoxSize(element, next);
74759
74873
  const crop = stageCrop();
74760
- const patches = buildBoxSizePatches(selection.element);
74874
+ const patches = buildBoxSizePatches(element);
74761
74875
  if (crop) patches.push(crop.patch);
74762
74876
  if (offset) {
74763
- applyStudioPathOffset(selection.element, offset);
74764
- patches.push(...buildPathOffsetPatches(selection.element));
74877
+ writeTranslatePx(element, offset);
74878
+ patches.push(translatePatch(offset));
74765
74879
  }
74766
74880
  return commitPositionPatchToHtml(selection, patches, {
74767
74881
  label: "Resize layer box",
74768
74882
  coalesceKey: `box-size:${getDomEditTargetKey(selection)}`
74769
74883
  }).catch((error) => {
74770
- restoreStudioBoxSize(selection.element, beforeSize);
74771
- if (beforeOffset) restoreStudioPathOffset(selection.element, beforeOffset);
74884
+ restoreStudioBoxSize(element, beforeSize);
74885
+ if (offset) element.style.setProperty("translate", beforeTranslate);
74772
74886
  crop?.revert();
74887
+ restore?.();
74773
74888
  throw error;
74774
74889
  });
74775
74890
  },
74776
- [commitPositionPatchToHtml, previewIframeRef, showToast, readOnlyPreview]
74891
+ [commitPositionPatchToHtml, readOnlyPreview]
74777
74892
  );
74778
74893
  const handleDomRotationCommit = useCallback125(
74779
- (selection, next) => {
74780
- if (readOnlyPreview) return Promise.resolve();
74781
- const gsapFallback = rejectGsapCssFallback(selection, previewIframeRef, showToast);
74782
- if (gsapFallback) return gsapFallback;
74783
- const before = captureStudioRotation(selection.element);
74784
- applyStudioRotation(selection.element, next);
74785
- return commitPositionPatchToHtml(selection, buildRotationPatches(selection.element), {
74786
- label: "Rotate layer",
74787
- coalesceKey: `rotation:${getDomEditTargetKey(selection)}`
74788
- }).catch((error) => {
74789
- restoreStudioRotation(selection.element, before);
74790
- throw error;
74791
- });
74792
- },
74793
- [commitPositionPatchToHtml, previewIframeRef, showToast, readOnlyPreview]
74894
+ (selection, next) => savePlainRotation({ commitPositionPatchToHtml, readOnlyPreview }, selection, next),
74895
+ [commitPositionPatchToHtml, readOnlyPreview]
74794
74896
  );
74795
74897
  const handleDomManualEditsReset = useCallback125(
74796
74898
  (selection) => {
@@ -77239,6 +77341,23 @@ function useDomEditWiring(params) {
77239
77341
  // src/hooks/useGsapAwareEditing.ts
77240
77342
  import { useCallback as useCallback139 } from "react";
77241
77343
 
77344
+ // src/utils/elementGsap.ts
77345
+ function gsapOf2(element) {
77346
+ return element.ownerDocument.defaultView?.gsap;
77347
+ }
77348
+ function setElementGsapPosition(element, x, y) {
77349
+ const gsap3 = gsapOf2(element);
77350
+ if (!gsap3?.set) return false;
77351
+ gsap3.set(element, { x, y });
77352
+ return true;
77353
+ }
77354
+ function setElementGsapScale(element, x, y) {
77355
+ const gsap3 = gsapOf2(element);
77356
+ if (!gsap3?.set) return false;
77357
+ gsap3.set(element, { scaleX: x, scaleY: y });
77358
+ return true;
77359
+ }
77360
+
77242
77361
  // src/hooks/gsapResizePreflight.ts
77243
77362
  function resizeRoute(animations, fetchedAnimations) {
77244
77363
  const allKnownAnimations = [...animations, ...fetchedAnimations];
@@ -77943,6 +78062,7 @@ function useGsapAwareEditing({
77943
78062
  trackGsapInteractionFailure,
77944
78063
  stageElementPositionOffset,
77945
78064
  handleDomBoxSizeCommit,
78065
+ handleDomRotationCommit,
77946
78066
  commitPositionPatchToHtml,
77947
78067
  addGsapAnimation,
77948
78068
  convertToKeyframes,
@@ -77958,8 +78078,8 @@ function useGsapAwareEditing({
77958
78078
  );
77959
78079
  const handleGsapAwarePathOffsetCommit = useCallback139(
77960
78080
  async (selection, next, modifiers) => {
77961
- if (!gsapWritesPosition(selection.element))
77962
- return stageElementPositionOffset(selection, next).save();
78081
+ if (modifiers?.plainTranslate ?? !gsapWritesPosition(selection.element))
78082
+ return stageElementPositionOffset(selection, next, true).save();
77963
78083
  if (gsapCommitMutation) {
77964
78084
  try {
77965
78085
  const ownedAnimations = getGsapAnimationsForSelection(selection);
@@ -77973,7 +78093,7 @@ function useGsapAwareEditing({
77973
78093
  makeFetchFallback(selection),
77974
78094
  modifiers
77975
78095
  );
77976
- await saveMove(outcome, () => stageElementPositionOffset(selection, next).save());
78096
+ await saveMove(outcome, () => stageElementPositionOffset(selection, next, false).save());
77977
78097
  } catch (error) {
77978
78098
  trackGsapInteractionFailure(error, selection, "drag", "Move animated layer");
77979
78099
  throw error;
@@ -78022,10 +78142,13 @@ function useGsapAwareEditing({
78022
78142
  return Promise.resolve();
78023
78143
  };
78024
78144
  const preflightAnimations = /* @__PURE__ */ new Map();
78025
- const offsetMembers = /* @__PURE__ */ new Set();
78145
+ const offsetMembers = /* @__PURE__ */ new Map();
78026
78146
  const preflightResults = await Promise.allSettled(
78027
- updates.map(async ({ selection }) => {
78028
- if (!gsapWritesPosition(selection.element)) return void offsetMembers.add(selection);
78147
+ updates.map(async ({ selection, plainTranslate }) => {
78148
+ if (plainTranslate ?? !gsapWritesPosition(selection.element)) {
78149
+ refuseGsapTakeover(selection.element, showToast);
78150
+ return void offsetMembers.set(selection, true);
78151
+ }
78029
78152
  const animations = await makeFetchFallback(selection, { failOnFetchError: true })();
78030
78153
  preflightAnimations.set(selection, animations);
78031
78154
  const outcome = await tryGsapDragIntercept(
@@ -78037,7 +78160,7 @@ function useGsapAwareEditing({
78037
78160
  void 0,
78038
78161
  { preflightOnly: true, group: true }
78039
78162
  );
78040
- if (outcome.status === "element-offset") offsetMembers.add(selection);
78163
+ if (outcome.status === "element-offset") offsetMembers.set(selection, false);
78041
78164
  assertGsapEditPersisted(outcome);
78042
78165
  })
78043
78166
  );
@@ -78056,8 +78179,9 @@ function useGsapAwareEditing({
78056
78179
  );
78057
78180
  for (const [index, { selection, next }] of updates.entries()) {
78058
78181
  renderOnCommit = index === lastScriptWrite;
78059
- if (offsetMembers.has(selection)) {
78060
- await stageElementPositionOffset(selection, next, coalesceKey).save();
78182
+ const plain = offsetMembers.get(selection);
78183
+ if (plain !== void 0) {
78184
+ await stageElementPositionOffset(selection, next, plain, coalesceKey).save();
78061
78185
  continue;
78062
78186
  }
78063
78187
  try {
@@ -78094,11 +78218,14 @@ function useGsapAwareEditing({
78094
78218
  previewIframeRef,
78095
78219
  makeFetchFallback,
78096
78220
  trackGsapInteractionFailure,
78097
- stageElementPositionOffset
78221
+ stageElementPositionOffset,
78222
+ showToast
78098
78223
  ]
78099
78224
  );
78100
78225
  const handleGsapAwareBoxSizeCommit = useCallback139(
78101
78226
  async (selection, next, offset, restore = () => void 0) => {
78227
+ if (!gsapWritesBox(selection.element))
78228
+ return handleDomBoxSizeCommit(selection, next, offset, restore);
78102
78229
  let targetAnimations;
78103
78230
  try {
78104
78231
  const ownedAnimations = getGsapAnimationsForSelection(selection);
@@ -78169,7 +78296,8 @@ function useGsapAwareEditing({
78169
78296
  makeFetchFallback(selection)
78170
78297
  );
78171
78298
  await saveMove(dragOutcome, async () => {
78172
- anchorMove = stageElementPositionOffset(selection, offset, coalesceKey);
78299
+ const plain = !gsapWritesPosition(selection.element);
78300
+ anchorMove = stageElementPositionOffset(selection, offset, plain, coalesceKey);
78173
78301
  });
78174
78302
  }
78175
78303
  logResizeSettle(selection.element, ownsDragOffset ? "gsap-scale" : "gsap-size");
@@ -78179,13 +78307,7 @@ function useGsapAwareEditing({
78179
78307
  throw error;
78180
78308
  }
78181
78309
  }
78182
- logResize("dom-route", {
78183
- next,
78184
- offset: offset ?? null,
78185
- hadGsapMutation: !!gsapCommitMutation
78186
- });
78187
- logResizeSettle(selection.element, "dom-route");
78188
- await handleDomBoxSizeCommit(selection, next, offset);
78310
+ throw new Error("Resize of a GSAP-owned box has no GSAP writer");
78189
78311
  },
78190
78312
  afterBufferedCommitsSaved: async () => {
78191
78313
  await anchorMove?.save();
@@ -78213,10 +78335,11 @@ function useGsapAwareEditing({
78213
78335
  );
78214
78336
  const handleGsapAwareRotationCommit = useCallback139(
78215
78337
  async (selection, next) => {
78338
+ if (next.plain || !gsapWritesRotation(selection.element))
78339
+ return handleDomRotationCommit(selection, next);
78216
78340
  if (gsapCommitMutation) {
78217
78341
  try {
78218
- const ownedAnimations = getGsapAnimationsForSelection(selection);
78219
- const targetAnimations = Array.isArray(ownedAnimations) ? ownedAnimations : await ownedAnimations;
78342
+ const targetAnimations = await getGsapAnimationsForSelection(selection);
78220
78343
  const outcome = await tryGsapRotationIntercept(
78221
78344
  selection,
78222
78345
  next.angle,
@@ -78237,7 +78360,8 @@ function useGsapAwareEditing({
78237
78360
  previewIframeRef,
78238
78361
  makeFetchFallback,
78239
78362
  trackGsapInteractionFailure,
78240
- getGsapAnimationsForSelection
78363
+ getGsapAnimationsForSelection,
78364
+ handleDomRotationCommit
78241
78365
  ]
78242
78366
  );
78243
78367
  const { commitAnimatedProperties: commitAnimatedPropertiesRaw } = useAnimatedPropertyCommit({
@@ -78779,6 +78903,7 @@ function useDomEditSession({
78779
78903
  stageElementPositionOffset,
78780
78904
  commitPositionPatchToHtml,
78781
78905
  handleDomBoxSizeCommit,
78906
+ handleDomRotationCommit: handleDomCssRotationCommit,
78782
78907
  handleDomManualEditsReset,
78783
78908
  handleDomEditElementsDelete,
78784
78909
  handleDomZIndexReorderCommit
@@ -79008,6 +79133,7 @@ function useDomEditSession({
79008
79133
  trackGsapInteractionFailure,
79009
79134
  stageElementPositionOffset,
79010
79135
  handleDomBoxSizeCommit,
79136
+ handleDomRotationCommit: handleDomCssRotationCommit,
79011
79137
  commitPositionPatchToHtml,
79012
79138
  addGsapAnimation,
79013
79139
  convertToKeyframes,
@@ -92909,7 +93035,6 @@ import { useCallback as useCallback189, useMemo as useMemo84, useRef as useRef18
92909
93035
  var noop2 = () => {
92910
93036
  };
92911
93037
  var NO_SELECTED_ANIMATIONS = [];
92912
- var noDomBoxSizeRoute = () => Promise.reject(new Error("Resize has no DOM route here"));
92913
93038
  function useDomGeometryCommit({
92914
93039
  projectId,
92915
93040
  iframeRef,
@@ -92962,15 +93087,12 @@ function useDomGeometryCommit({
92962
93087
  },
92963
93088
  [commitPositionPatchToHtml, queue2]
92964
93089
  );
92965
- const stageElementPositionOffset = useCallback189(
92966
- (selection, next, coalesceKey) => stageElementOffset(
92967
- { commitPositionPatchToHtml: commitWithFreshQueue, showToast },
92968
- selection,
92969
- next,
92970
- coalesceKey
92971
- ),
92972
- [commitWithFreshQueue, showToast]
92973
- );
93090
+ const { stageElementPositionOffset, handleDomBoxSizeCommit, handleDomRotationCommit } = useDomGeometryCommits({
93091
+ previewIframeRef: iframeRef,
93092
+ showToast,
93093
+ commitPositionPatchToHtml: commitWithFreshQueue,
93094
+ readOnlyPreview: false
93095
+ });
92974
93096
  const makeFetchFallback = useGsapAnimationFetchFallback(projectId);
92975
93097
  const trackGsapInteractionFailure = useGsapInteractionFailureTelemetry(activeCompPath, showToast);
92976
93098
  const {
@@ -92989,7 +93111,8 @@ function useDomGeometryCommit({
92989
93111
  makeFetchFallback,
92990
93112
  trackGsapInteractionFailure,
92991
93113
  stageElementPositionOffset,
92992
- handleDomBoxSizeCommit: noDomBoxSizeRoute,
93114
+ handleDomBoxSizeCommit,
93115
+ handleDomRotationCommit,
92993
93116
  commitPositionPatchToHtml: commitWithFreshQueue,
92994
93117
  addGsapAnimation: gsap3.addGsapAnimation,
92995
93118
  convertToKeyframes: gsap3.convertToKeyframes,