@hyperframes/parsers 0.7.15 → 0.7.17
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/assets.d.ts +69 -0
- package/dist/assets.js +74 -0
- package/dist/assets.js.map +1 -0
- package/dist/composition.d.ts +96 -0
- package/dist/composition.js +207 -0
- package/dist/composition.js.map +1 -0
- package/dist/gsapParser.d.ts +3 -2
- package/dist/gsapParser.js +76 -25
- package/dist/gsapParser.js.map +1 -1
- package/dist/gsapParserAcorn.d.ts +3 -2
- package/dist/gsapParserAcorn.js +67 -27
- package/dist/gsapParserAcorn.js.map +1 -1
- package/dist/gsapParserExports.d.ts +2 -1
- package/dist/gsapParserExports.js +60 -22
- package/dist/gsapParserExports.js.map +1 -1
- package/dist/gsapSerialize-Bei7m7M7.d.ts +166 -0
- package/dist/gsapWriterAcorn.d.ts +2 -1
- package/dist/gsapWriterAcorn.js +70 -26
- package/dist/gsapWriterAcorn.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +186 -25
- package/dist/index.js.map +1 -1
- package/dist/slideshow.d.ts +92 -0
- package/dist/slideshow.js +149 -0
- package/dist/slideshow.js.map +1 -0
- package/dist/{gsapSerialize-B_JRTCeV.d.ts → types-Cg0ZTXEf.d.ts} +1 -165
- package/package.json +15 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/gsapParserAcorn.ts","../src/gsapConstants.ts","../src/gsapSerialize.ts","../src/gsapInline.ts"],"sourcesContent":["// fallow-ignore-file code-duplication\n/**\n * Browser-safe GSAP read path — acorn + acorn-walk.\n *\n * T6b oracle: produces identical ParsedGsap output to gsapParser.ts (recast).\n * Replaces recast as the shared implementation once T6d passes.\n *\n * Write path (T6c) will add magic-string splice once read parity is confirmed.\n * No Node globals, no fs, no require — safe to bundle for browser use.\n */\nimport * as acorn from \"acorn\";\nimport * as acornWalk from \"acorn-walk\";\nimport type {\n ArcPathConfig,\n GsapAnimation,\n GsapKeyframesData,\n GsapMethod,\n GsapPercentageKeyframe,\n ParsedGsap,\n} from \"./gsapSerialize.js\";\nimport { classifyTweenPropertyGroup } from \"./gsapConstants.js\";\nimport { buildArcPath } from \"./gsapSerialize.js\";\nimport { inlineComputedTimelines, readProvenance } from \"./gsapInline.js\";\n\n// Browser-safe re-exports so studio code can build arc config without importing\n// the recast parser (this acorn module is the browser-safe gsap subpath).\nexport { buildArcPath, editabilityForProvenance } from \"./gsapSerialize.js\";\nexport type {\n ArcPathConfig,\n ArcPathSegment,\n MotionPathShape,\n GsapProvenance,\n GsapProvenanceKind,\n KeyframeEditability,\n} from \"./gsapSerialize.js\";\n\nconst GSAP_METHODS = new Set<string>([\"set\", \"to\", \"from\", \"fromTo\"]);\nconst QUERY_METHODS = new Set([\"querySelector\", \"querySelectorAll\"]);\nconst ITERATION_METHODS = new Set([\"forEach\", \"map\"]);\nconst SCOPE_NODE_TYPES = new Set([\n \"Program\",\n \"FunctionDeclaration\",\n \"FunctionExpression\",\n \"ArrowFunctionExpression\",\n]);\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\ntype ScopeBindings = ReadonlyMap<string, number | string | boolean>;\n/** Per-scope element bindings: scopeNode → (variable name → selector). */\ntype TargetBindings = Map<any, Map<string, string>>;\n\n// ── Value resolution ─────────────────────────────────────────────────────────\n\n// fallow-ignore-next-line complexity\nfunction resolveNode(\n node: any,\n scope: ReadonlyMap<string, number | string | boolean>,\n): number | string | boolean | undefined {\n if (!node) return undefined;\n if (node.type === \"NumericLiteral\" || (node.type === \"Literal\" && typeof node.value === \"number\"))\n return node.value;\n if (node.type === \"StringLiteral\" || (node.type === \"Literal\" && typeof node.value === \"string\"))\n return node.value;\n if (\n node.type === \"BooleanLiteral\" ||\n (node.type === \"Literal\" && typeof node.value === \"boolean\")\n )\n return node.value;\n if (node.type === \"UnaryExpression\" && node.operator === \"-\" && node.argument) {\n const val = resolveNode(node.argument, scope);\n return typeof val === \"number\" ? -val : undefined;\n }\n if (node.type === \"BinaryExpression\") {\n const left = resolveNode(node.left, scope);\n const right = resolveNode(node.right, scope);\n if (typeof left === \"number\" && typeof right === \"number\") {\n switch (node.operator) {\n case \"+\":\n return left + right;\n case \"-\":\n return left - right;\n case \"*\":\n return left * right;\n case \"/\":\n return right !== 0 ? left / right : undefined;\n }\n }\n if (typeof left === \"string\" && node.operator === \"+\") return left + String(right ?? \"\");\n if (typeof right === \"string\" && node.operator === \"+\") return String(left ?? \"\") + right;\n }\n if (node.type === \"Identifier\" && scope.has(node.name)) {\n return scope.get(node.name);\n }\n if (node.type === \"TemplateLiteral\" && node.expressions?.length === 0) {\n return node.quasis?.[0]?.value?.cooked ?? undefined;\n }\n return undefined;\n}\n\nfunction extractLiteralValue(node: any, scope: ScopeBindings): unknown {\n return resolveNode(node, scope);\n}\n\n// ── DOM selector resolution ───────────────────────────────────────────────────\n\n// fallow-ignore-next-line complexity\nfunction selectorFromQueryCall(node: any, scope: ScopeBindings): string | null {\n if (node?.type !== \"CallExpression\") return null;\n const callee = node.callee;\n if (callee?.type !== \"MemberExpression\" || callee.property?.type !== \"Identifier\") return null;\n const method = callee.property.name;\n const argValue = resolveNode(node.arguments?.[0], scope);\n if (typeof argValue !== \"string\" || argValue.length === 0) return null;\n if (QUERY_METHODS.has(method) || method === \"toArray\") return argValue;\n if (method === \"getElementById\") return `#${argValue}`;\n return null;\n}\n\n// ── Ancestor-based scope helpers (replaces NodePath walking) ──────────────────\n\n/**\n * Return the nearest ancestor node whose type is in SCOPE_NODE_TYPES.\n * `ancestors` is the acorn-walk ancestor array (root→current, current is last).\n */\nfunction enclosingScopeNodeFromAncestors(ancestors: any[]): any {\n for (let i = ancestors.length - 2; i >= 0; i--) {\n const node = ancestors[i];\n if (node && SCOPE_NODE_TYPES.has(node.type)) return node;\n }\n return null;\n}\n\n/** Scope chain innermost-first, derived from the acorn-walk ancestors array. */\nfunction scopeChainFromAncestors(ancestors: any[]): any[] {\n const chain: any[] = [];\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const node = ancestors[i];\n if (node && SCOPE_NODE_TYPES.has(node.type)) chain.push(node);\n }\n return chain;\n}\n\n// ── Target bindings ───────────────────────────────────────────────────────────\n\nfunction addBinding(\n bindings: TargetBindings,\n scopeNode: any,\n name: string,\n selector: string,\n): void {\n let scoped = bindings.get(scopeNode);\n if (!scoped) {\n scoped = new Map();\n bindings.set(scopeNode, scoped);\n }\n if (!scoped.has(name)) scoped.set(name, selector);\n}\n\nfunction lookupBindingFromAncestors(\n name: string,\n ancestors: any[],\n bindings: TargetBindings,\n): string | null {\n for (const scopeNode of scopeChainFromAncestors(ancestors)) {\n const selector = bindings.get(scopeNode)?.get(name);\n if (selector !== undefined) return selector;\n }\n // Program-scope bindings are stored under null (enclosingScopeNodeFromAncestors\n // returns null when no function wrapper exists — the common case in HF scripts).\n return bindings.get(null)?.get(name) ?? null;\n}\n\nfunction isFunctionNode(node: any): boolean {\n return (\n node?.type === \"ArrowFunctionExpression\" ||\n node?.type === \"FunctionExpression\" ||\n node?.type === \"FunctionDeclaration\"\n );\n}\n\nfunction resolveCollectionSelector(\n node: any,\n ancestors: any[],\n scope: ScopeBindings,\n bindings: TargetBindings,\n): string | null {\n if (node?.type === \"Identifier\")\n return lookupBindingFromAncestors(node.name, ancestors, bindings);\n if (node?.type === \"CallExpression\") return selectorFromQueryCall(node, scope);\n return null;\n}\n\nfunction collectScopeBindings(ast: any): ScopeBindings {\n const bindings = new Map<string, number | string | boolean>();\n acornWalk.simple(ast, {\n VariableDeclarator(node: any) {\n const name = node.id?.name;\n const init = node.init;\n if (name && init) {\n const val = resolveNode(init, bindings);\n if (val !== undefined) bindings.set(name, val);\n }\n },\n });\n return bindings;\n}\n\n/**\n * Build a lexically-scoped index of element variables → selector.\n * Pass 1: direct DOM-lookup assignments.\n * Pass 2: forEach/map callback params whose collection's selector is known.\n */\nfunction collectTargetBindings(ast: any, scope: ScopeBindings): TargetBindings {\n const bindings: TargetBindings = new Map();\n\n acornWalk.ancestor(ast, {\n VariableDeclarator(node: any, _: unknown, ancestors: any[]) {\n const name = node.id?.name;\n const selector = selectorFromQueryCall(node.init, scope);\n if (name && selector !== null) {\n addBinding(bindings, enclosingScopeNodeFromAncestors(ancestors), name, selector);\n }\n },\n AssignmentExpression(node: any, _: unknown, ancestors: any[]) {\n const left = node.left;\n const selector = selectorFromQueryCall(node.right, scope);\n if (left?.type === \"Identifier\" && selector !== null) {\n addBinding(bindings, enclosingScopeNodeFromAncestors(ancestors), left.name, selector);\n }\n },\n } as any);\n\n // Pass 2: forEach/map callback params take the collection's selector.\n acornWalk.ancestor(ast, {\n // fallow-ignore-next-line complexity\n CallExpression(node: any, _: unknown, ancestors: any[]) {\n const callee = node.callee;\n if (\n callee?.type === \"MemberExpression\" &&\n callee.property?.type === \"Identifier\" &&\n ITERATION_METHODS.has(callee.property.name)\n ) {\n const collectionSelector = resolveCollectionSelector(\n callee.object,\n ancestors,\n scope,\n bindings,\n );\n const fn = node.arguments?.[0];\n const param = fn?.params?.[0];\n if (collectionSelector && param?.type === \"Identifier\" && isFunctionNode(fn)) {\n addBinding(bindings, fn, param.name, collectionSelector);\n }\n }\n },\n } as any);\n\n return bindings;\n}\n\n// fallow-ignore-next-line complexity\nfunction resolveTargetSelector(\n node: any,\n ancestors: any[],\n scope: ScopeBindings,\n bindings: TargetBindings,\n): string | null {\n if (!node) return null;\n if (node.type === \"StringLiteral\" || node.type === \"Literal\") {\n return typeof node.value === \"string\" ? node.value : null;\n }\n if (node.type === \"Identifier\") {\n return lookupBindingFromAncestors(node.name, ancestors, bindings);\n }\n if (node.type === \"CallExpression\") {\n return selectorFromQueryCall(node, scope);\n }\n if (node.type === \"ArrayExpression\") {\n const parts = node.elements\n .map((el: any) => resolveTargetSelector(el, ancestors, scope, bindings))\n .filter((s: string | null): s is string => typeof s === \"string\" && s.length > 0);\n return parts.length > 0 ? parts.join(\", \") : null;\n }\n if (node.type === \"MemberExpression\" && node.object?.type === \"Identifier\") {\n return lookupBindingFromAncestors(node.object.name, ancestors, bindings);\n }\n return null;\n}\n\n// ── ObjectExpression utilities ────────────────────────────────────────────────\n\nfunction isObjectProperty(prop: any): boolean {\n return prop?.type === \"ObjectProperty\" || prop?.type === \"Property\";\n}\n\nfunction propKeyName(prop: any): string | undefined {\n return prop?.key?.name ?? prop?.key?.value;\n}\n\nfunction findPropertyNode(varsArgNode: any, key: string): any | undefined {\n if (varsArgNode?.type !== \"ObjectExpression\") return undefined;\n for (const prop of varsArgNode.properties ?? []) {\n if (!isObjectProperty(prop)) continue;\n if (propKeyName(prop) === key) return prop.value;\n }\n return undefined;\n}\n\n/**\n * Extract raw source text for a property value — the offset-splice primitive.\n * Equivalent to `recast.print(node).code` for unmodified nodes.\n */\nfunction extractRawPropertySource(\n varsArgNode: any,\n key: string,\n source: string,\n): string | undefined {\n const node = findPropertyNode(varsArgNode, key);\n return node ? source.slice(node.start, node.end) : undefined;\n}\n\n// fallow-ignore-next-line complexity\nfunction objectExpressionToRecord(\n node: any,\n scope: ScopeBindings,\n source: string,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n if (node?.type !== \"ObjectExpression\") return result;\n for (const prop of node.properties ?? []) {\n if (!isObjectProperty(prop)) continue;\n const key = prop.key?.name ?? prop.key?.value;\n if (!key) continue;\n const resolved = resolveNode(prop.value, scope);\n if (resolved !== undefined) {\n result[key] = resolved;\n } else {\n result[key] = `__raw:${source.slice(prop.value.start, prop.value.end)}`;\n }\n }\n return result;\n}\n\n// ── Timeline detection ────────────────────────────────────────────────────────\n\nfunction isGsapTimelineCall(node: any): boolean {\n return (\n node?.type === \"CallExpression\" &&\n node.callee?.type === \"MemberExpression\" &&\n node.callee.object?.name === \"gsap\" &&\n node.callee.property?.name === \"timeline\"\n );\n}\n\ninterface TimelineDefaults {\n ease?: string;\n duration?: number;\n}\n\ninterface TimelineDetection {\n timelineVar: string | null;\n timelineCount: number;\n defaults?: TimelineDefaults;\n}\n\n// fallow-ignore-next-line complexity\nfunction extractTimelineDefaults(\n callNode: any,\n scope: ScopeBindings,\n): TimelineDefaults | undefined {\n const arg = callNode.arguments?.[0];\n if (!arg || arg.type !== \"ObjectExpression\") return undefined;\n const defaultsProp = arg.properties?.find(\n (p: any) => isObjectProperty(p) && propKeyName(p) === \"defaults\",\n );\n if (!defaultsProp?.value || defaultsProp.value.type !== \"ObjectExpression\") return undefined;\n const result: TimelineDefaults = {};\n for (const prop of defaultsProp.value.properties ?? []) {\n if (!isObjectProperty(prop)) continue;\n const key = propKeyName(prop);\n const val = resolveNode(prop.value, scope);\n if (key === \"ease\" && typeof val === \"string\") result.ease = val;\n if (key === \"duration\" && typeof val === \"number\") result.duration = val;\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\nfunction findTimelineVar(ast: any, scope?: ScopeBindings): TimelineDetection {\n let timelineVar: string | null = null;\n let timelineCount = 0;\n let defaults: TimelineDefaults | undefined;\n const emptyScope: ScopeBindings = scope ?? new Map();\n\n acornWalk.simple(ast, {\n VariableDeclarator(node: any) {\n if (isGsapTimelineCall(node.init)) {\n timelineCount += 1;\n if (!timelineVar) {\n timelineVar = node.id?.name ?? null;\n defaults = extractTimelineDefaults(node.init, emptyScope);\n }\n }\n },\n AssignmentExpression(node: any) {\n if (isGsapTimelineCall(node.right)) {\n timelineCount += 1;\n if (!timelineVar) {\n const left = node.left;\n if (left?.type === \"Identifier\") timelineVar = left.name;\n defaults = extractTimelineDefaults(node.right, emptyScope);\n }\n }\n },\n });\n\n return { timelineVar, timelineCount, defaults };\n}\n\n// ── Tween call collection ─────────────────────────────────────────────────────\n\n/** Keys stored on dedicated GsapAnimation fields (not in properties/extras). */\nconst BUILTIN_VAR_KEYS = new Set([\"duration\", \"ease\", \"delay\"]);\n/** Keys never preserved (callbacks / advanced patterns). */\nconst DROPPED_VAR_KEYS = new Set([\"onComplete\", \"onStart\", \"onUpdate\", \"onRepeat\"]);\n/** Keys that go in `extras` — non-editable GSAP config that must survive round-trips. */\nconst EXTRAS_KEYS = new Set([\n \"stagger\",\n \"yoyo\",\n \"repeat\",\n \"repeatDelay\",\n \"snap\",\n \"overwrite\",\n \"immediateRender\",\n]);\n\nexport interface TweenCallInfo {\n node: any;\n /** acorn-walk ancestor array at the call site (root→call, call is last). */\n ancestors: any[];\n method: GsapMethod;\n selector: string;\n varsArg: any;\n fromArg?: any;\n positionArg?: any;\n /** True for a base `gsap.set(...)` (off-timeline) rather than `tl.set(...)`. */\n global?: boolean;\n}\n\n/** True when callee chain is rooted at the timeline variable. */\nfunction isTimelineRootedCall(callNode: any, timelineVar: string): boolean {\n let obj = callNode.callee?.object;\n while (obj?.type === \"CallExpression\") {\n obj = obj.callee?.object;\n }\n return obj?.type === \"Identifier\" && obj.name === timelineVar;\n}\n\n/**\n * Pre-order recursive walk for tween collection.\n *\n * acorn-walk is POST-order (visitor fires after children), which reverses\n * chained calls vs recast.types.visit (PRE-order). We need pre-order to\n * match the golden ordering where the outermost chained call appears first.\n */\nfunction findAllTweenCalls(\n ast: any,\n timelineVar: string,\n scope: ScopeBindings,\n targetBindings: TargetBindings,\n): TweenCallInfo[] {\n const results: TweenCallInfo[] = [];\n\n // fallow-ignore-next-line complexity\n function visit(node: any, ancestors: readonly any[]): void {\n if (!node || typeof node !== \"object\") return;\n const nodeAncestors = [...ancestors, node];\n\n // Fire BEFORE children (pre-order) so chained outer calls come first.\n if (node.type === \"CallExpression\") {\n const callee = node.callee;\n // A base `gsap.set(\"#sel\", props)` is an off-timeline static hold — parse it as\n // an editable global `set` so a static value round-trips and re-edits in place.\n // STRING-LITERAL selectors only: variable-target holds stay surrounding source.\n const gsapSetArg = node.arguments?.[0];\n const isGlobalSet =\n callee?.type === \"MemberExpression\" &&\n callee.object?.type === \"Identifier\" &&\n callee.object.name === \"gsap\" &&\n callee.property?.type === \"Identifier\" &&\n callee.property.name === \"set\" &&\n (gsapSetArg?.type === \"StringLiteral\" ||\n (gsapSetArg?.type === \"Literal\" && typeof gsapSetArg.value === \"string\"));\n if (\n callee?.type === \"MemberExpression\" &&\n callee.property?.type === \"Identifier\" &&\n (isTimelineRootedCall(node, timelineVar) || isGlobalSet) &&\n GSAP_METHODS.has(callee.property.name)\n ) {\n const method = callee.property.name;\n const args = node.arguments;\n const selectorValue =\n args.length >= 1\n ? (resolveTargetSelector(args[0], nodeAncestors, scope, targetBindings) ??\n \"__unresolved__\")\n : \"__unresolved__\";\n\n if (method === \"fromTo\" && args.length >= 3) {\n results.push({\n node,\n ancestors: nodeAncestors,\n method: \"fromTo\",\n selector: selectorValue,\n fromArg: args[1],\n varsArg: args[2],\n positionArg: args[3],\n });\n } else if (method !== \"fromTo\" && args.length >= 2) {\n results.push({\n node,\n ancestors: nodeAncestors,\n method: method as GsapMethod,\n selector: selectorValue,\n varsArg: args[1],\n positionArg: args[2],\n ...(isGlobalSet ? { global: true } : {}),\n });\n }\n }\n }\n\n // Traverse children. Object.keys preserves insertion order, so callee\n // comes before arguments in acorn's CallExpression nodes.\n for (const key of Object.keys(node)) {\n if (key === \"type\" || key === \"start\" || key === \"end\" || key === \"loc\") continue;\n const child = (node as any)[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === \"object\" && item.type) visit(item, nodeAncestors);\n }\n } else if (child && typeof child === \"object\" && (child as any).type) {\n visit(child, nodeAncestors);\n }\n }\n }\n\n visit(ast, []);\n return results;\n}\n\n// ── Keyframes parsing ─────────────────────────────────────────────────────────\n\nconst PERCENTAGE_KEY_RE = /^(\\d+(?:\\.\\d+)?)%$/;\n\nfunction tryResolveStringProp(propValue: any, scope: ScopeBindings): string | undefined {\n const val = resolveNode(propValue, scope);\n return typeof val === \"string\" ? val : undefined;\n}\n\n// fallow-ignore-next-line complexity\nfunction parsePercentageKeyframes(\n node: any,\n scope: ScopeBindings,\n source: string,\n): GsapKeyframesData {\n const keyframes: GsapPercentageKeyframe[] = [];\n let ease: string | undefined;\n let easeEach: string | undefined;\n\n for (const prop of node.properties ?? []) {\n if (prop.type !== \"ObjectProperty\" && prop.type !== \"Property\") continue;\n const key = prop.key?.value ?? prop.key?.name;\n if (typeof key !== \"string\") continue;\n\n const pctMatch = PERCENTAGE_KEY_RE.exec(key);\n if (pctMatch) {\n const percentage = Number.parseFloat(pctMatch[1] ?? \"0\");\n const record = objectExpressionToRecord(prop.value, scope, source);\n const properties: Record<string, number | string> = {};\n let kfEase: string | undefined;\n for (const [k, v] of Object.entries(record)) {\n if (k === \"ease\" && typeof v === \"string\") {\n kfEase = v;\n } else if (typeof v === \"number\" || typeof v === \"string\") {\n properties[k] = v;\n }\n }\n keyframes.push({ percentage, properties, ...(kfEase ? { ease: kfEase } : {}) });\n } else if (key === \"ease\") {\n ease = tryResolveStringProp(prop.value, scope) ?? ease;\n } else if (key === \"easeEach\") {\n easeEach = tryResolveStringProp(prop.value, scope) ?? easeEach;\n }\n }\n\n keyframes.sort((a, b) => a.percentage - b.percentage);\n\n return {\n format: \"percentage\",\n keyframes,\n ...(ease ? { ease } : {}),\n ...(easeEach ? { easeEach } : {}),\n };\n}\n\n// fallow-ignore-next-line complexity\nfunction computeKeyframesTotalDuration(\n varsNode: any,\n scope: ScopeBindings,\n source: string,\n): number | undefined {\n const kfNode = (varsNode.properties ?? []).find(\n (p: any) => (p.key?.name ?? p.key?.value) === \"keyframes\",\n )?.value;\n if (!kfNode || kfNode.type !== \"ArrayExpression\") return undefined;\n let total = 0;\n for (const el of kfNode.elements ?? []) {\n if (!el || el.type !== \"ObjectExpression\") continue;\n const r = objectExpressionToRecord(el, scope, source);\n if (typeof r.duration === \"number\") total += r.duration;\n }\n return total > 0 ? total : undefined;\n}\n\n// fallow-ignore-next-line complexity\nfunction parseObjectArrayKeyframes(\n node: any,\n scope: ScopeBindings,\n source: string,\n): GsapKeyframesData {\n const elements = node.elements ?? [];\n const raw: Array<{\n properties: Record<string, number | string>;\n duration?: number;\n ease?: string;\n }> = [];\n\n for (const el of elements) {\n if (!el || el.type !== \"ObjectExpression\") continue;\n const record = objectExpressionToRecord(el, scope, source);\n const properties: Record<string, number | string> = {};\n let duration: number | undefined;\n let ease: string | undefined;\n for (const [k, v] of Object.entries(record)) {\n if (k === \"duration\" && typeof v === \"number\") {\n duration = v;\n } else if (k === \"ease\" && typeof v === \"string\") {\n ease = v;\n } else if (typeof v === \"number\" || typeof v === \"string\") {\n properties[k] = v;\n }\n }\n raw.push({ properties, duration, ease });\n }\n\n const totalDuration = raw.reduce((sum, r) => sum + (r.duration ?? 0), 0);\n const keyframes: GsapPercentageKeyframe[] = [];\n\n if (totalDuration > 0) {\n let cumulative = 0;\n for (const entry of raw) {\n cumulative += entry.duration ?? 0;\n const percentage = Math.round((cumulative / totalDuration) * 100);\n keyframes.push({\n percentage,\n properties: entry.properties,\n ...(entry.ease ? { ease: entry.ease } : {}),\n });\n }\n } else {\n for (let i = 0; i < raw.length; i++) {\n const entry = raw[i];\n if (!entry) continue;\n const percentage = raw.length > 1 ? Math.round((i / (raw.length - 1)) * 100) : 0;\n keyframes.push({\n percentage,\n properties: entry.properties,\n ...(entry.ease ? { ease: entry.ease } : {}),\n });\n }\n }\n\n return { format: \"object-array\", keyframes };\n}\n\n// fallow-ignore-next-line complexity\nfunction parseSimpleArrayKeyframes(node: any, scope: ScopeBindings): GsapKeyframesData {\n const arrayProps: Map<string, (number | string)[]> = new Map();\n let ease: string | undefined;\n let easeEach: string | undefined;\n\n for (const prop of node.properties ?? []) {\n if (prop.type !== \"ObjectProperty\" && prop.type !== \"Property\") continue;\n const key = prop.key?.name ?? prop.key?.value;\n if (typeof key !== \"string\") continue;\n\n if (prop.value?.type === \"ArrayExpression\") {\n const values: (number | string)[] = [];\n for (const el of prop.value.elements ?? []) {\n const val = resolveNode(el, scope);\n if (typeof val === \"number\" || typeof val === \"string\") {\n values.push(val);\n }\n }\n if (values.length > 0) arrayProps.set(key, values);\n } else if (key === \"ease\") {\n ease = tryResolveStringProp(prop.value, scope) ?? ease;\n } else if (key === \"easeEach\") {\n easeEach = tryResolveStringProp(prop.value, scope) ?? easeEach;\n }\n }\n\n const maxLen = Math.max(...[...arrayProps.values()].map((a) => a.length), 0);\n const keyframes: GsapPercentageKeyframe[] = [];\n\n for (let i = 0; i < maxLen; i++) {\n const percentage = maxLen > 1 ? Math.round((i / (maxLen - 1)) * 100) : 0;\n const properties: Record<string, number | string> = {};\n for (const [key, values] of arrayProps) {\n if (i < values.length) properties[key] = values[i] as number | string;\n }\n keyframes.push({ percentage, properties });\n }\n\n return {\n format: \"simple-array\",\n keyframes,\n ...(ease ? { ease } : {}),\n ...(easeEach ? { easeEach } : {}),\n };\n}\n\n// fallow-ignore-next-line complexity\nfunction parseKeyframesNode(\n node: any,\n scope: ScopeBindings,\n source: string,\n): GsapKeyframesData | undefined {\n if (!node) return undefined;\n\n if (node.type === \"ArrayExpression\") {\n return parseObjectArrayKeyframes(node, scope, source);\n }\n\n if (node.type !== \"ObjectExpression\") return undefined;\n\n const props = node.properties ?? [];\n let hasPercentageKey = false;\n let hasArrayValue = false;\n\n for (const prop of props) {\n if (prop.type !== \"ObjectProperty\" && prop.type !== \"Property\") continue;\n const key = prop.key?.value ?? prop.key?.name;\n if (typeof key === \"string\" && PERCENTAGE_KEY_RE.test(key)) {\n hasPercentageKey = true;\n break;\n }\n if (prop.value?.type === \"ArrayExpression\") {\n hasArrayValue = true;\n }\n }\n\n if (hasPercentageKey) return parsePercentageKeyframes(node, scope, source);\n if (hasArrayValue) return parseSimpleArrayKeyframes(node, scope);\n\n return undefined;\n}\n\n// ── MotionPath parsing ────────────────────────────────────────────────────────\n\ninterface MotionPathParseResult {\n arcPath: ArcPathConfig;\n waypoints: Array<{ x: number; y: number }>;\n}\n\n// fallow-ignore-next-line complexity\nfunction parseMotionPathNode(\n node: any,\n scope: ScopeBindings,\n source: string,\n): MotionPathParseResult | undefined {\n if (!node) return undefined;\n\n let pathNode: any;\n let autoRotate: boolean | number = false;\n let curviness = 1;\n let isCubic = false;\n\n if (node.type === \"ObjectExpression\") {\n for (const prop of node.properties ?? []) {\n if (!isObjectProperty(prop)) continue;\n const key = propKeyName(prop);\n if (key === \"path\") pathNode = prop.value;\n else if (key === \"autoRotate\") {\n const val = resolveNode(prop.value, scope);\n autoRotate = typeof val === \"number\" ? val : val === true;\n } else if (key === \"curviness\") {\n const val = resolveNode(prop.value, scope);\n if (typeof val === \"number\") curviness = val;\n } else if (key === \"type\") {\n const val = resolveNode(prop.value, scope);\n if (val === \"cubic\") isCubic = true;\n }\n }\n } else if (node.type === \"ArrayExpression\") {\n pathNode = node;\n }\n\n if (!pathNode || pathNode.type !== \"ArrayExpression\") return undefined;\n\n const elements = pathNode.elements ?? [];\n const coords: Array<{ x: number; y: number }> = [];\n for (const elem of elements) {\n if (!elem || elem.type !== \"ObjectExpression\") continue;\n const rec = objectExpressionToRecord(elem, scope, source);\n const x = typeof rec.x === \"number\" ? rec.x : undefined;\n const y = typeof rec.y === \"number\" ? rec.y : undefined;\n if (x !== undefined && y !== undefined) coords.push({ x, y });\n }\n\n return buildArcPath(coords, curviness, autoRotate, isCubic);\n}\n\n// ── Animation assembly ────────────────────────────────────────────────────────\n\n// fallow-ignore-next-line complexity\nfunction tweenCallToAnimation(\n call: TweenCallInfo,\n scope: ScopeBindings,\n source: string,\n): Omit<GsapAnimation, \"id\"> {\n const vars = objectExpressionToRecord(call.varsArg, scope, source);\n const properties: Record<string, number | string> = {};\n const extras: Record<string, unknown> = {};\n let keyframesData: GsapKeyframesData | undefined;\n let hasUnresolvedKeyframes = false;\n let motionPathResult: MotionPathParseResult | undefined;\n\n for (const [key, val] of Object.entries(vars)) {\n if (BUILTIN_VAR_KEYS.has(key)) continue;\n if (DROPPED_VAR_KEYS.has(key)) continue;\n\n if (key === \"keyframes\") {\n const kfNode = findPropertyNode(call.varsArg, \"keyframes\");\n keyframesData = parseKeyframesNode(kfNode, scope, source);\n if (!keyframesData && kfNode) hasUnresolvedKeyframes = true;\n continue;\n }\n\n if (key === \"motionPath\") {\n const mpNode = findPropertyNode(call.varsArg, \"motionPath\");\n motionPathResult = parseMotionPathNode(mpNode, scope, source);\n continue;\n }\n\n if (key === \"easeEach\") continue;\n\n if (EXTRAS_KEYS.has(key)) {\n const rawSource = extractRawPropertySource(call.varsArg, key, source);\n if (rawSource !== undefined) {\n extras[key] = `__raw:${rawSource}`;\n } else if (val !== undefined) {\n extras[key] = val;\n }\n continue;\n }\n\n if (typeof val === \"number\" || typeof val === \"string\") {\n properties[key] = val;\n }\n }\n\n if (keyframesData && typeof vars.easeEach === \"string\") {\n keyframesData.easeEach = vars.easeEach as string;\n }\n\n if (motionPathResult) {\n const { waypoints } = motionPathResult;\n if (!keyframesData) {\n const kf: GsapPercentageKeyframe[] = waypoints.map((wp, i) => ({\n percentage: waypoints.length > 1 ? Math.round((i / (waypoints.length - 1)) * 100) : 0,\n properties: { x: wp.x, y: wp.y },\n }));\n keyframesData = { format: \"percentage\", keyframes: kf };\n } else {\n const kfs = keyframesData.keyframes;\n if (kfs.length === waypoints.length) {\n for (let i = 0; i < kfs.length; i++) {\n const kf = kfs[i];\n const wp = waypoints[i];\n if (kf && wp) {\n kf.properties.x = wp.x;\n kf.properties.y = wp.y;\n }\n }\n }\n }\n }\n\n let fromProperties: Record<string, number | string> | undefined;\n if (call.method === \"fromTo\" && call.fromArg) {\n fromProperties = {};\n const fromVars = objectExpressionToRecord(call.fromArg, scope, source);\n for (const [key, val] of Object.entries(fromVars)) {\n if (typeof val === \"number\" || typeof val === \"string\") {\n fromProperties[key] = val;\n }\n }\n }\n\n const hasPositionArg = !!call.positionArg;\n const posVal = hasPositionArg ? extractLiteralValue(call.positionArg, scope) : 0;\n const position: number | string =\n typeof posVal === \"number\" ? posVal : typeof posVal === \"string\" ? posVal : 0;\n let duration = typeof vars.duration === \"number\" ? vars.duration : undefined;\n const ease = typeof vars.ease === \"string\" ? vars.ease : undefined;\n\n if (duration === undefined && keyframesData) {\n duration = computeKeyframesTotalDuration(call.varsArg, scope, source);\n }\n\n const anim: Omit<GsapAnimation, \"id\"> = {\n targetSelector: call.selector,\n method: call.method,\n position,\n properties,\n fromProperties,\n duration,\n ease,\n };\n if (!hasPositionArg) anim.implicitPosition = true;\n let group = classifyTweenPropertyGroup(properties);\n if (!group && keyframesData) {\n const kfProps: Record<string, unknown> = {};\n for (const kf of keyframesData.keyframes) {\n for (const k of Object.keys(kf.properties)) kfProps[k] = true;\n }\n group = classifyTweenPropertyGroup(kfProps);\n }\n if (group) anim.propertyGroup = group;\n if (call.global) anim.global = true;\n if (Object.keys(extras).length > 0) anim.extras = extras;\n if (keyframesData) anim.keyframes = keyframesData;\n if (motionPathResult) anim.arcPath = motionPathResult.arcPath;\n if (hasUnresolvedKeyframes) anim.hasUnresolvedKeyframes = true;\n if (call.selector === \"__unresolved__\") anim.hasUnresolvedSelector = true;\n const provenance = readProvenance(call.node);\n if (provenance) anim.provenance = provenance;\n return anim;\n}\n\n// ── Timeline position resolution ─────────────────────────────────────────────\n\nconst GSAP_DEFAULT_DURATION = 0.5;\n\n// fallow-ignore-next-line complexity\nfunction resolvePositionString(pos: string, cursor: number, prevStart: number): number | null {\n const trimmed = pos.trim();\n if (trimmed === \"\") return cursor;\n if (trimmed.startsWith(\"+=\")) {\n const n = Number.parseFloat(trimmed.slice(2));\n return Number.isFinite(n) ? cursor + n : null;\n }\n if (trimmed.startsWith(\"-=\")) {\n const n = Number.parseFloat(trimmed.slice(2));\n return Number.isFinite(n) ? cursor - n : null;\n }\n if (trimmed === \"<\") return prevStart;\n if (trimmed === \">\") return cursor;\n if (trimmed.startsWith(\"<\")) {\n const n = Number.parseFloat(trimmed.slice(1));\n return Number.isFinite(n) ? prevStart + n : null;\n }\n if (trimmed.startsWith(\">\")) {\n const n = Number.parseFloat(trimmed.slice(1));\n return Number.isFinite(n) ? cursor + n : null;\n }\n const n = Number.parseFloat(trimmed);\n return Number.isFinite(n) ? n : null;\n}\n\nfunction applyTimelineDefaults(\n anims: Omit<GsapAnimation, \"id\">[],\n defaults?: TimelineDefaults,\n): void {\n if (!defaults) return;\n for (const anim of anims) {\n if (anim.method === \"set\") continue;\n if (anim.duration === undefined && defaults.duration !== undefined) {\n anim.duration = defaults.duration;\n }\n if (anim.ease === undefined && defaults.ease !== undefined) {\n anim.ease = defaults.ease;\n }\n }\n}\n\n// fallow-ignore-next-line complexity\nfunction resolveTimelinePositions(anims: Omit<GsapAnimation, \"id\">[]): void {\n let cursor = 0;\n let prevStart = 0;\n for (const anim of anims) {\n // A global `gsap.set(...)` is off-timeline — applied once at load, not\n // sequenced on the master timeline. It carries no position arg, so the\n // cursor fallback would otherwise hand it the comp-end time. Pin it to 0\n // (its load-time start) and don't advance the cursor/prevStart.\n if (anim.method === \"set\" && anim.global) {\n anim.resolvedStart = 0;\n continue;\n }\n const duration = anim.method === \"set\" ? 0 : (anim.duration ?? GSAP_DEFAULT_DURATION);\n let start: number | null;\n\n if (anim.implicitPosition) {\n start = cursor;\n } else if (typeof anim.position === \"number\") {\n start = anim.position;\n } else if (typeof anim.position === \"string\") {\n start = resolvePositionString(anim.position, cursor, prevStart);\n } else {\n start = cursor;\n }\n\n if (start != null) {\n anim.resolvedStart = Math.max(0, start);\n prevStart = anim.resolvedStart;\n cursor = Math.max(cursor, anim.resolvedStart + duration);\n }\n }\n}\n\nfunction compareByLoc(a: TweenCallInfo, b: TweenCallInfo): number {\n const aLoc = a.node.callee?.property?.loc?.start;\n const bLoc = b.node.callee?.property?.loc?.start;\n if (!aLoc || !bLoc) return 0;\n return aLoc.line - bLoc.line || aLoc.column - bLoc.column;\n}\n\n// Inlined tweens carry a monotonic __hfOrder (clones share source loc, so loc\n// can't order them); they sort by that, after all literal (loc-ordered) tweens.\nfunction compareCallOrder(a: TweenCallInfo, b: TweenCallInfo): number {\n const ao = a.node.__hfOrder;\n const bo = b.node.__hfOrder;\n if (ao === undefined && bo === undefined) return compareByLoc(a, b);\n if (ao === undefined) return -1;\n if (bo === undefined) return 1;\n return ao - bo;\n}\n\nfunction sortBySourcePosition(calls: TweenCallInfo[]): void {\n calls.sort(compareCallOrder);\n}\n\n// ── Stable ID generation ──────────────────────────────────────────────────────\n\nfunction assignStableIds(anims: Omit<GsapAnimation, \"id\">[]): GsapAnimation[] {\n const counts = new Map<string, number>();\n return anims.map((anim) => {\n const posKey =\n typeof anim.position === \"number\"\n ? String(Math.round(anim.position * 1000))\n : String(anim.position);\n const groupSuffix = anim.propertyGroup ? `-${anim.propertyGroup}` : \"\";\n const base = `${anim.targetSelector}-${anim.method}-${posKey}${groupSuffix}`;\n const count = (counts.get(base) ?? 0) + 1;\n counts.set(base, count);\n const id = count === 1 ? base : `${base}-${count}`;\n return { ...anim, id };\n });\n}\n\n// ── Write-path internal parse ─────────────────────────────────────────────────\n\nexport interface ParsedGsapAcornForWrite {\n ast: any;\n timelineVar: string;\n hasTimeline: boolean;\n located: Array<{ id: string; call: TweenCallInfo; animation: GsapAnimation }>;\n}\n\n/**\n * Parse a GSAP script and return internal AST + call nodes for the write path.\n * Consumed by gsapWriterAcorn.ts (magic-string offset-splice).\n */\nexport function parseGsapScriptAcornForWrite(script: string): ParsedGsapAcornForWrite | null {\n try {\n const ast = acorn.parse(script, {\n ecmaVersion: \"latest\",\n sourceType: \"script\",\n locations: true,\n });\n const scope = collectScopeBindings(ast);\n const targetBindings = collectTargetBindings(ast, scope);\n const detection = findTimelineVar(ast, scope);\n const timelineVar = detection.timelineVar ?? \"tl\";\n const calls = findAllTweenCalls(ast, timelineVar, scope, targetBindings);\n sortBySourcePosition(calls);\n const rawAnims = calls.map((call) => tweenCallToAnimation(call, scope, script));\n applyTimelineDefaults(rawAnims, detection.defaults);\n resolveTimelinePositions(rawAnims);\n const animations = assignStableIds(rawAnims);\n const located = calls.map((call, i) => ({\n id: animations[i]!.id,\n call,\n animation: animations[i]!,\n }));\n return { ast, timelineVar, hasTimeline: detection.timelineVar !== null, located };\n } catch {\n return null;\n }\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Browser-safe equivalent of `parseGsapScript` (gsapParser.ts).\n * Uses acorn + acorn-walk instead of recast + @babel/parser.\n */\nexport function parseGsapScriptAcorn(script: string): ParsedGsap {\n try {\n const ast = acorn.parse(script, {\n ecmaVersion: \"latest\",\n sourceType: \"script\",\n locations: true,\n });\n const scope = collectScopeBindings(ast);\n const detection = findTimelineVar(ast, scope);\n const timelineVar = detection.timelineVar ?? \"tl\";\n // Expand helper-built / bounded-loop timelines before analysis so their\n // tweens resolve at true positions (read path only — the write path keeps\n // original source nodes). Degrades to the un-inlined AST on any failure.\n try {\n inlineComputedTimelines(ast, timelineVar, (node) => resolveNode(node, scope));\n } catch {\n /* fall back to current behavior */\n }\n const targetBindings = collectTargetBindings(ast, scope);\n const calls = findAllTweenCalls(ast, timelineVar, scope, targetBindings);\n sortBySourcePosition(calls);\n const rawAnims = calls.map((call) => tweenCallToAnimation(call, scope, script));\n applyTimelineDefaults(rawAnims, detection.defaults);\n resolveTimelinePositions(rawAnims);\n const animations = assignStableIds(rawAnims);\n\n const timelineMatch = script.match(\n new RegExp(\n `^[\\\\s\\\\S]*?(?:const|let|var)\\\\s+${timelineVar}\\\\s*=\\\\s*gsap\\\\.timeline\\\\s*\\\\([^)]*\\\\)\\\\s*;?`,\n ),\n );\n const preamble =\n timelineMatch?.[0] ?? `const ${timelineVar} = gsap.timeline({ paused: true });`;\n\n const lastCallIdx = script.lastIndexOf(`${timelineVar}.`);\n let postamble = \"\";\n if (lastCallIdx !== -1) {\n const afterLast = script.slice(lastCallIdx);\n const endOfCall = afterLast.indexOf(\";\");\n if (endOfCall !== -1) {\n postamble = script.slice(lastCallIdx + endOfCall + 1).trim();\n }\n }\n\n const result: ParsedGsap = { animations, timelineVar, preamble, postamble };\n if (detection.timelineCount > 1) result.multipleTimelines = true;\n if (detection.timelineCount > 0 && detection.timelineVar === null)\n result.unsupportedTimelinePattern = true;\n return result;\n } catch {\n return { animations: [], timelineVar: \"tl\", preamble: \"\", postamble: \"\" };\n }\n}\n\n// ── Label extraction (WS-C) ──────────────────────────────────────────────────\n\nexport interface GsapLabelEntry {\n name: string;\n position: number;\n}\n\n/**\n * Extract all `tl.addLabel(\"name\", position)` calls from a GSAP script.\n *\n * Returns labels in source order. Position must be a numeric literal; labels\n * with non-numeric positions (e.g. label-relative offsets) are skipped.\n *\n * Pure — no side effects, no DOM, no Date.now.\n */\nexport function extractGsapLabels(script: string): GsapLabelEntry[] {\n try {\n const ast = acorn.parse(script, {\n ecmaVersion: \"latest\",\n sourceType: \"script\",\n locations: true,\n });\n const scope = collectScopeBindings(ast);\n const detection = findTimelineVar(ast, scope);\n const timelineVar = detection.timelineVar ?? \"tl\";\n\n const labels: GsapLabelEntry[] = [];\n\n acornWalk.simple(ast, {\n // fallow-ignore-next-line complexity\n ExpressionStatement(node: any) {\n const expr = node.expression;\n if (!expr || expr.type !== \"CallExpression\") return;\n const callee = expr.callee;\n // Match tl.addLabel(...)\n if (\n callee?.type !== \"MemberExpression\" ||\n callee.object?.name !== timelineVar ||\n callee.property?.name !== \"addLabel\"\n )\n return;\n const args = expr.arguments ?? [];\n const nameNode = args[0];\n const posNode = args[1];\n if (nameNode?.type !== \"Literal\" || typeof nameNode.value !== \"string\") return;\n if (!posNode) return;\n const pos = resolveNode(posNode, scope);\n if (typeof pos !== \"number\" || !Number.isFinite(pos)) return;\n labels.push({ name: nameNode.value, position: pos });\n },\n });\n\n return labels;\n } catch {\n // Labels are best-effort/supplementary, not load-bearing — a malformed or\n // unparseable script yields no labels rather than failing the caller.\n return [];\n }\n}\n","/**\n * GSAP property and ease constants.\n *\n * Extracted into a standalone module so browser code can import them\n * without pulling in gsapParser (which depends on recast / @babel/parser).\n */\n\nexport const SUPPORTED_PROPS = [\n // 2D Transforms\n \"x\",\n \"y\",\n \"scale\",\n \"scaleX\",\n \"scaleY\",\n \"rotation\",\n \"skewX\",\n \"skewY\",\n // 3D Transforms\n \"z\",\n \"rotationX\",\n \"rotationY\",\n \"rotationZ\",\n \"perspective\",\n \"transformPerspective\",\n \"transformOrigin\",\n // Visibility\n \"opacity\",\n \"visibility\",\n \"autoAlpha\",\n // Dimensions\n \"width\",\n \"height\",\n // Colors\n \"color\",\n \"backgroundColor\",\n \"borderColor\",\n // Box model\n \"borderRadius\",\n // Typography\n \"fontSize\",\n \"letterSpacing\",\n // Filter & Clipping\n \"filter\",\n \"clipPath\",\n // DOM content (number counters, text roll-ups)\n \"innerText\",\n];\n\n// ── Property Groups ─────────────────────────────────────────────────────────\n// Each group maps to an independent GSAP tween so editing one property\n// (e.g. drag → x/y) never contaminates another (e.g. scale, rotation).\n\nexport type PropertyGroupName = \"position\" | \"scale\" | \"size\" | \"rotation\" | \"visual\" | \"other\";\n\nexport const PROPERTY_GROUPS: Record<PropertyGroupName, ReadonlySet<string>> = {\n position: new Set([\"x\", \"y\", \"xPercent\", \"yPercent\"]),\n scale: new Set([\"scale\", \"scaleX\", \"scaleY\"]),\n size: new Set([\"width\", \"height\"]),\n rotation: new Set([\"rotation\", \"skewX\", \"skewY\"]),\n visual: new Set([\"opacity\", \"autoAlpha\"]),\n other: new Set<string>(),\n};\n\nconst PROP_TO_GROUP = new Map<string, PropertyGroupName>();\nfor (const [group, props] of Object.entries(PROPERTY_GROUPS) as [\n PropertyGroupName,\n ReadonlySet<string>,\n][]) {\n for (const p of props) PROP_TO_GROUP.set(p, group);\n}\n\nexport function classifyPropertyGroup(prop: string): PropertyGroupName {\n return PROP_TO_GROUP.get(prop) ?? \"other\";\n}\n\nexport function classifyTweenPropertyGroup(\n properties: Record<string, unknown>,\n): PropertyGroupName | undefined {\n const groups = new Set<PropertyGroupName>();\n for (const key of Object.keys(properties)) {\n // transformOrigin is a modifier; `_auto` is Studio's internal endpoint marker;\n // `data` is GSAP-reserved (carries the Studio hold-set tag). None is an animated\n // property, so none should affect the group.\n if (key === \"transformOrigin\" || key === \"_auto\" || key === \"data\") continue;\n const g = classifyPropertyGroup(key);\n groups.add(g);\n }\n if (groups.size === 1) return groups.values().next().value;\n return undefined;\n}\n\nexport const SUPPORTED_EASES = [\n \"none\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"spring-gentle\",\n \"spring-bouncy\",\n \"spring-stiff\",\n \"spring-wobbly\",\n \"spring-heavy\",\n \"steps(1)\",\n];\n","/**\n * Recast-free GSAP helpers: serialization, keyframe<->animation conversion,\n * validation, and shared types.\n *\n * This module MUST NOT import recast / @babel/parser. It is part of the\n * isomorphic core layer that the barrel and browser code depend on. AST\n * parsing of GSAP source lives in the Node-only `./gsapParser` module.\n */\nimport type { Keyframe, KeyframeProperties, ValidationResult } from \"./types.js\";\nimport type { PropertyGroupName } from \"./gsapConstants\";\n\nexport type GsapMethod = \"set\" | \"to\" | \"from\" | \"fromTo\";\n\n/** How a tween was constructed in source — drives display classification and editability. */\nexport type GsapProvenanceKind = \"literal\" | \"helper\" | \"loop\" | \"runtime-dynamic\";\n\n/**\n * Origin of a parsed tween. `literal` tweens map 1:1 to a source call and edit\n * directly; `helper`/`loop` tweens are expanded from a reused construct (unroll\n * to edit); `runtime-dynamic` tweens come from live introspection (override to\n * edit). Absent provenance is treated as `literal`.\n */\nexport interface GsapProvenance {\n kind: GsapProvenanceKind;\n /** Helper function name (kind === \"helper\"). */\n fn?: string;\n /** 1-based ordinal of the originating call site / loop construct in source order. */\n callSite?: number;\n /** 0-based iteration index (kind === \"loop\"). */\n iteration?: number;\n /** Source offset [start, end] of the originating call/loop, when known. */\n sourceRange?: [number, number];\n}\n\n/** How a tween's keyframes can be edited, derived from its provenance. */\nexport type KeyframeEditability = \"direct\" | \"unroll\" | \"source\";\n\n/**\n * Map provenance to an editing strategy:\n * - `direct` — literal tween, maps 1:1 to source; edit in place.\n * - `unroll` — helper/loop expansion; unroll to literal tweens, then edit.\n * - `source` — runtime-dynamic value; not statically editable, edit the code.\n */\nexport function editabilityForProvenance(provenance?: GsapProvenance): KeyframeEditability {\n if (!provenance || provenance.kind === \"literal\") return \"direct\";\n if (provenance.kind === \"runtime-dynamic\") return \"source\";\n return \"unroll\";\n}\n\nexport interface GsapAnimation {\n id: string;\n targetSelector: string;\n method: GsapMethod;\n position: number | string;\n properties: Record<string, number | string>;\n fromProperties?: Record<string, number | string>;\n duration?: number;\n ease?: string;\n /** Non-editable GSAP config (stagger, yoyo, repeat, etc.) preserved for round-trips. */\n extras?: Record<string, unknown>;\n /** Native GSAP keyframes data — present when the tween uses keyframes: { ... }. */\n keyframes?: GsapKeyframesData;\n /** Arc motion path config — present when the tween uses motionPath for curved position interpolation. */\n arcPath?: ArcPathConfig;\n /** True when the tween has a `keyframes` property that couldn't be statically resolved (dynamic). */\n hasUnresolvedKeyframes?: boolean;\n /** True when the tween's target selector couldn't be statically resolved (dynamic). */\n hasUnresolvedSelector?: boolean;\n /** Absolute start time computed by walking the timeline chain (handles +=, -=, <, >, labels). */\n resolvedStart?: number;\n /** True when no position arg was authored — the tween is sequentially placed by GSAP. */\n implicitPosition?: boolean;\n /** Which property group this tween belongs to (position, scale, size, rotation, visual, other).\n * Undefined for legacy mixed tweens that bundle multiple groups. */\n propertyGroup?: PropertyGroupName;\n /** True for a base `gsap.set(...)` (a static hold that runs immediately, OFF the\n * timeline) rather than `tl.set(...)`. Carries no timeline position and shows no\n * keyframe marker — used to persist a static value (e.g. a 3D transform) without\n * introducing a 0% keyframe. */\n global?: boolean;\n /** How this tween was constructed in source. Absent ⇒ literal. */\n provenance?: GsapProvenance;\n}\n\nexport interface GsapPercentageKeyframe {\n percentage: number;\n properties: Record<string, number | string>;\n ease?: string;\n}\n\nexport type GsapKeyframeFormat = \"percentage\" | \"object-array\" | \"simple-array\";\n\nexport interface GsapKeyframesData {\n format: GsapKeyframeFormat;\n keyframes: GsapPercentageKeyframe[];\n ease?: string;\n easeEach?: string;\n}\n\nexport interface ArcPathSegment {\n curviness: number;\n cp1?: { x: number; y: number };\n cp2?: { x: number; y: number };\n}\n\nexport interface ArcPathConfig {\n enabled: boolean;\n autoRotate: boolean | number;\n segments: ArcPathSegment[];\n}\n\nexport interface MotionPathShape {\n arcPath: ArcPathConfig;\n waypoints: Array<{ x: number; y: number }>;\n}\n\n/**\n * Build arcPath segments + waypoints from resolved path coordinates. Shared by\n * the AST parser (coords from literal nodes) and the runtime scanner (coords\n * from a live `vars.motionPath`), so both produce identical arc config.\n */\nexport function buildArcPath(\n coords: Array<{ x: number; y: number }>,\n curviness: number,\n autoRotate: boolean | number,\n isCubic: boolean,\n): MotionPathShape | undefined {\n const first = coords[0];\n if (coords.length < 2 || !first) return undefined;\n const segments: ArcPathSegment[] = [];\n let waypoints: Array<{ x: number; y: number }>;\n if (isCubic && coords.length >= 4) {\n // coords are [anchor, cp1, cp2, anchor, cp1, cp2, anchor, ...].\n waypoints = [first];\n for (let i = 1; i + 2 < coords.length; i += 3) {\n const cp1 = coords[i];\n const cp2 = coords[i + 1];\n const anchor = coords[i + 2];\n if (!cp1 || !cp2 || !anchor) continue;\n waypoints.push(anchor);\n segments.push({ curviness, cp1, cp2 });\n }\n } else {\n waypoints = coords;\n for (let i = 0; i < waypoints.length - 1; i++) segments.push({ curviness });\n }\n return { arcPath: { enabled: true, autoRotate, segments }, waypoints };\n}\n\nexport interface ParsedGsap {\n animations: GsapAnimation[];\n timelineVar: string;\n preamble: string;\n postamble: string;\n multipleTimelines?: boolean;\n unsupportedTimelinePattern?: boolean;\n}\n\nexport { SUPPORTED_PROPS, SUPPORTED_EASES } from \"./gsapConstants\";\n\n// ── Split-animation types (used by gsapWriterAcorn) ─────────────────────────\n\nexport interface SplitAnimationsOptions {\n originalId: string;\n newId: string;\n splitTime: number;\n elementStart: number;\n elementDuration: number;\n}\n\nexport interface SplitAnimationsResult {\n script: string;\n /** Non-ID-selector animations that the engine cannot safely retarget. */\n skippedSelectors: string[];\n}\n\n// ── Serialization ───────────────────────────────────────────────────────────\n\nexport function serializeGsapAnimations(\n animations: GsapAnimation[],\n timelineVar = \"tl\",\n options?: { includeMediaSync?: boolean; preamble?: string; postamble?: string },\n): string {\n const sorted = [...animations].sort((a, b) => {\n const aNum =\n a.resolvedStart ?? (typeof a.position === \"number\" ? a.position : Number.MAX_SAFE_INTEGER);\n const bNum =\n b.resolvedStart ?? (typeof b.position === \"number\" ? b.position : Number.MAX_SAFE_INTEGER);\n return aNum - bNum;\n });\n // fallow-ignore-next-line complexity\n const lines = sorted.map((anim) => {\n const selector = `\"${anim.targetSelector}\"`;\n const props: Record<string, number | string> = { ...anim.properties };\n if (anim.duration !== undefined) props.duration = anim.duration;\n if (anim.ease) props.ease = anim.ease;\n let propsStr = serializeObject(props);\n if (anim.extras && Object.keys(anim.extras).length > 0) {\n const extrasStr = serializeExtras(anim.extras);\n if (Object.keys(props).length === 0) {\n propsStr = `{ ${extrasStr} }`;\n } else {\n // Insert extras before the closing brace\n propsStr = propsStr.slice(0, -2) + `, ${extrasStr} }`;\n }\n }\n const posStr = typeof anim.position === \"string\" ? `\"${anim.position}\"` : anim.position;\n switch (anim.method) {\n case \"set\":\n // A global set is a base `gsap.set` — off the timeline, no position arg.\n return anim.global\n ? ` gsap.set(${selector}, ${propsStr});`\n : ` ${timelineVar}.set(${selector}, ${propsStr}, ${posStr});`;\n case \"to\":\n return ` ${timelineVar}.to(${selector}, ${propsStr}, ${posStr});`;\n case \"from\":\n return ` ${timelineVar}.from(${selector}, ${propsStr}, ${posStr});`;\n case \"fromTo\": {\n const fromStr = serializeObject(anim.fromProperties || {});\n return ` ${timelineVar}.fromTo(${selector}, ${fromStr}, ${propsStr}, ${posStr});`;\n }\n }\n });\n\n let mediaSync = \"\";\n if (options?.includeMediaSync) {\n mediaSync = `\n ${timelineVar}.eventCallback(\"onUpdate\", function() {\n const time = ${timelineVar}.time();\n document.querySelectorAll(\"video[data-start], audio[data-start]\").forEach(function(media) {\n const start = parseFloat(media.dataset.start);\n const end = parseFloat(media.dataset.end) || Infinity;\n const mediaTime = time - start;\n if (time >= start && time < end) {\n if (Math.abs(media.currentTime - mediaTime) > 0.1) {\n media.currentTime = mediaTime;\n }\n if (media.paused && !${timelineVar}.paused()) {\n media.play().catch(function() {});\n }\n } else if (!media.paused) {\n media.pause();\n }\n });\n });`;\n }\n\n const preamble = options?.preamble || `const ${timelineVar} = gsap.timeline({ paused: true });`;\n const postamble = options?.postamble ? `\\n ${options.postamble}` : \"\";\n\n return `\n ${preamble}\n${lines.join(\"\\n\")}${mediaSync}${postamble}\n `;\n}\n\nexport function serializeValue(value: unknown): string {\n if (typeof value === \"string\" && value.startsWith(\"__raw:\")) {\n return value.slice(6);\n }\n if (typeof value === \"string\") return JSON.stringify(value);\n return String(value);\n}\n\nexport function safeJsKey(key: string): string {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);\n}\n\nfunction serializeObject(obj: Record<string, number | string>): string {\n const entries = Object.entries(obj).map(([key, value]) => {\n return `${safeJsKey(key)}: ${serializeValue(value)}`;\n });\n return `{ ${entries.join(\", \")} }`;\n}\n\nfunction serializeExtras(extras: Record<string, unknown>): string {\n return Object.entries(extras)\n .map(([key, value]) => {\n return `${safeJsKey(key)}: ${serializeValue(value)}`;\n })\n .join(\", \");\n}\n\n// ── Element filtering ─────────────────────────────────────────────────────────\n\n/**\n * Filter animations to those targeting `#<elementId>` (id-only match). For the\n * studio panel's id-OR-selector matching, see `getAnimationsForElement` in\n * `useGsapTweenCache.ts` — distinct on purpose, hence the distinct name.\n */\nexport function getAnimationsForElementId(\n animations: GsapAnimation[],\n elementId: string,\n): GsapAnimation[] {\n const selector = `#${elementId}`;\n return animations.filter((a) => a.targetSelector === selector);\n}\n\n// ── Validation (regex-based, no AST needed) ─────────────────────────────────\n\nconst FORBIDDEN_GSAP_PATTERNS: Array<{ pattern: RegExp; message: string }> = [\n { pattern: /\\.call\\s*\\(/, message: \"call() method not allowed\" },\n { pattern: /\\.add\\s*\\(/, message: \"add() method not allowed\" },\n { pattern: /\\.addPause\\s*\\(/, message: \"addPause() method not allowed\" },\n { pattern: /gsap\\.registerEffect\\s*\\(/, message: \"registerEffect() not allowed\" },\n { pattern: /ScrollTrigger/, message: \"ScrollTrigger not allowed\" },\n { pattern: /onComplete\\s*:/, message: \"onComplete callback not allowed\" },\n { pattern: /onUpdate\\s*:/, message: \"onUpdate callback not allowed\" },\n { pattern: /onStart\\s*:/, message: \"onStart callback not allowed\" },\n { pattern: /onRepeat\\s*:/, message: \"onRepeat callback not allowed\" },\n { pattern: /onReverseComplete\\s*:/, message: \"onReverseComplete callback not allowed\" },\n { pattern: /repeat\\s*:\\s*-1/, message: \"Infinite repeat (repeat: -1) not allowed\" },\n { pattern: /Math\\.random\\s*\\(/, message: \"Random values (Math.random) not allowed\" },\n { pattern: /Date\\.now\\s*\\(/, message: \"Date-dependent values (Date.now) not allowed\" },\n { pattern: /new\\s+Date\\s*\\(/, message: \"Date constructor not allowed\" },\n { pattern: /setTimeout\\s*\\(/, message: \"setTimeout not allowed\" },\n { pattern: /setInterval\\s*\\(/, message: \"setInterval not allowed\" },\n { pattern: /requestAnimationFrame\\s*\\(/, message: \"requestAnimationFrame not allowed\" },\n];\n\nexport function validateCompositionGsap(script: string): ValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n for (const { pattern, message } of FORBIDDEN_GSAP_PATTERNS) {\n if (pattern.test(script)) errors.push(message);\n }\n if (/yoyo\\s*:\\s*true/.test(script)) {\n warnings.push(\"yoyo animations may behave unexpectedly when scrubbing\");\n }\n if (/stagger\\s*:/.test(script)) {\n warnings.push(\"stagger animations may not serialize correctly\");\n }\n return { valid: errors.length === 0, errors, warnings };\n}\n\n// ── Keyframe Conversion Helpers ─────────────────────────────────────────────\n\nexport function keyframesToGsapAnimations(\n elementId: string,\n keyframes: Keyframe[],\n elementStartTime: number,\n base?: { x?: number; y?: number; scale?: number },\n): GsapAnimation[] {\n const sorted = [...keyframes].sort((a, b) => a.time - b.time);\n const animations: GsapAnimation[] = [];\n const baseX = base?.x ?? 0;\n const baseY = base?.y ?? 0;\n const baseScale = base?.scale ?? 1;\n\n // fallow-ignore-next-line complexity\n sorted.forEach((kf, i) => {\n const absoluteTime = elementStartTime + kf.time;\n const isFirst = i === 0;\n const prevKf = i > 0 ? sorted[i - 1] : null;\n const duration = prevKf ? kf.time - prevKf.time : undefined;\n const position = prevKf ? elementStartTime + prevKf.time : absoluteTime;\n\n const properties: Record<string, number | string> = {};\n for (const [key, value] of Object.entries(kf.properties)) {\n if (typeof value !== \"number\") continue;\n if (key === \"x\") properties.x = baseX + value;\n else if (key === \"y\") properties.y = baseY + value;\n else if (key === \"scale\") properties.scale = baseScale * value;\n else properties[key] = value;\n }\n\n animations.push({\n id: `${elementId}-kf-${kf.id}`,\n targetSelector: `#${elementId}`,\n method: isFirst ? \"set\" : \"to\",\n position,\n properties,\n duration: isFirst ? undefined : duration,\n ease: kf.ease,\n });\n });\n\n return animations;\n}\n\nexport function gsapAnimationsToKeyframes(\n animations: GsapAnimation[],\n elementStartTime: number,\n options?: {\n baseX?: number;\n baseY?: number;\n baseScale?: number;\n clampTimeToZero?: boolean;\n skipBaseSet?: boolean;\n },\n): Keyframe[] {\n const validMethods: GsapMethod[] = [\"set\", \"to\", \"from\", \"fromTo\"];\n const baseX = options?.baseX ?? 0;\n const baseY = options?.baseY ?? 0;\n const baseScale = options?.baseScale ?? 1;\n const clampTimeToZero = options?.clampTimeToZero ?? true;\n const skipBaseSet = options?.skipBaseSet ?? false;\n const baseTimeEpsilon = 0.001;\n const baseValueEpsilon = 0.00001;\n\n return (\n animations\n .filter(\n (a): a is GsapAnimation & { position: number } =>\n validMethods.includes(a.method) && typeof a.position === \"number\",\n )\n // fallow-ignore-next-line complexity\n .map((a) => {\n const relativeTimeRaw = a.position - elementStartTime;\n const time = clampTimeToZero ? Math.max(0, relativeTimeRaw) : relativeTimeRaw;\n\n const properties: Partial<KeyframeProperties> = {};\n for (const [key, value] of Object.entries(a.properties)) {\n if (typeof value !== \"number\") continue;\n if (key === \"x\") properties.x = value - baseX;\n else if (key === \"y\") properties.y = value - baseY;\n else if (key === \"scale\") {\n properties.scale = baseScale !== 0 ? value / baseScale : value;\n } else {\n (properties as Record<string, number>)[key] = value;\n }\n }\n\n if (\n skipBaseSet &&\n a.method === \"set\" &&\n time < baseTimeEpsilon &&\n Object.values(properties).every(\n (v) => typeof v === \"number\" && Math.abs(v) < baseValueEpsilon,\n )\n ) {\n return null;\n }\n\n return {\n id: a.id.replace(/^.*-kf-/, \"\"),\n time,\n properties: properties as KeyframeProperties,\n ease: a.ease,\n };\n })\n .filter((kf): kf is NonNullable<typeof kf> => kf !== null)\n );\n}\n\n// ── Keyframe-conversion transforms (pure; shared by recast + acorn writers) ────\n\n/**\n * CSS identity values for properties whose \"rest\" state isn't 0 — used to\n * synthesize the missing endpoint when converting a flat tween to keyframes.\n */\nconst CSS_IDENTITY: Record<string, number> = {\n opacity: 1,\n autoAlpha: 1,\n scale: 1,\n scaleX: 1,\n scaleY: 1,\n};\n\nfunction cssIdentityValue(prop: string): number {\n return CSS_IDENTITY[prop] ?? 0;\n}\n\n/** Build the identity-endpoint map for a flat tween's properties. */\nfunction buildIdentityMap(props: Record<string, number | string>): Record<string, number | string> {\n const identity: Record<string, number | string> = {};\n for (const [key, val] of Object.entries(props)) {\n if (val != null) identity[key] = typeof val === \"number\" ? cssIdentityValue(key) : val;\n }\n return identity;\n}\n\n/**\n * Resolve the 0% (from) and 100% (to) property maps for a tween being\n * converted to percentage keyframes.\n *\n * @param resolvedFromValues — Despite the \"from\" in the name (historical), these\n * are runtime-captured DOM values that override the conversion endpoint:\n * - For to(): overrides fromProps (the 0% state / where the element is now).\n * - For from(): overrides toProps (the 100% state / where the element rests).\n * - For fromTo(): merges into toProps (the 100% endpoint the user is editing).\n */\nexport function resolveConversionProps(\n anim: GsapAnimation,\n resolvedFromValues?: Record<string, number | string>,\n): { fromProps: Record<string, number | string>; toProps: Record<string, number | string> } {\n if (anim.method === \"set\") {\n // A static hold becomes a keyframed `to` whose 0% and 100% both start at the\n // set's value — the visual is unchanged until the user edits a keyframe to\n // animate it. (The caller flips the call from `set` to `to` + adds a duration.)\n return { fromProps: { ...anim.properties }, toProps: { ...anim.properties } };\n }\n if (anim.method === \"to\") {\n const identity = buildIdentityMap(anim.properties);\n const fromProps = resolvedFromValues ? { ...identity, ...resolvedFromValues } : identity;\n return { fromProps, toProps: { ...anim.properties } };\n }\n if (anim.method === \"from\") {\n const identity = buildIdentityMap(anim.properties);\n const toProps = resolvedFromValues ? { ...identity, ...resolvedFromValues } : identity;\n return { fromProps: { ...anim.properties }, toProps };\n }\n // fromTo(fromVars, toVars): anim.fromProperties = fromVars (0% state),\n // anim.properties = toVars (100% state). resolvedFromValues contains the\n // current DOM position from a drag — it represents the NEW destination, so\n // it merges into toProps (the 100% endpoint the user is editing), NOT into\n // fromProps. This is intentional and not inverted.\n const toProps = resolvedFromValues\n ? { ...anim.properties, ...resolvedFromValues }\n : { ...anim.properties };\n return { fromProps: { ...(anim.fromProperties ?? {}) }, toProps };\n}\n\n// ── Arc path serialization helpers (shared by recast + acorn writers) ─────────\n\nfunction numericXY(props: Record<string, number | string>): { x: number; y: number } | null {\n const vx = props.x;\n const vy = props.y;\n return typeof vx === \"number\" && typeof vy === \"number\" ? { x: vx, y: vy } : null;\n}\n\nexport function extractArcWaypoints(anim: GsapAnimation): Array<{ x: number; y: number }> {\n const keyframeWps = (anim.keyframes?.keyframes ?? [])\n .map((kf) => numericXY(kf.properties))\n .filter((pt): pt is { x: number; y: number } => pt !== null);\n if (keyframeWps.length >= 2) return keyframeWps;\n const propX = anim.properties.x;\n const propY = anim.properties.y;\n if (typeof propX !== \"number\" && typeof propY !== \"number\") return keyframeWps;\n const destX = typeof propX === \"number\" ? propX : 0;\n const destY = typeof propY === \"number\" ? propY : 0;\n return [\n { x: 0, y: 0 },\n { x: destX, y: destY },\n ];\n}\n\nfunction autoRotateSuffix(autoRotate: boolean | number): string {\n if (autoRotate === true) return \", autoRotate: true\";\n if (typeof autoRotate === \"number\") return `, autoRotate: ${autoRotate}`;\n return \"\";\n}\n\nfunction cubicControlPoints(\n seg: ArcPathSegment,\n wp: { x: number; y: number },\n nextWp: { x: number; y: number },\n): string[] {\n if (seg.cp1 && seg.cp2) {\n return [`{x: ${seg.cp1.x}, y: ${seg.cp1.y}}`, `{x: ${seg.cp2.x}, y: ${seg.cp2.y}}`];\n }\n const dx = nextWp.x - wp.x;\n const dy = nextWp.y - wp.y;\n const c = seg.curviness ?? 1;\n return [\n `{x: ${wp.x + dx * 0.33}, y: ${wp.y + dy * 0.33 - c * Math.abs(dx) * 0.25}}`,\n `{x: ${wp.x + dx * 0.66}, y: ${wp.y + dy * 0.66 - c * Math.abs(dx) * 0.25}}`,\n ];\n}\n\nfunction buildCubicPathEntries(\n waypoints: Array<{ x: number; y: number }>,\n segments: ArcPathSegment[],\n): string[] {\n const first = waypoints[0];\n if (!first) return [];\n const entries = [`{x: ${first.x}, y: ${first.y}}`];\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n const wp = waypoints[i];\n const nextWp = waypoints[i + 1];\n if (!seg || !wp || !nextWp) continue;\n entries.push(...cubicControlPoints(seg, wp, nextWp));\n entries.push(`{x: ${nextWp.x}, y: ${nextWp.y}}`);\n }\n return entries;\n}\n\nexport function buildMotionPathObjectCode(config: {\n waypoints: Array<{ x: number; y: number }>;\n segments: ArcPathSegment[];\n autoRotate: boolean | number;\n}): string {\n const { waypoints, segments, autoRotate } = config;\n const arSuffix = autoRotateSuffix(autoRotate);\n // GSAP's simple `path` array supports only ONE scalar `curviness` for the whole\n // path, so per-segment curviness can only be expressed in the cubic form (each\n // segment's curviness baked into its control points). Emit cubic when segments\n // carry explicit control points OR when their curviness values differ — the\n // simple branch would otherwise serialize only segments[0].curviness and drop\n // every other segment's curve.\n const hasExplicitCp = segments.some((s) => s.cp1 && s.cp2);\n const curvinessVaries = segments.some(\n (s) => (s.curviness ?? 1) !== (segments[0]?.curviness ?? 1),\n );\n if ((hasExplicitCp || curvinessVaries) && waypoints.length >= 2) {\n const pathStr = buildCubicPathEntries(waypoints, segments).join(\", \");\n return `{ path: [${pathStr}], type: \"cubic\"${arSuffix} }`;\n }\n const pathEntries = waypoints.map((wp) => `{x: ${wp.x}, y: ${wp.y}}`);\n const curviness = segments[0]?.curviness ?? 1;\n const curvPart = curviness !== 1 ? `, curviness: ${curviness}` : \"\";\n return `{ path: [${pathEntries.join(\", \")}]${curvPart}${arSuffix} }`;\n}\n","/**\n * Static evaluation for computed GSAP timelines (browser-safe, acorn/ESTree).\n *\n * The read parser resolves only literals and top-level consts, so timelines\n * built by a helper called N times or by a bounded loop collapse to position 0.\n * This module expands those constructs into a synthetic analysis AST: each\n * helper invocation and each loop iteration becomes its own concrete set of\n * `tl.*` calls, with parameters/loop-vars substituted by the call's argument\n * (or element/index) AST nodes — after which the existing parse pipeline\n * resolves positions and `motionPath` arcs unchanged.\n *\n * Substituted nodes keep their original source offsets, so downstream\n * source-slicing (raw extras, keyframes) stays correct. The substitution\n * primitives never mutate their input; `inlineComputedTimelines` rewrites the\n * Program body of the freshly-parsed AST it is handed (owned by the caller).\n */\nimport type { GsapProvenance } from \"./gsapSerialize.js\";\n\n// acorn ESTree nodes are structurally untyped; mirror gsapParserAcorn.ts.\ntype Node = any;\n\n/** Node keys that are metadata, not child AST to traverse/substitute. */\nconst SKIP_KEYS = new Set([\"type\", \"start\", \"end\", \"loc\", \"range\", \"__hfProvenance\", \"__hfOrder\"]);\n\nconst FUNCTION_TYPES = new Set([\n \"ArrowFunctionExpression\",\n \"FunctionExpression\",\n \"FunctionDeclaration\",\n]);\nconst GSAP_METHODS = new Set([\"set\", \"to\", \"from\", \"fromTo\"]);\n\n// Bounds on synthetic expansion (recursion + iteration runaway guards).\nconst MAX_DEPTH = 8;\nconst MAX_ITERS = 512;\n\nfunction isFunctionNode(node: Node): boolean {\n return !!node && FUNCTION_TYPES.has(node.type);\n}\n\nfunction isNode(x: Node): boolean {\n return !!x && typeof x === \"object\" && typeof x.type === \"string\";\n}\n\n/**\n * Apply `fn` to each child AST node, writing back its return value. Skips\n * metadata keys and key/member slots that must not be treated as values.\n * The one place array-vs-single child traversal lives, so walkers stay flat.\n */\nfunction transformChildren(node: Node, fn: (child: Node) => Node): void {\n for (const key of Object.keys(node)) {\n if (SKIP_KEYS.has(key) || isNonValueIdentifierSlot(node, key)) continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (let i = 0; i < child.length; i++) child[i] = fn(child[i]);\n } else {\n node[key] = fn(child);\n }\n }\n}\n\n/** Deep structural clone preserving `start`/`end`/`loc` (needed for source slicing). */\nexport function cloneNode<T extends Node>(node: T): T {\n return structuredClone(node);\n}\n\n// ponytail: Identifier + default + rest only. Destructured bindings (`{x}`, `[x]`)\n// aren't inlined (U2 inlines Identifier-param helpers / loop vars only), so a\n// destructuring shadow is a double-rare miss that just falls back. Add the\n// pattern cases here if that ever bites.\nfunction collectPatternNames(pattern: Node, out: Set<string>): void {\n if (pattern?.type === \"Identifier\") out.add(pattern.name);\n else if (pattern?.type === \"AssignmentPattern\") collectPatternNames(pattern.left, out);\n else if (pattern?.type === \"RestElement\") collectPatternNames(pattern.argument, out);\n}\n\n/** Every identifier name bound anywhere inside the subtree (fn params, declared vars, catch params). */\nfunction collectBoundNames(root: Node): Set<string> {\n const names = new Set<string>();\n const visit = (node: Node): Node => {\n if (!isNode(node)) return node;\n if (isFunctionNode(node)) for (const p of node.params ?? []) collectPatternNames(p, names);\n else if (node.type === \"VariableDeclarator\") collectPatternNames(node.id, names);\n else if (node.type === \"CatchClause\") collectPatternNames(node.param, names);\n transformChildren(node, visit);\n return node;\n };\n visit(root);\n return names;\n}\n\n/** A child in key/property position that must not be treated as a value identifier. */\nfunction isNonValueIdentifierSlot(node: Node, key: string): boolean {\n if (node.computed) return false;\n return (\n (node.type === \"MemberExpression\" && key === \"property\") ||\n (node.type === \"Property\" && key === \"key\")\n );\n}\n\n/**\n * Substitute bound identifiers in an already-cloned subtree, returning the\n * (possibly replaced) root. Names shadowed anywhere inside (nested function\n * params, declared vars) are dropped up front rather than tracked per scope —\n * worst case we under-substitute and the caller falls back to current behavior.\n * Never substitutes identifiers in key/member positions. Mutates the passed\n * clone in place — callers pass `cloneNode(...)`.\n */\nexport function substituteParams(node: Node, bindings: ReadonlyMap<string, Node>): Node {\n const shadowed = collectBoundNames(node);\n let effective = bindings;\n if (shadowed.size > 0) {\n effective = new Map(bindings);\n for (const name of shadowed) (effective as Map<string, Node>).delete(name);\n }\n if (effective.size === 0) return node;\n return replace(node, effective);\n}\n\nfunction replace(node: Node, bindings: ReadonlyMap<string, Node>): Node {\n if (!isNode(node)) return node;\n if (node.type === \"Identifier\" && bindings.has(node.name)) {\n return cloneNode(bindings.get(node.name));\n }\n transformChildren(node, (child) => replace(child, bindings));\n return node;\n}\n\n/** Tag a node (typically a `tl.*` CallExpression) with its construction provenance. */\nexport function tagProvenance(node: Node, provenance: GsapProvenance): Node {\n if (node && typeof node === \"object\") node.__hfProvenance = provenance;\n return node;\n}\n\n/** Read a provenance tag previously set by `tagProvenance`, if any. */\nexport function readProvenance(node: Node): GsapProvenance | undefined {\n return node?.__hfProvenance;\n}\n\n/** Synthesize a numeric `Literal` node (for loop indices, which have no source node). */\nexport function numericLiteral(value: number): Node {\n return { type: \"Literal\", value, raw: String(value) };\n}\n\n// ── Expansion engine (U2) ─────────────────────────────────────────────────────\n\n/** Resolve an expression to a literal value (top-level consts in scope, arithmetic). */\ntype LiteralResolver = (node: Node) => number | string | boolean | undefined;\n\ninterface ExpandCtx {\n helpers: Map<string, Node>;\n timelineVar: string;\n resolve: LiteralResolver;\n depth: number;\n /** Mutable source-order counter for provenance call-site ordinals. */\n site: { n: number };\n /** Mutable counter stamping expansion order onto tweens (clones share source loc). */\n order: { n: number };\n}\n\nfunction walkNodes(node: Node, fn: (n: Node) => void): void {\n if (!isNode(node)) return;\n fn(node);\n for (const key of Object.keys(node)) {\n if (SKIP_KEYS.has(key)) continue;\n const child = node[key];\n if (Array.isArray(child)) for (const c of child) walkNodes(c, fn);\n else walkNodes(child, fn);\n }\n}\n\n/** The identifier a (possibly chained) call's member expression is rooted at. */\nfunction timelineRootName(call: Node): string | null {\n let obj = call.callee?.object;\n while (obj?.type === \"CallExpression\") obj = obj.callee?.object;\n return obj?.type === \"Identifier\" ? obj.name : null;\n}\n\nfunction isTimelineRooted(call: Node, timelineVar: string): boolean {\n if (timelineRootName(call) !== timelineVar) return false;\n return (\n call.callee?.property?.type === \"Identifier\" && GSAP_METHODS.has(call.callee.property.name)\n );\n}\n\nfunction containsTimelineCall(node: Node, timelineVar: string): boolean {\n let found = false;\n walkNodes(node, (n) => {\n if (n.type === \"CallExpression\" && isTimelineRooted(n, timelineVar)) found = true;\n });\n return found;\n}\n\nfunction rangeOf(node: Node): [number, number] | undefined {\n return typeof node.start === \"number\" && typeof node.end === \"number\"\n ? [node.start, node.end]\n : undefined;\n}\n\n/** Plain identifier params + block body (shape we can inline). Timeline content checked separately. */\nfunction isShapeEligible(fn: Node): boolean {\n return (\n isFunctionNode(fn) &&\n fn.body?.type === \"BlockStatement\" &&\n !(fn.params ?? []).some((p: Node) => p.type !== \"Identifier\")\n );\n}\n\n/** True if the subtree calls any function named in `names`. */\nfunction callsAny(node: Node, names: Set<string>): boolean {\n let hit = false;\n walkNodes(node, (n) => {\n if (\n n.type === \"CallExpression\" &&\n n.callee?.type === \"Identifier\" &&\n names.has(n.callee.name)\n ) {\n hit = true;\n }\n });\n return hit;\n}\n\n/** `[name, fnNode]` if a single-declarator `const f = fn` is an inlinable-shaped helper. */\nfunction varDeclHelper(stmt: Node): [string, Node] | null {\n if (stmt.declarations?.length !== 1) return null;\n const d = stmt.declarations[0];\n return d.id?.type === \"Identifier\" && isShapeEligible(d.init) ? [d.id.name, d.init] : null;\n}\n\n/** `[name, fnNode]` if `stmt` declares an inlinable-shaped helper, else null. */\nfunction helperFromStatement(stmt: Node): [string, Node] | null {\n if (stmt.type === \"FunctionDeclaration\") {\n return stmt.id && isShapeEligible(stmt) ? [stmt.id.name, stmt] : null;\n }\n if (stmt.type === \"VariableDeclaration\") return varDeclHelper(stmt);\n return null;\n}\n\n/** Top-level functions whose shape we can inline (Identifier params + block body). */\nfunction gatherHelperCandidates(program: Node): Map<string, Node> {\n const candidates = new Map<string, Node>();\n for (const stmt of program.body ?? []) {\n const helper = helperFromStatement(stmt);\n if (helper) candidates.set(helper[0], helper[1]);\n }\n return candidates;\n}\n\n/** Names that build the timeline directly or by calling another builder (transitive closure). */\nfunction timelineBuildingNames(candidates: Map<string, Node>, timelineVar: string): Set<string> {\n const building = new Set<string>();\n for (const [name, fn] of candidates) {\n if (containsTimelineCall(fn.body, timelineVar)) building.add(name);\n }\n for (let changed = true; changed; ) {\n changed = false;\n for (const [name, fn] of candidates) {\n if (!building.has(name) && callsAny(fn.body, building)) {\n building.add(name);\n changed = true;\n }\n }\n }\n return building;\n}\n\nfunction bump(counts: Map<string, number>, key: string): void {\n counts.set(key, (counts.get(key) ?? 0) + 1);\n}\n\n/**\n * Keep only candidates safe to drop: every reference to the name is its\n * declaration or a statement-level call. (1 decl id + 1 callee id per\n * statement-level call ⇒ total occurrences with no stray uses.)\n */\nfunction safelyDroppable(program: Node, candidates: Map<string, Node>): Map<string, Node> {\n const names = new Set(candidates.keys());\n const totalIds = new Map<string, number>();\n const stmtCalls = new Map<string, number>();\n walkNodes(program, (n) => {\n if (n.type === \"Identifier\" && names.has(n.name)) bump(totalIds, n.name);\n const e = n.type === \"ExpressionStatement\" ? n.expression : undefined;\n if (\n e?.type === \"CallExpression\" &&\n e.callee?.type === \"Identifier\" &&\n names.has(e.callee.name)\n ) {\n bump(stmtCalls, e.callee.name);\n }\n });\n const safe = new Map<string, Node>();\n for (const [name, fn] of candidates) {\n if ((totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0)) safe.set(name, fn);\n }\n return safe;\n}\n\n/** Top-level timeline-building helpers that are safe to inline-and-drop. */\nfunction collectInlinableHelpers(program: Node, timelineVar: string): Map<string, Node> {\n const candidates = gatherHelperCandidates(program);\n if (candidates.size === 0) return candidates;\n const building = timelineBuildingNames(candidates, timelineVar);\n for (const name of [...candidates.keys()]) if (!building.has(name)) candidates.delete(name);\n if (candidates.size === 0) return candidates;\n return safelyDroppable(program, candidates);\n}\n\nfunction isHelperDecl(stmt: Node, helpers: Map<string, Node>): boolean {\n if (stmt.type === \"FunctionDeclaration\") return !!stmt.id && helpers.get(stmt.id.name) === stmt;\n if (stmt.type === \"VariableDeclaration\" && stmt.declarations?.length === 1) {\n const d = stmt.declarations[0];\n return d.id?.type === \"Identifier\" && helpers.get(d.id.name) === d.init;\n }\n return false;\n}\n\nfunction bodyStatements(node: Node): Node[] {\n if (node?.type === \"BlockStatement\") return node.body ?? [];\n return node ? [{ type: \"ExpressionStatement\", expression: node }] : [];\n}\n\n/** Tag this body's direct timeline tweens with provenance + a monotonic expansion-order stamp. */\nfunction tagTimelineCalls(stmts: Node[], prov: GsapProvenance, ctx: ExpandCtx): void {\n for (const stmt of stmts) {\n walkNodes(stmt, (n) => {\n if (n.type === \"CallExpression\" && isTimelineRooted(n, ctx.timelineVar)) {\n tagProvenance(n, { ...prov });\n n.__hfOrder = ctx.order.n++;\n }\n });\n }\n}\n\n/** Clone a body as one scope, substitute the bindings, tag provenance, recurse. */\nfunction expandBody(\n bodyStmts: Node[],\n bindings: Map<string, Node>,\n prov: GsapProvenance,\n ctx: ExpandCtx,\n): Node[] {\n const block = substituteParams(cloneNode({ type: \"BlockStatement\", body: bodyStmts }), bindings);\n tagTimelineCalls(block.body, prov, ctx);\n return expandStatements(block.body, { ...ctx, depth: ctx.depth + 1 });\n}\n\nfunction inlineHelper(call: Node, ctx: ExpandCtx): Node[] {\n const fn = ctx.helpers.get(call.callee.name);\n const bindings = new Map<string, Node>();\n (fn.params ?? []).forEach((p: Node, i: number) => {\n const arg = call.arguments?.[i];\n if (arg) bindings.set(p.name, arg);\n });\n const prov: GsapProvenance = {\n kind: \"helper\",\n fn: call.callee.name,\n callSite: ++ctx.site.n,\n sourceRange: rangeOf(call),\n };\n return expandBody(fn.body.body, bindings, prov, ctx);\n}\n\nfunction assignStep(update: Node, resolve: LiteralResolver): number | undefined {\n if (update.operator === \"+=\") return asNum(resolve(update.right));\n if (update.operator === \"-=\") {\n const s = asNum(resolve(update.right));\n return s === undefined ? undefined : -s;\n }\n // `i = i + S` — the step is the right operand of the addition.\n if (update.operator === \"=\" && update.right?.type === \"BinaryExpression\") {\n return asNum(resolve(update.right.right));\n }\n return undefined;\n}\n\n/** The loop variable a `for` update clause mutates (`i++` or `i += S`), or null. */\nfunction updatedVarName(update: Node): string | null {\n if (update?.type === \"UpdateExpression\") return update.argument?.name ?? null;\n if (update?.type === \"AssignmentExpression\") return update.left?.name ?? null;\n return null;\n}\n\nfunction loopStep(update: Node, varName: string, resolve: LiteralResolver): number | undefined {\n if (updatedVarName(update) !== varName) return undefined;\n if (update.type === \"UpdateExpression\") return update.operator === \"++\" ? 1 : -1;\n return assignStep(update, resolve);\n}\n\nfunction asNum(v: unknown): number | undefined {\n return typeof v === \"number\" && Number.isFinite(v) ? v : undefined;\n}\n\nfunction loopSatisfied(op: string, x: number, end: number): boolean {\n if (op === \"<\") return x < end;\n if (op === \"<=\") return x <= end;\n if (op === \">\") return x > end;\n if (op === \">=\") return x >= end;\n return false;\n}\n\ninterface ForHeader {\n v: string;\n start: number;\n end: number;\n op: string;\n step: number;\n}\n\n/** The single `let v = <init>` of a for-loop init clause, or null. */\nfunction forInitVar(init: Node): { name: string; initExpr: Node } | null {\n if (init?.type !== \"VariableDeclaration\" || init.declarations?.length !== 1) return null;\n const d = init.declarations[0];\n return d.id?.type === \"Identifier\" ? { name: d.id.name, initExpr: d.init } : null;\n}\n\n/** Parse `for (let v = A; v <op> B; v += S)` into resolved bounds, or null if not statically bounded. */\nfunction parseForHeader(stmt: Node, resolve: LiteralResolver): ForHeader | null {\n const iv = forInitVar(stmt.init);\n const test = stmt.test;\n if (!iv || test?.type !== \"BinaryExpression\" || test.left?.name !== iv.name) return null;\n const start = asNum(resolve(iv.initExpr));\n const end = asNum(resolve(test.right));\n const step = loopStep(stmt.update, iv.name, resolve);\n if (start === undefined || end === undefined || !step) return null;\n return { v: iv.name, start, end, op: test.operator, step };\n}\n\nfunction unrollFor(stmt: Node, ctx: ExpandCtx): Node[] | null {\n const h = parseForHeader(stmt, ctx.resolve);\n if (!h) return null;\n const body = bodyStatements(stmt.body);\n const out: Node[] = [];\n const site = ++ctx.site.n;\n let iteration = 0;\n for (let x = h.start; loopSatisfied(h.op, x, h.end); x += h.step) {\n if (iteration >= MAX_ITERS) return null;\n const prov: GsapProvenance = {\n kind: \"loop\",\n callSite: site,\n iteration,\n sourceRange: rangeOf(stmt),\n };\n out.push(...expandBody(body, new Map([[h.v, numericLiteral(x)]]), prov, ctx));\n iteration++;\n }\n return out;\n}\n\nfunction forOfVarName(left: Node): string | null {\n if (left?.type === \"VariableDeclaration\") {\n const id = left.declarations?.[0]?.id;\n return id?.type === \"Identifier\" ? id.name : null;\n }\n return left?.type === \"Identifier\" ? left.name : null;\n}\n\n/** Expand `for (const el of [literal array]) {...}` and `[literal array].forEach((el, i) => {...})`. */\nfunction unrollOverArray(\n elements: Node[],\n body: Node[],\n elName: string | null,\n idxName: string | null,\n range: [number, number] | undefined,\n ctx: ExpandCtx,\n): Node[] {\n const out: Node[] = [];\n const site = ++ctx.site.n;\n elements.forEach((el, i) => {\n if (!el) return;\n const bindings = new Map<string, Node>();\n if (elName) bindings.set(elName, el);\n if (idxName) bindings.set(idxName, numericLiteral(i));\n const prov: GsapProvenance = { kind: \"loop\", callSite: site, iteration: i, sourceRange: range };\n out.push(...expandBody(body, bindings, prov, ctx));\n });\n return out;\n}\n\nfunction unrollForOf(stmt: Node, ctx: ExpandCtx): Node[] | null {\n if (stmt.right?.type !== \"ArrayExpression\") return null;\n const elName = forOfVarName(stmt.left);\n if (!elName) return null;\n return unrollOverArray(\n stmt.right.elements ?? [],\n bodyStatements(stmt.body),\n elName,\n null,\n rangeOf(stmt),\n ctx,\n );\n}\n\n/** The (element, index) param names of a callback, or null if either is non-Identifier. */\nfunction callbackParamNames(cb: Node): { el: string | null; idx: string | null } | null {\n const names: Array<string | null> = [];\n for (const p of [cb.params?.[0], cb.params?.[1]]) {\n if (!p) names.push(null);\n else if (p.type !== \"Identifier\") return null;\n else names.push(p.name);\n }\n return { el: names[0]!, idx: names[1]! };\n}\n\n/** True for `[arrayLiteral].forEach` member callees. */\nfunction isForEachCall(callee: Node): boolean {\n return (\n callee?.type === \"MemberExpression\" &&\n callee.property?.name === \"forEach\" &&\n callee.object?.type === \"ArrayExpression\"\n );\n}\n\n/** The element array + callback of `[...].forEach(cb)`, or null. */\nfunction forEachTarget(call: Node): { elements: Node[]; cb: Node } | null {\n if (!isForEachCall(call.callee)) return null;\n const cb = call.arguments?.[0];\n return isFunctionNode(cb) ? { elements: call.callee.object.elements ?? [], cb } : null;\n}\n\nfunction unrollForEach(call: Node, ctx: ExpandCtx): Node[] | null {\n const target = forEachTarget(call);\n if (!target) return null;\n const params = callbackParamNames(target.cb);\n if (!params) return null;\n return unrollOverArray(\n target.elements,\n bodyStatements(target.cb.body),\n params.el,\n params.idx,\n rangeOf(call),\n ctx,\n );\n}\n\nfunction expandCall(call: Node, ctx: ExpandCtx): Node[] | null {\n if (call.callee?.type === \"Identifier\" && ctx.helpers.has(call.callee.name)) {\n return inlineHelper(call, ctx);\n }\n return unrollForEach(call, ctx);\n}\n\nfunction expandStatement(stmt: Node, ctx: ExpandCtx): Node[] | null {\n if (ctx.depth >= MAX_DEPTH) return null;\n if (stmt.type === \"ForStatement\") return unrollFor(stmt, ctx);\n if (stmt.type === \"ForOfStatement\") return unrollForOf(stmt, ctx);\n if (stmt.type === \"ExpressionStatement\" && stmt.expression?.type === \"CallExpression\") {\n return expandCall(stmt.expression, ctx);\n }\n return null;\n}\n\nfunction expandStatements(stmts: Node[], ctx: ExpandCtx): Node[] {\n const out: Node[] = [];\n for (const stmt of stmts) {\n const expanded = expandStatement(stmt, ctx);\n if (expanded) out.push(...expanded);\n else out.push(stmt);\n }\n return out;\n}\n\n/**\n * Rewrite the Program body so helper invocations and bounded loops that build\n * the timeline are expanded into concrete per-call / per-iteration `tl.*`\n * statements, each tagged with provenance. Mutates `ast` in place (caller owns\n * the freshly-parsed tree). Constructs it can't statically resolve are left\n * untouched, so the parser falls back to current behavior for them.\n */\nexport function inlineComputedTimelines(\n ast: Node,\n timelineVar: string,\n resolve: LiteralResolver,\n): void {\n const helpers = collectInlinableHelpers(ast, timelineVar);\n const ctx: ExpandCtx = {\n helpers,\n timelineVar,\n resolve,\n depth: 0,\n site: { n: 0 },\n order: { n: 0 },\n };\n const body = (ast.body ?? []).filter((stmt: Node) => !isHelperDecl(stmt, helpers));\n ast.body = expandStatements(body, ctx);\n}\n"],"mappings":"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","names":["GSAP_METHODS","isFunctionNode","n"]}
|
|
1
|
+
{"version":3,"sources":["../src/gsapParserAcorn.ts","../src/gsapConstants.ts","../src/gsapSerialize.ts","../src/gsapInline.ts"],"sourcesContent":["// fallow-ignore-file code-duplication\n/**\n * Browser-safe GSAP read path — acorn + acorn-walk.\n *\n * T6b oracle: produces identical ParsedGsap output to gsapParser.ts (recast).\n * Replaces recast as the shared implementation once T6d passes.\n *\n * Write path (T6c) will add magic-string splice once read parity is confirmed.\n * No Node globals, no fs, no require — safe to bundle for browser use.\n */\nimport * as acorn from \"acorn\";\nimport * as acornWalk from \"acorn-walk\";\nimport type {\n ArcPathConfig,\n GsapAnimation,\n GsapKeyframesData,\n GsapMethod,\n GsapPercentageKeyframe,\n ParsedGsap,\n} from \"./gsapSerialize.js\";\nimport { classifyTweenPropertyGroup } from \"./gsapConstants.js\";\nimport { buildArcPath } from \"./gsapSerialize.js\";\nimport { inlineComputedTimelines, readProvenance } from \"./gsapInline.js\";\n\n// Browser-safe re-exports so studio code can build arc config without importing\n// the recast parser (this acorn module is the browser-safe gsap subpath).\nexport { buildArcPath, editabilityForProvenance } from \"./gsapSerialize.js\";\nexport type {\n ArcPathConfig,\n ArcPathSegment,\n MotionPathShape,\n GsapProvenance,\n GsapProvenanceKind,\n KeyframeEditability,\n} from \"./gsapSerialize.js\";\n\nconst GSAP_METHODS = new Set<string>([\"set\", \"to\", \"from\", \"fromTo\"]);\nconst QUERY_METHODS = new Set([\"querySelector\", \"querySelectorAll\"]);\nconst ITERATION_METHODS = new Set([\"forEach\", \"map\"]);\nconst SCOPE_NODE_TYPES = new Set([\n \"Program\",\n \"FunctionDeclaration\",\n \"FunctionExpression\",\n \"ArrowFunctionExpression\",\n]);\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\ntype ScopeBindings = ReadonlyMap<string, number | string | boolean>;\n/** Per-scope element bindings: scopeNode → (variable name → selector). */\ntype TargetBindings = Map<any, Map<string, string>>;\n\n// ── Value resolution ─────────────────────────────────────────────────────────\n\n// fallow-ignore-next-line complexity\nfunction resolveNode(\n node: any,\n scope: ReadonlyMap<string, number | string | boolean>,\n): number | string | boolean | undefined {\n if (!node) return undefined;\n if (node.type === \"NumericLiteral\" || (node.type === \"Literal\" && typeof node.value === \"number\"))\n return node.value;\n if (node.type === \"StringLiteral\" || (node.type === \"Literal\" && typeof node.value === \"string\"))\n return node.value;\n if (\n node.type === \"BooleanLiteral\" ||\n (node.type === \"Literal\" && typeof node.value === \"boolean\")\n )\n return node.value;\n if (node.type === \"UnaryExpression\" && node.operator === \"-\" && node.argument) {\n const val = resolveNode(node.argument, scope);\n return typeof val === \"number\" ? -val : undefined;\n }\n if (node.type === \"BinaryExpression\") {\n const left = resolveNode(node.left, scope);\n const right = resolveNode(node.right, scope);\n if (typeof left === \"number\" && typeof right === \"number\") {\n switch (node.operator) {\n case \"+\":\n return left + right;\n case \"-\":\n return left - right;\n case \"*\":\n return left * right;\n case \"/\":\n return right !== 0 ? left / right : undefined;\n }\n }\n if (typeof left === \"string\" && node.operator === \"+\") return left + String(right ?? \"\");\n if (typeof right === \"string\" && node.operator === \"+\") return String(left ?? \"\") + right;\n }\n if (node.type === \"Identifier\" && scope.has(node.name)) {\n return scope.get(node.name);\n }\n if (node.type === \"TemplateLiteral\" && node.expressions?.length === 0) {\n return node.quasis?.[0]?.value?.cooked ?? undefined;\n }\n return undefined;\n}\n\nfunction extractLiteralValue(node: any, scope: ScopeBindings): unknown {\n return resolveNode(node, scope);\n}\n\n// ── DOM selector resolution ───────────────────────────────────────────────────\n\n// fallow-ignore-next-line complexity\nfunction selectorFromQueryCall(node: any, scope: ScopeBindings): string | null {\n if (node?.type !== \"CallExpression\") return null;\n const callee = node.callee;\n if (callee?.type !== \"MemberExpression\" || callee.property?.type !== \"Identifier\") return null;\n const method = callee.property.name;\n const argValue = resolveNode(node.arguments?.[0], scope);\n if (typeof argValue !== \"string\" || argValue.length === 0) return null;\n if (QUERY_METHODS.has(method) || method === \"toArray\") return argValue;\n if (method === \"getElementById\") return `#${argValue}`;\n return null;\n}\n\n// ── Ancestor-based scope helpers (replaces NodePath walking) ──────────────────\n\n/**\n * Return the nearest ancestor node whose type is in SCOPE_NODE_TYPES.\n * `ancestors` is the acorn-walk ancestor array (root→current, current is last).\n */\nfunction enclosingScopeNodeFromAncestors(ancestors: any[]): any {\n for (let i = ancestors.length - 2; i >= 0; i--) {\n const node = ancestors[i];\n if (node && SCOPE_NODE_TYPES.has(node.type)) return node;\n }\n return null;\n}\n\n/** Scope chain innermost-first, derived from the acorn-walk ancestors array. */\nfunction scopeChainFromAncestors(ancestors: any[]): any[] {\n const chain: any[] = [];\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const node = ancestors[i];\n if (node && SCOPE_NODE_TYPES.has(node.type)) chain.push(node);\n }\n return chain;\n}\n\n// ── Target bindings ───────────────────────────────────────────────────────────\n\nfunction addBinding(\n bindings: TargetBindings,\n scopeNode: any,\n name: string,\n selector: string,\n): void {\n let scoped = bindings.get(scopeNode);\n if (!scoped) {\n scoped = new Map();\n bindings.set(scopeNode, scoped);\n }\n if (!scoped.has(name)) scoped.set(name, selector);\n}\n\nfunction lookupBindingFromAncestors(\n name: string,\n ancestors: any[],\n bindings: TargetBindings,\n): string | null {\n for (const scopeNode of scopeChainFromAncestors(ancestors)) {\n const selector = bindings.get(scopeNode)?.get(name);\n if (selector !== undefined) return selector;\n }\n // Program-scope bindings are stored under null (enclosingScopeNodeFromAncestors\n // returns null when no function wrapper exists — the common case in HF scripts).\n return bindings.get(null)?.get(name) ?? null;\n}\n\nfunction isFunctionNode(node: any): boolean {\n return (\n node?.type === \"ArrowFunctionExpression\" ||\n node?.type === \"FunctionExpression\" ||\n node?.type === \"FunctionDeclaration\"\n );\n}\n\nfunction resolveCollectionSelector(\n node: any,\n ancestors: any[],\n scope: ScopeBindings,\n bindings: TargetBindings,\n): string | null {\n if (node?.type === \"Identifier\")\n return lookupBindingFromAncestors(node.name, ancestors, bindings);\n if (node?.type === \"CallExpression\") return selectorFromQueryCall(node, scope);\n return null;\n}\n\nfunction collectScopeBindings(ast: any): ScopeBindings {\n const bindings = new Map<string, number | string | boolean>();\n acornWalk.simple(ast, {\n VariableDeclarator(node: any) {\n const name = node.id?.name;\n const init = node.init;\n if (name && init) {\n const val = resolveNode(init, bindings);\n if (val !== undefined) bindings.set(name, val);\n }\n },\n });\n return bindings;\n}\n\n/**\n * Build a lexically-scoped index of element variables → selector.\n * Pass 1: direct DOM-lookup assignments.\n * Pass 2: forEach/map callback params whose collection's selector is known.\n */\nfunction collectTargetBindings(ast: any, scope: ScopeBindings): TargetBindings {\n const bindings: TargetBindings = new Map();\n\n acornWalk.ancestor(ast, {\n VariableDeclarator(node: any, _: unknown, ancestors: any[]) {\n const name = node.id?.name;\n const selector = selectorFromQueryCall(node.init, scope);\n if (name && selector !== null) {\n addBinding(bindings, enclosingScopeNodeFromAncestors(ancestors), name, selector);\n }\n },\n AssignmentExpression(node: any, _: unknown, ancestors: any[]) {\n const left = node.left;\n const selector = selectorFromQueryCall(node.right, scope);\n if (left?.type === \"Identifier\" && selector !== null) {\n addBinding(bindings, enclosingScopeNodeFromAncestors(ancestors), left.name, selector);\n }\n },\n } as any);\n\n // Pass 2: forEach/map callback params take the collection's selector.\n acornWalk.ancestor(ast, {\n // fallow-ignore-next-line complexity\n CallExpression(node: any, _: unknown, ancestors: any[]) {\n const callee = node.callee;\n if (\n callee?.type === \"MemberExpression\" &&\n callee.property?.type === \"Identifier\" &&\n ITERATION_METHODS.has(callee.property.name)\n ) {\n const collectionSelector = resolveCollectionSelector(\n callee.object,\n ancestors,\n scope,\n bindings,\n );\n const fn = node.arguments?.[0];\n const param = fn?.params?.[0];\n if (collectionSelector && param?.type === \"Identifier\" && isFunctionNode(fn)) {\n addBinding(bindings, fn, param.name, collectionSelector);\n }\n }\n },\n } as any);\n\n return bindings;\n}\n\n// fallow-ignore-next-line complexity\nfunction resolveTargetSelector(\n node: any,\n ancestors: any[],\n scope: ScopeBindings,\n bindings: TargetBindings,\n): string | null {\n if (!node) return null;\n if (node.type === \"StringLiteral\" || node.type === \"Literal\") {\n return typeof node.value === \"string\" ? node.value : null;\n }\n if (node.type === \"Identifier\") {\n return lookupBindingFromAncestors(node.name, ancestors, bindings);\n }\n if (node.type === \"CallExpression\") {\n return selectorFromQueryCall(node, scope);\n }\n if (node.type === \"ArrayExpression\") {\n const parts = node.elements\n .map((el: any) => resolveTargetSelector(el, ancestors, scope, bindings))\n .filter((s: string | null): s is string => typeof s === \"string\" && s.length > 0);\n return parts.length > 0 ? parts.join(\", \") : null;\n }\n if (node.type === \"MemberExpression\" && node.object?.type === \"Identifier\") {\n return lookupBindingFromAncestors(node.object.name, ancestors, bindings);\n }\n return null;\n}\n\n// ── ObjectExpression utilities ────────────────────────────────────────────────\n\nfunction isObjectProperty(prop: any): boolean {\n return prop?.type === \"ObjectProperty\" || prop?.type === \"Property\";\n}\n\nfunction propKeyName(prop: any): string | undefined {\n return prop?.key?.name ?? prop?.key?.value;\n}\n\nfunction findPropertyNode(varsArgNode: any, key: string): any | undefined {\n if (varsArgNode?.type !== \"ObjectExpression\") return undefined;\n for (const prop of varsArgNode.properties ?? []) {\n if (!isObjectProperty(prop)) continue;\n if (propKeyName(prop) === key) return prop.value;\n }\n return undefined;\n}\n\n/**\n * Extract raw source text for a property value — the offset-splice primitive.\n * Equivalent to `recast.print(node).code` for unmodified nodes.\n */\nfunction extractRawPropertySource(\n varsArgNode: any,\n key: string,\n source: string,\n): string | undefined {\n const node = findPropertyNode(varsArgNode, key);\n return node ? source.slice(node.start, node.end) : undefined;\n}\n\n// fallow-ignore-next-line complexity\nfunction objectExpressionToRecord(\n node: any,\n scope: ScopeBindings,\n source: string,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n if (node?.type !== \"ObjectExpression\") return result;\n for (const prop of node.properties ?? []) {\n if (!isObjectProperty(prop)) continue;\n const key = prop.key?.name ?? prop.key?.value;\n if (!key) continue;\n const resolved = resolveNode(prop.value, scope);\n if (resolved !== undefined) {\n result[key] = resolved;\n } else {\n result[key] = `__raw:${source.slice(prop.value.start, prop.value.end)}`;\n }\n }\n return result;\n}\n\n// ── Timeline detection ────────────────────────────────────────────────────────\n\nfunction isGsapTimelineCall(node: any): boolean {\n return (\n node?.type === \"CallExpression\" &&\n node.callee?.type === \"MemberExpression\" &&\n node.callee.object?.name === \"gsap\" &&\n node.callee.property?.name === \"timeline\"\n );\n}\n\ninterface TimelineDefaults {\n ease?: string;\n duration?: number;\n}\n\n// How the timeline is referred to in source. `identifier` is the canonical\n// `const tl = …` form; `member` is the inline `window.__timelines[\"scene\"] = …`\n// form, where the timeline IS the member expression (no variable name).\ntype TimelineRef = { kind: \"identifier\"; name: string } | { kind: \"member\"; node: any };\n\ninterface TimelineDetection {\n /** Identifier name for the canonical form, else null (member or none). */\n timelineVar: string | null;\n /** Structural reference: identifier OR member expression. Null when none found. */\n ref: TimelineRef | null;\n timelineCount: number;\n defaults?: TimelineDefaults;\n}\n\n/** The static string key of a member access (`window.__timelines[\"scene\"]` → \"scene\"), else null. */\nfunction staticMemberKey(node: any): string | null {\n if (!node || node.type !== \"MemberExpression\") return null;\n if (node.computed) {\n const p = node.property;\n if (p?.type === \"Literal\" && typeof p.value === \"string\") return p.value;\n return null; // computed non-string-literal key → not statically resolvable\n }\n return node.property?.type === \"Identifier\" ? node.property.name : null;\n}\n\n/** True when a member expression refers to a statically-resolvable timeline slot. */\nfunction isStaticMemberRef(node: any): boolean {\n return node?.type === \"MemberExpression\" && staticMemberKey(node) !== null;\n}\n\n/** Structural equality of two member-access nodes (object chain + static key), quote-insensitive. */\nfunction sameMemberAccess(a: any, b: any): boolean {\n if (a?.type !== \"MemberExpression\" || b?.type !== \"MemberExpression\") return false;\n if (staticMemberKey(a) !== staticMemberKey(b) || staticMemberKey(a) === null) return false;\n const ao = a.object;\n const bo = b.object;\n if (ao?.type === \"Identifier\" && bo?.type === \"Identifier\") return ao.name === bo.name;\n if (ao?.type === \"MemberExpression\" && bo?.type === \"MemberExpression\")\n return sameMemberAccess(ao, bo);\n return false;\n}\n\n/** The source string a tween call is rooted at: identifier name, or the member source as written. */\nfunction timelineRootSource(ref: TimelineRef, script: string): string {\n return ref.kind === \"identifier\" ? ref.name : script.slice(ref.node.start, ref.node.end);\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n// fallow-ignore-next-line complexity\nfunction extractTimelineDefaults(\n callNode: any,\n scope: ScopeBindings,\n): TimelineDefaults | undefined {\n const arg = callNode.arguments?.[0];\n if (!arg || arg.type !== \"ObjectExpression\") return undefined;\n const defaultsProp = arg.properties?.find(\n (p: any) => isObjectProperty(p) && propKeyName(p) === \"defaults\",\n );\n if (!defaultsProp?.value || defaultsProp.value.type !== \"ObjectExpression\") return undefined;\n const result: TimelineDefaults = {};\n for (const prop of defaultsProp.value.properties ?? []) {\n if (!isObjectProperty(prop)) continue;\n const key = propKeyName(prop);\n const val = resolveNode(prop.value, scope);\n if (key === \"ease\" && typeof val === \"string\") result.ease = val;\n if (key === \"duration\" && typeof val === \"number\") result.duration = val;\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\nfunction findTimelineVar(ast: any, scope?: ScopeBindings): TimelineDetection {\n let timelineVar: string | null = null;\n let ref: TimelineRef | null = null;\n let timelineCount = 0;\n let defaults: TimelineDefaults | undefined;\n const emptyScope: ScopeBindings = scope ?? new Map();\n\n acornWalk.simple(ast, {\n VariableDeclarator(node: any) {\n if (isGsapTimelineCall(node.init)) {\n timelineCount += 1;\n if (!ref && node.id?.type === \"Identifier\") {\n timelineVar = node.id.name;\n ref = { kind: \"identifier\", name: node.id.name };\n defaults = extractTimelineDefaults(node.init, emptyScope);\n }\n }\n },\n AssignmentExpression(node: any) {\n if (isGsapTimelineCall(node.right)) {\n timelineCount += 1;\n if (!ref) {\n const left = node.left;\n if (left?.type === \"Identifier\") {\n timelineVar = left.name;\n ref = { kind: \"identifier\", name: left.name };\n defaults = extractTimelineDefaults(node.right, emptyScope);\n } else if (isStaticMemberRef(left)) {\n // Inline form: `window.__timelines[\"scene\"] = gsap.timeline(...)`.\n ref = { kind: \"member\", node: left };\n defaults = extractTimelineDefaults(node.right, emptyScope);\n }\n }\n }\n },\n });\n\n return { timelineVar, ref, timelineCount, defaults };\n}\n\n// ── Tween call collection ─────────────────────────────────────────────────────\n\n/** Keys stored on dedicated GsapAnimation fields (not in properties/extras). */\nconst BUILTIN_VAR_KEYS = new Set([\"duration\", \"ease\", \"delay\"]);\n/** Keys never preserved (callbacks / advanced patterns). */\nconst DROPPED_VAR_KEYS = new Set([\"onComplete\", \"onStart\", \"onUpdate\", \"onRepeat\"]);\n/** Keys that go in `extras` — non-editable GSAP config that must survive round-trips. */\nconst EXTRAS_KEYS = new Set([\n \"stagger\",\n \"yoyo\",\n \"repeat\",\n \"repeatDelay\",\n \"snap\",\n \"overwrite\",\n \"immediateRender\",\n]);\n\nexport interface TweenCallInfo {\n node: any;\n /** acorn-walk ancestor array at the call site (root→call, call is last). */\n ancestors: any[];\n method: GsapMethod;\n selector: string;\n varsArg: any;\n fromArg?: any;\n positionArg?: any;\n /** True for a base `gsap.set(...)` (off-timeline) rather than `tl.set(...)`. */\n global?: boolean;\n}\n\n/** True when the callee chain is rooted at the timeline reference (identifier or member). */\nfunction isTimelineRootedCall(callNode: any, ref: TimelineRef): boolean {\n let obj = callNode.callee?.object;\n while (obj?.type === \"CallExpression\") {\n obj = obj.callee?.object;\n }\n if (ref.kind === \"identifier\") return obj?.type === \"Identifier\" && obj.name === ref.name;\n return sameMemberAccess(obj, ref.node);\n}\n\n/**\n * Pre-order recursive walk for tween collection.\n *\n * acorn-walk is POST-order (visitor fires after children), which reverses\n * chained calls vs recast.types.visit (PRE-order). We need pre-order to\n * match the golden ordering where the outermost chained call appears first.\n */\nfunction findAllTweenCalls(\n ast: any,\n ref: TimelineRef,\n scope: ScopeBindings,\n targetBindings: TargetBindings,\n): TweenCallInfo[] {\n const results: TweenCallInfo[] = [];\n\n // fallow-ignore-next-line complexity\n function visit(node: any, ancestors: readonly any[]): void {\n if (!node || typeof node !== \"object\") return;\n const nodeAncestors = [...ancestors, node];\n\n // Fire BEFORE children (pre-order) so chained outer calls come first.\n if (node.type === \"CallExpression\") {\n const callee = node.callee;\n // A base `gsap.set(\"#sel\", props)` is an off-timeline static hold — parse it as\n // an editable global `set` so a static value round-trips and re-edits in place.\n // STRING-LITERAL selectors only: variable-target holds stay surrounding source.\n const gsapSetArg = node.arguments?.[0];\n const isGlobalSet =\n callee?.type === \"MemberExpression\" &&\n callee.object?.type === \"Identifier\" &&\n callee.object.name === \"gsap\" &&\n callee.property?.type === \"Identifier\" &&\n callee.property.name === \"set\" &&\n (gsapSetArg?.type === \"StringLiteral\" ||\n (gsapSetArg?.type === \"Literal\" && typeof gsapSetArg.value === \"string\"));\n if (\n callee?.type === \"MemberExpression\" &&\n callee.property?.type === \"Identifier\" &&\n (isTimelineRootedCall(node, ref) || isGlobalSet) &&\n GSAP_METHODS.has(callee.property.name)\n ) {\n const method = callee.property.name;\n const args = node.arguments;\n const selectorValue =\n args.length >= 1\n ? (resolveTargetSelector(args[0], nodeAncestors, scope, targetBindings) ??\n \"__unresolved__\")\n : \"__unresolved__\";\n\n if (method === \"fromTo\" && args.length >= 3) {\n results.push({\n node,\n ancestors: nodeAncestors,\n method: \"fromTo\",\n selector: selectorValue,\n fromArg: args[1],\n varsArg: args[2],\n positionArg: args[3],\n });\n } else if (method !== \"fromTo\" && args.length >= 2) {\n results.push({\n node,\n ancestors: nodeAncestors,\n method: method as GsapMethod,\n selector: selectorValue,\n varsArg: args[1],\n positionArg: args[2],\n ...(isGlobalSet ? { global: true } : {}),\n });\n }\n }\n }\n\n // Traverse children. Object.keys preserves insertion order, so callee\n // comes before arguments in acorn's CallExpression nodes.\n for (const key of Object.keys(node)) {\n if (key === \"type\" || key === \"start\" || key === \"end\" || key === \"loc\") continue;\n const child = (node as any)[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === \"object\" && item.type) visit(item, nodeAncestors);\n }\n } else if (child && typeof child === \"object\" && (child as any).type) {\n visit(child, nodeAncestors);\n }\n }\n }\n\n visit(ast, []);\n return results;\n}\n\n// ── Keyframes parsing ─────────────────────────────────────────────────────────\n\nconst PERCENTAGE_KEY_RE = /^(\\d+(?:\\.\\d+)?)%$/;\n\nfunction tryResolveStringProp(propValue: any, scope: ScopeBindings): string | undefined {\n const val = resolveNode(propValue, scope);\n return typeof val === \"string\" ? val : undefined;\n}\n\n// fallow-ignore-next-line complexity\nfunction parsePercentageKeyframes(\n node: any,\n scope: ScopeBindings,\n source: string,\n): GsapKeyframesData {\n const keyframes: GsapPercentageKeyframe[] = [];\n let ease: string | undefined;\n let easeEach: string | undefined;\n\n for (const prop of node.properties ?? []) {\n if (prop.type !== \"ObjectProperty\" && prop.type !== \"Property\") continue;\n const key = prop.key?.value ?? prop.key?.name;\n if (typeof key !== \"string\") continue;\n\n const pctMatch = PERCENTAGE_KEY_RE.exec(key);\n if (pctMatch) {\n const percentage = Number.parseFloat(pctMatch[1] ?? \"0\");\n const record = objectExpressionToRecord(prop.value, scope, source);\n const properties: Record<string, number | string> = {};\n let kfEase: string | undefined;\n for (const [k, v] of Object.entries(record)) {\n if (k === \"ease\" && typeof v === \"string\") {\n kfEase = v;\n } else if (typeof v === \"number\" || typeof v === \"string\") {\n properties[k] = v;\n }\n }\n keyframes.push({ percentage, properties, ...(kfEase ? { ease: kfEase } : {}) });\n } else if (key === \"ease\") {\n ease = tryResolveStringProp(prop.value, scope) ?? ease;\n } else if (key === \"easeEach\") {\n easeEach = tryResolveStringProp(prop.value, scope) ?? easeEach;\n }\n }\n\n keyframes.sort((a, b) => a.percentage - b.percentage);\n\n return {\n format: \"percentage\",\n keyframes,\n ...(ease ? { ease } : {}),\n ...(easeEach ? { easeEach } : {}),\n };\n}\n\n// fallow-ignore-next-line complexity\nfunction computeKeyframesTotalDuration(\n varsNode: any,\n scope: ScopeBindings,\n source: string,\n): number | undefined {\n const kfNode = (varsNode.properties ?? []).find(\n (p: any) => (p.key?.name ?? p.key?.value) === \"keyframes\",\n )?.value;\n if (!kfNode || kfNode.type !== \"ArrayExpression\") return undefined;\n let total = 0;\n for (const el of kfNode.elements ?? []) {\n if (!el || el.type !== \"ObjectExpression\") continue;\n const r = objectExpressionToRecord(el, scope, source);\n if (typeof r.duration === \"number\") total += r.duration;\n }\n return total > 0 ? total : undefined;\n}\n\n// fallow-ignore-next-line complexity\nfunction parseObjectArrayKeyframes(\n node: any,\n scope: ScopeBindings,\n source: string,\n): GsapKeyframesData {\n const elements = node.elements ?? [];\n const raw: Array<{\n properties: Record<string, number | string>;\n duration?: number;\n ease?: string;\n }> = [];\n\n for (const el of elements) {\n if (!el || el.type !== \"ObjectExpression\") continue;\n const record = objectExpressionToRecord(el, scope, source);\n const properties: Record<string, number | string> = {};\n let duration: number | undefined;\n let ease: string | undefined;\n for (const [k, v] of Object.entries(record)) {\n if (k === \"duration\" && typeof v === \"number\") {\n duration = v;\n } else if (k === \"ease\" && typeof v === \"string\") {\n ease = v;\n } else if (typeof v === \"number\" || typeof v === \"string\") {\n properties[k] = v;\n }\n }\n raw.push({ properties, duration, ease });\n }\n\n const totalDuration = raw.reduce((sum, r) => sum + (r.duration ?? 0), 0);\n const keyframes: GsapPercentageKeyframe[] = [];\n\n if (totalDuration > 0) {\n let cumulative = 0;\n for (const entry of raw) {\n cumulative += entry.duration ?? 0;\n const percentage = Math.round((cumulative / totalDuration) * 100);\n keyframes.push({\n percentage,\n properties: entry.properties,\n ...(entry.ease ? { ease: entry.ease } : {}),\n });\n }\n } else {\n for (let i = 0; i < raw.length; i++) {\n const entry = raw[i];\n if (!entry) continue;\n const percentage = raw.length > 1 ? Math.round((i / (raw.length - 1)) * 100) : 0;\n keyframes.push({\n percentage,\n properties: entry.properties,\n ...(entry.ease ? { ease: entry.ease } : {}),\n });\n }\n }\n\n return { format: \"object-array\", keyframes };\n}\n\n// fallow-ignore-next-line complexity\nfunction parseSimpleArrayKeyframes(node: any, scope: ScopeBindings): GsapKeyframesData {\n const arrayProps: Map<string, (number | string)[]> = new Map();\n let ease: string | undefined;\n let easeEach: string | undefined;\n\n for (const prop of node.properties ?? []) {\n if (prop.type !== \"ObjectProperty\" && prop.type !== \"Property\") continue;\n const key = prop.key?.name ?? prop.key?.value;\n if (typeof key !== \"string\") continue;\n\n if (prop.value?.type === \"ArrayExpression\") {\n const values: (number | string)[] = [];\n for (const el of prop.value.elements ?? []) {\n const val = resolveNode(el, scope);\n if (typeof val === \"number\" || typeof val === \"string\") {\n values.push(val);\n }\n }\n if (values.length > 0) arrayProps.set(key, values);\n } else if (key === \"ease\") {\n ease = tryResolveStringProp(prop.value, scope) ?? ease;\n } else if (key === \"easeEach\") {\n easeEach = tryResolveStringProp(prop.value, scope) ?? easeEach;\n }\n }\n\n const maxLen = Math.max(...[...arrayProps.values()].map((a) => a.length), 0);\n const keyframes: GsapPercentageKeyframe[] = [];\n\n for (let i = 0; i < maxLen; i++) {\n const percentage = maxLen > 1 ? Math.round((i / (maxLen - 1)) * 100) : 0;\n const properties: Record<string, number | string> = {};\n for (const [key, values] of arrayProps) {\n if (i < values.length) properties[key] = values[i] as number | string;\n }\n keyframes.push({ percentage, properties });\n }\n\n return {\n format: \"simple-array\",\n keyframes,\n ...(ease ? { ease } : {}),\n ...(easeEach ? { easeEach } : {}),\n };\n}\n\n// fallow-ignore-next-line complexity\nfunction parseKeyframesNode(\n node: any,\n scope: ScopeBindings,\n source: string,\n): GsapKeyframesData | undefined {\n if (!node) return undefined;\n\n if (node.type === \"ArrayExpression\") {\n return parseObjectArrayKeyframes(node, scope, source);\n }\n\n if (node.type !== \"ObjectExpression\") return undefined;\n\n const props = node.properties ?? [];\n let hasPercentageKey = false;\n let hasArrayValue = false;\n\n for (const prop of props) {\n if (prop.type !== \"ObjectProperty\" && prop.type !== \"Property\") continue;\n const key = prop.key?.value ?? prop.key?.name;\n if (typeof key === \"string\" && PERCENTAGE_KEY_RE.test(key)) {\n hasPercentageKey = true;\n break;\n }\n if (prop.value?.type === \"ArrayExpression\") {\n hasArrayValue = true;\n }\n }\n\n if (hasPercentageKey) return parsePercentageKeyframes(node, scope, source);\n if (hasArrayValue) return parseSimpleArrayKeyframes(node, scope);\n\n return undefined;\n}\n\n// ── MotionPath parsing ────────────────────────────────────────────────────────\n\ninterface MotionPathParseResult {\n arcPath: ArcPathConfig;\n waypoints: Array<{ x: number; y: number }>;\n}\n\n// fallow-ignore-next-line complexity\nfunction parseMotionPathNode(\n node: any,\n scope: ScopeBindings,\n source: string,\n): MotionPathParseResult | undefined {\n if (!node) return undefined;\n\n let pathNode: any;\n let autoRotate: boolean | number = false;\n let curviness = 1;\n let isCubic = false;\n\n if (node.type === \"ObjectExpression\") {\n for (const prop of node.properties ?? []) {\n if (!isObjectProperty(prop)) continue;\n const key = propKeyName(prop);\n if (key === \"path\") pathNode = prop.value;\n else if (key === \"autoRotate\") {\n const val = resolveNode(prop.value, scope);\n autoRotate = typeof val === \"number\" ? val : val === true;\n } else if (key === \"curviness\") {\n const val = resolveNode(prop.value, scope);\n if (typeof val === \"number\") curviness = val;\n } else if (key === \"type\") {\n const val = resolveNode(prop.value, scope);\n if (val === \"cubic\") isCubic = true;\n }\n }\n } else if (node.type === \"ArrayExpression\") {\n pathNode = node;\n }\n\n if (!pathNode || pathNode.type !== \"ArrayExpression\") return undefined;\n\n const elements = pathNode.elements ?? [];\n const coords: Array<{ x: number; y: number }> = [];\n for (const elem of elements) {\n if (!elem || elem.type !== \"ObjectExpression\") continue;\n const rec = objectExpressionToRecord(elem, scope, source);\n const x = typeof rec.x === \"number\" ? rec.x : undefined;\n const y = typeof rec.y === \"number\" ? rec.y : undefined;\n if (x !== undefined && y !== undefined) coords.push({ x, y });\n }\n\n return buildArcPath(coords, curviness, autoRotate, isCubic);\n}\n\n// ── Animation assembly ────────────────────────────────────────────────────────\n\n// fallow-ignore-next-line complexity\nfunction tweenCallToAnimation(\n call: TweenCallInfo,\n scope: ScopeBindings,\n source: string,\n): Omit<GsapAnimation, \"id\"> {\n const vars = objectExpressionToRecord(call.varsArg, scope, source);\n const properties: Record<string, number | string> = {};\n const extras: Record<string, unknown> = {};\n let keyframesData: GsapKeyframesData | undefined;\n let hasUnresolvedKeyframes = false;\n let motionPathResult: MotionPathParseResult | undefined;\n\n for (const [key, val] of Object.entries(vars)) {\n if (BUILTIN_VAR_KEYS.has(key)) continue;\n if (DROPPED_VAR_KEYS.has(key)) continue;\n\n if (key === \"keyframes\") {\n const kfNode = findPropertyNode(call.varsArg, \"keyframes\");\n keyframesData = parseKeyframesNode(kfNode, scope, source);\n if (!keyframesData && kfNode) hasUnresolvedKeyframes = true;\n continue;\n }\n\n if (key === \"motionPath\") {\n const mpNode = findPropertyNode(call.varsArg, \"motionPath\");\n motionPathResult = parseMotionPathNode(mpNode, scope, source);\n continue;\n }\n\n if (key === \"easeEach\") continue;\n\n if (EXTRAS_KEYS.has(key)) {\n const rawSource = extractRawPropertySource(call.varsArg, key, source);\n if (rawSource !== undefined) {\n extras[key] = `__raw:${rawSource}`;\n } else if (val !== undefined) {\n extras[key] = val;\n }\n continue;\n }\n\n if (typeof val === \"number\" || typeof val === \"string\") {\n properties[key] = val;\n }\n }\n\n if (keyframesData && typeof vars.easeEach === \"string\") {\n keyframesData.easeEach = vars.easeEach as string;\n }\n\n if (motionPathResult) {\n const { waypoints } = motionPathResult;\n if (!keyframesData) {\n const kf: GsapPercentageKeyframe[] = waypoints.map((wp, i) => ({\n percentage: waypoints.length > 1 ? Math.round((i / (waypoints.length - 1)) * 100) : 0,\n properties: { x: wp.x, y: wp.y },\n }));\n keyframesData = { format: \"percentage\", keyframes: kf };\n } else {\n const kfs = keyframesData.keyframes;\n if (kfs.length === waypoints.length) {\n for (let i = 0; i < kfs.length; i++) {\n const kf = kfs[i];\n const wp = waypoints[i];\n if (kf && wp) {\n kf.properties.x = wp.x;\n kf.properties.y = wp.y;\n }\n }\n }\n }\n }\n\n let fromProperties: Record<string, number | string> | undefined;\n if (call.method === \"fromTo\" && call.fromArg) {\n fromProperties = {};\n const fromVars = objectExpressionToRecord(call.fromArg, scope, source);\n for (const [key, val] of Object.entries(fromVars)) {\n if (typeof val === \"number\" || typeof val === \"string\") {\n fromProperties[key] = val;\n }\n }\n }\n\n const hasPositionArg = !!call.positionArg;\n const posVal = hasPositionArg ? extractLiteralValue(call.positionArg, scope) : 0;\n const position: number | string =\n typeof posVal === \"number\" ? posVal : typeof posVal === \"string\" ? posVal : 0;\n let duration = typeof vars.duration === \"number\" ? vars.duration : undefined;\n const ease = typeof vars.ease === \"string\" ? vars.ease : undefined;\n\n if (duration === undefined && keyframesData) {\n duration = computeKeyframesTotalDuration(call.varsArg, scope, source);\n }\n\n const anim: Omit<GsapAnimation, \"id\"> = {\n targetSelector: call.selector,\n method: call.method,\n position,\n properties,\n fromProperties,\n duration,\n ease,\n };\n if (!hasPositionArg) anim.implicitPosition = true;\n let group = classifyTweenPropertyGroup(properties);\n if (!group && keyframesData) {\n const kfProps: Record<string, unknown> = {};\n for (const kf of keyframesData.keyframes) {\n for (const k of Object.keys(kf.properties)) kfProps[k] = true;\n }\n group = classifyTweenPropertyGroup(kfProps);\n }\n if (group) anim.propertyGroup = group;\n if (call.global) anim.global = true;\n if (Object.keys(extras).length > 0) anim.extras = extras;\n if (keyframesData) anim.keyframes = keyframesData;\n if (motionPathResult) anim.arcPath = motionPathResult.arcPath;\n if (hasUnresolvedKeyframes) anim.hasUnresolvedKeyframes = true;\n if (call.selector === \"__unresolved__\") anim.hasUnresolvedSelector = true;\n const provenance = readProvenance(call.node);\n if (provenance) anim.provenance = provenance;\n return anim;\n}\n\n// ── Timeline position resolution ─────────────────────────────────────────────\n\nconst GSAP_DEFAULT_DURATION = 0.5;\n\n// fallow-ignore-next-line complexity\nfunction resolvePositionString(pos: string, cursor: number, prevStart: number): number | null {\n const trimmed = pos.trim();\n if (trimmed === \"\") return cursor;\n if (trimmed.startsWith(\"+=\")) {\n const n = Number.parseFloat(trimmed.slice(2));\n return Number.isFinite(n) ? cursor + n : null;\n }\n if (trimmed.startsWith(\"-=\")) {\n const n = Number.parseFloat(trimmed.slice(2));\n return Number.isFinite(n) ? cursor - n : null;\n }\n if (trimmed === \"<\") return prevStart;\n if (trimmed === \">\") return cursor;\n if (trimmed.startsWith(\"<\")) {\n const n = Number.parseFloat(trimmed.slice(1));\n return Number.isFinite(n) ? prevStart + n : null;\n }\n if (trimmed.startsWith(\">\")) {\n const n = Number.parseFloat(trimmed.slice(1));\n return Number.isFinite(n) ? cursor + n : null;\n }\n const n = Number.parseFloat(trimmed);\n return Number.isFinite(n) ? n : null;\n}\n\nfunction applyTimelineDefaults(\n anims: Omit<GsapAnimation, \"id\">[],\n defaults?: TimelineDefaults,\n): void {\n if (!defaults) return;\n for (const anim of anims) {\n if (anim.method === \"set\") continue;\n if (anim.duration === undefined && defaults.duration !== undefined) {\n anim.duration = defaults.duration;\n }\n if (anim.ease === undefined && defaults.ease !== undefined) {\n anim.ease = defaults.ease;\n }\n }\n}\n\n// fallow-ignore-next-line complexity\nfunction resolveTimelinePositions(anims: Omit<GsapAnimation, \"id\">[]): void {\n let cursor = 0;\n let prevStart = 0;\n for (const anim of anims) {\n // A global `gsap.set(...)` is off-timeline — applied once at load, not\n // sequenced on the master timeline. It carries no position arg, so the\n // cursor fallback would otherwise hand it the comp-end time. Pin it to 0\n // (its load-time start) and don't advance the cursor/prevStart.\n if (anim.method === \"set\" && anim.global) {\n anim.resolvedStart = 0;\n continue;\n }\n const duration = anim.method === \"set\" ? 0 : (anim.duration ?? GSAP_DEFAULT_DURATION);\n let start: number | null;\n\n if (anim.implicitPosition) {\n start = cursor;\n } else if (typeof anim.position === \"number\") {\n start = anim.position;\n } else if (typeof anim.position === \"string\") {\n start = resolvePositionString(anim.position, cursor, prevStart);\n } else {\n start = cursor;\n }\n\n if (start != null) {\n anim.resolvedStart = Math.max(0, start);\n prevStart = anim.resolvedStart;\n cursor = Math.max(cursor, anim.resolvedStart + duration);\n }\n }\n}\n\nfunction compareByLoc(a: TweenCallInfo, b: TweenCallInfo): number {\n const aLoc = a.node.callee?.property?.loc?.start;\n const bLoc = b.node.callee?.property?.loc?.start;\n if (!aLoc || !bLoc) return 0;\n return aLoc.line - bLoc.line || aLoc.column - bLoc.column;\n}\n\n// Inlined tweens carry a monotonic __hfOrder (clones share source loc, so loc\n// can't order them); they sort by that, after all literal (loc-ordered) tweens.\nfunction compareCallOrder(a: TweenCallInfo, b: TweenCallInfo): number {\n const ao = a.node.__hfOrder;\n const bo = b.node.__hfOrder;\n if (ao === undefined && bo === undefined) return compareByLoc(a, b);\n if (ao === undefined) return -1;\n if (bo === undefined) return 1;\n return ao - bo;\n}\n\nfunction sortBySourcePosition(calls: TweenCallInfo[]): void {\n calls.sort(compareCallOrder);\n}\n\n// ── Stable ID generation ──────────────────────────────────────────────────────\n\nfunction assignStableIds(anims: Omit<GsapAnimation, \"id\">[]): GsapAnimation[] {\n const counts = new Map<string, number>();\n return anims.map((anim) => {\n const posKey =\n typeof anim.position === \"number\"\n ? String(Math.round(anim.position * 1000))\n : String(anim.position);\n const groupSuffix = anim.propertyGroup ? `-${anim.propertyGroup}` : \"\";\n const base = `${anim.targetSelector}-${anim.method}-${posKey}${groupSuffix}`;\n const count = (counts.get(base) ?? 0) + 1;\n counts.set(base, count);\n const id = count === 1 ? base : `${base}-${count}`;\n return { ...anim, id };\n });\n}\n\n// ── Write-path internal parse ─────────────────────────────────────────────────\n\nexport interface ParsedGsapAcornForWrite {\n ast: any;\n timelineVar: string;\n hasTimeline: boolean;\n located: Array<{ id: string; call: TweenCallInfo; animation: GsapAnimation }>;\n}\n\n/**\n * Parse a GSAP script and return internal AST + call nodes for the write path.\n * Consumed by gsapWriterAcorn.ts (magic-string offset-splice).\n */\nexport function parseGsapScriptAcornForWrite(script: string): ParsedGsapAcornForWrite | null {\n try {\n const ast = acorn.parse(script, {\n ecmaVersion: \"latest\",\n sourceType: \"script\",\n locations: true,\n });\n const scope = collectScopeBindings(ast);\n const targetBindings = collectTargetBindings(ast, scope);\n const detection = findTimelineVar(ast, scope);\n const ref: TimelineRef = detection.ref ?? { kind: \"identifier\", name: \"tl\" };\n const timelineVar = timelineRootSource(ref, script);\n const calls = findAllTweenCalls(ast, ref, scope, targetBindings);\n sortBySourcePosition(calls);\n const rawAnims = calls.map((call) => tweenCallToAnimation(call, scope, script));\n applyTimelineDefaults(rawAnims, detection.defaults);\n resolveTimelinePositions(rawAnims);\n const animations = assignStableIds(rawAnims);\n const located = calls.map((call, i) => ({\n id: animations[i]!.id,\n call,\n animation: animations[i]!,\n }));\n return { ast, timelineVar, hasTimeline: detection.ref !== null, located };\n } catch {\n return null;\n }\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Browser-safe equivalent of `parseGsapScript` (gsapParser.ts).\n * Uses acorn + acorn-walk instead of recast + @babel/parser.\n */\nexport function parseGsapScriptAcorn(script: string): ParsedGsap {\n try {\n const ast = acorn.parse(script, {\n ecmaVersion: \"latest\",\n sourceType: \"script\",\n locations: true,\n });\n const scope = collectScopeBindings(ast);\n const detection = findTimelineVar(ast, scope);\n const ref: TimelineRef = detection.ref ?? { kind: \"identifier\", name: \"tl\" };\n const timelineVar = timelineRootSource(ref, script);\n // Expand helper-built / bounded-loop timelines before analysis so their\n // tweens resolve at true positions (read path only — the write path keeps\n // original source nodes). Degrades to the un-inlined AST on any failure.\n // Only the identifier form uses the helper-built pattern; inline member\n // timelines have nothing to inline, so skip (avoids mis-rooting on the member).\n if (ref.kind === \"identifier\") {\n try {\n inlineComputedTimelines(ast, timelineVar, (node) => resolveNode(node, scope));\n } catch {\n /* fall back to current behavior */\n }\n }\n const targetBindings = collectTargetBindings(ast, scope);\n const calls = findAllTweenCalls(ast, ref, scope, targetBindings);\n sortBySourcePosition(calls);\n const rawAnims = calls.map((call) => tweenCallToAnimation(call, scope, script));\n applyTimelineDefaults(rawAnims, detection.defaults);\n resolveTimelinePositions(rawAnims);\n const animations = assignStableIds(rawAnims);\n\n // Preamble = source up to and including the timeline declaration/assignment.\n // Identifier keeps the original `const|let|var <name> = …` regex (byte-stable);\n // member matches `<member source> = …`.\n const declPattern =\n ref.kind === \"identifier\"\n ? `(?:const|let|var)\\\\s+${timelineVar}\\\\s*=\\\\s*gsap\\\\.timeline\\\\s*\\\\([^)]*\\\\)\\\\s*;?`\n : `${escapeRegExp(timelineVar)}\\\\s*=\\\\s*gsap\\\\.timeline\\\\s*\\\\([^)]*\\\\)\\\\s*;?`;\n const timelineMatch = script.match(new RegExp(`^[\\\\s\\\\S]*?${declPattern}`));\n const fallbackPreamble =\n ref.kind === \"identifier\"\n ? `const ${timelineVar} = gsap.timeline({ paused: true });`\n : `${timelineVar} = gsap.timeline({ paused: true });`;\n const preamble = timelineMatch?.[0] ?? fallbackPreamble;\n\n const lastCallIdx = script.lastIndexOf(`${timelineVar}.`);\n let postamble = \"\";\n if (lastCallIdx !== -1) {\n const afterLast = script.slice(lastCallIdx);\n const endOfCall = afterLast.indexOf(\";\");\n if (endOfCall !== -1) {\n postamble = script.slice(lastCallIdx + endOfCall + 1).trim();\n }\n }\n\n const result: ParsedGsap = { animations, timelineVar, preamble, postamble };\n if (detection.timelineCount > 1) result.multipleTimelines = true;\n if (detection.timelineCount > 0 && detection.ref === null)\n result.unsupportedTimelinePattern = true;\n return result;\n } catch {\n return { animations: [], timelineVar: \"tl\", preamble: \"\", postamble: \"\" };\n }\n}\n\n// ── Label extraction (WS-C) ──────────────────────────────────────────────────\n\nexport interface GsapLabelEntry {\n name: string;\n position: number;\n}\n\n/**\n * Extract all `tl.addLabel(\"name\", position)` calls from a GSAP script.\n *\n * Returns labels in source order. Position must be a numeric literal; labels\n * with non-numeric positions (e.g. label-relative offsets) are skipped.\n *\n * Pure — no side effects, no DOM, no Date.now.\n */\nexport function extractGsapLabels(script: string): GsapLabelEntry[] {\n try {\n const ast = acorn.parse(script, {\n ecmaVersion: \"latest\",\n sourceType: \"script\",\n locations: true,\n });\n const scope = collectScopeBindings(ast);\n const detection = findTimelineVar(ast, scope);\n const ref: TimelineRef = detection.ref ?? { kind: \"identifier\", name: \"tl\" };\n\n const labels: GsapLabelEntry[] = [];\n\n acornWalk.simple(ast, {\n // fallow-ignore-next-line complexity\n ExpressionStatement(node: any) {\n const expr = node.expression;\n if (!expr || expr.type !== \"CallExpression\") return;\n const callee = expr.callee;\n // Match <timeline>.addLabel(...) for identifier or member timeline refs.\n const objMatches =\n ref.kind === \"identifier\"\n ? callee.object?.type === \"Identifier\" && callee.object.name === ref.name\n : sameMemberAccess(callee.object, ref.node);\n if (\n callee?.type !== \"MemberExpression\" ||\n !objMatches ||\n callee.property?.name !== \"addLabel\"\n )\n return;\n const args = expr.arguments ?? [];\n const nameNode = args[0];\n const posNode = args[1];\n if (nameNode?.type !== \"Literal\" || typeof nameNode.value !== \"string\") return;\n if (!posNode) return;\n const pos = resolveNode(posNode, scope);\n if (typeof pos !== \"number\" || !Number.isFinite(pos)) return;\n labels.push({ name: nameNode.value, position: pos });\n },\n });\n\n return labels;\n } catch {\n // Labels are best-effort/supplementary, not load-bearing — a malformed or\n // unparseable script yields no labels rather than failing the caller.\n return [];\n }\n}\n","/**\n * GSAP property and ease constants.\n *\n * Extracted into a standalone module so browser code can import them\n * without pulling in gsapParser (which depends on recast / @babel/parser).\n */\n\nexport const SUPPORTED_PROPS = [\n // 2D Transforms\n \"x\",\n \"y\",\n \"scale\",\n \"scaleX\",\n \"scaleY\",\n \"rotation\",\n \"skewX\",\n \"skewY\",\n // 3D Transforms\n \"z\",\n \"rotationX\",\n \"rotationY\",\n \"rotationZ\",\n \"perspective\",\n \"transformPerspective\",\n \"transformOrigin\",\n // Visibility\n \"opacity\",\n \"visibility\",\n \"autoAlpha\",\n // Dimensions\n \"width\",\n \"height\",\n // Colors\n \"color\",\n \"backgroundColor\",\n \"borderColor\",\n // Box model\n \"borderRadius\",\n // Typography\n \"fontSize\",\n \"letterSpacing\",\n // Filter & Clipping\n \"filter\",\n \"clipPath\",\n // DOM content (number counters, text roll-ups)\n \"innerText\",\n];\n\n// ── Property Groups ─────────────────────────────────────────────────────────\n// Each group maps to an independent GSAP tween so editing one property\n// (e.g. drag → x/y) never contaminates another (e.g. scale, rotation).\n\nexport type PropertyGroupName = \"position\" | \"scale\" | \"size\" | \"rotation\" | \"visual\" | \"other\";\n\nexport const PROPERTY_GROUPS: Record<PropertyGroupName, ReadonlySet<string>> = {\n position: new Set([\"x\", \"y\", \"xPercent\", \"yPercent\"]),\n scale: new Set([\"scale\", \"scaleX\", \"scaleY\"]),\n size: new Set([\"width\", \"height\"]),\n rotation: new Set([\"rotation\", \"skewX\", \"skewY\"]),\n visual: new Set([\"opacity\", \"autoAlpha\"]),\n other: new Set<string>(),\n};\n\nconst PROP_TO_GROUP = new Map<string, PropertyGroupName>();\nfor (const [group, props] of Object.entries(PROPERTY_GROUPS) as [\n PropertyGroupName,\n ReadonlySet<string>,\n][]) {\n for (const p of props) PROP_TO_GROUP.set(p, group);\n}\n\nexport function classifyPropertyGroup(prop: string): PropertyGroupName {\n return PROP_TO_GROUP.get(prop) ?? \"other\";\n}\n\nexport function classifyTweenPropertyGroup(\n properties: Record<string, unknown>,\n): PropertyGroupName | undefined {\n const groups = new Set<PropertyGroupName>();\n for (const key of Object.keys(properties)) {\n // transformOrigin is a modifier; `_auto` is Studio's internal endpoint marker;\n // `data` is GSAP-reserved (carries the Studio hold-set tag). None is an animated\n // property, so none should affect the group.\n if (key === \"transformOrigin\" || key === \"_auto\" || key === \"data\") continue;\n const g = classifyPropertyGroup(key);\n groups.add(g);\n }\n if (groups.size === 1) return groups.values().next().value;\n return undefined;\n}\n\nexport const SUPPORTED_EASES = [\n \"none\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"spring-gentle\",\n \"spring-bouncy\",\n \"spring-stiff\",\n \"spring-wobbly\",\n \"spring-heavy\",\n \"steps(1)\",\n];\n","/**\n * Recast-free GSAP helpers: serialization, keyframe<->animation conversion,\n * validation, and shared types.\n *\n * This module MUST NOT import recast / @babel/parser. It is part of the\n * isomorphic core layer that the barrel and browser code depend on. AST\n * parsing of GSAP source lives in the Node-only `./gsapParser` module.\n */\nimport type { Keyframe, KeyframeProperties, ValidationResult } from \"./types.js\";\nimport type { PropertyGroupName } from \"./gsapConstants\";\n\nexport type GsapMethod = \"set\" | \"to\" | \"from\" | \"fromTo\";\n\n/** How a tween was constructed in source — drives display classification and editability. */\nexport type GsapProvenanceKind = \"literal\" | \"helper\" | \"loop\" | \"runtime-dynamic\";\n\n/**\n * Origin of a parsed tween. `literal` tweens map 1:1 to a source call and edit\n * directly; `helper`/`loop` tweens are expanded from a reused construct (unroll\n * to edit); `runtime-dynamic` tweens come from live introspection (override to\n * edit). Absent provenance is treated as `literal`.\n */\nexport interface GsapProvenance {\n kind: GsapProvenanceKind;\n /** Helper function name (kind === \"helper\"). */\n fn?: string;\n /** 1-based ordinal of the originating call site / loop construct in source order. */\n callSite?: number;\n /** 0-based iteration index (kind === \"loop\"). */\n iteration?: number;\n /** Source offset [start, end] of the originating call/loop, when known. */\n sourceRange?: [number, number];\n}\n\n/** How a tween's keyframes can be edited, derived from its provenance. */\nexport type KeyframeEditability = \"direct\" | \"unroll\" | \"source\";\n\n/**\n * Map provenance to an editing strategy:\n * - `direct` — literal tween, maps 1:1 to source; edit in place.\n * - `unroll` — helper/loop expansion; unroll to literal tweens, then edit.\n * - `source` — runtime-dynamic value; not statically editable, edit the code.\n */\nexport function editabilityForProvenance(provenance?: GsapProvenance): KeyframeEditability {\n if (!provenance || provenance.kind === \"literal\") return \"direct\";\n if (provenance.kind === \"runtime-dynamic\") return \"source\";\n return \"unroll\";\n}\n\nexport interface GsapAnimation {\n id: string;\n targetSelector: string;\n method: GsapMethod;\n position: number | string;\n properties: Record<string, number | string>;\n fromProperties?: Record<string, number | string>;\n duration?: number;\n ease?: string;\n /** Non-editable GSAP config (stagger, yoyo, repeat, etc.) preserved for round-trips. */\n extras?: Record<string, unknown>;\n /** Native GSAP keyframes data — present when the tween uses keyframes: { ... }. */\n keyframes?: GsapKeyframesData;\n /** Arc motion path config — present when the tween uses motionPath for curved position interpolation. */\n arcPath?: ArcPathConfig;\n /** True when the tween has a `keyframes` property that couldn't be statically resolved (dynamic). */\n hasUnresolvedKeyframes?: boolean;\n /** True when the tween's target selector couldn't be statically resolved (dynamic). */\n hasUnresolvedSelector?: boolean;\n /** Absolute start time computed by walking the timeline chain (handles +=, -=, <, >, labels). */\n resolvedStart?: number;\n /** True when no position arg was authored — the tween is sequentially placed by GSAP. */\n implicitPosition?: boolean;\n /** Which property group this tween belongs to (position, scale, size, rotation, visual, other).\n * Undefined for legacy mixed tweens that bundle multiple groups. */\n propertyGroup?: PropertyGroupName;\n /** True for a base `gsap.set(...)` (a static hold that runs immediately, OFF the\n * timeline) rather than `tl.set(...)`. Carries no timeline position and shows no\n * keyframe marker — used to persist a static value (e.g. a 3D transform) without\n * introducing a 0% keyframe. */\n global?: boolean;\n /** How this tween was constructed in source. Absent ⇒ literal. */\n provenance?: GsapProvenance;\n}\n\nexport interface GsapPercentageKeyframe {\n percentage: number;\n properties: Record<string, number | string>;\n ease?: string;\n}\n\nexport type GsapKeyframeFormat = \"percentage\" | \"object-array\" | \"simple-array\";\n\nexport interface GsapKeyframesData {\n format: GsapKeyframeFormat;\n keyframes: GsapPercentageKeyframe[];\n ease?: string;\n easeEach?: string;\n}\n\nexport interface ArcPathSegment {\n curviness: number;\n cp1?: { x: number; y: number };\n cp2?: { x: number; y: number };\n}\n\nexport interface ArcPathConfig {\n enabled: boolean;\n autoRotate: boolean | number;\n segments: ArcPathSegment[];\n}\n\nexport interface MotionPathShape {\n arcPath: ArcPathConfig;\n waypoints: Array<{ x: number; y: number }>;\n}\n\n/**\n * Build arcPath segments + waypoints from resolved path coordinates. Shared by\n * the AST parser (coords from literal nodes) and the runtime scanner (coords\n * from a live `vars.motionPath`), so both produce identical arc config.\n */\nexport function buildArcPath(\n coords: Array<{ x: number; y: number }>,\n curviness: number,\n autoRotate: boolean | number,\n isCubic: boolean,\n): MotionPathShape | undefined {\n const first = coords[0];\n if (coords.length < 2 || !first) return undefined;\n const segments: ArcPathSegment[] = [];\n let waypoints: Array<{ x: number; y: number }>;\n if (isCubic && coords.length >= 4) {\n // coords are [anchor, cp1, cp2, anchor, cp1, cp2, anchor, ...].\n waypoints = [first];\n for (let i = 1; i + 2 < coords.length; i += 3) {\n const cp1 = coords[i];\n const cp2 = coords[i + 1];\n const anchor = coords[i + 2];\n if (!cp1 || !cp2 || !anchor) continue;\n waypoints.push(anchor);\n segments.push({ curviness, cp1, cp2 });\n }\n } else {\n waypoints = coords;\n for (let i = 0; i < waypoints.length - 1; i++) segments.push({ curviness });\n }\n return { arcPath: { enabled: true, autoRotate, segments }, waypoints };\n}\n\nexport interface ParsedGsap {\n animations: GsapAnimation[];\n timelineVar: string;\n preamble: string;\n postamble: string;\n multipleTimelines?: boolean;\n unsupportedTimelinePattern?: boolean;\n}\n\nexport { SUPPORTED_PROPS, SUPPORTED_EASES } from \"./gsapConstants\";\n\n// ── Split-animation types (used by gsapWriterAcorn) ─────────────────────────\n\nexport interface SplitAnimationsOptions {\n originalId: string;\n newId: string;\n splitTime: number;\n elementStart: number;\n elementDuration: number;\n}\n\nexport interface SplitAnimationsResult {\n script: string;\n /** Non-ID-selector animations that the engine cannot safely retarget. */\n skippedSelectors: string[];\n}\n\n// ── Serialization ───────────────────────────────────────────────────────────\n\nexport function serializeGsapAnimations(\n animations: GsapAnimation[],\n timelineVar = \"tl\",\n options?: { includeMediaSync?: boolean; preamble?: string; postamble?: string },\n): string {\n const sorted = [...animations].sort((a, b) => {\n const aNum =\n a.resolvedStart ?? (typeof a.position === \"number\" ? a.position : Number.MAX_SAFE_INTEGER);\n const bNum =\n b.resolvedStart ?? (typeof b.position === \"number\" ? b.position : Number.MAX_SAFE_INTEGER);\n return aNum - bNum;\n });\n // fallow-ignore-next-line complexity\n const lines = sorted.map((anim) => {\n const selector = `\"${anim.targetSelector}\"`;\n const props: Record<string, number | string> = { ...anim.properties };\n if (anim.duration !== undefined) props.duration = anim.duration;\n if (anim.ease) props.ease = anim.ease;\n let propsStr = serializeObject(props);\n if (anim.extras && Object.keys(anim.extras).length > 0) {\n const extrasStr = serializeExtras(anim.extras);\n if (Object.keys(props).length === 0) {\n propsStr = `{ ${extrasStr} }`;\n } else {\n // Insert extras before the closing brace\n propsStr = propsStr.slice(0, -2) + `, ${extrasStr} }`;\n }\n }\n const posStr = typeof anim.position === \"string\" ? `\"${anim.position}\"` : anim.position;\n switch (anim.method) {\n case \"set\":\n // A global set is a base `gsap.set` — off the timeline, no position arg.\n return anim.global\n ? ` gsap.set(${selector}, ${propsStr});`\n : ` ${timelineVar}.set(${selector}, ${propsStr}, ${posStr});`;\n case \"to\":\n return ` ${timelineVar}.to(${selector}, ${propsStr}, ${posStr});`;\n case \"from\":\n return ` ${timelineVar}.from(${selector}, ${propsStr}, ${posStr});`;\n case \"fromTo\": {\n const fromStr = serializeObject(anim.fromProperties || {});\n return ` ${timelineVar}.fromTo(${selector}, ${fromStr}, ${propsStr}, ${posStr});`;\n }\n }\n });\n\n let mediaSync = \"\";\n if (options?.includeMediaSync) {\n mediaSync = `\n ${timelineVar}.eventCallback(\"onUpdate\", function() {\n const time = ${timelineVar}.time();\n document.querySelectorAll(\"video[data-start], audio[data-start]\").forEach(function(media) {\n const start = parseFloat(media.dataset.start);\n const end = parseFloat(media.dataset.end) || Infinity;\n const mediaTime = time - start;\n if (time >= start && time < end) {\n if (Math.abs(media.currentTime - mediaTime) > 0.1) {\n media.currentTime = mediaTime;\n }\n if (media.paused && !${timelineVar}.paused()) {\n media.play().catch(function() {});\n }\n } else if (!media.paused) {\n media.pause();\n }\n });\n });`;\n }\n\n const preamble = options?.preamble || `const ${timelineVar} = gsap.timeline({ paused: true });`;\n const postamble = options?.postamble ? `\\n ${options.postamble}` : \"\";\n\n return `\n ${preamble}\n${lines.join(\"\\n\")}${mediaSync}${postamble}\n `;\n}\n\nexport function serializeValue(value: unknown): string {\n if (typeof value === \"string\" && value.startsWith(\"__raw:\")) {\n return value.slice(6);\n }\n if (typeof value === \"string\") return JSON.stringify(value);\n return String(value);\n}\n\nexport function safeJsKey(key: string): string {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);\n}\n\nfunction serializeObject(obj: Record<string, number | string>): string {\n const entries = Object.entries(obj).map(([key, value]) => {\n return `${safeJsKey(key)}: ${serializeValue(value)}`;\n });\n return `{ ${entries.join(\", \")} }`;\n}\n\nfunction serializeExtras(extras: Record<string, unknown>): string {\n return Object.entries(extras)\n .map(([key, value]) => {\n return `${safeJsKey(key)}: ${serializeValue(value)}`;\n })\n .join(\", \");\n}\n\n// ── Element filtering ─────────────────────────────────────────────────────────\n\n/**\n * Filter animations to those targeting `#<elementId>` (id-only match). For the\n * studio panel's id-OR-selector matching, see `getAnimationsForElement` in\n * `useGsapTweenCache.ts` — distinct on purpose, hence the distinct name.\n */\nexport function getAnimationsForElementId(\n animations: GsapAnimation[],\n elementId: string,\n): GsapAnimation[] {\n const selector = `#${elementId}`;\n return animations.filter((a) => a.targetSelector === selector);\n}\n\n// ── Validation (regex-based, no AST needed) ─────────────────────────────────\n\nconst FORBIDDEN_GSAP_PATTERNS: Array<{ pattern: RegExp; message: string }> = [\n { pattern: /\\.call\\s*\\(/, message: \"call() method not allowed\" },\n { pattern: /\\.add\\s*\\(/, message: \"add() method not allowed\" },\n { pattern: /\\.addPause\\s*\\(/, message: \"addPause() method not allowed\" },\n { pattern: /gsap\\.registerEffect\\s*\\(/, message: \"registerEffect() not allowed\" },\n { pattern: /ScrollTrigger/, message: \"ScrollTrigger not allowed\" },\n { pattern: /onComplete\\s*:/, message: \"onComplete callback not allowed\" },\n { pattern: /onUpdate\\s*:/, message: \"onUpdate callback not allowed\" },\n { pattern: /onStart\\s*:/, message: \"onStart callback not allowed\" },\n { pattern: /onRepeat\\s*:/, message: \"onRepeat callback not allowed\" },\n { pattern: /onReverseComplete\\s*:/, message: \"onReverseComplete callback not allowed\" },\n { pattern: /repeat\\s*:\\s*-1/, message: \"Infinite repeat (repeat: -1) not allowed\" },\n { pattern: /Math\\.random\\s*\\(/, message: \"Random values (Math.random) not allowed\" },\n { pattern: /Date\\.now\\s*\\(/, message: \"Date-dependent values (Date.now) not allowed\" },\n { pattern: /new\\s+Date\\s*\\(/, message: \"Date constructor not allowed\" },\n { pattern: /setTimeout\\s*\\(/, message: \"setTimeout not allowed\" },\n { pattern: /setInterval\\s*\\(/, message: \"setInterval not allowed\" },\n { pattern: /requestAnimationFrame\\s*\\(/, message: \"requestAnimationFrame not allowed\" },\n];\n\nexport function validateCompositionGsap(script: string): ValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n for (const { pattern, message } of FORBIDDEN_GSAP_PATTERNS) {\n if (pattern.test(script)) errors.push(message);\n }\n if (/yoyo\\s*:\\s*true/.test(script)) {\n warnings.push(\"yoyo animations may behave unexpectedly when scrubbing\");\n }\n if (/stagger\\s*:/.test(script)) {\n warnings.push(\"stagger animations may not serialize correctly\");\n }\n return { valid: errors.length === 0, errors, warnings };\n}\n\n// ── Keyframe Conversion Helpers ─────────────────────────────────────────────\n\nexport function keyframesToGsapAnimations(\n elementId: string,\n keyframes: Keyframe[],\n elementStartTime: number,\n base?: { x?: number; y?: number; scale?: number },\n): GsapAnimation[] {\n const sorted = [...keyframes].sort((a, b) => a.time - b.time);\n const animations: GsapAnimation[] = [];\n const baseX = base?.x ?? 0;\n const baseY = base?.y ?? 0;\n const baseScale = base?.scale ?? 1;\n\n // fallow-ignore-next-line complexity\n sorted.forEach((kf, i) => {\n const absoluteTime = elementStartTime + kf.time;\n const isFirst = i === 0;\n const prevKf = i > 0 ? sorted[i - 1] : null;\n const duration = prevKf ? kf.time - prevKf.time : undefined;\n const position = prevKf ? elementStartTime + prevKf.time : absoluteTime;\n\n const properties: Record<string, number | string> = {};\n for (const [key, value] of Object.entries(kf.properties)) {\n if (typeof value !== \"number\") continue;\n if (key === \"x\") properties.x = baseX + value;\n else if (key === \"y\") properties.y = baseY + value;\n else if (key === \"scale\") properties.scale = baseScale * value;\n else properties[key] = value;\n }\n\n animations.push({\n id: `${elementId}-kf-${kf.id}`,\n targetSelector: `#${elementId}`,\n method: isFirst ? \"set\" : \"to\",\n position,\n properties,\n duration: isFirst ? undefined : duration,\n ease: kf.ease,\n });\n });\n\n return animations;\n}\n\nexport function gsapAnimationsToKeyframes(\n animations: GsapAnimation[],\n elementStartTime: number,\n options?: {\n baseX?: number;\n baseY?: number;\n baseScale?: number;\n clampTimeToZero?: boolean;\n skipBaseSet?: boolean;\n },\n): Keyframe[] {\n const validMethods: GsapMethod[] = [\"set\", \"to\", \"from\", \"fromTo\"];\n const baseX = options?.baseX ?? 0;\n const baseY = options?.baseY ?? 0;\n const baseScale = options?.baseScale ?? 1;\n const clampTimeToZero = options?.clampTimeToZero ?? true;\n const skipBaseSet = options?.skipBaseSet ?? false;\n const baseTimeEpsilon = 0.001;\n const baseValueEpsilon = 0.00001;\n\n return (\n animations\n .filter(\n (a): a is GsapAnimation & { position: number } =>\n validMethods.includes(a.method) && typeof a.position === \"number\",\n )\n // fallow-ignore-next-line complexity\n .map((a) => {\n const relativeTimeRaw = a.position - elementStartTime;\n const time = clampTimeToZero ? Math.max(0, relativeTimeRaw) : relativeTimeRaw;\n\n const properties: Partial<KeyframeProperties> = {};\n for (const [key, value] of Object.entries(a.properties)) {\n if (typeof value !== \"number\") continue;\n if (key === \"x\") properties.x = value - baseX;\n else if (key === \"y\") properties.y = value - baseY;\n else if (key === \"scale\") {\n properties.scale = baseScale !== 0 ? value / baseScale : value;\n } else {\n (properties as Record<string, number>)[key] = value;\n }\n }\n\n if (\n skipBaseSet &&\n a.method === \"set\" &&\n time < baseTimeEpsilon &&\n Object.values(properties).every(\n (v) => typeof v === \"number\" && Math.abs(v) < baseValueEpsilon,\n )\n ) {\n return null;\n }\n\n return {\n id: a.id.replace(/^.*-kf-/, \"\"),\n time,\n properties: properties as KeyframeProperties,\n ease: a.ease,\n };\n })\n .filter((kf): kf is NonNullable<typeof kf> => kf !== null)\n );\n}\n\n// ── Keyframe-conversion transforms (pure; shared by recast + acorn writers) ────\n\n/**\n * CSS identity values for properties whose \"rest\" state isn't 0 — used to\n * synthesize the missing endpoint when converting a flat tween to keyframes.\n */\nconst CSS_IDENTITY: Record<string, number> = {\n opacity: 1,\n autoAlpha: 1,\n scale: 1,\n scaleX: 1,\n scaleY: 1,\n};\n\nfunction cssIdentityValue(prop: string): number {\n return CSS_IDENTITY[prop] ?? 0;\n}\n\n/** Build the identity-endpoint map for a flat tween's properties. */\nfunction buildIdentityMap(props: Record<string, number | string>): Record<string, number | string> {\n const identity: Record<string, number | string> = {};\n for (const [key, val] of Object.entries(props)) {\n if (val != null) identity[key] = typeof val === \"number\" ? cssIdentityValue(key) : val;\n }\n return identity;\n}\n\n/**\n * Resolve the 0% (from) and 100% (to) property maps for a tween being\n * converted to percentage keyframes.\n *\n * @param resolvedFromValues — Despite the \"from\" in the name (historical), these\n * are runtime-captured DOM values that override the conversion endpoint:\n * - For to(): overrides fromProps (the 0% state / where the element is now).\n * - For from(): overrides toProps (the 100% state / where the element rests).\n * - For fromTo(): merges into toProps (the 100% endpoint the user is editing).\n */\nexport function resolveConversionProps(\n anim: GsapAnimation,\n resolvedFromValues?: Record<string, number | string>,\n): { fromProps: Record<string, number | string>; toProps: Record<string, number | string> } {\n if (anim.method === \"set\") {\n // A static hold becomes a keyframed `to` whose 0% and 100% both start at the\n // set's value — the visual is unchanged until the user edits a keyframe to\n // animate it. (The caller flips the call from `set` to `to` + adds a duration.)\n return { fromProps: { ...anim.properties }, toProps: { ...anim.properties } };\n }\n if (anim.method === \"to\") {\n const identity = buildIdentityMap(anim.properties);\n const fromProps = resolvedFromValues ? { ...identity, ...resolvedFromValues } : identity;\n return { fromProps, toProps: { ...anim.properties } };\n }\n if (anim.method === \"from\") {\n const identity = buildIdentityMap(anim.properties);\n const toProps = resolvedFromValues ? { ...identity, ...resolvedFromValues } : identity;\n return { fromProps: { ...anim.properties }, toProps };\n }\n // fromTo(fromVars, toVars): anim.fromProperties = fromVars (0% state),\n // anim.properties = toVars (100% state). resolvedFromValues contains the\n // current DOM position from a drag — it represents the NEW destination, so\n // it merges into toProps (the 100% endpoint the user is editing), NOT into\n // fromProps. This is intentional and not inverted.\n const toProps = resolvedFromValues\n ? { ...anim.properties, ...resolvedFromValues }\n : { ...anim.properties };\n return { fromProps: { ...(anim.fromProperties ?? {}) }, toProps };\n}\n\n// ── Arc path serialization helpers (shared by recast + acorn writers) ─────────\n\nfunction numericXY(props: Record<string, number | string>): { x: number; y: number } | null {\n const vx = props.x;\n const vy = props.y;\n return typeof vx === \"number\" && typeof vy === \"number\" ? { x: vx, y: vy } : null;\n}\n\nexport function extractArcWaypoints(anim: GsapAnimation): Array<{ x: number; y: number }> {\n const keyframeWps = (anim.keyframes?.keyframes ?? [])\n .map((kf) => numericXY(kf.properties))\n .filter((pt): pt is { x: number; y: number } => pt !== null);\n if (keyframeWps.length >= 2) return keyframeWps;\n const propX = anim.properties.x;\n const propY = anim.properties.y;\n if (typeof propX !== \"number\" && typeof propY !== \"number\") return keyframeWps;\n const destX = typeof propX === \"number\" ? propX : 0;\n const destY = typeof propY === \"number\" ? propY : 0;\n return [\n { x: 0, y: 0 },\n { x: destX, y: destY },\n ];\n}\n\nfunction autoRotateSuffix(autoRotate: boolean | number): string {\n if (autoRotate === true) return \", autoRotate: true\";\n if (typeof autoRotate === \"number\") return `, autoRotate: ${autoRotate}`;\n return \"\";\n}\n\nfunction cubicControlPoints(\n seg: ArcPathSegment,\n wp: { x: number; y: number },\n nextWp: { x: number; y: number },\n): string[] {\n if (seg.cp1 && seg.cp2) {\n return [`{x: ${seg.cp1.x}, y: ${seg.cp1.y}}`, `{x: ${seg.cp2.x}, y: ${seg.cp2.y}}`];\n }\n const dx = nextWp.x - wp.x;\n const dy = nextWp.y - wp.y;\n const c = seg.curviness ?? 1;\n return [\n `{x: ${wp.x + dx * 0.33}, y: ${wp.y + dy * 0.33 - c * Math.abs(dx) * 0.25}}`,\n `{x: ${wp.x + dx * 0.66}, y: ${wp.y + dy * 0.66 - c * Math.abs(dx) * 0.25}}`,\n ];\n}\n\nfunction buildCubicPathEntries(\n waypoints: Array<{ x: number; y: number }>,\n segments: ArcPathSegment[],\n): string[] {\n const first = waypoints[0];\n if (!first) return [];\n const entries = [`{x: ${first.x}, y: ${first.y}}`];\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n const wp = waypoints[i];\n const nextWp = waypoints[i + 1];\n if (!seg || !wp || !nextWp) continue;\n entries.push(...cubicControlPoints(seg, wp, nextWp));\n entries.push(`{x: ${nextWp.x}, y: ${nextWp.y}}`);\n }\n return entries;\n}\n\nexport function buildMotionPathObjectCode(config: {\n waypoints: Array<{ x: number; y: number }>;\n segments: ArcPathSegment[];\n autoRotate: boolean | number;\n}): string {\n const { waypoints, segments, autoRotate } = config;\n const arSuffix = autoRotateSuffix(autoRotate);\n // GSAP's simple `path` array supports only ONE scalar `curviness` for the whole\n // path, so per-segment curviness can only be expressed in the cubic form (each\n // segment's curviness baked into its control points). Emit cubic when segments\n // carry explicit control points OR when their curviness values differ — the\n // simple branch would otherwise serialize only segments[0].curviness and drop\n // every other segment's curve.\n const hasExplicitCp = segments.some((s) => s.cp1 && s.cp2);\n const curvinessVaries = segments.some(\n (s) => (s.curviness ?? 1) !== (segments[0]?.curviness ?? 1),\n );\n if ((hasExplicitCp || curvinessVaries) && waypoints.length >= 2) {\n const pathStr = buildCubicPathEntries(waypoints, segments).join(\", \");\n return `{ path: [${pathStr}], type: \"cubic\"${arSuffix} }`;\n }\n const pathEntries = waypoints.map((wp) => `{x: ${wp.x}, y: ${wp.y}}`);\n const curviness = segments[0]?.curviness ?? 1;\n const curvPart = curviness !== 1 ? `, curviness: ${curviness}` : \"\";\n return `{ path: [${pathEntries.join(\", \")}]${curvPart}${arSuffix} }`;\n}\n","/**\n * Static evaluation for computed GSAP timelines (browser-safe, acorn/ESTree).\n *\n * The read parser resolves only literals and top-level consts, so timelines\n * built by a helper called N times or by a bounded loop collapse to position 0.\n * This module expands those constructs into a synthetic analysis AST: each\n * helper invocation and each loop iteration becomes its own concrete set of\n * `tl.*` calls, with parameters/loop-vars substituted by the call's argument\n * (or element/index) AST nodes — after which the existing parse pipeline\n * resolves positions and `motionPath` arcs unchanged.\n *\n * Substituted nodes keep their original source offsets, so downstream\n * source-slicing (raw extras, keyframes) stays correct. The substitution\n * primitives never mutate their input; `inlineComputedTimelines` rewrites the\n * Program body of the freshly-parsed AST it is handed (owned by the caller).\n */\nimport type { GsapProvenance } from \"./gsapSerialize.js\";\n\n// acorn ESTree nodes are structurally untyped; mirror gsapParserAcorn.ts.\ntype Node = any;\n\n/** Node keys that are metadata, not child AST to traverse/substitute. */\nconst SKIP_KEYS = new Set([\"type\", \"start\", \"end\", \"loc\", \"range\", \"__hfProvenance\", \"__hfOrder\"]);\n\nconst FUNCTION_TYPES = new Set([\n \"ArrowFunctionExpression\",\n \"FunctionExpression\",\n \"FunctionDeclaration\",\n]);\nconst GSAP_METHODS = new Set([\"set\", \"to\", \"from\", \"fromTo\"]);\n\n// Bounds on synthetic expansion (recursion + iteration runaway guards).\nconst MAX_DEPTH = 8;\nconst MAX_ITERS = 512;\n\nfunction isFunctionNode(node: Node): boolean {\n return !!node && FUNCTION_TYPES.has(node.type);\n}\n\nfunction isNode(x: Node): boolean {\n return !!x && typeof x === \"object\" && typeof x.type === \"string\";\n}\n\n/**\n * Apply `fn` to each child AST node, writing back its return value. Skips\n * metadata keys and key/member slots that must not be treated as values.\n * The one place array-vs-single child traversal lives, so walkers stay flat.\n */\nfunction transformChildren(node: Node, fn: (child: Node) => Node): void {\n for (const key of Object.keys(node)) {\n if (SKIP_KEYS.has(key) || isNonValueIdentifierSlot(node, key)) continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (let i = 0; i < child.length; i++) child[i] = fn(child[i]);\n } else {\n node[key] = fn(child);\n }\n }\n}\n\n/** Deep structural clone preserving `start`/`end`/`loc` (needed for source slicing). */\nexport function cloneNode<T extends Node>(node: T): T {\n return structuredClone(node);\n}\n\n// ponytail: Identifier + default + rest only. Destructured bindings (`{x}`, `[x]`)\n// aren't inlined (U2 inlines Identifier-param helpers / loop vars only), so a\n// destructuring shadow is a double-rare miss that just falls back. Add the\n// pattern cases here if that ever bites.\nfunction collectPatternNames(pattern: Node, out: Set<string>): void {\n if (pattern?.type === \"Identifier\") out.add(pattern.name);\n else if (pattern?.type === \"AssignmentPattern\") collectPatternNames(pattern.left, out);\n else if (pattern?.type === \"RestElement\") collectPatternNames(pattern.argument, out);\n}\n\n/** Every identifier name bound anywhere inside the subtree (fn params, declared vars, catch params). */\nfunction collectBoundNames(root: Node): Set<string> {\n const names = new Set<string>();\n const visit = (node: Node): Node => {\n if (!isNode(node)) return node;\n if (isFunctionNode(node)) for (const p of node.params ?? []) collectPatternNames(p, names);\n else if (node.type === \"VariableDeclarator\") collectPatternNames(node.id, names);\n else if (node.type === \"CatchClause\") collectPatternNames(node.param, names);\n transformChildren(node, visit);\n return node;\n };\n visit(root);\n return names;\n}\n\n/** A child in key/property position that must not be treated as a value identifier. */\nfunction isNonValueIdentifierSlot(node: Node, key: string): boolean {\n if (node.computed) return false;\n return (\n (node.type === \"MemberExpression\" && key === \"property\") ||\n (node.type === \"Property\" && key === \"key\")\n );\n}\n\n/**\n * Substitute bound identifiers in an already-cloned subtree, returning the\n * (possibly replaced) root. Names shadowed anywhere inside (nested function\n * params, declared vars) are dropped up front rather than tracked per scope —\n * worst case we under-substitute and the caller falls back to current behavior.\n * Never substitutes identifiers in key/member positions. Mutates the passed\n * clone in place — callers pass `cloneNode(...)`.\n */\nexport function substituteParams(node: Node, bindings: ReadonlyMap<string, Node>): Node {\n const shadowed = collectBoundNames(node);\n let effective = bindings;\n if (shadowed.size > 0) {\n effective = new Map(bindings);\n for (const name of shadowed) (effective as Map<string, Node>).delete(name);\n }\n if (effective.size === 0) return node;\n return replace(node, effective);\n}\n\nfunction replace(node: Node, bindings: ReadonlyMap<string, Node>): Node {\n if (!isNode(node)) return node;\n if (node.type === \"Identifier\" && bindings.has(node.name)) {\n return cloneNode(bindings.get(node.name));\n }\n transformChildren(node, (child) => replace(child, bindings));\n return node;\n}\n\n/** Tag a node (typically a `tl.*` CallExpression) with its construction provenance. */\nexport function tagProvenance(node: Node, provenance: GsapProvenance): Node {\n if (node && typeof node === \"object\") node.__hfProvenance = provenance;\n return node;\n}\n\n/** Read a provenance tag previously set by `tagProvenance`, if any. */\nexport function readProvenance(node: Node): GsapProvenance | undefined {\n return node?.__hfProvenance;\n}\n\n/** Synthesize a numeric `Literal` node (for loop indices, which have no source node). */\nexport function numericLiteral(value: number): Node {\n return { type: \"Literal\", value, raw: String(value) };\n}\n\n// ── Expansion engine (U2) ─────────────────────────────────────────────────────\n\n/** Resolve an expression to a literal value (top-level consts in scope, arithmetic). */\ntype LiteralResolver = (node: Node) => number | string | boolean | undefined;\n\ninterface ExpandCtx {\n helpers: Map<string, Node>;\n timelineVar: string;\n resolve: LiteralResolver;\n depth: number;\n /** Mutable source-order counter for provenance call-site ordinals. */\n site: { n: number };\n /** Mutable counter stamping expansion order onto tweens (clones share source loc). */\n order: { n: number };\n}\n\nfunction walkNodes(node: Node, fn: (n: Node) => void): void {\n if (!isNode(node)) return;\n fn(node);\n for (const key of Object.keys(node)) {\n if (SKIP_KEYS.has(key)) continue;\n const child = node[key];\n if (Array.isArray(child)) for (const c of child) walkNodes(c, fn);\n else walkNodes(child, fn);\n }\n}\n\n/** The identifier a (possibly chained) call's member expression is rooted at. */\nfunction timelineRootName(call: Node): string | null {\n let obj = call.callee?.object;\n while (obj?.type === \"CallExpression\") obj = obj.callee?.object;\n return obj?.type === \"Identifier\" ? obj.name : null;\n}\n\nfunction isTimelineRooted(call: Node, timelineVar: string): boolean {\n if (timelineRootName(call) !== timelineVar) return false;\n return (\n call.callee?.property?.type === \"Identifier\" && GSAP_METHODS.has(call.callee.property.name)\n );\n}\n\nfunction containsTimelineCall(node: Node, timelineVar: string): boolean {\n let found = false;\n walkNodes(node, (n) => {\n if (n.type === \"CallExpression\" && isTimelineRooted(n, timelineVar)) found = true;\n });\n return found;\n}\n\nfunction rangeOf(node: Node): [number, number] | undefined {\n return typeof node.start === \"number\" && typeof node.end === \"number\"\n ? [node.start, node.end]\n : undefined;\n}\n\n/** Plain identifier params + block body (shape we can inline). Timeline content checked separately. */\nfunction isShapeEligible(fn: Node): boolean {\n return (\n isFunctionNode(fn) &&\n fn.body?.type === \"BlockStatement\" &&\n !(fn.params ?? []).some((p: Node) => p.type !== \"Identifier\")\n );\n}\n\n/** True if the subtree calls any function named in `names`. */\nfunction callsAny(node: Node, names: Set<string>): boolean {\n let hit = false;\n walkNodes(node, (n) => {\n if (\n n.type === \"CallExpression\" &&\n n.callee?.type === \"Identifier\" &&\n names.has(n.callee.name)\n ) {\n hit = true;\n }\n });\n return hit;\n}\n\n/** `[name, fnNode]` if a single-declarator `const f = fn` is an inlinable-shaped helper. */\nfunction varDeclHelper(stmt: Node): [string, Node] | null {\n if (stmt.declarations?.length !== 1) return null;\n const d = stmt.declarations[0];\n return d.id?.type === \"Identifier\" && isShapeEligible(d.init) ? [d.id.name, d.init] : null;\n}\n\n/** `[name, fnNode]` if `stmt` declares an inlinable-shaped helper, else null. */\nfunction helperFromStatement(stmt: Node): [string, Node] | null {\n if (stmt.type === \"FunctionDeclaration\") {\n return stmt.id && isShapeEligible(stmt) ? [stmt.id.name, stmt] : null;\n }\n if (stmt.type === \"VariableDeclaration\") return varDeclHelper(stmt);\n return null;\n}\n\n/** Top-level functions whose shape we can inline (Identifier params + block body). */\nfunction gatherHelperCandidates(program: Node): Map<string, Node> {\n const candidates = new Map<string, Node>();\n for (const stmt of program.body ?? []) {\n const helper = helperFromStatement(stmt);\n if (helper) candidates.set(helper[0], helper[1]);\n }\n return candidates;\n}\n\n/** Names that build the timeline directly or by calling another builder (transitive closure). */\nfunction timelineBuildingNames(candidates: Map<string, Node>, timelineVar: string): Set<string> {\n const building = new Set<string>();\n for (const [name, fn] of candidates) {\n if (containsTimelineCall(fn.body, timelineVar)) building.add(name);\n }\n for (let changed = true; changed; ) {\n changed = false;\n for (const [name, fn] of candidates) {\n if (!building.has(name) && callsAny(fn.body, building)) {\n building.add(name);\n changed = true;\n }\n }\n }\n return building;\n}\n\nfunction bump(counts: Map<string, number>, key: string): void {\n counts.set(key, (counts.get(key) ?? 0) + 1);\n}\n\n/**\n * Keep only candidates safe to drop: every reference to the name is its\n * declaration or a statement-level call. (1 decl id + 1 callee id per\n * statement-level call ⇒ total occurrences with no stray uses.)\n */\nfunction safelyDroppable(program: Node, candidates: Map<string, Node>): Map<string, Node> {\n const names = new Set(candidates.keys());\n const totalIds = new Map<string, number>();\n const stmtCalls = new Map<string, number>();\n walkNodes(program, (n) => {\n if (n.type === \"Identifier\" && names.has(n.name)) bump(totalIds, n.name);\n const e = n.type === \"ExpressionStatement\" ? n.expression : undefined;\n if (\n e?.type === \"CallExpression\" &&\n e.callee?.type === \"Identifier\" &&\n names.has(e.callee.name)\n ) {\n bump(stmtCalls, e.callee.name);\n }\n });\n const safe = new Map<string, Node>();\n for (const [name, fn] of candidates) {\n if ((totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0)) safe.set(name, fn);\n }\n return safe;\n}\n\n/** Top-level timeline-building helpers that are safe to inline-and-drop. */\nfunction collectInlinableHelpers(program: Node, timelineVar: string): Map<string, Node> {\n const candidates = gatherHelperCandidates(program);\n if (candidates.size === 0) return candidates;\n const building = timelineBuildingNames(candidates, timelineVar);\n for (const name of [...candidates.keys()]) if (!building.has(name)) candidates.delete(name);\n if (candidates.size === 0) return candidates;\n return safelyDroppable(program, candidates);\n}\n\nfunction isHelperDecl(stmt: Node, helpers: Map<string, Node>): boolean {\n if (stmt.type === \"FunctionDeclaration\") return !!stmt.id && helpers.get(stmt.id.name) === stmt;\n if (stmt.type === \"VariableDeclaration\" && stmt.declarations?.length === 1) {\n const d = stmt.declarations[0];\n return d.id?.type === \"Identifier\" && helpers.get(d.id.name) === d.init;\n }\n return false;\n}\n\nfunction bodyStatements(node: Node): Node[] {\n if (node?.type === \"BlockStatement\") return node.body ?? [];\n return node ? [{ type: \"ExpressionStatement\", expression: node }] : [];\n}\n\n/** Tag this body's direct timeline tweens with provenance + a monotonic expansion-order stamp. */\nfunction tagTimelineCalls(stmts: Node[], prov: GsapProvenance, ctx: ExpandCtx): void {\n for (const stmt of stmts) {\n walkNodes(stmt, (n) => {\n if (n.type === \"CallExpression\" && isTimelineRooted(n, ctx.timelineVar)) {\n tagProvenance(n, { ...prov });\n n.__hfOrder = ctx.order.n++;\n }\n });\n }\n}\n\n/** Clone a body as one scope, substitute the bindings, tag provenance, recurse. */\nfunction expandBody(\n bodyStmts: Node[],\n bindings: Map<string, Node>,\n prov: GsapProvenance,\n ctx: ExpandCtx,\n): Node[] {\n const block = substituteParams(cloneNode({ type: \"BlockStatement\", body: bodyStmts }), bindings);\n tagTimelineCalls(block.body, prov, ctx);\n return expandStatements(block.body, { ...ctx, depth: ctx.depth + 1 });\n}\n\nfunction inlineHelper(call: Node, ctx: ExpandCtx): Node[] {\n const fn = ctx.helpers.get(call.callee.name);\n const bindings = new Map<string, Node>();\n (fn.params ?? []).forEach((p: Node, i: number) => {\n const arg = call.arguments?.[i];\n if (arg) bindings.set(p.name, arg);\n });\n const prov: GsapProvenance = {\n kind: \"helper\",\n fn: call.callee.name,\n callSite: ++ctx.site.n,\n sourceRange: rangeOf(call),\n };\n return expandBody(fn.body.body, bindings, prov, ctx);\n}\n\nfunction assignStep(update: Node, resolve: LiteralResolver): number | undefined {\n if (update.operator === \"+=\") return asNum(resolve(update.right));\n if (update.operator === \"-=\") {\n const s = asNum(resolve(update.right));\n return s === undefined ? undefined : -s;\n }\n // `i = i + S` — the step is the right operand of the addition.\n if (update.operator === \"=\" && update.right?.type === \"BinaryExpression\") {\n return asNum(resolve(update.right.right));\n }\n return undefined;\n}\n\n/** The loop variable a `for` update clause mutates (`i++` or `i += S`), or null. */\nfunction updatedVarName(update: Node): string | null {\n if (update?.type === \"UpdateExpression\") return update.argument?.name ?? null;\n if (update?.type === \"AssignmentExpression\") return update.left?.name ?? null;\n return null;\n}\n\nfunction loopStep(update: Node, varName: string, resolve: LiteralResolver): number | undefined {\n if (updatedVarName(update) !== varName) return undefined;\n if (update.type === \"UpdateExpression\") return update.operator === \"++\" ? 1 : -1;\n return assignStep(update, resolve);\n}\n\nfunction asNum(v: unknown): number | undefined {\n return typeof v === \"number\" && Number.isFinite(v) ? v : undefined;\n}\n\nfunction loopSatisfied(op: string, x: number, end: number): boolean {\n if (op === \"<\") return x < end;\n if (op === \"<=\") return x <= end;\n if (op === \">\") return x > end;\n if (op === \">=\") return x >= end;\n return false;\n}\n\ninterface ForHeader {\n v: string;\n start: number;\n end: number;\n op: string;\n step: number;\n}\n\n/** The single `let v = <init>` of a for-loop init clause, or null. */\nfunction forInitVar(init: Node): { name: string; initExpr: Node } | null {\n if (init?.type !== \"VariableDeclaration\" || init.declarations?.length !== 1) return null;\n const d = init.declarations[0];\n return d.id?.type === \"Identifier\" ? { name: d.id.name, initExpr: d.init } : null;\n}\n\n/** Parse `for (let v = A; v <op> B; v += S)` into resolved bounds, or null if not statically bounded. */\nfunction parseForHeader(stmt: Node, resolve: LiteralResolver): ForHeader | null {\n const iv = forInitVar(stmt.init);\n const test = stmt.test;\n if (!iv || test?.type !== \"BinaryExpression\" || test.left?.name !== iv.name) return null;\n const start = asNum(resolve(iv.initExpr));\n const end = asNum(resolve(test.right));\n const step = loopStep(stmt.update, iv.name, resolve);\n if (start === undefined || end === undefined || !step) return null;\n return { v: iv.name, start, end, op: test.operator, step };\n}\n\nfunction unrollFor(stmt: Node, ctx: ExpandCtx): Node[] | null {\n const h = parseForHeader(stmt, ctx.resolve);\n if (!h) return null;\n const body = bodyStatements(stmt.body);\n const out: Node[] = [];\n const site = ++ctx.site.n;\n let iteration = 0;\n for (let x = h.start; loopSatisfied(h.op, x, h.end); x += h.step) {\n if (iteration >= MAX_ITERS) return null;\n const prov: GsapProvenance = {\n kind: \"loop\",\n callSite: site,\n iteration,\n sourceRange: rangeOf(stmt),\n };\n out.push(...expandBody(body, new Map([[h.v, numericLiteral(x)]]), prov, ctx));\n iteration++;\n }\n return out;\n}\n\nfunction forOfVarName(left: Node): string | null {\n if (left?.type === \"VariableDeclaration\") {\n const id = left.declarations?.[0]?.id;\n return id?.type === \"Identifier\" ? id.name : null;\n }\n return left?.type === \"Identifier\" ? left.name : null;\n}\n\n/** Expand `for (const el of [literal array]) {...}` and `[literal array].forEach((el, i) => {...})`. */\nfunction unrollOverArray(\n elements: Node[],\n body: Node[],\n elName: string | null,\n idxName: string | null,\n range: [number, number] | undefined,\n ctx: ExpandCtx,\n): Node[] {\n const out: Node[] = [];\n const site = ++ctx.site.n;\n elements.forEach((el, i) => {\n if (!el) return;\n const bindings = new Map<string, Node>();\n if (elName) bindings.set(elName, el);\n if (idxName) bindings.set(idxName, numericLiteral(i));\n const prov: GsapProvenance = { kind: \"loop\", callSite: site, iteration: i, sourceRange: range };\n out.push(...expandBody(body, bindings, prov, ctx));\n });\n return out;\n}\n\nfunction unrollForOf(stmt: Node, ctx: ExpandCtx): Node[] | null {\n if (stmt.right?.type !== \"ArrayExpression\") return null;\n const elName = forOfVarName(stmt.left);\n if (!elName) return null;\n return unrollOverArray(\n stmt.right.elements ?? [],\n bodyStatements(stmt.body),\n elName,\n null,\n rangeOf(stmt),\n ctx,\n );\n}\n\n/** The (element, index) param names of a callback, or null if either is non-Identifier. */\nfunction callbackParamNames(cb: Node): { el: string | null; idx: string | null } | null {\n const names: Array<string | null> = [];\n for (const p of [cb.params?.[0], cb.params?.[1]]) {\n if (!p) names.push(null);\n else if (p.type !== \"Identifier\") return null;\n else names.push(p.name);\n }\n return { el: names[0]!, idx: names[1]! };\n}\n\n/** True for `[arrayLiteral].forEach` member callees. */\nfunction isForEachCall(callee: Node): boolean {\n return (\n callee?.type === \"MemberExpression\" &&\n callee.property?.name === \"forEach\" &&\n callee.object?.type === \"ArrayExpression\"\n );\n}\n\n/** The element array + callback of `[...].forEach(cb)`, or null. */\nfunction forEachTarget(call: Node): { elements: Node[]; cb: Node } | null {\n if (!isForEachCall(call.callee)) return null;\n const cb = call.arguments?.[0];\n return isFunctionNode(cb) ? { elements: call.callee.object.elements ?? [], cb } : null;\n}\n\nfunction unrollForEach(call: Node, ctx: ExpandCtx): Node[] | null {\n const target = forEachTarget(call);\n if (!target) return null;\n const params = callbackParamNames(target.cb);\n if (!params) return null;\n return unrollOverArray(\n target.elements,\n bodyStatements(target.cb.body),\n params.el,\n params.idx,\n rangeOf(call),\n ctx,\n );\n}\n\nfunction expandCall(call: Node, ctx: ExpandCtx): Node[] | null {\n if (call.callee?.type === \"Identifier\" && ctx.helpers.has(call.callee.name)) {\n return inlineHelper(call, ctx);\n }\n return unrollForEach(call, ctx);\n}\n\nfunction expandStatement(stmt: Node, ctx: ExpandCtx): Node[] | null {\n if (ctx.depth >= MAX_DEPTH) return null;\n if (stmt.type === \"ForStatement\") return unrollFor(stmt, ctx);\n if (stmt.type === \"ForOfStatement\") return unrollForOf(stmt, ctx);\n if (stmt.type === \"ExpressionStatement\" && stmt.expression?.type === \"CallExpression\") {\n return expandCall(stmt.expression, ctx);\n }\n return null;\n}\n\nfunction expandStatements(stmts: Node[], ctx: ExpandCtx): Node[] {\n const out: Node[] = [];\n for (const stmt of stmts) {\n const expanded = expandStatement(stmt, ctx);\n if (expanded) out.push(...expanded);\n else out.push(stmt);\n }\n return out;\n}\n\n/**\n * Rewrite the Program body so helper invocations and bounded loops that build\n * the timeline are expanded into concrete per-call / per-iteration `tl.*`\n * statements, each tagged with provenance. Mutates `ast` in place (caller owns\n * the freshly-parsed tree). Constructs it can't statically resolve are left\n * untouched, so the parser falls back to current behavior for them.\n */\nexport function inlineComputedTimelines(\n ast: Node,\n timelineVar: string,\n resolve: LiteralResolver,\n): void {\n const helpers = collectInlinableHelpers(ast, timelineVar);\n const ctx: ExpandCtx = {\n helpers,\n timelineVar,\n resolve,\n depth: 0,\n site: { n: 0 },\n order: { n: 0 },\n };\n const body = (ast.body ?? []).filter((stmt: Node) => !isHelperDecl(stmt, helpers));\n ast.body = expandStatements(body, ctx);\n}\n"],"mappings":"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","names":["GSAP_METHODS","isFunctionNode","n"]}
|