hyperframes 0.7.62 → 0.7.64

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/cli.js CHANGED
@@ -50,7 +50,7 @@ var VERSION;
50
50
  var init_version = __esm({
51
51
  "src/version.ts"() {
52
52
  "use strict";
53
- VERSION = true ? "0.7.62" : "0.0.0-dev";
53
+ VERSION = true ? "0.7.64" : "0.0.0-dev";
54
54
  }
55
55
  });
56
56
 
@@ -53939,9 +53939,9 @@ function getElementName(el) {
53939
53939
  return el.id || el.className?.toString().split(" ")[0] || "Element";
53940
53940
  }
53941
53941
  function getZIndex(el) {
53942
- const timing = readClipTiming(el);
53943
- if (timing.trackSource !== "default" && timing.trackSource !== "invalid") {
53944
- return timing.trackIndex;
53942
+ const timing2 = readClipTiming(el);
53943
+ if (timing2.trackSource !== "default" && timing2.trackSource !== "invalid") {
53944
+ return timing2.trackIndex;
53945
53945
  }
53946
53946
  const style = el.style?.zIndex;
53947
53947
  if (style) return parseInt(style, 10) || 0;
@@ -54048,11 +54048,11 @@ function parseHtml(html) {
54048
54048
  const type = getElementType(el);
54049
54049
  if (!type) return;
54050
54050
  const ownId = el.id || el.getAttribute("data-hf-id");
54051
- const timing = readClipTiming(el, {
54051
+ const timing2 = readClipTiming(el, {
54052
54052
  resolveReferenceEnd: (refId) => resolveEnd(refId, new Set(ownId ? [ownId] : []))
54053
54053
  });
54054
- const start = timing.start ?? 0;
54055
- const duration = timing.duration ?? 5;
54054
+ const start = timing2.start ?? 0;
54055
+ const duration = timing2.duration ?? 5;
54056
54056
  const id = el.getAttribute("data-hf-id") || el.id || `element-${++idCounter}`;
54057
54057
  const name = getElementName(el);
54058
54058
  const zIndex = getZIndex(el);
@@ -72708,10 +72708,10 @@ function collectCompositionIdScenes(ctx, seen, out) {
72708
72708
  const compositionId = readDecodedAttr(tag.raw, "data-composition-id");
72709
72709
  if (!compositionId || !isSceneLikeCompositionId(compositionId) || seen.has(compositionId))
72710
72710
  continue;
72711
- const timing = parseTiming(tag.raw);
72712
- if (!timing || timing.duration <= 0) continue;
72711
+ const timing2 = parseTiming(tag.raw);
72712
+ if (!timing2 || timing2.duration <= 0) continue;
72713
72713
  seen.add(compositionId);
72714
- out.push({ id: compositionId, ...timing });
72714
+ out.push({ id: compositionId, ...timing2 });
72715
72715
  }
72716
72716
  }
72717
72717
  function extractScenesFromClips(ctx) {
@@ -75369,8 +75369,8 @@ ${other.raw}`)
75369
75369
  ({ tags }) => {
75370
75370
  const findings = [];
75371
75371
  for (const tag of tags) {
75372
- const timing = readTagTiming(tag.raw);
75373
- if (timing.diagnostics.some(({ code }) => code === "deprecated-layer")) {
75372
+ const timing2 = readTagTiming(tag.raw);
75373
+ if (timing2.diagnostics.some(({ code }) => code === "deprecated-layer")) {
75374
75374
  const elementId = readAttr(tag.raw, "id") || void 0;
75375
75375
  findings.push({
75376
75376
  code: "deprecated_data_layer",
@@ -75381,7 +75381,7 @@ ${other.raw}`)
75381
75381
  snippet: truncateSnippet(tag.raw)
75382
75382
  });
75383
75383
  }
75384
- if (timing.diagnostics.some(({ code }) => code === "deprecated-end")) {
75384
+ if (timing2.diagnostics.some(({ code }) => code === "deprecated-end")) {
75385
75385
  const elementId = readAttr(tag.raw, "id") || void 0;
75386
75386
  findings.push({
75387
75387
  code: "deprecated_data_end",
@@ -75473,8 +75473,8 @@ ${other.raw}`)
75473
75473
  for (const tag of tags) {
75474
75474
  const trackStr = readAttr(tag.raw, COMPOSITION_ATTRIBUTES2.trackIndex);
75475
75475
  if (!trackStr) continue;
75476
- const timing = readTagTiming(tag.raw);
75477
- const { start, duration } = timing;
75476
+ const timing2 = readTagTiming(tag.raw);
75477
+ const { start, duration } = timing2;
75478
75478
  const track = trackStr;
75479
75479
  if (start == null || duration == null) continue;
75480
75480
  const clips = trackMap.get(track) || [];
@@ -77432,6 +77432,112 @@ var init_htmlBundler = __esm({
77432
77432
  }
77433
77433
  });
77434
77434
 
77435
+ // ../core/dist/compiler/htmlParityContract.js
77436
+ function finiteAttribute(element, name) {
77437
+ const raw = element.getAttribute(name);
77438
+ if (raw === null || raw.trim() === "")
77439
+ return null;
77440
+ const value = Number(raw);
77441
+ return Number.isFinite(value) ? value : null;
77442
+ }
77443
+ function timing(element) {
77444
+ const start = finiteAttribute(element, "data-start") ?? 0;
77445
+ const duration = finiteAttribute(element, "data-duration") ?? (() => {
77446
+ const end = finiteAttribute(element, "data-end");
77447
+ return end === null ? null : Math.max(0, end - start);
77448
+ })();
77449
+ return {
77450
+ start,
77451
+ duration,
77452
+ trackIndex: finiteAttribute(element, "data-track-index") ?? finiteAttribute(element, "data-layer")
77453
+ };
77454
+ }
77455
+ function normalizeJson(value) {
77456
+ if (value === null)
77457
+ return null;
77458
+ try {
77459
+ return JSON.stringify(canonicalizeJson(JSON.parse(value)));
77460
+ } catch {
77461
+ return value.trim();
77462
+ }
77463
+ }
77464
+ function canonicalizeJson(value) {
77465
+ if (Array.isArray(value))
77466
+ return value.map(canonicalizeJson);
77467
+ if (value === null || typeof value !== "object")
77468
+ return value;
77469
+ return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key2, nested]) => [key2, canonicalizeJson(nested)]));
77470
+ }
77471
+ function styleSignatures(document2) {
77472
+ return [...document2.querySelectorAll("style")].map((style) => style.textContent ?? "").flatMap((css) => css.match(/[^{}]+\{[^{}]*--parity-contract\s*:[^{}]+\}/g) ?? []).map((rule) => rule.replace(/\s+/g, " ").replace(/\s*([:;{},])\s*/g, "$1").trim()).sort();
77473
+ }
77474
+ function parityFontFamilies(html) {
77475
+ const families = /* @__PURE__ */ new Set();
77476
+ for (const match of html.matchAll(/font-family\s*:\s*([^;}]+)/gi)) {
77477
+ for (const family of match[1].split(",")) {
77478
+ const normalized2 = family.trim().replace(/^['"]|['"]$/g, "");
77479
+ if (normalized2.startsWith("Parity"))
77480
+ families.add(normalized2);
77481
+ }
77482
+ }
77483
+ return [...families].sort();
77484
+ }
77485
+ function resources(document2) {
77486
+ const resources2 = [];
77487
+ for (const [index, element] of [
77488
+ ...document2.querySelectorAll("[src], [href], [poster]")
77489
+ ].entries()) {
77490
+ for (const attribute2 of ["src", "href", "poster"]) {
77491
+ const value = element.getAttribute(attribute2)?.trim();
77492
+ if (!value)
77493
+ continue;
77494
+ if (element.tagName.toLowerCase() === "script" && /hyperframes|runtime/i.test(value))
77495
+ continue;
77496
+ resources2.push({
77497
+ identity: element.getAttribute("data-hf-id") ?? element.getAttribute("id") ?? `${element.tagName.toLowerCase()}[${index}]`,
77498
+ attribute: attribute2,
77499
+ locality: /^https?:\/\//i.test(value) ? "remote" : "local"
77500
+ });
77501
+ }
77502
+ }
77503
+ return resources2.sort((left, right) => `${left.identity}:${left.attribute}`.localeCompare(`${right.identity}:${right.attribute}`));
77504
+ }
77505
+ function extractCompiledHtmlParityContract(html) {
77506
+ const { document: document2 } = parseHTML(html);
77507
+ const compositions = [...document2.querySelectorAll("[data-composition-id]")].map((element) => {
77508
+ const resolved2 = timing(element);
77509
+ return {
77510
+ id: element.getAttribute("data-composition-id") ?? "",
77511
+ originalId: element.getAttribute("data-hf-original-composition-id"),
77512
+ ...resolved2,
77513
+ width: finiteAttribute(element, "data-width"),
77514
+ height: finiteAttribute(element, "data-height"),
77515
+ variableValues: normalizeJson(element.getAttribute("data-variable-values"))
77516
+ };
77517
+ });
77518
+ const timedElements = [
77519
+ ...document2.querySelectorAll("[data-start], [data-duration], [data-end], [data-track-index], [data-layer]")
77520
+ ].filter((element) => !element.hasAttribute("data-composition-id")).map((element, index) => ({
77521
+ identity: element.getAttribute("data-hf-id") ?? element.getAttribute("id") ?? `${element.tagName.toLowerCase()}[${index}]`,
77522
+ ...timing(element)
77523
+ }));
77524
+ return {
77525
+ compositions,
77526
+ timedElements,
77527
+ authoredStyleSignatures: styleSignatures(document2),
77528
+ parityFontFamilies: parityFontFamilies(html),
77529
+ resources: resources(document2),
77530
+ runtimeBootstrap: /__hyperframes|data-hyperframes-(?:preview-)?runtime/i.test(html),
77531
+ variableBootstrap: /__hfVariables(?:ByComp)?/.test(html)
77532
+ };
77533
+ }
77534
+ var init_htmlParityContract = __esm({
77535
+ "../core/dist/compiler/htmlParityContract.js"() {
77536
+ "use strict";
77537
+ init_esm10();
77538
+ }
77539
+ });
77540
+
77435
77541
  // ../core/dist/compiler/index.js
77436
77542
  var compiler_exports = {};
77437
77543
  __export(compiler_exports, {
@@ -77447,6 +77553,7 @@ __export(compiler_exports, {
77447
77553
  compileHtml: () => compileHtml,
77448
77554
  compileTimingAttrs: () => compileTimingAttrs,
77449
77555
  emitRootCompositionVariableStyles: () => emitRootCompositionVariableStyles,
77556
+ extractCompiledHtmlParityContract: () => extractCompiledHtmlParityContract,
77450
77557
  extractResolvedMedia: () => extractResolvedMedia,
77451
77558
  injectDurations: () => injectDurations,
77452
77559
  injectScriptsAtHeadStart: () => injectScriptsAtHeadStart,
@@ -77474,6 +77581,7 @@ var init_compiler = __esm({
77474
77581
  init_htmlCompiler();
77475
77582
  init_htmlBundler();
77476
77583
  init_getVariables();
77584
+ init_htmlParityContract();
77477
77585
  init_htmlDocument();
77478
77586
  init_staticGuard();
77479
77587
  init_compositionScoping();
@@ -93616,8 +93724,8 @@ function probeElementInSource(source, target) {
93616
93724
  return el != null && isHTMLElement(el);
93617
93725
  }
93618
93726
  function resolveElementTiming(el) {
93619
- const timing = readClipTiming2(el);
93620
- return { start: timing.start ?? 0, duration: timing.duration ?? 0 };
93727
+ const timing2 = readClipTiming2(el);
93728
+ return { start: timing2.start ?? 0, duration: timing2.duration ?? 0 };
93621
93729
  }
93622
93730
  function setElementDuration(el, start, duration) {
93623
93731
  writeClipTiming2(el, {
@@ -93629,8 +93737,8 @@ function splitElementInHtml(source, target, splitTime, newId, fallbackTiming) {
93629
93737
  const { document: document2, wrappedFragment } = parseSourceDocument(source);
93630
93738
  const el = findTargetElement(document2, target);
93631
93739
  if (!el || !isHTMLElement(el)) return { html: source, matched: false, newId: null };
93632
- const timing = resolveElementTiming(el);
93633
- let { start, duration } = timing;
93740
+ const timing2 = resolveElementTiming(el);
93741
+ let { start, duration } = timing2;
93634
93742
  if (duration <= 0 && fallbackTiming && fallbackTiming.duration > 0) {
93635
93743
  start = fallbackTiming.start;
93636
93744
  duration = fallbackTiming.duration;
@@ -97659,6 +97767,72 @@ function updateArcSegmentInScript(script, animationId, segmentIndex, update2) {
97659
97767
  ms.overwrite(mpProp.value.start, mpProp.value.end, motionPathCode);
97660
97768
  return ms.toString();
97661
97769
  }
97770
+ function hasCubicSegments(segments) {
97771
+ return segments.some((segment) => segment.cp1 != null || segment.cp2 != null);
97772
+ }
97773
+ function writeMotionPathValue(script, target, waypoints, segments, autoRotate) {
97774
+ const motionPath = findPropertyNode22(target.call.varsArg, "motionPath");
97775
+ if (!motionPath) return script;
97776
+ const code = buildMotionPathObjectCode({ waypoints, segments, autoRotate });
97777
+ const ms = new MagicString(script);
97778
+ ms.overwrite(motionPath.value.start, motionPath.value.end, code);
97779
+ return ms.toString();
97780
+ }
97781
+ function updateMotionPathPointInScript(script, animationId, pointIndex, point) {
97782
+ const parsed = parseGsapScriptAcornForWrite3(script);
97783
+ const target = parsed?.located.find((entry) => entry.id === animationId);
97784
+ if (!target?.animation.arcPath?.enabled) return script;
97785
+ const waypoints = extractArcWaypoints(target.animation);
97786
+ if (waypoints.length < 2 || pointIndex < 0 || pointIndex >= waypoints.length) return script;
97787
+ const next = waypoints.map((waypoint, index) => index === pointIndex ? { ...point } : waypoint);
97788
+ return writeMotionPathValue(
97789
+ script,
97790
+ target,
97791
+ next,
97792
+ target.animation.arcPath.segments,
97793
+ target.animation.arcPath.autoRotate
97794
+ );
97795
+ }
97796
+ function addMotionPathPointInScript(script, animationId, index, point) {
97797
+ const parsed = parseGsapScriptAcornForWrite3(script);
97798
+ const target = parsed?.located.find((entry) => entry.id === animationId);
97799
+ const arc = target?.animation.arcPath;
97800
+ if (!target || !arc?.enabled || hasCubicSegments(arc.segments)) return script;
97801
+ const waypoints = extractArcWaypoints(target.animation);
97802
+ if (index < 1 || index > waypoints.length - 1) return script;
97803
+ const segments = [...arc.segments];
97804
+ waypoints.splice(index, 0, { ...point });
97805
+ segments.splice(index - 1, 0, { curviness: segments[index - 1]?.curviness ?? 1 });
97806
+ return writeMotionPathValue(script, target, waypoints, segments, arc.autoRotate);
97807
+ }
97808
+ function removeMotionPathPointInScript(script, animationId, index) {
97809
+ const parsed = parseGsapScriptAcornForWrite3(script);
97810
+ const target = parsed?.located.find((entry) => entry.id === animationId);
97811
+ const arc = target?.animation.arcPath;
97812
+ if (!target || !arc?.enabled || hasCubicSegments(arc.segments)) return script;
97813
+ const waypoints = extractArcWaypoints(target.animation);
97814
+ if (waypoints.length <= 2 || index < 0 || index >= waypoints.length) return script;
97815
+ const segments = [...arc.segments];
97816
+ waypoints.splice(index, 1);
97817
+ segments.splice(Math.min(index, segments.length - 1), 1);
97818
+ return writeMotionPathValue(script, target, waypoints, segments, arc.autoRotate);
97819
+ }
97820
+ function addMotionPathToScript(script, targetSelector, position, duration, point, ease = "power1.inOut") {
97821
+ const motionPath = buildMotionPathObjectCode({
97822
+ waypoints: [{ x: 0, y: 0 }, { ...point }],
97823
+ segments: [{ curviness: 1 }],
97824
+ autoRotate: false
97825
+ });
97826
+ const result = addAnimationToScript(script, {
97827
+ targetSelector,
97828
+ method: "to",
97829
+ position,
97830
+ duration,
97831
+ ease,
97832
+ properties: { motionPath: `__raw:${motionPath}` }
97833
+ });
97834
+ return { script: result.script, id: result.id || null };
97835
+ }
97662
97836
  function removeArcPathFromScript(script, animationId) {
97663
97837
  return setArcPathInScript(script, animationId, {
97664
97838
  enabled: false,
@@ -97697,6 +97871,56 @@ function insertInheritedStateSetInScript(script, selector, position, properties)
97697
97871
  }
97698
97872
  return ms.toString();
97699
97873
  }
97874
+ function isStudioHoldSet(animation) {
97875
+ return animation.method === "set" && animation.properties.data === STUDIO_HOLD_MARKER;
97876
+ }
97877
+ function removeStudioHoldSets(script, parsed) {
97878
+ const staleHolds = parsed.located.filter((entry) => isStudioHoldSet(entry.animation));
97879
+ if (staleHolds.length === 0) return script;
97880
+ const ms = new MagicString(script);
97881
+ for (const hold of staleHolds) removeCallFromMagicString2(ms, hold.call, script);
97882
+ return ms.toString();
97883
+ }
97884
+ function animationStart(animation) {
97885
+ if (animation.resolvedStart !== void 0) return animation.resolvedStart;
97886
+ return typeof animation.position === "number" ? animation.position : 0;
97887
+ }
97888
+ function positionProperties(properties) {
97889
+ const position = {};
97890
+ for (const [property, value] of Object.entries(properties)) {
97891
+ if (classifyPropertyGroup4(property) === "position" && typeof value === "number") {
97892
+ position[property] = value;
97893
+ }
97894
+ }
97895
+ return position;
97896
+ }
97897
+ function positionHoldForAnimation(animation) {
97898
+ if (!animation.keyframes) return null;
97899
+ if (!(animationStart(animation) > 1e-3)) return null;
97900
+ const first = [...animation.keyframes.keyframes].sort(
97901
+ (left, right) => left.percentage - right.percentage
97902
+ )[0];
97903
+ if (!first) return null;
97904
+ const position = positionProperties(first.properties);
97905
+ return Object.keys(position).length > 0 ? position : null;
97906
+ }
97907
+ function syncPositionHoldsBeforeKeyframes(script) {
97908
+ const parsed = parseGsapScriptAcornForWrite3(script);
97909
+ if (!parsed) return script;
97910
+ let result = removeStudioHoldSets(script, parsed);
97911
+ const current2 = parseGsapScriptAcornForWrite3(result);
97912
+ if (!current2) return result;
97913
+ for (const entry of current2.located) {
97914
+ const animation = entry.animation;
97915
+ const position = positionHoldForAnimation(animation);
97916
+ if (!position) continue;
97917
+ result = insertInheritedStateSetInScript(result, animation.targetSelector, 0, {
97918
+ ...position,
97919
+ data: STUDIO_HOLD_MARKER
97920
+ });
97921
+ }
97922
+ return result;
97923
+ }
97700
97924
  function computeForwardBaselines(matching, splitTime) {
97701
97925
  const before3 = [];
97702
97926
  const acc = {};
@@ -97981,7 +98205,7 @@ function unrollDynamicAnimations(script, animationId, elements) {
97981
98205
  }
97982
98206
  return ms.toString();
97983
98207
  }
97984
- var PROPERTY_GROUPS4, PROP_TO_GROUP4, CSS_IDENTITY, GSAP_METHODS4, QUERY_METHODS3, ITERATION_METHODS3, SCOPE_NODE_TYPES3, CONST_NODES3, MATH_FNS3, MATH_CONSTS3, BUILTIN_VAR_KEYS3, DROPPED_VAR_KEYS3, EXTRAS_KEYS3, PERCENTAGE_KEY_RE3, GSAP_DEFAULT_DURATION3, NON_EDITABLE_PROP_KEYS, CSS_IDENTITY2, NON_EDITABLE_VAR_KEYS, PERCENTAGE_KEY_RE22, PCT_TOLERANCE, MOVE_NOOP_EPSILON_PCT, LITERAL_NODE_TYPES, REFUSE_UNROLL;
98208
+ var PROPERTY_GROUPS4, PROP_TO_GROUP4, CSS_IDENTITY, GSAP_METHODS4, QUERY_METHODS3, ITERATION_METHODS3, SCOPE_NODE_TYPES3, CONST_NODES3, MATH_FNS3, MATH_CONSTS3, BUILTIN_VAR_KEYS3, DROPPED_VAR_KEYS3, EXTRAS_KEYS3, PERCENTAGE_KEY_RE3, GSAP_DEFAULT_DURATION3, NON_EDITABLE_PROP_KEYS, CSS_IDENTITY2, NON_EDITABLE_VAR_KEYS, PERCENTAGE_KEY_RE22, PCT_TOLERANCE, MOVE_NOOP_EPSILON_PCT, LITERAL_NODE_TYPES, STUDIO_HOLD_MARKER, REFUSE_UNROLL;
97985
98209
  var init_gsapWriterAcorn = __esm({
97986
98210
  "../parsers/dist/gsapWriterAcorn.js"() {
97987
98211
  "use strict";
@@ -98076,6 +98300,7 @@ var init_gsapWriterAcorn = __esm({
98076
98300
  PCT_TOLERANCE = 2;
98077
98301
  MOVE_NOOP_EPSILON_PCT = 0.05;
98078
98302
  LITERAL_NODE_TYPES = /* @__PURE__ */ new Set(["Literal", "NumericLiteral", "StringLiteral"]);
98303
+ STUDIO_HOLD_MARKER = "hf-hold";
98079
98304
  REFUSE_UNROLL = /* @__PURE__ */ Symbol("refuse-unroll");
98080
98305
  }
98081
98306
  });
@@ -98435,8 +98660,8 @@ __export(gsapParser_exports, {
98435
98660
  addAnimationToScript: () => addAnimationToScript2,
98436
98661
  addAnimationWithKeyframesToScript: () => addAnimationWithKeyframesToScript2,
98437
98662
  addKeyframeToScript: () => addKeyframeToScript2,
98438
- addMotionPathPointInScript: () => addMotionPathPointInScript,
98439
- addMotionPathToScript: () => addMotionPathToScript,
98663
+ addMotionPathPointInScript: () => addMotionPathPointInScript2,
98664
+ addMotionPathToScript: () => addMotionPathToScript2,
98440
98665
  classifyPropertyGroup: () => classifyPropertyGroup5,
98441
98666
  classifyTweenPropertyGroup: () => classifyTweenPropertyGroup4,
98442
98667
  convertToKeyframesInScript: () => convertToKeyframesInScript,
@@ -98444,7 +98669,7 @@ __export(gsapParser_exports, {
98444
98669
  generateSpringEaseData: () => generateSpringEaseData,
98445
98670
  getAnimationsForElementId: () => getAnimationsForElementId2,
98446
98671
  gsapAnimationsToKeyframes: () => gsapAnimationsToKeyframes2,
98447
- isStudioHoldSet: () => isStudioHoldSet,
98672
+ isStudioHoldSet: () => isStudioHoldSet2,
98448
98673
  keyframesToGsapAnimations: () => keyframesToGsapAnimations2,
98449
98674
  materializeKeyframesInScript: () => materializeKeyframesInScript,
98450
98675
  moveKeyframeInScript: () => moveKeyframeInScript2,
@@ -98453,7 +98678,7 @@ __export(gsapParser_exports, {
98453
98678
  removeAnimationFromScript: () => removeAnimationFromScript3,
98454
98679
  removeArcPathFromScript: () => removeArcPathFromScript2,
98455
98680
  removeKeyframeFromScript: () => removeKeyframeFromScript2,
98456
- removeMotionPathPointInScript: () => removeMotionPathPointInScript,
98681
+ removeMotionPathPointInScript: () => removeMotionPathPointInScript2,
98457
98682
  resizeKeyframedTweenInScript: () => resizeKeyframedTweenInScript2,
98458
98683
  scalePositionsInScript: () => scalePositionsInScript2,
98459
98684
  serializeGsapAnimations: () => serializeGsapAnimations2,
@@ -98461,12 +98686,12 @@ __export(gsapParser_exports, {
98461
98686
  shiftPositionsInScript: () => shiftPositionsInScript2,
98462
98687
  splitAnimationsInScript: () => splitAnimationsInScript2,
98463
98688
  splitIntoPropertyGroups: () => splitIntoPropertyGroups,
98464
- syncPositionHoldsBeforeKeyframes: () => syncPositionHoldsBeforeKeyframes,
98689
+ syncPositionHoldsBeforeKeyframes: () => syncPositionHoldsBeforeKeyframes2,
98465
98690
  unrollDynamicAnimations: () => unrollDynamicAnimations2,
98466
98691
  updateAnimationInScript: () => updateAnimationInScript2,
98467
98692
  updateArcSegmentInScript: () => updateArcSegmentInScript2,
98468
98693
  updateKeyframeInScript: () => updateKeyframeInScript2,
98469
- updateMotionPathPointInScript: () => updateMotionPathPointInScript,
98694
+ updateMotionPathPointInScript: () => updateMotionPathPointInScript2,
98470
98695
  validateCompositionGsap: () => validateCompositionGsap2
98471
98696
  });
98472
98697
  function classifyPropertyGroup5(prop2) {
@@ -99725,7 +99950,13 @@ function addAnimationToScript2(script, animation) {
99725
99950
  const id = `anim-${Date.now()}`;
99726
99951
  const statementCode = buildTweenStatementCode2(parsed.timelineVar, animation);
99727
99952
  const newStatement = parseScript(statementCode).program.body[0];
99728
- insertAfterAnchor(parsed, newStatement);
99953
+ if (animation.method === "set" && animation.global) {
99954
+ const timeline = findTimelineDeclarationPath(parsed.ast, parsed.timelineVar);
99955
+ if (timeline) timeline.insertBefore(newStatement);
99956
+ else insertAfterAnchor(parsed, newStatement);
99957
+ } else {
99958
+ insertAfterAnchor(parsed, newStatement);
99959
+ }
99729
99960
  return { script: recast2.print(parsed.ast).code, id };
99730
99961
  }
99731
99962
  function addAnimationWithKeyframesToScript2(script, targetSelector, position, duration, keyframes, ease, easeEach) {
@@ -99854,10 +100085,10 @@ function insertInheritedStateSet(script, selector, position, properties) {
99854
100085
  }
99855
100086
  return recast2.print(parsed.ast).code;
99856
100087
  }
99857
- function isStudioHoldSet(anim) {
99858
- return anim.method === "set" && anim.properties?.data === STUDIO_HOLD_MARKER;
100088
+ function isStudioHoldSet2(anim) {
100089
+ return anim.method === "set" && anim.properties?.data === STUDIO_HOLD_MARKER2;
99859
100090
  }
99860
- function syncPositionHoldsBeforeKeyframes(script) {
100091
+ function syncPositionHoldsBeforeKeyframes2(script) {
99861
100092
  let parsed;
99862
100093
  try {
99863
100094
  parsed = parseGsapScript(script);
@@ -99865,7 +100096,7 @@ function syncPositionHoldsBeforeKeyframes(script) {
99865
100096
  return script;
99866
100097
  }
99867
100098
  let result = script;
99868
- const staleHoldIds = parsed.animations.filter(isStudioHoldSet).map((a) => a.id);
100099
+ const staleHoldIds = parsed.animations.filter(isStudioHoldSet2).map((a) => a.id);
99869
100100
  for (const id of staleHoldIds) result = removeAnimationFromScript3(result, id);
99870
100101
  let reparsed;
99871
100102
  try {
@@ -99886,7 +100117,7 @@ function syncPositionHoldsBeforeKeyframes(script) {
99886
100117
  if (Object.keys(posProps).length === 0) continue;
99887
100118
  result = insertInheritedStateSet(result, anim.targetSelector, 0, {
99888
100119
  ...posProps,
99889
- data: STUDIO_HOLD_MARKER
100120
+ data: STUDIO_HOLD_MARKER2
99890
100121
  });
99891
100122
  }
99892
100123
  return result;
@@ -100591,7 +100822,7 @@ function updateArcSegmentInScript2(script, animationId, segmentIndex, update2) {
100591
100822
  }
100592
100823
  return recast2.print(loc.parsed.ast).code;
100593
100824
  }
100594
- function updateMotionPathPointInScript(script, animationId, pointIndex, point) {
100825
+ function updateMotionPathPointInScript2(script, animationId, pointIndex, point) {
100595
100826
  const loc = locateAnimation(script, animationId);
100596
100827
  if (!loc) return script;
100597
100828
  const anim = loc.target.animation;
@@ -100615,10 +100846,10 @@ function updateMotionPathPointInScript(script, animationId, pointIndex, point) {
100615
100846
  }
100616
100847
  return recast2.print(loc.parsed.ast).code;
100617
100848
  }
100618
- function hasCubicSegments(segments) {
100849
+ function hasCubicSegments2(segments) {
100619
100850
  return segments.some((s2) => s2.cp1 != null || s2.cp2 != null);
100620
100851
  }
100621
- function writeMotionPathValue(loc, waypoints, segments, autoRotate) {
100852
+ function writeMotionPathValue2(loc, waypoints, segments, autoRotate) {
100622
100853
  const motionPathCode = buildMotionPathObjectCode2({ waypoints, segments, autoRotate });
100623
100854
  const varsArg = loc.target.call.varsArg;
100624
100855
  const existingProp = varsArg.properties.find(
@@ -100627,32 +100858,32 @@ function writeMotionPathValue(loc, waypoints, segments, autoRotate) {
100627
100858
  if (existingProp) existingProp.value = parseExpr(motionPathCode);
100628
100859
  return recast2.print(loc.parsed.ast).code;
100629
100860
  }
100630
- function addMotionPathPointInScript(script, animationId, index, point) {
100861
+ function addMotionPathPointInScript2(script, animationId, index, point) {
100631
100862
  const loc = locateAnimation(script, animationId);
100632
100863
  if (!loc) return script;
100633
100864
  const anim = loc.target.animation;
100634
- if (!anim.arcPath?.enabled || hasCubicSegments(anim.arcPath.segments)) return script;
100865
+ if (!anim.arcPath?.enabled || hasCubicSegments2(anim.arcPath.segments)) return script;
100635
100866
  const waypoints = extractArcWaypoints2(anim);
100636
100867
  if (index < 1 || index > waypoints.length - 1) return script;
100637
100868
  const segments = [...anim.arcPath.segments];
100638
100869
  waypoints.splice(index, 0, { x: point.x, y: point.y });
100639
100870
  const splitCurviness = segments[index - 1]?.curviness ?? 1;
100640
100871
  segments.splice(index - 1, 0, { curviness: splitCurviness });
100641
- return writeMotionPathValue(loc, waypoints, segments, anim.arcPath.autoRotate);
100872
+ return writeMotionPathValue2(loc, waypoints, segments, anim.arcPath.autoRotate);
100642
100873
  }
100643
- function removeMotionPathPointInScript(script, animationId, index) {
100874
+ function removeMotionPathPointInScript2(script, animationId, index) {
100644
100875
  const loc = locateAnimation(script, animationId);
100645
100876
  if (!loc) return script;
100646
100877
  const anim = loc.target.animation;
100647
- if (!anim.arcPath?.enabled || hasCubicSegments(anim.arcPath.segments)) return script;
100878
+ if (!anim.arcPath?.enabled || hasCubicSegments2(anim.arcPath.segments)) return script;
100648
100879
  const waypoints = extractArcWaypoints2(anim);
100649
100880
  if (waypoints.length <= 2 || index < 0 || index >= waypoints.length) return script;
100650
100881
  const segments = [...anim.arcPath.segments];
100651
100882
  waypoints.splice(index, 1);
100652
100883
  segments.splice(Math.min(index, segments.length - 1), 1);
100653
- return writeMotionPathValue(loc, waypoints, segments, anim.arcPath.autoRotate);
100884
+ return writeMotionPathValue2(loc, waypoints, segments, anim.arcPath.autoRotate);
100654
100885
  }
100655
- function addMotionPathToScript(script, targetSelector, position, duration, point, ease = "power1.inOut") {
100886
+ function addMotionPathToScript2(script, targetSelector, position, duration, point, ease = "power1.inOut") {
100656
100887
  let parsed;
100657
100888
  try {
100658
100889
  parsed = parseGsapAst(script);
@@ -100839,7 +101070,7 @@ function unrollDynamicAnimations2(script, animationId, elements) {
100839
101070
  }
100840
101071
  return script;
100841
101072
  }
100842
- var recast2, import_parser3, SUPPORTED_PROPS, PROPERTY_GROUPS5, PROP_TO_GROUP5, SUPPORTED_EASES, FORBIDDEN_GSAP_PATTERNS2, CSS_IDENTITY3, SPRING_PRESETS, GSAP_METHODS5, QUERY_METHODS4, ITERATION_METHODS4, SCOPE_NODE_TYPES4, BUILTIN_VAR_KEYS4, DROPPED_VAR_KEYS4, EXTRAS_KEYS4, PERCENTAGE_KEY_RE4, GSAP_DEFAULT_DURATION4, STUDIO_HOLD_MARKER, PCT_TOLERANCE2, MOVE_NOOP_EPSILON_PCT2, ANIM_ID_RE;
101073
+ var recast2, import_parser3, SUPPORTED_PROPS, PROPERTY_GROUPS5, PROP_TO_GROUP5, SUPPORTED_EASES, FORBIDDEN_GSAP_PATTERNS2, CSS_IDENTITY3, SPRING_PRESETS, GSAP_METHODS5, QUERY_METHODS4, ITERATION_METHODS4, SCOPE_NODE_TYPES4, BUILTIN_VAR_KEYS4, DROPPED_VAR_KEYS4, EXTRAS_KEYS4, PERCENTAGE_KEY_RE4, GSAP_DEFAULT_DURATION4, STUDIO_HOLD_MARKER2, PCT_TOLERANCE2, MOVE_NOOP_EPSILON_PCT2, ANIM_ID_RE;
100843
101074
  var init_gsapParser = __esm({
100844
101075
  "../parsers/dist/gsapParser.js"() {
100845
101076
  "use strict";
@@ -100985,7 +101216,7 @@ var init_gsapParser = __esm({
100985
101216
  ]);
100986
101217
  PERCENTAGE_KEY_RE4 = /^(\d+(?:\.\d+)?)%$/;
100987
101218
  GSAP_DEFAULT_DURATION4 = 0.5;
100988
- STUDIO_HOLD_MARKER = "hf-hold";
101219
+ STUDIO_HOLD_MARKER2 = "hf-hold";
100989
101220
  PCT_TOLERANCE2 = 2;
100990
101221
  MOVE_NOOP_EPSILON_PCT2 = 0.05;
100991
101222
  ANIM_ID_RE = /^(.*)-(fromTo|from|to|set)-(\d+)-([a-z]+)$/;
@@ -101677,9 +101908,10 @@ function insertCompositionIntoSource(input2) {
101677
101908
  }
101678
101909
  return { html: document2.toString(), hostId, track, duration };
101679
101910
  }
101680
- function isAcornGsapWriterEnabled() {
101681
- const val = process.env["STUDIO_SDK_CUTOVER_ENABLED"];
101682
- return val === "true" || val === "1";
101911
+ function resolveGsapWriter(env) {
101912
+ const configured = env.HYPERFRAMES_GSAP_WRITER ?? "recast";
101913
+ if (configured === "recast" || configured === "acorn") return configured;
101914
+ throw new Error(`Invalid ${GSAP_WRITER_MIGRATION.flag}=${configured}; expected recast or acorn`);
101683
101915
  }
101684
101916
  async function loadGsapParser() {
101685
101917
  return Promise.resolve().then(() => (init_gsapParser(), gsapParser_exports));
@@ -102119,8 +102351,8 @@ function bakeVisibilityOnDelete(document2, anim) {
102119
102351
  } catch {
102120
102352
  }
102121
102353
  }
102122
- async function executeGsapMutation(body, block, respond2) {
102123
- if (!isAcornGsapWriterEnabled()) {
102354
+ async function executeGsapMutation(body, block, respond2, writer) {
102355
+ if (writer === "recast") {
102124
102356
  return executeGsapMutationRecast(body, block, respond2);
102125
102357
  }
102126
102358
  return executeGsapMutationAcorn(body, block, respond2);
@@ -102181,16 +102413,23 @@ async function applyGsapMutations(c3, res, mutations) {
102181
102413
  const initialScript = block.scriptText;
102182
102414
  const skippedSelectors = /* @__PURE__ */ new Set();
102183
102415
  const respond2 = (data2, status) => status ? c3.json(data2, status) : c3.json(data2);
102416
+ let writer;
102417
+ try {
102418
+ writer = resolveGsapWriter({
102419
+ HYPERFRAMES_GSAP_WRITER: process.env["HYPERFRAMES_GSAP_WRITER"]
102420
+ });
102421
+ } catch (error) {
102422
+ return c3.json({ error: error instanceof Error ? error.message : String(error) }, 400);
102423
+ }
102184
102424
  for (const mutation of mutations) {
102185
- const result = await executeGsapMutation(mutation, block, respond2);
102425
+ const result = await executeGsapMutation(mutation, block, respond2, writer);
102186
102426
  if (result instanceof Response) return result;
102187
102427
  let newScript = typeof result === "string" ? result : result.script;
102188
102428
  if (typeof result !== "string") {
102189
102429
  for (const selector of result.skippedSelectors) skippedSelectors.add(selector);
102190
102430
  }
102191
102431
  if (HOLD_SYNC_MUTATION_TYPES.has(mutation.type)) {
102192
- const parser = await loadGsapParser();
102193
- newScript = parser.syncPositionHoldsBeforeKeyframes(newScript);
102432
+ newScript = writer === "acorn" ? syncPositionHoldsBeforeKeyframes(newScript) : (await loadGsapParser()).syncPositionHoldsBeforeKeyframes(newScript);
102194
102433
  }
102195
102434
  block.scriptText = newScript;
102196
102435
  }
@@ -102269,6 +102508,12 @@ function executeGsapMutationAcorn(body, block, respond2) {
102269
102508
  if (body.fromProperties && body.method !== "fromTo") {
102270
102509
  return respond2({ error: "fromProperties is only valid for method=fromTo" }, 400);
102271
102510
  }
102511
+ if (Object.keys(body.properties).some((key2) => {
102512
+ const group = classifyPropertyGroup3(key2);
102513
+ return group === "position" || group === "rotation";
102514
+ })) {
102515
+ stripStudioEditsFromTarget(block.document, body.targetSelector);
102516
+ }
102272
102517
  const result = addAnimationToScript(block.scriptText, {
102273
102518
  targetSelector: body.targetSelector,
102274
102519
  method: body.method,
@@ -102406,10 +102651,38 @@ function executeGsapMutationAcorn(body, block, respond2) {
102406
102651
  ...body.cp2 ? { cp2: body.cp2 } : {}
102407
102652
  });
102408
102653
  }
102654
+ case "update-motion-path-point": {
102655
+ return updateMotionPathPointInScript(block.scriptText, body.animationId, body.pointIndex, {
102656
+ x: body.x,
102657
+ y: body.y
102658
+ });
102659
+ }
102660
+ case "add-motion-path-point": {
102661
+ return addMotionPathPointInScript(block.scriptText, body.animationId, body.index, {
102662
+ x: body.x,
102663
+ y: body.y
102664
+ });
102665
+ }
102666
+ case "remove-motion-path-point": {
102667
+ return removeMotionPathPointInScript(block.scriptText, body.animationId, body.index);
102668
+ }
102669
+ case "add-motion-path": {
102670
+ return addMotionPathToScript(
102671
+ block.scriptText,
102672
+ body.targetSelector,
102673
+ body.position,
102674
+ body.duration,
102675
+ { x: body.x, y: body.y },
102676
+ body.ease
102677
+ ).script;
102678
+ }
102409
102679
  case "remove-arc-path": {
102410
102680
  return removeArcPathFromScript(block.scriptText, body.animationId);
102411
102681
  }
102412
102682
  case "add-with-keyframes": {
102683
+ if (keyframesWritePosition(body.keyframes) || keyframesWriteRotation(body.keyframes)) {
102684
+ stripStudioEditsFromTarget(block.document, body.targetSelector);
102685
+ }
102413
102686
  const result = addAnimationWithKeyframesToScript(
102414
102687
  block.scriptText,
102415
102688
  body.targetSelector,
@@ -102422,6 +102695,9 @@ function executeGsapMutationAcorn(body, block, respond2) {
102422
102695
  return result.script;
102423
102696
  }
102424
102697
  case "replace-with-keyframes": {
102698
+ if (keyframesWritePosition(body.keyframes) || keyframesWriteRotation(body.keyframes)) {
102699
+ stripStudioEditsFromTarget(block.document, body.targetSelector);
102700
+ }
102425
102701
  const script = removeAnimationFromScript2(block.scriptText, body.animationId);
102426
102702
  const added = addAnimationWithKeyframesToScript(
102427
102703
  script,
@@ -102505,10 +102781,10 @@ async function executeGsapMutationRecast(body, block, respond2) {
102505
102781
  unrollDynamicAnimations: unrollDynamicAnimations22,
102506
102782
  setArcPathInScript: setArcPathInScript22,
102507
102783
  updateArcSegmentInScript: updateArcSegmentInScript22,
102508
- updateMotionPathPointInScript: updateMotionPathPointInScript2,
102509
- addMotionPathPointInScript: addMotionPathPointInScript2,
102510
- removeMotionPathPointInScript: removeMotionPathPointInScript2,
102511
- addMotionPathToScript: addMotionPathToScript2,
102784
+ updateMotionPathPointInScript: updateMotionPathPointInScript22,
102785
+ addMotionPathPointInScript: addMotionPathPointInScript22,
102786
+ removeMotionPathPointInScript: removeMotionPathPointInScript22,
102787
+ addMotionPathToScript: addMotionPathToScript22,
102512
102788
  removeArcPathFromScript: removeArcPathFromScript22,
102513
102789
  addAnimationWithKeyframesToScript: addAnimationWithKeyframesToScript22,
102514
102790
  splitAnimationsInScript: splitAnimationsInScript22,
@@ -102705,22 +102981,22 @@ async function executeGsapMutationRecast(body, block, respond2) {
102705
102981
  });
102706
102982
  }
102707
102983
  case "update-motion-path-point": {
102708
- return updateMotionPathPointInScript2(block.scriptText, body.animationId, body.pointIndex, {
102984
+ return updateMotionPathPointInScript22(block.scriptText, body.animationId, body.pointIndex, {
102709
102985
  x: body.x,
102710
102986
  y: body.y
102711
102987
  });
102712
102988
  }
102713
102989
  case "add-motion-path-point": {
102714
- return addMotionPathPointInScript2(block.scriptText, body.animationId, body.index, {
102990
+ return addMotionPathPointInScript22(block.scriptText, body.animationId, body.index, {
102715
102991
  x: body.x,
102716
102992
  y: body.y
102717
102993
  });
102718
102994
  }
102719
102995
  case "remove-motion-path-point": {
102720
- return removeMotionPathPointInScript2(block.scriptText, body.animationId, body.index);
102996
+ return removeMotionPathPointInScript22(block.scriptText, body.animationId, body.index);
102721
102997
  }
102722
102998
  case "add-motion-path": {
102723
- const result = addMotionPathToScript2(
102999
+ const result = addMotionPathToScript22(
102724
103000
  block.scriptText,
102725
103001
  body.targetSelector,
102726
103002
  body.position,
@@ -102743,7 +103019,8 @@ async function executeGsapMutationRecast(body, block, respond2) {
102743
103019
  body.position,
102744
103020
  body.duration,
102745
103021
  body.keyframes,
102746
- body.ease
103022
+ body.ease,
103023
+ body.easeEach
102747
103024
  );
102748
103025
  return result.script;
102749
103026
  }
@@ -102820,7 +103097,7 @@ async function executeGsapMutationRecast(body, block, respond2) {
102820
103097
  return respond2({ error: `unknown mutation type: ${body.type}` }, 400);
102821
103098
  }
102822
103099
  }
102823
- async function foldAtomicCutFile(c3, file, absPath, before3) {
103100
+ async function foldAtomicCutFile(c3, file, absPath, before3, writer) {
102824
103101
  let after2 = before3;
102825
103102
  let splitCount = 0;
102826
103103
  const skippedSelectors = /* @__PURE__ */ new Set();
@@ -102866,7 +103143,8 @@ async function foldAtomicCutFile(c3, file, absPath, before3) {
102866
103143
  elementDuration: cut.elementDuration
102867
103144
  },
102868
103145
  block,
102869
- respond2
103146
+ respond2,
103147
+ writer
102870
103148
  );
102871
103149
  if (result instanceof Response) return result;
102872
103150
  let script = typeof result === "string" ? result : result.script;
@@ -102874,8 +103152,7 @@ async function foldAtomicCutFile(c3, file, absPath, before3) {
102874
103152
  for (const selector of result.skippedSelectors) skippedSelectors.add(selector);
102875
103153
  }
102876
103154
  if (script !== block.scriptText) {
102877
- const parser = await loadGsapParser();
102878
- script = parser.syncPositionHoldsBeforeKeyframes(script);
103155
+ script = writer === "acorn" ? syncPositionHoldsBeforeKeyframes(script) : (await loadGsapParser()).syncPositionHoldsBeforeKeyframes(script);
102879
103156
  after2 = block.replaceScript(script);
102880
103157
  }
102881
103158
  }
@@ -103165,6 +103442,14 @@ function registerFileRoutes(api, adapter2) {
103165
103442
  const files = body.files;
103166
103443
  const project = await adapter2.resolveProject(c3.req.param("id"));
103167
103444
  if (!project) return c3.json({ error: "not found" }, 404);
103445
+ let writer;
103446
+ try {
103447
+ writer = resolveGsapWriter({
103448
+ HYPERFRAMES_GSAP_WRITER: process.env["HYPERFRAMES_GSAP_WRITER"]
103449
+ });
103450
+ } catch (error) {
103451
+ return c3.json({ error: error instanceof Error ? error.message : String(error) }, 400);
103452
+ }
103168
103453
  return serializeAtomicCut(async () => {
103169
103454
  const seen = /* @__PURE__ */ new Set();
103170
103455
  const prepared = [];
@@ -103193,7 +103478,7 @@ function registerFileRoutes(api, adapter2) {
103193
103478
  }
103194
103479
  let folded;
103195
103480
  try {
103196
- folded = await foldAtomicCutFile(c3, file, absPath, before3);
103481
+ folded = await foldAtomicCutFile(c3, file, absPath, before3, writer);
103197
103482
  } catch (error) {
103198
103483
  const message = error instanceof Error ? error.message : "Cut transform failed";
103199
103484
  return c3.json({ error: message }, 400);
@@ -105116,7 +105401,7 @@ function updateBackgroundRemovalProgress(state, event) {
105116
105401
  state.framesProcessed = event.index;
105117
105402
  state.avgMsPerFrame = event.avgMsPerFrame;
105118
105403
  }
105119
- var IGNORE_DIRS, SIGNATURE_TEXT_EXTENSIONS, SIGNATURE_EXCLUDED_DIRS, MAX_SIGNATURE_TEXT_BYTES, STUDIO_SIGNATURE_MANIFEST_PATHS, projectSignatureCache, COMPOSITION_ID_RE, MIME_TYPES2, SAMPLE_RATE, PEAK_COUNT, WAVEFORM_CACHE_VERSION, VIDEO_EXT2, AUDIO_EXT2, DEFAULT_KEEP_PER_FILE, RECEIPT_TTL_MS, receipts, CompositionInsertionError, atomicCutTail, HOLD_SYNC_MUTATION_TYPES, REGEXP_SPECIALS, NON_RENDERED_TAGS, VARIABLES_PAYLOAD_ERROR, PROJECT_SIGNATURE_META, GSAP_CDN_VERSION, GSAP_CDN_SCRIPT, GSAP_CUSTOM_EASE_CDN_SCRIPT, GSAP_MOTION_PATH_CDN_SCRIPT, GSAP_CDN_FALLBACK_SCRIPT, VALID_RESOLUTIONS, THUMBNAIL_CACHE_VERSION, MAX_FONT_RESULTS, GOOGLE_FONTS_METADATA_URL, GOOGLE_FONTS_FETCH_TIMEOUT_MS, cachedFonts, cachedGoogleFonts, GOOGLE_FONT_FALLBACKS, VIDEO_EXTENSIONS2, IMAGE_EXTENSIONS, VIDEO_OUTPUT_EXTENSIONS, QUALITIES, DEVICES;
105404
+ var IGNORE_DIRS, SIGNATURE_TEXT_EXTENSIONS, SIGNATURE_EXCLUDED_DIRS, MAX_SIGNATURE_TEXT_BYTES, STUDIO_SIGNATURE_MANIFEST_PATHS, projectSignatureCache, COMPOSITION_ID_RE, MIME_TYPES2, SAMPLE_RATE, PEAK_COUNT, WAVEFORM_CACHE_VERSION, VIDEO_EXT2, AUDIO_EXT2, DEFAULT_KEEP_PER_FILE, RECEIPT_TTL_MS, receipts, CompositionInsertionError, differential, behavioral, GSAP_MUTATION_CAPABILITIES, GSAP_WRITER_MIGRATION, atomicCutTail, HOLD_SYNC_MUTATION_TYPES, REGEXP_SPECIALS, NON_RENDERED_TAGS, VARIABLES_PAYLOAD_ERROR, PROJECT_SIGNATURE_META, GSAP_CDN_VERSION, GSAP_CDN_SCRIPT, GSAP_CUSTOM_EASE_CDN_SCRIPT, GSAP_MOTION_PATH_CDN_SCRIPT, GSAP_CDN_FALLBACK_SCRIPT, VALID_RESOLUTIONS, THUMBNAIL_CACHE_VERSION, MAX_FONT_RESULTS, GOOGLE_FONTS_METADATA_URL, GOOGLE_FONTS_FETCH_TIMEOUT_MS, cachedFonts, cachedGoogleFonts, GOOGLE_FONT_FALLBACKS, VIDEO_EXTENSIONS2, IMAGE_EXTENSIONS, VIDEO_OUTPUT_EXTENSIONS, QUALITIES, DEVICES;
105120
105405
  var init_dist9 = __esm({
105121
105406
  "../studio-server/dist/index.js"() {
105122
105407
  "use strict";
@@ -105231,6 +105516,61 @@ var init_dist9 = __esm({
105231
105516
  }
105232
105517
  status;
105233
105518
  };
105519
+ differential = (family) => ({
105520
+ family,
105521
+ acorn: "supported",
105522
+ recast: "supported",
105523
+ parity: "differential"
105524
+ });
105525
+ behavioral = (family) => ({
105526
+ family,
105527
+ acorn: "supported",
105528
+ recast: "supported",
105529
+ parity: "behavioral"
105530
+ });
105531
+ GSAP_MUTATION_CAPABILITIES = {
105532
+ "update-property": differential("animation"),
105533
+ "update-properties": differential("animation"),
105534
+ "update-from-property": differential("animation"),
105535
+ "update-meta": differential("animation"),
105536
+ add: differential("animation"),
105537
+ delete: differential("animation"),
105538
+ "add-property": differential("animation"),
105539
+ "add-from-property": differential("animation"),
105540
+ "remove-property": differential("animation"),
105541
+ "remove-from-property": differential("animation"),
105542
+ "add-keyframe": differential("keyframe"),
105543
+ "remove-keyframe": differential("keyframe"),
105544
+ "move-keyframe": behavioral("keyframe"),
105545
+ "resize-keyframed-tween": behavioral("keyframe"),
105546
+ "update-keyframe": differential("keyframe"),
105547
+ "convert-to-keyframes": behavioral("keyframe"),
105548
+ "remove-all-keyframes": behavioral("keyframe"),
105549
+ "materialize-keyframes": behavioral("keyframe"),
105550
+ "set-arc-path": behavioral("motion_path"),
105551
+ "update-arc-segment": behavioral("motion_path"),
105552
+ "update-motion-path-point": differential("motion_path"),
105553
+ "add-motion-path-point": differential("motion_path"),
105554
+ "remove-motion-path-point": differential("motion_path"),
105555
+ "add-motion-path": differential("motion_path"),
105556
+ "remove-arc-path": behavioral("motion_path"),
105557
+ "add-with-keyframes": behavioral("keyframe"),
105558
+ "replace-with-keyframes": behavioral("keyframe"),
105559
+ "split-animations": behavioral("structure"),
105560
+ "split-into-property-groups": behavioral("structure"),
105561
+ "delete-all-for-selector": behavioral("structure"),
105562
+ "consolidate-position-writes": behavioral("structure"),
105563
+ "unroll-timeline": behavioral("structure"),
105564
+ "shift-positions": behavioral("timing"),
105565
+ "shift-positions-batch": behavioral("timing"),
105566
+ "scale-positions": behavioral("timing")
105567
+ };
105568
+ GSAP_WRITER_MIGRATION = Object.freeze({
105569
+ flag: "HYPERFRAMES_GSAP_WRITER",
105570
+ owner: "studio-foundations",
105571
+ deadline: "2026-09-30",
105572
+ graduationCriteria: "Every operation has differential parity, the Acorn path imports no Recast runtime, and canary divergence is zero for the agreed soak window."
105573
+ });
105234
105574
  atomicCutTail = Promise.resolve();
105235
105575
  HOLD_SYNC_MUTATION_TYPES = /* @__PURE__ */ new Set([
105236
105576
  "add-keyframe",
@@ -137674,13 +138014,13 @@ function timelineDuration(page) {
137674
138014
  return d3;
137675
138015
  };
137676
138016
  const animationDurationSeconds = (animation) => {
137677
- const timing = animation.effect?.getTiming?.();
137678
- if (!timing) return 0;
137679
- const durationMs = Number(timing.duration);
137680
- const iterations = Number(timing.iterations ?? 1);
138017
+ const timing2 = animation.effect?.getTiming?.();
138018
+ if (!timing2) return 0;
138019
+ const durationMs = Number(timing2.duration);
138020
+ const iterations = Number(timing2.iterations ?? 1);
137681
138021
  if (!Number.isFinite(durationMs) || !Number.isFinite(iterations)) return 0;
137682
- const delayMs = Number(timing.delay ?? 0);
137683
- const endDelayMs = Number(timing.endDelay ?? 0);
138022
+ const delayMs = Number(timing2.delay ?? 0);
138023
+ const endDelayMs = Number(timing2.endDelay ?? 0);
137684
138024
  return finiteMsToSeconds(Math.max(0, delayMs) + durationMs * iterations + endDelayMs);
137685
138025
  };
137686
138026
  const waapiDuration = () => {
@@ -138332,9 +138672,9 @@ function fmtProps(props) {
138332
138672
  return Object.entries(props).filter(([k2]) => k2 !== "ease").map(([k2, v2]) => `${k2}:${v2}`).join(" ");
138333
138673
  }
138334
138674
  function printTween(t2) {
138335
- const timing = c.dim(`@${t2.start}s\u2192${t2.end}s (${t2.duration}s)`);
138675
+ const timing2 = c.dim(`@${t2.start}s\u2192${t2.end}s (${t2.duration}s)`);
138336
138676
  const group = t2.group ? c.dim(` ${t2.group}`) : "";
138337
- console.log(` ${c.accent(t2.target)}${group} ${c.dim(t2.method)}/${t2.shape} ${timing}`);
138677
+ console.log(` ${c.accent(t2.target)}${group} ${c.dim(t2.method)}/${t2.shape} ${timing2}`);
138338
138678
  if (t2.shape === "motionPath") {
138339
138679
  console.log(c.dim(` motionPath arc (${t2.keyframes.length} stops)`));
138340
138680
  } else {