@pixerate/flair 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +1 -0
- package/dist/catalog/index.js +2 -2
- package/dist/{chunk-WAMA45G3.js → chunk-5USSDEQL.js} +77 -21
- package/dist/chunk-5USSDEQL.js.map +1 -0
- package/dist/{chunk-GTIAOYOK.js → chunk-74ZLCZOG.js} +13 -10
- package/dist/chunk-74ZLCZOG.js.map +1 -0
- package/dist/{chunk-NGKNI3QX.js → chunk-CK6EV37I.js} +19 -495
- package/dist/chunk-CK6EV37I.js.map +1 -0
- package/dist/chunk-DBTLCXKY.js +332 -0
- package/dist/chunk-DBTLCXKY.js.map +1 -0
- package/dist/chunk-G2B5L234.js +414 -0
- package/dist/chunk-G2B5L234.js.map +1 -0
- package/dist/{chunk-VP6IEWIK.js → chunk-H6L67KHI.js} +1 -1
- package/dist/chunk-H6VDFBIO.js +498 -0
- package/dist/chunk-H6VDFBIO.js.map +1 -0
- package/dist/{chunk-OQ4EWZ3B.js → chunk-HVXWNGTW.js} +83 -6
- package/dist/{chunk-OQ4EWZ3B.js.map → chunk-HVXWNGTW.js.map} +1 -1
- package/dist/chunk-JL6TI6II.js +724 -0
- package/dist/chunk-JL6TI6II.js.map +1 -0
- package/dist/{chunk-OHW7UG6D.js → chunk-ORAFCHX3.js} +26 -2
- package/dist/{chunk-OHW7UG6D.js.map → chunk-ORAFCHX3.js.map} +1 -1
- package/dist/{chunk-ARKC7LDW.js → chunk-RDU63CDO.js} +2 -331
- package/dist/chunk-RDU63CDO.js.map +1 -0
- package/dist/{chunk-LVPIIWPP.js → chunk-STKEKXCK.js} +18 -8
- package/dist/chunk-STKEKXCK.js.map +1 -0
- package/dist/chunk-UCZ43ARE.js +902 -0
- package/dist/chunk-UCZ43ARE.js.map +1 -0
- package/dist/chunk-YBGRXVAE.js +407 -0
- package/dist/chunk-YBGRXVAE.js.map +1 -0
- package/dist/cli.js +74 -11
- package/dist/cli.js.map +1 -1
- package/dist/editor/index.d.ts +1 -1
- package/dist/editor/index.js +14 -12
- package/dist/editor/index.js.map +1 -1
- package/dist/effect-GGH3OSOT.js +47 -0
- package/dist/embed/index.d.ts +215 -0
- package/dist/embed/index.js +21 -0
- package/dist/{export-DH2HMACO.js → export-QVW474KM.js} +3 -3
- package/dist/export-QVW474KM.js.map +1 -0
- package/dist/frames-VEcqa40g.d.ts +161 -0
- package/dist/index.d.ts +47 -164
- package/dist/index.js +102 -80
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +167 -7
- package/dist/node.js +25 -3
- package/dist/react/index.d.ts +33 -2
- package/dist/react/index.js +54 -9
- package/dist/react/index.js.map +1 -1
- package/dist/recorder-CDPPTJMG.js +31 -0
- package/dist/recorder-CDPPTJMG.js.map +1 -0
- package/dist/{renderer-C2P1qGzP.d.ts → renderer-teaa98RE.d.ts} +1 -1
- package/dist/svelte/index.d.ts +33 -4
- package/dist/svelte/index.js +51 -9
- package/dist/svelte/index.js.map +1 -1
- package/dist/vector/index.d.ts +52 -1
- package/dist/vector/index.js +8 -4
- package/package.json +1 -1
- package/dist/chunk-ARKC7LDW.js.map +0 -1
- package/dist/chunk-GTIAOYOK.js.map +0 -1
- package/dist/chunk-LVPIIWPP.js.map +0 -1
- package/dist/chunk-NGKNI3QX.js.map +0 -1
- package/dist/chunk-UP6QQVRS.js +0 -331
- package/dist/chunk-UP6QQVRS.js.map +0 -1
- package/dist/chunk-WAMA45G3.js.map +0 -1
- package/dist/recorder-HKFFHQES.js +0 -10
- /package/dist/{chunk-VP6IEWIK.js.map → chunk-H6L67KHI.js.map} +0 -0
- /package/dist/{export-DH2HMACO.js.map → effect-GGH3OSOT.js.map} +0 -0
- /package/dist/{recorder-HKFFHQES.js.map → embed/index.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/export/motn.ts","../src/export/lottie.ts","../src/export/interchange.ts"],"sourcesContent":["import type { Scene, Shot } from '../scene/types.js';\nimport { DEFAULT_STAGE, DEFAULT_PERSPECTIVE, centreOf, isAngled, type View } from '../scene/camera.js';\nimport { cameraSamples, shotMoveMs, sceneStage, type CameraSample } from '../scene/cameratrack.js';\nimport { isElementCommand } from '../scene/types.js';\n\nexport interface MotnExportOptions {\n frameRate?: number;\n}\n\nfunction escapeXml(unsafe: string): string {\n return unsafe\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nconst r3 = (n: number) => Math.round(n * 1000) / 1000;\n\n/** A parameter, keyframed (linear, at frames) when the samples change and static when they do not. */\nfunction curveParameter(name: string, id: number, samples: readonly CameraSample[], value: (v: View) => number, indent: string): string[] {\n const values = samples.map((x) => r3(value(x.view)));\n if (values.every((v) => v === values[0])) return [`${indent}<parameter name=\"${name}\" id=\"${id}\" value=\"${values[0]}\"/>`];\n return [\n `${indent}<parameter name=\"${name}\" id=\"${id}\" value=\"${values[0]}\">`,\n `${indent} <curve type=\"1\" default=\"${values[0]}\" value=\"${values[0]}\">`,\n ...samples.map((x, i) => `${indent} <keypoint interpolation=\"1\"><time>${x.frame}</time><value>${values[i]}</value></keypoint>`),\n `${indent} </curve>`,\n `${indent}</parameter>`,\n ];\n}\n\n/**\n * The scene's camera as a group the shot groups sit in: its anchor point is\n * the camera's centre, its scale the zoom and its rotations the angle\n * (Motion's y points up, so tilt and roll turn the other way), keyframed\n * every other frame through each move. The perspective distance and each\n * move's motion blur are noted in comments: set them on a Motion camera and\n * in the render settings.\n */\nfunction cameraGroupOpen(scene: Scene, frameRate: number, totalFrames: number, id: number): string[] {\n const stage = sceneStage(scene);\n const samples = cameraSamples(scene, frameRate);\n const angled = samples.some((x) => isAngled(x.view));\n const lines = [` <group name=\"Camera\" id=\"${id}\">`];\n if (angled) {\n const distance = r3((samples.find((x) => x.view.perspective)?.view.perspective ?? DEFAULT_PERSPECTIVE) * stage.width);\n lines.push(` <!-- 3D group: view it through a camera ${distance}px from the canvas -->`);\n }\n for (const shot of scene.shots) {\n const transition = shot.camera?.transition;\n if (transition && transition !== 'move') lines.push(` <!-- ${escapeXml(shot.title ?? 'Shot')}: ${transition} in -->`);\n if (shot.camera?.motionBlur) lines.push(` <!-- ${escapeXml(shot.title ?? 'Shot')}: motion blur ${shot.camera.motionBlur} on the move in -->`);\n }\n lines.push(` <timing in=\"0\" out=\"${totalFrames - 1}\" offset=\"0\"/>`);\n lines.push(' <parameter name=\"Properties\" id=\"1\">');\n lines.push(' <parameter name=\"Transform\" id=\"100\">');\n lines.push(' <parameter name=\"Position\" id=\"101\">');\n lines.push(' <parameter name=\"X\" id=\"1\" value=\"0\"/>');\n lines.push(' <parameter name=\"Y\" id=\"2\" value=\"0\"/>');\n lines.push(' </parameter>');\n lines.push(' <parameter name=\"Scale\" id=\"102\">');\n lines.push(...curveParameter('X', 1, samples, (v) => v.zoom * 100, ' '));\n lines.push(...curveParameter('Y', 2, samples, (v) => v.zoom * 100, ' '));\n lines.push(' </parameter>');\n lines.push(' <parameter name=\"Rotation\" id=\"103\">');\n lines.push(...curveParameter('X', 1, samples, (v) => 0 - (v.tilt ?? 0), ' '));\n lines.push(...curveParameter('Y', 2, samples, (v) => v.turn ?? 0, ' '));\n lines.push(...curveParameter('Z', 3, samples, (v) => 0 - (v.roll ?? 0), ' '));\n lines.push(' </parameter>');\n lines.push(' <parameter name=\"Anchor Point\" id=\"104\">');\n lines.push(...curveParameter('X', 1, samples, (v) => centreOf(v, stage)[0], ' '));\n lines.push(...curveParameter('Y', 2, samples, (v) => 0 - centreOf(v, stage)[1], ' '));\n lines.push(' </parameter>');\n lines.push(' </parameter>');\n lines.push(' </parameter>');\n return lines;\n}\n\n/**\n * Serializes a Flair Scene into Apple Motion ozml 4.0 XML document format\n * (.motn). A scene with a camera puts its shots in a \"Camera\" group that\n * moves, zooms and turns as the camera does.\n */\nexport function exportMotn(scene: Scene, options: MotnExportOptions = {}): string {\n const frameRate = options.frameRate ?? 30;\n const width = scene.stage?.width ?? DEFAULT_STAGE.width;\n const height = scene.stage?.height ?? DEFAULT_STAGE.height;\n\n // Calculate shot frame ranges\n let currentMs = 0;\n const shotTimings = scene.shots.map((shot, idx) => {\n const camMs = shotMoveMs(shot, idx);\n const holdMs = shot.hold ?? 800;\n const durationMs = camMs + holdMs;\n const startMs = currentMs;\n currentMs += durationMs;\n\n const startFrame = Math.round((startMs / 1000) * frameRate);\n const durationFrames = Math.max(1, Math.round((durationMs / 1000) * frameRate));\n const endFrame = startFrame + durationFrames - 1;\n\n return {\n shot,\n startFrame,\n durationFrames,\n endFrame,\n };\n });\n\n const totalFrames = Math.max(1, Math.round((currentMs / 1000) * frameRate));\n\n let nodeId = 10000;\n const lines: string[] = [];\n\n lines.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n lines.push('<!DOCTYPE ozxmlscene>');\n lines.push('<ozml version=\"4.0\">');\n if (scene.name) {\n lines.push(` <!-- Scene: ${escapeXml(scene.name)} -->`);\n }\n lines.push('');\n lines.push(' <displayversion>5.0</displayversion>');\n lines.push('');\n lines.push(' <factory id=\"1\" uuid=\"044beba5ad3211d7ac9b000393833f6a\">');\n lines.push(' <description>Style</description>');\n lines.push(' <manufacturer>Apple</manufacturer>');\n lines.push(' <version>1</version>');\n lines.push(' </factory>');\n lines.push(' <factory id=\"2\" uuid=\"babfc7777f4711d7aaa7000393833f6a\">');\n lines.push(' <description>Text</description>');\n lines.push(' <manufacturer>Apple</manufacturer>');\n lines.push(' <version>1</version>');\n lines.push(' </factory>');\n lines.push(' <factory id=\"3\" uuid=\"712462a4323911d78f8400039389b702\">');\n lines.push(' <description>Shape</description>');\n lines.push(' <manufacturer>Apple</manufacturer>');\n lines.push(' <version>1</version>');\n lines.push(' </factory>');\n lines.push(' <factory id=\"4\" uuid=\"65cb4dc9d4504fa281921f5f751fba06\">');\n lines.push(' <description>Widget</description>');\n lines.push(' <manufacturer>Apple</manufacturer>');\n lines.push(' <version>1</version>');\n lines.push(' </factory>');\n lines.push('');\n lines.push(' <scene>');\n lines.push(' <sceneSettings>');\n lines.push(` <width>${width}</width>`);\n lines.push(` <height>${height}</height>`);\n lines.push(` <duration>${totalFrames}</duration>`);\n lines.push(` <frameRate>${frameRate}</frameRate>`);\n lines.push(' <NTSC>0</NTSC>');\n lines.push(' <channels>4</channels>');\n lines.push(' <channelDepth>8</channelDepth>');\n lines.push(' <pixelAspectRatio>1</pixelAspectRatio>');\n lines.push(' <backgroundColor red=\"0\" green=\"0\" blue=\"0\" alpha=\"1\"/>');\n lines.push(' </sceneSettings>');\n lines.push(' <currentFrame>0</currentFrame>');\n lines.push(` <timeRange offset=\"0\" duration=\"${totalFrames}\"/>`);\n lines.push(` <playRange offset=\"0\" duration=\"${totalFrames}\"/>`);\n lines.push(' <flags>1</flags>');\n\n // Rig widget export if defined\n if (scene.rig && Object.keys(scene.rig.widgets).length > 0) {\n lines.push(` <scenenode name=\"Rigs\" id=\"${nodeId++}\" factoryID=\"4\" version=\"1\">`);\n for (const [widgetName, widget] of Object.entries(scene.rig.widgets)) {\n lines.push(` <scenenode name=\"${escapeXml(widgetName)}\" id=\"${nodeId++}\" factoryID=\"4\" version=\"1\">`);\n lines.push(' <parameter name=\"Object\" id=\"2\">');\n if (widget.type === 'slider') {\n lines.push(` <parameter name=\"Widget\" id=\"100\" default=\"0\" value=\"${widget.value}\"/>`);\n } else if (widget.type === 'toggle') {\n lines.push(` <parameter name=\"Widget\" id=\"100\" default=\"0\" value=\"${widget.enabled ? 1 : 0}\"/>`);\n } else if (widget.type === 'popup') {\n lines.push(` <parameter name=\"Widget\" id=\"100\" default=\"0\" value=\"${escapeXml(widget.selected)}\"/>`);\n }\n lines.push(' </parameter>');\n lines.push(' </scenenode>');\n }\n lines.push(' </scenenode>');\n }\n\n // Groups and element nodes per shot, inside the camera group when there is one.\n const hasCamera = scene.shots.some((s) => s.camera);\n if (hasCamera) lines.push(...cameraGroupOpen(scene, frameRate, totalFrames, nodeId++));\n for (const [idx, item] of shotTimings.entries()) {\n const shotLabel = item.shot.title\n ? `Shot ${idx + 1}: ${escapeXml(item.shot.title)}`\n : `Shot ${idx + 1}`;\n lines.push(` <group name=\"${shotLabel}\" id=\"${nodeId++}\">`);\n lines.push(` <timing in=\"${item.startFrame}\" out=\"${item.endFrame}\" offset=\"${item.startFrame}\"/>`);\n\n if (item.shot.run) {\n for (const cmd of item.shot.run) {\n if (isElementCommand(cmd) && cmd.element) {\n const el = cmd.element;\n const isText = el.type === 'text';\n const factoryId = isText ? 2 : 3;\n lines.push(` <scenenode name=\"${escapeXml(el.id)}\" id=\"${nodeId++}\" factoryID=\"${factoryId}\" version=\"1\">`);\n lines.push(` <timing in=\"${item.startFrame}\" out=\"${item.endFrame}\" offset=\"${item.startFrame}\"/>`);\n lines.push(' <parameter name=\"Properties\" id=\"1\">');\n lines.push(' <parameter name=\"Transform\" id=\"100\">');\n lines.push(' <parameter name=\"Position\" id=\"101\">');\n lines.push(` <parameter name=\"X\" id=\"1\" value=\"${el.x}\"/>`);\n lines.push(` <parameter name=\"Y\" id=\"2\" value=\"${-el.y}\"/>`);\n lines.push(' </parameter>');\n if (!isText) {\n lines.push(' <parameter name=\"Scale\" id=\"102\">');\n lines.push(` <parameter name=\"X\" id=\"1\" value=\"${el.width}\"/>`);\n lines.push(` <parameter name=\"Y\" id=\"2\" value=\"${el.height}\"/>`);\n lines.push(' </parameter>');\n }\n lines.push(' </parameter>');\n lines.push(' </parameter>');\n\n if (isText && el.text) {\n lines.push(` <text>${escapeXml(el.text)}</text>`);\n }\n lines.push(' </scenenode>');\n }\n }\n }\n\n lines.push(' </group>');\n }\n if (hasCamera) lines.push(' </group>');\n\n lines.push(' </scene>');\n lines.push('</ozml>');\n lines.push('');\n\n return lines.join('\\n');\n}\n","/**\n * Lottie JSON Vector Animation Exporter.\n *\n * Converts Flair scenes, elements, shapes, transforms, and keyframes into\n * official Lottie JSON format (v5.5.2) compatible with Airbnb Lottie-Web,\n * iOS/Android Lottie, Figma, and Telegram.\n */\n\nimport type { Scene } from '../scene/types.js';\nimport { DEFAULT_STAGE, DEFAULT_PERSPECTIVE, boardHeight, centreOf, isAngled, type View } from '../scene/camera.js';\nimport { cameraSamples, shotMoveMs, sceneStage } from '../scene/cameratrack.js';\nimport { isElementCommand, isUpdateCommand } from '../scene/types.js';\nimport type { KeyframeEase } from '../time/keyframe.js';\n\nexport interface LottieExportOptions {\n /** Target framerate in fps. Default: 30 */\n frameRate?: number;\n}\n\nexport interface LottieKeyframe<T> {\n t: number; // frame number\n s: T; // start value\n e?: T; // end value\n o?: { x: number | number[]; y: number | number[] }; // out tangent ease\n i?: { x: number | number[]; y: number | number[] }; // in tangent ease\n h?: number; // hold keyframe flag\n}\n\nexport interface LottieAnimatable<T, K = T> {\n a: 0 | 1; // 0 = static, 1 = animated\n k: T | LottieKeyframe<K>[];\n}\n\nexport interface LottieTransform {\n p: LottieAnimatable<[number, number, number], [number, number, number]>; // position\n a: LottieAnimatable<[number, number, number], [number, number, number]>; // anchor\n s: LottieAnimatable<[number, number, number], [number, number, number]>; // scale\n r?: LottieAnimatable<number, [number]>; // rotation (2D layers)\n or?: LottieAnimatable<[number, number, number]>; // orientation (3D layers: players expect it with rx/ry/rz)\n rx?: LottieAnimatable<number, [number]>; // X rotation (3D layers)\n ry?: LottieAnimatable<number, [number]>; // Y rotation (3D layers)\n rz?: LottieAnimatable<number, [number]>; // Z rotation (3D layers)\n o: LottieAnimatable<number, [number]>; // opacity\n}\n\n\nexport interface LottieShapeItem {\n ty: string;\n nm?: string;\n [key: string]: unknown;\n}\n\nexport interface LottieLayer {\n ddd: 0 | 1;\n ind: number;\n ty: number; // 0 = precomp, 1 = solid, 2 = image, 3 = null, 4 = shape, 5 = text, 13 = camera\n nm: string;\n /** Index of the parent layer: element layers hang off the camera rig. */\n parent?: number;\n /** Camera layers: perspective (the AE camera's zoom), in px. */\n pe?: LottieAnimatable<number, [number]>;\n sr: number;\n ks: LottieTransform;\n ao: 0 | 1;\n ip: number;\n op: number;\n st: number;\n bm: number;\n shapes?: LottieShapeItem[];\n sw?: number;\n sh?: number;\n sc?: string;\n}\n\nexport interface LottieAnimation {\n v: string;\n fr: number;\n ip: number;\n op: number;\n w: number;\n h: number;\n nm: string;\n ddd: 0 | 1;\n assets: unknown[];\n layers: LottieLayer[];\n}\n\n/**\n * Maps AE speed and influence into normalized Lottie Bezier ease control points (o.x, o.y, i.x, i.y).\n */\nexport function createLottieEase(\n durationFrames: number,\n deltaVal: number,\n outEase?: KeyframeEase,\n inEase?: KeyframeEase\n): { o: { x: number; y: number }; i: { x: number; y: number } } {\n const infOut = Math.max(0.001, Math.min(1.0, (outEase?.influence ?? 33.333) / 100));\n const infIn = Math.max(0.001, Math.min(1.0, (inEase?.influence ?? 33.333) / 100));\n\n const safeDelta = Math.abs(deltaVal) > 1e-6 ? deltaVal : 1;\n const speedOut = outEase?.speed ?? 0;\n const speedIn = inEase?.speed ?? 0;\n\n // Lottie normalized control points\n const ox = infOut;\n const oy = Math.max(0, Math.min(1, (speedOut * infOut * durationFrames) / safeDelta));\n\n const ix = 1.0 - infIn;\n const iy = Math.max(0, Math.min(1, 1.0 - (speedIn * infIn * durationFrames) / safeDelta));\n\n return {\n o: { x: Number(ox.toFixed(4)), y: Number(oy.toFixed(4)) },\n i: { x: Number(ix.toFixed(4)), y: Number(iy.toFixed(4)) },\n };\n}\n\n/** Linear keyframes for a sampled value, or a static value when it never changes. */\nfunction sampled<T extends number | number[]>(samples: { t: number; v: T }[]): LottieAnimatable<T, any> {\n const same = samples.every((x) => JSON.stringify(x.v) === JSON.stringify(samples[0]!.v));\n if (same) return { a: 0, k: samples[0]!.v };\n const keys = samples.map((x, i) => {\n const s = (Array.isArray(x.v) ? x.v : [x.v]) as number[];\n return i < samples.length - 1 ? { t: x.t, s, o: { x: 0, y: 0 }, i: { x: 1, y: 1 } } : { t: x.t, s };\n });\n return { a: 1, k: keys as LottieKeyframe<any>[] };\n}\n\nconst r3 = (n: number) => Math.round(n * 1000) / 1000;\n\n/**\n * The scene's camera as layers: a null \"Camera\" rig the element layers hang\n * off (its anchor is the camera's centre, its scale the zoom and, in 3D, its\n * rotations the angle), and, when the camera is ever angled, an AE camera\n * whose zoom is the perspective distance. Sampled every other frame during\n * moves, so the eased path and perspective come through. Lottie has no\n * motion blur, so that is left out.\n */\nfunction cameraLayers(scene: Scene, fr: number, totalFrames: number): { layers: LottieLayer[]; rig: number; ddd: 0 | 1 } | null {\n if (!scene.shots.some((s) => s.camera)) return null;\n const stage = sceneStage(scene);\n const samples = cameraSamples(scene, fr).map((x) => ({ t: x.frame, view: x.view }));\n const ddd: 0 | 1 = samples.some((x) => isAngled(x.view)) ? 1 : 0;\n const w = stage.width;\n const h = boardHeight(stage);\n const at = <T extends number | number[]>(fn: (v: View) => T) => sampled(samples.map((x) => ({ t: x.t, v: fn(x.view) })));\n const ks: LottieTransform = {\n a: at((v) => {\n const [cx, cy] = centreOf(v, stage);\n return [r3(cx), r3(cy), 0] as [number, number, number];\n }) as LottieTransform['a'],\n p: { a: 0, k: [w / 2, h / 2, 0] },\n s: at((v) => [r3(v.zoom * 100), r3(v.zoom * 100), 100] as [number, number, number]) as LottieTransform['s'],\n o: { a: 0, k: 100 },\n };\n // AE turns the other way round X and Y from CSS (its z points into the screen).\n if (ddd) {\n ks.or = { a: 0, k: [0, 0, 0] };\n ks.rx = at((v) => r3(0 - (v.tilt ?? 0)));\n ks.ry = at((v) => r3(0 - (v.turn ?? 0)));\n ks.rz = at((v) => r3(v.roll ?? 0));\n } else ks.r = at((v) => r3(v.roll ?? 0));\n const layers: LottieLayer[] = [];\n if (ddd) {\n const distance = at((v) => r3((v.perspective ?? DEFAULT_PERSPECTIVE) * w));\n const d0 = (DEFAULT_PERSPECTIVE * w) as number;\n layers.push({\n ddd: 1,\n ind: 1,\n ty: 13,\n nm: 'Camera Lens',\n sr: 1,\n pe: distance,\n ks: {\n p: { a: 0, k: [w / 2, h / 2, -d0] },\n a: { a: 0, k: [w / 2, h / 2, 0] },\n s: { a: 0, k: [100, 100, 100] },\n or: { a: 0, k: [0, 0, 0] },\n rx: { a: 0, k: 0 },\n ry: { a: 0, k: 0 },\n rz: { a: 0, k: 0 },\n o: { a: 0, k: 100 },\n },\n ao: 0,\n ip: 0,\n op: totalFrames,\n st: 0,\n bm: 0,\n });\n }\n const rig = layers.length + 1;\n layers.push({ ddd, ind: rig, ty: 3, nm: 'Camera', sr: 1, ks, ao: 0, ip: 0, op: totalFrames, st: 0, bm: 0 });\n return { layers, rig, ddd };\n}\n\n/**\n * Serializes a Flair Scene into standard Lottie JSON animation. A scene\n * with a camera gets a camera rig the element layers hang off, in 3D (with\n * an AE camera) when the camera is angled.\n */\nexport function exportLottie(scene: Scene, options: LottieExportOptions = {}): LottieAnimation {\n const fr = options.frameRate ?? 30;\n const width = scene.stage?.width ?? DEFAULT_STAGE.width;\n const height = scene.stage?.height ?? DEFAULT_STAGE.height;\n\n // Compute shot timeline frames\n let currentMs = 0;\n const shotTimings = scene.shots.map((shot, idx) => {\n const camMs = shotMoveMs(shot, idx);\n const holdMs = shot.hold ?? 800;\n const durationMs = camMs + holdMs;\n const startMs = currentMs;\n currentMs += durationMs;\n\n const startFrame = Math.round((startMs / 1000) * fr);\n const durationFrames = Math.max(1, Math.round((durationMs / 1000) * fr));\n const endFrame = startFrame + durationFrames;\n\n return {\n shot,\n startFrame,\n durationFrames,\n endFrame,\n };\n });\n\n const totalFrames = Math.max(1, Math.round((currentMs / 1000) * fr));\n\n // Collect elements and track property updates across shots\n interface ElementTrack {\n id: string;\n type: string;\n initialX: number;\n initialY: number;\n width: number;\n height: number;\n text?: string;\n opacity: number;\n inFrame: number;\n outFrame: number;\n posKeyframes: LottieKeyframe<[number, number, number]>[];\n opacityKeyframes: LottieKeyframe<[number]>[];\n }\n\n const tracks = new Map<string, ElementTrack>();\n\n for (const timing of shotTimings) {\n const shot = timing.shot;\n if (!shot.run) continue;\n\n for (const cmd of shot.run) {\n if (isElementCommand(cmd)) {\n const el = cmd.element;\n if (!tracks.has(el.id)) {\n tracks.set(el.id, {\n id: el.id,\n type: el.type,\n initialX: el.x,\n initialY: el.y,\n width: el.width,\n height: el.height,\n text: el.text,\n opacity: el.opacity ?? 1,\n inFrame: timing.startFrame,\n outFrame: totalFrames,\n posKeyframes: [\n {\n t: timing.startFrame,\n s: [el.x + el.width * 0.5, el.y + el.height * 0.5, 0],\n },\n ],\n opacityKeyframes: [\n {\n t: timing.startFrame,\n s: [(el.opacity ?? 1) * 100],\n },\n ],\n });\n }\n } else if (isUpdateCommand(cmd)) {\n const track = tracks.get(cmd.id);\n if (track) {\n const props = cmd.props;\n const prevPos = track.posKeyframes[track.posKeyframes.length - 1];\n const newX = props.x !== undefined ? props.x : prevPos.s[0] - track.width * 0.5;\n const newY = props.y !== undefined ? props.y : prevPos.s[1] - track.height * 0.5;\n\n const ease = createLottieEase(timing.durationFrames, 1);\n prevPos.o = ease.o;\n prevPos.i = ease.i;\n\n track.posKeyframes.push({\n t: timing.endFrame,\n s: [newX + track.width * 0.5, newY + track.height * 0.5, 0],\n });\n\n if (props.opacity !== undefined) {\n const prevOp = track.opacityKeyframes[track.opacityKeyframes.length - 1];\n prevOp.o = ease.o;\n prevOp.i = ease.i;\n track.opacityKeyframes.push({\n t: timing.endFrame,\n s: [props.opacity * 100],\n });\n }\n }\n }\n }\n }\n\n // Build Lottie layers: the camera first, then the elements hanging off its rig.\n const camera = cameraLayers(scene, fr, totalFrames);\n const layers: LottieLayer[] = camera ? [...camera.layers] : [];\n let layerIndex = layers.length + 1;\n\n for (const track of tracks.values()) {\n const isPosAnimated = track.posKeyframes.length > 1;\n const isOpAnimated = track.opacityKeyframes.length > 1;\n\n const p: LottieAnimatable<[number, number, number], [number, number, number]> = isPosAnimated\n ? { a: 1, k: track.posKeyframes }\n : { a: 0, k: [track.initialX + track.width * 0.5, track.initialY + track.height * 0.5, 0] };\n\n const o: LottieAnimatable<number, [number]> = isOpAnimated\n ? { a: 1, k: track.opacityKeyframes }\n : { a: 0, k: track.opacity * 100 };\n\n const ks: LottieTransform = {\n p,\n a: { a: 0, k: [0, 0, 0] },\n s: { a: 0, k: [100, 100, 100] },\n r: { a: 0, k: 0 },\n o,\n };\n\n // Shape items for rectangle / visual element\n const shapes: LottieShapeItem[] = [\n {\n ty: 'gr',\n nm: track.id,\n it: [\n {\n ty: 'rc',\n nm: 'Rectangle Path',\n d: 1,\n s: { a: 0, k: [track.width, track.height] },\n p: { a: 0, k: [0, 0] },\n r: { a: 0, k: 8 },\n },\n {\n ty: 'fl',\n nm: 'Fill',\n c: { a: 0, k: [0.2, 0.4, 0.9, 1] },\n o: { a: 0, k: 100 },\n r: 1,\n },\n {\n ty: 'tr',\n nm: 'Transform',\n p: { a: 0, k: [0, 0] },\n a: { a: 0, k: [0, 0] },\n s: { a: 0, k: [100, 100] },\n r: { a: 0, k: 0 },\n o: { a: 0, k: 100 },\n },\n ],\n },\n ];\n\n layers.push({\n ddd: camera?.ddd ?? 0,\n ind: layerIndex++,\n ...(camera && { parent: camera.rig }),\n ty: 4, // Shape layer\n nm: track.id,\n sr: 1,\n ks,\n ao: 0,\n ip: track.inFrame,\n op: track.outFrame,\n st: track.inFrame,\n bm: 0, // Normal blend mode\n shapes,\n });\n }\n\n return {\n v: '5.5.2',\n fr,\n ip: 0,\n op: totalFrames,\n w: width,\n h: height,\n nm: scene.name || 'Flair Animation',\n ddd: camera?.ddd ?? 0,\n assets: [],\n layers,\n };\n}\n","import type { Scene, Shot } from '../scene/types.js';\nimport { DEFAULT_STAGE, boardHeight, centreOf, projectPoint, type CameraTransition, type View } from '../scene/camera.js';\nimport { cameraSamples, shotMoveMs, cameraTrack, sceneStage, type CameraSample } from '../scene/cameratrack.js';\n\nexport interface Fcp7ExportOptions {\n /** Timeline timebase / frame rate (default 30). */\n frameRate?: number;\n /** NTSC flag (default false, or true if 29.97 / 59.94). */\n ntsc?: boolean;\n /** Starting timecode (default \"00:00:00:00\"). */\n timecodeStart?: string;\n /** Sequence name override. */\n sequenceName?: string;\n /** Media path prefix or file base URL (default \"file://localhost/media/\"). */\n mediaPathPrefix?: string;\n /** Include text generator overlay track for titles/captions (default true). */\n includeTextTrack?: boolean;\n /** Include timeline sequence markers (default true). */\n includeMarkers?: boolean;\n}\n\nexport interface EdlExportOptions {\n /** Timeline timebase / frame rate (default 30). */\n frameRate?: number;\n /** Drop frame flag (default false). */\n dropFrame?: boolean;\n /** Starting timecode (default \"01:00:00:00\" as per standard broadcast EDL practice). */\n timecodeStart?: string;\n /** Reel name identifier (default \"AX\", max 8 chars). */\n reel?: string;\n}\n\nexport interface ShotTiming {\n shot: Shot;\n index: number;\n startFrame: number;\n endFrame: number;\n durationFrames: number;\n startMs: number;\n durationMs: number;\n}\n\nfunction escapeXml(unsafe: string): string {\n return unsafe\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/**\n * Calculates start and duration frame boundaries for each shot in a scene.\n */\nexport function calculateShotTimings(scene: Scene, frameRate: number = 30): ShotTiming[] {\n let currentMs = 0;\n return scene.shots.map((shot, index) => {\n const camMs = shotMoveMs(shot, index);\n const holdMs = shot.hold ?? 800;\n const durationMs = camMs + holdMs;\n const startMs = currentMs;\n currentMs += durationMs;\n\n const startFrame = Math.round((startMs / 1000) * frameRate);\n const durationFrames = Math.max(1, Math.round((durationMs / 1000) * frameRate));\n const endFrame = startFrame + durationFrames;\n\n return {\n shot,\n index,\n startFrame,\n endFrame,\n durationFrames,\n startMs,\n durationMs,\n };\n });\n}\n\n/**\n * Converts frame count to standard SMPTE timecode HH:MM:SS:FF.\n */\nexport function framesToTimecode(\n frame: number,\n timebase: number = 30,\n dropFrame: boolean = false\n): string {\n const roundedFps = Math.round(timebase);\n let totalFrames = Math.max(0, Math.floor(frame));\n\n if (dropFrame && (roundedFps === 30 || roundedFps === 29)) {\n // 29.97 DF: drop frames 0 and 1 at the start of every minute except minutes 0, 10, 20, 30, 40, 50\n const dropFramesPer10Mins = 18;\n const framesPer10Mins = 17982; // 10 * 60 * 30 - 18\n const framesPerMinute = 1798; // 60 * 30 - 2\n\n const d = Math.floor(totalFrames / framesPer10Mins);\n const m = totalFrames % framesPer10Mins;\n\n if (m >= 2) {\n totalFrames += dropFramesPer10Mins * d + 2 * Math.floor((m - 2) / framesPerMinute);\n } else {\n totalFrames += dropFramesPer10Mins * d;\n }\n }\n\n const ff = totalFrames % roundedFps;\n const totalSeconds = Math.floor(totalFrames / roundedFps);\n const ss = totalSeconds % 60;\n const totalMinutes = Math.floor(totalSeconds / 60);\n const mm = totalMinutes % 60;\n const hh = Math.floor(totalMinutes / 60);\n\n const pad = (n: number) => n.toString().padStart(2, '0');\n const separator = dropFrame ? ';' : ':';\n return `${pad(hh)}:${pad(mm)}:${pad(ss)}${separator}${pad(ff)}`;\n}\n\n/**\n * Converts standard SMPTE timecode HH:MM:SS:FF to frame count.\n */\nexport function timecodeToFrames(\n timecode: string,\n timebase: number = 30,\n dropFrame: boolean = false\n): number {\n const parts = timecode.split(/[:;]/).map(Number);\n if (parts.length !== 4 || parts.some(isNaN)) {\n return 0;\n }\n const [hh, mm, ss, ff] = parts;\n const roundedFps = Math.round(timebase);\n\n if (dropFrame && (roundedFps === 30 || roundedFps === 29)) {\n const totalMinutes = hh * 60 + mm;\n const dropCount = (totalMinutes - Math.floor(totalMinutes / 10)) * 2;\n return ((hh * 3600 + mm * 60 + ss) * roundedFps + ff) - dropCount;\n }\n\n return (hh * 3600 + mm * 60 + ss) * roundedFps + ff;\n}\n\nconst r4 = (n: number) => Math.round(n * 10000) / 10000;\n\nconst CORNERS = [\n ['ulcorner', 'Upper Left', 0, 0],\n ['urcorner', 'Upper Right', 1, 0],\n ['lrcorner', 'Lower Right', 1, 1],\n ['llcorner', 'Lower Left', 0, 1],\n] as const;\n\n/**\n * Where the camera puts a full-frame clip's corners, as FCP's Distort\n * offsets from the middle of the frame (fractions of its size, ±0.5 when\n * untouched): a corner pin draws the camera's zoom, pan and 3D angle\n * exactly for a flat picture of the stage.\n */\nfunction cornerPins(view: View, stage: ReturnType<typeof sceneStage>): [number, number][] {\n const w = stage.width;\n const h = boardHeight(stage);\n return CORNERS.map(([, , cx, cy]) => {\n const p = projectPoint(view, stage, [cx * w, cy * h]) ?? [cx * w, cy * h];\n return [r4((p[0] - w / 2) / w), r4((p[1] - h / 2) / h)];\n });\n}\n\n/**\n * The Distort and Motion Blur filters that play a shot's camera on its clip\n * (the clip being a flat render of the whole stage), keyed at frames in the\n * clip; nothing when the camera never leaves the full frame.\n */\nfunction cameraFilters(samples: readonly CameraSample[], stage: ReturnType<typeof sceneStage>, startFrame: number, motionBlur: number, indent: string): string[] {\n const pins = samples.map((x) => cornerPins(x.view, stage));\n const untouched = pins.every((corners) => corners.every(([hz, vt], i) => hz === (CORNERS[i]![2] - 0.5) && vt === (CORNERS[i]![3] - 0.5)));\n const lines: string[] = [];\n if (!untouched) {\n lines.push(`${indent}<filter>`, `${indent} <effect>`, `${indent} <name>Distort</name>`, `${indent} <effectid>deformation</effectid>`, `${indent} <effectcategory>motion</effectcategory>`, `${indent} <effecttype>motion</effecttype>`, `${indent} <mediatype>video</mediatype>`);\n CORNERS.forEach(([id, name], i) => {\n lines.push(`${indent} <parameter>`, `${indent} <parameterid>${id}</parameterid>`, `${indent} <name>${name}</name>`);\n const point = (k: number) => `<value><horiz>${pins[k]![i]![0]}</horiz><vert>${pins[k]![i]![1]}</vert></value>`;\n if (samples.length === 1) lines.push(`${indent} ${point(0)}`);\n else samples.forEach((x, k) => lines.push(`${indent} <keyframe><when>${x.frame - startFrame}</when>${point(k)}</keyframe>`));\n lines.push(`${indent} </parameter>`);\n });\n lines.push(`${indent} </effect>`, `${indent}</filter>`);\n }\n if (motionBlur > 0) {\n lines.push(\n `${indent}<filter>`,\n `${indent} <effect>`,\n `${indent} <name>Motion Blur</name>`,\n `${indent} <effectid>motionblur</effectid>`,\n `${indent} <effectcategory>motion</effectcategory>`,\n `${indent} <effecttype>motion</effecttype>`,\n `${indent} <mediatype>video</mediatype>`,\n `${indent} <parameter>`,\n `${indent} <parameterid>duration</parameterid>`,\n `${indent} <name>% Blur</name>`,\n `${indent} <value>${Math.round(Math.min(1000, motionBlur * 250))}</value>`,\n `${indent} </parameter>`,\n `${indent} <parameter>`,\n `${indent} <parameterid>samples</parameterid>`,\n `${indent} <name>Samples</name>`,\n `${indent} <value>8</value>`,\n `${indent} </parameter>`,\n `${indent} </effect>`,\n `${indent}</filter>`,\n );\n }\n return lines;\n}\n\n/**\n * Serializes a Flair Scene into Apple Final Cut Pro 7 XML Interchange Format (xmeml v4).\n * Compatible with Premiere Pro, DaVinci Resolve, and Final Cut Pro. Each\n * shot's camera (zoom, pan and 3D angle) is a keyframed Distort corner pin\n * on its clip, with Motion Blur when the shot's move blurs.\n */\nexport function exportFcp7Xml(scene: Scene, options: Fcp7ExportOptions = {}): string {\n const frameRate = options.frameRate ?? 30;\n const timebase = Math.round(frameRate);\n const ntsc = options.ntsc ?? (Math.abs(frameRate - 29.97) < 0.05 || Math.abs(frameRate - 59.94) < 0.05);\n const ntscStr = ntsc ? 'TRUE' : 'FALSE';\n const width = scene.stage?.width ?? DEFAULT_STAGE.width;\n const height = scene.stage?.height ?? DEFAULT_STAGE.height;\n const sequenceName = options.sequenceName ?? scene.name ?? 'Flair Sequence';\n const timecodeStart = options.timecodeStart ?? '00:00:00:00';\n const mediaPrefix = options.mediaPathPrefix ?? 'file://localhost/media/';\n const includeTextTrack = options.includeTextTrack ?? true;\n const includeMarkers = options.includeMarkers ?? true;\n\n const timings = calculateShotTimings(scene, frameRate);\n const totalFrames = timings.length > 0 ? timings[timings.length - 1].endFrame : 0;\n const startFrameOffset = timecodeToFrames(timecodeStart, frameRate);\n const stage = sceneStage(scene);\n const samples = scene.shots.some((s) => s.camera) ? cameraSamples(scene, frameRate) : [];\n // A shot's camera keys: its own, after the view it starts from (the last key before it).\n const shotSamples = (index: number, startFrame: number): CameraSample[] => {\n const own = samples.filter((x) => x.shot === index);\n const before = samples.filter((x) => x.shot < index).at(-1);\n if (own.length === 0) return before ? [{ ...before, frame: startFrame, shot: index }] : [];\n return own[0]!.frame > startFrame && before ? [{ ...before, frame: startFrame, shot: index }, ...own] : own;\n };\n\n const lines: string[] = [];\n\n lines.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n lines.push('<!DOCTYPE xmeml>');\n lines.push('<xmeml version=\"4\">');\n lines.push(` <sequence id=\"sequence-1\">`);\n lines.push(` <name>${escapeXml(sequenceName)}</name>`);\n lines.push(` <duration>${totalFrames}</duration>`);\n lines.push(' <rate>');\n lines.push(` <timebase>${timebase}</timebase>`);\n lines.push(` <ntsc>${ntscStr}</ntsc>`);\n lines.push(' </rate>');\n lines.push(' <timecode>');\n lines.push(' <rate>');\n lines.push(` <timebase>${timebase}</timebase>`);\n lines.push(` <ntsc>${ntscStr}</ntsc>`);\n lines.push(' </rate>');\n lines.push(` <string>${timecodeStart}</string>`);\n lines.push(` <frame>${startFrameOffset}</frame>`);\n lines.push(' <displayformat>NDF</displayformat>');\n lines.push(' </timecode>');\n\n // Sequence Timeline Markers\n if (includeMarkers) {\n timings.forEach(({ shot, index, startFrame, endFrame }) => {\n const name = shot.title || `Shot ${index + 1}`;\n const comment = shot.caption || '';\n lines.push(' <marker>');\n lines.push(` <name>${escapeXml(name)}</name>`);\n lines.push(` <comment>${escapeXml(comment)}</comment>`);\n lines.push(` <in>${startFrame}</in>`);\n lines.push(` <out>${endFrame}</out>`);\n lines.push(' </marker>');\n });\n }\n\n lines.push(' <media>');\n lines.push(' <video>');\n lines.push(' <format>');\n lines.push(' <samplecharacteristics>');\n lines.push(` <width>${width}</width>`);\n lines.push(` <height>${height}</height>`);\n lines.push(' <pixelaspectratio>square</pixelaspectratio>');\n lines.push(' <rate>');\n lines.push(` <timebase>${timebase}</timebase>`);\n lines.push(` <ntsc>${ntscStr}</ntsc>`);\n lines.push(' </rate>');\n lines.push(' </samplecharacteristics>');\n lines.push(' </format>');\n\n // Video Track 1: Base Shot Clips\n lines.push(' <track>');\n lines.push(' <enabled>TRUE</enabled>');\n lines.push(' <locked>FALSE</locked>');\n\n timings.forEach(({ shot, index, startFrame, endFrame, durationFrames }) => {\n const shotName = shot.title || `Shot_${index + 1}`;\n const fileId = `file-${index + 1}`;\n const clipId = `clipitem-${index + 1}`;\n const fileName = `${shotName.replace(/[^a-zA-Z0-9_-]/g, '_')}.mov`;\n const fileUrl = `${mediaPrefix.replace(/\\/+$/, '')}/${fileName}`;\n\n lines.push(` <clipitem id=\"${clipId}\">`);\n lines.push(` <name>${escapeXml(shotName)}</name>`);\n lines.push(` <duration>${durationFrames}</duration>`);\n lines.push(' <rate>');\n lines.push(` <timebase>${timebase}</timebase>`);\n lines.push(` <ntsc>${ntscStr}</ntsc>`);\n lines.push(' </rate>');\n lines.push(` <start>${startFrame}</start>`);\n lines.push(` <end>${endFrame}</end>`);\n lines.push(' <in>0</in>');\n lines.push(` <out>${durationFrames}</out>`);\n\n // File element\n lines.push(` <file id=\"${fileId}\">`);\n lines.push(` <name>${escapeXml(fileName)}</name>`);\n lines.push(` <pathurl>${escapeXml(fileUrl)}</pathurl>`);\n lines.push(' <rate>');\n lines.push(` <timebase>${timebase}</timebase>`);\n lines.push(` <ntsc>${ntscStr}</ntsc>`);\n lines.push(' </rate>');\n lines.push(` <duration>${durationFrames}</duration>`);\n lines.push(' <timecode>');\n lines.push(' <rate>');\n lines.push(` <timebase>${timebase}</timebase>`);\n lines.push(` <ntsc>${ntscStr}</ntsc>`);\n lines.push(' </rate>');\n lines.push(' <string>00:00:00:00</string>');\n lines.push(' <frame>0</frame>');\n lines.push(' <displayformat>NDF</displayformat>');\n lines.push(' </timecode>');\n lines.push(' <media>');\n lines.push(' <video>');\n lines.push(' <samplecharacteristics>');\n lines.push(` <width>${width}</width>`);\n lines.push(` <height>${height}</height>`);\n lines.push(' </samplecharacteristics>');\n lines.push(' </video>');\n lines.push(' </media>');\n lines.push(' </file>');\n\n // Clip marker if caption is present\n if (shot.caption) {\n lines.push(' <marker>');\n lines.push(` <name>${escapeXml(shotName)} Narration</name>`);\n lines.push(` <comment>${escapeXml(shot.caption)}</comment>`);\n lines.push(' <in>0</in>');\n lines.push(` <out>${durationFrames}</out>`);\n lines.push(' </marker>');\n }\n\n // Basic Motion Filter\n lines.push(' <filter>');\n lines.push(' <effect>');\n lines.push(' <name>Basic Motion</name>');\n lines.push(' <effectid>basic</effectid>');\n lines.push(' <effectcategory>motion</effectcategory>');\n lines.push(' <effecttype>motion</effecttype>');\n lines.push(' <mediatype>video</mediatype>');\n lines.push(' <parameter>');\n lines.push(' <parameterid>scale</parameterid>');\n lines.push(' <name>Scale</name>');\n lines.push(' <value>100</value>');\n lines.push(' </parameter>');\n lines.push(' </effect>');\n lines.push(' </filter>');\n const keys = shotSamples(index, startFrame);\n if (keys.length > 0) lines.push(...cameraFilters(keys, stage, startFrame, shot.camera?.motionBlur ?? 0, ' '));\n lines.push(' </clipitem>');\n });\n\n lines.push(' </track>');\n\n // Video Track 2: Title / Narration Overlay Track (Generators)\n const hasTextOverlays = timings.some((t) => t.shot.title || t.shot.caption);\n if (includeTextTrack && hasTextOverlays) {\n lines.push(' <track>');\n lines.push(' <enabled>TRUE</enabled>');\n lines.push(' <locked>FALSE</locked>');\n\n timings.forEach(({ shot, index, startFrame, endFrame, durationFrames }) => {\n const text = shot.title ?? shot.caption;\n if (!text) return;\n\n const generatorId = `generator-title-${index + 1}`;\n lines.push(` <clipitem id=\"${generatorId}\">`);\n lines.push(` <name>${escapeXml(text)}</name>`);\n lines.push(` <duration>${durationFrames}</duration>`);\n lines.push(' <rate>');\n lines.push(` <timebase>${timebase}</timebase>`);\n lines.push(` <ntsc>${ntscStr}</ntsc>`);\n lines.push(' </rate>');\n lines.push(` <start>${startFrame}</start>`);\n lines.push(` <end>${endFrame}</end>`);\n lines.push(' <in>0</in>');\n lines.push(` <out>${durationFrames}</out>`);\n lines.push(' <effect>');\n lines.push(' <name>Text</name>');\n lines.push(' <effectid>Text</effectid>');\n lines.push(' <effectcategory>Text</effectcategory>');\n lines.push(' <effecttype>generator</effecttype>');\n lines.push(' <mediatype>video</mediatype>');\n lines.push(' <parameter>');\n lines.push(' <parameterid>str</parameterid>');\n lines.push(' <name>Text</name>');\n lines.push(` <value>${escapeXml(text)}</value>`);\n lines.push(' </parameter>');\n lines.push(' </effect>');\n lines.push(' </clipitem>');\n });\n\n lines.push(' </track>');\n }\n\n lines.push(' </video>');\n lines.push(' </media>');\n lines.push(' </sequence>');\n lines.push('</xmeml>');\n\n return lines.join('\\n');\n}\n\n/** A camera view as a line an editor can follow: \"whip to zoom 1.6x on (800, 450), tilt 35°, turn -15°, motion blur 1.5\". */\nfunction describeCamera(view: View, motionBlur: number, stage: ReturnType<typeof sceneStage>, transition: CameraTransition = 'move'): string {\n const [cx, cy] = centreOf(view, stage);\n const lead = transition === 'move' ? '' : `${transition} to `;\n const parts = [`${lead}zoom ${r4(view.zoom).toFixed(2)}x on (${Math.round(cx)}, ${Math.round(cy)})`];\n if (view.tilt) parts.push(`tilt ${r4(view.tilt)}°`);\n if (view.turn) parts.push(`turn ${r4(view.turn)}°`);\n if (view.roll) parts.push(`roll ${r4(view.roll)}°`);\n if (view.perspective) parts.push(`perspective ${view.perspective}`);\n if (motionBlur > 0) parts.push(`motion blur ${motionBlur}`);\n return parts.join(', ');\n}\n\n/**\n * Serializes a Flair Scene into standard CMX 3600 Edit Decision List (EDL).\n * The format has no transforms, so each shot's camera is written as a\n * `* CAMERA:` comment.\n * Fully readable by DaVinci Resolve, Premiere Pro, Avid, and Lightworks.\n */\nexport function exportCmx3600Edl(scene: Scene, options: EdlExportOptions = {}): string {\n const frameRate = options.frameRate ?? 30;\n const timebase = Math.round(frameRate);\n const dropFrame = options.dropFrame ?? false;\n const reel = (options.reel ?? 'AX').slice(0, 8).padEnd(8, ' ');\n const title = (scene.name ?? 'UNTITLED').toUpperCase().replace(/[^A-Z0-9_ -]/g, '');\n const startTc = options.timecodeStart ?? '01:00:00:00';\n\n const timings = calculateShotTimings(scene, frameRate);\n let recordFrame = timecodeToFrames(startTc, timebase, dropFrame);\n const track = scene.shots.some((s) => s.camera) ? cameraTrack(scene) : undefined;\n\n const lines: string[] = [];\n lines.push(`TITLE: ${title}`);\n lines.push(dropFrame ? 'FCM: DROP FRAME' : 'FCM: NON-DROP FRAME');\n lines.push('');\n\n timings.forEach(({ shot, index, durationFrames }) => {\n const eventNum = (index + 1).toString().padStart(3, '0');\n const srcInTc = '00:00:00:00';\n const srcOutTc = framesToTimecode(durationFrames, timebase, dropFrame);\n\n const recInTc = framesToTimecode(recordFrame, timebase, dropFrame);\n recordFrame += durationFrames;\n const recOutTc = framesToTimecode(recordFrame, timebase, dropFrame);\n\n // Standard CMX 3600 line format:\n // Event Reel Track Transition SourceIn SourceOut RecordIn RecordOut\n lines.push(`${eventNum} ${reel} V C ${srcInTc} ${srcOutTc} ${recInTc} ${recOutTc}`);\n\n const clipName = shot.title || `Shot ${index + 1}`;\n lines.push(`* FROM CLIP NAME: ${clipName}`);\n if (shot.caption) {\n lines.push(`* COMMENT: ${shot.caption}`);\n }\n // CMX 3600 has no transforms, so the camera is a note for the editor.\n const camera = track?.[index];\n if (camera && shot.camera) lines.push(`* CAMERA: ${describeCamera(camera.to, camera.motionBlur, sceneStage(scene), camera.transition)}`);\n lines.push('');\n });\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":["r3","escapeXml"]}
|