@a-company/atelier 0.27.2 → 0.27.4
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/{chunk-PHS7IW52.js → chunk-C5DBTHXB.js} +4 -2
- package/dist/chunk-C5DBTHXB.js.map +1 -0
- package/dist/{chunk-OKHQNXN4.js → chunk-LC7ICNMN.js} +4 -4
- package/dist/chunk-LC7ICNMN.js.map +1 -0
- package/dist/cli.cjs +12 -15
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +11 -16
- package/dist/cli.js.map +1 -1
- package/dist/{dist-3PO6F556.js → dist-6IHF7WA7.js} +2 -2
- package/dist/index.cjs +4 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/mcp.cjs +4 -2
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.js +4 -2
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-OKHQNXN4.js.map +0 -1
- package/dist/chunk-PHS7IW52.js.map +0 -1
- /package/dist/{dist-3PO6F556.js.map → dist-6IHF7WA7.js.map} +0 -0
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../math/src/easing.ts","../../math/src/spring.ts","../../math/src/lerp.ts","../../math/src/color.ts","../../math/src/path.ts","../../core/src/resolver/delta-resolver.ts","../../core/src/resolver/easing-resolver.ts","../../core/src/expressions/expression-evaluator.ts","../../core/src/resolver/frame-resolver.ts","../../core/src/validation/overlap-validator.ts","../../core/src/builder/document-builder.ts","../../core/src/units/resolve-units.ts","../../core/src/presets/preset-resolver.ts","../../core/src/state/state-machine.ts","../../core/src/templates/template-resolver.ts","../../core/src/audio/audio-timing.ts","../../canvas/src/styles.ts","../../canvas/src/apply-properties.ts","../../canvas/src/renderers/shape-renderer.ts","../../canvas/src/renderers/text-renderer.ts","../../canvas/src/renderers/image-renderer.ts","../../canvas/src/renderers/ref-renderer.ts","../../canvas/src/render-frame.ts","../../canvas/src/image-cache.ts","../src/index.ts","../src/commands/validate.ts","../../schema/src/units.ts","../../schema/src/coordinates.ts","../../schema/src/color.ts","../../schema/src/shape.ts","../../schema/src/easing.ts","../../schema/src/shadow.ts","../../schema/src/layer.ts","../../schema/src/interaction.ts","../../schema/src/delta.ts","../../schema/src/state.ts","../../schema/src/preset.ts","../../schema/src/variable.ts","../../schema/src/asset.ts","../../schema/src/document.ts","../../schema/src/validate.ts","../../schema/src/parse.ts","../src/commands/info.ts","../src/commands/still.ts","../src/commands/render.ts","../src/commands/render-pipeline.ts","../src/commands/export-svg.ts","../../svg/src/render-svg.ts","../../svg/src/svg-properties.ts","../../svg/src/svg-gradients.ts","../../svg/src/svg-shapes.ts","../../svg/src/svg-text.ts","../../svg/src/svg-filters.ts","../../svg/src/svg-clip.ts","../src/commands/export-lottie.ts","../../lottie/src/map-colors.ts","../../lottie/src/map-shapes.ts","../../lottie/src/map-easing.ts","../../lottie/src/map-keyframes.ts","../../lottie/src/map-layers.ts","../../lottie/src/warnings.ts","../../lottie/src/export-lottie.ts","../src/commands/assets.ts","../src/commands/variables.ts"],"sourcesContent":["/**\n * Linear easing — no acceleration.\n */\nexport function linear(t: number): number {\n return t;\n}\n\n/**\n * Cubic bezier easing — CSS-compatible.\n * Implements the same algorithm as CSS cubic-bezier().\n * @param x1 - first control point x\n * @param y1 - first control point y\n * @param x2 - second control point x\n * @param y2 - second control point y\n */\nexport function cubicBezier(\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): (t: number) => number {\n // Use binary search to find the parametric t value that gives us our x,\n // then compute the corresponding y. This is the standard algorithm used\n // by browsers for CSS transitions.\n\n return (t: number): number => {\n if (t <= 0) return 0;\n if (t >= 1) return 1;\n\n // Binary search for the parametric t value that gives us our x\n let lo = 0;\n let hi = 1;\n let mid: number = 0;\n\n for (let i = 0; i < 20; i++) {\n mid = (lo + hi) / 2;\n const x = sampleBezier(x1, x2, mid);\n if (Math.abs(x - t) < 1e-6) break;\n if (x < t) lo = mid;\n else hi = mid;\n }\n\n mid = (lo + hi) / 2;\n return sampleBezier(y1, y2, mid);\n };\n}\n\n/** Sample a single axis of a cubic bezier at parametric t */\nfunction sampleBezier(p1: number, p2: number, t: number): number {\n // B(t) = 3(1-t)^2*t*p1 + 3(1-t)*t^2*p2 + t^3\n return 3 * (1 - t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t;\n}\n\n/** Common CSS easing presets */\nexport const easeIn = cubicBezier(0.42, 0, 1, 1);\nexport const easeOut = cubicBezier(0, 0, 0.58, 1);\nexport const easeInOut = cubicBezier(0.42, 0, 0.58, 1);\n\n/**\n * Step easing — jumps between discrete values.\n * @param steps - number of steps\n * @param position - \"start\" or \"end\" (default \"end\")\n */\nexport function step(\n steps: number,\n position: \"start\" | \"end\" = \"end\",\n): (t: number) => number {\n return (t: number): number => {\n if (t <= 0) return position === \"start\" ? 1 / steps : 0;\n if (t >= 1) return 1;\n\n const s = Math.floor(t * steps);\n if (position === \"start\") {\n return Math.min((s + 1) / steps, 1);\n }\n return s / steps;\n };\n}\n","export interface SpringConfig {\n mass?: number; // default 1\n stiffness?: number; // default 100\n damping?: number; // default 10\n velocity?: number; // default 0\n}\n\n/**\n * Creates a spring easing function.\n * Uses damped harmonic oscillator physics.\n * Returns a function that takes t (0-1) and returns the spring value.\n *\n * The spring always goes from 0 to 1, but may overshoot.\n */\nexport function spring(config: SpringConfig = {}): (t: number) => number {\n const {\n mass = 1,\n stiffness = 100,\n damping = 10,\n velocity = 0,\n } = config;\n\n const w0 = Math.sqrt(stiffness / mass); // natural frequency\n const zeta = damping / (2 * Math.sqrt(stiffness * mass)); // damping ratio\n\n // Determine total duration to normalize t\n // We pre-calculate a reasonable duration where the spring settles\n const duration = estimateSettleTime(zeta, w0);\n\n return (t: number): number => {\n if (t <= 0) return 0;\n if (t >= 1) return 1;\n\n const time = t * duration;\n let value: number;\n\n if (zeta < 1) {\n // Underdamped\n const wd = w0 * Math.sqrt(1 - zeta * zeta);\n const A = 1;\n const B = (zeta * w0 + velocity) / wd;\n value =\n 1 -\n Math.exp(-zeta * w0 * time) *\n (A * Math.cos(wd * time) + B * Math.sin(wd * time));\n } else if (zeta === 1) {\n // Critically damped\n value = 1 - Math.exp(-w0 * time) * (1 + (w0 + velocity) * time);\n } else {\n // Overdamped\n const s1 = -w0 * (zeta - Math.sqrt(zeta * zeta - 1));\n const s2 = -w0 * (zeta + Math.sqrt(zeta * zeta - 1));\n const A = (velocity - s2) / (s1 - s2);\n const B = 1 - A;\n value = 1 - A * Math.exp(s1 * time) - B * Math.exp(s2 * time);\n }\n\n return value;\n };\n}\n\n/**\n * Estimates the time for a spring to settle within 0.1% of target.\n */\nfunction estimateSettleTime(zeta: number, w0: number): number {\n if (zeta >= 1) {\n return 10 / (zeta * w0);\n }\n // For underdamped: settling ~ -ln(0.001) / (zeta * w0)\n return Math.log(1000) / (zeta * w0);\n}\n","/**\n * Linear interpolation between two numbers.\n */\nexport function lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\n/**\n * Clamp a value between min and max.\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Interpolate between two multi-dimensional values.\n * Arrays must be the same length.\n */\nexport function lerpArray(a: number[], b: number[], t: number): number[] {\n return a.map((v, i) => lerp(v, b[i], t));\n}\n\n/**\n * Re-maps a value from one range to another.\n */\nexport function remap(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number,\n): number {\n const t = (value - inMin) / (inMax - inMin);\n return lerp(outMin, outMax, t);\n}\n","import { lerp, clamp } from \"./lerp.js\";\n\nexport interface RGBA {\n r: number; // 0-255\n g: number; // 0-255\n b: number; // 0-255\n a: number; // 0-1\n}\n\nexport interface HSLA {\n h: number; // 0-360\n s: number; // 0-100\n l: number; // 0-100\n a: number; // 0-1\n}\n\n/**\n * Parse a hex color string to RGBA.\n * Supports: #RGB, #RGBA, #RRGGBB, #RRGGBBAA\n */\nexport function hexToRgba(hex: string): RGBA {\n let h = hex.replace(\"#\", \"\");\n\n if (h.length === 3)\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2] + \"ff\";\n else if (h.length === 4)\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2] + h[3] + h[3];\n else if (h.length === 6) h = h + \"ff\";\n\n return {\n r: parseInt(h.slice(0, 2), 16),\n g: parseInt(h.slice(2, 4), 16),\n b: parseInt(h.slice(4, 6), 16),\n a: parseInt(h.slice(6, 8), 16) / 255,\n };\n}\n\n/**\n * Convert RGBA to hex string.\n */\nexport function rgbaToHex(color: RGBA): string {\n const r = clamp(Math.round(color.r), 0, 255)\n .toString(16)\n .padStart(2, \"0\");\n const g = clamp(Math.round(color.g), 0, 255)\n .toString(16)\n .padStart(2, \"0\");\n const b = clamp(Math.round(color.b), 0, 255)\n .toString(16)\n .padStart(2, \"0\");\n const a = clamp(Math.round(color.a * 255), 0, 255)\n .toString(16)\n .padStart(2, \"0\");\n return `#${r}${g}${b}${a === \"ff\" ? \"\" : a}`;\n}\n\n/**\n * Interpolate between two RGBA colors.\n */\nexport function lerpRgba(a: RGBA, b: RGBA, t: number): RGBA {\n return {\n r: lerp(a.r, b.r, t),\n g: lerp(a.g, b.g, t),\n b: lerp(a.b, b.b, t),\n a: lerp(a.a, b.a, t),\n };\n}\n\n/**\n * Convert RGBA to HSLA.\n */\nexport function rgbaToHsla(color: RGBA): HSLA {\n const r = color.r / 255;\n const g = color.g / 255;\n const b = color.b / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const d = max - min;\n const l = (max + min) / 2;\n\n let h = 0;\n let s = 0;\n\n if (d !== 0) {\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n else if (max === g) h = ((b - r) / d + 2) / 6;\n else h = ((r - g) / d + 4) / 6;\n }\n\n return { h: h * 360, s: s * 100, l: l * 100, a: color.a };\n}\n\n/**\n * Convert HSLA to RGBA.\n */\nexport function hslaToRgba(color: HSLA): RGBA {\n const h = color.h / 360;\n const s = color.s / 100;\n const l = color.l / 100;\n\n let r: number, g: number, b: number;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n r = hueToRgb(p, q, h + 1 / 3);\n g = hueToRgb(p, q, h);\n b = hueToRgb(p, q, h - 1 / 3);\n }\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n a: color.a,\n };\n}\n\nfunction hueToRgb(p: number, q: number, t: number): number {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n}\n\n/**\n * Interpolate between two HSLA colors (shortest hue path).\n */\nexport function lerpHsla(a: HSLA, b: HSLA, t: number): HSLA {\n // Handle hue wrapping — take the shortest path\n let dh = b.h - a.h;\n if (dh > 180) dh -= 360;\n if (dh < -180) dh += 360;\n\n return {\n h: (((a.h + dh * t) % 360) + 360) % 360,\n s: lerp(a.s, b.s, t),\n l: lerp(a.l, b.l, t),\n a: lerp(a.a, b.a, t),\n };\n}\n","/**\n * Path interpolation utilities for motion paths.\n * Evaluates position and tangent along a path defined by points with bezier handles.\n */\n\nexport interface PathPoint2D {\n x: number;\n y: number;\n in?: { x: number; y: number };\n out?: { x: number; y: number };\n}\n\nexport interface PathPosition {\n x: number;\n y: number;\n /** Tangent angle in degrees */\n angle: number;\n}\n\n/**\n * Compute the length of a single cubic bezier segment using subdivision.\n */\nfunction bezierSegmentLength(\n p0x: number, p0y: number,\n c0x: number, c0y: number,\n c1x: number, c1y: number,\n p1x: number, p1y: number,\n steps = 32,\n): number {\n let length = 0;\n let prevX = p0x;\n let prevY = p0y;\n for (let i = 1; i <= steps; i++) {\n const t = i / steps;\n const mt = 1 - t;\n const x = mt * mt * mt * p0x + 3 * mt * mt * t * c0x + 3 * mt * t * t * c1x + t * t * t * p1x;\n const y = mt * mt * mt * p0y + 3 * mt * mt * t * c0y + 3 * mt * t * t * c1y + t * t * t * p1y;\n const dx = x - prevX;\n const dy = y - prevY;\n length += Math.sqrt(dx * dx + dy * dy);\n prevX = x;\n prevY = y;\n }\n return length;\n}\n\n/**\n * Evaluate a cubic bezier at parameter t, returning position and tangent.\n */\nfunction evalBezier(\n p0x: number, p0y: number,\n c0x: number, c0y: number,\n c1x: number, c1y: number,\n p1x: number, p1y: number,\n t: number,\n): PathPosition {\n const mt = 1 - t;\n const x = mt * mt * mt * p0x + 3 * mt * mt * t * c0x + 3 * mt * t * t * c1x + t * t * t * p1x;\n const y = mt * mt * mt * p0y + 3 * mt * mt * t * c0y + 3 * mt * t * t * c1y + t * t * t * p1y;\n\n // Tangent (first derivative)\n const tx = 3 * mt * mt * (c0x - p0x) + 6 * mt * t * (c1x - c0x) + 3 * t * t * (p1x - c1x);\n const ty = 3 * mt * mt * (c0y - p0y) + 6 * mt * t * (c1y - c0y) + 3 * t * t * (p1y - c1y);\n\n const angle = Math.atan2(ty, tx) * (180 / Math.PI);\n\n return { x, y, angle };\n}\n\n/**\n * Build a lookup table of cumulative segment lengths for a path.\n */\nfunction buildSegmentLengths(points: PathPoint2D[], closed: boolean): number[] {\n const segCount = closed ? points.length : points.length - 1;\n const lengths: number[] = [];\n\n for (let i = 0; i < segCount; i++) {\n const p0 = points[i];\n const p1 = points[(i + 1) % points.length];\n\n const c0x = p0.x + (p0.out?.x ?? 0);\n const c0y = p0.y + (p0.out?.y ?? 0);\n const c1x = p1.x + (p1.in?.x ?? 0);\n const c1y = p1.y + (p1.in?.y ?? 0);\n\n lengths.push(bezierSegmentLength(p0.x, p0.y, c0x, c0y, c1x, c1y, p1.x, p1.y));\n }\n\n return lengths;\n}\n\n/**\n * Evaluate a point along a path at a given progress (0–1).\n * Uses arc-length parameterization for uniform speed.\n */\nexport function evaluatePathAtProgress(\n points: PathPoint2D[],\n progress: number,\n closed = false,\n): PathPosition {\n if (points.length < 2) {\n return { x: points[0]?.x ?? 0, y: points[0]?.y ?? 0, angle: 0 };\n }\n\n // Clamp progress\n const t = Math.max(0, Math.min(1, progress));\n\n const segLengths = buildSegmentLengths(points, closed);\n const totalLength = segLengths.reduce((a, b) => a + b, 0);\n\n if (totalLength === 0) {\n return { x: points[0].x, y: points[0].y, angle: 0 };\n }\n\n const targetLength = t * totalLength;\n\n // Find which segment the target length falls in\n let accumulated = 0;\n for (let i = 0; i < segLengths.length; i++) {\n const segLen = segLengths[i];\n if (accumulated + segLen >= targetLength || i === segLengths.length - 1) {\n // Progress within this segment\n const segProgress = segLen === 0 ? 0 : (targetLength - accumulated) / segLen;\n\n const p0 = points[i];\n const p1 = points[(i + 1) % points.length];\n\n const c0x = p0.x + (p0.out?.x ?? 0);\n const c0y = p0.y + (p0.out?.y ?? 0);\n const c1x = p1.x + (p1.in?.x ?? 0);\n const c1y = p1.y + (p1.in?.y ?? 0);\n\n return evalBezier(p0.x, p0.y, c0x, c0y, c1x, c1y, p1.x, p1.y, segProgress);\n }\n accumulated += segLen;\n }\n\n // Fallback (shouldn't reach here)\n const last = points[points.length - 1];\n return { x: last.x, y: last.y, angle: 0 };\n}\n","import type { Delta, FrameRange } from \"@a-company/atelier-types\";\nimport { lerp, clamp, hexToRgba, lerpRgba, rgbaToHex } from \"@a-company/atelier-math\";\nimport { resolveEasing } from \"./easing-resolver.js\";\nimport { isExpression, evaluateExpression, type ExpressionContext } from \"../expressions/expression-evaluator.js\";\n\n/**\n * Check if a frame is within a delta's range (inclusive).\n */\nexport function isFrameInRange(frame: number, range: FrameRange): boolean {\n return frame >= range[0] && frame <= range[1];\n}\n\n/**\n * Compute the progress (0-1) of a frame within a delta's range.\n */\nexport function computeProgress(frame: number, range: FrameRange): number {\n const [start, end] = range;\n if (start === end) return 1; // instantaneous\n return clamp((frame - start) / (end - start), 0, 1);\n}\n\n/**\n * Resolve a single delta's value at a given frame.\n * Returns undefined if the frame is outside the delta's range.\n * Returns the interpolated value if within range.\n *\n * If `from` or `to` is an expression object `{ expr: \"...\" }`,\n * it is evaluated with the current animation context before interpolation.\n */\nexport function resolveDeltaValue(delta: Delta, frame: number): unknown | undefined {\n if (!isFrameInRange(frame, delta.range)) {\n return undefined;\n }\n\n const progress = computeProgress(frame, delta.range);\n const easingFn = resolveEasing(delta.easing);\n const easedProgress = easingFn(progress);\n\n const exprCtx: ExpressionContext = {\n t: easedProgress,\n progress,\n frame,\n duration: delta.range[1] - delta.range[0],\n };\n\n const from = isExpression(delta.from)\n ? evaluateExpression(delta.from.expr, exprCtx)\n : delta.from;\n\n const to = isExpression(delta.to)\n ? evaluateExpression(delta.to.expr, exprCtx)\n : delta.to;\n\n return interpolateValue(from, to, easedProgress);\n}\n\n/**\n * Interpolate between two values based on eased progress.\n * Handles numbers, strings (pass-through at threshold), and nested objects.\n */\nexport function interpolateValue(from: unknown, to: unknown, t: number): unknown {\n // Number interpolation\n if (typeof from === \"number\" && typeof to === \"number\") {\n return lerp(from, to, t);\n }\n\n // Hex color interpolation\n if (typeof from === \"string\" && typeof to === \"string\") {\n if (from.startsWith(\"#\") && to.startsWith(\"#\")) {\n return rgbaToHex(lerpRgba(hexToRgba(from), hexToRgba(to), t));\n }\n // Non-color strings — snap at end\n return t >= 1 ? to : from;\n }\n\n // Boolean interpolation — snap at midpoint for frame-precise control\n if (typeof from === \"boolean\" && typeof to === \"boolean\") {\n return t >= 0.5 ? to : from;\n }\n\n // For unknown types, snap at end\n return t >= 1 ? to : from;\n}\n\n/**\n * Given multiple deltas for the SAME layer+property, find the active one\n * at a given frame and return its resolved value.\n *\n * If no delta is active at this frame, holds the `to` value of the most\n * recent completed delta (the one whose range ended most recently before\n * this frame). This prevents properties from reverting after animation ends.\n *\n * Assumes no overlaps (validated elsewhere).\n */\nexport function resolvePropertyAtFrame(\n deltas: Delta[],\n frame: number,\n): unknown | undefined {\n // Check for an active delta first\n for (const delta of deltas) {\n if (isFrameInRange(frame, delta.range)) {\n return resolveDeltaValue(delta, frame);\n }\n }\n\n // No active delta — hold the `to` value of the most recently completed delta\n let lastCompleted: Delta | undefined;\n for (const delta of deltas) {\n if (frame > delta.range[1]) {\n if (!lastCompleted || delta.range[1] > lastCompleted.range[1]) {\n lastCompleted = delta;\n }\n }\n }\n\n if (!lastCompleted) return undefined;\n\n // If the held `to` value is an expression, evaluate at t=1\n if (isExpression(lastCompleted.to)) {\n return evaluateExpression(lastCompleted.to.expr, {\n t: 1,\n progress: 1,\n frame,\n duration: lastCompleted.range[1] - lastCompleted.range[0],\n });\n }\n\n return lastCompleted.to;\n}\n","import type { Easing } from \"@a-company/atelier-types\";\nimport { linear, cubicBezier, easeIn, easeOut, easeInOut, step, spring } from \"@a-company/atelier-math\";\n\n/**\n * Converts an Easing type definition into an executable easing function.\n * Returns a function (t: number) => number where t is 0-1.\n */\nexport function resolveEasing(easing: Easing | undefined): (t: number) => number {\n if (!easing) return linear;\n\n // String presets\n if (typeof easing === \"string\") {\n switch (easing) {\n case \"ease-in\": return easeIn;\n case \"ease-out\": return easeOut;\n case \"ease-in-out\": return easeInOut;\n default: return linear;\n }\n }\n\n // Object easing definitions\n switch (easing.type) {\n case \"linear\":\n return linear;\n case \"cubic-bezier\":\n return cubicBezier(easing.x1, easing.y1, easing.x2, easing.y2);\n case \"spring\":\n return spring({\n mass: easing.mass,\n stiffness: easing.stiffness,\n damping: easing.damping,\n velocity: easing.velocity,\n });\n case \"step\":\n return step(easing.steps, easing.position);\n default:\n return linear;\n }\n}\n","/**\n * Safe recursive descent expression evaluator.\n * No eval(), no Function(), no code generation.\n *\n * Supports:\n * - Numbers: 42, 3.14, -1\n * - Operators: + - * / % **\n * - Parentheses: (expr)\n * - Math functions: sin, cos, tan, abs, min, max, floor, ceil, round, sqrt, pow, clamp, sign, log\n * - Constants: pi, tau, e\n * - Context variables: t, frame, duration, progress\n * - Comparison: <, >, <=, >=, ==, !=\n * - Ternary: condition ? trueExpr : falseExpr\n */\n\n/** Context variables available during expression evaluation */\nexport interface ExpressionContext {\n /** Eased progress 0–1 */\n t: number;\n /** Raw progress 0–1 (before easing) */\n progress: number;\n /** Current frame number */\n frame: number;\n /** Delta duration in frames */\n duration: number;\n}\n\n// ── Tokenizer ───────────────────────────────────────────────\n\ntype TokenType =\n | \"number\"\n | \"ident\"\n | \"op\"\n | \"lparen\"\n | \"rparen\"\n | \"comma\"\n | \"question\"\n | \"colon\"\n | \"compare\"\n | \"eof\";\n\ninterface Token {\n type: TokenType;\n value: string;\n}\n\nfunction tokenize(expr: string): Token[] {\n const tokens: Token[] = [];\n let i = 0;\n\n while (i < expr.length) {\n const ch = expr[i];\n\n // Whitespace\n if (ch === \" \" || ch === \"\\t\" || ch === \"\\n\" || ch === \"\\r\") {\n i++;\n continue;\n }\n\n // Numbers\n if ((ch >= \"0\" && ch <= \"9\") || ch === \".\") {\n let num = \"\";\n while (i < expr.length && ((expr[i] >= \"0\" && expr[i] <= \"9\") || expr[i] === \".\")) {\n num += expr[i++];\n }\n tokens.push({ type: \"number\", value: num });\n continue;\n }\n\n // Identifiers (variables, functions, constants)\n if ((ch >= \"a\" && ch <= \"z\") || (ch >= \"A\" && ch <= \"Z\") || ch === \"_\") {\n let id = \"\";\n while (i < expr.length && ((expr[i] >= \"a\" && expr[i] <= \"z\") || (expr[i] >= \"A\" && expr[i] <= \"Z\") || (expr[i] >= \"0\" && expr[i] <= \"9\") || expr[i] === \"_\")) {\n id += expr[i++];\n }\n tokens.push({ type: \"ident\", value: id });\n continue;\n }\n\n // Comparison operators (must check before single-char ops)\n if (ch === \"<\" || ch === \">\" || ch === \"!\" || ch === \"=\") {\n if (i + 1 < expr.length && expr[i + 1] === \"=\") {\n tokens.push({ type: \"compare\", value: ch + \"=\" });\n i += 2;\n continue;\n }\n if (ch === \"<\" || ch === \">\") {\n tokens.push({ type: \"compare\", value: ch });\n i++;\n continue;\n }\n }\n\n // Power operator\n if (ch === \"*\" && i + 1 < expr.length && expr[i + 1] === \"*\") {\n tokens.push({ type: \"op\", value: \"**\" });\n i += 2;\n continue;\n }\n\n // Operators\n if (ch === \"+\" || ch === \"-\" || ch === \"*\" || ch === \"/\" || ch === \"%\") {\n tokens.push({ type: \"op\", value: ch });\n i++;\n continue;\n }\n\n // Grouping and function calls\n if (ch === \"(\") { tokens.push({ type: \"lparen\", value: \"(\" }); i++; continue; }\n if (ch === \")\") { tokens.push({ type: \"rparen\", value: \")\" }); i++; continue; }\n if (ch === \",\") { tokens.push({ type: \"comma\", value: \",\" }); i++; continue; }\n\n // Ternary\n if (ch === \"?\") { tokens.push({ type: \"question\", value: \"?\" }); i++; continue; }\n if (ch === \":\") { tokens.push({ type: \"colon\", value: \":\" }); i++; continue; }\n\n throw new Error(`Expression: unexpected character '${ch}' at position ${i}`);\n }\n\n tokens.push({ type: \"eof\", value: \"\" });\n return tokens;\n}\n\n// ── Parser + Evaluator ──────────────────────────────────────\n\nconst CONSTANTS: Record<string, number> = {\n pi: Math.PI,\n PI: Math.PI,\n tau: Math.PI * 2,\n TAU: Math.PI * 2,\n e: Math.E,\n E: Math.E,\n};\n\nconst FUNCTIONS: Record<string, (...args: number[]) => number> = {\n sin: Math.sin,\n cos: Math.cos,\n tan: Math.tan,\n abs: Math.abs,\n floor: Math.floor,\n ceil: Math.ceil,\n round: Math.round,\n sqrt: Math.sqrt,\n sign: Math.sign,\n log: Math.log,\n min: (...args) => Math.min(...args),\n max: (...args) => Math.max(...args),\n pow: (a, b) => Math.pow(a, b),\n clamp: (v, lo, hi) => Math.min(Math.max(v, lo), hi),\n};\n\nclass Parser {\n private tokens: Token[];\n private pos = 0;\n private ctx: ExpressionContext;\n\n constructor(tokens: Token[], ctx: ExpressionContext) {\n this.tokens = tokens;\n this.ctx = ctx;\n }\n\n private peek(): Token {\n return this.tokens[this.pos];\n }\n\n private consume(expectedType?: TokenType): Token {\n const tok = this.tokens[this.pos++];\n if (expectedType && tok.type !== expectedType) {\n throw new Error(`Expression: expected ${expectedType} but got ${tok.type} '${tok.value}'`);\n }\n return tok;\n }\n\n /** Entry: ternary (lowest precedence) */\n parse(): number {\n const result = this.parseTernary();\n if (this.peek().type !== \"eof\") {\n throw new Error(`Expression: unexpected token '${this.peek().value}'`);\n }\n return result;\n }\n\n /** ternary: comparison ? expr : expr */\n private parseTernary(): number {\n const condition = this.parseComparison();\n if (this.peek().type === \"question\") {\n this.consume(); // ?\n const trueVal = this.parseTernary();\n this.consume(\"colon\"); // :\n const falseVal = this.parseTernary();\n return condition ? trueVal : falseVal;\n }\n return condition;\n }\n\n /** comparison: additive (< | > | <= | >= | == | !=) additive */\n private parseComparison(): number {\n let left = this.parseAdditive();\n while (this.peek().type === \"compare\") {\n const op = this.consume().value;\n const right = this.parseAdditive();\n switch (op) {\n case \"<\": left = left < right ? 1 : 0; break;\n case \">\": left = left > right ? 1 : 0; break;\n case \"<=\": left = left <= right ? 1 : 0; break;\n case \">=\": left = left >= right ? 1 : 0; break;\n case \"==\": left = left === right ? 1 : 0; break;\n case \"!=\": left = left !== right ? 1 : 0; break;\n }\n }\n return left;\n }\n\n /** additive: multiplicative (('+' | '-') multiplicative)* */\n private parseAdditive(): number {\n let left = this.parseMultiplicative();\n while (this.peek().type === \"op\" && (this.peek().value === \"+\" || this.peek().value === \"-\")) {\n const op = this.consume().value;\n const right = this.parseMultiplicative();\n left = op === \"+\" ? left + right : left - right;\n }\n return left;\n }\n\n /** multiplicative: power (('*' | '/' | '%') power)* */\n private parseMultiplicative(): number {\n let left = this.parsePower();\n while (this.peek().type === \"op\" && (this.peek().value === \"*\" || this.peek().value === \"/\" || this.peek().value === \"%\")) {\n const op = this.consume().value;\n const right = this.parsePower();\n if (op === \"*\") left = left * right;\n else if (op === \"/\") left = right !== 0 ? left / right : 0;\n else left = left % right;\n }\n return left;\n }\n\n /** power: unary ('**' unary)* (right-associative) */\n private parsePower(): number {\n const base = this.parseUnary();\n if (this.peek().type === \"op\" && this.peek().value === \"**\") {\n this.consume();\n const exp = this.parsePower(); // right-associative\n return Math.pow(base, exp);\n }\n return base;\n }\n\n /** unary: ('-' | '+') unary | primary */\n private parseUnary(): number {\n if (this.peek().type === \"op\" && (this.peek().value === \"-\" || this.peek().value === \"+\")) {\n const op = this.consume().value;\n const val = this.parseUnary();\n return op === \"-\" ? -val : val;\n }\n return this.parsePrimary();\n }\n\n /** primary: number | ident | function(args) | '(' expr ')' */\n private parsePrimary(): number {\n const tok = this.peek();\n\n // Number literal\n if (tok.type === \"number\") {\n this.consume();\n return parseFloat(tok.value);\n }\n\n // Identifier: constant, context variable, or function\n if (tok.type === \"ident\") {\n this.consume();\n const name = tok.value;\n\n // Function call\n if (this.peek().type === \"lparen\") {\n this.consume(); // (\n const args: number[] = [];\n if (this.peek().type !== \"rparen\") {\n args.push(this.parseTernary());\n while (this.peek().type === \"comma\") {\n this.consume(); // ,\n args.push(this.parseTernary());\n }\n }\n this.consume(\"rparen\"); // )\n\n const fn = FUNCTIONS[name];\n if (!fn) throw new Error(`Expression: unknown function '${name}'`);\n return fn(...args);\n }\n\n // Constant\n if (name in CONSTANTS) return CONSTANTS[name];\n\n // Context variable\n if (name in this.ctx) return (this.ctx as unknown as Record<string, number>)[name];\n\n throw new Error(`Expression: unknown variable '${name}'`);\n }\n\n // Parenthesized expression\n if (tok.type === \"lparen\") {\n this.consume(); // (\n const val = this.parseTernary();\n this.consume(\"rparen\"); // )\n return val;\n }\n\n throw new Error(`Expression: unexpected token '${tok.value}'`);\n }\n}\n\n// ── Public API ──────────────────────────────────────────────\n\n/**\n * Check if a value is an expression object { expr: string }.\n */\nexport function isExpression(value: unknown): value is { expr: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"expr\" in value &&\n typeof (value as Record<string, unknown>).expr === \"string\"\n );\n}\n\n/**\n * Evaluate an expression string with the given context.\n * Returns a number. Throws on syntax errors or unknown identifiers.\n */\nexport function evaluateExpression(expr: string, ctx: ExpressionContext): number {\n const tokens = tokenize(expr);\n const parser = new Parser(tokens, ctx);\n return parser.parse();\n}\n","import type { AtelierDocument, Layer, Delta, AnimatableProperty } from \"@a-company/atelier-types\";\nimport { resolvePropertyAtFrame } from \"./delta-resolver.js\";\n\n/** A resolved layer at a specific frame — all animated properties computed */\nexport interface ResolvedLayer {\n id: string;\n /** Original layer definition */\n layer: Layer;\n /** Computed property overrides from active deltas */\n computedProperties: Partial<Record<AnimatableProperty, unknown>>;\n}\n\n/** The resolved state of an entire document at a specific frame */\nexport interface ResolvedFrame {\n /** Frame number that was resolved */\n frame: number;\n /** State name that was resolved */\n stateName: string;\n /** All layers with their computed properties */\n layers: ResolvedLayer[];\n}\n\n/**\n * Resolve all layers at a given frame within a named state.\n * This is the main entry point for frame resolution.\n * @param overrideDeltas - Optional pre-merged deltas (used for hierarchical state resolution)\n */\nexport function resolveFrame(\n doc: AtelierDocument,\n stateName: string,\n frame: number,\n overrideDeltas?: Delta[],\n): ResolvedFrame {\n const state = doc.states[stateName];\n if (!state) {\n throw new Error(`State \"${stateName}\" not found in document \"${doc.name}\"`);\n }\n\n // Group deltas by layer+property\n const deltasByLayerProperty = groupDeltas(overrideDeltas ?? state.deltas);\n\n // Resolve each layer\n const resolvedLayers: ResolvedLayer[] = doc.layers.map((layer) => {\n const computedProperties: Partial<Record<AnimatableProperty, unknown>> = {};\n\n // Find all animated properties for this layer\n const layerDeltas = deltasByLayerProperty.get(layer.id);\n if (layerDeltas) {\n for (const [property, deltas] of layerDeltas) {\n const value = resolvePropertyAtFrame(deltas, frame);\n if (value !== undefined) {\n computedProperties[property as AnimatableProperty] = value;\n }\n }\n }\n\n return { id: layer.id, layer, computedProperties };\n });\n\n return { frame, stateName, layers: resolvedLayers };\n}\n\n/**\n * Group deltas by layer ID, then by property name.\n */\nfunction groupDeltas(\n deltas: Delta[],\n): Map<string, Map<string, Delta[]>> {\n const map = new Map<string, Map<string, Delta[]>>();\n\n for (const delta of deltas) {\n let layerMap = map.get(delta.layer);\n if (!layerMap) {\n layerMap = new Map();\n map.set(delta.layer, layerMap);\n }\n\n let propDeltas = layerMap.get(delta.property);\n if (!propDeltas) {\n propDeltas = [];\n layerMap.set(delta.property, propDeltas);\n }\n\n propDeltas.push(delta);\n }\n\n return map;\n}\n","import type { Delta, FrameRange } from \"@a-company/atelier-types\";\n\nexport interface OverlapError {\n layerId: string;\n property: string;\n existingRange: FrameRange;\n newRange: FrameRange;\n message: string;\n}\n\n/**\n * Check if two frame ranges overlap.\n */\nexport function rangesOverlap(a: FrameRange, b: FrameRange): boolean {\n return a[0] <= b[1] && b[0] <= a[1];\n}\n\n/**\n * Validate that a new delta doesn't overlap with existing deltas\n * on the same layer+property.\n */\nexport function validateNoOverlap(\n existing: Delta[],\n newDelta: Delta,\n): OverlapError | null {\n for (const delta of existing) {\n if (\n delta.layer === newDelta.layer &&\n delta.property === newDelta.property &&\n rangesOverlap(delta.range, newDelta.range)\n ) {\n return {\n layerId: newDelta.layer,\n property: newDelta.property,\n existingRange: delta.range,\n newRange: newDelta.range,\n message: `Overlapping delta on layer \"${newDelta.layer}\" property \"${newDelta.property}\": ` +\n `existing [${delta.range[0]}-${delta.range[1]}] overlaps with new [${newDelta.range[0]}-${newDelta.range[1]}]`,\n };\n }\n }\n return null;\n}\n\n/**\n * Validate all deltas in a state have no overlaps.\n * Returns all overlap errors found.\n */\nexport function validateAllDeltas(deltas: Delta[]): OverlapError[] {\n const errors: OverlapError[] = [];\n\n for (let i = 0; i < deltas.length; i++) {\n for (let j = i + 1; j < deltas.length; j++) {\n const a = deltas[i];\n const b = deltas[j];\n\n if (\n a.layer === b.layer &&\n a.property === b.property &&\n rangesOverlap(a.range, b.range)\n ) {\n errors.push({\n layerId: a.layer,\n property: a.property,\n existingRange: a.range,\n newRange: b.range,\n message: `Overlapping deltas on layer \"${a.layer}\" property \"${a.property}\": ` +\n `[${a.range[0]}-${a.range[1]}] overlaps with [${b.range[0]}-${b.range[1]}]`,\n });\n }\n }\n }\n\n return errors;\n}\n","import type {\n AtelierDocument, Canvas, Layer, State, Delta, Preset,\n Variable, Asset,\n} from \"@a-company/atelier-types\";\nimport { validateNoOverlap } from \"../validation/overlap-validator.js\";\n\n/**\n * Fluent builder for constructing AtelierDocument objects.\n * Validates constraints (like no-overlap) as you build.\n */\nexport class DocumentBuilder {\n private doc: AtelierDocument;\n\n constructor(name: string, canvas: Canvas) {\n this.doc = {\n version: \"1.0\",\n name,\n canvas,\n layers: [],\n states: {},\n };\n }\n\n /** Set document description */\n description(desc: string): this {\n this.doc.description = desc;\n return this;\n }\n\n /** Add tags to the document */\n tags(...tags: string[]): this {\n this.doc.tags = [...(this.doc.tags ?? []), ...tags];\n return this;\n }\n\n /** Add a variable definition */\n variable(id: string, variable: Variable): this {\n if (!this.doc.variables) this.doc.variables = {};\n this.doc.variables[id] = variable;\n return this;\n }\n\n /** Add an asset reference */\n asset(id: string, asset: Asset): this {\n if (!this.doc.assets) this.doc.assets = {};\n this.doc.assets[id] = asset;\n return this;\n }\n\n /** Add a preset */\n preset(id: string, preset: Preset): this {\n if (!this.doc.presets) this.doc.presets = {};\n this.doc.presets[id] = preset;\n return this;\n }\n\n /** Add a layer */\n addLayer(layer: Layer): this {\n // Check for duplicate IDs\n if (this.doc.layers.some(l => l.id === layer.id)) {\n throw new Error(`Layer with id \"${layer.id}\" already exists`);\n }\n this.doc.layers.push(layer);\n return this;\n }\n\n /** Add a state */\n addState(name: string, state: Omit<State, \"deltas\"> & { deltas?: Delta[] }): this {\n if (this.doc.states[name]) {\n throw new Error(`State \"${name}\" already exists`);\n }\n this.doc.states[name] = { ...state, deltas: state.deltas ?? [] };\n return this;\n }\n\n /** Add a delta to an existing state, with overlap validation */\n addDelta(stateName: string, delta: Delta): this {\n const state = this.doc.states[stateName];\n if (!state) {\n throw new Error(`State \"${stateName}\" not found`);\n }\n\n // Verify the layer exists\n if (!this.doc.layers.some(l => l.id === delta.layer)) {\n throw new Error(`Layer \"${delta.layer}\" not found — add the layer before adding deltas`);\n }\n\n // Check for overlaps\n const overlap = validateNoOverlap(state.deltas, delta);\n if (overlap) {\n throw new Error(overlap.message);\n }\n\n state.deltas.push(delta);\n return this;\n }\n\n /** Build and return the final document */\n build(): AtelierDocument {\n return JSON.parse(JSON.stringify(this.doc)) as AtelierDocument;\n }\n}\n\n/**\n * Create a new DocumentBuilder.\n * Convenience function for starting a builder chain.\n */\nexport function createDocument(name: string, canvas: Canvas): DocumentBuilder {\n return new DocumentBuilder(name, canvas);\n}\n","import type { UnitValue } from \"@a-company/atelier-types\";\n\n/**\n * Check if a UnitValue is a percentage string.\n */\nexport function isPercentage(value: UnitValue): value is `${number}%` {\n return typeof value === \"string\" && value.endsWith(\"%\");\n}\n\n/**\n * Parse a percentage string to its numeric value (0-100).\n */\nexport function parsePercentage(value: `${number}%`): number {\n return parseFloat(value);\n}\n\n/**\n * Resolve a UnitValue to pixels given a reference dimension.\n * Pixel values pass through unchanged.\n * Percentage values are computed relative to the reference.\n */\nexport function resolveUnit(value: UnitValue, reference: number): number {\n if (isPercentage(value)) {\n return (parsePercentage(value) / 100) * reference;\n }\n return value;\n}\n","import type { Preset, Delta, FrameRange } from \"@a-company/atelier-types\";\n\n/**\n * Expand a preset into concrete deltas for a specific layer and start frame.\n *\n * @param preset - The preset to expand\n * @param layerId - Target layer ID\n * @param startFrame - Frame to start the preset from\n * @param duration - Total duration to map preset offsets into\n */\nexport function expandPreset(\n preset: Preset,\n layerId: string,\n startFrame: number,\n duration: number,\n): Delta[] {\n return preset.deltas.map((pd, index) => {\n let range: FrameRange;\n if (pd.offset) {\n range = [startFrame + pd.offset[0], startFrame + pd.offset[1]];\n } else {\n range = [startFrame, startFrame + duration];\n }\n\n return {\n id: `preset-${layerId}-${index}`,\n layer: layerId,\n property: pd.property,\n range,\n from: pd.from,\n to: pd.to,\n easing: pd.easing,\n };\n });\n}\n","import type { AtelierDocument, Easing, State, Delta } from \"@a-company/atelier-types\";\nimport { resolveFrame, type ResolvedFrame } from \"../resolver/frame-resolver.js\";\nimport { resolveEasing } from \"../resolver/easing-resolver.js\";\n\nexport interface StateTransition {\n from: string;\n to: string;\n at: number; // frame at which transition occurs\n}\n\nexport interface PlaybackState {\n stateName: string;\n frame: number;\n resolved: ResolvedFrame;\n isComplete: boolean;\n}\n\nexport interface ActiveTransition {\n fromState: string;\n toState: string;\n duration: number;\n easingFn: (t: number) => number;\n transitionFrame: number; // how many frames into the transition\n}\n\nexport class StateMachine {\n private currentState: string;\n private currentFrame = 0;\n private transitions: StateTransition[] = [];\n private activeTransition: ActiveTransition | null = null;\n\n constructor(\n private doc: AtelierDocument,\n initialState?: string,\n ) {\n // Default to first state\n const stateNames = Object.keys(doc.states);\n if (stateNames.length === 0) throw new Error(\"Document has no states\");\n this.currentState = initialState ?? stateNames[0];\n if (!doc.states[this.currentState]) {\n throw new Error(`State \"${this.currentState}\" not found`);\n }\n }\n\n /** Get current state name */\n get state(): string {\n return this.currentState;\n }\n\n /** Get current frame */\n get frame(): number {\n return this.currentFrame;\n }\n\n /** Get all state names */\n get stateNames(): string[] {\n return Object.keys(this.doc.states);\n }\n\n /** Get current state duration */\n get duration(): number {\n return this.doc.states[this.currentState].duration;\n }\n\n /** Check if current state playback is complete */\n get isComplete(): boolean {\n return this.currentFrame >= this.duration - 1;\n }\n\n /** Check if currently in a transition blend */\n isTransitioning(): boolean {\n return this.activeTransition !== null;\n }\n\n /** Get transition progress (0–1) with easing applied, or null if not transitioning */\n getTransitionProgress(): number | null {\n if (!this.activeTransition) return null;\n const { transitionFrame, duration, easingFn } = this.activeTransition;\n const rawProgress = Math.min(transitionFrame / duration, 1);\n return easingFn(rawProgress);\n }\n\n // ── Hierarchical State Support ────────────────────────────\n\n /**\n * Resolve the ancestor chain for a state (root → … → parent → self).\n * Throws on circular parent references.\n */\n resolveAncestorChain(stateName: string): string[] {\n const chain: string[] = [];\n const visited = new Set<string>();\n let current: string | undefined = stateName;\n\n while (current) {\n if (visited.has(current)) {\n throw new Error(`Circular parent reference detected: \"${current}\" already in chain [${chain.join(\" → \")}]`);\n }\n visited.add(current);\n chain.unshift(current); // prepend so root is first\n const stateObj: State | undefined = this.doc.states[current];\n if (!stateObj) {\n throw new Error(`Parent state \"${current}\" not found`);\n }\n current = stateObj.parent;\n }\n\n return chain;\n }\n\n /**\n * Collect merged deltas from ancestor chain.\n * Child overrides parent deltas for the same layer+property combination.\n * Deltas for different layer+property pairs are accumulated from all ancestors.\n */\n collectDeltas(stateName: string): Delta[] {\n const chain = this.resolveAncestorChain(stateName);\n // Walk root → child. Later entries override earlier for same layer+property.\n const deltaMap = new Map<string, Delta[]>();\n\n for (const ancestorName of chain) {\n const state = this.doc.states[ancestorName];\n // Group this state's deltas by layer+property\n const stateGroups = new Map<string, Delta[]>();\n for (const delta of state.deltas) {\n const key = `${delta.layer}:${delta.property}`;\n if (!stateGroups.has(key)) stateGroups.set(key, []);\n stateGroups.get(key)!.push(delta);\n }\n // Child replaces parent for same key\n for (const [key, deltas] of stateGroups) {\n deltaMap.set(key, deltas);\n }\n }\n\n // Flatten all deltas\n const result: Delta[] = [];\n for (const deltas of deltaMap.values()) {\n result.push(...deltas);\n }\n return result;\n }\n\n // ── Playback ──────────────────────────────────────────────\n\n /** Advance to next frame, returns resolved frame */\n tick(): PlaybackState {\n // Handle active transition\n if (this.activeTransition) {\n this.activeTransition.transitionFrame++;\n if (this.activeTransition.transitionFrame >= this.activeTransition.duration) {\n // Transition complete\n this.activeTransition = null;\n }\n }\n\n const resolved = this.resolveCurrentFrame();\n const result: PlaybackState = {\n stateName: this.currentState,\n frame: this.currentFrame,\n resolved,\n isComplete: this.isComplete,\n };\n if (this.currentFrame < this.duration - 1) {\n this.currentFrame++;\n }\n return result;\n }\n\n /** Resolve the current frame, blending if in transition */\n private resolveCurrentFrame(): ResolvedFrame {\n if (this.activeTransition) {\n const progress = this.getTransitionProgress()!;\n const fromResolved = resolveFrame(\n this.doc, this.activeTransition.fromState, this.currentFrame,\n this.collectDeltas(this.activeTransition.fromState),\n );\n const toResolved = resolveFrame(\n this.doc, this.activeTransition.toState, this.currentFrame,\n this.collectDeltas(this.activeTransition.toState),\n );\n return blendResolvedFrames(fromResolved, toResolved, progress);\n }\n\n // Check if current state has a parent — use merged deltas\n const state = this.doc.states[this.currentState];\n if (state.parent) {\n const mergedDeltas = this.collectDeltas(this.currentState);\n return resolveFrame(this.doc, this.currentState, this.currentFrame, mergedDeltas);\n }\n\n return resolveFrame(this.doc, this.currentState, this.currentFrame);\n }\n\n /** Transition to a different state (instant or blended) */\n transition(stateName: string, startFrame = 0): void {\n if (!this.doc.states[stateName]) {\n throw new Error(`State \"${stateName}\" not found`);\n }\n\n const fromState = this.currentState;\n const currentStateObj = this.doc.states[fromState];\n const transConfig = currentStateObj.transitions?.[stateName];\n\n this.transitions.push({\n from: fromState,\n to: stateName,\n at: this.currentFrame,\n });\n\n if (transConfig && transConfig.duration > 0) {\n // Start a smooth transition\n this.activeTransition = {\n fromState,\n toState: stateName,\n duration: transConfig.duration,\n easingFn: resolveEasing(transConfig.easing),\n transitionFrame: 0,\n };\n }\n\n this.currentState = stateName;\n this.currentFrame = startFrame;\n }\n\n /**\n * Start a smooth transition to target state with explicit duration/easing.\n * This ignores any transitions config on the state.\n */\n transitionTo(targetState: string, duration: number, easing?: Easing): void {\n if (!this.doc.states[targetState]) {\n throw new Error(`State \"${targetState}\" not found`);\n }\n\n const fromState = this.currentState;\n this.transitions.push({\n from: fromState,\n to: targetState,\n at: this.currentFrame,\n });\n\n this.activeTransition = {\n fromState,\n toState: targetState,\n duration,\n easingFn: resolveEasing(easing),\n transitionFrame: 0,\n };\n\n this.currentState = targetState;\n this.currentFrame = 0;\n }\n\n /** Seek to a specific frame in current state */\n seek(frame: number): void {\n this.currentFrame = Math.max(0, Math.min(frame, this.duration - 1));\n }\n\n /** Reset to initial state */\n reset(stateName?: string): void {\n if (stateName) {\n if (!this.doc.states[stateName]) throw new Error(`State \"${stateName}\" not found`);\n this.currentState = stateName;\n }\n this.currentFrame = 0;\n this.activeTransition = null;\n }\n\n /** Get transition history */\n get history(): ReadonlyArray<StateTransition> {\n return this.transitions;\n }\n\n /** Resolve a specific frame without advancing */\n resolveAt(stateName: string, frame: number): ResolvedFrame {\n if (!this.doc.states[stateName]) throw new Error(`State \"${stateName}\" not found`);\n const state = this.doc.states[stateName];\n if (state.parent) {\n return resolveFrame(this.doc, stateName, frame, this.collectDeltas(stateName));\n }\n return resolveFrame(this.doc, stateName, frame);\n }\n\n /** Play through entire current state, calling callback on each frame */\n playThrough(onFrame: (state: PlaybackState) => void): void {\n this.currentFrame = 0;\n while (!this.isComplete) {\n onFrame(this.tick());\n }\n onFrame(this.tick()); // last frame\n }\n}\n\n// ── Frame Blending ────────────────────────────────────────────\n\nimport type { ResolvedLayer } from \"../resolver/frame-resolver.js\";\nimport type { AnimatableProperty } from \"@a-company/atelier-types\";\nimport { interpolateValue } from \"../resolver/delta-resolver.js\";\n\n/**\n * Blend two resolved frames together for smooth state transitions.\n * Numeric properties are lerped, colors are color-lerped, discrete values snap at t >= 0.5.\n */\nexport function blendResolvedFrames(\n frameA: ResolvedFrame,\n frameB: ResolvedFrame,\n t: number,\n): ResolvedFrame {\n // Build layer maps\n const mapA = new Map<string, ResolvedLayer>();\n const mapB = new Map<string, ResolvedLayer>();\n for (const l of frameA.layers) mapA.set(l.id, l);\n for (const l of frameB.layers) mapB.set(l.id, l);\n\n // Get all unique layer IDs\n const allIds = new Set([...mapA.keys(), ...mapB.keys()]);\n const blendedLayers: ResolvedLayer[] = [];\n\n for (const id of allIds) {\n const layerA = mapA.get(id);\n const layerB = mapB.get(id);\n\n if (layerA && layerB) {\n // Both exist — blend computed properties\n blendedLayers.push(blendLayers(layerA, layerB, t));\n } else if (layerA && !layerB) {\n // Only in A — fade out (set opacity toward 0)\n blendedLayers.push(fadeLayer(layerA, 1 - t));\n } else if (!layerA && layerB) {\n // Only in B — fade in (set opacity from 0)\n blendedLayers.push(fadeLayer(layerB, t));\n }\n }\n\n return {\n frame: frameB.frame,\n stateName: frameB.stateName,\n layers: blendedLayers,\n };\n}\n\nfunction blendLayers(a: ResolvedLayer, b: ResolvedLayer, t: number): ResolvedLayer {\n const allProps = new Set([\n ...Object.keys(a.computedProperties),\n ...Object.keys(b.computedProperties),\n ]);\n\n const blended: Partial<Record<AnimatableProperty, unknown>> = {};\n\n for (const prop of allProps) {\n const valA = a.computedProperties[prop as AnimatableProperty];\n const valB = b.computedProperties[prop as AnimatableProperty];\n\n if (valA !== undefined && valB !== undefined) {\n blended[prop as AnimatableProperty] = interpolateValue(valA, valB, t);\n } else if (valA !== undefined) {\n blended[prop as AnimatableProperty] = valA;\n } else {\n blended[prop as AnimatableProperty] = valB;\n }\n }\n\n return {\n id: a.id,\n layer: a.layer,\n computedProperties: blended,\n };\n}\n\nfunction fadeLayer(layer: ResolvedLayer, opacity: number): ResolvedLayer {\n const cp = { ...layer.computedProperties };\n const existingOpacity = (cp.opacity as number) ?? 1;\n cp.opacity = existingOpacity * opacity;\n return {\n id: layer.id,\n layer: layer.layer,\n computedProperties: cp,\n };\n}\n","import type { AtelierDocument } from \"@a-company/atelier-types\";\n\nexport interface TemplateBindings {\n [variableName: string]: unknown;\n}\n\nexport interface TemplateError {\n variable: string;\n message: string;\n}\n\nexport type TemplateResult =\n | {\n success: true;\n document: AtelierDocument;\n }\n | {\n success: false;\n errors: TemplateError[];\n };\n\n/**\n * Instantiate a template document by substituting variable values.\n * Walks the document tree, replacing {{variableName}} patterns with bound values.\n */\nexport function instantiateTemplate(\n template: AtelierDocument,\n bindings: TemplateBindings,\n): TemplateResult {\n // 1. Validate all required variables have bindings\n const errors: TemplateError[] = [];\n const variables = template.variables ?? {};\n\n for (const [name, variable] of Object.entries(variables)) {\n if (bindings[name] === undefined && variable.default === undefined) {\n errors.push({ variable: name, message: `Required variable \"${name}\" not provided` });\n }\n }\n\n // Check for unknown bindings\n for (const name of Object.keys(bindings)) {\n if (!variables[name]) {\n errors.push({ variable: name, message: `Unknown variable \"${name}\"` });\n }\n }\n\n if (errors.length > 0) return { success: false, errors };\n\n // 2. Merge bindings with defaults\n const resolved: Record<string, unknown> = {};\n for (const [name, variable] of Object.entries(variables)) {\n resolved[name] = bindings[name] ?? variable.default;\n }\n\n // 3. Deep clone and substitute\n const doc = JSON.parse(JSON.stringify(template)) as AtelierDocument;\n substituteInObject(doc as unknown as Record<string, unknown>, resolved);\n\n // 4. Remove variables section (no longer a template)\n delete doc.variables;\n\n return { success: true, document: doc };\n}\n\n/**\n * Recursively substitute {{variableName}} patterns in string values.\n */\nfunction substituteInObject(obj: Record<string, unknown>, bindings: Record<string, unknown>): void {\n for (const key of Object.keys(obj)) {\n const value = obj[key];\n if (typeof value === \"string\") {\n obj[key] = substituteString(value, bindings);\n } else if (Array.isArray(value)) {\n substituteInArray(value, bindings);\n } else if (value !== null && typeof value === \"object\") {\n substituteInObject(value as Record<string, unknown>, bindings);\n }\n }\n}\n\nfunction substituteInArray(arr: unknown[], bindings: Record<string, unknown>): void {\n for (let i = 0; i < arr.length; i++) {\n const value = arr[i];\n if (typeof value === \"string\") {\n arr[i] = substituteString(value, bindings);\n } else if (Array.isArray(value)) {\n substituteInArray(value, bindings);\n } else if (value !== null && typeof value === \"object\") {\n substituteInObject(value as Record<string, unknown>, bindings);\n }\n }\n}\n\n/**\n * Replace {{variableName}} in a string with the bound value.\n * If the entire string is a single {{var}}, return the raw value (preserving type).\n * Otherwise, interpolate into the string.\n */\nfunction substituteString(str: string, bindings: Record<string, unknown>): unknown {\n // Exact match: entire string is {{varName}} -> return raw value\n const exactMatch = str.match(/^\\{\\{(\\w+)\\}\\}$/);\n if (exactMatch) {\n const name = exactMatch[1];\n return name in bindings ? bindings[name] : str;\n }\n\n // Partial match: replace all {{varName}} occurrences with string values\n return str.replace(/\\{\\{(\\w+)\\}\\}/g, (_, name: string) => {\n return name in bindings ? String(bindings[name]) : `{{${name}}}`;\n });\n}\n\n/**\n * List all variables used in a document (scan for {{variableName}} patterns).\n */\nexport function findTemplateVariables(doc: AtelierDocument): string[] {\n const vars = new Set<string>();\n scanForVariables(doc, vars);\n return Array.from(vars);\n}\n\nfunction scanForVariables(value: unknown, vars: Set<string>): void {\n if (typeof value === \"string\") {\n const matches = value.matchAll(/\\{\\{(\\w+)\\}\\}/g);\n for (const match of matches) {\n vars.add(match[1]);\n }\n } else if (Array.isArray(value)) {\n for (const item of value) scanForVariables(item, vars);\n } else if (value !== null && typeof value === \"object\") {\n for (const v of Object.values(value as Record<string, unknown>)) {\n scanForVariables(v, vars);\n }\n }\n}\n","import type { Audio } from \"@a-company/atelier-types\";\n\n/** Audio playback state at a given frame */\nexport interface AudioPlaybackState {\n /** Whether audio should be playing at this frame */\n shouldPlay: boolean;\n /** Current position in the audio track (seconds) */\n currentTime: number;\n /** Effective volume (0–1) */\n volume: number;\n}\n\n/**\n * Convert a frame number to time in seconds.\n */\nexport function frameToTime(frame: number, fps: number): number {\n return frame / fps;\n}\n\n/**\n * Convert time in seconds to a frame number (floored).\n */\nexport function timeToFrame(time: number, fps: number): number {\n return Math.floor(time * fps);\n}\n\n/**\n * Compute the audio playback state for a given frame.\n *\n * @param audio - Audio configuration from a state\n * @param frame - Current frame number within the state\n * @param fps - Frames per second from canvas config\n * @param stateDuration - Total state duration in frames\n * @returns AudioPlaybackState with shouldPlay, currentTime, and volume\n */\nexport function computeAudioState(\n audio: Audio,\n frame: number,\n fps: number,\n stateDuration: number,\n): AudioPlaybackState {\n const startFrame = audio.startFrame ?? 0;\n const offset = audio.offset ?? 0;\n const volume = audio.volume ?? 1;\n const loop = audio.loop ?? false;\n\n // Before audio starts\n if (frame < startFrame) {\n return { shouldPlay: false, currentTime: 0, volume };\n }\n\n // Time elapsed since audio started\n const elapsedFrames = frame - startFrame;\n const elapsedTime = frameToTime(elapsedFrames, fps);\n\n // Total available playback time (from startFrame to end of state)\n const availableFrames = stateDuration - startFrame;\n const availableTime = frameToTime(availableFrames, fps);\n\n if (!loop) {\n // Non-looping: audio plays from offset, stops at end of state\n const currentTime = offset + elapsedTime;\n return {\n shouldPlay: frame < stateDuration,\n currentTime,\n volume,\n };\n }\n\n // Looping: wrap elapsed time around available duration\n // The audio segment length is the available time\n const segmentDuration = availableTime;\n if (segmentDuration <= 0) {\n return { shouldPlay: false, currentTime: 0, volume };\n }\n\n const wrappedTime = elapsedTime % segmentDuration;\n const currentTime = offset + wrappedTime;\n\n return {\n shouldPlay: frame < stateDuration,\n currentTime,\n volume,\n };\n}\n\n/**\n * Compute audio cue points — frames where audio events occur.\n *\n * @param audio - Audio configuration\n * @param stateDuration - Total state duration in frames\n * @returns Array of { frame, event } describing audio events\n */\nexport function computeAudioCues(\n audio: Audio,\n stateDuration: number,\n): Array<{ frame: number; event: \"start\" | \"end\" | \"loop\" }> {\n const startFrame = audio.startFrame ?? 0;\n const loop = audio.loop ?? false;\n const cues: Array<{ frame: number; event: \"start\" | \"end\" | \"loop\" }> = [];\n\n if (startFrame < stateDuration) {\n cues.push({ frame: startFrame, event: \"start\" });\n }\n\n if (loop) {\n // In loop mode, audio restarts each full cycle\n const availableFrames = stateDuration - startFrame;\n if (availableFrames > 0) {\n // Loop points at each full cycle\n for (let i = 1; startFrame + i * availableFrames < stateDuration; i++) {\n cues.push({ frame: startFrame + i * availableFrames, event: \"loop\" });\n }\n }\n }\n\n // Audio ends when state ends\n if (stateDuration > startFrame) {\n cues.push({ frame: stateDuration - 1, event: \"end\" });\n }\n\n return cues;\n}\n","import type { Fill, Stroke, Color, RGBAColor, HSLAColor } from \"@a-company/atelier-types\";\nimport type { RenderContext } from \"./canvas-types.js\";\n\n/**\n * Convert an Atelier Color to a CSS color string.\n */\nexport function colorToCSS(color: Color): string {\n if (typeof color === \"string\") return color; // hex string\n\n if (\"r\" in color) {\n const c = color as RGBAColor;\n return `rgba(${Math.round(c.r)}, ${Math.round(c.g)}, ${Math.round(c.b)}, ${c.a})`;\n }\n\n if (\"h\" in color) {\n const c = color as HSLAColor;\n return `hsla(${c.h}, ${c.s}%, ${c.l}%, ${c.a})`;\n }\n\n return \"#000000\";\n}\n\n/**\n * Apply a Fill to the canvas context's fillStyle.\n */\nexport function applyFill(ctx: RenderContext, fill: Fill, width: number, height: number): void {\n switch (fill.type) {\n case \"solid\":\n ctx.fillStyle = colorToCSS(fill.color);\n break;\n\n case \"linear-gradient\": {\n const rad = (fill.angle * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const halfW = width / 2;\n const halfH = height / 2;\n const grad = ctx.createLinearGradient(\n halfW - cos * halfW, halfH - sin * halfH,\n halfW + cos * halfW, halfH + sin * halfH,\n );\n for (const stop of fill.stops) {\n grad.addColorStop(stop.offset, colorToCSS(stop.color));\n }\n ctx.fillStyle = grad as unknown as string;\n break;\n }\n\n case \"radial-gradient\": {\n const cx = typeof fill.center.x === \"number\" ? fill.center.x : (parseFloat(fill.center.x) / 100) * width;\n const cy = typeof fill.center.y === \"number\" ? fill.center.y : (parseFloat(fill.center.y) / 100) * height;\n const r = typeof fill.radius === \"number\" ? fill.radius : (parseFloat(fill.radius) / 100) * Math.max(width, height);\n const grad = ctx.createRadialGradient(cx, cy, 0, cx, cy, r);\n for (const stop of fill.stops) {\n grad.addColorStop(stop.offset, colorToCSS(stop.color));\n }\n ctx.fillStyle = grad as unknown as string;\n break;\n }\n }\n}\n\n/**\n * Apply a Stroke to the canvas context.\n * @param pathLength - total perimeter of the shape (needed for strokeStart/strokeEnd trim)\n */\nexport function applyStroke(ctx: RenderContext, stroke: Stroke, pathLength: number): void {\n ctx.strokeStyle = colorToCSS(stroke.color);\n ctx.lineWidth = stroke.width;\n if (stroke.lineCap) ctx.lineCap = stroke.lineCap;\n if (stroke.lineJoin) ctx.lineJoin = stroke.lineJoin;\n\n const start = stroke.strokeStart ?? 0;\n const end = stroke.strokeEnd ?? 1;\n\n if (start !== 0 || end !== 1) {\n const visible = (end - start) * pathLength;\n ctx.setLineDash([Math.max(visible, 0), pathLength + 1]);\n ctx.lineDashOffset = -start * pathLength;\n } else if (stroke.dash) {\n ctx.setLineDash(stroke.dash);\n }\n}\n","import type { Layer, Visual, ShapeVisual, TextVisual, ImageVisual, Color, BlendMode, LinearGradientFill, RadialGradientFill } from \"@a-company/atelier-types\";\nimport { colorToCSS } from \"./styles.js\";\nimport { evaluatePathAtProgress } from \"@a-company/atelier-math\";\nimport type { ResolvedLayer } from \"@a-company/atelier-core\";\n\n/**\n * Effective values for a layer at a given frame,\n * with computed properties merged over defaults.\n */\nexport interface EffectiveLayer {\n /** Original layer */\n layer: Layer;\n /** Visual with animated property overrides applied */\n visual: Visual;\n /** Effective frame position (may be animated) */\n x: number;\n y: number;\n /** Effective bounds */\n width: number;\n height: number;\n /** Effective transform values */\n opacity: number;\n rotation: number;\n scaleX: number;\n scaleY: number;\n anchorX: number;\n anchorY: number;\n /** Resolved shadow (if layer has shadow or shadow is animated) */\n shadow?: {\n color: string;\n blur: number;\n offsetX: number;\n offsetY: number;\n };\n /** Blend mode for compositing */\n blendMode: string;\n /** Motion path auto-rotation in degrees (applied additively to rotation) */\n motionPathAngle: number;\n /** Whether this layer is visible (may be animated) */\n visible: boolean;\n /** Color tint overlay */\n tint?: {\n color: string;\n amount: number;\n };\n}\n\n/**\n * Resolve a UnitValue to pixels. Percentages resolve against a reference dimension.\n */\nfunction resolveUnit(value: number | string, reference: number): number {\n if (typeof value === \"string\" && value.endsWith(\"%\")) {\n return (parseFloat(value) / 100) * reference;\n }\n return value as number;\n}\n\n/**\n * Build the effective layer values by merging computed properties over layer defaults.\n * @param resolved - The resolved layer from frame resolution\n * @param parentWidth - Parent/canvas width for percentage resolution\n * @param parentHeight - Parent/canvas height for percentage resolution\n */\nexport function buildEffectiveLayer(\n resolved: ResolvedLayer,\n parentWidth: number,\n parentHeight: number,\n): EffectiveLayer {\n const { layer, computedProperties } = resolved;\n const cp = computedProperties as Record<string, unknown>;\n\n const hasShadow = layer.shadow || cp[\"shadow.blur\"] !== undefined || cp[\"shadow.color\"] !== undefined;\n const hasTint = layer.tint || cp[\"tint.amount\"] !== undefined || cp[\"tint.color\"] !== undefined;\n\n // Resolve base position\n let x = resolveUnit((cp[\"frame.x\"] ?? layer.frame.x) as number | string, parentWidth);\n let y = resolveUnit((cp[\"frame.y\"] ?? layer.frame.y) as number | string, parentHeight);\n let motionPathAngle = 0;\n\n // Motion path overrides position when progress is animated\n const motionProgress = cp[\"motionPath.progress\"] as number | undefined;\n if (motionProgress !== undefined && layer.motionPath && layer.motionPath.points.length >= 2) {\n const pos = evaluatePathAtProgress(layer.motionPath.points, motionProgress, layer.motionPath.closed);\n x = pos.x;\n y = pos.y;\n if (layer.motionPath.autoRotate) {\n motionPathAngle = pos.angle + (layer.motionPath.autoRotateOffset ?? 0);\n }\n }\n\n return {\n layer,\n visual: buildEffectiveVisual(layer.visual, cp),\n x,\n y,\n width: resolveUnit((cp[\"bounds.width\"] ?? layer.bounds.width) as number | string, parentWidth),\n height: resolveUnit((cp[\"bounds.height\"] ?? layer.bounds.height) as number | string, parentHeight),\n opacity: (cp[\"opacity\"] as number) ?? layer.opacity ?? 1,\n rotation: (cp[\"rotation\"] as number) ?? layer.rotation ?? 0,\n scaleX: (cp[\"scale.x\"] as number) ?? layer.scale?.x ?? 1,\n scaleY: (cp[\"scale.y\"] as number) ?? layer.scale?.y ?? 1,\n anchorX: (cp[\"anchorPoint.x\"] as number) ?? layer.anchorPoint?.x ?? 0,\n anchorY: (cp[\"anchorPoint.y\"] as number) ?? layer.anchorPoint?.y ?? 0,\n shadow: hasShadow ? {\n color: colorToCSS((cp[\"shadow.color\"] ?? layer.shadow?.color ?? \"#00000080\") as Color),\n blur: (cp[\"shadow.blur\"] as number) ?? layer.shadow?.blur ?? 0,\n offsetX: (cp[\"shadow.offsetX\"] as number) ?? layer.shadow?.offsetX ?? 0,\n offsetY: (cp[\"shadow.offsetY\"] as number) ?? layer.shadow?.offsetY ?? 0,\n } : undefined,\n blendMode: (layer.blendMode as BlendMode) ?? \"normal\",\n motionPathAngle,\n visible: (cp[\"visible\"] as boolean) ?? layer.visible ?? true,\n tint: hasTint ? {\n color: colorToCSS((cp[\"tint.color\"] ?? layer.tint?.color ?? \"#FF0000\") as Color),\n amount: (cp[\"tint.amount\"] as number) ?? layer.tint?.amount ?? 0,\n } : undefined,\n };\n}\n\n/**\n * Build an effective visual by applying computed property overrides.\n * Returns the original visual if no visual properties are animated.\n */\nfunction buildEffectiveVisual(visual: Visual, cp: Record<string, unknown>): Visual {\n const hasVisualOverride =\n cp[\"visual.fill.color\"] !== undefined ||\n cp[\"visual.fill.angle\"] !== undefined ||\n cp[\"visual.fill.center.x\"] !== undefined ||\n cp[\"visual.fill.center.y\"] !== undefined ||\n cp[\"visual.fill.radius\"] !== undefined ||\n cp[\"visual.stroke.color\"] !== undefined ||\n cp[\"visual.stroke.width\"] !== undefined ||\n cp[\"visual.stroke.start\"] !== undefined ||\n cp[\"visual.stroke.end\"] !== undefined ||\n cp[\"visual.shape.cornerRadius\"] !== undefined ||\n cp[\"visual.style.fontSize\"] !== undefined ||\n cp[\"visual.style.color\"] !== undefined;\n\n const hasImageOverride =\n cp[\"visual.image.sourceRect.x\"] !== undefined ||\n cp[\"visual.image.sourceRect.y\"] !== undefined ||\n cp[\"visual.image.sourceRect.width\"] !== undefined ||\n cp[\"visual.image.sourceRect.height\"] !== undefined ||\n cp[\"visual.image.frameIndex\"] !== undefined;\n\n if (!hasVisualOverride && !hasImageOverride) return visual;\n\n if (visual.type === \"shape\") {\n const v: ShapeVisual = { ...visual };\n\n if (cp[\"visual.shape.cornerRadius\"] !== undefined && v.shape.type === \"rect\") {\n v.shape = { ...v.shape, cornerRadius: cp[\"visual.shape.cornerRadius\"] as number };\n }\n\n if (v.fill) {\n if (cp[\"visual.fill.color\"] !== undefined && v.fill.type === \"solid\") {\n v.fill = { ...v.fill, color: cp[\"visual.fill.color\"] as string };\n }\n if (cp[\"visual.fill.angle\"] !== undefined && v.fill.type === \"linear-gradient\") {\n v.fill = { ...v.fill, angle: cp[\"visual.fill.angle\"] as number } as LinearGradientFill;\n }\n if (v.fill.type === \"radial-gradient\") {\n const cx = cp[\"visual.fill.center.x\"];\n const cy = cp[\"visual.fill.center.y\"];\n const r = cp[\"visual.fill.radius\"];\n if (cx !== undefined || cy !== undefined || r !== undefined) {\n const f = v.fill as RadialGradientFill;\n v.fill = {\n ...f,\n center: {\n x: cx !== undefined ? (cx as number) : f.center.x,\n y: cy !== undefined ? (cy as number) : f.center.y,\n },\n radius: r !== undefined ? (r as number) : f.radius,\n } as RadialGradientFill;\n }\n }\n }\n\n if (v.stroke) {\n const strokeColor = cp[\"visual.stroke.color\"] ?? v.stroke.color;\n const strokeWidth = (cp[\"visual.stroke.width\"] as number) ?? v.stroke.width;\n const strokeStart = (cp[\"visual.stroke.start\"] as number | undefined) ?? v.stroke.strokeStart;\n const strokeEnd = (cp[\"visual.stroke.end\"] as number | undefined) ?? v.stroke.strokeEnd;\n if (\n strokeColor !== v.stroke.color ||\n strokeWidth !== v.stroke.width ||\n strokeStart !== v.stroke.strokeStart ||\n strokeEnd !== v.stroke.strokeEnd\n ) {\n v.stroke = {\n ...v.stroke,\n color: strokeColor as string,\n width: strokeWidth,\n strokeStart,\n strokeEnd,\n };\n }\n }\n\n return v;\n }\n\n if (visual.type === \"text\") {\n const v: TextVisual = { ...visual };\n const fontSize = (cp[\"visual.style.fontSize\"] as number) ?? v.style.fontSize;\n const color = cp[\"visual.style.color\"] ?? v.style.color;\n if (fontSize !== v.style.fontSize || color !== v.style.color) {\n v.style = { ...v.style, fontSize, color: color as string };\n }\n return v;\n }\n\n if (visual.type === \"image\" && hasImageOverride) {\n const v: ImageVisual = { ...visual };\n\n // Merge animated sourceRect fields\n if (\n cp[\"visual.image.sourceRect.x\"] !== undefined ||\n cp[\"visual.image.sourceRect.y\"] !== undefined ||\n cp[\"visual.image.sourceRect.width\"] !== undefined ||\n cp[\"visual.image.sourceRect.height\"] !== undefined\n ) {\n const base = v.sourceRect ?? { x: 0, y: 0, width: 0, height: 0 };\n v.sourceRect = {\n x: (cp[\"visual.image.sourceRect.x\"] as number) ?? base.x,\n y: (cp[\"visual.image.sourceRect.y\"] as number) ?? base.y,\n width: (cp[\"visual.image.sourceRect.width\"] as number) ?? base.width,\n height: (cp[\"visual.image.sourceRect.height\"] as number) ?? base.height,\n };\n }\n\n // Merge animated frameIndex\n if (cp[\"visual.image.frameIndex\"] !== undefined) {\n v.frameIndex = Math.floor(cp[\"visual.image.frameIndex\"] as number);\n }\n\n return v;\n }\n\n return visual;\n}\n","import type { ShapeVisual } from \"@a-company/atelier-types\";\nimport type { RenderContext } from \"../canvas-types.js\";\nimport type { EffectiveLayer } from \"../apply-properties.js\";\nimport { applyFill, applyStroke } from \"../styles.js\";\n\nexport function renderShape(ctx: RenderContext, eff: EffectiveLayer): void {\n const visual = eff.visual as ShapeVisual;\n const { shape } = visual;\n const { width, height } = eff;\n\n switch (shape.type) {\n case \"rect\":\n renderRect(ctx, width, height, shape.cornerRadius, visual);\n break;\n case \"ellipse\":\n renderEllipse(ctx, width, height, visual);\n break;\n case \"path\":\n renderPath(ctx, shape.points, shape.closed, visual);\n break;\n }\n}\n\n// ── Perimeter helpers ───────────────────────────────────────\n\nfunction rectPerimeter(w: number, h: number): number {\n return 2 * (w + h);\n}\n\nfunction ellipsePerimeter(w: number, h: number): number {\n const a = w / 2;\n const b = h / 2;\n // Ramanujan approximation\n return Math.PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (a + 3 * b)));\n}\n\nfunction dist(x1: number, y1: number, x2: number, y2: number): number {\n const dx = x2 - x1;\n const dy = y2 - y1;\n return Math.sqrt(dx * dx + dy * dy);\n}\n\nfunction pathPerimeter(\n points: { x: number; y: number; in?: { x: number; y: number }; out?: { x: number; y: number } }[],\n closed: boolean | undefined,\n): number {\n let length = 0;\n for (let i = 1; i < points.length; i++) {\n const prev = points[i - 1];\n const curr = points[i];\n if (prev.out && curr.in) {\n // Approximate bezier with chord * 1.2\n length += dist(prev.x, prev.y, curr.x, curr.y) * 1.2;\n } else {\n length += dist(prev.x, prev.y, curr.x, curr.y);\n }\n }\n if (closed && points.length > 1) {\n const first = points[0];\n const last = points[points.length - 1];\n length += dist(last.x, last.y, first.x, first.y);\n }\n return length;\n}\n\n// ── Renderers ───────────────────────────────────────────────\n\nfunction renderRect(\n ctx: RenderContext,\n width: number,\n height: number,\n cornerRadius: number | [number, number, number, number] | undefined,\n visual: ShapeVisual,\n): void {\n if (visual.fill) {\n applyFill(ctx, visual.fill, width, height);\n if (cornerRadius && ctx.roundRect) {\n ctx.beginPath();\n ctx.roundRect(0, 0, width, height, cornerRadius);\n ctx.fill();\n } else {\n ctx.fillRect(0, 0, width, height);\n }\n }\n if (visual.stroke) {\n const perimeter = rectPerimeter(width, height);\n applyStroke(ctx, visual.stroke, perimeter);\n if (cornerRadius && ctx.roundRect) {\n ctx.beginPath();\n ctx.roundRect(0, 0, width, height, cornerRadius);\n ctx.stroke();\n } else {\n ctx.strokeRect(0, 0, width, height);\n }\n }\n}\n\nfunction renderEllipse(\n ctx: RenderContext,\n width: number,\n height: number,\n visual: ShapeVisual,\n): void {\n ctx.beginPath();\n ctx.ellipse(width / 2, height / 2, width / 2, height / 2, 0, 0, Math.PI * 2);\n\n if (visual.fill) {\n applyFill(ctx, visual.fill, width, height);\n ctx.fill();\n }\n if (visual.stroke) {\n const perimeter = ellipsePerimeter(width, height);\n applyStroke(ctx, visual.stroke, perimeter);\n ctx.stroke();\n }\n}\n\nfunction renderPath(\n ctx: RenderContext,\n points: { x: number; y: number; in?: { x: number; y: number }; out?: { x: number; y: number } }[],\n closed: boolean | undefined,\n visual: ShapeVisual,\n): void {\n if (points.length < 2) return;\n\n ctx.beginPath();\n ctx.moveTo(points[0].x, points[0].y);\n\n for (let i = 1; i < points.length; i++) {\n const prev = points[i - 1];\n const curr = points[i];\n\n if (prev.out && curr.in) {\n ctx.bezierCurveTo(\n prev.x + prev.out.x, prev.y + prev.out.y,\n curr.x + curr.in.x, curr.y + curr.in.y,\n curr.x, curr.y,\n );\n } else {\n ctx.lineTo(curr.x, curr.y);\n }\n }\n\n if (closed) ctx.closePath();\n\n if (visual.fill) {\n applyFill(ctx, visual.fill, 0, 0);\n ctx.fill();\n }\n if (visual.stroke) {\n const perimeter = pathPerimeter(points, closed);\n applyStroke(ctx, visual.stroke, perimeter);\n ctx.stroke();\n }\n}\n","import type { TextVisual } from \"@a-company/atelier-types\";\nimport type { RenderContext } from \"../canvas-types.js\";\nimport type { EffectiveLayer } from \"../apply-properties.js\";\nimport { colorToCSS } from \"../styles.js\";\n\nexport function renderText(ctx: RenderContext, eff: EffectiveLayer): void {\n const visual = eff.visual as TextVisual;\n const { style } = visual;\n\n // Build font string\n const fontStyle = style.fontStyle ?? \"normal\";\n const fontWeight = style.fontWeight ?? \"normal\";\n const fontSize = style.fontSize;\n const fontFamily = style.fontFamily;\n ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;\n\n // Set alignment — position text within its bounding box\n const align = style.textAlign ?? \"left\";\n ctx.textAlign = align;\n ctx.textBaseline = \"top\";\n\n // Set color\n ctx.fillStyle = colorToCSS(style.color);\n\n // Canvas 2D textAlign anchors at the draw point, so offset within bounds:\n // \"left\" → draw at x=0 (text flows right from left edge)\n // \"center\" → draw at x=width/2 (text centers within bounds)\n // \"right\" → draw at x=width (text flows left from right edge)\n let textX = 0;\n if (align === \"center\") {\n textX = eff.width / 2;\n } else if (align === \"right\") {\n textX = eff.width;\n }\n\n ctx.fillText(visual.content, textX, 0);\n}\n","import type { ImageVisual } from \"@a-company/atelier-types\";\nimport type { RenderContext } from \"../canvas-types.js\";\nimport type { EffectiveLayer } from \"../apply-properties.js\";\nimport type { ImageCache } from \"../image-cache.js\";\n\n/**\n * Render an image layer to the canvas.\n * Supports sourceRect cropping and spritesheet grid animation.\n * If the image hasn't loaded yet, triggers a cache load and returns\n * (the image will appear on the next re-render).\n */\nexport function renderImage(ctx: RenderContext, eff: EffectiveLayer, imageCache: ImageCache): void {\n const visual = eff.visual as ImageVisual;\n const src = visual.src;\n if (!src) return;\n\n const img = imageCache.get(src);\n if (!img) {\n imageCache.load(src);\n return;\n }\n\n // Spritesheet grid computation takes precedence over manual sourceRect\n if (visual.spritesheet) {\n const { columns, rows, frameWidth, frameHeight, frameCount } = visual.spritesheet;\n const maxFrames = frameCount ?? (columns * rows);\n const idx = Math.max(0, Math.min(Math.floor(visual.frameIndex ?? 0), maxFrames - 1));\n const col = idx % columns;\n const row = Math.floor(idx / columns);\n const sx = col * frameWidth;\n const sy = row * frameHeight;\n (ctx.drawImage as Function)(img, sx, sy, frameWidth, frameHeight, 0, 0, eff.width, eff.height);\n return;\n }\n\n // Manual sourceRect crop\n if (visual.sourceRect) {\n const sr = visual.sourceRect;\n (ctx.drawImage as Function)(img, sr.x, sr.y, sr.width, sr.height, 0, 0, eff.width, eff.height);\n return;\n }\n\n // Default: draw full image to bounds\n ctx.drawImage(img, 0, 0, eff.width, eff.height);\n}\n","import type { AtelierDocument, RefVisual, ImageVisual } from \"@a-company/atelier-types\";\nimport { resolveFrame } from \"@a-company/atelier-core\";\nimport type { RenderContext, DocumentResolver } from \"../canvas-types.js\";\nimport type { EffectiveLayer } from \"../apply-properties.js\";\nimport { buildEffectiveLayer } from \"../apply-properties.js\";\nimport { renderShape } from \"./shape-renderer.js\";\nimport { renderText } from \"./text-renderer.js\";\nimport { renderImage } from \"./image-renderer.js\";\nimport type { ImageCache } from \"../image-cache.js\";\n\nexport interface RefRenderOpts {\n documentResolver?: DocumentResolver;\n maxRefDepth?: number;\n imageCache?: ImageCache;\n /** Internal: tracks visited refs for cycle detection */\n _visitedRefs?: Set<string>;\n /** Internal: current recursion depth */\n _depth?: number;\n}\n\n/**\n * Render a ref layer. If a documentResolver is provided, resolves and renders\n * the sub-document inline. Otherwise falls back to a placeholder rectangle.\n */\nexport function renderRef(\n ctx: RenderContext,\n eff: EffectiveLayer,\n opts?: RefRenderOpts,\n _parentDoc?: AtelierDocument,\n): void {\n const visual = eff.visual as RefVisual;\n const resolver = opts?.documentResolver;\n\n if (!resolver) {\n renderPlaceholder(ctx, eff, `REF: ${visual.src}`);\n return;\n }\n\n const depth = opts?._depth ?? 0;\n const maxDepth = opts?.maxRefDepth ?? 4;\n\n if (depth >= maxDepth) {\n renderPlaceholder(ctx, eff, \"MAX DEPTH\");\n return;\n }\n\n const visitedRefs = opts?._visitedRefs ?? new Set<string>();\n\n if (visitedRefs.has(visual.src)) {\n renderPlaceholder(ctx, eff, \"CYCLE\");\n return;\n }\n\n const subDoc = resolver(visual.src);\n if (!subDoc) {\n renderPlaceholder(ctx, eff, \"NOT FOUND\");\n return;\n }\n\n // Determine which state and frame to render\n const stateNames = Object.keys(subDoc.states);\n if (stateNames.length === 0) {\n renderPlaceholder(ctx, eff, \"NO STATES\");\n return;\n }\n\n const stateName = visual.state ?? stateNames[0];\n const stateObj = subDoc.states[stateName];\n if (!stateObj) {\n renderPlaceholder(ctx, eff, `STATE? ${stateName}`);\n return;\n }\n\n const maxFrame = Math.max(0, stateObj.duration - 1);\n const frame = Math.min(visual.frame ?? 0, maxFrame);\n\n // Resolve the sub-document frame\n const resolved = resolveFrame(subDoc, stateName, frame);\n\n // Mark as visited for cycle detection\n visitedRefs.add(visual.src);\n\n // Scale to fit eff bounds\n const scaleX = eff.width / subDoc.canvas.width;\n const scaleY = eff.height / subDoc.canvas.height;\n\n ctx.save();\n ctx.scale(scaleX, scaleY);\n\n // Build and render sub-doc layers\n const { width: subW, height: subH } = subDoc.canvas;\n\n for (const resolvedLayer of resolved.layers) {\n const subEff = buildEffectiveLayer(resolvedLayer, subW, subH);\n\n if (!subEff.visible) continue;\n if (subEff.opacity <= 0) continue;\n\n // Resolve asset for images\n if (resolvedLayer.layer.visual.type === \"image\") {\n const iv = subEff.visual as ImageVisual;\n if (!iv.src && iv.assetId && subDoc.assets?.[iv.assetId]) {\n iv.src = subDoc.assets[iv.assetId].src;\n }\n }\n\n ctx.save();\n ctx.globalAlpha = subEff.opacity;\n ctx.translate(subEff.x, subEff.y);\n\n switch (resolvedLayer.layer.visual.type) {\n case \"shape\":\n renderShape(ctx, subEff);\n break;\n case \"text\":\n renderText(ctx, subEff);\n break;\n case \"image\":\n if (opts?.imageCache) renderImage(ctx, subEff, opts.imageCache);\n break;\n case \"ref\":\n renderRef(ctx, subEff, {\n ...opts,\n _visitedRefs: visitedRefs,\n _depth: depth + 1,\n }, subDoc);\n break;\n case \"group\":\n break;\n }\n\n ctx.restore();\n }\n\n ctx.restore();\n\n // Remove from visited after rendering (allow same ref in different branches)\n visitedRefs.delete(visual.src);\n}\n\n/** Render a dashed placeholder rectangle with label */\nfunction renderPlaceholder(ctx: RenderContext, eff: EffectiveLayer, label: string): void {\n const { width, height } = eff;\n\n ctx.strokeStyle = \"#888888\";\n ctx.lineWidth = 2;\n ctx.setLineDash([6, 4]);\n ctx.strokeRect(0, 0, width, height);\n ctx.setLineDash([]);\n\n ctx.fillStyle = \"#888888\";\n ctx.font = `${Math.max(12, Math.min(16, height * 0.15))}px sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(label, width / 2, height / 2, width - 8);\n}\n","import type { AtelierDocument, ImageVisual, Shape } from \"@a-company/atelier-types\";\nimport type { ResolvedFrame } from \"@a-company/atelier-core\";\nimport type { RenderContext, DocumentResolver } from \"./canvas-types.js\";\nimport { buildEffectiveLayer, type EffectiveLayer } from \"./apply-properties.js\";\nimport { renderShape } from \"./renderers/shape-renderer.js\";\nimport { renderText } from \"./renderers/text-renderer.js\";\nimport { renderImage } from \"./renderers/image-renderer.js\";\nimport { renderRef } from \"./renderers/ref-renderer.js\";\nimport type { ImageCache } from \"./image-cache.js\";\n\n/** Options for renderFrame */\nexport interface RenderOptions {\n imageCache?: ImageCache;\n documentResolver?: DocumentResolver;\n maxRefDepth?: number;\n}\n\n/**\n * Render a resolved frame to a Canvas 2D context.\n * Clears the canvas and draws all visible layers in order.\n */\nexport function renderFrame(\n ctx: RenderContext,\n resolvedFrame: ResolvedFrame,\n doc: AtelierDocument,\n optsOrCache?: RenderOptions | ImageCache,\n): void {\n // Backward compatible: detect old ImageCache arg vs new RenderOptions\n let imageCache: ImageCache | undefined;\n let documentResolver: DocumentResolver | undefined;\n let maxRefDepth = 4;\n\n if (optsOrCache && typeof (optsOrCache as ImageCache).get === \"function\") {\n imageCache = optsOrCache as ImageCache;\n } else if (optsOrCache) {\n const opts = optsOrCache as RenderOptions;\n imageCache = opts.imageCache;\n documentResolver = opts.documentResolver;\n maxRefDepth = opts.maxRefDepth ?? 4;\n }\n const { width, height } = doc.canvas;\n\n // Clear canvas\n ctx.fillStyle = doc.canvas.background ?? \"transparent\";\n ctx.fillRect(0, 0, width, height);\n\n // Build effective layers into a map for ancestor transform lookups\n const effMap = new Map<string, EffectiveLayer>();\n const effList: EffectiveLayer[] = [];\n\n for (const resolvedLayer of resolvedFrame.layers) {\n const eff = buildEffectiveLayer(resolvedLayer, width, height);\n effMap.set(resolvedLayer.layer.id, eff);\n effList.push(eff);\n }\n\n // Render each layer in order (painters algorithm — first = back)\n for (const eff of effList) {\n const { layer } = eff;\n\n // Skip invisible layers\n if (!eff.visible) continue;\n\n // Skip fully transparent layers\n if (eff.opacity <= 0) continue;\n\n // Resolve assetId → src for image visuals\n if (layer.visual.type === \"image\") {\n const iv = eff.visual as ImageVisual;\n if (!iv.src && iv.assetId && doc.assets?.[iv.assetId]) {\n iv.src = doc.assets[iv.assetId].src;\n }\n }\n\n ctx.save();\n\n // Apply ancestor transforms (group/parent inheritance)\n applyAncestorTransforms(ctx, layer.id, effMap, doc);\n\n // Apply transforms\n ctx.globalAlpha = eff.opacity;\n\n // Apply blend mode\n if (eff.blendMode !== \"normal\") {\n ctx.globalCompositeOperation = blendModeToComposite(eff.blendMode);\n }\n\n ctx.translate(eff.x, eff.y);\n\n // Apply anchor-relative transforms\n const anchorPixelX = eff.anchorX * eff.width;\n const anchorPixelY = eff.anchorY * eff.height;\n\n // Combine explicit rotation with motion path auto-rotation\n const totalRotation = eff.rotation + eff.motionPathAngle;\n\n if (totalRotation !== 0 || eff.scaleX !== 1 || eff.scaleY !== 1) {\n ctx.translate(anchorPixelX, anchorPixelY);\n if (totalRotation !== 0) {\n ctx.rotate((totalRotation * Math.PI) / 180);\n }\n if (eff.scaleX !== 1 || eff.scaleY !== 1) {\n ctx.scale(eff.scaleX, eff.scaleY);\n }\n ctx.translate(-anchorPixelX, -anchorPixelY);\n }\n\n // Apply shadow if present\n if (eff.shadow) {\n ctx.shadowColor = eff.shadow.color;\n ctx.shadowBlur = eff.shadow.blur;\n ctx.shadowOffsetX = eff.shadow.offsetX;\n ctx.shadowOffsetY = eff.shadow.offsetY;\n }\n\n // Apply clip path if present\n if (layer.clipPath) {\n applyClipPath(ctx, layer.clipPath, eff.width, eff.height);\n }\n\n // Tint requires offscreen compositing — draw to offscreen if tint is active\n const hasTint = eff.tint && eff.tint.amount > 0 && ctx.createOffscreen;\n let renderCtx = ctx;\n let offscreen: { ctx: RenderContext; canvas: unknown } | null = null;\n\n if (hasTint) {\n offscreen = ctx.createOffscreen!(eff.width, eff.height);\n renderCtx = offscreen.ctx;\n }\n\n // Ref rendering options (passed through for sub-doc composition)\n const refOpts = { documentResolver, maxRefDepth, imageCache };\n\n // Dispatch to type-specific renderer\n switch (layer.visual.type) {\n case \"shape\":\n renderShape(renderCtx, eff);\n break;\n case \"text\":\n renderText(renderCtx, eff);\n break;\n case \"image\":\n if (imageCache) renderImage(renderCtx, eff, imageCache);\n break;\n case \"group\":\n // Groups are structural containers — no visual output\n break;\n case \"ref\":\n renderRef(renderCtx, eff, refOpts, doc);\n break;\n }\n\n // Apply tint via multiply composite on offscreen canvas\n if (hasTint && offscreen && eff.tint) {\n const offCtx = offscreen.ctx;\n // Draw tint color over the content using multiply\n offCtx.save();\n offCtx.globalCompositeOperation = \"multiply\";\n offCtx.fillStyle = eff.tint.color;\n offCtx.fillRect(0, 0, eff.width, eff.height);\n offCtx.restore();\n\n // Clip to original content shape using destination-in\n offCtx.save();\n offCtx.globalCompositeOperation = \"destination-in\";\n // Re-render the content to create the alpha mask\n switch (layer.visual.type) {\n case \"shape\": renderShape(offCtx, eff); break;\n case \"text\": renderText(offCtx, eff); break;\n case \"image\": if (imageCache) renderImage(offCtx, eff, imageCache); break;\n case \"ref\": renderRef(offCtx, eff, refOpts, doc); break;\n }\n offCtx.restore();\n\n // Blend tinted offscreen back with original at tint.amount alpha\n // First draw original content\n switch (layer.visual.type) {\n case \"shape\": renderShape(ctx, eff); break;\n case \"text\": renderText(ctx, eff); break;\n case \"image\": if (imageCache) renderImage(ctx, eff, imageCache); break;\n case \"ref\": renderRef(ctx, eff, refOpts, doc); break;\n }\n // Then overlay tinted version at tint amount\n const prevAlpha = ctx.globalAlpha;\n ctx.globalAlpha = eff.tint.amount;\n ctx.drawImage(offscreen.canvas, 0, 0, eff.width, eff.height);\n ctx.globalAlpha = prevAlpha;\n }\n\n ctx.restore();\n }\n}\n\n/** Apply a shape as a clipping region */\nfunction applyClipPath(ctx: RenderContext, shape: Shape, width: number, height: number): void {\n ctx.beginPath();\n switch (shape.type) {\n case \"rect\":\n if (shape.cornerRadius && ctx.roundRect) {\n ctx.roundRect(0, 0, width, height, shape.cornerRadius);\n } else {\n // Manual rect path for clipping (fillRect doesn't create a path)\n ctx.moveTo(0, 0);\n ctx.lineTo(width, 0);\n ctx.lineTo(width, height);\n ctx.lineTo(0, height);\n ctx.closePath();\n }\n break;\n case \"ellipse\":\n ctx.ellipse(width / 2, height / 2, width / 2, height / 2, 0, 0, Math.PI * 2);\n break;\n case \"path\":\n if (shape.points.length >= 2) {\n ctx.moveTo(shape.points[0].x, shape.points[0].y);\n for (let i = 1; i < shape.points.length; i++) {\n const prev = shape.points[i - 1];\n const curr = shape.points[i];\n if (prev.out && curr.in) {\n ctx.bezierCurveTo(\n prev.x + prev.out.x, prev.y + prev.out.y,\n curr.x + curr.in.x, curr.y + curr.in.y,\n curr.x, curr.y,\n );\n } else {\n ctx.lineTo(curr.x, curr.y);\n }\n }\n if (shape.closed) ctx.closePath();\n }\n break;\n }\n ctx.clip();\n}\n\n/** Map Atelier blend mode names to Canvas 2D globalCompositeOperation values */\nfunction blendModeToComposite(mode: string): string {\n const map: Record<string, string> = {\n \"multiply\": \"multiply\",\n \"screen\": \"screen\",\n \"overlay\": \"overlay\",\n \"darken\": \"darken\",\n \"lighten\": \"lighten\",\n \"color-dodge\": \"color-dodge\",\n \"color-burn\": \"color-burn\",\n \"hard-light\": \"hard-light\",\n \"soft-light\": \"soft-light\",\n \"difference\": \"difference\",\n \"exclusion\": \"exclusion\",\n \"hue\": \"hue\",\n \"saturation\": \"saturation\",\n \"color\": \"color\",\n \"luminosity\": \"luminosity\",\n };\n return map[mode] ?? \"source-over\";\n}\n\n/**\n * Walk the parentId chain and apply each ancestor's transforms.\n * This makes child layers inherit parent position/rotation/scale.\n */\nfunction applyAncestorTransforms(\n ctx: RenderContext,\n layerId: string,\n effMap: Map<string, EffectiveLayer>,\n doc: AtelierDocument,\n): void {\n // Collect ancestor chain (excluding self)\n const chain: EffectiveLayer[] = [];\n const layer = doc.layers.find((l) => l.id === layerId);\n let parentId = layer?.parentId;\n const visited = new Set<string>();\n\n while (parentId && !visited.has(parentId)) {\n visited.add(parentId);\n const parentEff = effMap.get(parentId);\n if (!parentEff) break;\n chain.push(parentEff);\n parentId = parentEff.layer.parentId;\n }\n\n // Apply from root ancestor down to direct parent\n for (let i = chain.length - 1; i >= 0; i--) {\n const p = chain[i];\n ctx.translate(p.x, p.y);\n\n const ax = p.anchorX * p.width;\n const ay = p.anchorY * p.height;\n\n if (p.rotation !== 0 || p.scaleX !== 1 || p.scaleY !== 1) {\n ctx.translate(ax, ay);\n if (p.rotation !== 0) ctx.rotate((p.rotation * Math.PI) / 180);\n if (p.scaleX !== 1 || p.scaleY !== 1) ctx.scale(p.scaleX, p.scaleY);\n ctx.translate(-ax, -ay);\n }\n }\n}\n","/**\n * A loaded image entry that can be drawn via RenderContext.drawImage.\n */\nexport interface CachedImage {\n complete: boolean;\n image: unknown;\n}\n\n/**\n * Simple image cache for loading and caching images.\n * Browser-agnostic — the actual Image constructor is injected via createImage.\n * Triggers an onLoad callback when an image finishes loading so the\n * renderer can re-render the current frame.\n */\nexport class ImageCache {\n private cache = new Map<string, CachedImage>();\n private loading = new Set<string>();\n private onLoad?: () => void;\n private createImage?: (src: string, onLoad: () => void, onError: () => void) => unknown;\n\n constructor(opts?: {\n onLoad?: () => void;\n createImage?: (src: string, onLoad: () => void, onError: () => void) => unknown;\n }) {\n this.onLoad = opts?.onLoad;\n this.createImage = opts?.createImage;\n }\n\n get(src: string): unknown | null {\n const entry = this.cache.get(src);\n return entry?.complete ? entry.image : null;\n }\n\n load(src: string): void {\n if (this.cache.has(src) || this.loading.has(src)) return;\n if (!this.createImage) return;\n this.loading.add(src);\n const image = this.createImage(\n src,\n () => {\n this.cache.set(src, { complete: true, image });\n this.loading.delete(src);\n this.onLoad?.();\n },\n () => {\n this.loading.delete(src);\n },\n );\n }\n}\n","// @a-company/atelier-cli — CLI tool: validate, preview, render, info commands\n\n// Command registration functions (for programmatic use)\nexport { validateCommand, validateFile } from \"./commands/validate.js\";\nexport { infoCommand, getInfo } from \"./commands/info.js\";\nexport type { DocumentInfo } from \"./commands/info.js\";\nexport { stillCommand, resolveStill } from \"./commands/still.js\";\nexport { renderCommand } from \"./commands/render.js\";\nexport { exportSvgCommand } from \"./commands/export-svg.js\";\nexport { exportLottieCommand } from \"./commands/export-lottie.js\";\nexport { assetsCommand, getAssets } from \"./commands/assets.js\";\nexport type { AssetInfo } from \"./commands/assets.js\";\nexport { variablesCommand, getVariables } from \"./commands/variables.js\";\nexport type { VariableInfo } from \"./commands/variables.js\";\nexport {\n checkFfmpeg,\n buildFfmpegArgs,\n renderDocument,\n} from \"./commands/render-pipeline.js\";\nexport type {\n RenderFormat,\n RenderOptions,\n RenderResult,\n ProgressInfo,\n} from \"./commands/render-pipeline.js\";\n","import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport { validateAllDeltas } from \"@a-company/atelier-core\";\n\n/**\n * Validate an .atelier file: parse YAML, check schema, check delta overlaps.\n * Returns { valid, errors } for programmatic use.\n */\nexport function validateFile(filePath: string): {\n valid: boolean;\n errors: string[];\n} {\n const absPath = resolve(filePath);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n return { valid: false, errors: [`Cannot read file: ${absPath}`] };\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n return {\n valid: false,\n errors: result.errors.map(\n (e) => `${e.path}: ${e.message}`,\n ),\n };\n }\n\n // Check all states for delta overlaps\n const overlapErrors: string[] = [];\n for (const [stateName, state] of Object.entries(result.data.states)) {\n const overlaps = validateAllDeltas(state.deltas);\n for (const overlap of overlaps) {\n overlapErrors.push(`State \"${stateName}\": ${overlap.message}`);\n }\n }\n\n if (overlapErrors.length > 0) {\n return { valid: false, errors: overlapErrors };\n }\n\n return { valid: true, errors: [] };\n}\n\n/**\n * Register the `validate` subcommand on the Commander program.\n */\nexport function validateCommand(program: Command): void {\n program\n .command(\"validate <file>\")\n .description(\"Validate an .atelier YAML file\")\n .action((file: string) => {\n const { valid, errors } = validateFile(file);\n if (valid) {\n console.log(\"Valid\");\n } else {\n console.error(\"Validation errors:\");\n for (const error of errors) {\n console.error(` - ${error}`);\n }\n process.exit(1);\n }\n });\n}\n","import { z } from \"zod\";\n\n/** Pixel value — any number */\nexport const PixelSchema = z.number();\n\n/** Percentage string like \"50%\" */\nexport const PercentageSchema = z.string().regex(/^-?\\d+(\\.\\d+)?%$/, {\n message: \"Percentage must be a number followed by %, e.g. \\\"50%\\\"\",\n});\n\n/** Either pixel or percentage */\nexport const UnitValueSchema = z.union([PixelSchema, PercentageSchema]);\n","import { z } from \"zod\";\nimport { UnitValueSchema } from \"./units.js\";\n\nexport const FrameSchema = z.object({\n x: UnitValueSchema,\n y: UnitValueSchema,\n});\n\nexport const BoundsSchema = z.object({\n width: UnitValueSchema,\n height: UnitValueSchema,\n});\n\nexport const AnchorPointSchema = z.object({\n x: z.number().min(0).max(1),\n y: z.number().min(0).max(1),\n});\n","import { z } from \"zod\";\n\nexport const RGBAColorSchema = z.object({\n r: z.number().min(0).max(255),\n g: z.number().min(0).max(255),\n b: z.number().min(0).max(255),\n a: z.number().min(0).max(1),\n});\n\nexport const HSLAColorSchema = z.object({\n h: z.number().min(0).max(360),\n s: z.number().min(0).max(100),\n l: z.number().min(0).max(100),\n a: z.number().min(0).max(1),\n});\n\nexport const HexColorSchema = z.string().regex(/^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/, {\n message: \"Color must be a hex string: #RGB, #RGBA, #RRGGBB, or #RRGGBBAA\",\n});\n\nexport const ColorSchema = z.union([RGBAColorSchema, HSLAColorSchema, HexColorSchema]);\n","import { z } from \"zod\";\nimport { ColorSchema } from \"./color.js\";\nimport { UnitValueSchema } from \"./units.js\";\n\nexport const PathPointSchema = z.object({\n x: z.number(),\n y: z.number(),\n in: z.object({ x: z.number(), y: z.number() }).optional(),\n out: z.object({ x: z.number(), y: z.number() }).optional(),\n});\n\nexport const RectShapeSchema = z.object({\n type: z.literal(\"rect\"),\n cornerRadius: z.union([\n z.number().min(0),\n z.tuple([z.number().min(0), z.number().min(0), z.number().min(0), z.number().min(0)]),\n ]).optional(),\n});\n\nexport const EllipseShapeSchema = z.object({\n type: z.literal(\"ellipse\"),\n});\n\nexport const PathShapeSchema = z.object({\n type: z.literal(\"path\"),\n points: z.array(PathPointSchema).min(2, \"Path must have at least 2 points\"),\n closed: z.boolean().optional(),\n});\n\nexport const ShapeSchema = z.discriminatedUnion(\"type\", [\n RectShapeSchema,\n EllipseShapeSchema,\n PathShapeSchema,\n]);\n\nexport const GradientStopSchema = z.object({\n offset: z.number().min(0).max(1),\n color: ColorSchema,\n});\n\nexport const SolidFillSchema = z.object({\n type: z.literal(\"solid\"),\n color: ColorSchema,\n});\n\nexport const LinearGradientFillSchema = z.object({\n type: z.literal(\"linear-gradient\"),\n angle: z.number(),\n stops: z.array(GradientStopSchema).min(2, \"Gradient needs at least 2 stops\"),\n});\n\nexport const RadialGradientFillSchema = z.object({\n type: z.literal(\"radial-gradient\"),\n center: z.object({ x: UnitValueSchema, y: UnitValueSchema }),\n radius: UnitValueSchema,\n stops: z.array(GradientStopSchema).min(2, \"Gradient needs at least 2 stops\"),\n});\n\nexport const FillSchema = z.discriminatedUnion(\"type\", [\n SolidFillSchema,\n LinearGradientFillSchema,\n RadialGradientFillSchema,\n]);\n\nexport const StrokeSchema = z.object({\n color: ColorSchema,\n width: z.number().min(0),\n dash: z.array(z.number().min(0)).optional(),\n lineCap: z.enum([\"butt\", \"round\", \"square\"]).optional(),\n lineJoin: z.enum([\"miter\", \"round\", \"bevel\"]).optional(),\n strokeStart: z.number().min(0).max(1).optional(),\n strokeEnd: z.number().min(0).max(1).optional(),\n});\n\nexport const TextStyleSchema = z.object({\n fontFamily: z.string().min(1, \"fontFamily is required\"),\n fontSize: z.number().positive(\"fontSize must be positive\"),\n fontWeight: z.union([z.number(), z.enum([\"normal\", \"bold\"])]).optional(),\n fontStyle: z.enum([\"normal\", \"italic\"]).optional(),\n textAlign: z.enum([\"left\", \"center\", \"right\"]).optional(),\n lineHeight: z.number().positive().optional(),\n letterSpacing: z.number().optional(),\n color: ColorSchema,\n});\n","import { z } from \"zod\";\n\nexport const LinearEasingSchema = z.object({ type: z.literal(\"linear\") });\n\nexport const CubicBezierEasingSchema = z.object({\n type: z.literal(\"cubic-bezier\"),\n x1: z.number().min(0).max(1),\n y1: z.number(),\n x2: z.number().min(0).max(1),\n y2: z.number(),\n});\n\nexport const SpringEasingSchema = z.object({\n type: z.literal(\"spring\"),\n mass: z.number().positive().optional(),\n stiffness: z.number().positive().optional(),\n damping: z.number().positive().optional(),\n velocity: z.number().optional(),\n});\n\nexport const StepEasingSchema = z.object({\n type: z.literal(\"step\"),\n steps: z.number().int().positive(),\n position: z.enum([\"start\", \"end\"]).optional(),\n});\n\nexport const EasingPresetSchema = z.enum([\"ease-in\", \"ease-out\", \"ease-in-out\"]);\n\nexport const EasingSchema = z.union([\n LinearEasingSchema,\n CubicBezierEasingSchema,\n SpringEasingSchema,\n StepEasingSchema,\n EasingPresetSchema,\n]);\n","import { z } from \"zod\";\nimport { ColorSchema } from \"./color.js\";\n\nexport const ShadowSchema = z.object({\n color: ColorSchema,\n blur: z.number().min(0),\n offsetX: z.number().optional(),\n offsetY: z.number().optional(),\n});\n","import { z } from \"zod\";\nimport { ShapeSchema, FillSchema, StrokeSchema, TextStyleSchema, PathPointSchema } from \"./shape.js\";\nimport { FrameSchema, BoundsSchema, AnchorPointSchema } from \"./coordinates.js\";\nimport { ShadowSchema } from \"./shadow.js\";\nimport { InteractionSchema } from \"./interaction.js\";\n\nexport const BlendModeSchema = z.enum([\n \"normal\", \"multiply\", \"screen\", \"overlay\",\n \"darken\", \"lighten\", \"color-dodge\", \"color-burn\",\n \"hard-light\", \"soft-light\", \"difference\", \"exclusion\",\n \"hue\", \"saturation\", \"color\", \"luminosity\",\n]);\n\nexport const MotionPathSchema = z.object({\n points: z.array(PathPointSchema).min(2, \"Motion path must have at least 2 points\"),\n closed: z.boolean().optional(),\n autoRotate: z.boolean().optional(),\n autoRotateOffset: z.number().optional(),\n});\n\nexport const ShapeVisualSchema = z.object({\n type: z.literal(\"shape\"),\n shape: ShapeSchema,\n fill: FillSchema.optional(),\n stroke: StrokeSchema.optional(),\n});\n\nexport const TextVisualSchema = z.object({\n type: z.literal(\"text\"),\n content: z.string(),\n style: TextStyleSchema,\n});\n\nexport const SpritesheetConfigSchema = z.object({\n columns: z.number().int().positive(),\n rows: z.number().int().positive(),\n frameCount: z.number().int().positive().optional(),\n frameWidth: z.number().positive(),\n frameHeight: z.number().positive(),\n});\n\nexport const SourceRectSchema = z.object({\n x: z.number(),\n y: z.number(),\n width: z.number().positive(),\n height: z.number().positive(),\n});\n\nexport const ImageVisualSchema = z.object({\n type: z.literal(\"image\"),\n assetId: z.string().min(1, \"assetId is required\"),\n src: z.string().optional(),\n sourceRect: SourceRectSchema.optional(),\n spritesheet: SpritesheetConfigSchema.optional(),\n frameIndex: z.number().int().min(0).optional(),\n});\n\nexport const GroupVisualSchema = z.object({\n type: z.literal(\"group\"),\n});\n\nexport const RefVisualSchema = z.object({\n type: z.literal(\"ref\"),\n src: z.string().min(1, \"src is required\"),\n state: z.string().optional(),\n frame: z.number().int().min(0).optional(),\n});\n\nexport const VisualSchema = z.discriminatedUnion(\"type\", [\n ShapeVisualSchema,\n TextVisualSchema,\n ImageVisualSchema,\n GroupVisualSchema,\n RefVisualSchema,\n]);\n\nexport const LayerSchema = z.object({\n id: z.string().min(1, \"Layer id is required\"),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n visual: VisualSchema,\n frame: FrameSchema,\n bounds: BoundsSchema,\n anchorPoint: AnchorPointSchema.optional(),\n parentId: z.string().optional(),\n opacity: z.number().min(0).max(1).optional(),\n rotation: z.number().optional(),\n scale: z.object({ x: z.number(), y: z.number() }).optional(),\n visible: z.boolean().optional(),\n shadow: ShadowSchema.optional(),\n blendMode: BlendModeSchema.optional(),\n motionPath: MotionPathSchema.optional(),\n clipPath: ShapeSchema.optional(),\n tint: z.object({\n color: z.string(),\n amount: z.number().min(0).max(1),\n }).optional(),\n interactions: z.array(InteractionSchema).optional(),\n});\n","import { z } from \"zod\";\n\nexport const TriggerTypeSchema = z.enum([\n \"click\", \"hover\", \"pointerdown\", \"pointerup\", \"timer\", \"signal\",\n]);\n\nexport const TriggerSchema = z.object({\n type: TriggerTypeSchema,\n delay: z.number().nonnegative(\"Timer delay must be non-negative\").optional(),\n signal: z.string().optional(),\n}).refine(\n (t) => t.type !== \"timer\" || t.delay !== undefined,\n { message: \"Timer trigger requires a delay\" },\n).refine(\n (t) => t.type !== \"signal\" || t.signal !== undefined,\n { message: \"Signal trigger requires a signal name\" },\n);\n\nexport const ActionTypeSchema = z.enum([\n \"go-to-state\", \"emit-signal\", \"set-variable\", \"toggle-visibility\",\n]);\n\nexport const ActionSchema = z.object({\n type: ActionTypeSchema,\n state: z.string().optional(),\n signal: z.string().optional(),\n variable: z.string().optional(),\n value: z.unknown().optional(),\n targetLayer: z.string().optional(),\n}).refine(\n (a) => a.type !== \"go-to-state\" || a.state !== undefined,\n { message: \"go-to-state action requires a state name\" },\n).refine(\n (a) => a.type !== \"emit-signal\" || a.signal !== undefined,\n { message: \"emit-signal action requires a signal name\" },\n).refine(\n (a) => a.type !== \"set-variable\" || (a.variable !== undefined && a.value !== undefined),\n { message: \"set-variable action requires variable and value\" },\n);\n\nexport const InteractionSchema = z.object({\n id: z.string().min(1, \"Interaction id is required\"),\n trigger: TriggerSchema,\n action: ActionSchema,\n description: z.string().optional(),\n});\n","import { z } from \"zod\";\nimport { EasingSchema } from \"./easing.js\";\n\nexport const AnimatablePropertySchema = z.enum([\n \"frame.x\",\n \"frame.y\",\n \"bounds.width\",\n \"bounds.height\",\n \"opacity\",\n \"rotation\",\n \"scale.x\",\n \"scale.y\",\n \"anchorPoint.x\",\n \"anchorPoint.y\",\n \"visual.shape.cornerRadius\",\n \"visual.fill.color\",\n \"visual.stroke.color\",\n \"visual.stroke.width\",\n \"visual.stroke.start\",\n \"visual.stroke.end\",\n \"visual.style.fontSize\",\n \"visual.style.color\",\n \"shadow.color\",\n \"shadow.blur\",\n \"shadow.offsetX\",\n \"shadow.offsetY\",\n \"motionPath.progress\",\n \"visual.fill.angle\",\n \"visual.fill.center.x\",\n \"visual.fill.center.y\",\n \"visual.fill.radius\",\n \"visual.image.sourceRect.x\",\n \"visual.image.sourceRect.y\",\n \"visual.image.sourceRect.width\",\n \"visual.image.sourceRect.height\",\n \"visual.image.frameIndex\",\n \"visible\",\n \"tint.color\",\n \"tint.amount\",\n]);\n\nexport const FrameRangeSchema = z.tuple([\n z.number().int().min(0, \"Frame start must be >= 0\"),\n z.number().int().min(0, \"Frame end must be >= 0\"),\n]).refine(([start, end]) => end >= start, {\n message: \"Frame range end must be >= start\",\n});\n\nexport const DeltaSchema = z.object({\n id: z.string().optional(),\n name: z.string().optional(),\n layer: z.string().min(1, \"Delta must reference a layer id\"),\n property: AnimatablePropertySchema,\n range: FrameRangeSchema,\n from: z.unknown(),\n to: z.unknown(),\n easing: EasingSchema.optional(),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n});\n","import { z } from \"zod\";\nimport { DeltaSchema } from \"./delta.js\";\nimport { EasingSchema } from \"./easing.js\";\n\nexport const AudioSchema = z.object({\n src: z.string().min(1, \"Audio src is required\"),\n offset: z.number().min(0, \"Audio offset must be non-negative\").optional(),\n volume: z.number().min(0).max(1, \"Audio volume must be 0–1\").optional(),\n loop: z.boolean().optional(),\n startFrame: z.number().int().min(0, \"Audio startFrame must be a non-negative integer\").optional(),\n});\n\nexport const StateTransitionConfigSchema = z.object({\n duration: z.number().int().positive(\"Transition duration must be a positive integer (frames)\"),\n easing: EasingSchema.optional(),\n});\n\nexport const StateSchema = z.object({\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n parent: z.string().optional(),\n duration: z.number().int().positive(\"State duration must be a positive integer (frames)\"),\n deltas: z.array(DeltaSchema),\n audio: AudioSchema.optional(),\n transitions: z.record(z.string(), StateTransitionConfigSchema).optional(),\n});\n","import { z } from \"zod\";\nimport { AnimatablePropertySchema } from \"./delta.js\";\nimport { EasingSchema } from \"./easing.js\";\n\nexport const PresetDeltaSchema = z.object({\n property: AnimatablePropertySchema,\n offset: z.tuple([z.number().int().min(0), z.number().int().min(0)]).optional(),\n from: z.unknown(),\n to: z.unknown(),\n easing: EasingSchema.optional(),\n});\n\nexport const PresetSchema = z.object({\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n deltas: z.array(PresetDeltaSchema).min(1, \"Preset must have at least one delta\"),\n});\n","import { z } from \"zod\";\n\nexport const VariableTypeSchema = z.enum([\"string\", \"number\", \"color\", \"asset\", \"boolean\"]);\n\nexport const VariableSchema = z.object({\n type: VariableTypeSchema,\n default: z.unknown().optional(),\n description: z.string().optional(),\n});\n","import { z } from \"zod\";\n\nexport const AssetTypeSchema = z.enum([\"image\", \"svg\", \"font\", \"animation\", \"audio\"]);\n\nexport const AssetSchema = z.object({\n type: AssetTypeSchema,\n src: z.string().min(1, \"Asset src is required\"),\n description: z.string().optional(),\n spritesheet: z.object({\n columns: z.number().int().positive(),\n rows: z.number().int().positive(),\n frameCount: z.number().int().positive().optional(),\n frameWidth: z.number().positive(),\n frameHeight: z.number().positive(),\n }).optional(),\n});\n","import { z } from \"zod\";\nimport { LayerSchema } from \"./layer.js\";\nimport { StateSchema } from \"./state.js\";\nimport { PresetSchema } from \"./preset.js\";\nimport { VariableSchema } from \"./variable.js\";\nimport { AssetSchema } from \"./asset.js\";\n\nexport const CanvasSchema = z.object({\n width: z.number().int().positive(\"Canvas width must be a positive integer\"),\n height: z.number().int().positive(\"Canvas height must be a positive integer\"),\n fps: z.number().int().positive(\"FPS must be a positive integer\"),\n background: z.string().optional(),\n});\n\nexport const AtelierDocumentSchema = z.object({\n version: z.string().min(1, \"Version is required\"),\n name: z.string().min(1, \"Animation name is required\"),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n canvas: CanvasSchema,\n variables: z.record(z.string(), VariableSchema).optional(),\n assets: z.record(z.string(), AssetSchema).optional(),\n presets: z.record(z.string(), PresetSchema).optional(),\n layers: z.array(LayerSchema),\n states: z.record(z.string(), StateSchema),\n});\n","import type { AtelierDocument, Layer, Delta } from \"@a-company/atelier-types\";\nimport { AtelierDocumentSchema } from \"./document.js\";\nimport { LayerSchema } from \"./layer.js\";\nimport { DeltaSchema } from \"./delta.js\";\nimport type { z } from \"zod\";\n\n/** Validation result — either success with typed data or failure with readable errors */\nexport type ValidationResult<T> =\n | { success: true; data: T }\n | { success: false; errors: ValidationError[] };\n\nexport interface ValidationError {\n path: string;\n message: string;\n}\n\n/** Format Zod errors into flat, AI-readable error messages */\nfunction formatErrors(error: z.ZodError): ValidationError[] {\n return error.issues.map((issue) => ({\n path: issue.path.join(\".\") || \"(root)\",\n message: issue.message,\n }));\n}\n\n/** Validate a complete AtelierDocument */\nexport function validateDocument(input: unknown): ValidationResult<AtelierDocument> {\n const result = AtelierDocumentSchema.safeParse(input);\n if (result.success) {\n return { success: true, data: result.data as AtelierDocument };\n }\n return { success: false, errors: formatErrors(result.error) };\n}\n\n/** Validate a single Layer */\nexport function validateLayer(input: unknown): ValidationResult<Layer> {\n const result = LayerSchema.safeParse(input);\n if (result.success) {\n return { success: true, data: result.data as Layer };\n }\n return { success: false, errors: formatErrors(result.error) };\n}\n\n/** Validate a single Delta */\nexport function validateDelta(input: unknown): ValidationResult<Delta> {\n const result = DeltaSchema.safeParse(input);\n if (result.success) {\n return { success: true, data: result.data as Delta };\n }\n return { success: false, errors: formatErrors(result.error) };\n}\n","import { parse as yamlParse, stringify as yamlStringify } from \"yaml\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { validateDocument } from \"./validate.js\";\nimport type { ValidationResult } from \"./validate.js\";\n\n/**\n * Parse a YAML string into a validated AtelierDocument.\n * Returns validation errors if the YAML is invalid or doesn't match the schema.\n */\nexport function parseAtelier(yamlString: string): ValidationResult<AtelierDocument> {\n let parsed: unknown;\n try {\n parsed = yamlParse(yamlString);\n } catch (err) {\n return {\n success: false,\n errors: [{ path: \"(yaml)\", message: `YAML parse error: ${(err as Error).message}` }],\n };\n }\n return validateDocument(parsed);\n}\n\n/**\n * Serialize an AtelierDocument to YAML string.\n */\nexport function serializeAtelier(doc: AtelierDocument): string {\n return yamlStringify(doc, { indent: 2 });\n}\n","import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\n\n/**\n * Info summary for an AtelierDocument.\n */\nexport interface DocumentInfo {\n name: string;\n description?: string;\n canvas: {\n width: number;\n height: number;\n fps: number;\n background?: string;\n };\n layers: {\n count: number;\n items: { id: string; type: string }[];\n };\n states: {\n count: number;\n items: { name: string; duration: number; deltaCount: number }[];\n };\n presets: {\n count: number;\n };\n}\n\n/**\n * Extract summary info from a parsed AtelierDocument.\n */\nexport function getInfo(doc: AtelierDocument): DocumentInfo {\n return {\n name: doc.name,\n description: doc.description,\n canvas: {\n width: doc.canvas.width,\n height: doc.canvas.height,\n fps: doc.canvas.fps,\n background: doc.canvas.background,\n },\n layers: {\n count: doc.layers.length,\n items: doc.layers.map((layer) => ({\n id: layer.id,\n type: layer.visual.type,\n })),\n },\n states: {\n count: Object.keys(doc.states).length,\n items: Object.entries(doc.states).map(([name, state]) => ({\n name,\n duration: state.duration,\n deltaCount: state.deltas.length,\n })),\n },\n presets: {\n count: doc.presets ? Object.keys(doc.presets).length : 0,\n },\n };\n}\n\n/**\n * Format a DocumentInfo for terminal output.\n */\nfunction formatInfo(info: DocumentInfo): string {\n const lines: string[] = [];\n\n lines.push(`Name: ${info.name}`);\n if (info.description) {\n lines.push(`Description: ${info.description}`);\n }\n\n const bg = info.canvas.background\n ? `, background: ${info.canvas.background}`\n : \"\";\n lines.push(\n `Canvas: ${info.canvas.width}x${info.canvas.height} @ ${info.canvas.fps}fps${bg}`,\n );\n\n lines.push(`Layers: ${info.layers.count}`);\n for (const layer of info.layers.items) {\n lines.push(` - ${layer.id} (${layer.type})`);\n }\n\n lines.push(`States: ${info.states.count}`);\n for (const state of info.states.items) {\n lines.push(\n ` - ${state.name}: ${state.duration} frames, ${state.deltaCount} deltas`,\n );\n }\n\n if (info.presets.count > 0) {\n lines.push(`Presets: ${info.presets.count}`);\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/**\n * Register the `info` subcommand on the Commander program.\n */\nexport function infoCommand(program: Command): void {\n program\n .command(\"info <file>\")\n .description(\"Display summary info for an .atelier file\")\n .action((file: string) => {\n const doc = readAndParse(file);\n const info = getInfo(doc);\n console.log(formatInfo(info));\n });\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport { resolveFrame } from \"@a-company/atelier-core\";\nimport type { ResolvedFrame } from \"@a-company/atelier-core\";\n\n/**\n * Resolve a single frame from a document, returning the resolved frame data.\n * If stateName is not provided, uses the first state.\n * If frame is not provided, uses frame 0.\n */\nexport function resolveStill(\n doc: AtelierDocument,\n stateName?: string,\n frame?: number,\n): ResolvedFrame {\n const stateNames = Object.keys(doc.states);\n if (stateNames.length === 0) {\n throw new Error(\"Document has no states\");\n }\n\n const resolvedStateName = stateName ?? stateNames[0];\n if (!(resolvedStateName in doc.states)) {\n throw new Error(\n `State \"${resolvedStateName}\" not found. Available: ${stateNames.join(\", \")}`,\n );\n }\n\n const resolvedFrame = frame ?? 0;\n return resolveFrame(doc, resolvedStateName, resolvedFrame);\n}\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/**\n * Register the `still` subcommand on the Commander program.\n */\nexport function stillCommand(program: Command): void {\n program\n .command(\"still <file>\")\n .description(\n \"Resolve a single frame and output as JSON or render as PNG\",\n )\n .option(\"-s, --state <name>\", \"State name (defaults to first state)\")\n .option(\n \"-f, --frame <number>\",\n \"Frame number (defaults to 0)\",\n \"0\",\n )\n .option(\n \"--format <type>\",\n \"Output format: json | png (default: json)\",\n \"json\",\n )\n .option(\"-o, --output <path>\", \"Output file path (default: stdout)\")\n .action(\n async (\n file: string,\n options: { state?: string; frame: string; format: string; output?: string },\n ) => {\n const doc = readAndParse(file);\n\n const frameNumber = parseInt(options.frame, 10);\n if (isNaN(frameNumber) || frameNumber < 0) {\n console.error(\n `Invalid frame number: ${options.frame}`,\n );\n process.exit(1);\n return;\n }\n\n if (options.format !== \"json\" && options.format !== \"png\") {\n console.error(`Unknown format: \"${options.format}\". Use json or png.`);\n process.exit(1);\n return;\n }\n\n try {\n const resolved = resolveStill(\n doc,\n options.state,\n frameNumber,\n );\n\n if (options.format === \"json\") {\n const json = JSON.stringify(resolved, null, 2);\n if (options.output) {\n writeFileSync(resolve(options.output), json, \"utf-8\");\n } else {\n console.log(json);\n }\n } else {\n // PNG format — dynamic import of canvas\n let canvasMod: typeof import(\"canvas\");\n try {\n canvasMod = await import(\"canvas\");\n } catch {\n console.error(\"PNG output requires the 'canvas' package. Install it: npm i canvas\");\n process.exit(1);\n return;\n }\n\n const { renderFrame } = await import(\"@a-company/atelier-canvas\");\n\n const { createCanvas } = canvasMod;\n const cvs = createCanvas(doc.canvas.width, doc.canvas.height);\n const ctx = cvs.getContext(\"2d\");\n renderFrame(ctx as unknown as import(\"@a-company/atelier-canvas\").RenderContext, resolved, doc);\n\n const buffer = cvs.toBuffer(\"image/png\");\n if (options.output) {\n writeFileSync(resolve(options.output), buffer);\n } else {\n process.stdout.write(buffer);\n }\n }\n } catch (err) {\n console.error(\n (err as Error).message,\n );\n process.exit(1);\n }\n },\n );\n}\n","/**\n * `atelier render <file>` — render an animation to MP4 or GIF via FFmpeg.\n *\n * Usage:\n * atelier render animation.atelier → animation.mp4\n * atelier render animation.atelier -f gif → animation.gif\n * atelier render animation.atelier -o out/video.mp4 → custom path\n * atelier render animation.atelier -s intro outro → specific states\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { resolve, basename, extname } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport {\n checkFfmpeg,\n renderDocument,\n type RenderFormat,\n} from \"./render-pipeline.js\";\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\nfunction inferFormat(output: string | undefined): RenderFormat {\n if (!output) return \"mp4\";\n const ext = extname(output).toLowerCase();\n if (ext === \".gif\") return \"gif\";\n return \"mp4\";\n}\n\n/** Register the `render` subcommand on the Commander program. */\nexport function renderCommand(program: Command): void {\n program\n .command(\"render <file>\")\n .description(\"Render animation to MP4 or GIF via FFmpeg\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .option(\"-f, --format <type>\", \"Output format: mp4 | gif\")\n .option(\n \"-s, --state <names...>\",\n \"State(s) to render (default: all in order)\",\n )\n .action(\n async (\n file: string,\n options: {\n output?: string;\n format?: string;\n state?: string[];\n },\n ) => {\n // Check FFmpeg availability\n const hasFfmpeg = await checkFfmpeg();\n if (!hasFfmpeg) {\n console.error(\"FFmpeg is not installed or not in PATH.\");\n console.error(\"Install it:\");\n console.error(\" macOS: brew install ffmpeg\");\n console.error(\" Ubuntu: sudo apt install ffmpeg\");\n console.error(\" Windows: https://ffmpeg.org/download.html\");\n process.exit(1);\n return;\n }\n\n const doc = readAndParse(file);\n\n // Resolve format\n let format: RenderFormat;\n if (options.format) {\n if (options.format !== \"mp4\" && options.format !== \"gif\") {\n console.error(\n `Unknown format: \"${options.format}\". Use mp4 or gif.`,\n );\n process.exit(1);\n return;\n }\n format = options.format;\n } else {\n format = inferFormat(options.output);\n }\n\n // Resolve output path\n const inputName = basename(file, extname(file));\n const output = options.output ?? `${inputName}.${format}`;\n\n const startTime = Date.now();\n\n try {\n const result = await renderDocument(doc, {\n output: resolve(output),\n format,\n states: options.state,\n onProgress: ({ frame, totalFrames, state, percent }) => {\n const elapsed = (Date.now() - startTime) / 1000;\n const rate = elapsed > 0 ? frame / elapsed : 0;\n const remaining =\n rate > 0 ? (totalFrames - frame) / rate : 0;\n process.stderr.write(\n `\\rRendering: frame ${frame}/${totalFrames} (${percent}%) - state \"${state}\" - ETA ${remaining.toFixed(1)}s`,\n );\n },\n });\n\n process.stderr.write(\"\\n\");\n console.log(\n `Done: ${result.totalFrames} frames \\u2192 ${result.output} (${(result.durationMs / 1000).toFixed(1)}s)`,\n );\n } catch (err) {\n process.stderr.write(\"\\n\");\n console.error((err as Error).message);\n process.exit(1);\n }\n },\n );\n}\n","/**\n * Core render pipeline — renders an Atelier document to MP4 or GIF via FFmpeg.\n * Pure pipeline with no Commander dependency; testable in isolation.\n */\n\nimport { spawn } from \"node:child_process\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { resolveFrame } from \"@a-company/atelier-core\";\nimport { renderFrame, ImageCache } from \"@a-company/atelier-canvas\";\n\n// ─── Types ───────────────────────────────────────────────────\n\nexport type RenderFormat = \"mp4\" | \"gif\";\n\nexport interface RenderOptions {\n output: string;\n format: RenderFormat;\n states?: string[];\n onProgress?: (info: ProgressInfo) => void;\n}\n\nexport interface ProgressInfo {\n frame: number;\n totalFrames: number;\n state: string;\n percent: number;\n}\n\nexport interface RenderResult {\n output: string;\n format: RenderFormat;\n totalFrames: number;\n states: string[];\n durationMs: number;\n}\n\n// ─── FFmpeg Helpers ──────────────────────────────────────────\n\n/** Check whether FFmpeg is available on the system PATH. */\nexport async function checkFfmpeg(): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn(\"ffmpeg\", [\"-version\"], { stdio: \"pipe\" });\n proc.on(\"error\", () => resolve(false));\n proc.on(\"close\", (code) => resolve(code === 0));\n });\n}\n\n/** Build the FFmpeg argument array for the given format. Pure function. */\nexport function buildFfmpegArgs(\n width: number,\n height: number,\n fps: number,\n format: RenderFormat,\n output: string,\n): string[] {\n const input = [\n \"-y\",\n \"-f\", \"rawvideo\",\n \"-pix_fmt\", \"bgra\",\n \"-s\", `${width}x${height}`,\n \"-r\", String(fps),\n \"-i\", \"pipe:0\",\n ];\n\n if (format === \"mp4\") {\n return [\n ...input,\n \"-c:v\", \"libx264\",\n \"-pix_fmt\", \"yuv420p\",\n \"-preset\", \"medium\",\n \"-crf\", \"18\",\n \"-movflags\", \"+faststart\",\n output,\n ];\n }\n\n // GIF — single-pass palette generation (stdin-compatible)\n return [\n ...input,\n \"-vf\", \"split[s0][s1];[s0]palettegen=stats_mode=single[p];[s1][p]paletteuse=dither=sierra2_4a\",\n \"-loop\", \"0\",\n output,\n ];\n}\n\n// ─── Image Pre-loading ───────────────────────────────────────\n\n/**\n * Scan document layers for image visuals, pre-load them with node-canvas\n * loadImage, and return a populated ImageCache ready for rendering.\n */\nasync function preloadImages(\n doc: AtelierDocument,\n loadImage: (src: string) => Promise<unknown>,\n): Promise<ImageCache> {\n const sources = new Set<string>();\n\n for (const layer of doc.layers) {\n if (layer.visual.type === \"image\") {\n const iv = layer.visual as { src?: string; assetId?: string };\n if (iv.src) {\n sources.add(iv.src);\n } else if (iv.assetId && doc.assets?.[iv.assetId]) {\n sources.add(doc.assets[iv.assetId].src);\n }\n }\n }\n\n if (sources.size === 0) {\n return new ImageCache();\n }\n\n // Load all images in parallel\n const preloaded = new Map<string, unknown>();\n await Promise.all(\n [...sources].map(async (src) => {\n try {\n preloaded.set(src, await loadImage(src));\n } catch {\n // Images that fail to load will render as blank\n }\n }),\n );\n\n // Create ImageCache pre-populated with loaded images.\n // createImage returns the pre-loaded image and fires onLoad on next tick\n // so that the ImageCache internal `image` variable is assigned first.\n const imageCache = new ImageCache({\n createImage: (src, onLoad, onError) => {\n const img = preloaded.get(src);\n if (img) {\n process.nextTick(onLoad);\n return img;\n }\n process.nextTick(onError);\n return {};\n },\n });\n\n for (const src of preloaded.keys()) {\n imageCache.load(src);\n }\n\n // Wait for nextTick callbacks to populate the cache\n await new Promise<void>((resolve) => process.nextTick(resolve));\n\n return imageCache;\n}\n\n// ─── Main Render Loop ────────────────────────────────────────\n\n/**\n * Render an Atelier document to a video/GIF file via FFmpeg.\n * Dynamically imports `canvas` (node-canvas) — fails with a helpful\n * message if the native dependency is not installed.\n */\nexport async function renderDocument(\n doc: AtelierDocument,\n opts: RenderOptions,\n): Promise<RenderResult> {\n // Dynamic import — canvas requires native compilation.\n // Use a variable to avoid TypeScript resolving the module at compile time.\n const canvasModuleName = \"canvas\";\n let createCanvas: (w: number, h: number) => unknown;\n let loadImage: (src: string) => Promise<unknown>;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const canvasModule = await import(/* webpackIgnore: true */ canvasModuleName);\n createCanvas = canvasModule.createCanvas;\n loadImage = canvasModule.loadImage;\n } catch {\n throw new Error(\n \"The 'canvas' package is not installed.\\n\" +\n \"Install it with:\\n\" +\n \" npm install canvas\\n\" +\n \"Prerequisites vary by OS:\\n\" +\n \" macOS: brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman\\n\" +\n \" Ubuntu: sudo apt install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev\\n\" +\n \"See: https://github.com/Automattic/node-canvas#compiling\",\n );\n }\n\n const { width, height, fps } = doc.canvas;\n const { output, format, states, onProgress } = opts;\n\n // H.264 requires even dimensions\n if (format === \"mp4\" && (width % 2 !== 0 || height % 2 !== 0)) {\n throw new Error(\n `H.264 requires even dimensions. Canvas is ${width}\\u00d7${height}. ` +\n `Try ${width + (width % 2)}\\u00d7${height + (height % 2)}.`,\n );\n }\n\n // Resolve which states to render\n const allStates = Object.keys(doc.states);\n const renderStates = states ?? allStates;\n for (const s of renderStates) {\n if (!(s in doc.states)) {\n throw new Error(\n `State \"${s}\" not found. Available: ${allStates.join(\", \")}`,\n );\n }\n }\n\n // Total frame count across all states\n let totalFrames = 0;\n for (const s of renderStates) {\n totalFrames += doc.states[s].duration;\n }\n\n if (totalFrames === 0) {\n throw new Error(\"Nothing to render \\u2014 all states have duration 0\");\n }\n\n // Pre-load images before the render loop\n const imageCache = await preloadImages(doc, loadImage);\n\n // Create node-canvas\n const canvas = createCanvas(width, height) as { getContext(id: \"2d\"): unknown; toBuffer(format: \"raw\"): Buffer };\n const ctx = canvas.getContext(\"2d\");\n\n // Spawn FFmpeg\n const ffmpegArgs = buildFfmpegArgs(width, height, fps, format, output);\n const ffmpeg = spawn(\"ffmpeg\", ffmpegArgs, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n let stderrOutput = \"\";\n ffmpeg.stderr?.on(\"data\", (chunk: Buffer) => {\n stderrOutput += chunk.toString();\n });\n\n const startTime = Date.now();\n let frameIndex = 0;\n\n for (const stateName of renderStates) {\n const duration = doc.states[stateName].duration;\n for (let f = 0; f < duration; f++) {\n const resolved = resolveFrame(doc, stateName, f);\n renderFrame(ctx as never, resolved, doc, imageCache);\n\n const raw = canvas.toBuffer(\"raw\");\n const canWrite = ffmpeg.stdin!.write(raw);\n if (!canWrite) {\n await new Promise<void>((resolve) =>\n ffmpeg.stdin!.once(\"drain\", resolve),\n );\n }\n\n frameIndex++;\n onProgress?.({\n frame: frameIndex,\n totalFrames,\n state: stateName,\n percent: Math.round((frameIndex / totalFrames) * 100),\n });\n }\n }\n\n // Close stdin and wait for FFmpeg to exit\n ffmpeg.stdin!.end();\n\n const exitCode = await new Promise<number | null>((resolve) => {\n ffmpeg.on(\"close\", resolve);\n });\n\n if (exitCode !== 0) {\n throw new Error(\n `FFmpeg exited with code ${exitCode}.\\n${stderrOutput.slice(-500)}`,\n );\n }\n\n return {\n output,\n format,\n totalFrames,\n states: renderStates,\n durationMs: Date.now() - startTime,\n };\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport { renderFrameSVG } from \"@a-company/atelier-svg\";\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/** Register the `export-svg` subcommand on the Commander program. */\nexport function exportSvgCommand(program: Command): void {\n program\n .command(\"export-svg <file>\")\n .description(\"Export a frame as SVG\")\n .option(\"-s, --state <name>\", \"State name (defaults to first state)\")\n .option(\"-f, --frame <number>\", \"Frame number (defaults to 0)\", \"0\")\n .option(\"-o, --output <path>\", \"Output file path (default: stdout)\")\n .option(\"--xml-declaration\", \"Include XML declaration\")\n .action(\n (\n file: string,\n options: { state?: string; frame: string; output?: string; xmlDeclaration?: boolean },\n ) => {\n const doc = readAndParse(file);\n\n const frameNumber = parseInt(options.frame, 10);\n if (isNaN(frameNumber) || frameNumber < 0) {\n console.error(`Invalid frame number: ${options.frame}`);\n process.exit(1);\n return;\n }\n\n const stateNames = Object.keys(doc.states);\n if (stateNames.length === 0) {\n console.error(\"Document has no states\");\n process.exit(1);\n return;\n }\n\n const stateName = options.state ?? stateNames[0];\n if (!doc.states[stateName]) {\n console.error(`State \"${stateName}\" not found. Available: ${stateNames.join(\", \")}`);\n process.exit(1);\n return;\n }\n\n try {\n const svg = renderFrameSVG(doc, stateName, frameNumber, {\n xmlDeclaration: options.xmlDeclaration,\n });\n\n if (options.output) {\n writeFileSync(resolve(options.output), svg, \"utf-8\");\n } else {\n console.log(svg);\n }\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n },\n );\n}\n","import type { AtelierDocument, ImageVisual, RefVisual } from \"@a-company/atelier-types\";\nimport { resolveFrame, type ResolvedFrame } from \"@a-company/atelier-core\";\nimport { buildEffectiveLayer, type EffectiveLayer, type DocumentResolver } from \"@a-company/atelier-canvas\";\nimport { buildTransform, buildStyleAttrs } from \"./svg-properties.js\";\nimport { renderShapeSVG } from \"./svg-shapes.js\";\nimport { renderTextSVG } from \"./svg-text.js\";\nimport { buildShadowFilter, buildTintFilter, resetFilterCounter } from \"./svg-filters.js\";\nimport { resetGradientCounter } from \"./svg-gradients.js\";\nimport { buildClipPathDef, resetClipCounter } from \"./svg-clip.js\";\nimport { escapeXml } from \"./svg-properties.js\";\n\nexport interface RenderSVGOptions {\n /** Include XML declaration (default: false) */\n xmlDeclaration?: boolean;\n /** Include viewBox attribute (default: true) */\n viewBox?: boolean;\n /** Indent size in spaces (default: 2) */\n indent?: number;\n /** Resolves ref layer src paths to loaded AtelierDocuments */\n documentResolver?: DocumentResolver;\n /** Maximum ref nesting depth (default: 4) */\n maxRefDepth?: number;\n}\n\n/**\n * Render a resolved frame as an SVG string.\n * If no resolved frame is provided, resolves the given state and frame.\n */\nexport function renderFrameSVG(\n doc: AtelierDocument,\n stateOrFrame: string | ResolvedFrame,\n frame?: number,\n opts?: RenderSVGOptions,\n): string {\n // Reset counters for deterministic IDs\n resetGradientCounter();\n resetFilterCounter();\n resetClipCounter();\n\n let resolved: ResolvedFrame;\n if (typeof stateOrFrame === \"string\") {\n resolved = resolveFrame(doc, stateOrFrame, frame ?? 0);\n } else {\n resolved = stateOrFrame;\n }\n\n const { width, height } = doc.canvas;\n const indent = opts?.indent ?? 2;\n const pad = \" \".repeat(indent);\n\n // Build effective layers\n const effLayers: EffectiveLayer[] = resolved.layers.map(rl =>\n buildEffectiveLayer(rl, width, height),\n );\n\n // Collect all defs and layer elements\n const allDefs: string[] = [];\n const layerElements: string[] = [];\n\n for (let i = 0; i < effLayers.length; i++) {\n const eff = effLayers[i];\n const layer = resolved.layers[i].layer;\n\n // Skip invisible or fully transparent\n if (!eff.visible) continue;\n if (eff.opacity <= 0) continue;\n\n // Resolve asset for images\n if (layer.visual.type === \"image\") {\n const iv = eff.visual as ImageVisual;\n if (!iv.src && iv.assetId && doc.assets?.[iv.assetId]) {\n (eff.visual as ImageVisual).src = doc.assets[iv.assetId].src;\n }\n }\n\n // Build transform\n const transform = buildTransform(eff);\n const styleAttrs = buildStyleAttrs(eff);\n\n // Build shadow filter\n const filterResult = buildShadowFilter(eff);\n if (filterResult) allDefs.push(filterResult.defs);\n\n // Build tint filter\n const tintResult = buildTintFilter(eff);\n if (tintResult) allDefs.push(tintResult.defs);\n\n // Build clip path\n let clipAttr = \"\";\n if (layer.clipPath) {\n const clipResult = buildClipPathDef(layer.clipPath, eff.width, eff.height);\n if (clipResult.defs) {\n allDefs.push(clipResult.defs);\n clipAttr = ` clip-path=\"${clipResult.clipRef}\"`;\n }\n }\n\n // Build group attributes\n const gAttrs: string[] = [];\n if (transform) gAttrs.push(`transform=\"${transform}\"`);\n if (styleAttrs) gAttrs.push(styleAttrs);\n // Apply combined or individual filters\n if (filterResult && tintResult) {\n // When both shadow and tint exist, we need a combined filter\n // For simplicity, apply shadow filter and tint separately via style\n gAttrs.push(`filter=\"${filterResult.filterRef}\"`);\n // Tint is a second filter — wrap content in nested group\n } else if (filterResult) {\n gAttrs.push(`filter=\"${filterResult.filterRef}\"`);\n } else if (tintResult) {\n gAttrs.push(`filter=\"${tintResult.filterRef}\"`);\n }\n if (clipAttr) gAttrs.push(clipAttr.trim());\n\n // Render visual content\n let content = \"\";\n let layerDefs = \"\";\n\n switch (layer.visual.type) {\n case \"shape\": {\n const result = renderShapeSVG(eff, eff.visual as import(\"@a-company/atelier-types\").ShapeVisual);\n content = result.elements;\n layerDefs = result.defs;\n break;\n }\n case \"text\":\n content = renderTextSVG(eff, eff.visual as import(\"@a-company/atelier-types\").TextVisual);\n break;\n case \"image\": {\n const iv = eff.visual as ImageVisual;\n if (iv.src) {\n if (iv.spritesheet) {\n // Spritesheet: compute source rect and use full sheet dimensions for inner image\n const { columns, rows, frameWidth, frameHeight, frameCount } = iv.spritesheet;\n const maxFrames = frameCount ?? (columns * rows);\n const idx = Math.max(0, Math.min(Math.floor(iv.frameIndex ?? 0), maxFrames - 1));\n const col = idx % columns;\n const row = Math.floor(idx / columns);\n const sx = col * frameWidth;\n const sy = row * frameHeight;\n const imgW = columns * frameWidth;\n const imgH = rows * frameHeight;\n content = `<svg viewBox=\"${sx} ${sy} ${frameWidth} ${frameHeight}\" width=\"${eff.width}\" height=\"${eff.height}\">` +\n `<image href=\"${escapeXml(iv.src)}\" width=\"${imgW}\" height=\"${imgH}\" />` +\n `</svg>`;\n } else if (iv.sourceRect) {\n // Manual sourceRect: viewBox crops from image coordinate space\n const sr = iv.sourceRect;\n content = `<svg viewBox=\"${sr.x} ${sr.y} ${sr.width} ${sr.height}\" width=\"${eff.width}\" height=\"${eff.height}\">` +\n `<image href=\"${escapeXml(iv.src)}\" width=\"${eff.width}\" height=\"${eff.height}\" />` +\n `</svg>`;\n } else {\n content = `<image href=\"${escapeXml(iv.src)}\" width=\"${eff.width}\" height=\"${eff.height}\" />`;\n }\n }\n break;\n }\n case \"group\":\n // Groups are structural — no visual content in SVG either\n break;\n case \"ref\": {\n const refVisual = eff.visual as RefVisual;\n const refContent = renderRefSVG(eff, refVisual, doc, opts);\n content = refContent;\n break;\n }\n }\n\n if (layerDefs) allDefs.push(layerDefs);\n\n if (content) {\n const gOpen = gAttrs.length > 0 ? `<g ${gAttrs.join(\" \")}>` : \"<g>\";\n layerElements.push(`${pad}${gOpen}${content}</g>`);\n }\n }\n\n // Build SVG\n const lines: string[] = [];\n\n if (opts?.xmlDeclaration) {\n lines.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n }\n\n const viewBox = opts?.viewBox !== false ? ` viewBox=\"0 0 ${width} ${height}\"` : \"\";\n const bg = doc.canvas.background;\n\n lines.push(`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\"${viewBox}>`);\n\n // Defs section\n if (allDefs.length > 0) {\n lines.push(`${pad}<defs>`);\n for (const def of allDefs) {\n lines.push(`${pad}${pad}${def}`);\n }\n lines.push(`${pad}</defs>`);\n }\n\n // Background\n if (bg && bg !== \"transparent\") {\n lines.push(`${pad}<rect width=\"${width}\" height=\"${height}\" fill=\"${bg}\" />`);\n }\n\n // Layers\n lines.push(...layerElements);\n\n lines.push(\"</svg>\");\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a ref layer as SVG. Uses documentResolver to inline sub-doc content,\n * or falls back to a dashed placeholder rectangle.\n */\nfunction renderRefSVG(\n eff: EffectiveLayer,\n visual: RefVisual,\n _parentDoc: AtelierDocument,\n opts?: RenderSVGOptions,\n _depth?: number,\n _visitedRefs?: Set<string>,\n): string {\n const resolver = opts?.documentResolver;\n\n if (!resolver) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#999\" stroke-dasharray=\"4 2\" />`;\n }\n\n const depth = _depth ?? 0;\n const maxDepth = opts?.maxRefDepth ?? 4;\n if (depth >= maxDepth) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#c33\" stroke-dasharray=\"4 2\" /><text x=\"${eff.width / 2}\" y=\"${eff.height / 2}\" text-anchor=\"middle\" dominant-baseline=\"middle\" fill=\"#c33\" font-size=\"12\">MAX DEPTH</text>`;\n }\n\n const visitedRefs = _visitedRefs ?? new Set<string>();\n if (visitedRefs.has(visual.src)) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#c33\" stroke-dasharray=\"4 2\" /><text x=\"${eff.width / 2}\" y=\"${eff.height / 2}\" text-anchor=\"middle\" dominant-baseline=\"middle\" fill=\"#c33\" font-size=\"12\">CYCLE</text>`;\n }\n\n const subDoc = resolver(visual.src);\n if (!subDoc) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#999\" stroke-dasharray=\"4 2\" /><text x=\"${eff.width / 2}\" y=\"${eff.height / 2}\" text-anchor=\"middle\" dominant-baseline=\"middle\" fill=\"#999\" font-size=\"12\">NOT FOUND</text>`;\n }\n\n const stateNames = Object.keys(subDoc.states);\n if (stateNames.length === 0) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#999\" stroke-dasharray=\"4 2\" />`;\n }\n\n const stateName = visual.state ?? stateNames[0];\n const stateObj = subDoc.states[stateName];\n if (!stateObj) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#999\" stroke-dasharray=\"4 2\" />`;\n }\n\n const maxFrame = Math.max(0, stateObj.duration - 1);\n const frame = Math.min(visual.frame ?? 0, maxFrame);\n\n visitedRefs.add(visual.src);\n\n // Render sub-doc as nested <svg> with viewBox for scaling\n const subW = subDoc.canvas.width;\n const subH = subDoc.canvas.height;\n const resolved = resolveFrame(subDoc, stateName, frame);\n\n const subParts: string[] = [];\n for (const rl of resolved.layers) {\n const subEff = buildEffectiveLayer(rl, subW, subH);\n if (!subEff.visible || subEff.opacity <= 0) continue;\n\n // Resolve asset\n if (rl.layer.visual.type === \"image\") {\n const iv = subEff.visual as ImageVisual;\n if (!iv.src && iv.assetId && subDoc.assets?.[iv.assetId]) {\n iv.src = subDoc.assets[iv.assetId].src;\n }\n }\n\n const transform = buildTransform(subEff);\n const styleAttrs = buildStyleAttrs(subEff);\n const gAttrs: string[] = [];\n if (transform) gAttrs.push(`transform=\"${transform}\"`);\n if (styleAttrs) gAttrs.push(styleAttrs);\n\n let childContent = \"\";\n switch (rl.layer.visual.type) {\n case \"shape\": {\n const result = renderShapeSVG(subEff, subEff.visual as import(\"@a-company/atelier-types\").ShapeVisual);\n childContent = result.elements;\n break;\n }\n case \"text\":\n childContent = renderTextSVG(subEff, subEff.visual as import(\"@a-company/atelier-types\").TextVisual);\n break;\n case \"image\": {\n const iv = subEff.visual as ImageVisual;\n if (iv.src) {\n childContent = `<image href=\"${escapeXml(iv.src)}\" width=\"${subEff.width}\" height=\"${subEff.height}\" />`;\n }\n break;\n }\n case \"ref\": {\n const refV = subEff.visual as RefVisual;\n childContent = renderRefSVG(subEff, refV, subDoc, opts, depth + 1, visitedRefs);\n break;\n }\n }\n\n if (childContent) {\n const gOpen = gAttrs.length > 0 ? `<g ${gAttrs.join(\" \")}>` : \"<g>\";\n subParts.push(`${gOpen}${childContent}</g>`);\n }\n }\n\n visitedRefs.delete(visual.src);\n\n return `<svg x=\"0\" y=\"0\" width=\"${eff.width}\" height=\"${eff.height}\" viewBox=\"0 0 ${subW} ${subH}\">${subParts.join(\"\")}</svg>`;\n}\n","import type { EffectiveLayer } from \"@a-company/atelier-canvas\";\n\n/** Build SVG transform attribute from effective layer values */\nexport function buildTransform(eff: EffectiveLayer): string {\n const parts: string[] = [];\n\n // Translate to position\n if (eff.x !== 0 || eff.y !== 0) {\n parts.push(`translate(${eff.x}, ${eff.y})`);\n }\n\n const totalRotation = eff.rotation + eff.motionPathAngle;\n if (totalRotation !== 0 || eff.scaleX !== 1 || eff.scaleY !== 1) {\n const ax = eff.anchorX * eff.width;\n const ay = eff.anchorY * eff.height;\n\n // Move to anchor, apply rotation/scale, move back\n if (ax !== 0 || ay !== 0) {\n parts.push(`translate(${ax}, ${ay})`);\n }\n if (totalRotation !== 0) {\n parts.push(`rotate(${totalRotation})`);\n }\n if (eff.scaleX !== 1 || eff.scaleY !== 1) {\n parts.push(`scale(${eff.scaleX}, ${eff.scaleY})`);\n }\n if (ax !== 0 || ay !== 0) {\n parts.push(`translate(${-ax}, ${-ay})`);\n }\n }\n\n return parts.length > 0 ? parts.join(\" \") : \"\";\n}\n\n/** Build common SVG style attributes */\nexport function buildStyleAttrs(eff: EffectiveLayer): string {\n const attrs: string[] = [];\n\n if (eff.opacity < 1) {\n attrs.push(`opacity=\"${eff.opacity}\"`);\n }\n\n if (eff.blendMode !== \"normal\") {\n attrs.push(`style=\"mix-blend-mode: ${eff.blendMode}\"`);\n }\n\n return attrs.join(\" \");\n}\n\n/** Escape XML special characters */\nexport function escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n","import type { Fill, LinearGradientFill, RadialGradientFill, Color, RGBAColor, HSLAColor } from \"@a-company/atelier-types\";\n\nlet gradientIdCounter = 0;\n\nexport function resetGradientCounter(): void {\n gradientIdCounter = 0;\n}\n\n/** Convert an Atelier Color to a CSS color string */\nexport function colorToCSS(color: Color): string {\n if (typeof color === \"string\") return color;\n if (\"r\" in color) {\n const c = color as RGBAColor;\n return `rgba(${Math.round(c.r)}, ${Math.round(c.g)}, ${Math.round(c.b)}, ${c.a})`;\n }\n if (\"h\" in color) {\n const c = color as HSLAColor;\n return `hsla(${c.h}, ${c.s}%, ${c.l}%, ${c.a})`;\n }\n return \"#000000\";\n}\n\n/** Generate SVG gradient defs and return the fill reference */\nexport function buildGradientDef(fill: Fill, width: number, height: number): { defs: string; fillRef: string } {\n if (fill.type === \"solid\") {\n return { defs: \"\", fillRef: colorToCSS(fill.color) };\n }\n\n if (fill.type === \"linear-gradient\") {\n return buildLinearGradient(fill, width, height);\n }\n\n if (fill.type === \"radial-gradient\") {\n return buildRadialGradient(fill, width, height);\n }\n\n return { defs: \"\", fillRef: \"none\" };\n}\n\nfunction buildLinearGradient(fill: LinearGradientFill, _width: number, _height: number): { defs: string; fillRef: string } {\n const id = `grad-${++gradientIdCounter}`;\n const rad = (fill.angle * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n\n // Map angle to x1,y1,x2,y2 (0-1 percentages)\n const x1 = 0.5 - cos * 0.5;\n const y1 = 0.5 - sin * 0.5;\n const x2 = 0.5 + cos * 0.5;\n const y2 = 0.5 + sin * 0.5;\n\n const stops = fill.stops.map(s =>\n `<stop offset=\"${s.offset}\" stop-color=\"${colorToCSS(s.color)}\" />`\n ).join(\"\");\n\n const def = `<linearGradient id=\"${id}\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\">${stops}</linearGradient>`;\n return { defs: def, fillRef: `url(#${id})` };\n}\n\nfunction buildRadialGradient(fill: RadialGradientFill, width: number, height: number): { defs: string; fillRef: string } {\n const id = `grad-${++gradientIdCounter}`;\n\n const cx = typeof fill.center.x === \"number\" ? fill.center.x : (parseFloat(fill.center.x) / 100) * width;\n const cy = typeof fill.center.y === \"number\" ? fill.center.y : (parseFloat(fill.center.y) / 100) * height;\n const r = typeof fill.radius === \"number\" ? fill.radius : (parseFloat(fill.radius) / 100) * Math.max(width, height);\n\n const stops = fill.stops.map(s =>\n `<stop offset=\"${s.offset}\" stop-color=\"${colorToCSS(s.color)}\" />`\n ).join(\"\");\n\n const def = `<radialGradient id=\"${id}\" cx=\"${cx}\" cy=\"${cy}\" r=\"${r}\" gradientUnits=\"userSpaceOnUse\">${stops}</radialGradient>`;\n return { defs: def, fillRef: `url(#${id})` };\n}\n","import type { ShapeVisual, Shape, RectShape, PathShape, Stroke } from \"@a-company/atelier-types\";\nimport type { EffectiveLayer } from \"@a-company/atelier-canvas\";\nimport { buildGradientDef, colorToCSS } from \"./svg-gradients.js\";\n\n/** Render a shape visual as SVG elements */\nexport function renderShapeSVG(\n eff: EffectiveLayer,\n visual: ShapeVisual,\n): { elements: string; defs: string } {\n const { shape } = visual;\n const defs: string[] = [];\n\n let fillAttr = \"none\";\n if (visual.fill) {\n const gradResult = buildGradientDef(visual.fill, eff.width, eff.height);\n if (gradResult.defs) defs.push(gradResult.defs);\n fillAttr = gradResult.fillRef;\n }\n\n let strokeAttrs = \"\";\n if (visual.stroke) {\n strokeAttrs = buildStrokeAttrs(visual.stroke);\n }\n\n const element = buildShapeElement(shape, eff.width, eff.height, fillAttr, strokeAttrs);\n return { elements: element, defs: defs.join(\"\") };\n}\n\nfunction buildShapeElement(\n shape: Shape,\n width: number,\n height: number,\n fill: string,\n strokeAttrs: string,\n): string {\n switch (shape.type) {\n case \"rect\":\n return buildRectElement(shape, width, height, fill, strokeAttrs);\n case \"ellipse\":\n return buildEllipseElement(width, height, fill, strokeAttrs);\n case \"path\":\n return buildPathElement(shape, fill, strokeAttrs);\n }\n}\n\nfunction buildRectElement(\n shape: RectShape,\n width: number,\n height: number,\n fill: string,\n strokeAttrs: string,\n): string {\n let rx = \"\";\n if (shape.cornerRadius) {\n const r = typeof shape.cornerRadius === \"number\" ? shape.cornerRadius : shape.cornerRadius[0];\n rx = ` rx=\"${r}\" ry=\"${r}\"`;\n }\n return `<rect width=\"${width}\" height=\"${height}\" fill=\"${fill}\"${rx}${strokeAttrs ? \" \" + strokeAttrs : \"\"} />`;\n}\n\nfunction buildEllipseElement(\n width: number,\n height: number,\n fill: string,\n strokeAttrs: string,\n): string {\n const cx = width / 2;\n const cy = height / 2;\n const rx = width / 2;\n const ry = height / 2;\n return `<ellipse cx=\"${cx}\" cy=\"${cy}\" rx=\"${rx}\" ry=\"${ry}\" fill=\"${fill}\"${strokeAttrs ? \" \" + strokeAttrs : \"\"} />`;\n}\n\nfunction buildPathElement(\n shape: PathShape,\n fill: string,\n strokeAttrs: string,\n): string {\n if (shape.points.length < 2) return \"\";\n\n const d: string[] = [];\n d.push(`M ${shape.points[0].x} ${shape.points[0].y}`);\n\n for (let i = 1; i < shape.points.length; i++) {\n const prev = shape.points[i - 1];\n const curr = shape.points[i];\n\n if (prev.out && curr.in) {\n d.push(`C ${prev.x + prev.out.x} ${prev.y + prev.out.y} ${curr.x + curr.in.x} ${curr.y + curr.in.y} ${curr.x} ${curr.y}`);\n } else {\n d.push(`L ${curr.x} ${curr.y}`);\n }\n }\n\n if (shape.closed) d.push(\"Z\");\n\n return `<path d=\"${d.join(\" \")}\" fill=\"${fill}\"${strokeAttrs ? \" \" + strokeAttrs : \"\"} />`;\n}\n\nfunction buildStrokeAttrs(stroke: Stroke): string {\n const parts: string[] = [];\n parts.push(`stroke=\"${colorToCSS(stroke.color)}\"`);\n parts.push(`stroke-width=\"${stroke.width}\"`);\n\n if (stroke.lineCap) parts.push(`stroke-linecap=\"${stroke.lineCap}\"`);\n if (stroke.lineJoin) parts.push(`stroke-linejoin=\"${stroke.lineJoin}\"`);\n if (stroke.dash) parts.push(`stroke-dasharray=\"${stroke.dash.join(\" \")}\"`);\n\n return parts.join(\" \");\n}\n","import type { TextVisual } from \"@a-company/atelier-types\";\nimport type { EffectiveLayer } from \"@a-company/atelier-canvas\";\nimport { colorToCSS } from \"./svg-gradients.js\";\nimport { escapeXml } from \"./svg-properties.js\";\n\n/** Render a text visual as SVG elements */\nexport function renderTextSVG(eff: EffectiveLayer, visual: TextVisual): string {\n const { style } = visual;\n\n const attrs: string[] = [];\n\n // Font attributes\n attrs.push(`font-family=\"${escapeXml(style.fontFamily)}\"`);\n attrs.push(`font-size=\"${style.fontSize}\"`);\n\n if (style.fontWeight && style.fontWeight !== \"normal\") {\n attrs.push(`font-weight=\"${style.fontWeight}\"`);\n }\n if (style.fontStyle && style.fontStyle !== \"normal\") {\n attrs.push(`font-style=\"${style.fontStyle}\"`);\n }\n\n // Color\n attrs.push(`fill=\"${colorToCSS(style.color)}\"`);\n\n // Text alignment\n const align = style.textAlign ?? \"left\";\n let textAnchor = \"start\";\n let x = 0;\n if (align === \"center\") {\n textAnchor = \"middle\";\n x = eff.width / 2;\n } else if (align === \"right\") {\n textAnchor = \"end\";\n x = eff.width;\n }\n attrs.push(`text-anchor=\"${textAnchor}\"`);\n\n // Letter spacing\n if (style.letterSpacing) {\n attrs.push(`letter-spacing=\"${style.letterSpacing}\"`);\n }\n\n // SVG text baseline: use dominant-baseline for top alignment\n attrs.push(`dominant-baseline=\"hanging\"`);\n\n return `<text x=\"${x}\" y=\"0\" ${attrs.join(\" \")}>${escapeXml(visual.content)}</text>`;\n}\n","import type { EffectiveLayer } from \"@a-company/atelier-canvas\";\n\nlet filterIdCounter = 0;\n\nexport function resetFilterCounter(): void {\n filterIdCounter = 0;\n}\n\n/** Build SVG filter definition for shadow effects */\nexport function buildShadowFilter(eff: EffectiveLayer): { defs: string; filterRef: string } | null {\n if (!eff.shadow) return null;\n\n const id = `filter-${++filterIdCounter}`;\n const { color, blur, offsetX, offsetY } = eff.shadow;\n\n const def = [\n `<filter id=\"${id}\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">`,\n `<feDropShadow dx=\"${offsetX}\" dy=\"${offsetY}\" stdDeviation=\"${blur / 2}\" flood-color=\"${color}\" />`,\n `</filter>`,\n ].join(\"\");\n\n return { defs: def, filterRef: `url(#${id})` };\n}\n\n/** Build SVG filter definition for tint effect (feFlood + feBlend multiply) */\nexport function buildTintFilter(eff: EffectiveLayer): { defs: string; filterRef: string } | null {\n if (!eff.tint || eff.tint.amount <= 0) return null;\n\n const id = `filter-${++filterIdCounter}`;\n const { color, amount } = eff.tint;\n\n const def = [\n `<filter id=\"${id}\" x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">`,\n `<feFlood flood-color=\"${color}\" flood-opacity=\"${amount}\" result=\"tint\" />`,\n `<feBlend in=\"SourceGraphic\" in2=\"tint\" mode=\"multiply\" />`,\n `</filter>`,\n ].join(\"\");\n\n return { defs: def, filterRef: `url(#${id})` };\n}\n","import type { Shape } from \"@a-company/atelier-types\";\n\nlet clipIdCounter = 0;\n\nexport function resetClipCounter(): void {\n clipIdCounter = 0;\n}\n\n/** Build SVG clipPath definition */\nexport function buildClipPathDef(shape: Shape, width: number, height: number): { defs: string; clipRef: string } {\n const id = `clip-${++clipIdCounter}`;\n let pathContent = \"\";\n\n switch (shape.type) {\n case \"rect\":\n if (shape.cornerRadius) {\n const r = typeof shape.cornerRadius === \"number\" ? shape.cornerRadius : shape.cornerRadius[0];\n pathContent = `<rect width=\"${width}\" height=\"${height}\" rx=\"${r}\" ry=\"${r}\" />`;\n } else {\n pathContent = `<rect width=\"${width}\" height=\"${height}\" />`;\n }\n break;\n case \"ellipse\":\n pathContent = `<ellipse cx=\"${width / 2}\" cy=\"${height / 2}\" rx=\"${width / 2}\" ry=\"${height / 2}\" />`;\n break;\n case \"path\": {\n if (shape.points.length < 2) return { defs: \"\", clipRef: \"\" };\n const d: string[] = [];\n d.push(`M ${shape.points[0].x} ${shape.points[0].y}`);\n for (let i = 1; i < shape.points.length; i++) {\n const prev = shape.points[i - 1];\n const curr = shape.points[i];\n if (prev.out && curr.in) {\n d.push(`C ${prev.x + prev.out.x} ${prev.y + prev.out.y} ${curr.x + curr.in.x} ${curr.y + curr.in.y} ${curr.x} ${curr.y}`);\n } else {\n d.push(`L ${curr.x} ${curr.y}`);\n }\n }\n if (shape.closed) d.push(\"Z\");\n pathContent = `<path d=\"${d.join(\" \")}\" />`;\n break;\n }\n }\n\n const def = `<clipPath id=\"${id}\">${pathContent}</clipPath>`;\n return { defs: def, clipRef: `url(#${id})` };\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport { exportToLottie } from \"@a-company/atelier-lottie\";\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/** Register the `export-lottie` subcommand on the Commander program. */\nexport function exportLottieCommand(program: Command): void {\n program\n .command(\"export-lottie <file>\")\n .description(\"Export a document to Lottie JSON format\")\n .option(\"-s, --state <name>\", \"State name (defaults to first state)\")\n .option(\"-o, --output <path>\", \"Output file path (default: stdout)\")\n .action(\n (\n file: string,\n options: { state?: string; output?: string },\n ) => {\n const doc = readAndParse(file);\n\n try {\n const { json, warnings } = exportToLottie(doc, {\n state: options.state,\n });\n\n // Print warnings to stderr\n for (const warning of warnings) {\n console.error(`Warning: ${warning}`);\n }\n\n const output = JSON.stringify(json, null, 2);\n if (options.output) {\n writeFileSync(resolve(options.output), output, \"utf-8\");\n } else {\n console.log(output);\n }\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n },\n );\n}\n","import type { Color, RGBAColor, HSLAColor } from \"@a-company/atelier-types\";\n\n/** Convert an Atelier color to Lottie [r, g, b, a] format (0–1 range) */\nexport function colorToLottie(color: Color): number[] {\n if (typeof color === \"string\") {\n return hexToLottie(color);\n }\n\n if (\"r\" in color) {\n const c = color as RGBAColor;\n return [c.r / 255, c.g / 255, c.b / 255, c.a];\n }\n\n if (\"h\" in color) {\n const c = color as HSLAColor;\n const rgb = hslToRgb(c.h, c.s, c.l);\n return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, c.a];\n }\n\n return [0, 0, 0, 1];\n}\n\nfunction hexToLottie(hex: string): number[] {\n const clean = hex.replace(\"#\", \"\");\n if (clean.length === 3 || clean.length === 4) {\n const r = parseInt(clean[0] + clean[0], 16) / 255;\n const g = parseInt(clean[1] + clean[1], 16) / 255;\n const b = parseInt(clean[2] + clean[2], 16) / 255;\n const a = clean.length === 4 ? parseInt(clean[3] + clean[3], 16) / 255 : 1;\n return [r, g, b, a];\n }\n const r = parseInt(clean.slice(0, 2), 16) / 255;\n const g = parseInt(clean.slice(2, 4), 16) / 255;\n const b = parseInt(clean.slice(4, 6), 16) / 255;\n const a = clean.length === 8 ? parseInt(clean.slice(6, 8), 16) / 255 : 1;\n return [r, g, b, a];\n}\n\nfunction hslToRgb(h: number, s: number, l: number): [number, number, number] {\n s = s / 100;\n l = l / 100;\n const a = s * Math.min(l, 1 - l);\n const f = (n: number) => {\n const k = (n + h / 30) % 12;\n return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n };\n return [Math.round(f(0) * 255), Math.round(f(8) * 255), Math.round(f(4) * 255)];\n}\n","import type { ShapeVisual, Fill, Stroke } from \"@a-company/atelier-types\";\nimport type { LottieShapeItem } from \"./lottie-types.js\";\nimport { colorToLottie } from \"./map-colors.js\";\n\n/** Map an Atelier shape visual to Lottie shape items */\nexport function mapShapeVisual(\n visual: ShapeVisual,\n width: number,\n height: number,\n): LottieShapeItem[] {\n const items: LottieShapeItem[] = [];\n\n // Shape geometry\n switch (visual.shape.type) {\n case \"rect\":\n items.push({\n ty: \"rc\",\n nm: \"Rectangle\",\n d: 1,\n s: { a: 0, k: [width, height] },\n p: { a: 0, k: [width / 2, height / 2] },\n r: { a: 0, k: typeof visual.shape.cornerRadius === \"number\" ? visual.shape.cornerRadius : 0 },\n });\n break;\n case \"ellipse\":\n items.push({\n ty: \"el\",\n nm: \"Ellipse\",\n d: 1,\n s: { a: 0, k: [width, height] },\n p: { a: 0, k: [width / 2, height / 2] },\n });\n break;\n case \"path\": {\n const vertices = visual.shape.points.map(p => [p.x, p.y]);\n const inTangents = visual.shape.points.map(p => p.in ? [p.in.x, p.in.y] : [0, 0]);\n const outTangents = visual.shape.points.map(p => p.out ? [p.out.x, p.out.y] : [0, 0]);\n items.push({\n ty: \"sh\",\n nm: \"Path\",\n ks: {\n a: 0,\n k: {\n c: visual.shape.closed ?? false,\n v: vertices,\n i: inTangents,\n o: outTangents,\n },\n },\n });\n break;\n }\n }\n\n // Fill\n if (visual.fill) {\n items.push(mapFill(visual.fill, width, height));\n }\n\n // Stroke\n if (visual.stroke) {\n items.push(mapStroke(visual.stroke));\n }\n\n return items;\n}\n\nfunction mapFill(fill: Fill, _width: number, _height: number): LottieShapeItem {\n if (fill.type === \"solid\") {\n const color = colorToLottie(fill.color);\n return {\n ty: \"fl\",\n nm: \"Fill\",\n c: { a: 0, k: color.slice(0, 3) },\n o: { a: 0, k: (color[3] ?? 1) * 100 },\n r: 1,\n };\n }\n\n if (fill.type === \"linear-gradient\") {\n const stops: number[] = [];\n for (const stop of fill.stops) {\n const c = colorToLottie(stop.color);\n stops.push(stop.offset, c[0], c[1], c[2]);\n }\n return {\n ty: \"gf\",\n nm: \"Gradient Fill\",\n t: 1, // linear\n s: { a: 0, k: [0, 0] },\n e: { a: 0, k: [100, 0] },\n g: { p: fill.stops.length, k: { a: 0, k: stops } },\n r: 1,\n o: { a: 0, k: 100 },\n };\n }\n\n if (fill.type === \"radial-gradient\") {\n const stops: number[] = [];\n for (const stop of fill.stops) {\n const c = colorToLottie(stop.color);\n stops.push(stop.offset, c[0], c[1], c[2]);\n }\n return {\n ty: \"gf\",\n nm: \"Gradient Fill\",\n t: 2, // radial\n s: { a: 0, k: [50, 50] },\n e: { a: 0, k: [100, 50] },\n g: { p: fill.stops.length, k: { a: 0, k: stops } },\n r: 1,\n o: { a: 0, k: 100 },\n };\n }\n\n return { ty: \"fl\", nm: \"Fill\", c: { a: 0, k: [0, 0, 0] }, o: { a: 0, k: 100 }, r: 1 };\n}\n\nfunction mapStroke(stroke: Stroke): LottieShapeItem {\n const color = colorToLottie(stroke.color);\n return {\n ty: \"st\",\n nm: \"Stroke\",\n c: { a: 0, k: color.slice(0, 3) },\n o: { a: 0, k: (color[3] ?? 1) * 100 },\n w: { a: 0, k: stroke.width },\n lc: stroke.lineCap === \"round\" ? 2 : stroke.lineCap === \"square\" ? 3 : 1,\n lj: stroke.lineJoin === \"round\" ? 2 : stroke.lineJoin === \"bevel\" ? 3 : 1,\n };\n}\n","import type { Easing } from \"@a-company/atelier-types\";\n\nexport interface LottieEasing {\n i: { x: number[]; y: number[] };\n o: { x: number[]; y: number[] };\n}\n\n/** Map an Atelier easing to Lottie bezier easing curves */\nexport function mapEasing(easing: Easing | undefined): LottieEasing | { h: 1 } {\n if (!easing) return linearEasing();\n\n if (typeof easing === \"string\") {\n switch (easing) {\n case \"ease-in\":\n return bezierEasing(0.42, 0, 1, 1);\n case \"ease-out\":\n return bezierEasing(0, 0, 0.58, 1);\n case \"ease-in-out\":\n return bezierEasing(0.42, 0, 0.58, 1);\n default:\n return linearEasing();\n }\n }\n\n switch (easing.type) {\n case \"linear\":\n return linearEasing();\n case \"cubic-bezier\":\n return bezierEasing(easing.x1, easing.y1, easing.x2, easing.y2);\n case \"spring\":\n // Approximate spring as a cubic-bezier (lossy)\n return bezierEasing(0.25, 0.1, 0.25, 1);\n case \"step\":\n // Steps map to hold keyframes\n return { h: 1 };\n default:\n return linearEasing();\n }\n}\n\nfunction linearEasing(): LottieEasing {\n return {\n i: { x: [0.833], y: [0.833] },\n o: { x: [0.167], y: [0.167] },\n };\n}\n\nfunction bezierEasing(x1: number, y1: number, x2: number, y2: number): LottieEasing {\n return {\n i: { x: [x2], y: [y2] },\n o: { x: [x1], y: [y1] },\n };\n}\n\n/** Check if an easing is lossy (spring/step → approximated) */\nexport function isLossyEasing(easing: Easing | undefined): string | null {\n if (!easing || typeof easing === \"string\") return null;\n if (easing.type === \"spring\") return \"Spring easing approximated as cubic-bezier\";\n if (easing.type === \"step\") return \"Step easing mapped to hold keyframes\";\n return null;\n}\n","import type { Delta, AnimatableProperty } from \"@a-company/atelier-types\";\nimport type { LottieAnimatedValue, LottieAnimatedMultiValue, LottieKeyframe, LottieMultiKeyframe } from \"./lottie-types.js\";\nimport { mapEasing, isLossyEasing } from \"./map-easing.js\";\n\n/** Map deltas for a single layer+property to Lottie animated value */\nexport function mapDeltasToAnimated(\n deltas: Delta[],\n property: AnimatableProperty,\n warnings: string[],\n): LottieAnimatedValue {\n if (deltas.length === 0) {\n return { a: 0, k: 0 };\n }\n\n // Check for lossy easings\n for (const d of deltas) {\n const lossyMsg = isLossyEasing(d.easing);\n if (lossyMsg) warnings.push(`${property}: ${lossyMsg}`);\n }\n\n // If expressions, warn and use static\n for (const d of deltas) {\n if (isExpression(d.from) || isExpression(d.to)) {\n warnings.push(`${property}: Expression values not supported in Lottie, using static values`);\n return { a: 0, k: typeof d.from === \"number\" ? d.from : 0 };\n }\n }\n\n // Single delta — simple animated value\n if (deltas.length === 1) {\n const d = deltas[0];\n const fromVal = resolveValue(d.from, property);\n const toVal = resolveValue(d.to, property);\n\n if (fromVal === toVal) {\n return { a: 0, k: fromVal };\n }\n\n const easing = mapEasing(d.easing);\n const kfs: LottieKeyframe[] = [];\n\n if (\"h\" in easing) {\n kfs.push({ t: d.range[0], s: [fromVal], h: 1 });\n kfs.push({ t: d.range[1], s: [toVal] });\n } else {\n kfs.push({ t: d.range[0], s: [fromVal], e: [toVal], i: easing.i, o: easing.o });\n kfs.push({ t: d.range[1], s: [toVal] });\n }\n\n return { a: 1, k: kfs };\n }\n\n // Multiple deltas — chain keyframes\n const sorted = [...deltas].sort((a, b) => a.range[0] - b.range[0]);\n const kfs: LottieKeyframe[] = [];\n\n for (const d of sorted) {\n const fromVal = resolveValue(d.from, property);\n const toVal = resolveValue(d.to, property);\n const easing = mapEasing(d.easing);\n\n if (\"h\" in easing) {\n kfs.push({ t: d.range[0], s: [fromVal], h: 1 });\n } else {\n kfs.push({ t: d.range[0], s: [fromVal], e: [toVal], i: easing.i, o: easing.o });\n }\n }\n\n // Final keyframe\n const last = sorted[sorted.length - 1];\n kfs.push({ t: last.range[1], s: [resolveValue(last.to, property)] });\n\n return { a: 1, k: kfs };\n}\n\n/** Map position deltas (frame.x, frame.y) to Lottie multi-dimensional animated value */\nexport function mapPositionDeltas(\n xDeltas: Delta[],\n yDeltas: Delta[],\n baseX: number,\n baseY: number,\n warnings: string[],\n): LottieAnimatedMultiValue {\n const hasXAnim = xDeltas.length > 0;\n const hasYAnim = yDeltas.length > 0;\n\n if (!hasXAnim && !hasYAnim) {\n return { a: 0, k: [baseX, baseY, 0] };\n }\n\n // Collect all unique frame points\n const frames = new Set<number>();\n for (const d of [...xDeltas, ...yDeltas]) {\n frames.add(d.range[0]);\n frames.add(d.range[1]);\n }\n const sortedFrames = [...frames].sort((a, b) => a - b);\n\n if (sortedFrames.length < 2) {\n return { a: 0, k: [baseX, baseY, 0] };\n }\n\n // Build multi-dimensional keyframes\n const kfs: LottieMultiKeyframe[] = [];\n for (let i = 0; i < sortedFrames.length; i++) {\n const f = sortedFrames[i];\n const x = resolveAtFrame(xDeltas, f, baseX);\n const y = resolveAtFrame(yDeltas, f, baseY);\n\n if (i < sortedFrames.length - 1) {\n const nextF = sortedFrames[i + 1];\n const nextX = resolveAtFrame(xDeltas, nextF, baseX);\n const nextY = resolveAtFrame(yDeltas, nextF, baseY);\n\n // Find the active delta's easing\n const activeX = xDeltas.find(d => d.range[0] <= f && d.range[1] >= f);\n const activeY = yDeltas.find(d => d.range[0] <= f && d.range[1] >= f);\n const easing = mapEasing(activeX?.easing ?? activeY?.easing);\n\n if (\"h\" in easing) {\n kfs.push({ t: f, s: [x, y, 0], h: 1 });\n } else {\n kfs.push({ t: f, s: [x, y, 0], e: [nextX, nextY, 0], i: easing.i, o: easing.o });\n }\n } else {\n kfs.push({ t: f, s: [x, y, 0] });\n }\n }\n\n // Check for lossy warnings\n for (const d of [...xDeltas, ...yDeltas]) {\n const msg = isLossyEasing(d.easing);\n if (msg) warnings.push(`position: ${msg}`);\n }\n\n return { a: 1, k: kfs };\n}\n\nfunction resolveAtFrame(deltas: Delta[], frame: number, base: number): number {\n for (const d of deltas) {\n if (frame >= d.range[0] && frame <= d.range[1]) {\n const from = typeof d.from === \"number\" ? d.from : base;\n const to = typeof d.to === \"number\" ? d.to : base;\n const progress = d.range[0] === d.range[1] ? 1 : (frame - d.range[0]) / (d.range[1] - d.range[0]);\n return from + (to - from) * progress;\n }\n }\n // Hold last completed value\n let lastCompleted: Delta | undefined;\n for (const d of deltas) {\n if (frame > d.range[1]) {\n if (!lastCompleted || d.range[1] > lastCompleted.range[1]) {\n lastCompleted = d;\n }\n }\n }\n if (lastCompleted) return typeof lastCompleted.to === \"number\" ? lastCompleted.to : base;\n return base;\n}\n\nfunction resolveValue(val: unknown, _property: AnimatableProperty): number {\n if (typeof val === \"number\") return val;\n if (typeof val === \"string\" && val.startsWith(\"#\")) {\n // Color — for Lottie, colors are handled separately\n return 0;\n }\n return 0;\n}\n\nfunction isExpression(val: unknown): boolean {\n return typeof val === \"object\" && val !== null && \"expr\" in val;\n}\n","import type { AtelierDocument, Layer, Delta, State, UnitValue } from \"@a-company/atelier-types\";\nimport type { LottieLayer, LottieTransform, LottieTextData } from \"./lottie-types.js\";\nimport { mapShapeVisual } from \"./map-shapes.js\";\nimport { mapDeltasToAnimated, mapPositionDeltas } from \"./map-keyframes.js\";\nimport { colorToLottie } from \"./map-colors.js\";\n\n/** Resolve a UnitValue to a plain number (percentages treated as 0 for Lottie) */\nfunction toNum(v: UnitValue): number {\n return typeof v === \"number\" ? v : 0;\n}\n\n/** Map all layers in a document+state to Lottie layers */\nexport function mapLayers(\n doc: AtelierDocument,\n state: State,\n warnings: string[],\n): LottieLayer[] {\n const layerIndexMap = new Map<string, number>();\n doc.layers.forEach((l, i) => layerIndexMap.set(l.id, i));\n\n return doc.layers.map((layer, index) => {\n const deltas = state.deltas.filter(d => d.layer === layer.id);\n return mapLayer(layer, index, deltas, layerIndexMap, doc, warnings);\n });\n}\n\nfunction mapLayer(\n layer: Layer,\n index: number,\n deltas: Delta[],\n layerIndexMap: Map<string, number>,\n doc: AtelierDocument,\n warnings: string[],\n): LottieLayer {\n const duration = getMaxFrame(deltas, doc);\n\n const base: LottieLayer = {\n ty: getLayerType(layer),\n nm: layer.id,\n ind: index,\n ip: 0,\n op: duration,\n st: 0,\n ks: buildTransform(layer, deltas, warnings),\n };\n\n // Parent\n if (layer.parentId) {\n const parentIdx = layerIndexMap.get(layer.parentId);\n if (parentIdx !== undefined) {\n base.parent = parentIdx;\n }\n }\n\n // Blend mode\n if (layer.blendMode) {\n base.bm = mapBlendMode(layer.blendMode);\n }\n\n // Shape layer\n if (layer.visual.type === \"shape\") {\n base.shapes = mapShapeVisual(layer.visual, toNum(layer.bounds.width), toNum(layer.bounds.height));\n }\n\n // Text layer\n if (layer.visual.type === \"text\") {\n const color = colorToLottie(layer.visual.style.color);\n base.t = {\n d: {\n k: [{\n s: {\n s: layer.visual.style.fontSize,\n f: layer.visual.style.fontFamily,\n t: layer.visual.content,\n fc: color.slice(0, 3),\n j: layer.visual.style.textAlign === \"center\" ? 1 :\n layer.visual.style.textAlign === \"right\" ? 2 : 0,\n },\n t: 0,\n }],\n },\n } as LottieTextData;\n }\n\n // Image layer\n if (layer.visual.type === \"image\") {\n base.refId = layer.visual.assetId;\n base.w = toNum(layer.bounds.width);\n base.h = toNum(layer.bounds.height);\n\n if (layer.visual.spritesheet) {\n warnings.push(`Layer \"${layer.id}\": Spritesheet animation not supported in Lottie export`);\n }\n if (layer.visual.sourceRect) {\n warnings.push(`Layer \"${layer.id}\": sourceRect cropping not supported in Lottie export`);\n }\n }\n\n // Tint warning\n if (layer.tint && layer.tint.amount > 0) {\n warnings.push(`Layer \"${layer.id}\": Tint effect not supported in Lottie export`);\n }\n\n return base;\n}\n\nfunction getLayerType(layer: Layer): number {\n switch (layer.visual.type) {\n case \"shape\": return 4;\n case \"text\": return 5;\n case \"image\": return 2;\n case \"group\": return 3; // null layer\n case \"ref\": return 0; // precomp\n default: return 4;\n }\n}\n\nfunction buildTransform(\n layer: Layer,\n deltas: Delta[],\n warnings: string[],\n): LottieTransform {\n // Group deltas by property\n const byProp = new Map<string, Delta[]>();\n for (const d of deltas) {\n if (!byProp.has(d.property)) byProp.set(d.property, []);\n byProp.get(d.property)!.push(d);\n }\n\n const xDeltas = byProp.get(\"frame.x\") ?? [];\n const yDeltas = byProp.get(\"frame.y\") ?? [];\n const opacityDeltas = byProp.get(\"opacity\") ?? [];\n const rotationDeltas = byProp.get(\"rotation\") ?? [];\n const scaleXDeltas = byProp.get(\"scale.x\") ?? [];\n const scaleYDeltas = byProp.get(\"scale.y\") ?? [];\n\n // Position\n const position = mapPositionDeltas(\n xDeltas, yDeltas,\n typeof layer.frame.x === \"number\" ? layer.frame.x : 0,\n typeof layer.frame.y === \"number\" ? layer.frame.y : 0,\n warnings,\n );\n\n // Opacity (Lottie uses 0–100)\n let opacity;\n if (opacityDeltas.length > 0) {\n const raw = mapDeltasToAnimated(opacityDeltas, \"opacity\", warnings);\n // Scale 0-1 to 0-100\n if (raw.a === 0) {\n opacity = { a: 0 as const, k: (raw.k as number) * 100 };\n } else {\n const kfs = (raw.k as Array<{ t: number; s: [number]; e?: [number]; [key: string]: unknown }>).map(kf => ({\n ...kf,\n s: [kf.s[0] * 100] as [number],\n e: kf.e ? [kf.e[0] * 100] as [number] : undefined,\n }));\n opacity = { a: 1 as const, k: kfs };\n }\n } else {\n opacity = { a: 0 as const, k: (layer.opacity ?? 1) * 100 };\n }\n\n // Rotation\n const rotation = rotationDeltas.length > 0\n ? mapDeltasToAnimated(rotationDeltas, \"rotation\", warnings)\n : { a: 0 as const, k: layer.rotation ?? 0 };\n\n // Scale (Lottie uses 0–100)\n const baseScaleX = (layer.scale?.x ?? 1) * 100;\n const baseScaleY = (layer.scale?.y ?? 1) * 100;\n let scale;\n if (scaleXDeltas.length > 0 || scaleYDeltas.length > 0) {\n // Simplified: use x deltas for now\n scale = { a: 0 as const, k: [baseScaleX, baseScaleY, 100] };\n if (scaleXDeltas.length > 0 || scaleYDeltas.length > 0) {\n warnings.push(\"Scale animation partially mapped to Lottie\");\n }\n } else {\n scale = { a: 0 as const, k: [baseScaleX, baseScaleY, 100] };\n }\n\n // Anchor point\n const ax = (layer.anchorPoint?.x ?? 0) * toNum(layer.bounds.width);\n const ay = (layer.anchorPoint?.y ?? 0) * toNum(layer.bounds.height);\n\n return {\n o: opacity,\n r: rotation,\n p: position,\n a: { a: 0, k: [ax, ay, 0] },\n s: scale,\n };\n}\n\nfunction getMaxFrame(deltas: Delta[], doc: AtelierDocument): number {\n let max = 0;\n for (const state of Object.values(doc.states)) {\n if (state.duration > max) max = state.duration;\n }\n for (const d of deltas) {\n if (d.range[1] > max) max = d.range[1];\n }\n return max || 60;\n}\n\nfunction mapBlendMode(mode: string): number {\n const map: Record<string, number> = {\n normal: 0, multiply: 1, screen: 2, overlay: 3,\n darken: 4, lighten: 5, \"color-dodge\": 6, \"color-burn\": 7,\n \"hard-light\": 8, \"soft-light\": 9, difference: 10, exclusion: 11,\n hue: 12, saturation: 13, color: 14, luminosity: 15,\n };\n return map[mode] ?? 0;\n}\n","import type { AtelierDocument, State } from \"@a-company/atelier-types\";\n\n/** Check for unsupported features and collect warnings */\nexport function collectUnsupportedWarnings(doc: AtelierDocument, state: State): string[] {\n const warnings: string[] = [];\n\n // Audio not supported\n if (state.audio) {\n warnings.push(\"Audio tracks are not supported in Lottie format and will be dropped\");\n }\n\n // Expressions not supported\n for (const delta of state.deltas) {\n if (isExpression(delta.from) || isExpression(delta.to)) {\n warnings.push(`Expression values on \"${delta.layer}.${delta.property}\" not supported in Lottie`);\n }\n }\n\n // Shadow not supported in base Lottie\n for (const layer of doc.layers) {\n if (layer.shadow) {\n warnings.push(`Shadow on layer \"${layer.id}\" is not supported in base Lottie format`);\n }\n }\n\n // Motion path not directly mapped\n for (const layer of doc.layers) {\n if (layer.motionPath) {\n warnings.push(`Motion path on layer \"${layer.id}\" is not directly mappable to Lottie`);\n }\n }\n\n // Clip paths have limited support\n for (const layer of doc.layers) {\n if (layer.clipPath) {\n warnings.push(`Clip path on layer \"${layer.id}\" mapped as Lottie mask (partial support)`);\n }\n }\n\n // States/transitions\n if (Object.keys(doc.states).length > 1) {\n warnings.push(\"Multiple states flattened to single timeline in Lottie export\");\n }\n\n return warnings;\n}\n\nfunction isExpression(val: unknown): boolean {\n return typeof val === \"object\" && val !== null && \"expr\" in val;\n}\n","import type { AtelierDocument } from \"@a-company/atelier-types\";\nimport type { LottieAnimation, LottieAsset } from \"./lottie-types.js\";\nimport { mapLayers } from \"./map-layers.js\";\nimport { collectUnsupportedWarnings } from \"./warnings.js\";\n\nexport interface ExportLottieOptions {\n /** State to export (defaults to first state) */\n state?: string;\n}\n\nexport interface ExportLottieResult {\n /** The Lottie JSON animation */\n json: LottieAnimation;\n /** Warnings about unsupported features */\n warnings: string[];\n}\n\n/**\n * Export an Atelier document to Lottie JSON format.\n * This is a lossy conversion — not all features are supported.\n */\nexport function exportToLottie(\n doc: AtelierDocument,\n opts?: ExportLottieOptions,\n): ExportLottieResult {\n const stateNames = Object.keys(doc.states);\n if (stateNames.length === 0) {\n throw new Error(\"Document has no states to export\");\n }\n\n const stateName = opts?.state ?? stateNames[0];\n const state = doc.states[stateName];\n if (!state) {\n throw new Error(`State \"${stateName}\" not found`);\n }\n\n const warnings: string[] = [];\n\n // Collect unsupported feature warnings\n warnings.push(...collectUnsupportedWarnings(doc, state));\n\n // Map layers\n const layers = mapLayers(doc, state, warnings);\n\n // Map assets\n const assets: LottieAsset[] = [];\n if (doc.assets) {\n for (const [id, asset] of Object.entries(doc.assets)) {\n if (asset.type === \"image\") {\n assets.push({\n id,\n w: 100,\n h: 100,\n p: asset.src,\n e: 0,\n });\n }\n }\n }\n\n const json: LottieAnimation = {\n v: \"5.7.4\",\n fr: doc.canvas.fps,\n ip: 0,\n op: state.duration,\n w: doc.canvas.width,\n h: doc.canvas.height,\n nm: doc.name,\n layers,\n ...(assets.length > 0 ? { assets } : {}),\n };\n\n // Deduplicate warnings\n const uniqueWarnings = [...new Set(warnings)];\n\n return { json, warnings: uniqueWarnings };\n}\n","import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument, ImageVisual } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\n\n/** Asset summary entry */\nexport interface AssetInfo {\n assetId: string;\n type: string;\n src: string;\n description?: string;\n usedByLayers: string[];\n usedByStates: string[];\n}\n\n/**\n * Extract asset info from a parsed AtelierDocument.\n */\nexport function getAssets(doc: AtelierDocument): AssetInfo[] {\n const assets = doc.assets ?? {};\n return Object.entries(assets).map(([assetId, asset]) => {\n const usedByLayers = doc.layers\n .filter(l => l.visual.type === \"image\" && (l.visual as ImageVisual).assetId === assetId)\n .map(l => l.id);\n\n const usedByStates = Object.entries(doc.states)\n .filter(([, state]) => state.audio?.src === assetId)\n .map(([name]) => name);\n\n return {\n assetId,\n type: asset.type,\n src: asset.src,\n description: asset.description,\n usedByLayers,\n usedByStates,\n };\n });\n}\n\n/**\n * Format asset info for terminal output.\n */\nfunction formatAssets(assets: AssetInfo[]): string {\n if (assets.length === 0) return \"No assets registered.\";\n\n const lines: string[] = [`Assets: ${assets.length}`];\n for (const a of assets) {\n const desc = a.description ? ` — ${a.description}` : \"\";\n lines.push(` - ${a.assetId} (${a.type}): ${a.src}${desc}`);\n if (a.usedByLayers.length > 0) {\n lines.push(` Layers: ${a.usedByLayers.join(\", \")}`);\n }\n if (a.usedByStates.length > 0) {\n lines.push(` States: ${a.usedByStates.join(\", \")}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/**\n * Register the `assets` subcommand on the Commander program.\n */\nexport function assetsCommand(program: Command): void {\n program\n .command(\"assets <file>\")\n .description(\"List all assets in an .atelier file with usage info\")\n .action((file: string) => {\n const doc = readAndParse(file);\n const assets = getAssets(doc);\n console.log(formatAssets(assets));\n });\n}\n","import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport { findTemplateVariables } from \"@a-company/atelier-core\";\n\n/** Variable summary entry */\nexport interface VariableInfo {\n name: string;\n type: string;\n description?: string;\n default?: unknown;\n referenced: boolean;\n}\n\n/**\n * Extract variable info from a parsed AtelierDocument.\n */\nexport function getVariables(doc: AtelierDocument): { variables: VariableInfo[]; undeclared: string[] } {\n const variables = doc.variables ?? {};\n const referenced = findTemplateVariables(doc);\n\n const entries = Object.entries(variables).map(([name, variable]) => ({\n name,\n type: variable.type,\n description: variable.description,\n default: variable.default,\n referenced: referenced.includes(name),\n }));\n\n const undeclared = referenced.filter(r => !variables[r]);\n\n return { variables: entries, undeclared };\n}\n\n/**\n * Format variable info for terminal output.\n */\nfunction formatVariables(info: { variables: VariableInfo[]; undeclared: string[] }): string {\n if (info.variables.length === 0 && info.undeclared.length === 0) return \"No variables declared or referenced.\";\n\n const lines: string[] = [];\n\n if (info.variables.length > 0) {\n lines.push(`Variables: ${info.variables.length}`);\n for (const v of info.variables) {\n const desc = v.description ? ` — ${v.description}` : \"\";\n const def = v.default !== undefined ? ` [default: ${JSON.stringify(v.default)}]` : \"\";\n const ref = v.referenced ? \"\" : \" (unused)\";\n lines.push(` - {{${v.name}}} (${v.type})${def}${desc}${ref}`);\n }\n }\n\n if (info.undeclared.length > 0) {\n lines.push(`Undeclared references: ${info.undeclared.length}`);\n for (const name of info.undeclared) {\n lines.push(` - {{${name}}} (not declared in variables)`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/**\n * Register the `variables` subcommand on the Commander program.\n */\nexport function variablesCommand(program: Command): void {\n program\n .command(\"variables <file>\")\n .description(\"List all variables in an .atelier file with usage info\")\n .action((file: string) => {\n const doc = readAndParse(file);\n const info = getVariables(doc);\n console.log(formatVariables(info));\n });\n}\n"],"mappings":"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","names":["init_dist","import_zod","z","yamlParse","init_dist","import_node_fs","import_node_path","import_node_fs","import_node_path","init_dist","readAndParse","renderFrame","import_node_fs","import_node_path","init_dist","resolve","readAndParse","import_node_fs","import_node_path","init_dist","colorToCSS","readAndParse","import_node_fs","import_node_path","r","g","b","a","isExpression","kfs","buildTransform","readAndParse","import_node_fs","import_node_path","readAndParse","import_node_fs","import_node_path","init_dist","readAndParse"]}
|
|
1
|
+
{"version":3,"sources":["../../math/src/easing.ts","../../math/src/spring.ts","../../math/src/lerp.ts","../../math/src/color.ts","../../math/src/path.ts","../../core/src/resolver/delta-resolver.ts","../../core/src/resolver/easing-resolver.ts","../../core/src/expressions/expression-evaluator.ts","../../core/src/resolver/frame-resolver.ts","../../core/src/validation/overlap-validator.ts","../../core/src/builder/document-builder.ts","../../core/src/units/resolve-units.ts","../../core/src/presets/preset-resolver.ts","../../core/src/state/state-machine.ts","../../core/src/templates/template-resolver.ts","../../core/src/audio/audio-timing.ts","../../canvas/src/styles.ts","../../canvas/src/apply-properties.ts","../../canvas/src/renderers/shape-renderer.ts","../../canvas/src/renderers/text-renderer.ts","../../canvas/src/renderers/image-renderer.ts","../../canvas/src/renderers/ref-renderer.ts","../../canvas/src/render-frame.ts","../../canvas/src/image-cache.ts","../src/index.ts","../src/commands/validate.ts","../../schema/src/units.ts","../../schema/src/coordinates.ts","../../schema/src/color.ts","../../schema/src/shape.ts","../../schema/src/easing.ts","../../schema/src/shadow.ts","../../schema/src/layer.ts","../../schema/src/interaction.ts","../../schema/src/delta.ts","../../schema/src/state.ts","../../schema/src/preset.ts","../../schema/src/variable.ts","../../schema/src/asset.ts","../../schema/src/document.ts","../../schema/src/validate.ts","../../schema/src/parse.ts","../src/commands/info.ts","../src/commands/still.ts","../src/commands/render.ts","../src/commands/render-pipeline.ts","../src/commands/export-svg.ts","../../svg/src/render-svg.ts","../../svg/src/svg-properties.ts","../../svg/src/svg-gradients.ts","../../svg/src/svg-shapes.ts","../../svg/src/svg-text.ts","../../svg/src/svg-filters.ts","../../svg/src/svg-clip.ts","../src/commands/export-lottie.ts","../../lottie/src/map-colors.ts","../../lottie/src/map-shapes.ts","../../lottie/src/map-easing.ts","../../lottie/src/map-keyframes.ts","../../lottie/src/map-layers.ts","../../lottie/src/warnings.ts","../../lottie/src/export-lottie.ts","../src/commands/assets.ts","../src/commands/variables.ts"],"sourcesContent":["/**\n * Linear easing — no acceleration.\n */\nexport function linear(t: number): number {\n return t;\n}\n\n/**\n * Cubic bezier easing — CSS-compatible.\n * Implements the same algorithm as CSS cubic-bezier().\n * @param x1 - first control point x\n * @param y1 - first control point y\n * @param x2 - second control point x\n * @param y2 - second control point y\n */\nexport function cubicBezier(\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): (t: number) => number {\n // Use binary search to find the parametric t value that gives us our x,\n // then compute the corresponding y. This is the standard algorithm used\n // by browsers for CSS transitions.\n\n return (t: number): number => {\n if (t <= 0) return 0;\n if (t >= 1) return 1;\n\n // Binary search for the parametric t value that gives us our x\n let lo = 0;\n let hi = 1;\n let mid: number = 0;\n\n for (let i = 0; i < 20; i++) {\n mid = (lo + hi) / 2;\n const x = sampleBezier(x1, x2, mid);\n if (Math.abs(x - t) < 1e-6) break;\n if (x < t) lo = mid;\n else hi = mid;\n }\n\n mid = (lo + hi) / 2;\n return sampleBezier(y1, y2, mid);\n };\n}\n\n/** Sample a single axis of a cubic bezier at parametric t */\nfunction sampleBezier(p1: number, p2: number, t: number): number {\n // B(t) = 3(1-t)^2*t*p1 + 3(1-t)*t^2*p2 + t^3\n return 3 * (1 - t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t;\n}\n\n/** Common CSS easing presets */\nexport const easeIn = cubicBezier(0.42, 0, 1, 1);\nexport const easeOut = cubicBezier(0, 0, 0.58, 1);\nexport const easeInOut = cubicBezier(0.42, 0, 0.58, 1);\n\n/**\n * Step easing — jumps between discrete values.\n * @param steps - number of steps\n * @param position - \"start\" or \"end\" (default \"end\")\n */\nexport function step(\n steps: number,\n position: \"start\" | \"end\" = \"end\",\n): (t: number) => number {\n return (t: number): number => {\n if (t <= 0) return position === \"start\" ? 1 / steps : 0;\n if (t >= 1) return 1;\n\n const s = Math.floor(t * steps);\n if (position === \"start\") {\n return Math.min((s + 1) / steps, 1);\n }\n return s / steps;\n };\n}\n","export interface SpringConfig {\n mass?: number; // default 1\n stiffness?: number; // default 100\n damping?: number; // default 10\n velocity?: number; // default 0\n}\n\n/**\n * Creates a spring easing function.\n * Uses damped harmonic oscillator physics.\n * Returns a function that takes t (0-1) and returns the spring value.\n *\n * The spring always goes from 0 to 1, but may overshoot.\n */\nexport function spring(config: SpringConfig = {}): (t: number) => number {\n const {\n mass = 1,\n stiffness = 100,\n damping = 10,\n velocity = 0,\n } = config;\n\n const w0 = Math.sqrt(stiffness / mass); // natural frequency\n const zeta = damping / (2 * Math.sqrt(stiffness * mass)); // damping ratio\n\n // Determine total duration to normalize t\n // We pre-calculate a reasonable duration where the spring settles\n const duration = estimateSettleTime(zeta, w0);\n\n return (t: number): number => {\n if (t <= 0) return 0;\n if (t >= 1) return 1;\n\n const time = t * duration;\n let value: number;\n\n if (zeta < 1) {\n // Underdamped\n const wd = w0 * Math.sqrt(1 - zeta * zeta);\n const A = 1;\n const B = (zeta * w0 + velocity) / wd;\n value =\n 1 -\n Math.exp(-zeta * w0 * time) *\n (A * Math.cos(wd * time) + B * Math.sin(wd * time));\n } else if (zeta === 1) {\n // Critically damped\n value = 1 - Math.exp(-w0 * time) * (1 + (w0 + velocity) * time);\n } else {\n // Overdamped\n const s1 = -w0 * (zeta - Math.sqrt(zeta * zeta - 1));\n const s2 = -w0 * (zeta + Math.sqrt(zeta * zeta - 1));\n const A = (velocity - s2) / (s1 - s2);\n const B = 1 - A;\n value = 1 - A * Math.exp(s1 * time) - B * Math.exp(s2 * time);\n }\n\n return value;\n };\n}\n\n/**\n * Estimates the time for a spring to settle within 0.1% of target.\n */\nfunction estimateSettleTime(zeta: number, w0: number): number {\n if (zeta >= 1) {\n return 10 / (zeta * w0);\n }\n // For underdamped: settling ~ -ln(0.001) / (zeta * w0)\n return Math.log(1000) / (zeta * w0);\n}\n","/**\n * Linear interpolation between two numbers.\n */\nexport function lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\n/**\n * Clamp a value between min and max.\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Interpolate between two multi-dimensional values.\n * Arrays must be the same length.\n */\nexport function lerpArray(a: number[], b: number[], t: number): number[] {\n return a.map((v, i) => lerp(v, b[i], t));\n}\n\n/**\n * Re-maps a value from one range to another.\n */\nexport function remap(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number,\n): number {\n const t = (value - inMin) / (inMax - inMin);\n return lerp(outMin, outMax, t);\n}\n","import { lerp, clamp } from \"./lerp.js\";\n\nexport interface RGBA {\n r: number; // 0-255\n g: number; // 0-255\n b: number; // 0-255\n a: number; // 0-1\n}\n\nexport interface HSLA {\n h: number; // 0-360\n s: number; // 0-100\n l: number; // 0-100\n a: number; // 0-1\n}\n\n/**\n * Parse a hex color string to RGBA.\n * Supports: #RGB, #RGBA, #RRGGBB, #RRGGBBAA\n */\nexport function hexToRgba(hex: string): RGBA {\n let h = hex.replace(\"#\", \"\");\n\n if (h.length === 3)\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2] + \"ff\";\n else if (h.length === 4)\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2] + h[3] + h[3];\n else if (h.length === 6) h = h + \"ff\";\n\n return {\n r: parseInt(h.slice(0, 2), 16),\n g: parseInt(h.slice(2, 4), 16),\n b: parseInt(h.slice(4, 6), 16),\n a: parseInt(h.slice(6, 8), 16) / 255,\n };\n}\n\n/**\n * Convert RGBA to hex string.\n */\nexport function rgbaToHex(color: RGBA): string {\n const r = clamp(Math.round(color.r), 0, 255)\n .toString(16)\n .padStart(2, \"0\");\n const g = clamp(Math.round(color.g), 0, 255)\n .toString(16)\n .padStart(2, \"0\");\n const b = clamp(Math.round(color.b), 0, 255)\n .toString(16)\n .padStart(2, \"0\");\n const a = clamp(Math.round(color.a * 255), 0, 255)\n .toString(16)\n .padStart(2, \"0\");\n return `#${r}${g}${b}${a === \"ff\" ? \"\" : a}`;\n}\n\n/**\n * Interpolate between two RGBA colors.\n */\nexport function lerpRgba(a: RGBA, b: RGBA, t: number): RGBA {\n return {\n r: lerp(a.r, b.r, t),\n g: lerp(a.g, b.g, t),\n b: lerp(a.b, b.b, t),\n a: lerp(a.a, b.a, t),\n };\n}\n\n/**\n * Convert RGBA to HSLA.\n */\nexport function rgbaToHsla(color: RGBA): HSLA {\n const r = color.r / 255;\n const g = color.g / 255;\n const b = color.b / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const d = max - min;\n const l = (max + min) / 2;\n\n let h = 0;\n let s = 0;\n\n if (d !== 0) {\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n else if (max === g) h = ((b - r) / d + 2) / 6;\n else h = ((r - g) / d + 4) / 6;\n }\n\n return { h: h * 360, s: s * 100, l: l * 100, a: color.a };\n}\n\n/**\n * Convert HSLA to RGBA.\n */\nexport function hslaToRgba(color: HSLA): RGBA {\n const h = color.h / 360;\n const s = color.s / 100;\n const l = color.l / 100;\n\n let r: number, g: number, b: number;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n r = hueToRgb(p, q, h + 1 / 3);\n g = hueToRgb(p, q, h);\n b = hueToRgb(p, q, h - 1 / 3);\n }\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n a: color.a,\n };\n}\n\nfunction hueToRgb(p: number, q: number, t: number): number {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n}\n\n/**\n * Interpolate between two HSLA colors (shortest hue path).\n */\nexport function lerpHsla(a: HSLA, b: HSLA, t: number): HSLA {\n // Handle hue wrapping — take the shortest path\n let dh = b.h - a.h;\n if (dh > 180) dh -= 360;\n if (dh < -180) dh += 360;\n\n return {\n h: (((a.h + dh * t) % 360) + 360) % 360,\n s: lerp(a.s, b.s, t),\n l: lerp(a.l, b.l, t),\n a: lerp(a.a, b.a, t),\n };\n}\n","/**\n * Path interpolation utilities for motion paths.\n * Evaluates position and tangent along a path defined by points with bezier handles.\n */\n\nexport interface PathPoint2D {\n x: number;\n y: number;\n in?: { x: number; y: number };\n out?: { x: number; y: number };\n}\n\nexport interface PathPosition {\n x: number;\n y: number;\n /** Tangent angle in degrees */\n angle: number;\n}\n\n/**\n * Compute the length of a single cubic bezier segment using subdivision.\n */\nfunction bezierSegmentLength(\n p0x: number, p0y: number,\n c0x: number, c0y: number,\n c1x: number, c1y: number,\n p1x: number, p1y: number,\n steps = 32,\n): number {\n let length = 0;\n let prevX = p0x;\n let prevY = p0y;\n for (let i = 1; i <= steps; i++) {\n const t = i / steps;\n const mt = 1 - t;\n const x = mt * mt * mt * p0x + 3 * mt * mt * t * c0x + 3 * mt * t * t * c1x + t * t * t * p1x;\n const y = mt * mt * mt * p0y + 3 * mt * mt * t * c0y + 3 * mt * t * t * c1y + t * t * t * p1y;\n const dx = x - prevX;\n const dy = y - prevY;\n length += Math.sqrt(dx * dx + dy * dy);\n prevX = x;\n prevY = y;\n }\n return length;\n}\n\n/**\n * Evaluate a cubic bezier at parameter t, returning position and tangent.\n */\nfunction evalBezier(\n p0x: number, p0y: number,\n c0x: number, c0y: number,\n c1x: number, c1y: number,\n p1x: number, p1y: number,\n t: number,\n): PathPosition {\n const mt = 1 - t;\n const x = mt * mt * mt * p0x + 3 * mt * mt * t * c0x + 3 * mt * t * t * c1x + t * t * t * p1x;\n const y = mt * mt * mt * p0y + 3 * mt * mt * t * c0y + 3 * mt * t * t * c1y + t * t * t * p1y;\n\n // Tangent (first derivative)\n const tx = 3 * mt * mt * (c0x - p0x) + 6 * mt * t * (c1x - c0x) + 3 * t * t * (p1x - c1x);\n const ty = 3 * mt * mt * (c0y - p0y) + 6 * mt * t * (c1y - c0y) + 3 * t * t * (p1y - c1y);\n\n const angle = Math.atan2(ty, tx) * (180 / Math.PI);\n\n return { x, y, angle };\n}\n\n/**\n * Build a lookup table of cumulative segment lengths for a path.\n */\nfunction buildSegmentLengths(points: PathPoint2D[], closed: boolean): number[] {\n const segCount = closed ? points.length : points.length - 1;\n const lengths: number[] = [];\n\n for (let i = 0; i < segCount; i++) {\n const p0 = points[i];\n const p1 = points[(i + 1) % points.length];\n\n const c0x = p0.x + (p0.out?.x ?? 0);\n const c0y = p0.y + (p0.out?.y ?? 0);\n const c1x = p1.x + (p1.in?.x ?? 0);\n const c1y = p1.y + (p1.in?.y ?? 0);\n\n lengths.push(bezierSegmentLength(p0.x, p0.y, c0x, c0y, c1x, c1y, p1.x, p1.y));\n }\n\n return lengths;\n}\n\n/**\n * Evaluate a point along a path at a given progress (0–1).\n * Uses arc-length parameterization for uniform speed.\n */\nexport function evaluatePathAtProgress(\n points: PathPoint2D[],\n progress: number,\n closed = false,\n): PathPosition {\n if (points.length < 2) {\n return { x: points[0]?.x ?? 0, y: points[0]?.y ?? 0, angle: 0 };\n }\n\n // Clamp progress\n const t = Math.max(0, Math.min(1, progress));\n\n const segLengths = buildSegmentLengths(points, closed);\n const totalLength = segLengths.reduce((a, b) => a + b, 0);\n\n if (totalLength === 0) {\n return { x: points[0].x, y: points[0].y, angle: 0 };\n }\n\n const targetLength = t * totalLength;\n\n // Find which segment the target length falls in\n let accumulated = 0;\n for (let i = 0; i < segLengths.length; i++) {\n const segLen = segLengths[i];\n if (accumulated + segLen >= targetLength || i === segLengths.length - 1) {\n // Progress within this segment\n const segProgress = segLen === 0 ? 0 : (targetLength - accumulated) / segLen;\n\n const p0 = points[i];\n const p1 = points[(i + 1) % points.length];\n\n const c0x = p0.x + (p0.out?.x ?? 0);\n const c0y = p0.y + (p0.out?.y ?? 0);\n const c1x = p1.x + (p1.in?.x ?? 0);\n const c1y = p1.y + (p1.in?.y ?? 0);\n\n return evalBezier(p0.x, p0.y, c0x, c0y, c1x, c1y, p1.x, p1.y, segProgress);\n }\n accumulated += segLen;\n }\n\n // Fallback (shouldn't reach here)\n const last = points[points.length - 1];\n return { x: last.x, y: last.y, angle: 0 };\n}\n","import type { Delta, FrameRange } from \"@a-company/atelier-types\";\nimport { lerp, clamp, hexToRgba, lerpRgba, rgbaToHex } from \"@a-company/atelier-math\";\nimport { resolveEasing } from \"./easing-resolver.js\";\nimport { isExpression, evaluateExpression, type ExpressionContext } from \"../expressions/expression-evaluator.js\";\n\n/**\n * Check if a frame is within a delta's range (inclusive).\n */\nexport function isFrameInRange(frame: number, range: FrameRange): boolean {\n return frame >= range[0] && frame <= range[1];\n}\n\n/**\n * Compute the progress (0-1) of a frame within a delta's range.\n */\nexport function computeProgress(frame: number, range: FrameRange): number {\n const [start, end] = range;\n if (start === end) return 1; // instantaneous\n return clamp((frame - start) / (end - start), 0, 1);\n}\n\n/**\n * Resolve a single delta's value at a given frame.\n * Returns undefined if the frame is outside the delta's range.\n * Returns the interpolated value if within range.\n *\n * If `from` or `to` is an expression object `{ expr: \"...\" }`,\n * it is evaluated with the current animation context before interpolation.\n */\nexport function resolveDeltaValue(delta: Delta, frame: number): unknown | undefined {\n if (!isFrameInRange(frame, delta.range)) {\n return undefined;\n }\n\n const progress = computeProgress(frame, delta.range);\n const easingFn = resolveEasing(delta.easing);\n const easedProgress = easingFn(progress);\n\n const exprCtx: ExpressionContext = {\n t: easedProgress,\n progress,\n frame,\n duration: delta.range[1] - delta.range[0],\n };\n\n const from = isExpression(delta.from)\n ? evaluateExpression(delta.from.expr, exprCtx)\n : delta.from;\n\n const to = isExpression(delta.to)\n ? evaluateExpression(delta.to.expr, exprCtx)\n : delta.to;\n\n return interpolateValue(from, to, easedProgress);\n}\n\n/**\n * Interpolate between two values based on eased progress.\n * Handles numbers, strings (pass-through at threshold), and nested objects.\n */\nexport function interpolateValue(from: unknown, to: unknown, t: number): unknown {\n // Number interpolation\n if (typeof from === \"number\" && typeof to === \"number\") {\n return lerp(from, to, t);\n }\n\n // Hex color interpolation\n if (typeof from === \"string\" && typeof to === \"string\") {\n if (from.startsWith(\"#\") && to.startsWith(\"#\")) {\n return rgbaToHex(lerpRgba(hexToRgba(from), hexToRgba(to), t));\n }\n // Non-color strings — snap at end\n return t >= 1 ? to : from;\n }\n\n // Boolean interpolation — snap at midpoint for frame-precise control\n if (typeof from === \"boolean\" && typeof to === \"boolean\") {\n return t >= 0.5 ? to : from;\n }\n\n // For unknown types, snap at end\n return t >= 1 ? to : from;\n}\n\n/**\n * Given multiple deltas for the SAME layer+property, find the active one\n * at a given frame and return its resolved value.\n *\n * If no delta is active at this frame, holds the `to` value of the most\n * recent completed delta (the one whose range ended most recently before\n * this frame). This prevents properties from reverting after animation ends.\n *\n * Assumes no overlaps (validated elsewhere).\n */\nexport function resolvePropertyAtFrame(\n deltas: Delta[],\n frame: number,\n): unknown | undefined {\n // Check for an active delta first\n for (const delta of deltas) {\n if (isFrameInRange(frame, delta.range)) {\n return resolveDeltaValue(delta, frame);\n }\n }\n\n // No active delta — hold the `to` value of the most recently completed delta\n let lastCompleted: Delta | undefined;\n for (const delta of deltas) {\n if (frame > delta.range[1]) {\n if (!lastCompleted || delta.range[1] > lastCompleted.range[1]) {\n lastCompleted = delta;\n }\n }\n }\n\n if (!lastCompleted) return undefined;\n\n // If the held `to` value is an expression, evaluate at t=1\n if (isExpression(lastCompleted.to)) {\n return evaluateExpression(lastCompleted.to.expr, {\n t: 1,\n progress: 1,\n frame,\n duration: lastCompleted.range[1] - lastCompleted.range[0],\n });\n }\n\n return lastCompleted.to;\n}\n","import type { Easing } from \"@a-company/atelier-types\";\nimport { linear, cubicBezier, easeIn, easeOut, easeInOut, step, spring } from \"@a-company/atelier-math\";\n\n/**\n * Converts an Easing type definition into an executable easing function.\n * Returns a function (t: number) => number where t is 0-1.\n */\nexport function resolveEasing(easing: Easing | undefined): (t: number) => number {\n if (!easing) return linear;\n\n // String presets\n if (typeof easing === \"string\") {\n switch (easing) {\n case \"linear\": return linear;\n case \"ease-in\": return easeIn;\n case \"ease-out\": return easeOut;\n case \"ease-in-out\": return easeInOut;\n default: return linear;\n }\n }\n\n // Object easing definitions\n switch (easing.type) {\n case \"linear\":\n return linear;\n case \"cubic-bezier\":\n return cubicBezier(easing.x1, easing.y1, easing.x2, easing.y2);\n case \"spring\":\n return spring({\n mass: easing.mass,\n stiffness: easing.stiffness,\n damping: easing.damping,\n velocity: easing.velocity,\n });\n case \"step\":\n return step(easing.steps, easing.position);\n default:\n return linear;\n }\n}\n","/**\n * Safe recursive descent expression evaluator.\n * No eval(), no Function(), no code generation.\n *\n * Supports:\n * - Numbers: 42, 3.14, -1\n * - Operators: + - * / % **\n * - Parentheses: (expr)\n * - Math functions: sin, cos, tan, abs, min, max, floor, ceil, round, sqrt, pow, clamp, sign, log\n * - Constants: pi, tau, e\n * - Context variables: t, frame, duration, progress\n * - Comparison: <, >, <=, >=, ==, !=\n * - Ternary: condition ? trueExpr : falseExpr\n */\n\n/** Context variables available during expression evaluation */\nexport interface ExpressionContext {\n /** Eased progress 0–1 */\n t: number;\n /** Raw progress 0–1 (before easing) */\n progress: number;\n /** Current frame number */\n frame: number;\n /** Delta duration in frames */\n duration: number;\n}\n\n// ── Tokenizer ───────────────────────────────────────────────\n\ntype TokenType =\n | \"number\"\n | \"ident\"\n | \"op\"\n | \"lparen\"\n | \"rparen\"\n | \"comma\"\n | \"question\"\n | \"colon\"\n | \"compare\"\n | \"eof\";\n\ninterface Token {\n type: TokenType;\n value: string;\n}\n\nfunction tokenize(expr: string): Token[] {\n const tokens: Token[] = [];\n let i = 0;\n\n while (i < expr.length) {\n const ch = expr[i];\n\n // Whitespace\n if (ch === \" \" || ch === \"\\t\" || ch === \"\\n\" || ch === \"\\r\") {\n i++;\n continue;\n }\n\n // Numbers\n if ((ch >= \"0\" && ch <= \"9\") || ch === \".\") {\n let num = \"\";\n while (i < expr.length && ((expr[i] >= \"0\" && expr[i] <= \"9\") || expr[i] === \".\")) {\n num += expr[i++];\n }\n tokens.push({ type: \"number\", value: num });\n continue;\n }\n\n // Identifiers (variables, functions, constants)\n if ((ch >= \"a\" && ch <= \"z\") || (ch >= \"A\" && ch <= \"Z\") || ch === \"_\") {\n let id = \"\";\n while (i < expr.length && ((expr[i] >= \"a\" && expr[i] <= \"z\") || (expr[i] >= \"A\" && expr[i] <= \"Z\") || (expr[i] >= \"0\" && expr[i] <= \"9\") || expr[i] === \"_\")) {\n id += expr[i++];\n }\n tokens.push({ type: \"ident\", value: id });\n continue;\n }\n\n // Comparison operators (must check before single-char ops)\n if (ch === \"<\" || ch === \">\" || ch === \"!\" || ch === \"=\") {\n if (i + 1 < expr.length && expr[i + 1] === \"=\") {\n tokens.push({ type: \"compare\", value: ch + \"=\" });\n i += 2;\n continue;\n }\n if (ch === \"<\" || ch === \">\") {\n tokens.push({ type: \"compare\", value: ch });\n i++;\n continue;\n }\n }\n\n // Power operator\n if (ch === \"*\" && i + 1 < expr.length && expr[i + 1] === \"*\") {\n tokens.push({ type: \"op\", value: \"**\" });\n i += 2;\n continue;\n }\n\n // Operators\n if (ch === \"+\" || ch === \"-\" || ch === \"*\" || ch === \"/\" || ch === \"%\") {\n tokens.push({ type: \"op\", value: ch });\n i++;\n continue;\n }\n\n // Grouping and function calls\n if (ch === \"(\") { tokens.push({ type: \"lparen\", value: \"(\" }); i++; continue; }\n if (ch === \")\") { tokens.push({ type: \"rparen\", value: \")\" }); i++; continue; }\n if (ch === \",\") { tokens.push({ type: \"comma\", value: \",\" }); i++; continue; }\n\n // Ternary\n if (ch === \"?\") { tokens.push({ type: \"question\", value: \"?\" }); i++; continue; }\n if (ch === \":\") { tokens.push({ type: \"colon\", value: \":\" }); i++; continue; }\n\n throw new Error(`Expression: unexpected character '${ch}' at position ${i}`);\n }\n\n tokens.push({ type: \"eof\", value: \"\" });\n return tokens;\n}\n\n// ── Parser + Evaluator ──────────────────────────────────────\n\nconst CONSTANTS: Record<string, number> = {\n pi: Math.PI,\n PI: Math.PI,\n tau: Math.PI * 2,\n TAU: Math.PI * 2,\n e: Math.E,\n E: Math.E,\n};\n\nconst FUNCTIONS: Record<string, (...args: number[]) => number> = {\n sin: Math.sin,\n cos: Math.cos,\n tan: Math.tan,\n abs: Math.abs,\n floor: Math.floor,\n ceil: Math.ceil,\n round: Math.round,\n sqrt: Math.sqrt,\n sign: Math.sign,\n log: Math.log,\n min: (...args) => Math.min(...args),\n max: (...args) => Math.max(...args),\n pow: (a, b) => Math.pow(a, b),\n clamp: (v, lo, hi) => Math.min(Math.max(v, lo), hi),\n};\n\nclass Parser {\n private tokens: Token[];\n private pos = 0;\n private ctx: ExpressionContext;\n\n constructor(tokens: Token[], ctx: ExpressionContext) {\n this.tokens = tokens;\n this.ctx = ctx;\n }\n\n private peek(): Token {\n return this.tokens[this.pos];\n }\n\n private consume(expectedType?: TokenType): Token {\n const tok = this.tokens[this.pos++];\n if (expectedType && tok.type !== expectedType) {\n throw new Error(`Expression: expected ${expectedType} but got ${tok.type} '${tok.value}'`);\n }\n return tok;\n }\n\n /** Entry: ternary (lowest precedence) */\n parse(): number {\n const result = this.parseTernary();\n if (this.peek().type !== \"eof\") {\n throw new Error(`Expression: unexpected token '${this.peek().value}'`);\n }\n return result;\n }\n\n /** ternary: comparison ? expr : expr */\n private parseTernary(): number {\n const condition = this.parseComparison();\n if (this.peek().type === \"question\") {\n this.consume(); // ?\n const trueVal = this.parseTernary();\n this.consume(\"colon\"); // :\n const falseVal = this.parseTernary();\n return condition ? trueVal : falseVal;\n }\n return condition;\n }\n\n /** comparison: additive (< | > | <= | >= | == | !=) additive */\n private parseComparison(): number {\n let left = this.parseAdditive();\n while (this.peek().type === \"compare\") {\n const op = this.consume().value;\n const right = this.parseAdditive();\n switch (op) {\n case \"<\": left = left < right ? 1 : 0; break;\n case \">\": left = left > right ? 1 : 0; break;\n case \"<=\": left = left <= right ? 1 : 0; break;\n case \">=\": left = left >= right ? 1 : 0; break;\n case \"==\": left = left === right ? 1 : 0; break;\n case \"!=\": left = left !== right ? 1 : 0; break;\n }\n }\n return left;\n }\n\n /** additive: multiplicative (('+' | '-') multiplicative)* */\n private parseAdditive(): number {\n let left = this.parseMultiplicative();\n while (this.peek().type === \"op\" && (this.peek().value === \"+\" || this.peek().value === \"-\")) {\n const op = this.consume().value;\n const right = this.parseMultiplicative();\n left = op === \"+\" ? left + right : left - right;\n }\n return left;\n }\n\n /** multiplicative: power (('*' | '/' | '%') power)* */\n private parseMultiplicative(): number {\n let left = this.parsePower();\n while (this.peek().type === \"op\" && (this.peek().value === \"*\" || this.peek().value === \"/\" || this.peek().value === \"%\")) {\n const op = this.consume().value;\n const right = this.parsePower();\n if (op === \"*\") left = left * right;\n else if (op === \"/\") left = right !== 0 ? left / right : 0;\n else left = left % right;\n }\n return left;\n }\n\n /** power: unary ('**' unary)* (right-associative) */\n private parsePower(): number {\n const base = this.parseUnary();\n if (this.peek().type === \"op\" && this.peek().value === \"**\") {\n this.consume();\n const exp = this.parsePower(); // right-associative\n return Math.pow(base, exp);\n }\n return base;\n }\n\n /** unary: ('-' | '+') unary | primary */\n private parseUnary(): number {\n if (this.peek().type === \"op\" && (this.peek().value === \"-\" || this.peek().value === \"+\")) {\n const op = this.consume().value;\n const val = this.parseUnary();\n return op === \"-\" ? -val : val;\n }\n return this.parsePrimary();\n }\n\n /** primary: number | ident | function(args) | '(' expr ')' */\n private parsePrimary(): number {\n const tok = this.peek();\n\n // Number literal\n if (tok.type === \"number\") {\n this.consume();\n return parseFloat(tok.value);\n }\n\n // Identifier: constant, context variable, or function\n if (tok.type === \"ident\") {\n this.consume();\n const name = tok.value;\n\n // Function call\n if (this.peek().type === \"lparen\") {\n this.consume(); // (\n const args: number[] = [];\n if (this.peek().type !== \"rparen\") {\n args.push(this.parseTernary());\n while (this.peek().type === \"comma\") {\n this.consume(); // ,\n args.push(this.parseTernary());\n }\n }\n this.consume(\"rparen\"); // )\n\n const fn = FUNCTIONS[name];\n if (!fn) throw new Error(`Expression: unknown function '${name}'`);\n return fn(...args);\n }\n\n // Constant\n if (name in CONSTANTS) return CONSTANTS[name];\n\n // Context variable\n if (name in this.ctx) return (this.ctx as unknown as Record<string, number>)[name];\n\n throw new Error(`Expression: unknown variable '${name}'`);\n }\n\n // Parenthesized expression\n if (tok.type === \"lparen\") {\n this.consume(); // (\n const val = this.parseTernary();\n this.consume(\"rparen\"); // )\n return val;\n }\n\n throw new Error(`Expression: unexpected token '${tok.value}'`);\n }\n}\n\n// ── Public API ──────────────────────────────────────────────\n\n/**\n * Check if a value is an expression object { expr: string }.\n */\nexport function isExpression(value: unknown): value is { expr: string } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"expr\" in value &&\n typeof (value as Record<string, unknown>).expr === \"string\"\n );\n}\n\n/**\n * Evaluate an expression string with the given context.\n * Returns a number. Throws on syntax errors or unknown identifiers.\n */\nexport function evaluateExpression(expr: string, ctx: ExpressionContext): number {\n const tokens = tokenize(expr);\n const parser = new Parser(tokens, ctx);\n return parser.parse();\n}\n","import type { AtelierDocument, Layer, Delta, AnimatableProperty } from \"@a-company/atelier-types\";\nimport { resolvePropertyAtFrame } from \"./delta-resolver.js\";\n\n/** A resolved layer at a specific frame — all animated properties computed */\nexport interface ResolvedLayer {\n id: string;\n /** Original layer definition */\n layer: Layer;\n /** Computed property overrides from active deltas */\n computedProperties: Partial<Record<AnimatableProperty, unknown>>;\n}\n\n/** The resolved state of an entire document at a specific frame */\nexport interface ResolvedFrame {\n /** Frame number that was resolved */\n frame: number;\n /** State name that was resolved */\n stateName: string;\n /** All layers with their computed properties */\n layers: ResolvedLayer[];\n}\n\n/**\n * Resolve all layers at a given frame within a named state.\n * This is the main entry point for frame resolution.\n * @param overrideDeltas - Optional pre-merged deltas (used for hierarchical state resolution)\n */\nexport function resolveFrame(\n doc: AtelierDocument,\n stateName: string,\n frame: number,\n overrideDeltas?: Delta[],\n): ResolvedFrame {\n const state = doc.states[stateName];\n if (!state) {\n throw new Error(`State \"${stateName}\" not found in document \"${doc.name}\"`);\n }\n\n // Group deltas by layer+property\n const deltasByLayerProperty = groupDeltas(overrideDeltas ?? state.deltas);\n\n // Resolve each layer\n const resolvedLayers: ResolvedLayer[] = doc.layers.map((layer) => {\n const computedProperties: Partial<Record<AnimatableProperty, unknown>> = {};\n\n // Find all animated properties for this layer\n const layerDeltas = deltasByLayerProperty.get(layer.id);\n if (layerDeltas) {\n for (const [property, deltas] of layerDeltas) {\n const value = resolvePropertyAtFrame(deltas, frame);\n if (value !== undefined) {\n computedProperties[property as AnimatableProperty] = value;\n }\n }\n }\n\n return { id: layer.id, layer, computedProperties };\n });\n\n return { frame, stateName, layers: resolvedLayers };\n}\n\n/**\n * Group deltas by layer ID, then by property name.\n */\nfunction groupDeltas(\n deltas: Delta[],\n): Map<string, Map<string, Delta[]>> {\n const map = new Map<string, Map<string, Delta[]>>();\n\n for (const delta of deltas) {\n let layerMap = map.get(delta.layer);\n if (!layerMap) {\n layerMap = new Map();\n map.set(delta.layer, layerMap);\n }\n\n let propDeltas = layerMap.get(delta.property);\n if (!propDeltas) {\n propDeltas = [];\n layerMap.set(delta.property, propDeltas);\n }\n\n propDeltas.push(delta);\n }\n\n return map;\n}\n","import type { Delta, FrameRange } from \"@a-company/atelier-types\";\n\nexport interface OverlapError {\n layerId: string;\n property: string;\n existingRange: FrameRange;\n newRange: FrameRange;\n message: string;\n}\n\n/**\n * Check if two frame ranges overlap.\n * Boundary-touching ranges (e.g., [0-50] and [50-90]) are allowed —\n * only ranges that share more than a single boundary frame are overlaps.\n */\nexport function rangesOverlap(a: FrameRange, b: FrameRange): boolean {\n return a[0] < b[1] && b[0] < a[1];\n}\n\n/**\n * Validate that a new delta doesn't overlap with existing deltas\n * on the same layer+property.\n */\nexport function validateNoOverlap(\n existing: Delta[],\n newDelta: Delta,\n): OverlapError | null {\n for (const delta of existing) {\n if (\n delta.layer === newDelta.layer &&\n delta.property === newDelta.property &&\n rangesOverlap(delta.range, newDelta.range)\n ) {\n return {\n layerId: newDelta.layer,\n property: newDelta.property,\n existingRange: delta.range,\n newRange: newDelta.range,\n message: `Overlapping delta on layer \"${newDelta.layer}\" property \"${newDelta.property}\": ` +\n `existing [${delta.range[0]}-${delta.range[1]}] overlaps with new [${newDelta.range[0]}-${newDelta.range[1]}]`,\n };\n }\n }\n return null;\n}\n\n/**\n * Validate all deltas in a state have no overlaps.\n * Returns all overlap errors found.\n */\nexport function validateAllDeltas(deltas: Delta[]): OverlapError[] {\n const errors: OverlapError[] = [];\n\n for (let i = 0; i < deltas.length; i++) {\n for (let j = i + 1; j < deltas.length; j++) {\n const a = deltas[i];\n const b = deltas[j];\n\n if (\n a.layer === b.layer &&\n a.property === b.property &&\n rangesOverlap(a.range, b.range)\n ) {\n errors.push({\n layerId: a.layer,\n property: a.property,\n existingRange: a.range,\n newRange: b.range,\n message: `Overlapping deltas on layer \"${a.layer}\" property \"${a.property}\": ` +\n `[${a.range[0]}-${a.range[1]}] overlaps with [${b.range[0]}-${b.range[1]}]`,\n });\n }\n }\n }\n\n return errors;\n}\n","import type {\n AtelierDocument, Canvas, Layer, State, Delta, Preset,\n Variable, Asset,\n} from \"@a-company/atelier-types\";\nimport { validateNoOverlap } from \"../validation/overlap-validator.js\";\n\n/**\n * Fluent builder for constructing AtelierDocument objects.\n * Validates constraints (like no-overlap) as you build.\n */\nexport class DocumentBuilder {\n private doc: AtelierDocument;\n\n constructor(name: string, canvas: Canvas) {\n this.doc = {\n version: \"1.0\",\n name,\n canvas,\n layers: [],\n states: {},\n };\n }\n\n /** Set document description */\n description(desc: string): this {\n this.doc.description = desc;\n return this;\n }\n\n /** Add tags to the document */\n tags(...tags: string[]): this {\n this.doc.tags = [...(this.doc.tags ?? []), ...tags];\n return this;\n }\n\n /** Add a variable definition */\n variable(id: string, variable: Variable): this {\n if (!this.doc.variables) this.doc.variables = {};\n this.doc.variables[id] = variable;\n return this;\n }\n\n /** Add an asset reference */\n asset(id: string, asset: Asset): this {\n if (!this.doc.assets) this.doc.assets = {};\n this.doc.assets[id] = asset;\n return this;\n }\n\n /** Add a preset */\n preset(id: string, preset: Preset): this {\n if (!this.doc.presets) this.doc.presets = {};\n this.doc.presets[id] = preset;\n return this;\n }\n\n /** Add a layer */\n addLayer(layer: Layer): this {\n // Check for duplicate IDs\n if (this.doc.layers.some(l => l.id === layer.id)) {\n throw new Error(`Layer with id \"${layer.id}\" already exists`);\n }\n this.doc.layers.push(layer);\n return this;\n }\n\n /** Add a state */\n addState(name: string, state: Omit<State, \"deltas\"> & { deltas?: Delta[] }): this {\n if (this.doc.states[name]) {\n throw new Error(`State \"${name}\" already exists`);\n }\n this.doc.states[name] = { ...state, deltas: state.deltas ?? [] };\n return this;\n }\n\n /** Add a delta to an existing state, with overlap validation */\n addDelta(stateName: string, delta: Delta): this {\n const state = this.doc.states[stateName];\n if (!state) {\n throw new Error(`State \"${stateName}\" not found`);\n }\n\n // Verify the layer exists\n if (!this.doc.layers.some(l => l.id === delta.layer)) {\n throw new Error(`Layer \"${delta.layer}\" not found — add the layer before adding deltas`);\n }\n\n // Check for overlaps\n const overlap = validateNoOverlap(state.deltas, delta);\n if (overlap) {\n throw new Error(overlap.message);\n }\n\n state.deltas.push(delta);\n return this;\n }\n\n /** Build and return the final document */\n build(): AtelierDocument {\n return JSON.parse(JSON.stringify(this.doc)) as AtelierDocument;\n }\n}\n\n/**\n * Create a new DocumentBuilder.\n * Convenience function for starting a builder chain.\n */\nexport function createDocument(name: string, canvas: Canvas): DocumentBuilder {\n return new DocumentBuilder(name, canvas);\n}\n","import type { UnitValue } from \"@a-company/atelier-types\";\n\n/**\n * Check if a UnitValue is a percentage string.\n */\nexport function isPercentage(value: UnitValue): value is `${number}%` {\n return typeof value === \"string\" && value.endsWith(\"%\");\n}\n\n/**\n * Parse a percentage string to its numeric value (0-100).\n */\nexport function parsePercentage(value: `${number}%`): number {\n return parseFloat(value);\n}\n\n/**\n * Resolve a UnitValue to pixels given a reference dimension.\n * Pixel values pass through unchanged.\n * Percentage values are computed relative to the reference.\n */\nexport function resolveUnit(value: UnitValue, reference: number): number {\n if (isPercentage(value)) {\n return (parsePercentage(value) / 100) * reference;\n }\n return value;\n}\n","import type { Preset, Delta, FrameRange } from \"@a-company/atelier-types\";\n\n/**\n * Expand a preset into concrete deltas for a specific layer and start frame.\n *\n * @param preset - The preset to expand\n * @param layerId - Target layer ID\n * @param startFrame - Frame to start the preset from\n * @param duration - Total duration to map preset offsets into\n */\nexport function expandPreset(\n preset: Preset,\n layerId: string,\n startFrame: number,\n duration: number,\n): Delta[] {\n return preset.deltas.map((pd, index) => {\n let range: FrameRange;\n if (pd.offset) {\n range = [startFrame + pd.offset[0], startFrame + pd.offset[1]];\n } else {\n range = [startFrame, startFrame + duration];\n }\n\n return {\n id: `preset-${layerId}-${index}`,\n layer: layerId,\n property: pd.property,\n range,\n from: pd.from,\n to: pd.to,\n easing: pd.easing,\n };\n });\n}\n","import type { AtelierDocument, Easing, State, Delta } from \"@a-company/atelier-types\";\nimport { resolveFrame, type ResolvedFrame } from \"../resolver/frame-resolver.js\";\nimport { resolveEasing } from \"../resolver/easing-resolver.js\";\n\nexport interface StateTransition {\n from: string;\n to: string;\n at: number; // frame at which transition occurs\n}\n\nexport interface PlaybackState {\n stateName: string;\n frame: number;\n resolved: ResolvedFrame;\n isComplete: boolean;\n}\n\nexport interface ActiveTransition {\n fromState: string;\n toState: string;\n duration: number;\n easingFn: (t: number) => number;\n transitionFrame: number; // how many frames into the transition\n}\n\nexport class StateMachine {\n private currentState: string;\n private currentFrame = 0;\n private transitions: StateTransition[] = [];\n private activeTransition: ActiveTransition | null = null;\n\n constructor(\n private doc: AtelierDocument,\n initialState?: string,\n ) {\n // Default to first state\n const stateNames = Object.keys(doc.states);\n if (stateNames.length === 0) throw new Error(\"Document has no states\");\n this.currentState = initialState ?? stateNames[0];\n if (!doc.states[this.currentState]) {\n throw new Error(`State \"${this.currentState}\" not found`);\n }\n }\n\n /** Get current state name */\n get state(): string {\n return this.currentState;\n }\n\n /** Get current frame */\n get frame(): number {\n return this.currentFrame;\n }\n\n /** Get all state names */\n get stateNames(): string[] {\n return Object.keys(this.doc.states);\n }\n\n /** Get current state duration */\n get duration(): number {\n return this.doc.states[this.currentState].duration;\n }\n\n /** Check if current state playback is complete */\n get isComplete(): boolean {\n return this.currentFrame >= this.duration - 1;\n }\n\n /** Check if currently in a transition blend */\n isTransitioning(): boolean {\n return this.activeTransition !== null;\n }\n\n /** Get transition progress (0–1) with easing applied, or null if not transitioning */\n getTransitionProgress(): number | null {\n if (!this.activeTransition) return null;\n const { transitionFrame, duration, easingFn } = this.activeTransition;\n const rawProgress = Math.min(transitionFrame / duration, 1);\n return easingFn(rawProgress);\n }\n\n // ── Hierarchical State Support ────────────────────────────\n\n /**\n * Resolve the ancestor chain for a state (root → … → parent → self).\n * Throws on circular parent references.\n */\n resolveAncestorChain(stateName: string): string[] {\n const chain: string[] = [];\n const visited = new Set<string>();\n let current: string | undefined = stateName;\n\n while (current) {\n if (visited.has(current)) {\n throw new Error(`Circular parent reference detected: \"${current}\" already in chain [${chain.join(\" → \")}]`);\n }\n visited.add(current);\n chain.unshift(current); // prepend so root is first\n const stateObj: State | undefined = this.doc.states[current];\n if (!stateObj) {\n throw new Error(`Parent state \"${current}\" not found`);\n }\n current = stateObj.parent;\n }\n\n return chain;\n }\n\n /**\n * Collect merged deltas from ancestor chain.\n * Child overrides parent deltas for the same layer+property combination.\n * Deltas for different layer+property pairs are accumulated from all ancestors.\n */\n collectDeltas(stateName: string): Delta[] {\n const chain = this.resolveAncestorChain(stateName);\n // Walk root → child. Later entries override earlier for same layer+property.\n const deltaMap = new Map<string, Delta[]>();\n\n for (const ancestorName of chain) {\n const state = this.doc.states[ancestorName];\n // Group this state's deltas by layer+property\n const stateGroups = new Map<string, Delta[]>();\n for (const delta of state.deltas) {\n const key = `${delta.layer}:${delta.property}`;\n if (!stateGroups.has(key)) stateGroups.set(key, []);\n stateGroups.get(key)!.push(delta);\n }\n // Child replaces parent for same key\n for (const [key, deltas] of stateGroups) {\n deltaMap.set(key, deltas);\n }\n }\n\n // Flatten all deltas\n const result: Delta[] = [];\n for (const deltas of deltaMap.values()) {\n result.push(...deltas);\n }\n return result;\n }\n\n // ── Playback ──────────────────────────────────────────────\n\n /** Advance to next frame, returns resolved frame */\n tick(): PlaybackState {\n // Handle active transition\n if (this.activeTransition) {\n this.activeTransition.transitionFrame++;\n if (this.activeTransition.transitionFrame >= this.activeTransition.duration) {\n // Transition complete\n this.activeTransition = null;\n }\n }\n\n const resolved = this.resolveCurrentFrame();\n const result: PlaybackState = {\n stateName: this.currentState,\n frame: this.currentFrame,\n resolved,\n isComplete: this.isComplete,\n };\n if (this.currentFrame < this.duration - 1) {\n this.currentFrame++;\n }\n return result;\n }\n\n /** Resolve the current frame, blending if in transition */\n private resolveCurrentFrame(): ResolvedFrame {\n if (this.activeTransition) {\n const progress = this.getTransitionProgress()!;\n const fromResolved = resolveFrame(\n this.doc, this.activeTransition.fromState, this.currentFrame,\n this.collectDeltas(this.activeTransition.fromState),\n );\n const toResolved = resolveFrame(\n this.doc, this.activeTransition.toState, this.currentFrame,\n this.collectDeltas(this.activeTransition.toState),\n );\n return blendResolvedFrames(fromResolved, toResolved, progress);\n }\n\n // Check if current state has a parent — use merged deltas\n const state = this.doc.states[this.currentState];\n if (state.parent) {\n const mergedDeltas = this.collectDeltas(this.currentState);\n return resolveFrame(this.doc, this.currentState, this.currentFrame, mergedDeltas);\n }\n\n return resolveFrame(this.doc, this.currentState, this.currentFrame);\n }\n\n /** Transition to a different state (instant or blended) */\n transition(stateName: string, startFrame = 0): void {\n if (!this.doc.states[stateName]) {\n throw new Error(`State \"${stateName}\" not found`);\n }\n\n const fromState = this.currentState;\n const currentStateObj = this.doc.states[fromState];\n const transConfig = currentStateObj.transitions?.[stateName];\n\n this.transitions.push({\n from: fromState,\n to: stateName,\n at: this.currentFrame,\n });\n\n if (transConfig && transConfig.duration > 0) {\n // Start a smooth transition\n this.activeTransition = {\n fromState,\n toState: stateName,\n duration: transConfig.duration,\n easingFn: resolveEasing(transConfig.easing),\n transitionFrame: 0,\n };\n }\n\n this.currentState = stateName;\n this.currentFrame = startFrame;\n }\n\n /**\n * Start a smooth transition to target state with explicit duration/easing.\n * This ignores any transitions config on the state.\n */\n transitionTo(targetState: string, duration: number, easing?: Easing): void {\n if (!this.doc.states[targetState]) {\n throw new Error(`State \"${targetState}\" not found`);\n }\n\n const fromState = this.currentState;\n this.transitions.push({\n from: fromState,\n to: targetState,\n at: this.currentFrame,\n });\n\n this.activeTransition = {\n fromState,\n toState: targetState,\n duration,\n easingFn: resolveEasing(easing),\n transitionFrame: 0,\n };\n\n this.currentState = targetState;\n this.currentFrame = 0;\n }\n\n /** Seek to a specific frame in current state */\n seek(frame: number): void {\n this.currentFrame = Math.max(0, Math.min(frame, this.duration - 1));\n }\n\n /** Reset to initial state */\n reset(stateName?: string): void {\n if (stateName) {\n if (!this.doc.states[stateName]) throw new Error(`State \"${stateName}\" not found`);\n this.currentState = stateName;\n }\n this.currentFrame = 0;\n this.activeTransition = null;\n }\n\n /** Get transition history */\n get history(): ReadonlyArray<StateTransition> {\n return this.transitions;\n }\n\n /** Resolve a specific frame without advancing */\n resolveAt(stateName: string, frame: number): ResolvedFrame {\n if (!this.doc.states[stateName]) throw new Error(`State \"${stateName}\" not found`);\n const state = this.doc.states[stateName];\n if (state.parent) {\n return resolveFrame(this.doc, stateName, frame, this.collectDeltas(stateName));\n }\n return resolveFrame(this.doc, stateName, frame);\n }\n\n /** Play through entire current state, calling callback on each frame */\n playThrough(onFrame: (state: PlaybackState) => void): void {\n this.currentFrame = 0;\n while (!this.isComplete) {\n onFrame(this.tick());\n }\n onFrame(this.tick()); // last frame\n }\n}\n\n// ── Frame Blending ────────────────────────────────────────────\n\nimport type { ResolvedLayer } from \"../resolver/frame-resolver.js\";\nimport type { AnimatableProperty } from \"@a-company/atelier-types\";\nimport { interpolateValue } from \"../resolver/delta-resolver.js\";\n\n/**\n * Blend two resolved frames together for smooth state transitions.\n * Numeric properties are lerped, colors are color-lerped, discrete values snap at t >= 0.5.\n */\nexport function blendResolvedFrames(\n frameA: ResolvedFrame,\n frameB: ResolvedFrame,\n t: number,\n): ResolvedFrame {\n // Build layer maps\n const mapA = new Map<string, ResolvedLayer>();\n const mapB = new Map<string, ResolvedLayer>();\n for (const l of frameA.layers) mapA.set(l.id, l);\n for (const l of frameB.layers) mapB.set(l.id, l);\n\n // Get all unique layer IDs\n const allIds = new Set([...mapA.keys(), ...mapB.keys()]);\n const blendedLayers: ResolvedLayer[] = [];\n\n for (const id of allIds) {\n const layerA = mapA.get(id);\n const layerB = mapB.get(id);\n\n if (layerA && layerB) {\n // Both exist — blend computed properties\n blendedLayers.push(blendLayers(layerA, layerB, t));\n } else if (layerA && !layerB) {\n // Only in A — fade out (set opacity toward 0)\n blendedLayers.push(fadeLayer(layerA, 1 - t));\n } else if (!layerA && layerB) {\n // Only in B — fade in (set opacity from 0)\n blendedLayers.push(fadeLayer(layerB, t));\n }\n }\n\n return {\n frame: frameB.frame,\n stateName: frameB.stateName,\n layers: blendedLayers,\n };\n}\n\nfunction blendLayers(a: ResolvedLayer, b: ResolvedLayer, t: number): ResolvedLayer {\n const allProps = new Set([\n ...Object.keys(a.computedProperties),\n ...Object.keys(b.computedProperties),\n ]);\n\n const blended: Partial<Record<AnimatableProperty, unknown>> = {};\n\n for (const prop of allProps) {\n const valA = a.computedProperties[prop as AnimatableProperty];\n const valB = b.computedProperties[prop as AnimatableProperty];\n\n if (valA !== undefined && valB !== undefined) {\n blended[prop as AnimatableProperty] = interpolateValue(valA, valB, t);\n } else if (valA !== undefined) {\n blended[prop as AnimatableProperty] = valA;\n } else {\n blended[prop as AnimatableProperty] = valB;\n }\n }\n\n return {\n id: a.id,\n layer: a.layer,\n computedProperties: blended,\n };\n}\n\nfunction fadeLayer(layer: ResolvedLayer, opacity: number): ResolvedLayer {\n const cp = { ...layer.computedProperties };\n const existingOpacity = (cp.opacity as number) ?? 1;\n cp.opacity = existingOpacity * opacity;\n return {\n id: layer.id,\n layer: layer.layer,\n computedProperties: cp,\n };\n}\n","import type { AtelierDocument } from \"@a-company/atelier-types\";\n\nexport interface TemplateBindings {\n [variableName: string]: unknown;\n}\n\nexport interface TemplateError {\n variable: string;\n message: string;\n}\n\nexport type TemplateResult =\n | {\n success: true;\n document: AtelierDocument;\n }\n | {\n success: false;\n errors: TemplateError[];\n };\n\n/**\n * Instantiate a template document by substituting variable values.\n * Walks the document tree, replacing {{variableName}} patterns with bound values.\n */\nexport function instantiateTemplate(\n template: AtelierDocument,\n bindings: TemplateBindings,\n): TemplateResult {\n // 1. Validate all required variables have bindings\n const errors: TemplateError[] = [];\n const variables = template.variables ?? {};\n\n for (const [name, variable] of Object.entries(variables)) {\n if (bindings[name] === undefined && variable.default === undefined) {\n errors.push({ variable: name, message: `Required variable \"${name}\" not provided` });\n }\n }\n\n // Check for unknown bindings\n for (const name of Object.keys(bindings)) {\n if (!variables[name]) {\n errors.push({ variable: name, message: `Unknown variable \"${name}\"` });\n }\n }\n\n if (errors.length > 0) return { success: false, errors };\n\n // 2. Merge bindings with defaults\n const resolved: Record<string, unknown> = {};\n for (const [name, variable] of Object.entries(variables)) {\n resolved[name] = bindings[name] ?? variable.default;\n }\n\n // 3. Deep clone and substitute\n const doc = JSON.parse(JSON.stringify(template)) as AtelierDocument;\n substituteInObject(doc as unknown as Record<string, unknown>, resolved);\n\n // 4. Remove variables section (no longer a template)\n delete doc.variables;\n\n return { success: true, document: doc };\n}\n\n/**\n * Recursively substitute {{variableName}} patterns in string values.\n */\nfunction substituteInObject(obj: Record<string, unknown>, bindings: Record<string, unknown>): void {\n for (const key of Object.keys(obj)) {\n const value = obj[key];\n if (typeof value === \"string\") {\n obj[key] = substituteString(value, bindings);\n } else if (Array.isArray(value)) {\n substituteInArray(value, bindings);\n } else if (value !== null && typeof value === \"object\") {\n substituteInObject(value as Record<string, unknown>, bindings);\n }\n }\n}\n\nfunction substituteInArray(arr: unknown[], bindings: Record<string, unknown>): void {\n for (let i = 0; i < arr.length; i++) {\n const value = arr[i];\n if (typeof value === \"string\") {\n arr[i] = substituteString(value, bindings);\n } else if (Array.isArray(value)) {\n substituteInArray(value, bindings);\n } else if (value !== null && typeof value === \"object\") {\n substituteInObject(value as Record<string, unknown>, bindings);\n }\n }\n}\n\n/**\n * Replace {{variableName}} in a string with the bound value.\n * If the entire string is a single {{var}}, return the raw value (preserving type).\n * Otherwise, interpolate into the string.\n */\nfunction substituteString(str: string, bindings: Record<string, unknown>): unknown {\n // Exact match: entire string is {{varName}} -> return raw value\n const exactMatch = str.match(/^\\{\\{(\\w+)\\}\\}$/);\n if (exactMatch) {\n const name = exactMatch[1];\n return name in bindings ? bindings[name] : str;\n }\n\n // Partial match: replace all {{varName}} occurrences with string values\n return str.replace(/\\{\\{(\\w+)\\}\\}/g, (_, name: string) => {\n return name in bindings ? String(bindings[name]) : `{{${name}}}`;\n });\n}\n\n/**\n * List all variables used in a document (scan for {{variableName}} patterns).\n */\nexport function findTemplateVariables(doc: AtelierDocument): string[] {\n const vars = new Set<string>();\n scanForVariables(doc, vars);\n return Array.from(vars);\n}\n\nfunction scanForVariables(value: unknown, vars: Set<string>): void {\n if (typeof value === \"string\") {\n const matches = value.matchAll(/\\{\\{(\\w+)\\}\\}/g);\n for (const match of matches) {\n vars.add(match[1]);\n }\n } else if (Array.isArray(value)) {\n for (const item of value) scanForVariables(item, vars);\n } else if (value !== null && typeof value === \"object\") {\n for (const v of Object.values(value as Record<string, unknown>)) {\n scanForVariables(v, vars);\n }\n }\n}\n","import type { Audio } from \"@a-company/atelier-types\";\n\n/** Audio playback state at a given frame */\nexport interface AudioPlaybackState {\n /** Whether audio should be playing at this frame */\n shouldPlay: boolean;\n /** Current position in the audio track (seconds) */\n currentTime: number;\n /** Effective volume (0–1) */\n volume: number;\n}\n\n/**\n * Convert a frame number to time in seconds.\n */\nexport function frameToTime(frame: number, fps: number): number {\n return frame / fps;\n}\n\n/**\n * Convert time in seconds to a frame number (floored).\n */\nexport function timeToFrame(time: number, fps: number): number {\n return Math.floor(time * fps);\n}\n\n/**\n * Compute the audio playback state for a given frame.\n *\n * @param audio - Audio configuration from a state\n * @param frame - Current frame number within the state\n * @param fps - Frames per second from canvas config\n * @param stateDuration - Total state duration in frames\n * @returns AudioPlaybackState with shouldPlay, currentTime, and volume\n */\nexport function computeAudioState(\n audio: Audio,\n frame: number,\n fps: number,\n stateDuration: number,\n): AudioPlaybackState {\n const startFrame = audio.startFrame ?? 0;\n const offset = audio.offset ?? 0;\n const volume = audio.volume ?? 1;\n const loop = audio.loop ?? false;\n\n // Before audio starts\n if (frame < startFrame) {\n return { shouldPlay: false, currentTime: 0, volume };\n }\n\n // Time elapsed since audio started\n const elapsedFrames = frame - startFrame;\n const elapsedTime = frameToTime(elapsedFrames, fps);\n\n // Total available playback time (from startFrame to end of state)\n const availableFrames = stateDuration - startFrame;\n const availableTime = frameToTime(availableFrames, fps);\n\n if (!loop) {\n // Non-looping: audio plays from offset, stops at end of state\n const currentTime = offset + elapsedTime;\n return {\n shouldPlay: frame < stateDuration,\n currentTime,\n volume,\n };\n }\n\n // Looping: wrap elapsed time around available duration\n // The audio segment length is the available time\n const segmentDuration = availableTime;\n if (segmentDuration <= 0) {\n return { shouldPlay: false, currentTime: 0, volume };\n }\n\n const wrappedTime = elapsedTime % segmentDuration;\n const currentTime = offset + wrappedTime;\n\n return {\n shouldPlay: frame < stateDuration,\n currentTime,\n volume,\n };\n}\n\n/**\n * Compute audio cue points — frames where audio events occur.\n *\n * @param audio - Audio configuration\n * @param stateDuration - Total state duration in frames\n * @returns Array of { frame, event } describing audio events\n */\nexport function computeAudioCues(\n audio: Audio,\n stateDuration: number,\n): Array<{ frame: number; event: \"start\" | \"end\" | \"loop\" }> {\n const startFrame = audio.startFrame ?? 0;\n const loop = audio.loop ?? false;\n const cues: Array<{ frame: number; event: \"start\" | \"end\" | \"loop\" }> = [];\n\n if (startFrame < stateDuration) {\n cues.push({ frame: startFrame, event: \"start\" });\n }\n\n if (loop) {\n // In loop mode, audio restarts each full cycle\n const availableFrames = stateDuration - startFrame;\n if (availableFrames > 0) {\n // Loop points at each full cycle\n for (let i = 1; startFrame + i * availableFrames < stateDuration; i++) {\n cues.push({ frame: startFrame + i * availableFrames, event: \"loop\" });\n }\n }\n }\n\n // Audio ends when state ends\n if (stateDuration > startFrame) {\n cues.push({ frame: stateDuration - 1, event: \"end\" });\n }\n\n return cues;\n}\n","import type { Fill, Stroke, Color, RGBAColor, HSLAColor } from \"@a-company/atelier-types\";\nimport type { RenderContext } from \"./canvas-types.js\";\n\n/**\n * Convert an Atelier Color to a CSS color string.\n */\nexport function colorToCSS(color: Color): string {\n if (typeof color === \"string\") return color; // hex string\n\n if (\"r\" in color) {\n const c = color as RGBAColor;\n return `rgba(${Math.round(c.r)}, ${Math.round(c.g)}, ${Math.round(c.b)}, ${c.a})`;\n }\n\n if (\"h\" in color) {\n const c = color as HSLAColor;\n return `hsla(${c.h}, ${c.s}%, ${c.l}%, ${c.a})`;\n }\n\n return \"#000000\";\n}\n\n/**\n * Apply a Fill to the canvas context's fillStyle.\n */\nexport function applyFill(ctx: RenderContext, fill: Fill, width: number, height: number): void {\n switch (fill.type) {\n case \"solid\":\n ctx.fillStyle = colorToCSS(fill.color);\n break;\n\n case \"linear-gradient\": {\n const rad = (fill.angle * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const halfW = width / 2;\n const halfH = height / 2;\n const grad = ctx.createLinearGradient(\n halfW - cos * halfW, halfH - sin * halfH,\n halfW + cos * halfW, halfH + sin * halfH,\n );\n for (const stop of fill.stops) {\n grad.addColorStop(stop.offset, colorToCSS(stop.color));\n }\n ctx.fillStyle = grad as unknown as string;\n break;\n }\n\n case \"radial-gradient\": {\n const cx = typeof fill.center.x === \"number\" ? fill.center.x : (parseFloat(fill.center.x) / 100) * width;\n const cy = typeof fill.center.y === \"number\" ? fill.center.y : (parseFloat(fill.center.y) / 100) * height;\n const r = typeof fill.radius === \"number\" ? fill.radius : (parseFloat(fill.radius) / 100) * Math.max(width, height);\n const grad = ctx.createRadialGradient(cx, cy, 0, cx, cy, r);\n for (const stop of fill.stops) {\n grad.addColorStop(stop.offset, colorToCSS(stop.color));\n }\n ctx.fillStyle = grad as unknown as string;\n break;\n }\n }\n}\n\n/**\n * Apply a Stroke to the canvas context.\n * @param pathLength - total perimeter of the shape (needed for strokeStart/strokeEnd trim)\n */\nexport function applyStroke(ctx: RenderContext, stroke: Stroke, pathLength: number): void {\n ctx.strokeStyle = colorToCSS(stroke.color);\n ctx.lineWidth = stroke.width;\n if (stroke.lineCap) ctx.lineCap = stroke.lineCap;\n if (stroke.lineJoin) ctx.lineJoin = stroke.lineJoin;\n\n const start = stroke.strokeStart ?? 0;\n const end = stroke.strokeEnd ?? 1;\n\n if (start !== 0 || end !== 1) {\n const visible = (end - start) * pathLength;\n ctx.setLineDash([Math.max(visible, 0), pathLength + 1]);\n ctx.lineDashOffset = -start * pathLength;\n } else if (stroke.dash) {\n ctx.setLineDash(stroke.dash);\n }\n}\n","import type { Layer, Visual, ShapeVisual, TextVisual, ImageVisual, Color, BlendMode, LinearGradientFill, RadialGradientFill } from \"@a-company/atelier-types\";\nimport { colorToCSS } from \"./styles.js\";\nimport { evaluatePathAtProgress } from \"@a-company/atelier-math\";\nimport type { ResolvedLayer } from \"@a-company/atelier-core\";\n\n/**\n * Effective values for a layer at a given frame,\n * with computed properties merged over defaults.\n */\nexport interface EffectiveLayer {\n /** Original layer */\n layer: Layer;\n /** Visual with animated property overrides applied */\n visual: Visual;\n /** Effective frame position (may be animated) */\n x: number;\n y: number;\n /** Effective bounds */\n width: number;\n height: number;\n /** Effective transform values */\n opacity: number;\n rotation: number;\n scaleX: number;\n scaleY: number;\n anchorX: number;\n anchorY: number;\n /** Resolved shadow (if layer has shadow or shadow is animated) */\n shadow?: {\n color: string;\n blur: number;\n offsetX: number;\n offsetY: number;\n };\n /** Blend mode for compositing */\n blendMode: string;\n /** Motion path auto-rotation in degrees (applied additively to rotation) */\n motionPathAngle: number;\n /** Whether this layer is visible (may be animated) */\n visible: boolean;\n /** Color tint overlay */\n tint?: {\n color: string;\n amount: number;\n };\n}\n\n/**\n * Resolve a UnitValue to pixels. Percentages resolve against a reference dimension.\n */\nfunction resolveUnit(value: number | string, reference: number): number {\n if (typeof value === \"string\" && value.endsWith(\"%\")) {\n return (parseFloat(value) / 100) * reference;\n }\n return value as number;\n}\n\n/**\n * Build the effective layer values by merging computed properties over layer defaults.\n * @param resolved - The resolved layer from frame resolution\n * @param parentWidth - Parent/canvas width for percentage resolution\n * @param parentHeight - Parent/canvas height for percentage resolution\n */\nexport function buildEffectiveLayer(\n resolved: ResolvedLayer,\n parentWidth: number,\n parentHeight: number,\n): EffectiveLayer {\n const { layer, computedProperties } = resolved;\n const cp = computedProperties as Record<string, unknown>;\n\n const hasShadow = layer.shadow || cp[\"shadow.blur\"] !== undefined || cp[\"shadow.color\"] !== undefined;\n const hasTint = layer.tint || cp[\"tint.amount\"] !== undefined || cp[\"tint.color\"] !== undefined;\n\n // Resolve base position\n let x = resolveUnit((cp[\"frame.x\"] ?? layer.frame.x) as number | string, parentWidth);\n let y = resolveUnit((cp[\"frame.y\"] ?? layer.frame.y) as number | string, parentHeight);\n let motionPathAngle = 0;\n\n // Motion path overrides position when progress is animated\n const motionProgress = cp[\"motionPath.progress\"] as number | undefined;\n if (motionProgress !== undefined && layer.motionPath && layer.motionPath.points.length >= 2) {\n const pos = evaluatePathAtProgress(layer.motionPath.points, motionProgress, layer.motionPath.closed);\n x = pos.x;\n y = pos.y;\n if (layer.motionPath.autoRotate) {\n motionPathAngle = pos.angle + (layer.motionPath.autoRotateOffset ?? 0);\n }\n }\n\n return {\n layer,\n visual: buildEffectiveVisual(layer.visual, cp),\n x,\n y,\n width: resolveUnit((cp[\"bounds.width\"] ?? layer.bounds.width) as number | string, parentWidth),\n height: resolveUnit((cp[\"bounds.height\"] ?? layer.bounds.height) as number | string, parentHeight),\n opacity: (cp[\"opacity\"] as number) ?? layer.opacity ?? 1,\n rotation: (cp[\"rotation\"] as number) ?? layer.rotation ?? 0,\n scaleX: (cp[\"scale.x\"] as number) ?? layer.scale?.x ?? 1,\n scaleY: (cp[\"scale.y\"] as number) ?? layer.scale?.y ?? 1,\n anchorX: (cp[\"anchorPoint.x\"] as number) ?? layer.anchorPoint?.x ?? 0,\n anchorY: (cp[\"anchorPoint.y\"] as number) ?? layer.anchorPoint?.y ?? 0,\n shadow: hasShadow ? {\n color: colorToCSS((cp[\"shadow.color\"] ?? layer.shadow?.color ?? \"#00000080\") as Color),\n blur: (cp[\"shadow.blur\"] as number) ?? layer.shadow?.blur ?? 0,\n offsetX: (cp[\"shadow.offsetX\"] as number) ?? layer.shadow?.offsetX ?? 0,\n offsetY: (cp[\"shadow.offsetY\"] as number) ?? layer.shadow?.offsetY ?? 0,\n } : undefined,\n blendMode: (layer.blendMode as BlendMode) ?? \"normal\",\n motionPathAngle,\n visible: (cp[\"visible\"] as boolean) ?? layer.visible ?? true,\n tint: hasTint ? {\n color: colorToCSS((cp[\"tint.color\"] ?? layer.tint?.color ?? \"#FF0000\") as Color),\n amount: (cp[\"tint.amount\"] as number) ?? layer.tint?.amount ?? 0,\n } : undefined,\n };\n}\n\n/**\n * Build an effective visual by applying computed property overrides.\n * Returns the original visual if no visual properties are animated.\n */\nfunction buildEffectiveVisual(visual: Visual, cp: Record<string, unknown>): Visual {\n const hasVisualOverride =\n cp[\"visual.fill.color\"] !== undefined ||\n cp[\"visual.fill.angle\"] !== undefined ||\n cp[\"visual.fill.center.x\"] !== undefined ||\n cp[\"visual.fill.center.y\"] !== undefined ||\n cp[\"visual.fill.radius\"] !== undefined ||\n cp[\"visual.stroke.color\"] !== undefined ||\n cp[\"visual.stroke.width\"] !== undefined ||\n cp[\"visual.stroke.start\"] !== undefined ||\n cp[\"visual.stroke.end\"] !== undefined ||\n cp[\"visual.shape.cornerRadius\"] !== undefined ||\n cp[\"visual.style.fontSize\"] !== undefined ||\n cp[\"visual.style.color\"] !== undefined;\n\n const hasImageOverride =\n cp[\"visual.image.sourceRect.x\"] !== undefined ||\n cp[\"visual.image.sourceRect.y\"] !== undefined ||\n cp[\"visual.image.sourceRect.width\"] !== undefined ||\n cp[\"visual.image.sourceRect.height\"] !== undefined ||\n cp[\"visual.image.frameIndex\"] !== undefined;\n\n if (!hasVisualOverride && !hasImageOverride) return visual;\n\n if (visual.type === \"shape\") {\n const v: ShapeVisual = { ...visual };\n\n if (cp[\"visual.shape.cornerRadius\"] !== undefined && v.shape.type === \"rect\") {\n v.shape = { ...v.shape, cornerRadius: cp[\"visual.shape.cornerRadius\"] as number };\n }\n\n if (v.fill) {\n if (cp[\"visual.fill.color\"] !== undefined && v.fill.type === \"solid\") {\n v.fill = { ...v.fill, color: cp[\"visual.fill.color\"] as string };\n }\n if (cp[\"visual.fill.angle\"] !== undefined && v.fill.type === \"linear-gradient\") {\n v.fill = { ...v.fill, angle: cp[\"visual.fill.angle\"] as number } as LinearGradientFill;\n }\n if (v.fill.type === \"radial-gradient\") {\n const cx = cp[\"visual.fill.center.x\"];\n const cy = cp[\"visual.fill.center.y\"];\n const r = cp[\"visual.fill.radius\"];\n if (cx !== undefined || cy !== undefined || r !== undefined) {\n const f = v.fill as RadialGradientFill;\n v.fill = {\n ...f,\n center: {\n x: cx !== undefined ? (cx as number) : f.center.x,\n y: cy !== undefined ? (cy as number) : f.center.y,\n },\n radius: r !== undefined ? (r as number) : f.radius,\n } as RadialGradientFill;\n }\n }\n }\n\n if (v.stroke) {\n const strokeColor = cp[\"visual.stroke.color\"] ?? v.stroke.color;\n const strokeWidth = (cp[\"visual.stroke.width\"] as number) ?? v.stroke.width;\n const strokeStart = (cp[\"visual.stroke.start\"] as number | undefined) ?? v.stroke.strokeStart;\n const strokeEnd = (cp[\"visual.stroke.end\"] as number | undefined) ?? v.stroke.strokeEnd;\n if (\n strokeColor !== v.stroke.color ||\n strokeWidth !== v.stroke.width ||\n strokeStart !== v.stroke.strokeStart ||\n strokeEnd !== v.stroke.strokeEnd\n ) {\n v.stroke = {\n ...v.stroke,\n color: strokeColor as string,\n width: strokeWidth,\n strokeStart,\n strokeEnd,\n };\n }\n }\n\n return v;\n }\n\n if (visual.type === \"text\") {\n const v: TextVisual = { ...visual };\n const fontSize = (cp[\"visual.style.fontSize\"] as number) ?? v.style.fontSize;\n const color = cp[\"visual.style.color\"] ?? v.style.color;\n if (fontSize !== v.style.fontSize || color !== v.style.color) {\n v.style = { ...v.style, fontSize, color: color as string };\n }\n return v;\n }\n\n if (visual.type === \"image\" && hasImageOverride) {\n const v: ImageVisual = { ...visual };\n\n // Merge animated sourceRect fields\n if (\n cp[\"visual.image.sourceRect.x\"] !== undefined ||\n cp[\"visual.image.sourceRect.y\"] !== undefined ||\n cp[\"visual.image.sourceRect.width\"] !== undefined ||\n cp[\"visual.image.sourceRect.height\"] !== undefined\n ) {\n const base = v.sourceRect ?? { x: 0, y: 0, width: 0, height: 0 };\n v.sourceRect = {\n x: (cp[\"visual.image.sourceRect.x\"] as number) ?? base.x,\n y: (cp[\"visual.image.sourceRect.y\"] as number) ?? base.y,\n width: (cp[\"visual.image.sourceRect.width\"] as number) ?? base.width,\n height: (cp[\"visual.image.sourceRect.height\"] as number) ?? base.height,\n };\n }\n\n // Merge animated frameIndex\n if (cp[\"visual.image.frameIndex\"] !== undefined) {\n v.frameIndex = Math.floor(cp[\"visual.image.frameIndex\"] as number);\n }\n\n return v;\n }\n\n return visual;\n}\n","import type { ShapeVisual } from \"@a-company/atelier-types\";\nimport type { RenderContext } from \"../canvas-types.js\";\nimport type { EffectiveLayer } from \"../apply-properties.js\";\nimport { applyFill, applyStroke } from \"../styles.js\";\n\nexport function renderShape(ctx: RenderContext, eff: EffectiveLayer): void {\n const visual = eff.visual as ShapeVisual;\n const { shape } = visual;\n const { width, height } = eff;\n\n switch (shape.type) {\n case \"rect\":\n renderRect(ctx, width, height, shape.cornerRadius, visual);\n break;\n case \"ellipse\":\n renderEllipse(ctx, width, height, visual);\n break;\n case \"path\":\n renderPath(ctx, shape.points, shape.closed, visual);\n break;\n }\n}\n\n// ── Perimeter helpers ───────────────────────────────────────\n\nfunction rectPerimeter(w: number, h: number): number {\n return 2 * (w + h);\n}\n\nfunction ellipsePerimeter(w: number, h: number): number {\n const a = w / 2;\n const b = h / 2;\n // Ramanujan approximation\n return Math.PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (a + 3 * b)));\n}\n\nfunction dist(x1: number, y1: number, x2: number, y2: number): number {\n const dx = x2 - x1;\n const dy = y2 - y1;\n return Math.sqrt(dx * dx + dy * dy);\n}\n\nfunction pathPerimeter(\n points: { x: number; y: number; in?: { x: number; y: number }; out?: { x: number; y: number } }[],\n closed: boolean | undefined,\n): number {\n let length = 0;\n for (let i = 1; i < points.length; i++) {\n const prev = points[i - 1];\n const curr = points[i];\n if (prev.out && curr.in) {\n // Approximate bezier with chord * 1.2\n length += dist(prev.x, prev.y, curr.x, curr.y) * 1.2;\n } else {\n length += dist(prev.x, prev.y, curr.x, curr.y);\n }\n }\n if (closed && points.length > 1) {\n const first = points[0];\n const last = points[points.length - 1];\n length += dist(last.x, last.y, first.x, first.y);\n }\n return length;\n}\n\n// ── Renderers ───────────────────────────────────────────────\n\nfunction renderRect(\n ctx: RenderContext,\n width: number,\n height: number,\n cornerRadius: number | [number, number, number, number] | undefined,\n visual: ShapeVisual,\n): void {\n if (visual.fill) {\n applyFill(ctx, visual.fill, width, height);\n if (cornerRadius && ctx.roundRect) {\n ctx.beginPath();\n ctx.roundRect(0, 0, width, height, cornerRadius);\n ctx.fill();\n } else {\n ctx.fillRect(0, 0, width, height);\n }\n }\n if (visual.stroke) {\n const perimeter = rectPerimeter(width, height);\n applyStroke(ctx, visual.stroke, perimeter);\n if (cornerRadius && ctx.roundRect) {\n ctx.beginPath();\n ctx.roundRect(0, 0, width, height, cornerRadius);\n ctx.stroke();\n } else {\n ctx.strokeRect(0, 0, width, height);\n }\n }\n}\n\nfunction renderEllipse(\n ctx: RenderContext,\n width: number,\n height: number,\n visual: ShapeVisual,\n): void {\n ctx.beginPath();\n ctx.ellipse(width / 2, height / 2, width / 2, height / 2, 0, 0, Math.PI * 2);\n\n if (visual.fill) {\n applyFill(ctx, visual.fill, width, height);\n ctx.fill();\n }\n if (visual.stroke) {\n const perimeter = ellipsePerimeter(width, height);\n applyStroke(ctx, visual.stroke, perimeter);\n ctx.stroke();\n }\n}\n\nfunction renderPath(\n ctx: RenderContext,\n points: { x: number; y: number; in?: { x: number; y: number }; out?: { x: number; y: number } }[],\n closed: boolean | undefined,\n visual: ShapeVisual,\n): void {\n if (points.length < 2) return;\n\n ctx.beginPath();\n ctx.moveTo(points[0].x, points[0].y);\n\n for (let i = 1; i < points.length; i++) {\n const prev = points[i - 1];\n const curr = points[i];\n\n if (prev.out && curr.in) {\n ctx.bezierCurveTo(\n prev.x + prev.out.x, prev.y + prev.out.y,\n curr.x + curr.in.x, curr.y + curr.in.y,\n curr.x, curr.y,\n );\n } else {\n ctx.lineTo(curr.x, curr.y);\n }\n }\n\n if (closed) ctx.closePath();\n\n if (visual.fill) {\n applyFill(ctx, visual.fill, 0, 0);\n ctx.fill();\n }\n if (visual.stroke) {\n const perimeter = pathPerimeter(points, closed);\n applyStroke(ctx, visual.stroke, perimeter);\n ctx.stroke();\n }\n}\n","import type { TextVisual } from \"@a-company/atelier-types\";\nimport type { RenderContext } from \"../canvas-types.js\";\nimport type { EffectiveLayer } from \"../apply-properties.js\";\nimport { colorToCSS } from \"../styles.js\";\n\nexport function renderText(ctx: RenderContext, eff: EffectiveLayer): void {\n const visual = eff.visual as TextVisual;\n const { style } = visual;\n\n // Build font string\n const fontStyle = style.fontStyle ?? \"normal\";\n const fontWeight = style.fontWeight ?? \"normal\";\n const fontSize = style.fontSize;\n const fontFamily = style.fontFamily;\n ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;\n\n // Set alignment — position text within its bounding box\n const align = style.textAlign ?? \"left\";\n ctx.textAlign = align;\n ctx.textBaseline = \"top\";\n\n // Set color\n ctx.fillStyle = colorToCSS(style.color);\n\n // Canvas 2D textAlign anchors at the draw point, so offset within bounds:\n // \"left\" → draw at x=0 (text flows right from left edge)\n // \"center\" → draw at x=width/2 (text centers within bounds)\n // \"right\" → draw at x=width (text flows left from right edge)\n let textX = 0;\n if (align === \"center\") {\n textX = eff.width / 2;\n } else if (align === \"right\") {\n textX = eff.width;\n }\n\n ctx.fillText(visual.content, textX, 0);\n}\n","import type { ImageVisual } from \"@a-company/atelier-types\";\nimport type { RenderContext } from \"../canvas-types.js\";\nimport type { EffectiveLayer } from \"../apply-properties.js\";\nimport type { ImageCache } from \"../image-cache.js\";\n\n/**\n * Render an image layer to the canvas.\n * Supports sourceRect cropping and spritesheet grid animation.\n * If the image hasn't loaded yet, triggers a cache load and returns\n * (the image will appear on the next re-render).\n */\nexport function renderImage(ctx: RenderContext, eff: EffectiveLayer, imageCache: ImageCache): void {\n const visual = eff.visual as ImageVisual;\n const src = visual.src;\n if (!src) return;\n\n const img = imageCache.get(src);\n if (!img) {\n imageCache.load(src);\n return;\n }\n\n // Spritesheet grid computation takes precedence over manual sourceRect\n if (visual.spritesheet) {\n const { columns, rows, frameWidth, frameHeight, frameCount } = visual.spritesheet;\n const maxFrames = frameCount ?? (columns * rows);\n const idx = Math.max(0, Math.min(Math.floor(visual.frameIndex ?? 0), maxFrames - 1));\n const col = idx % columns;\n const row = Math.floor(idx / columns);\n const sx = col * frameWidth;\n const sy = row * frameHeight;\n (ctx.drawImage as Function)(img, sx, sy, frameWidth, frameHeight, 0, 0, eff.width, eff.height);\n return;\n }\n\n // Manual sourceRect crop\n if (visual.sourceRect) {\n const sr = visual.sourceRect;\n (ctx.drawImage as Function)(img, sr.x, sr.y, sr.width, sr.height, 0, 0, eff.width, eff.height);\n return;\n }\n\n // Default: draw full image to bounds\n ctx.drawImage(img, 0, 0, eff.width, eff.height);\n}\n","import type { AtelierDocument, RefVisual, ImageVisual } from \"@a-company/atelier-types\";\nimport { resolveFrame } from \"@a-company/atelier-core\";\nimport type { RenderContext, DocumentResolver } from \"../canvas-types.js\";\nimport type { EffectiveLayer } from \"../apply-properties.js\";\nimport { buildEffectiveLayer } from \"../apply-properties.js\";\nimport { renderShape } from \"./shape-renderer.js\";\nimport { renderText } from \"./text-renderer.js\";\nimport { renderImage } from \"./image-renderer.js\";\nimport type { ImageCache } from \"../image-cache.js\";\n\nexport interface RefRenderOpts {\n documentResolver?: DocumentResolver;\n maxRefDepth?: number;\n imageCache?: ImageCache;\n /** Internal: tracks visited refs for cycle detection */\n _visitedRefs?: Set<string>;\n /** Internal: current recursion depth */\n _depth?: number;\n}\n\n/**\n * Render a ref layer. If a documentResolver is provided, resolves and renders\n * the sub-document inline. Otherwise falls back to a placeholder rectangle.\n */\nexport function renderRef(\n ctx: RenderContext,\n eff: EffectiveLayer,\n opts?: RefRenderOpts,\n _parentDoc?: AtelierDocument,\n): void {\n const visual = eff.visual as RefVisual;\n const resolver = opts?.documentResolver;\n\n if (!resolver) {\n renderPlaceholder(ctx, eff, `REF: ${visual.src}`);\n return;\n }\n\n const depth = opts?._depth ?? 0;\n const maxDepth = opts?.maxRefDepth ?? 4;\n\n if (depth >= maxDepth) {\n renderPlaceholder(ctx, eff, \"MAX DEPTH\");\n return;\n }\n\n const visitedRefs = opts?._visitedRefs ?? new Set<string>();\n\n if (visitedRefs.has(visual.src)) {\n renderPlaceholder(ctx, eff, \"CYCLE\");\n return;\n }\n\n const subDoc = resolver(visual.src);\n if (!subDoc) {\n renderPlaceholder(ctx, eff, \"NOT FOUND\");\n return;\n }\n\n // Determine which state and frame to render\n const stateNames = Object.keys(subDoc.states);\n if (stateNames.length === 0) {\n renderPlaceholder(ctx, eff, \"NO STATES\");\n return;\n }\n\n const stateName = visual.state ?? stateNames[0];\n const stateObj = subDoc.states[stateName];\n if (!stateObj) {\n renderPlaceholder(ctx, eff, `STATE? ${stateName}`);\n return;\n }\n\n const maxFrame = Math.max(0, stateObj.duration - 1);\n const frame = Math.min(visual.frame ?? 0, maxFrame);\n\n // Resolve the sub-document frame\n const resolved = resolveFrame(subDoc, stateName, frame);\n\n // Mark as visited for cycle detection\n visitedRefs.add(visual.src);\n\n // Scale to fit eff bounds\n const scaleX = eff.width / subDoc.canvas.width;\n const scaleY = eff.height / subDoc.canvas.height;\n\n ctx.save();\n ctx.scale(scaleX, scaleY);\n\n // Build and render sub-doc layers\n const { width: subW, height: subH } = subDoc.canvas;\n\n for (const resolvedLayer of resolved.layers) {\n const subEff = buildEffectiveLayer(resolvedLayer, subW, subH);\n\n if (!subEff.visible) continue;\n if (subEff.opacity <= 0) continue;\n\n // Resolve asset for images\n if (resolvedLayer.layer.visual.type === \"image\") {\n const iv = subEff.visual as ImageVisual;\n if (!iv.src && iv.assetId && subDoc.assets?.[iv.assetId]) {\n iv.src = subDoc.assets[iv.assetId].src;\n }\n }\n\n ctx.save();\n ctx.globalAlpha = subEff.opacity;\n ctx.translate(subEff.x, subEff.y);\n\n switch (resolvedLayer.layer.visual.type) {\n case \"shape\":\n renderShape(ctx, subEff);\n break;\n case \"text\":\n renderText(ctx, subEff);\n break;\n case \"image\":\n if (opts?.imageCache) renderImage(ctx, subEff, opts.imageCache);\n break;\n case \"ref\":\n renderRef(ctx, subEff, {\n ...opts,\n _visitedRefs: visitedRefs,\n _depth: depth + 1,\n }, subDoc);\n break;\n case \"group\":\n break;\n }\n\n ctx.restore();\n }\n\n ctx.restore();\n\n // Remove from visited after rendering (allow same ref in different branches)\n visitedRefs.delete(visual.src);\n}\n\n/** Render a dashed placeholder rectangle with label */\nfunction renderPlaceholder(ctx: RenderContext, eff: EffectiveLayer, label: string): void {\n const { width, height } = eff;\n\n ctx.strokeStyle = \"#888888\";\n ctx.lineWidth = 2;\n ctx.setLineDash([6, 4]);\n ctx.strokeRect(0, 0, width, height);\n ctx.setLineDash([]);\n\n ctx.fillStyle = \"#888888\";\n ctx.font = `${Math.max(12, Math.min(16, height * 0.15))}px sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(label, width / 2, height / 2, width - 8);\n}\n","import type { AtelierDocument, ImageVisual, Shape } from \"@a-company/atelier-types\";\nimport type { ResolvedFrame } from \"@a-company/atelier-core\";\nimport type { RenderContext, DocumentResolver } from \"./canvas-types.js\";\nimport { buildEffectiveLayer, type EffectiveLayer } from \"./apply-properties.js\";\nimport { renderShape } from \"./renderers/shape-renderer.js\";\nimport { renderText } from \"./renderers/text-renderer.js\";\nimport { renderImage } from \"./renderers/image-renderer.js\";\nimport { renderRef } from \"./renderers/ref-renderer.js\";\nimport type { ImageCache } from \"./image-cache.js\";\n\n/** Options for renderFrame */\nexport interface RenderOptions {\n imageCache?: ImageCache;\n documentResolver?: DocumentResolver;\n maxRefDepth?: number;\n}\n\n/**\n * Render a resolved frame to a Canvas 2D context.\n * Clears the canvas and draws all visible layers in order.\n */\nexport function renderFrame(\n ctx: RenderContext,\n resolvedFrame: ResolvedFrame,\n doc: AtelierDocument,\n optsOrCache?: RenderOptions | ImageCache,\n): void {\n // Backward compatible: detect old ImageCache arg vs new RenderOptions\n let imageCache: ImageCache | undefined;\n let documentResolver: DocumentResolver | undefined;\n let maxRefDepth = 4;\n\n if (optsOrCache && typeof (optsOrCache as ImageCache).get === \"function\") {\n imageCache = optsOrCache as ImageCache;\n } else if (optsOrCache) {\n const opts = optsOrCache as RenderOptions;\n imageCache = opts.imageCache;\n documentResolver = opts.documentResolver;\n maxRefDepth = opts.maxRefDepth ?? 4;\n }\n const { width, height } = doc.canvas;\n\n // Clear canvas\n ctx.fillStyle = doc.canvas.background ?? \"transparent\";\n ctx.fillRect(0, 0, width, height);\n\n // Build effective layers into a map for ancestor transform lookups\n const effMap = new Map<string, EffectiveLayer>();\n const effList: EffectiveLayer[] = [];\n\n for (const resolvedLayer of resolvedFrame.layers) {\n const eff = buildEffectiveLayer(resolvedLayer, width, height);\n effMap.set(resolvedLayer.layer.id, eff);\n effList.push(eff);\n }\n\n // Render each layer in order (painters algorithm — first = back)\n for (const eff of effList) {\n const { layer } = eff;\n\n // Skip invisible layers\n if (!eff.visible) continue;\n\n // Skip fully transparent layers\n if (eff.opacity <= 0) continue;\n\n // Resolve assetId → src for image visuals\n if (layer.visual.type === \"image\") {\n const iv = eff.visual as ImageVisual;\n if (!iv.src && iv.assetId && doc.assets?.[iv.assetId]) {\n iv.src = doc.assets[iv.assetId].src;\n }\n }\n\n ctx.save();\n\n // Apply ancestor transforms (group/parent inheritance)\n applyAncestorTransforms(ctx, layer.id, effMap, doc);\n\n // Apply transforms\n ctx.globalAlpha = eff.opacity;\n\n // Apply blend mode\n if (eff.blendMode !== \"normal\") {\n ctx.globalCompositeOperation = blendModeToComposite(eff.blendMode);\n }\n\n ctx.translate(eff.x, eff.y);\n\n // Apply anchor-relative transforms\n const anchorPixelX = eff.anchorX * eff.width;\n const anchorPixelY = eff.anchorY * eff.height;\n\n // Combine explicit rotation with motion path auto-rotation\n const totalRotation = eff.rotation + eff.motionPathAngle;\n\n if (totalRotation !== 0 || eff.scaleX !== 1 || eff.scaleY !== 1) {\n ctx.translate(anchorPixelX, anchorPixelY);\n if (totalRotation !== 0) {\n ctx.rotate((totalRotation * Math.PI) / 180);\n }\n if (eff.scaleX !== 1 || eff.scaleY !== 1) {\n ctx.scale(eff.scaleX, eff.scaleY);\n }\n ctx.translate(-anchorPixelX, -anchorPixelY);\n }\n\n // Apply shadow if present\n if (eff.shadow) {\n ctx.shadowColor = eff.shadow.color;\n ctx.shadowBlur = eff.shadow.blur;\n ctx.shadowOffsetX = eff.shadow.offsetX;\n ctx.shadowOffsetY = eff.shadow.offsetY;\n }\n\n // Apply clip path if present\n if (layer.clipPath) {\n applyClipPath(ctx, layer.clipPath, eff.width, eff.height);\n }\n\n // Tint requires offscreen compositing — draw to offscreen if tint is active\n const hasTint = eff.tint && eff.tint.amount > 0 && ctx.createOffscreen;\n let renderCtx = ctx;\n let offscreen: { ctx: RenderContext; canvas: unknown } | null = null;\n\n if (hasTint) {\n offscreen = ctx.createOffscreen!(eff.width, eff.height);\n renderCtx = offscreen.ctx;\n }\n\n // Ref rendering options (passed through for sub-doc composition)\n const refOpts = { documentResolver, maxRefDepth, imageCache };\n\n // Dispatch to type-specific renderer\n switch (layer.visual.type) {\n case \"shape\":\n renderShape(renderCtx, eff);\n break;\n case \"text\":\n renderText(renderCtx, eff);\n break;\n case \"image\":\n if (imageCache) renderImage(renderCtx, eff, imageCache);\n break;\n case \"group\":\n // Groups are structural containers — no visual output\n break;\n case \"ref\":\n renderRef(renderCtx, eff, refOpts, doc);\n break;\n }\n\n // Apply tint via multiply composite on offscreen canvas\n if (hasTint && offscreen && eff.tint) {\n const offCtx = offscreen.ctx;\n // Draw tint color over the content using multiply\n offCtx.save();\n offCtx.globalCompositeOperation = \"multiply\";\n offCtx.fillStyle = eff.tint.color;\n offCtx.fillRect(0, 0, eff.width, eff.height);\n offCtx.restore();\n\n // Clip to original content shape using destination-in\n offCtx.save();\n offCtx.globalCompositeOperation = \"destination-in\";\n // Re-render the content to create the alpha mask\n switch (layer.visual.type) {\n case \"shape\": renderShape(offCtx, eff); break;\n case \"text\": renderText(offCtx, eff); break;\n case \"image\": if (imageCache) renderImage(offCtx, eff, imageCache); break;\n case \"ref\": renderRef(offCtx, eff, refOpts, doc); break;\n }\n offCtx.restore();\n\n // Blend tinted offscreen back with original at tint.amount alpha\n // First draw original content\n switch (layer.visual.type) {\n case \"shape\": renderShape(ctx, eff); break;\n case \"text\": renderText(ctx, eff); break;\n case \"image\": if (imageCache) renderImage(ctx, eff, imageCache); break;\n case \"ref\": renderRef(ctx, eff, refOpts, doc); break;\n }\n // Then overlay tinted version at tint amount\n const prevAlpha = ctx.globalAlpha;\n ctx.globalAlpha = eff.tint.amount;\n ctx.drawImage(offscreen.canvas, 0, 0, eff.width, eff.height);\n ctx.globalAlpha = prevAlpha;\n }\n\n ctx.restore();\n }\n}\n\n/** Apply a shape as a clipping region */\nfunction applyClipPath(ctx: RenderContext, shape: Shape, width: number, height: number): void {\n ctx.beginPath();\n switch (shape.type) {\n case \"rect\":\n if (shape.cornerRadius && ctx.roundRect) {\n ctx.roundRect(0, 0, width, height, shape.cornerRadius);\n } else {\n // Manual rect path for clipping (fillRect doesn't create a path)\n ctx.moveTo(0, 0);\n ctx.lineTo(width, 0);\n ctx.lineTo(width, height);\n ctx.lineTo(0, height);\n ctx.closePath();\n }\n break;\n case \"ellipse\":\n ctx.ellipse(width / 2, height / 2, width / 2, height / 2, 0, 0, Math.PI * 2);\n break;\n case \"path\":\n if (shape.points.length >= 2) {\n ctx.moveTo(shape.points[0].x, shape.points[0].y);\n for (let i = 1; i < shape.points.length; i++) {\n const prev = shape.points[i - 1];\n const curr = shape.points[i];\n if (prev.out && curr.in) {\n ctx.bezierCurveTo(\n prev.x + prev.out.x, prev.y + prev.out.y,\n curr.x + curr.in.x, curr.y + curr.in.y,\n curr.x, curr.y,\n );\n } else {\n ctx.lineTo(curr.x, curr.y);\n }\n }\n if (shape.closed) ctx.closePath();\n }\n break;\n }\n ctx.clip();\n}\n\n/** Map Atelier blend mode names to Canvas 2D globalCompositeOperation values */\nfunction blendModeToComposite(mode: string): string {\n const map: Record<string, string> = {\n \"multiply\": \"multiply\",\n \"screen\": \"screen\",\n \"overlay\": \"overlay\",\n \"darken\": \"darken\",\n \"lighten\": \"lighten\",\n \"color-dodge\": \"color-dodge\",\n \"color-burn\": \"color-burn\",\n \"hard-light\": \"hard-light\",\n \"soft-light\": \"soft-light\",\n \"difference\": \"difference\",\n \"exclusion\": \"exclusion\",\n \"hue\": \"hue\",\n \"saturation\": \"saturation\",\n \"color\": \"color\",\n \"luminosity\": \"luminosity\",\n };\n return map[mode] ?? \"source-over\";\n}\n\n/**\n * Walk the parentId chain and apply each ancestor's transforms.\n * This makes child layers inherit parent position/rotation/scale.\n */\nfunction applyAncestorTransforms(\n ctx: RenderContext,\n layerId: string,\n effMap: Map<string, EffectiveLayer>,\n doc: AtelierDocument,\n): void {\n // Collect ancestor chain (excluding self)\n const chain: EffectiveLayer[] = [];\n const layer = doc.layers.find((l) => l.id === layerId);\n let parentId = layer?.parentId;\n const visited = new Set<string>();\n\n while (parentId && !visited.has(parentId)) {\n visited.add(parentId);\n const parentEff = effMap.get(parentId);\n if (!parentEff) break;\n chain.push(parentEff);\n parentId = parentEff.layer.parentId;\n }\n\n // Apply from root ancestor down to direct parent\n for (let i = chain.length - 1; i >= 0; i--) {\n const p = chain[i];\n ctx.translate(p.x, p.y);\n\n const ax = p.anchorX * p.width;\n const ay = p.anchorY * p.height;\n\n if (p.rotation !== 0 || p.scaleX !== 1 || p.scaleY !== 1) {\n ctx.translate(ax, ay);\n if (p.rotation !== 0) ctx.rotate((p.rotation * Math.PI) / 180);\n if (p.scaleX !== 1 || p.scaleY !== 1) ctx.scale(p.scaleX, p.scaleY);\n ctx.translate(-ax, -ay);\n }\n }\n}\n","/**\n * A loaded image entry that can be drawn via RenderContext.drawImage.\n */\nexport interface CachedImage {\n complete: boolean;\n image: unknown;\n}\n\n/**\n * Simple image cache for loading and caching images.\n * Browser-agnostic — the actual Image constructor is injected via createImage.\n * Triggers an onLoad callback when an image finishes loading so the\n * renderer can re-render the current frame.\n */\nexport class ImageCache {\n private cache = new Map<string, CachedImage>();\n private loading = new Set<string>();\n private onLoad?: () => void;\n private createImage?: (src: string, onLoad: () => void, onError: () => void) => unknown;\n\n constructor(opts?: {\n onLoad?: () => void;\n createImage?: (src: string, onLoad: () => void, onError: () => void) => unknown;\n }) {\n this.onLoad = opts?.onLoad;\n this.createImage = opts?.createImage;\n }\n\n get(src: string): unknown | null {\n const entry = this.cache.get(src);\n return entry?.complete ? entry.image : null;\n }\n\n load(src: string): void {\n if (this.cache.has(src) || this.loading.has(src)) return;\n if (!this.createImage) return;\n this.loading.add(src);\n const image = this.createImage(\n src,\n () => {\n this.cache.set(src, { complete: true, image });\n this.loading.delete(src);\n this.onLoad?.();\n },\n () => {\n this.loading.delete(src);\n },\n );\n }\n}\n","// @a-company/atelier-cli — CLI tool: validate, preview, render, info commands\n\n// Command registration functions (for programmatic use)\nexport { validateCommand, validateFile } from \"./commands/validate.js\";\nexport { infoCommand, getInfo } from \"./commands/info.js\";\nexport type { DocumentInfo } from \"./commands/info.js\";\nexport { stillCommand, resolveStill } from \"./commands/still.js\";\nexport { renderCommand } from \"./commands/render.js\";\nexport { exportSvgCommand } from \"./commands/export-svg.js\";\nexport { exportLottieCommand } from \"./commands/export-lottie.js\";\nexport { assetsCommand, getAssets } from \"./commands/assets.js\";\nexport type { AssetInfo } from \"./commands/assets.js\";\nexport { variablesCommand, getVariables } from \"./commands/variables.js\";\nexport type { VariableInfo } from \"./commands/variables.js\";\nexport {\n checkFfmpeg,\n buildFfmpegArgs,\n renderDocument,\n} from \"./commands/render-pipeline.js\";\nexport type {\n RenderFormat,\n RenderOptions,\n RenderResult,\n ProgressInfo,\n} from \"./commands/render-pipeline.js\";\n","import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport { validateAllDeltas } from \"@a-company/atelier-core\";\n\n/**\n * Validate an .atelier file: parse YAML, check schema, check delta overlaps.\n * Returns { valid, errors } for programmatic use.\n */\nexport function validateFile(filePath: string): {\n valid: boolean;\n errors: string[];\n} {\n const absPath = resolve(filePath);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n return { valid: false, errors: [`Cannot read file: ${absPath}`] };\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n return {\n valid: false,\n errors: result.errors.map(\n (e) => `${e.path}: ${e.message}`,\n ),\n };\n }\n\n // Check all states for delta overlaps\n const overlapErrors: string[] = [];\n for (const [stateName, state] of Object.entries(result.data.states)) {\n const overlaps = validateAllDeltas(state.deltas);\n for (const overlap of overlaps) {\n overlapErrors.push(`State \"${stateName}\": ${overlap.message}`);\n }\n }\n\n if (overlapErrors.length > 0) {\n return { valid: false, errors: overlapErrors };\n }\n\n return { valid: true, errors: [] };\n}\n\n/**\n * Register the `validate` subcommand on the Commander program.\n */\nexport function validateCommand(program: Command): void {\n program\n .command(\"validate <file>\")\n .description(\"Validate an .atelier YAML file\")\n .action((file: string) => {\n const { valid, errors } = validateFile(file);\n if (valid) {\n console.log(\"Valid\");\n } else {\n console.error(\"Validation errors:\");\n for (const error of errors) {\n console.error(` - ${error}`);\n }\n process.exit(1);\n }\n });\n}\n","import { z } from \"zod\";\n\n/** Pixel value — any number */\nexport const PixelSchema = z.number();\n\n/** Percentage string like \"50%\" */\nexport const PercentageSchema = z.string().regex(/^-?\\d+(\\.\\d+)?%$/, {\n message: \"Percentage must be a number followed by %, e.g. \\\"50%\\\"\",\n});\n\n/** Either pixel or percentage */\nexport const UnitValueSchema = z.union([PixelSchema, PercentageSchema]);\n","import { z } from \"zod\";\nimport { UnitValueSchema } from \"./units.js\";\n\nexport const FrameSchema = z.object({\n x: UnitValueSchema,\n y: UnitValueSchema,\n});\n\nexport const BoundsSchema = z.object({\n width: UnitValueSchema,\n height: UnitValueSchema,\n});\n\nexport const AnchorPointSchema = z.object({\n x: z.number().min(0).max(1),\n y: z.number().min(0).max(1),\n});\n","import { z } from \"zod\";\n\nexport const RGBAColorSchema = z.object({\n r: z.number().min(0).max(255),\n g: z.number().min(0).max(255),\n b: z.number().min(0).max(255),\n a: z.number().min(0).max(1),\n});\n\nexport const HSLAColorSchema = z.object({\n h: z.number().min(0).max(360),\n s: z.number().min(0).max(100),\n l: z.number().min(0).max(100),\n a: z.number().min(0).max(1),\n});\n\nexport const HexColorSchema = z.string().regex(/^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/, {\n message: \"Color must be a hex string: #RGB, #RGBA, #RRGGBB, or #RRGGBBAA\",\n});\n\nexport const ColorSchema = z.union([RGBAColorSchema, HSLAColorSchema, HexColorSchema]);\n","import { z } from \"zod\";\nimport { ColorSchema } from \"./color.js\";\nimport { UnitValueSchema } from \"./units.js\";\n\nexport const PathPointSchema = z.object({\n x: z.number(),\n y: z.number(),\n in: z.object({ x: z.number(), y: z.number() }).optional(),\n out: z.object({ x: z.number(), y: z.number() }).optional(),\n});\n\nexport const RectShapeSchema = z.object({\n type: z.literal(\"rect\"),\n cornerRadius: z.union([\n z.number().min(0),\n z.tuple([z.number().min(0), z.number().min(0), z.number().min(0), z.number().min(0)]),\n ]).optional(),\n});\n\nexport const EllipseShapeSchema = z.object({\n type: z.literal(\"ellipse\"),\n});\n\nexport const PathShapeSchema = z.object({\n type: z.literal(\"path\"),\n points: z.array(PathPointSchema).min(2, \"Path must have at least 2 points\"),\n closed: z.boolean().optional(),\n});\n\nexport const ShapeSchema = z.discriminatedUnion(\"type\", [\n RectShapeSchema,\n EllipseShapeSchema,\n PathShapeSchema,\n]);\n\nexport const GradientStopSchema = z.object({\n offset: z.number().min(0).max(1),\n color: ColorSchema,\n});\n\nexport const SolidFillSchema = z.object({\n type: z.literal(\"solid\"),\n color: ColorSchema,\n});\n\nexport const LinearGradientFillSchema = z.object({\n type: z.literal(\"linear-gradient\"),\n angle: z.number(),\n stops: z.array(GradientStopSchema).min(2, \"Gradient needs at least 2 stops\"),\n});\n\nexport const RadialGradientFillSchema = z.object({\n type: z.literal(\"radial-gradient\"),\n center: z.object({ x: UnitValueSchema, y: UnitValueSchema }),\n radius: UnitValueSchema,\n stops: z.array(GradientStopSchema).min(2, \"Gradient needs at least 2 stops\"),\n});\n\nexport const FillSchema = z.discriminatedUnion(\"type\", [\n SolidFillSchema,\n LinearGradientFillSchema,\n RadialGradientFillSchema,\n]);\n\nexport const StrokeSchema = z.object({\n color: ColorSchema,\n width: z.number().min(0),\n dash: z.array(z.number().min(0)).optional(),\n lineCap: z.enum([\"butt\", \"round\", \"square\"]).optional(),\n lineJoin: z.enum([\"miter\", \"round\", \"bevel\"]).optional(),\n strokeStart: z.number().min(0).max(1).optional(),\n strokeEnd: z.number().min(0).max(1).optional(),\n});\n\nexport const TextStyleSchema = z.object({\n fontFamily: z.string().min(1, \"fontFamily is required\"),\n fontSize: z.number().positive(\"fontSize must be positive\"),\n fontWeight: z.union([z.number(), z.enum([\"normal\", \"bold\"])]).optional(),\n fontStyle: z.enum([\"normal\", \"italic\"]).optional(),\n textAlign: z.enum([\"left\", \"center\", \"right\"]).optional(),\n lineHeight: z.number().positive().optional(),\n letterSpacing: z.number().optional(),\n color: ColorSchema,\n});\n","import { z } from \"zod\";\n\nexport const LinearEasingSchema = z.object({ type: z.literal(\"linear\") });\n\nexport const CubicBezierEasingSchema = z.object({\n type: z.literal(\"cubic-bezier\"),\n x1: z.number().min(0).max(1),\n y1: z.number(),\n x2: z.number().min(0).max(1),\n y2: z.number(),\n});\n\nexport const SpringEasingSchema = z.object({\n type: z.literal(\"spring\"),\n mass: z.number().positive().optional(),\n stiffness: z.number().positive().optional(),\n damping: z.number().positive().optional(),\n velocity: z.number().optional(),\n});\n\nexport const StepEasingSchema = z.object({\n type: z.literal(\"step\"),\n steps: z.number().int().positive(),\n position: z.enum([\"start\", \"end\"]).optional(),\n});\n\nexport const EasingPresetSchema = z.enum([\"linear\", \"ease-in\", \"ease-out\", \"ease-in-out\"]);\n\nexport const EasingSchema = z.union([\n LinearEasingSchema,\n CubicBezierEasingSchema,\n SpringEasingSchema,\n StepEasingSchema,\n EasingPresetSchema,\n]);\n","import { z } from \"zod\";\nimport { ColorSchema } from \"./color.js\";\n\nexport const ShadowSchema = z.object({\n color: ColorSchema,\n blur: z.number().min(0),\n offsetX: z.number().optional(),\n offsetY: z.number().optional(),\n});\n","import { z } from \"zod\";\nimport { ShapeSchema, FillSchema, StrokeSchema, TextStyleSchema, PathPointSchema } from \"./shape.js\";\nimport { FrameSchema, BoundsSchema, AnchorPointSchema } from \"./coordinates.js\";\nimport { ShadowSchema } from \"./shadow.js\";\nimport { InteractionSchema } from \"./interaction.js\";\n\nexport const BlendModeSchema = z.enum([\n \"normal\", \"multiply\", \"screen\", \"overlay\",\n \"darken\", \"lighten\", \"color-dodge\", \"color-burn\",\n \"hard-light\", \"soft-light\", \"difference\", \"exclusion\",\n \"hue\", \"saturation\", \"color\", \"luminosity\",\n]);\n\nexport const MotionPathSchema = z.object({\n points: z.array(PathPointSchema).min(2, \"Motion path must have at least 2 points\"),\n closed: z.boolean().optional(),\n autoRotate: z.boolean().optional(),\n autoRotateOffset: z.number().optional(),\n});\n\nexport const ShapeVisualSchema = z.object({\n type: z.literal(\"shape\"),\n shape: ShapeSchema,\n fill: FillSchema.optional(),\n stroke: StrokeSchema.optional(),\n});\n\nexport const TextVisualSchema = z.object({\n type: z.literal(\"text\"),\n content: z.string(),\n style: TextStyleSchema,\n});\n\nexport const SpritesheetConfigSchema = z.object({\n columns: z.number().int().positive(),\n rows: z.number().int().positive(),\n frameCount: z.number().int().positive().optional(),\n frameWidth: z.number().positive(),\n frameHeight: z.number().positive(),\n});\n\nexport const SourceRectSchema = z.object({\n x: z.number(),\n y: z.number(),\n width: z.number().positive(),\n height: z.number().positive(),\n});\n\nexport const ImageVisualSchema = z.object({\n type: z.literal(\"image\"),\n assetId: z.string().min(1, \"assetId is required\"),\n src: z.string().optional(),\n sourceRect: SourceRectSchema.optional(),\n spritesheet: SpritesheetConfigSchema.optional(),\n frameIndex: z.number().int().min(0).optional(),\n});\n\nexport const GroupVisualSchema = z.object({\n type: z.literal(\"group\"),\n});\n\nexport const RefVisualSchema = z.object({\n type: z.literal(\"ref\"),\n src: z.string().min(1, \"src is required\"),\n state: z.string().optional(),\n frame: z.number().int().min(0).optional(),\n});\n\nexport const VisualSchema = z.discriminatedUnion(\"type\", [\n ShapeVisualSchema,\n TextVisualSchema,\n ImageVisualSchema,\n GroupVisualSchema,\n RefVisualSchema,\n]);\n\nexport const LayerSchema = z.object({\n id: z.string().min(1, \"Layer id is required\"),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n visual: VisualSchema,\n frame: FrameSchema,\n bounds: BoundsSchema,\n anchorPoint: AnchorPointSchema.optional(),\n parentId: z.string().optional(),\n opacity: z.number().min(0).max(1).optional(),\n rotation: z.number().optional(),\n scale: z.object({ x: z.number(), y: z.number() }).optional(),\n visible: z.boolean().optional(),\n shadow: ShadowSchema.optional(),\n blendMode: BlendModeSchema.optional(),\n motionPath: MotionPathSchema.optional(),\n clipPath: ShapeSchema.optional(),\n tint: z.object({\n color: z.string(),\n amount: z.number().min(0).max(1),\n }).optional(),\n interactions: z.array(InteractionSchema).optional(),\n});\n","import { z } from \"zod\";\n\nexport const TriggerTypeSchema = z.enum([\n \"click\", \"hover\", \"pointerdown\", \"pointerup\", \"timer\", \"signal\",\n]);\n\nexport const TriggerSchema = z.object({\n type: TriggerTypeSchema,\n delay: z.number().nonnegative(\"Timer delay must be non-negative\").optional(),\n signal: z.string().optional(),\n}).refine(\n (t) => t.type !== \"timer\" || t.delay !== undefined,\n { message: \"Timer trigger requires a delay\" },\n).refine(\n (t) => t.type !== \"signal\" || t.signal !== undefined,\n { message: \"Signal trigger requires a signal name\" },\n);\n\nexport const ActionTypeSchema = z.enum([\n \"go-to-state\", \"emit-signal\", \"set-variable\", \"toggle-visibility\",\n]);\n\nexport const ActionSchema = z.object({\n type: ActionTypeSchema,\n state: z.string().optional(),\n signal: z.string().optional(),\n variable: z.string().optional(),\n value: z.unknown().optional(),\n targetLayer: z.string().optional(),\n}).refine(\n (a) => a.type !== \"go-to-state\" || a.state !== undefined,\n { message: \"go-to-state action requires a state name\" },\n).refine(\n (a) => a.type !== \"emit-signal\" || a.signal !== undefined,\n { message: \"emit-signal action requires a signal name\" },\n).refine(\n (a) => a.type !== \"set-variable\" || (a.variable !== undefined && a.value !== undefined),\n { message: \"set-variable action requires variable and value\" },\n);\n\nexport const InteractionSchema = z.object({\n id: z.string().min(1, \"Interaction id is required\"),\n trigger: TriggerSchema,\n action: ActionSchema,\n description: z.string().optional(),\n});\n","import { z } from \"zod\";\nimport { EasingSchema } from \"./easing.js\";\n\nexport const AnimatablePropertySchema = z.enum([\n \"frame.x\",\n \"frame.y\",\n \"bounds.width\",\n \"bounds.height\",\n \"opacity\",\n \"rotation\",\n \"scale.x\",\n \"scale.y\",\n \"anchorPoint.x\",\n \"anchorPoint.y\",\n \"visual.shape.cornerRadius\",\n \"visual.fill.color\",\n \"visual.stroke.color\",\n \"visual.stroke.width\",\n \"visual.stroke.start\",\n \"visual.stroke.end\",\n \"visual.style.fontSize\",\n \"visual.style.color\",\n \"shadow.color\",\n \"shadow.blur\",\n \"shadow.offsetX\",\n \"shadow.offsetY\",\n \"motionPath.progress\",\n \"visual.fill.angle\",\n \"visual.fill.center.x\",\n \"visual.fill.center.y\",\n \"visual.fill.radius\",\n \"visual.image.sourceRect.x\",\n \"visual.image.sourceRect.y\",\n \"visual.image.sourceRect.width\",\n \"visual.image.sourceRect.height\",\n \"visual.image.frameIndex\",\n \"visible\",\n \"tint.color\",\n \"tint.amount\",\n]);\n\nexport const FrameRangeSchema = z.tuple([\n z.number().int().min(0, \"Frame start must be >= 0\"),\n z.number().int().min(0, \"Frame end must be >= 0\"),\n]).refine(([start, end]) => end >= start, {\n message: \"Frame range end must be >= start\",\n});\n\nexport const DeltaSchema = z.object({\n id: z.string().optional(),\n name: z.string().optional(),\n layer: z.string().min(1, \"Delta must reference a layer id\"),\n property: AnimatablePropertySchema,\n range: FrameRangeSchema,\n from: z.unknown(),\n to: z.unknown(),\n easing: EasingSchema.optional(),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n});\n","import { z } from \"zod\";\nimport { DeltaSchema } from \"./delta.js\";\nimport { EasingSchema } from \"./easing.js\";\n\nexport const AudioSchema = z.object({\n src: z.string().min(1, \"Audio src is required\"),\n offset: z.number().min(0, \"Audio offset must be non-negative\").optional(),\n volume: z.number().min(0).max(1, \"Audio volume must be 0–1\").optional(),\n loop: z.boolean().optional(),\n startFrame: z.number().int().min(0, \"Audio startFrame must be a non-negative integer\").optional(),\n});\n\nexport const StateTransitionConfigSchema = z.object({\n duration: z.number().int().positive(\"Transition duration must be a positive integer (frames)\"),\n easing: EasingSchema.optional(),\n});\n\nexport const StateSchema = z.object({\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n parent: z.string().optional(),\n duration: z.number().int().positive(\"State duration must be a positive integer (frames)\"),\n deltas: z.array(DeltaSchema),\n audio: AudioSchema.optional(),\n transitions: z.record(z.string(), StateTransitionConfigSchema).optional(),\n});\n","import { z } from \"zod\";\nimport { AnimatablePropertySchema } from \"./delta.js\";\nimport { EasingSchema } from \"./easing.js\";\n\nexport const PresetDeltaSchema = z.object({\n property: AnimatablePropertySchema,\n offset: z.tuple([z.number().int().min(0), z.number().int().min(0)]).optional(),\n from: z.unknown(),\n to: z.unknown(),\n easing: EasingSchema.optional(),\n});\n\nexport const PresetSchema = z.object({\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n deltas: z.array(PresetDeltaSchema).min(1, \"Preset must have at least one delta\"),\n});\n","import { z } from \"zod\";\n\nexport const VariableTypeSchema = z.enum([\"string\", \"number\", \"color\", \"asset\", \"boolean\"]);\n\nexport const VariableSchema = z.object({\n type: VariableTypeSchema,\n default: z.unknown().optional(),\n description: z.string().optional(),\n});\n","import { z } from \"zod\";\n\nexport const AssetTypeSchema = z.enum([\"image\", \"svg\", \"font\", \"animation\", \"audio\"]);\n\nexport const AssetSchema = z.object({\n type: AssetTypeSchema,\n src: z.string().min(1, \"Asset src is required\"),\n description: z.string().optional(),\n spritesheet: z.object({\n columns: z.number().int().positive(),\n rows: z.number().int().positive(),\n frameCount: z.number().int().positive().optional(),\n frameWidth: z.number().positive(),\n frameHeight: z.number().positive(),\n }).optional(),\n});\n","import { z } from \"zod\";\nimport { LayerSchema } from \"./layer.js\";\nimport { StateSchema } from \"./state.js\";\nimport { PresetSchema } from \"./preset.js\";\nimport { VariableSchema } from \"./variable.js\";\nimport { AssetSchema } from \"./asset.js\";\n\nexport const CanvasSchema = z.object({\n width: z.number().int().positive(\"Canvas width must be a positive integer\"),\n height: z.number().int().positive(\"Canvas height must be a positive integer\"),\n fps: z.number().int().positive(\"FPS must be a positive integer\"),\n background: z.string().optional(),\n});\n\nexport const AtelierDocumentSchema = z.object({\n version: z.string().min(1, \"Version is required\"),\n name: z.string().min(1, \"Animation name is required\"),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n canvas: CanvasSchema,\n variables: z.record(z.string(), VariableSchema).optional(),\n assets: z.record(z.string(), AssetSchema).optional(),\n presets: z.record(z.string(), PresetSchema).optional(),\n layers: z.array(LayerSchema),\n states: z.record(z.string(), StateSchema),\n});\n","import type { AtelierDocument, Layer, Delta } from \"@a-company/atelier-types\";\nimport { AtelierDocumentSchema } from \"./document.js\";\nimport { LayerSchema } from \"./layer.js\";\nimport { DeltaSchema } from \"./delta.js\";\nimport type { z } from \"zod\";\n\n/** Validation result — either success with typed data or failure with readable errors */\nexport type ValidationResult<T> =\n | { success: true; data: T }\n | { success: false; errors: ValidationError[] };\n\nexport interface ValidationError {\n path: string;\n message: string;\n}\n\n/** Format Zod errors into flat, AI-readable error messages */\nfunction formatErrors(error: z.ZodError): ValidationError[] {\n return error.issues.map((issue) => ({\n path: issue.path.join(\".\") || \"(root)\",\n message: issue.message,\n }));\n}\n\n/** Validate a complete AtelierDocument */\nexport function validateDocument(input: unknown): ValidationResult<AtelierDocument> {\n const result = AtelierDocumentSchema.safeParse(input);\n if (result.success) {\n return { success: true, data: result.data as AtelierDocument };\n }\n return { success: false, errors: formatErrors(result.error) };\n}\n\n/** Validate a single Layer */\nexport function validateLayer(input: unknown): ValidationResult<Layer> {\n const result = LayerSchema.safeParse(input);\n if (result.success) {\n return { success: true, data: result.data as Layer };\n }\n return { success: false, errors: formatErrors(result.error) };\n}\n\n/** Validate a single Delta */\nexport function validateDelta(input: unknown): ValidationResult<Delta> {\n const result = DeltaSchema.safeParse(input);\n if (result.success) {\n return { success: true, data: result.data as Delta };\n }\n return { success: false, errors: formatErrors(result.error) };\n}\n","import { parse as yamlParse, stringify as yamlStringify } from \"yaml\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { validateDocument } from \"./validate.js\";\nimport type { ValidationResult } from \"./validate.js\";\n\n/**\n * Parse a YAML string into a validated AtelierDocument.\n * Returns validation errors if the YAML is invalid or doesn't match the schema.\n */\nexport function parseAtelier(yamlString: string): ValidationResult<AtelierDocument> {\n let parsed: unknown;\n try {\n parsed = yamlParse(yamlString);\n } catch (err) {\n return {\n success: false,\n errors: [{ path: \"(yaml)\", message: `YAML parse error: ${(err as Error).message}` }],\n };\n }\n return validateDocument(parsed);\n}\n\n/**\n * Serialize an AtelierDocument to YAML string.\n */\nexport function serializeAtelier(doc: AtelierDocument): string {\n return yamlStringify(doc, { indent: 2 });\n}\n","import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\n\n/**\n * Info summary for an AtelierDocument.\n */\nexport interface DocumentInfo {\n name: string;\n description?: string;\n canvas: {\n width: number;\n height: number;\n fps: number;\n background?: string;\n };\n layers: {\n count: number;\n items: { id: string; type: string }[];\n };\n states: {\n count: number;\n items: { name: string; duration: number; deltaCount: number }[];\n };\n presets: {\n count: number;\n };\n}\n\n/**\n * Extract summary info from a parsed AtelierDocument.\n */\nexport function getInfo(doc: AtelierDocument): DocumentInfo {\n return {\n name: doc.name,\n description: doc.description,\n canvas: {\n width: doc.canvas.width,\n height: doc.canvas.height,\n fps: doc.canvas.fps,\n background: doc.canvas.background,\n },\n layers: {\n count: doc.layers.length,\n items: doc.layers.map((layer) => ({\n id: layer.id,\n type: layer.visual.type,\n })),\n },\n states: {\n count: Object.keys(doc.states).length,\n items: Object.entries(doc.states).map(([name, state]) => ({\n name,\n duration: state.duration,\n deltaCount: state.deltas.length,\n })),\n },\n presets: {\n count: doc.presets ? Object.keys(doc.presets).length : 0,\n },\n };\n}\n\n/**\n * Format a DocumentInfo for terminal output.\n */\nfunction formatInfo(info: DocumentInfo): string {\n const lines: string[] = [];\n\n lines.push(`Name: ${info.name}`);\n if (info.description) {\n lines.push(`Description: ${info.description}`);\n }\n\n const bg = info.canvas.background\n ? `, background: ${info.canvas.background}`\n : \"\";\n lines.push(\n `Canvas: ${info.canvas.width}x${info.canvas.height} @ ${info.canvas.fps}fps${bg}`,\n );\n\n lines.push(`Layers: ${info.layers.count}`);\n for (const layer of info.layers.items) {\n lines.push(` - ${layer.id} (${layer.type})`);\n }\n\n lines.push(`States: ${info.states.count}`);\n for (const state of info.states.items) {\n lines.push(\n ` - ${state.name}: ${state.duration} frames, ${state.deltaCount} deltas`,\n );\n }\n\n if (info.presets.count > 0) {\n lines.push(`Presets: ${info.presets.count}`);\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/**\n * Register the `info` subcommand on the Commander program.\n */\nexport function infoCommand(program: Command): void {\n program\n .command(\"info <file>\")\n .description(\"Display summary info for an .atelier file\")\n .action((file: string) => {\n const doc = readAndParse(file);\n const info = getInfo(doc);\n console.log(formatInfo(info));\n });\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport { resolveFrame } from \"@a-company/atelier-core\";\nimport type { ResolvedFrame } from \"@a-company/atelier-core\";\n\n/**\n * Resolve a single frame from a document, returning the resolved frame data.\n * If stateName is not provided, uses the first state.\n * If frame is not provided, uses frame 0.\n */\nexport function resolveStill(\n doc: AtelierDocument,\n stateName?: string,\n frame?: number,\n): ResolvedFrame {\n const stateNames = Object.keys(doc.states);\n if (stateNames.length === 0) {\n throw new Error(\"Document has no states\");\n }\n\n const resolvedStateName = stateName ?? stateNames[0];\n if (!(resolvedStateName in doc.states)) {\n throw new Error(\n `State \"${resolvedStateName}\" not found. Available: ${stateNames.join(\", \")}`,\n );\n }\n\n const resolvedFrame = frame ?? 0;\n return resolveFrame(doc, resolvedStateName, resolvedFrame);\n}\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/**\n * Register the `still` subcommand on the Commander program.\n */\nexport function stillCommand(program: Command): void {\n program\n .command(\"still <file>\")\n .description(\n \"Resolve a single frame and output as JSON or render as PNG\",\n )\n .option(\"-s, --state <name>\", \"State name (defaults to first state)\")\n .option(\n \"-f, --frame <number>\",\n \"Frame number (defaults to 0)\",\n \"0\",\n )\n .option(\n \"--format <type>\",\n \"Output format: json | png (default: json)\",\n \"json\",\n )\n .option(\"-o, --output <path>\", \"Output file path (default: stdout)\")\n .action(\n async (\n file: string,\n options: { state?: string; frame: string; format: string; output?: string },\n ) => {\n const doc = readAndParse(file);\n\n const frameNumber = parseInt(options.frame, 10);\n if (isNaN(frameNumber) || frameNumber < 0) {\n console.error(\n `Invalid frame number: ${options.frame}`,\n );\n process.exit(1);\n return;\n }\n\n if (options.format !== \"json\" && options.format !== \"png\") {\n console.error(`Unknown format: \"${options.format}\". Use json or png.`);\n process.exit(1);\n return;\n }\n\n try {\n const resolved = resolveStill(\n doc,\n options.state,\n frameNumber,\n );\n\n if (options.format === \"json\") {\n const json = JSON.stringify(resolved, null, 2);\n if (options.output) {\n writeFileSync(resolve(options.output), json, \"utf-8\");\n } else {\n console.log(json);\n }\n } else {\n // PNG format — dynamic import of canvas\n let canvasMod: typeof import(\"canvas\");\n try {\n canvasMod = await import(\"canvas\");\n } catch {\n console.error(\"PNG output requires the 'canvas' package. Install it: npm i canvas\");\n process.exit(1);\n return;\n }\n\n const { renderFrame } = await import(\"@a-company/atelier-canvas\");\n\n const { createCanvas } = canvasMod;\n const cvs = createCanvas(doc.canvas.width, doc.canvas.height);\n const ctx = cvs.getContext(\"2d\");\n renderFrame(ctx as unknown as import(\"@a-company/atelier-canvas\").RenderContext, resolved, doc);\n\n const buffer = cvs.toBuffer(\"image/png\");\n if (options.output) {\n writeFileSync(resolve(options.output), buffer);\n } else {\n process.stdout.write(buffer);\n }\n }\n } catch (err) {\n console.error(\n (err as Error).message,\n );\n process.exit(1);\n }\n },\n );\n}\n","/**\n * `atelier render <file>` — render an animation to MP4 or GIF via FFmpeg.\n *\n * Usage:\n * atelier render animation.atelier → animation.mp4\n * atelier render animation.atelier -f gif → animation.gif\n * atelier render animation.atelier -o out/video.mp4 → custom path\n * atelier render animation.atelier -s intro outro → specific states\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { resolve, basename, extname } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport {\n checkFfmpeg,\n renderDocument,\n type RenderFormat,\n} from \"./render-pipeline.js\";\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\nfunction inferFormat(output: string | undefined): RenderFormat {\n if (!output) return \"mp4\";\n const ext = extname(output).toLowerCase();\n if (ext === \".gif\") return \"gif\";\n return \"mp4\";\n}\n\n/** Register the `render` subcommand on the Commander program. */\nexport function renderCommand(program: Command): void {\n program\n .command(\"render <file>\")\n .description(\"Render animation to MP4 or GIF via FFmpeg\")\n .option(\"-o, --output <path>\", \"Output file path\")\n .option(\"-f, --format <type>\", \"Output format: mp4 | gif\")\n .option(\n \"-s, --state <names...>\",\n \"State(s) to render (default: all in order)\",\n )\n .action(\n async (\n file: string,\n options: {\n output?: string;\n format?: string;\n state?: string[];\n },\n ) => {\n // Check FFmpeg availability\n const hasFfmpeg = await checkFfmpeg();\n if (!hasFfmpeg) {\n console.error(\"FFmpeg is not installed or not in PATH.\");\n console.error(\"Install it:\");\n console.error(\" macOS: brew install ffmpeg\");\n console.error(\" Ubuntu: sudo apt install ffmpeg\");\n console.error(\" Windows: https://ffmpeg.org/download.html\");\n process.exit(1);\n return;\n }\n\n const doc = readAndParse(file);\n\n // Resolve format\n let format: RenderFormat;\n if (options.format) {\n if (options.format !== \"mp4\" && options.format !== \"gif\") {\n console.error(\n `Unknown format: \"${options.format}\". Use mp4 or gif.`,\n );\n process.exit(1);\n return;\n }\n format = options.format;\n } else {\n format = inferFormat(options.output);\n }\n\n // Resolve output path\n const inputName = basename(file, extname(file));\n const output = options.output ?? `${inputName}.${format}`;\n\n const startTime = Date.now();\n\n try {\n const result = await renderDocument(doc, {\n output: resolve(output),\n format,\n states: options.state,\n onProgress: ({ frame, totalFrames, state, percent }) => {\n const elapsed = (Date.now() - startTime) / 1000;\n const rate = elapsed > 0 ? frame / elapsed : 0;\n const remaining =\n rate > 0 ? (totalFrames - frame) / rate : 0;\n process.stderr.write(\n `\\rRendering: frame ${frame}/${totalFrames} (${percent}%) - state \"${state}\" - ETA ${remaining.toFixed(1)}s`,\n );\n },\n });\n\n process.stderr.write(\"\\n\");\n console.log(\n `Done: ${result.totalFrames} frames \\u2192 ${result.output} (${(result.durationMs / 1000).toFixed(1)}s)`,\n );\n } catch (err) {\n process.stderr.write(\"\\n\");\n console.error((err as Error).message);\n process.exit(1);\n }\n },\n );\n}\n","/**\n * Core render pipeline — renders an Atelier document to MP4 or GIF via FFmpeg.\n * Pure pipeline with no Commander dependency; testable in isolation.\n */\n\nimport { spawn } from \"node:child_process\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { resolveFrame } from \"@a-company/atelier-core\";\nimport { renderFrame, ImageCache } from \"@a-company/atelier-canvas\";\n\n// ─── Types ───────────────────────────────────────────────────\n\nexport type RenderFormat = \"mp4\" | \"gif\";\n\nexport interface RenderOptions {\n output: string;\n format: RenderFormat;\n states?: string[];\n onProgress?: (info: ProgressInfo) => void;\n}\n\nexport interface ProgressInfo {\n frame: number;\n totalFrames: number;\n state: string;\n percent: number;\n}\n\nexport interface RenderResult {\n output: string;\n format: RenderFormat;\n totalFrames: number;\n states: string[];\n durationMs: number;\n}\n\n// ─── FFmpeg Helpers ──────────────────────────────────────────\n\n/** Check whether FFmpeg is available on the system PATH. */\nexport async function checkFfmpeg(): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn(\"ffmpeg\", [\"-version\"], { stdio: \"pipe\" });\n proc.on(\"error\", () => resolve(false));\n proc.on(\"close\", (code) => resolve(code === 0));\n });\n}\n\n/** Build the FFmpeg argument array for the given format. Pure function. */\nexport function buildFfmpegArgs(\n width: number,\n height: number,\n fps: number,\n format: RenderFormat,\n output: string,\n): string[] {\n const input = [\n \"-y\",\n \"-f\", \"rawvideo\",\n \"-pix_fmt\", \"bgra\",\n \"-s\", `${width}x${height}`,\n \"-r\", String(fps),\n \"-i\", \"pipe:0\",\n ];\n\n if (format === \"mp4\") {\n return [\n ...input,\n \"-c:v\", \"libx264\",\n \"-pix_fmt\", \"yuv420p\",\n \"-preset\", \"medium\",\n \"-crf\", \"18\",\n \"-movflags\", \"+faststart\",\n output,\n ];\n }\n\n // GIF — single-pass palette generation (stdin-compatible)\n return [\n ...input,\n \"-vf\", \"split[s0][s1];[s0]palettegen=stats_mode=single[p];[s1][p]paletteuse=dither=sierra2_4a\",\n \"-loop\", \"0\",\n output,\n ];\n}\n\n// ─── Image Pre-loading ───────────────────────────────────────\n\n/**\n * Scan document layers for image visuals, pre-load them with node-canvas\n * loadImage, and return a populated ImageCache ready for rendering.\n */\nasync function preloadImages(\n doc: AtelierDocument,\n loadImage: (src: string) => Promise<unknown>,\n): Promise<ImageCache> {\n const sources = new Set<string>();\n\n for (const layer of doc.layers) {\n if (layer.visual.type === \"image\") {\n const iv = layer.visual as { src?: string; assetId?: string };\n if (iv.src) {\n sources.add(iv.src);\n } else if (iv.assetId && doc.assets?.[iv.assetId]) {\n sources.add(doc.assets[iv.assetId].src);\n }\n }\n }\n\n if (sources.size === 0) {\n return new ImageCache();\n }\n\n // Load all images in parallel\n const preloaded = new Map<string, unknown>();\n await Promise.all(\n [...sources].map(async (src) => {\n try {\n preloaded.set(src, await loadImage(src));\n } catch {\n // Images that fail to load will render as blank\n }\n }),\n );\n\n // Create ImageCache pre-populated with loaded images.\n // createImage returns the pre-loaded image and fires onLoad on next tick\n // so that the ImageCache internal `image` variable is assigned first.\n const imageCache = new ImageCache({\n createImage: (src, onLoad, onError) => {\n const img = preloaded.get(src);\n if (img) {\n process.nextTick(onLoad);\n return img;\n }\n process.nextTick(onError);\n return {};\n },\n });\n\n for (const src of preloaded.keys()) {\n imageCache.load(src);\n }\n\n // Wait for nextTick callbacks to populate the cache\n await new Promise<void>((resolve) => process.nextTick(resolve));\n\n return imageCache;\n}\n\n// ─── Main Render Loop ────────────────────────────────────────\n\n/**\n * Render an Atelier document to a video/GIF file via FFmpeg.\n * Dynamically imports `canvas` (node-canvas) — fails with a helpful\n * message if the native dependency is not installed.\n */\nexport async function renderDocument(\n doc: AtelierDocument,\n opts: RenderOptions,\n): Promise<RenderResult> {\n // Dynamic import — canvas requires native compilation.\n // Use a variable to avoid TypeScript resolving the module at compile time.\n const canvasModuleName = \"canvas\";\n let createCanvas: (w: number, h: number) => unknown;\n let loadImage: (src: string) => Promise<unknown>;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const canvasModule = await import(/* webpackIgnore: true */ canvasModuleName);\n createCanvas = canvasModule.createCanvas;\n loadImage = canvasModule.loadImage;\n } catch {\n throw new Error(\n \"The 'canvas' package is not installed.\\n\" +\n \"Install it with:\\n\" +\n \" npm install canvas\\n\" +\n \"Prerequisites vary by OS:\\n\" +\n \" macOS: brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman\\n\" +\n \" Ubuntu: sudo apt install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev\\n\" +\n \"See: https://github.com/Automattic/node-canvas#compiling\",\n );\n }\n\n const { width, height, fps } = doc.canvas;\n const { output, format, states, onProgress } = opts;\n\n // H.264 requires even dimensions\n if (format === \"mp4\" && (width % 2 !== 0 || height % 2 !== 0)) {\n throw new Error(\n `H.264 requires even dimensions. Canvas is ${width}\\u00d7${height}. ` +\n `Try ${width + (width % 2)}\\u00d7${height + (height % 2)}.`,\n );\n }\n\n // Resolve which states to render\n const allStates = Object.keys(doc.states);\n const renderStates = states ?? allStates;\n for (const s of renderStates) {\n if (!(s in doc.states)) {\n throw new Error(\n `State \"${s}\" not found. Available: ${allStates.join(\", \")}`,\n );\n }\n }\n\n // Total frame count across all states\n let totalFrames = 0;\n for (const s of renderStates) {\n totalFrames += doc.states[s].duration;\n }\n\n if (totalFrames === 0) {\n throw new Error(\"Nothing to render \\u2014 all states have duration 0\");\n }\n\n // Pre-load images before the render loop\n const imageCache = await preloadImages(doc, loadImage);\n\n // Create node-canvas\n const canvas = createCanvas(width, height) as { getContext(id: \"2d\"): unknown; toBuffer(format: \"raw\"): Buffer };\n const ctx = canvas.getContext(\"2d\");\n\n // Spawn FFmpeg\n const ffmpegArgs = buildFfmpegArgs(width, height, fps, format, output);\n const ffmpeg = spawn(\"ffmpeg\", ffmpegArgs, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n let stderrOutput = \"\";\n ffmpeg.stderr?.on(\"data\", (chunk: Buffer) => {\n stderrOutput += chunk.toString();\n });\n\n const startTime = Date.now();\n let frameIndex = 0;\n\n for (const stateName of renderStates) {\n const duration = doc.states[stateName].duration;\n for (let f = 0; f < duration; f++) {\n const resolved = resolveFrame(doc, stateName, f);\n renderFrame(ctx as never, resolved, doc, imageCache);\n\n const raw = canvas.toBuffer(\"raw\");\n const canWrite = ffmpeg.stdin!.write(raw);\n if (!canWrite) {\n await new Promise<void>((resolve) =>\n ffmpeg.stdin!.once(\"drain\", resolve),\n );\n }\n\n frameIndex++;\n onProgress?.({\n frame: frameIndex,\n totalFrames,\n state: stateName,\n percent: Math.round((frameIndex / totalFrames) * 100),\n });\n }\n }\n\n // Close stdin and wait for FFmpeg to exit\n ffmpeg.stdin!.end();\n\n const exitCode = await new Promise<number | null>((resolve) => {\n ffmpeg.on(\"close\", resolve);\n });\n\n if (exitCode !== 0) {\n throw new Error(\n `FFmpeg exited with code ${exitCode}.\\n${stderrOutput.slice(-500)}`,\n );\n }\n\n return {\n output,\n format,\n totalFrames,\n states: renderStates,\n durationMs: Date.now() - startTime,\n };\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport { renderFrameSVG } from \"@a-company/atelier-svg\";\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/** Register the `export-svg` subcommand on the Commander program. */\nexport function exportSvgCommand(program: Command): void {\n program\n .command(\"export-svg <file>\")\n .description(\"Export a frame as SVG\")\n .option(\"-s, --state <name>\", \"State name (defaults to first state)\")\n .option(\"-f, --frame <number>\", \"Frame number (defaults to 0)\", \"0\")\n .option(\"-o, --output <path>\", \"Output file path (default: stdout)\")\n .option(\"--xml-declaration\", \"Include XML declaration\")\n .action(\n (\n file: string,\n options: { state?: string; frame: string; output?: string; xmlDeclaration?: boolean },\n ) => {\n const doc = readAndParse(file);\n\n const frameNumber = parseInt(options.frame, 10);\n if (isNaN(frameNumber) || frameNumber < 0) {\n console.error(`Invalid frame number: ${options.frame}`);\n process.exit(1);\n return;\n }\n\n const stateNames = Object.keys(doc.states);\n if (stateNames.length === 0) {\n console.error(\"Document has no states\");\n process.exit(1);\n return;\n }\n\n const stateName = options.state ?? stateNames[0];\n if (!doc.states[stateName]) {\n console.error(`State \"${stateName}\" not found. Available: ${stateNames.join(\", \")}`);\n process.exit(1);\n return;\n }\n\n try {\n const svg = renderFrameSVG(doc, stateName, frameNumber, {\n xmlDeclaration: options.xmlDeclaration,\n });\n\n if (options.output) {\n writeFileSync(resolve(options.output), svg, \"utf-8\");\n } else {\n console.log(svg);\n }\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n },\n );\n}\n","import type { AtelierDocument, ImageVisual, RefVisual } from \"@a-company/atelier-types\";\nimport { resolveFrame, type ResolvedFrame } from \"@a-company/atelier-core\";\nimport { buildEffectiveLayer, type EffectiveLayer, type DocumentResolver } from \"@a-company/atelier-canvas\";\nimport { buildTransform, buildStyleAttrs } from \"./svg-properties.js\";\nimport { renderShapeSVG } from \"./svg-shapes.js\";\nimport { renderTextSVG } from \"./svg-text.js\";\nimport { buildShadowFilter, buildTintFilter, resetFilterCounter } from \"./svg-filters.js\";\nimport { resetGradientCounter } from \"./svg-gradients.js\";\nimport { buildClipPathDef, resetClipCounter } from \"./svg-clip.js\";\nimport { escapeXml } from \"./svg-properties.js\";\n\nexport interface RenderSVGOptions {\n /** Include XML declaration (default: false) */\n xmlDeclaration?: boolean;\n /** Include viewBox attribute (default: true) */\n viewBox?: boolean;\n /** Indent size in spaces (default: 2) */\n indent?: number;\n /** Resolves ref layer src paths to loaded AtelierDocuments */\n documentResolver?: DocumentResolver;\n /** Maximum ref nesting depth (default: 4) */\n maxRefDepth?: number;\n}\n\n/**\n * Render a resolved frame as an SVG string.\n * If no resolved frame is provided, resolves the given state and frame.\n */\nexport function renderFrameSVG(\n doc: AtelierDocument,\n stateOrFrame: string | ResolvedFrame,\n frame?: number,\n opts?: RenderSVGOptions,\n): string {\n // Reset counters for deterministic IDs\n resetGradientCounter();\n resetFilterCounter();\n resetClipCounter();\n\n let resolved: ResolvedFrame;\n if (typeof stateOrFrame === \"string\") {\n resolved = resolveFrame(doc, stateOrFrame, frame ?? 0);\n } else {\n resolved = stateOrFrame;\n }\n\n const { width, height } = doc.canvas;\n const indent = opts?.indent ?? 2;\n const pad = \" \".repeat(indent);\n\n // Build effective layers\n const effLayers: EffectiveLayer[] = resolved.layers.map(rl =>\n buildEffectiveLayer(rl, width, height),\n );\n\n // Collect all defs and layer elements\n const allDefs: string[] = [];\n const layerElements: string[] = [];\n\n for (let i = 0; i < effLayers.length; i++) {\n const eff = effLayers[i];\n const layer = resolved.layers[i].layer;\n\n // Skip invisible or fully transparent\n if (!eff.visible) continue;\n if (eff.opacity <= 0) continue;\n\n // Resolve asset for images\n if (layer.visual.type === \"image\") {\n const iv = eff.visual as ImageVisual;\n if (!iv.src && iv.assetId && doc.assets?.[iv.assetId]) {\n (eff.visual as ImageVisual).src = doc.assets[iv.assetId].src;\n }\n }\n\n // Build transform\n const transform = buildTransform(eff);\n const styleAttrs = buildStyleAttrs(eff);\n\n // Build shadow filter\n const filterResult = buildShadowFilter(eff);\n if (filterResult) allDefs.push(filterResult.defs);\n\n // Build tint filter\n const tintResult = buildTintFilter(eff);\n if (tintResult) allDefs.push(tintResult.defs);\n\n // Build clip path\n let clipAttr = \"\";\n if (layer.clipPath) {\n const clipResult = buildClipPathDef(layer.clipPath, eff.width, eff.height);\n if (clipResult.defs) {\n allDefs.push(clipResult.defs);\n clipAttr = ` clip-path=\"${clipResult.clipRef}\"`;\n }\n }\n\n // Build group attributes\n const gAttrs: string[] = [];\n if (transform) gAttrs.push(`transform=\"${transform}\"`);\n if (styleAttrs) gAttrs.push(styleAttrs);\n // Apply combined or individual filters\n if (filterResult && tintResult) {\n // When both shadow and tint exist, we need a combined filter\n // For simplicity, apply shadow filter and tint separately via style\n gAttrs.push(`filter=\"${filterResult.filterRef}\"`);\n // Tint is a second filter — wrap content in nested group\n } else if (filterResult) {\n gAttrs.push(`filter=\"${filterResult.filterRef}\"`);\n } else if (tintResult) {\n gAttrs.push(`filter=\"${tintResult.filterRef}\"`);\n }\n if (clipAttr) gAttrs.push(clipAttr.trim());\n\n // Render visual content\n let content = \"\";\n let layerDefs = \"\";\n\n switch (layer.visual.type) {\n case \"shape\": {\n const result = renderShapeSVG(eff, eff.visual as import(\"@a-company/atelier-types\").ShapeVisual);\n content = result.elements;\n layerDefs = result.defs;\n break;\n }\n case \"text\":\n content = renderTextSVG(eff, eff.visual as import(\"@a-company/atelier-types\").TextVisual);\n break;\n case \"image\": {\n const iv = eff.visual as ImageVisual;\n if (iv.src) {\n if (iv.spritesheet) {\n // Spritesheet: compute source rect and use full sheet dimensions for inner image\n const { columns, rows, frameWidth, frameHeight, frameCount } = iv.spritesheet;\n const maxFrames = frameCount ?? (columns * rows);\n const idx = Math.max(0, Math.min(Math.floor(iv.frameIndex ?? 0), maxFrames - 1));\n const col = idx % columns;\n const row = Math.floor(idx / columns);\n const sx = col * frameWidth;\n const sy = row * frameHeight;\n const imgW = columns * frameWidth;\n const imgH = rows * frameHeight;\n content = `<svg viewBox=\"${sx} ${sy} ${frameWidth} ${frameHeight}\" width=\"${eff.width}\" height=\"${eff.height}\">` +\n `<image href=\"${escapeXml(iv.src)}\" width=\"${imgW}\" height=\"${imgH}\" />` +\n `</svg>`;\n } else if (iv.sourceRect) {\n // Manual sourceRect: viewBox crops from image coordinate space\n const sr = iv.sourceRect;\n content = `<svg viewBox=\"${sr.x} ${sr.y} ${sr.width} ${sr.height}\" width=\"${eff.width}\" height=\"${eff.height}\">` +\n `<image href=\"${escapeXml(iv.src)}\" width=\"${eff.width}\" height=\"${eff.height}\" />` +\n `</svg>`;\n } else {\n content = `<image href=\"${escapeXml(iv.src)}\" width=\"${eff.width}\" height=\"${eff.height}\" />`;\n }\n }\n break;\n }\n case \"group\":\n // Groups are structural — no visual content in SVG either\n break;\n case \"ref\": {\n const refVisual = eff.visual as RefVisual;\n const refContent = renderRefSVG(eff, refVisual, doc, opts);\n content = refContent;\n break;\n }\n }\n\n if (layerDefs) allDefs.push(layerDefs);\n\n if (content) {\n const gOpen = gAttrs.length > 0 ? `<g ${gAttrs.join(\" \")}>` : \"<g>\";\n layerElements.push(`${pad}${gOpen}${content}</g>`);\n }\n }\n\n // Build SVG\n const lines: string[] = [];\n\n if (opts?.xmlDeclaration) {\n lines.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n }\n\n const viewBox = opts?.viewBox !== false ? ` viewBox=\"0 0 ${width} ${height}\"` : \"\";\n const bg = doc.canvas.background;\n\n lines.push(`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\"${viewBox}>`);\n\n // Defs section\n if (allDefs.length > 0) {\n lines.push(`${pad}<defs>`);\n for (const def of allDefs) {\n lines.push(`${pad}${pad}${def}`);\n }\n lines.push(`${pad}</defs>`);\n }\n\n // Background\n if (bg && bg !== \"transparent\") {\n lines.push(`${pad}<rect width=\"${width}\" height=\"${height}\" fill=\"${bg}\" />`);\n }\n\n // Layers\n lines.push(...layerElements);\n\n lines.push(\"</svg>\");\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a ref layer as SVG. Uses documentResolver to inline sub-doc content,\n * or falls back to a dashed placeholder rectangle.\n */\nfunction renderRefSVG(\n eff: EffectiveLayer,\n visual: RefVisual,\n _parentDoc: AtelierDocument,\n opts?: RenderSVGOptions,\n _depth?: number,\n _visitedRefs?: Set<string>,\n): string {\n const resolver = opts?.documentResolver;\n\n if (!resolver) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#999\" stroke-dasharray=\"4 2\" />`;\n }\n\n const depth = _depth ?? 0;\n const maxDepth = opts?.maxRefDepth ?? 4;\n if (depth >= maxDepth) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#c33\" stroke-dasharray=\"4 2\" /><text x=\"${eff.width / 2}\" y=\"${eff.height / 2}\" text-anchor=\"middle\" dominant-baseline=\"middle\" fill=\"#c33\" font-size=\"12\">MAX DEPTH</text>`;\n }\n\n const visitedRefs = _visitedRefs ?? new Set<string>();\n if (visitedRefs.has(visual.src)) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#c33\" stroke-dasharray=\"4 2\" /><text x=\"${eff.width / 2}\" y=\"${eff.height / 2}\" text-anchor=\"middle\" dominant-baseline=\"middle\" fill=\"#c33\" font-size=\"12\">CYCLE</text>`;\n }\n\n const subDoc = resolver(visual.src);\n if (!subDoc) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#999\" stroke-dasharray=\"4 2\" /><text x=\"${eff.width / 2}\" y=\"${eff.height / 2}\" text-anchor=\"middle\" dominant-baseline=\"middle\" fill=\"#999\" font-size=\"12\">NOT FOUND</text>`;\n }\n\n const stateNames = Object.keys(subDoc.states);\n if (stateNames.length === 0) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#999\" stroke-dasharray=\"4 2\" />`;\n }\n\n const stateName = visual.state ?? stateNames[0];\n const stateObj = subDoc.states[stateName];\n if (!stateObj) {\n return `<rect width=\"${eff.width}\" height=\"${eff.height}\" fill=\"none\" stroke=\"#999\" stroke-dasharray=\"4 2\" />`;\n }\n\n const maxFrame = Math.max(0, stateObj.duration - 1);\n const frame = Math.min(visual.frame ?? 0, maxFrame);\n\n visitedRefs.add(visual.src);\n\n // Render sub-doc as nested <svg> with viewBox for scaling\n const subW = subDoc.canvas.width;\n const subH = subDoc.canvas.height;\n const resolved = resolveFrame(subDoc, stateName, frame);\n\n const subParts: string[] = [];\n for (const rl of resolved.layers) {\n const subEff = buildEffectiveLayer(rl, subW, subH);\n if (!subEff.visible || subEff.opacity <= 0) continue;\n\n // Resolve asset\n if (rl.layer.visual.type === \"image\") {\n const iv = subEff.visual as ImageVisual;\n if (!iv.src && iv.assetId && subDoc.assets?.[iv.assetId]) {\n iv.src = subDoc.assets[iv.assetId].src;\n }\n }\n\n const transform = buildTransform(subEff);\n const styleAttrs = buildStyleAttrs(subEff);\n const gAttrs: string[] = [];\n if (transform) gAttrs.push(`transform=\"${transform}\"`);\n if (styleAttrs) gAttrs.push(styleAttrs);\n\n let childContent = \"\";\n switch (rl.layer.visual.type) {\n case \"shape\": {\n const result = renderShapeSVG(subEff, subEff.visual as import(\"@a-company/atelier-types\").ShapeVisual);\n childContent = result.elements;\n break;\n }\n case \"text\":\n childContent = renderTextSVG(subEff, subEff.visual as import(\"@a-company/atelier-types\").TextVisual);\n break;\n case \"image\": {\n const iv = subEff.visual as ImageVisual;\n if (iv.src) {\n childContent = `<image href=\"${escapeXml(iv.src)}\" width=\"${subEff.width}\" height=\"${subEff.height}\" />`;\n }\n break;\n }\n case \"ref\": {\n const refV = subEff.visual as RefVisual;\n childContent = renderRefSVG(subEff, refV, subDoc, opts, depth + 1, visitedRefs);\n break;\n }\n }\n\n if (childContent) {\n const gOpen = gAttrs.length > 0 ? `<g ${gAttrs.join(\" \")}>` : \"<g>\";\n subParts.push(`${gOpen}${childContent}</g>`);\n }\n }\n\n visitedRefs.delete(visual.src);\n\n return `<svg x=\"0\" y=\"0\" width=\"${eff.width}\" height=\"${eff.height}\" viewBox=\"0 0 ${subW} ${subH}\">${subParts.join(\"\")}</svg>`;\n}\n","import type { EffectiveLayer } from \"@a-company/atelier-canvas\";\n\n/** Build SVG transform attribute from effective layer values */\nexport function buildTransform(eff: EffectiveLayer): string {\n const parts: string[] = [];\n\n // Translate to position\n if (eff.x !== 0 || eff.y !== 0) {\n parts.push(`translate(${eff.x}, ${eff.y})`);\n }\n\n const totalRotation = eff.rotation + eff.motionPathAngle;\n if (totalRotation !== 0 || eff.scaleX !== 1 || eff.scaleY !== 1) {\n const ax = eff.anchorX * eff.width;\n const ay = eff.anchorY * eff.height;\n\n // Move to anchor, apply rotation/scale, move back\n if (ax !== 0 || ay !== 0) {\n parts.push(`translate(${ax}, ${ay})`);\n }\n if (totalRotation !== 0) {\n parts.push(`rotate(${totalRotation})`);\n }\n if (eff.scaleX !== 1 || eff.scaleY !== 1) {\n parts.push(`scale(${eff.scaleX}, ${eff.scaleY})`);\n }\n if (ax !== 0 || ay !== 0) {\n parts.push(`translate(${-ax}, ${-ay})`);\n }\n }\n\n return parts.length > 0 ? parts.join(\" \") : \"\";\n}\n\n/** Build common SVG style attributes */\nexport function buildStyleAttrs(eff: EffectiveLayer): string {\n const attrs: string[] = [];\n\n if (eff.opacity < 1) {\n attrs.push(`opacity=\"${eff.opacity}\"`);\n }\n\n if (eff.blendMode !== \"normal\") {\n attrs.push(`style=\"mix-blend-mode: ${eff.blendMode}\"`);\n }\n\n return attrs.join(\" \");\n}\n\n/** Escape XML special characters */\nexport function escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n","import type { Fill, LinearGradientFill, RadialGradientFill, Color, RGBAColor, HSLAColor } from \"@a-company/atelier-types\";\n\nlet gradientIdCounter = 0;\n\nexport function resetGradientCounter(): void {\n gradientIdCounter = 0;\n}\n\n/** Convert an Atelier Color to a CSS color string */\nexport function colorToCSS(color: Color): string {\n if (typeof color === \"string\") return color;\n if (\"r\" in color) {\n const c = color as RGBAColor;\n return `rgba(${Math.round(c.r)}, ${Math.round(c.g)}, ${Math.round(c.b)}, ${c.a})`;\n }\n if (\"h\" in color) {\n const c = color as HSLAColor;\n return `hsla(${c.h}, ${c.s}%, ${c.l}%, ${c.a})`;\n }\n return \"#000000\";\n}\n\n/** Generate SVG gradient defs and return the fill reference */\nexport function buildGradientDef(fill: Fill, width: number, height: number): { defs: string; fillRef: string } {\n if (fill.type === \"solid\") {\n return { defs: \"\", fillRef: colorToCSS(fill.color) };\n }\n\n if (fill.type === \"linear-gradient\") {\n return buildLinearGradient(fill, width, height);\n }\n\n if (fill.type === \"radial-gradient\") {\n return buildRadialGradient(fill, width, height);\n }\n\n return { defs: \"\", fillRef: \"none\" };\n}\n\nfunction buildLinearGradient(fill: LinearGradientFill, _width: number, _height: number): { defs: string; fillRef: string } {\n const id = `grad-${++gradientIdCounter}`;\n const rad = (fill.angle * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n\n // Map angle to x1,y1,x2,y2 (0-1 percentages)\n const x1 = 0.5 - cos * 0.5;\n const y1 = 0.5 - sin * 0.5;\n const x2 = 0.5 + cos * 0.5;\n const y2 = 0.5 + sin * 0.5;\n\n const stops = fill.stops.map(s =>\n `<stop offset=\"${s.offset}\" stop-color=\"${colorToCSS(s.color)}\" />`\n ).join(\"\");\n\n const def = `<linearGradient id=\"${id}\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\">${stops}</linearGradient>`;\n return { defs: def, fillRef: `url(#${id})` };\n}\n\nfunction buildRadialGradient(fill: RadialGradientFill, width: number, height: number): { defs: string; fillRef: string } {\n const id = `grad-${++gradientIdCounter}`;\n\n const cx = typeof fill.center.x === \"number\" ? fill.center.x : (parseFloat(fill.center.x) / 100) * width;\n const cy = typeof fill.center.y === \"number\" ? fill.center.y : (parseFloat(fill.center.y) / 100) * height;\n const r = typeof fill.radius === \"number\" ? fill.radius : (parseFloat(fill.radius) / 100) * Math.max(width, height);\n\n const stops = fill.stops.map(s =>\n `<stop offset=\"${s.offset}\" stop-color=\"${colorToCSS(s.color)}\" />`\n ).join(\"\");\n\n const def = `<radialGradient id=\"${id}\" cx=\"${cx}\" cy=\"${cy}\" r=\"${r}\" gradientUnits=\"userSpaceOnUse\">${stops}</radialGradient>`;\n return { defs: def, fillRef: `url(#${id})` };\n}\n","import type { ShapeVisual, Shape, RectShape, PathShape, Stroke } from \"@a-company/atelier-types\";\nimport type { EffectiveLayer } from \"@a-company/atelier-canvas\";\nimport { buildGradientDef, colorToCSS } from \"./svg-gradients.js\";\n\n/** Render a shape visual as SVG elements */\nexport function renderShapeSVG(\n eff: EffectiveLayer,\n visual: ShapeVisual,\n): { elements: string; defs: string } {\n const { shape } = visual;\n const defs: string[] = [];\n\n let fillAttr = \"none\";\n if (visual.fill) {\n const gradResult = buildGradientDef(visual.fill, eff.width, eff.height);\n if (gradResult.defs) defs.push(gradResult.defs);\n fillAttr = gradResult.fillRef;\n }\n\n let strokeAttrs = \"\";\n if (visual.stroke) {\n strokeAttrs = buildStrokeAttrs(visual.stroke);\n }\n\n const element = buildShapeElement(shape, eff.width, eff.height, fillAttr, strokeAttrs);\n return { elements: element, defs: defs.join(\"\") };\n}\n\nfunction buildShapeElement(\n shape: Shape,\n width: number,\n height: number,\n fill: string,\n strokeAttrs: string,\n): string {\n switch (shape.type) {\n case \"rect\":\n return buildRectElement(shape, width, height, fill, strokeAttrs);\n case \"ellipse\":\n return buildEllipseElement(width, height, fill, strokeAttrs);\n case \"path\":\n return buildPathElement(shape, fill, strokeAttrs);\n }\n}\n\nfunction buildRectElement(\n shape: RectShape,\n width: number,\n height: number,\n fill: string,\n strokeAttrs: string,\n): string {\n let rx = \"\";\n if (shape.cornerRadius) {\n const r = typeof shape.cornerRadius === \"number\" ? shape.cornerRadius : shape.cornerRadius[0];\n rx = ` rx=\"${r}\" ry=\"${r}\"`;\n }\n return `<rect width=\"${width}\" height=\"${height}\" fill=\"${fill}\"${rx}${strokeAttrs ? \" \" + strokeAttrs : \"\"} />`;\n}\n\nfunction buildEllipseElement(\n width: number,\n height: number,\n fill: string,\n strokeAttrs: string,\n): string {\n const cx = width / 2;\n const cy = height / 2;\n const rx = width / 2;\n const ry = height / 2;\n return `<ellipse cx=\"${cx}\" cy=\"${cy}\" rx=\"${rx}\" ry=\"${ry}\" fill=\"${fill}\"${strokeAttrs ? \" \" + strokeAttrs : \"\"} />`;\n}\n\nfunction buildPathElement(\n shape: PathShape,\n fill: string,\n strokeAttrs: string,\n): string {\n if (shape.points.length < 2) return \"\";\n\n const d: string[] = [];\n d.push(`M ${shape.points[0].x} ${shape.points[0].y}`);\n\n for (let i = 1; i < shape.points.length; i++) {\n const prev = shape.points[i - 1];\n const curr = shape.points[i];\n\n if (prev.out && curr.in) {\n d.push(`C ${prev.x + prev.out.x} ${prev.y + prev.out.y} ${curr.x + curr.in.x} ${curr.y + curr.in.y} ${curr.x} ${curr.y}`);\n } else {\n d.push(`L ${curr.x} ${curr.y}`);\n }\n }\n\n if (shape.closed) d.push(\"Z\");\n\n return `<path d=\"${d.join(\" \")}\" fill=\"${fill}\"${strokeAttrs ? \" \" + strokeAttrs : \"\"} />`;\n}\n\nfunction buildStrokeAttrs(stroke: Stroke): string {\n const parts: string[] = [];\n parts.push(`stroke=\"${colorToCSS(stroke.color)}\"`);\n parts.push(`stroke-width=\"${stroke.width}\"`);\n\n if (stroke.lineCap) parts.push(`stroke-linecap=\"${stroke.lineCap}\"`);\n if (stroke.lineJoin) parts.push(`stroke-linejoin=\"${stroke.lineJoin}\"`);\n if (stroke.dash) parts.push(`stroke-dasharray=\"${stroke.dash.join(\" \")}\"`);\n\n return parts.join(\" \");\n}\n","import type { TextVisual } from \"@a-company/atelier-types\";\nimport type { EffectiveLayer } from \"@a-company/atelier-canvas\";\nimport { colorToCSS } from \"./svg-gradients.js\";\nimport { escapeXml } from \"./svg-properties.js\";\n\n/** Render a text visual as SVG elements */\nexport function renderTextSVG(eff: EffectiveLayer, visual: TextVisual): string {\n const { style } = visual;\n\n const attrs: string[] = [];\n\n // Font attributes\n attrs.push(`font-family=\"${escapeXml(style.fontFamily)}\"`);\n attrs.push(`font-size=\"${style.fontSize}\"`);\n\n if (style.fontWeight && style.fontWeight !== \"normal\") {\n attrs.push(`font-weight=\"${style.fontWeight}\"`);\n }\n if (style.fontStyle && style.fontStyle !== \"normal\") {\n attrs.push(`font-style=\"${style.fontStyle}\"`);\n }\n\n // Color\n attrs.push(`fill=\"${colorToCSS(style.color)}\"`);\n\n // Text alignment\n const align = style.textAlign ?? \"left\";\n let textAnchor = \"start\";\n let x = 0;\n if (align === \"center\") {\n textAnchor = \"middle\";\n x = eff.width / 2;\n } else if (align === \"right\") {\n textAnchor = \"end\";\n x = eff.width;\n }\n attrs.push(`text-anchor=\"${textAnchor}\"`);\n\n // Letter spacing\n if (style.letterSpacing) {\n attrs.push(`letter-spacing=\"${style.letterSpacing}\"`);\n }\n\n // SVG text baseline: use dominant-baseline for top alignment\n attrs.push(`dominant-baseline=\"hanging\"`);\n\n return `<text x=\"${x}\" y=\"0\" ${attrs.join(\" \")}>${escapeXml(visual.content)}</text>`;\n}\n","import type { EffectiveLayer } from \"@a-company/atelier-canvas\";\n\nlet filterIdCounter = 0;\n\nexport function resetFilterCounter(): void {\n filterIdCounter = 0;\n}\n\n/** Build SVG filter definition for shadow effects */\nexport function buildShadowFilter(eff: EffectiveLayer): { defs: string; filterRef: string } | null {\n if (!eff.shadow) return null;\n\n const id = `filter-${++filterIdCounter}`;\n const { color, blur, offsetX, offsetY } = eff.shadow;\n\n const def = [\n `<filter id=\"${id}\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">`,\n `<feDropShadow dx=\"${offsetX}\" dy=\"${offsetY}\" stdDeviation=\"${blur / 2}\" flood-color=\"${color}\" />`,\n `</filter>`,\n ].join(\"\");\n\n return { defs: def, filterRef: `url(#${id})` };\n}\n\n/** Build SVG filter definition for tint effect (feFlood + feBlend multiply) */\nexport function buildTintFilter(eff: EffectiveLayer): { defs: string; filterRef: string } | null {\n if (!eff.tint || eff.tint.amount <= 0) return null;\n\n const id = `filter-${++filterIdCounter}`;\n const { color, amount } = eff.tint;\n\n const def = [\n `<filter id=\"${id}\" x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">`,\n `<feFlood flood-color=\"${color}\" flood-opacity=\"${amount}\" result=\"tint\" />`,\n `<feBlend in=\"SourceGraphic\" in2=\"tint\" mode=\"multiply\" />`,\n `</filter>`,\n ].join(\"\");\n\n return { defs: def, filterRef: `url(#${id})` };\n}\n","import type { Shape } from \"@a-company/atelier-types\";\n\nlet clipIdCounter = 0;\n\nexport function resetClipCounter(): void {\n clipIdCounter = 0;\n}\n\n/** Build SVG clipPath definition */\nexport function buildClipPathDef(shape: Shape, width: number, height: number): { defs: string; clipRef: string } {\n const id = `clip-${++clipIdCounter}`;\n let pathContent = \"\";\n\n switch (shape.type) {\n case \"rect\":\n if (shape.cornerRadius) {\n const r = typeof shape.cornerRadius === \"number\" ? shape.cornerRadius : shape.cornerRadius[0];\n pathContent = `<rect width=\"${width}\" height=\"${height}\" rx=\"${r}\" ry=\"${r}\" />`;\n } else {\n pathContent = `<rect width=\"${width}\" height=\"${height}\" />`;\n }\n break;\n case \"ellipse\":\n pathContent = `<ellipse cx=\"${width / 2}\" cy=\"${height / 2}\" rx=\"${width / 2}\" ry=\"${height / 2}\" />`;\n break;\n case \"path\": {\n if (shape.points.length < 2) return { defs: \"\", clipRef: \"\" };\n const d: string[] = [];\n d.push(`M ${shape.points[0].x} ${shape.points[0].y}`);\n for (let i = 1; i < shape.points.length; i++) {\n const prev = shape.points[i - 1];\n const curr = shape.points[i];\n if (prev.out && curr.in) {\n d.push(`C ${prev.x + prev.out.x} ${prev.y + prev.out.y} ${curr.x + curr.in.x} ${curr.y + curr.in.y} ${curr.x} ${curr.y}`);\n } else {\n d.push(`L ${curr.x} ${curr.y}`);\n }\n }\n if (shape.closed) d.push(\"Z\");\n pathContent = `<path d=\"${d.join(\" \")}\" />`;\n break;\n }\n }\n\n const def = `<clipPath id=\"${id}\">${pathContent}</clipPath>`;\n return { defs: def, clipRef: `url(#${id})` };\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport { exportToLottie } from \"@a-company/atelier-lottie\";\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/** Register the `export-lottie` subcommand on the Commander program. */\nexport function exportLottieCommand(program: Command): void {\n program\n .command(\"export-lottie <file>\")\n .description(\"Export a document to Lottie JSON format\")\n .option(\"-s, --state <name>\", \"State name (defaults to first state)\")\n .option(\"-o, --output <path>\", \"Output file path (default: stdout)\")\n .action(\n (\n file: string,\n options: { state?: string; output?: string },\n ) => {\n const doc = readAndParse(file);\n\n try {\n const { json, warnings } = exportToLottie(doc, {\n state: options.state,\n });\n\n // Print warnings to stderr\n for (const warning of warnings) {\n console.error(`Warning: ${warning}`);\n }\n\n const output = JSON.stringify(json, null, 2);\n if (options.output) {\n writeFileSync(resolve(options.output), output, \"utf-8\");\n } else {\n console.log(output);\n }\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n },\n );\n}\n","import type { Color, RGBAColor, HSLAColor } from \"@a-company/atelier-types\";\n\n/** Convert an Atelier color to Lottie [r, g, b, a] format (0–1 range) */\nexport function colorToLottie(color: Color): number[] {\n if (typeof color === \"string\") {\n return hexToLottie(color);\n }\n\n if (\"r\" in color) {\n const c = color as RGBAColor;\n return [c.r / 255, c.g / 255, c.b / 255, c.a];\n }\n\n if (\"h\" in color) {\n const c = color as HSLAColor;\n const rgb = hslToRgb(c.h, c.s, c.l);\n return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, c.a];\n }\n\n return [0, 0, 0, 1];\n}\n\nfunction hexToLottie(hex: string): number[] {\n const clean = hex.replace(\"#\", \"\");\n if (clean.length === 3 || clean.length === 4) {\n const r = parseInt(clean[0] + clean[0], 16) / 255;\n const g = parseInt(clean[1] + clean[1], 16) / 255;\n const b = parseInt(clean[2] + clean[2], 16) / 255;\n const a = clean.length === 4 ? parseInt(clean[3] + clean[3], 16) / 255 : 1;\n return [r, g, b, a];\n }\n const r = parseInt(clean.slice(0, 2), 16) / 255;\n const g = parseInt(clean.slice(2, 4), 16) / 255;\n const b = parseInt(clean.slice(4, 6), 16) / 255;\n const a = clean.length === 8 ? parseInt(clean.slice(6, 8), 16) / 255 : 1;\n return [r, g, b, a];\n}\n\nfunction hslToRgb(h: number, s: number, l: number): [number, number, number] {\n s = s / 100;\n l = l / 100;\n const a = s * Math.min(l, 1 - l);\n const f = (n: number) => {\n const k = (n + h / 30) % 12;\n return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n };\n return [Math.round(f(0) * 255), Math.round(f(8) * 255), Math.round(f(4) * 255)];\n}\n","import type { ShapeVisual, Fill, Stroke } from \"@a-company/atelier-types\";\nimport type { LottieShapeItem } from \"./lottie-types.js\";\nimport { colorToLottie } from \"./map-colors.js\";\n\n/** Map an Atelier shape visual to Lottie shape items */\nexport function mapShapeVisual(\n visual: ShapeVisual,\n width: number,\n height: number,\n): LottieShapeItem[] {\n const items: LottieShapeItem[] = [];\n\n // Shape geometry\n switch (visual.shape.type) {\n case \"rect\":\n items.push({\n ty: \"rc\",\n nm: \"Rectangle\",\n d: 1,\n s: { a: 0, k: [width, height] },\n p: { a: 0, k: [width / 2, height / 2] },\n r: { a: 0, k: typeof visual.shape.cornerRadius === \"number\" ? visual.shape.cornerRadius : 0 },\n });\n break;\n case \"ellipse\":\n items.push({\n ty: \"el\",\n nm: \"Ellipse\",\n d: 1,\n s: { a: 0, k: [width, height] },\n p: { a: 0, k: [width / 2, height / 2] },\n });\n break;\n case \"path\": {\n const vertices = visual.shape.points.map(p => [p.x, p.y]);\n const inTangents = visual.shape.points.map(p => p.in ? [p.in.x, p.in.y] : [0, 0]);\n const outTangents = visual.shape.points.map(p => p.out ? [p.out.x, p.out.y] : [0, 0]);\n items.push({\n ty: \"sh\",\n nm: \"Path\",\n ks: {\n a: 0,\n k: {\n c: visual.shape.closed ?? false,\n v: vertices,\n i: inTangents,\n o: outTangents,\n },\n },\n });\n break;\n }\n }\n\n // Fill\n if (visual.fill) {\n items.push(mapFill(visual.fill, width, height));\n }\n\n // Stroke\n if (visual.stroke) {\n items.push(mapStroke(visual.stroke));\n }\n\n return items;\n}\n\nfunction mapFill(fill: Fill, _width: number, _height: number): LottieShapeItem {\n if (fill.type === \"solid\") {\n const color = colorToLottie(fill.color);\n return {\n ty: \"fl\",\n nm: \"Fill\",\n c: { a: 0, k: color.slice(0, 3) },\n o: { a: 0, k: (color[3] ?? 1) * 100 },\n r: 1,\n };\n }\n\n if (fill.type === \"linear-gradient\") {\n const stops: number[] = [];\n for (const stop of fill.stops) {\n const c = colorToLottie(stop.color);\n stops.push(stop.offset, c[0], c[1], c[2]);\n }\n return {\n ty: \"gf\",\n nm: \"Gradient Fill\",\n t: 1, // linear\n s: { a: 0, k: [0, 0] },\n e: { a: 0, k: [100, 0] },\n g: { p: fill.stops.length, k: { a: 0, k: stops } },\n r: 1,\n o: { a: 0, k: 100 },\n };\n }\n\n if (fill.type === \"radial-gradient\") {\n const stops: number[] = [];\n for (const stop of fill.stops) {\n const c = colorToLottie(stop.color);\n stops.push(stop.offset, c[0], c[1], c[2]);\n }\n return {\n ty: \"gf\",\n nm: \"Gradient Fill\",\n t: 2, // radial\n s: { a: 0, k: [50, 50] },\n e: { a: 0, k: [100, 50] },\n g: { p: fill.stops.length, k: { a: 0, k: stops } },\n r: 1,\n o: { a: 0, k: 100 },\n };\n }\n\n return { ty: \"fl\", nm: \"Fill\", c: { a: 0, k: [0, 0, 0] }, o: { a: 0, k: 100 }, r: 1 };\n}\n\nfunction mapStroke(stroke: Stroke): LottieShapeItem {\n const color = colorToLottie(stroke.color);\n return {\n ty: \"st\",\n nm: \"Stroke\",\n c: { a: 0, k: color.slice(0, 3) },\n o: { a: 0, k: (color[3] ?? 1) * 100 },\n w: { a: 0, k: stroke.width },\n lc: stroke.lineCap === \"round\" ? 2 : stroke.lineCap === \"square\" ? 3 : 1,\n lj: stroke.lineJoin === \"round\" ? 2 : stroke.lineJoin === \"bevel\" ? 3 : 1,\n };\n}\n","import type { Easing } from \"@a-company/atelier-types\";\n\nexport interface LottieEasing {\n i: { x: number[]; y: number[] };\n o: { x: number[]; y: number[] };\n}\n\n/** Map an Atelier easing to Lottie bezier easing curves */\nexport function mapEasing(easing: Easing | undefined): LottieEasing | { h: 1 } {\n if (!easing) return linearEasing();\n\n if (typeof easing === \"string\") {\n switch (easing) {\n case \"ease-in\":\n return bezierEasing(0.42, 0, 1, 1);\n case \"ease-out\":\n return bezierEasing(0, 0, 0.58, 1);\n case \"ease-in-out\":\n return bezierEasing(0.42, 0, 0.58, 1);\n default:\n return linearEasing();\n }\n }\n\n switch (easing.type) {\n case \"linear\":\n return linearEasing();\n case \"cubic-bezier\":\n return bezierEasing(easing.x1, easing.y1, easing.x2, easing.y2);\n case \"spring\":\n // Approximate spring as a cubic-bezier (lossy)\n return bezierEasing(0.25, 0.1, 0.25, 1);\n case \"step\":\n // Steps map to hold keyframes\n return { h: 1 };\n default:\n return linearEasing();\n }\n}\n\nfunction linearEasing(): LottieEasing {\n return {\n i: { x: [0.833], y: [0.833] },\n o: { x: [0.167], y: [0.167] },\n };\n}\n\nfunction bezierEasing(x1: number, y1: number, x2: number, y2: number): LottieEasing {\n return {\n i: { x: [x2], y: [y2] },\n o: { x: [x1], y: [y1] },\n };\n}\n\n/** Check if an easing is lossy (spring/step → approximated) */\nexport function isLossyEasing(easing: Easing | undefined): string | null {\n if (!easing || typeof easing === \"string\") return null;\n if (easing.type === \"spring\") return \"Spring easing approximated as cubic-bezier\";\n if (easing.type === \"step\") return \"Step easing mapped to hold keyframes\";\n return null;\n}\n","import type { Delta, AnimatableProperty } from \"@a-company/atelier-types\";\nimport type { LottieAnimatedValue, LottieAnimatedMultiValue, LottieKeyframe, LottieMultiKeyframe } from \"./lottie-types.js\";\nimport { mapEasing, isLossyEasing } from \"./map-easing.js\";\n\n/** Map deltas for a single layer+property to Lottie animated value */\nexport function mapDeltasToAnimated(\n deltas: Delta[],\n property: AnimatableProperty,\n warnings: string[],\n): LottieAnimatedValue {\n if (deltas.length === 0) {\n return { a: 0, k: 0 };\n }\n\n // Check for lossy easings\n for (const d of deltas) {\n const lossyMsg = isLossyEasing(d.easing);\n if (lossyMsg) warnings.push(`${property}: ${lossyMsg}`);\n }\n\n // If expressions, warn and use static\n for (const d of deltas) {\n if (isExpression(d.from) || isExpression(d.to)) {\n warnings.push(`${property}: Expression values not supported in Lottie, using static values`);\n return { a: 0, k: typeof d.from === \"number\" ? d.from : 0 };\n }\n }\n\n // Single delta — simple animated value\n if (deltas.length === 1) {\n const d = deltas[0];\n const fromVal = resolveValue(d.from, property);\n const toVal = resolveValue(d.to, property);\n\n if (fromVal === toVal) {\n return { a: 0, k: fromVal };\n }\n\n const easing = mapEasing(d.easing);\n const kfs: LottieKeyframe[] = [];\n\n if (\"h\" in easing) {\n kfs.push({ t: d.range[0], s: [fromVal], h: 1 });\n kfs.push({ t: d.range[1], s: [toVal] });\n } else {\n kfs.push({ t: d.range[0], s: [fromVal], e: [toVal], i: easing.i, o: easing.o });\n kfs.push({ t: d.range[1], s: [toVal] });\n }\n\n return { a: 1, k: kfs };\n }\n\n // Multiple deltas — chain keyframes\n const sorted = [...deltas].sort((a, b) => a.range[0] - b.range[0]);\n const kfs: LottieKeyframe[] = [];\n\n for (const d of sorted) {\n const fromVal = resolveValue(d.from, property);\n const toVal = resolveValue(d.to, property);\n const easing = mapEasing(d.easing);\n\n if (\"h\" in easing) {\n kfs.push({ t: d.range[0], s: [fromVal], h: 1 });\n } else {\n kfs.push({ t: d.range[0], s: [fromVal], e: [toVal], i: easing.i, o: easing.o });\n }\n }\n\n // Final keyframe\n const last = sorted[sorted.length - 1];\n kfs.push({ t: last.range[1], s: [resolveValue(last.to, property)] });\n\n return { a: 1, k: kfs };\n}\n\n/** Map position deltas (frame.x, frame.y) to Lottie multi-dimensional animated value */\nexport function mapPositionDeltas(\n xDeltas: Delta[],\n yDeltas: Delta[],\n baseX: number,\n baseY: number,\n warnings: string[],\n): LottieAnimatedMultiValue {\n const hasXAnim = xDeltas.length > 0;\n const hasYAnim = yDeltas.length > 0;\n\n if (!hasXAnim && !hasYAnim) {\n return { a: 0, k: [baseX, baseY, 0] };\n }\n\n // Collect all unique frame points\n const frames = new Set<number>();\n for (const d of [...xDeltas, ...yDeltas]) {\n frames.add(d.range[0]);\n frames.add(d.range[1]);\n }\n const sortedFrames = [...frames].sort((a, b) => a - b);\n\n if (sortedFrames.length < 2) {\n return { a: 0, k: [baseX, baseY, 0] };\n }\n\n // Build multi-dimensional keyframes\n const kfs: LottieMultiKeyframe[] = [];\n for (let i = 0; i < sortedFrames.length; i++) {\n const f = sortedFrames[i];\n const x = resolveAtFrame(xDeltas, f, baseX);\n const y = resolveAtFrame(yDeltas, f, baseY);\n\n if (i < sortedFrames.length - 1) {\n const nextF = sortedFrames[i + 1];\n const nextX = resolveAtFrame(xDeltas, nextF, baseX);\n const nextY = resolveAtFrame(yDeltas, nextF, baseY);\n\n // Find the active delta's easing\n const activeX = xDeltas.find(d => d.range[0] <= f && d.range[1] >= f);\n const activeY = yDeltas.find(d => d.range[0] <= f && d.range[1] >= f);\n const easing = mapEasing(activeX?.easing ?? activeY?.easing);\n\n if (\"h\" in easing) {\n kfs.push({ t: f, s: [x, y, 0], h: 1 });\n } else {\n kfs.push({ t: f, s: [x, y, 0], e: [nextX, nextY, 0], i: easing.i, o: easing.o });\n }\n } else {\n kfs.push({ t: f, s: [x, y, 0] });\n }\n }\n\n // Check for lossy warnings\n for (const d of [...xDeltas, ...yDeltas]) {\n const msg = isLossyEasing(d.easing);\n if (msg) warnings.push(`position: ${msg}`);\n }\n\n return { a: 1, k: kfs };\n}\n\nfunction resolveAtFrame(deltas: Delta[], frame: number, base: number): number {\n for (const d of deltas) {\n if (frame >= d.range[0] && frame <= d.range[1]) {\n const from = typeof d.from === \"number\" ? d.from : base;\n const to = typeof d.to === \"number\" ? d.to : base;\n const progress = d.range[0] === d.range[1] ? 1 : (frame - d.range[0]) / (d.range[1] - d.range[0]);\n return from + (to - from) * progress;\n }\n }\n // Hold last completed value\n let lastCompleted: Delta | undefined;\n for (const d of deltas) {\n if (frame > d.range[1]) {\n if (!lastCompleted || d.range[1] > lastCompleted.range[1]) {\n lastCompleted = d;\n }\n }\n }\n if (lastCompleted) return typeof lastCompleted.to === \"number\" ? lastCompleted.to : base;\n return base;\n}\n\nfunction resolveValue(val: unknown, _property: AnimatableProperty): number {\n if (typeof val === \"number\") return val;\n if (typeof val === \"string\" && val.startsWith(\"#\")) {\n // Color — for Lottie, colors are handled separately\n return 0;\n }\n return 0;\n}\n\nfunction isExpression(val: unknown): boolean {\n return typeof val === \"object\" && val !== null && \"expr\" in val;\n}\n","import type { AtelierDocument, Layer, Delta, State, UnitValue } from \"@a-company/atelier-types\";\nimport type { LottieLayer, LottieTransform, LottieTextData } from \"./lottie-types.js\";\nimport { mapShapeVisual } from \"./map-shapes.js\";\nimport { mapDeltasToAnimated, mapPositionDeltas } from \"./map-keyframes.js\";\nimport { colorToLottie } from \"./map-colors.js\";\n\n/** Resolve a UnitValue to a plain number (percentages treated as 0 for Lottie) */\nfunction toNum(v: UnitValue): number {\n return typeof v === \"number\" ? v : 0;\n}\n\n/** Map all layers in a document+state to Lottie layers */\nexport function mapLayers(\n doc: AtelierDocument,\n state: State,\n warnings: string[],\n): LottieLayer[] {\n const layerIndexMap = new Map<string, number>();\n doc.layers.forEach((l, i) => layerIndexMap.set(l.id, i));\n\n return doc.layers.map((layer, index) => {\n const deltas = state.deltas.filter(d => d.layer === layer.id);\n return mapLayer(layer, index, deltas, layerIndexMap, doc, warnings);\n });\n}\n\nfunction mapLayer(\n layer: Layer,\n index: number,\n deltas: Delta[],\n layerIndexMap: Map<string, number>,\n doc: AtelierDocument,\n warnings: string[],\n): LottieLayer {\n const duration = getMaxFrame(deltas, doc);\n\n const base: LottieLayer = {\n ty: getLayerType(layer),\n nm: layer.id,\n ind: index,\n ip: 0,\n op: duration,\n st: 0,\n ks: buildTransform(layer, deltas, warnings),\n };\n\n // Parent\n if (layer.parentId) {\n const parentIdx = layerIndexMap.get(layer.parentId);\n if (parentIdx !== undefined) {\n base.parent = parentIdx;\n }\n }\n\n // Blend mode\n if (layer.blendMode) {\n base.bm = mapBlendMode(layer.blendMode);\n }\n\n // Shape layer\n if (layer.visual.type === \"shape\") {\n base.shapes = mapShapeVisual(layer.visual, toNum(layer.bounds.width), toNum(layer.bounds.height));\n }\n\n // Text layer\n if (layer.visual.type === \"text\") {\n const color = colorToLottie(layer.visual.style.color);\n base.t = {\n d: {\n k: [{\n s: {\n s: layer.visual.style.fontSize,\n f: layer.visual.style.fontFamily,\n t: layer.visual.content,\n fc: color.slice(0, 3),\n j: layer.visual.style.textAlign === \"center\" ? 1 :\n layer.visual.style.textAlign === \"right\" ? 2 : 0,\n },\n t: 0,\n }],\n },\n } as LottieTextData;\n }\n\n // Image layer\n if (layer.visual.type === \"image\") {\n base.refId = layer.visual.assetId;\n base.w = toNum(layer.bounds.width);\n base.h = toNum(layer.bounds.height);\n\n if (layer.visual.spritesheet) {\n warnings.push(`Layer \"${layer.id}\": Spritesheet animation not supported in Lottie export`);\n }\n if (layer.visual.sourceRect) {\n warnings.push(`Layer \"${layer.id}\": sourceRect cropping not supported in Lottie export`);\n }\n }\n\n // Tint warning\n if (layer.tint && layer.tint.amount > 0) {\n warnings.push(`Layer \"${layer.id}\": Tint effect not supported in Lottie export`);\n }\n\n return base;\n}\n\nfunction getLayerType(layer: Layer): number {\n switch (layer.visual.type) {\n case \"shape\": return 4;\n case \"text\": return 5;\n case \"image\": return 2;\n case \"group\": return 3; // null layer\n case \"ref\": return 0; // precomp\n default: return 4;\n }\n}\n\nfunction buildTransform(\n layer: Layer,\n deltas: Delta[],\n warnings: string[],\n): LottieTransform {\n // Group deltas by property\n const byProp = new Map<string, Delta[]>();\n for (const d of deltas) {\n if (!byProp.has(d.property)) byProp.set(d.property, []);\n byProp.get(d.property)!.push(d);\n }\n\n const xDeltas = byProp.get(\"frame.x\") ?? [];\n const yDeltas = byProp.get(\"frame.y\") ?? [];\n const opacityDeltas = byProp.get(\"opacity\") ?? [];\n const rotationDeltas = byProp.get(\"rotation\") ?? [];\n const scaleXDeltas = byProp.get(\"scale.x\") ?? [];\n const scaleYDeltas = byProp.get(\"scale.y\") ?? [];\n\n // Position\n const position = mapPositionDeltas(\n xDeltas, yDeltas,\n typeof layer.frame.x === \"number\" ? layer.frame.x : 0,\n typeof layer.frame.y === \"number\" ? layer.frame.y : 0,\n warnings,\n );\n\n // Opacity (Lottie uses 0–100)\n let opacity;\n if (opacityDeltas.length > 0) {\n const raw = mapDeltasToAnimated(opacityDeltas, \"opacity\", warnings);\n // Scale 0-1 to 0-100\n if (raw.a === 0) {\n opacity = { a: 0 as const, k: (raw.k as number) * 100 };\n } else {\n const kfs = (raw.k as Array<{ t: number; s: [number]; e?: [number]; [key: string]: unknown }>).map(kf => ({\n ...kf,\n s: [kf.s[0] * 100] as [number],\n e: kf.e ? [kf.e[0] * 100] as [number] : undefined,\n }));\n opacity = { a: 1 as const, k: kfs };\n }\n } else {\n opacity = { a: 0 as const, k: (layer.opacity ?? 1) * 100 };\n }\n\n // Rotation\n const rotation = rotationDeltas.length > 0\n ? mapDeltasToAnimated(rotationDeltas, \"rotation\", warnings)\n : { a: 0 as const, k: layer.rotation ?? 0 };\n\n // Scale (Lottie uses 0–100)\n const baseScaleX = (layer.scale?.x ?? 1) * 100;\n const baseScaleY = (layer.scale?.y ?? 1) * 100;\n let scale;\n if (scaleXDeltas.length > 0 || scaleYDeltas.length > 0) {\n // Simplified: use x deltas for now\n scale = { a: 0 as const, k: [baseScaleX, baseScaleY, 100] };\n if (scaleXDeltas.length > 0 || scaleYDeltas.length > 0) {\n warnings.push(\"Scale animation partially mapped to Lottie\");\n }\n } else {\n scale = { a: 0 as const, k: [baseScaleX, baseScaleY, 100] };\n }\n\n // Anchor point\n const ax = (layer.anchorPoint?.x ?? 0) * toNum(layer.bounds.width);\n const ay = (layer.anchorPoint?.y ?? 0) * toNum(layer.bounds.height);\n\n return {\n o: opacity,\n r: rotation,\n p: position,\n a: { a: 0, k: [ax, ay, 0] },\n s: scale,\n };\n}\n\nfunction getMaxFrame(deltas: Delta[], doc: AtelierDocument): number {\n let max = 0;\n for (const state of Object.values(doc.states)) {\n if (state.duration > max) max = state.duration;\n }\n for (const d of deltas) {\n if (d.range[1] > max) max = d.range[1];\n }\n return max || 60;\n}\n\nfunction mapBlendMode(mode: string): number {\n const map: Record<string, number> = {\n normal: 0, multiply: 1, screen: 2, overlay: 3,\n darken: 4, lighten: 5, \"color-dodge\": 6, \"color-burn\": 7,\n \"hard-light\": 8, \"soft-light\": 9, difference: 10, exclusion: 11,\n hue: 12, saturation: 13, color: 14, luminosity: 15,\n };\n return map[mode] ?? 0;\n}\n","import type { AtelierDocument, State } from \"@a-company/atelier-types\";\n\n/** Check for unsupported features and collect warnings */\nexport function collectUnsupportedWarnings(doc: AtelierDocument, state: State): string[] {\n const warnings: string[] = [];\n\n // Audio not supported\n if (state.audio) {\n warnings.push(\"Audio tracks are not supported in Lottie format and will be dropped\");\n }\n\n // Expressions not supported\n for (const delta of state.deltas) {\n if (isExpression(delta.from) || isExpression(delta.to)) {\n warnings.push(`Expression values on \"${delta.layer}.${delta.property}\" not supported in Lottie`);\n }\n }\n\n // Shadow not supported in base Lottie\n for (const layer of doc.layers) {\n if (layer.shadow) {\n warnings.push(`Shadow on layer \"${layer.id}\" is not supported in base Lottie format`);\n }\n }\n\n // Motion path not directly mapped\n for (const layer of doc.layers) {\n if (layer.motionPath) {\n warnings.push(`Motion path on layer \"${layer.id}\" is not directly mappable to Lottie`);\n }\n }\n\n // Clip paths have limited support\n for (const layer of doc.layers) {\n if (layer.clipPath) {\n warnings.push(`Clip path on layer \"${layer.id}\" mapped as Lottie mask (partial support)`);\n }\n }\n\n // States/transitions\n if (Object.keys(doc.states).length > 1) {\n warnings.push(\"Multiple states flattened to single timeline in Lottie export\");\n }\n\n return warnings;\n}\n\nfunction isExpression(val: unknown): boolean {\n return typeof val === \"object\" && val !== null && \"expr\" in val;\n}\n","import type { AtelierDocument } from \"@a-company/atelier-types\";\nimport type { LottieAnimation, LottieAsset } from \"./lottie-types.js\";\nimport { mapLayers } from \"./map-layers.js\";\nimport { collectUnsupportedWarnings } from \"./warnings.js\";\n\nexport interface ExportLottieOptions {\n /** State to export (defaults to first state) */\n state?: string;\n}\n\nexport interface ExportLottieResult {\n /** The Lottie JSON animation */\n json: LottieAnimation;\n /** Warnings about unsupported features */\n warnings: string[];\n}\n\n/**\n * Export an Atelier document to Lottie JSON format.\n * This is a lossy conversion — not all features are supported.\n */\nexport function exportToLottie(\n doc: AtelierDocument,\n opts?: ExportLottieOptions,\n): ExportLottieResult {\n const stateNames = Object.keys(doc.states);\n if (stateNames.length === 0) {\n throw new Error(\"Document has no states to export\");\n }\n\n const stateName = opts?.state ?? stateNames[0];\n const state = doc.states[stateName];\n if (!state) {\n throw new Error(`State \"${stateName}\" not found`);\n }\n\n const warnings: string[] = [];\n\n // Collect unsupported feature warnings\n warnings.push(...collectUnsupportedWarnings(doc, state));\n\n // Map layers\n const layers = mapLayers(doc, state, warnings);\n\n // Map assets\n const assets: LottieAsset[] = [];\n if (doc.assets) {\n for (const [id, asset] of Object.entries(doc.assets)) {\n if (asset.type === \"image\") {\n assets.push({\n id,\n w: 100,\n h: 100,\n p: asset.src,\n e: 0,\n });\n }\n }\n }\n\n const json: LottieAnimation = {\n v: \"5.7.4\",\n fr: doc.canvas.fps,\n ip: 0,\n op: state.duration,\n w: doc.canvas.width,\n h: doc.canvas.height,\n nm: doc.name,\n layers,\n ...(assets.length > 0 ? { assets } : {}),\n };\n\n // Deduplicate warnings\n const uniqueWarnings = [...new Set(warnings)];\n\n return { json, warnings: uniqueWarnings };\n}\n","import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument, ImageVisual } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\n\n/** Asset summary entry */\nexport interface AssetInfo {\n assetId: string;\n type: string;\n src: string;\n description?: string;\n usedByLayers: string[];\n usedByStates: string[];\n}\n\n/**\n * Extract asset info from a parsed AtelierDocument.\n */\nexport function getAssets(doc: AtelierDocument): AssetInfo[] {\n const assets = doc.assets ?? {};\n return Object.entries(assets).map(([assetId, asset]) => {\n const usedByLayers = doc.layers\n .filter(l => l.visual.type === \"image\" && (l.visual as ImageVisual).assetId === assetId)\n .map(l => l.id);\n\n const usedByStates = Object.entries(doc.states)\n .filter(([, state]) => state.audio?.src === assetId)\n .map(([name]) => name);\n\n return {\n assetId,\n type: asset.type,\n src: asset.src,\n description: asset.description,\n usedByLayers,\n usedByStates,\n };\n });\n}\n\n/**\n * Format asset info for terminal output.\n */\nfunction formatAssets(assets: AssetInfo[]): string {\n if (assets.length === 0) return \"No assets registered.\";\n\n const lines: string[] = [`Assets: ${assets.length}`];\n for (const a of assets) {\n const desc = a.description ? ` — ${a.description}` : \"\";\n lines.push(` - ${a.assetId} (${a.type}): ${a.src}${desc}`);\n if (a.usedByLayers.length > 0) {\n lines.push(` Layers: ${a.usedByLayers.join(\", \")}`);\n }\n if (a.usedByStates.length > 0) {\n lines.push(` States: ${a.usedByStates.join(\", \")}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/**\n * Register the `assets` subcommand on the Commander program.\n */\nexport function assetsCommand(program: Command): void {\n program\n .command(\"assets <file>\")\n .description(\"List all assets in an .atelier file with usage info\")\n .action((file: string) => {\n const doc = readAndParse(file);\n const assets = getAssets(doc);\n console.log(formatAssets(assets));\n });\n}\n","import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport type { AtelierDocument } from \"@a-company/atelier-types\";\nimport { parseAtelier } from \"@a-company/atelier-schema\";\nimport { findTemplateVariables } from \"@a-company/atelier-core\";\n\n/** Variable summary entry */\nexport interface VariableInfo {\n name: string;\n type: string;\n description?: string;\n default?: unknown;\n referenced: boolean;\n}\n\n/**\n * Extract variable info from a parsed AtelierDocument.\n */\nexport function getVariables(doc: AtelierDocument): { variables: VariableInfo[]; undeclared: string[] } {\n const variables = doc.variables ?? {};\n const referenced = findTemplateVariables(doc);\n\n const entries = Object.entries(variables).map(([name, variable]) => ({\n name,\n type: variable.type,\n description: variable.description,\n default: variable.default,\n referenced: referenced.includes(name),\n }));\n\n const undeclared = referenced.filter(r => !variables[r]);\n\n return { variables: entries, undeclared };\n}\n\n/**\n * Format variable info for terminal output.\n */\nfunction formatVariables(info: { variables: VariableInfo[]; undeclared: string[] }): string {\n if (info.variables.length === 0 && info.undeclared.length === 0) return \"No variables declared or referenced.\";\n\n const lines: string[] = [];\n\n if (info.variables.length > 0) {\n lines.push(`Variables: ${info.variables.length}`);\n for (const v of info.variables) {\n const desc = v.description ? ` — ${v.description}` : \"\";\n const def = v.default !== undefined ? ` [default: ${JSON.stringify(v.default)}]` : \"\";\n const ref = v.referenced ? \"\" : \" (unused)\";\n lines.push(` - {{${v.name}}} (${v.type})${def}${desc}${ref}`);\n }\n }\n\n if (info.undeclared.length > 0) {\n lines.push(`Undeclared references: ${info.undeclared.length}`);\n for (const name of info.undeclared) {\n lines.push(` - {{${name}}} (not declared in variables)`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Read and parse an .atelier file, exiting on failure. */\nfunction readAndParse(file: string): AtelierDocument {\n const absPath = resolve(file);\n let content: string;\n try {\n content = readFileSync(absPath, \"utf-8\");\n } catch {\n console.error(`Cannot read file: ${absPath}`);\n return process.exit(1);\n }\n\n const result = parseAtelier(content);\n if (!result.success) {\n console.error(\"Parse errors:\");\n for (const error of result.errors) {\n console.error(` - ${error.path}: ${error.message}`);\n }\n return process.exit(1);\n }\n\n return result.data;\n}\n\n/**\n * Register the `variables` subcommand on the Commander program.\n */\nexport function variablesCommand(program: Command): void {\n program\n .command(\"variables <file>\")\n .description(\"List all variables in an .atelier file with usage info\")\n .action((file: string) => {\n const doc = readAndParse(file);\n const info = getVariables(doc);\n console.log(formatVariables(info));\n });\n}\n"],"mappings":"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","names":["init_dist","import_zod","z","yamlParse","init_dist","import_node_fs","import_node_path","import_node_fs","import_node_path","init_dist","readAndParse","renderFrame","import_node_fs","import_node_path","init_dist","resolve","readAndParse","import_node_fs","import_node_path","init_dist","colorToCSS","readAndParse","import_node_fs","import_node_path","r","g","b","a","isExpression","kfs","buildTransform","readAndParse","import_node_fs","import_node_path","readAndParse","import_node_fs","import_node_path","init_dist","readAndParse"]}
|