@shotstack/shotstack-canvas 1.1.4 → 1.1.6

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/env/entry.node.ts","../src/schema/asset-schema.ts","../src/config/canvas-constants.ts","../src/wasm/hb-loader.ts","../src/core/font-registry.ts","../src/core/layout.ts","../src/core/gradients.ts","../src/core/decoration.ts","../src/core/drawops.ts","../src/core/animations.ts","../src/core/colors.ts","../src/painters/node.ts","../src/io/node.ts","../src/core/video-generator.ts","../src/types.ts"],"sourcesContent":["import { RichTextAssetSchema, type RichTextValidated } from \"../schema/asset-schema\";\r\nimport { CANVAS_CONFIG } from \"../config/canvas-constants\";\r\nimport { FontRegistry } from \"../core/font-registry\";\r\nimport { LayoutEngine } from \"../core/layout\";\r\nimport { buildDrawOps } from \"../core/drawops\";\r\nimport { applyAnimation } from \"../core/animations\";\r\nimport { createNodePainter } from \"../painters/node\";\r\nimport { loadFileOrHttpToArrayBuffer } from \"../io/node\";\r\nimport { VideoGenerator, VideoGenerationOptions } from \"../core/video-generator\";\r\n\r\nexport async function createTextEngine(\r\n opts: {\r\n width?: number;\r\n height?: number;\r\n pixelRatio?: number;\r\n fps?: number;\r\n wasmBaseURL?: string;\r\n } = {}\r\n) {\r\n const width = opts.width ?? CANVAS_CONFIG.DEFAULTS.width;\r\n const height = opts.height ?? CANVAS_CONFIG.DEFAULTS.height;\r\n const pixelRatio = opts.pixelRatio ?? CANVAS_CONFIG.DEFAULTS.pixelRatio;\r\n const fps = opts.fps ?? 30;\r\n const wasmBaseURL = opts.wasmBaseURL;\r\n\r\n const fonts = new FontRegistry(wasmBaseURL);\r\n const layout = new LayoutEngine(fonts);\r\n const videoGenerator = new VideoGenerator();\r\n\r\n try {\r\n await fonts.init();\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to initialize font registry: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n\r\n async function ensureFonts(asset: RichTextValidated) {\r\n try {\r\n if (asset.customFonts) {\r\n for (const cf of asset.customFonts) {\r\n try {\r\n const bytes = await loadFileOrHttpToArrayBuffer(cf.src);\r\n await fonts.registerFromBytes(bytes, {\r\n family: cf.family,\r\n weight: cf.weight ?? \"400\",\r\n style: cf.style ?? \"normal\",\r\n });\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to load custom font \"${cf.family}\" from ${cf.src}: ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n }\r\n const main = asset.font ?? {\r\n family: \"Roboto\",\r\n weight: \"400\",\r\n style: \"normal\",\r\n size: 48,\r\n color: \"#000000\",\r\n opacity: 1,\r\n };\r\n return main;\r\n } catch (err) {\r\n if (err instanceof Error) {\r\n throw err;\r\n }\r\n throw new Error(`Failed to ensure fonts: ${String(err)}`);\r\n }\r\n }\r\n\r\n return {\r\n validate(input: unknown): { value: RichTextValidated } {\r\n try {\r\n const { value, error } = RichTextAssetSchema.validate(input, {\r\n abortEarly: false,\r\n convert: true,\r\n });\r\n if (error) throw error;\r\n return { value: value as RichTextValidated };\r\n } catch (err) {\r\n if (err instanceof Error) {\r\n throw new Error(`Validation failed: ${err.message}`);\r\n }\r\n throw new Error(`Validation failed: ${String(err)}`);\r\n }\r\n },\r\n\r\n async registerFontFromFile(\r\n path: string,\r\n desc: { family: string; weight?: string | number; style?: string }\r\n ): Promise<void> {\r\n try {\r\n const bytes = await loadFileOrHttpToArrayBuffer(path);\r\n await fonts.registerFromBytes(bytes, desc);\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to register font \"${desc.family}\" from file ${path}: ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n },\r\n\r\n async registerFontFromUrl(\r\n url: string,\r\n desc: { family: string; weight?: string | number; style?: string }\r\n ): Promise<void> {\r\n try {\r\n const bytes = await loadFileOrHttpToArrayBuffer(url);\r\n await fonts.registerFromBytes(bytes, desc);\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to register font \"${desc.family}\" from URL ${url}: ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n },\r\n\r\n async renderFrame(asset: RichTextValidated, tSeconds: number) {\r\n try {\r\n const main = await ensureFonts(asset);\r\n const desc = { family: main.family, weight: `${main.weight}`, style: main.style };\r\n\r\n let lines;\r\n try {\r\n lines = await layout.layout({\r\n text: asset.text,\r\n width: asset.width ?? width,\r\n letterSpacing: asset.style?.letterSpacing ?? 0,\r\n fontSize: main.size,\r\n lineHeight: asset.style?.lineHeight ?? 1.2,\r\n desc,\r\n textTransform: asset.style?.textTransform ?? \"none\",\r\n });\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to layout text: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n\r\n const textRect = {\r\n x: 0,\r\n y: 0,\r\n width: asset.width ?? width,\r\n height: asset.height ?? height,\r\n };\r\n\r\n const canvasW = asset.width ?? width;\r\n const canvasH = asset.height ?? height;\r\n const canvasPR = asset.pixelRatio ?? pixelRatio;\r\n\r\n let ops0;\r\n try {\r\n ops0 = await buildDrawOps({\r\n canvas: { width: canvasW, height: canvasH, pixelRatio: canvasPR },\r\n textRect,\r\n lines,\r\n font: {\r\n family: main.family,\r\n size: main.size,\r\n weight: `${main.weight}`,\r\n style: main.style,\r\n color: main.color,\r\n opacity: main.opacity,\r\n },\r\n style: {\r\n lineHeight: asset.style?.lineHeight ?? 1.2,\r\n textDecoration: asset.style?.textDecoration ?? \"none\",\r\n gradient: asset.style?.gradient,\r\n },\r\n stroke: asset.stroke,\r\n shadow: asset.shadow,\r\n align: asset.align ?? { horizontal: \"left\", vertical: \"middle\" },\r\n background: asset.background,\r\n glyphPathProvider: (gid) => fonts.glyphPath(desc, gid),\r\n getUnitsPerEm: () => fonts.getUnitsPerEm(desc),\r\n });\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to build draw operations: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n\r\n try {\r\n const ops = applyAnimation(ops0, lines, {\r\n t: tSeconds,\r\n fontSize: main.size,\r\n anim: asset.animation\r\n ? {\r\n preset: asset.animation.preset,\r\n speed: asset.animation.speed,\r\n duration: asset.animation.duration,\r\n style: asset.animation.style,\r\n direction: asset.animation.direction,\r\n }\r\n : undefined,\r\n });\r\n\r\n return ops;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to apply animation: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n } catch (err) {\r\n if (err instanceof Error) {\r\n throw err;\r\n }\r\n throw new Error(`Failed to render frame at time ${tSeconds}s: ${String(err)}`);\r\n }\r\n },\r\n\r\n async createRenderer(p: { width?: number; height?: number; pixelRatio?: number }) {\r\n try {\r\n return await createNodePainter({\r\n width: p.width ?? width,\r\n height: p.height ?? height,\r\n pixelRatio: p.pixelRatio ?? pixelRatio,\r\n });\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to create renderer: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n },\r\n\r\n async generateVideo(\r\n asset: RichTextValidated,\r\n options: Partial<VideoGenerationOptions>\r\n ): Promise<void> {\r\n try {\r\n const finalOptions: VideoGenerationOptions = {\r\n width: asset.width ?? width,\r\n height: asset.height ?? height,\r\n fps: fps,\r\n duration: asset.animation?.duration ?? 3,\r\n outputPath: options.outputPath ?? \"output.mp4\",\r\n pixelRatio: asset.pixelRatio ?? pixelRatio,\r\n };\r\n\r\n const frameGenerator = async (time: number) => {\r\n return this.renderFrame(asset, time);\r\n };\r\n\r\n await videoGenerator.generateVideo(frameGenerator, finalOptions);\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to generate video: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n },\r\n\r\n destroy(): void {\r\n try {\r\n fonts.destroy();\r\n } catch (err) {\r\n console.error(`Error during cleanup: ${err instanceof Error ? err.message : String(err)}`);\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport * from \"../types\";\r\n","import Joi from \"joi\";\r\nimport { CANVAS_CONFIG } from \"../config/canvas-constants\";\r\n\r\nconst HEX6 = /^#[A-Fa-f0-9]{6}$/;\r\n\r\nconst gradientSchema = Joi.object({\r\n type: Joi.string().valid(\"linear\", \"radial\").default(\"linear\"),\r\n angle: Joi.number().min(0).max(360).default(0),\r\n stops: Joi.array()\r\n .items(\r\n Joi.object({\r\n offset: Joi.number().min(0).max(1).required(),\r\n color: Joi.string().pattern(HEX6).required()\r\n }).unknown(false)\r\n )\r\n .min(2)\r\n .required()\r\n}).unknown(false);\r\n\r\nconst shadowSchema = Joi.object({\r\n offsetX: Joi.number().default(0),\r\n offsetY: Joi.number().default(0),\r\n blur: Joi.number().min(0).default(0),\r\n color: Joi.string().pattern(HEX6).default(\"#000000\"),\r\n opacity: Joi.number().min(0).max(1).default(0.5)\r\n}).unknown(false);\r\n\r\nconst strokeSchema = Joi.object({\r\n width: Joi.number().min(0).default(0),\r\n color: Joi.string().pattern(HEX6).default(\"#000000\"),\r\n opacity: Joi.number().min(0).max(1).default(1)\r\n}).unknown(false);\r\n\r\nconst fontSchema = Joi.object({\r\n family: Joi.string().default(CANVAS_CONFIG.DEFAULTS.fontFamily),\r\n size: Joi.number()\r\n .min(CANVAS_CONFIG.LIMITS.minFontSize)\r\n .max(CANVAS_CONFIG.LIMITS.maxFontSize)\r\n .default(CANVAS_CONFIG.DEFAULTS.fontSize),\r\n weight: Joi.alternatives().try(Joi.string(), Joi.number()).default(\"400\"),\r\n style: Joi.string().valid(\"normal\", \"italic\", \"oblique\").default(\"normal\"),\r\n color: Joi.string().pattern(HEX6).default(CANVAS_CONFIG.DEFAULTS.color),\r\n opacity: Joi.number().min(0).max(1).default(1)\r\n}).unknown(false);\r\n\r\nconst styleSchema = Joi.object({\r\n letterSpacing: Joi.number().default(0),\r\n lineHeight: Joi.number().min(0).max(10).default(1.2),\r\n textTransform: Joi.string().valid(\"none\", \"uppercase\", \"lowercase\", \"capitalize\").default(\"none\"),\r\n textDecoration: Joi.string().valid(\"none\", \"underline\", \"line-through\").default(\"none\"),\r\n gradient: gradientSchema.optional()\r\n}).unknown(false);\r\n\r\nconst alignmentSchema = Joi.object({\r\n horizontal: Joi.string()\r\n .valid(\"left\", \"center\", \"right\")\r\n .default(CANVAS_CONFIG.DEFAULTS.textAlign),\r\n vertical: Joi.string().valid(\"top\", \"middle\", \"bottom\").default(\"middle\")\r\n}).unknown(false);\r\n\r\nconst animationSchema = Joi.object({\r\n preset: Joi.string().valid(...CANVAS_CONFIG.ANIMATION_TYPES as readonly string[]),\r\n speed: Joi.number().min(0.1).max(10).default(1),\r\n duration: Joi.number()\r\n .min(CANVAS_CONFIG.LIMITS.minDuration)\r\n .max(CANVAS_CONFIG.LIMITS.maxDuration)\r\n .optional(),\r\n style: Joi.string()\r\n .valid(\"character\", \"word\")\r\n .optional()\r\n .when(\"preset\", {\r\n is: Joi.valid(\"typewriter\", \"shift\"),\r\n then: Joi.optional(),\r\n otherwise: Joi.forbidden()\r\n }),\r\n direction: Joi.string()\r\n .optional()\r\n .when(\"preset\", {\r\n switch: [\r\n { is: \"ascend\", then: Joi.valid(\"up\", \"down\") },\r\n { is: \"shift\", then: Joi.valid(\"left\", \"right\", \"up\", \"down\") },\r\n { is: \"slideIn\", then: Joi.valid(\"left\", \"right\", \"up\", \"down\") },\r\n { is: \"movingLetters\", then: Joi.valid(\"left\", \"right\", \"up\", \"down\") }\r\n ],\r\n otherwise: Joi.forbidden()\r\n })\r\n}).unknown(false);\r\n\r\nconst backgroundSchema = Joi.object({\r\n color: Joi.string().pattern(HEX6).optional(),\r\n opacity: Joi.number().min(0).max(1).default(1),\r\n borderRadius: Joi.number().min(0).default(0)\r\n}).unknown(false);\r\n\r\nconst customFontSchema = Joi.object({\r\n src: Joi.string().uri().required(),\r\n family: Joi.string().required(),\r\n weight: Joi.alternatives().try(Joi.string(), Joi.number()).optional(),\r\n style: Joi.string().optional(),\r\n originalFamily: Joi.string().optional()\r\n}).unknown(false);\r\n\r\nexport const RichTextAssetSchema = Joi.object({\r\n type: Joi.string().valid(\"rich-text\").required(),\r\n text: Joi.string().allow(\"\").max(CANVAS_CONFIG.LIMITS.maxTextLength).default(\"\"),\r\n width: Joi.number()\r\n .min(CANVAS_CONFIG.LIMITS.minWidth)\r\n .max(CANVAS_CONFIG.LIMITS.maxWidth)\r\n .default(CANVAS_CONFIG.DEFAULTS.width)\r\n .optional(),\r\n height: Joi.number()\r\n .min(CANVAS_CONFIG.LIMITS.minHeight)\r\n .max(CANVAS_CONFIG.LIMITS.maxHeight)\r\n .default(CANVAS_CONFIG.DEFAULTS.height)\r\n .optional(),\r\n font: fontSchema.optional(),\r\n style: styleSchema.optional(),\r\n stroke: strokeSchema.optional(),\r\n shadow: shadowSchema.optional(),\r\n background: backgroundSchema.optional(),\r\n align: alignmentSchema.optional(),\r\n animation: animationSchema.optional(),\r\n customFonts: Joi.array().items(customFontSchema).optional(),\r\n cacheEnabled: Joi.boolean().default(true),\r\n pixelRatio: Joi.number().min(1).max(3).default(CANVAS_CONFIG.DEFAULTS.pixelRatio)\r\n}).unknown(false);\r\n\r\nexport type RichTextValidated = Required<{\r\n type: \"rich-text\";\r\n text: string;\r\n width?: number;\r\n height?: number;\r\n font?: {\r\n family: string;\r\n size: number;\r\n weight: string | number;\r\n style: \"normal\" | \"italic\" | \"oblique\";\r\n color: string;\r\n opacity: number;\r\n };\r\n style?: {\r\n letterSpacing: number;\r\n lineHeight: number;\r\n textTransform: \"none\" | \"uppercase\" | \"lowercase\" | \"capitalize\";\r\n textDecoration: \"none\" | \"underline\" | \"line-through\";\r\n gradient?: {\r\n type: \"linear\" | \"radial\";\r\n angle: number;\r\n stops: { offset: number; color: string }[];\r\n };\r\n };\r\n stroke?: { width: number; color: string; opacity: number };\r\n shadow?: { offsetX: number; offsetY: number; blur: number; color: string; opacity: number };\r\n background?: { color?: string; opacity: number; borderRadius: number };\r\n align?: { horizontal: \"left\" | \"center\" | \"right\"; vertical: \"top\" | \"middle\" | \"bottom\" };\r\n animation?: {\r\n preset: typeof CANVAS_CONFIG.ANIMATION_TYPES[number];\r\n speed: number;\r\n duration?: number;\r\n style?: \"character\" | \"word\";\r\n direction?: \"left\" | \"right\" | \"up\" | \"down\";\r\n };\r\n customFonts?: { src: string; family: string; weight?: string | number; style?: string; originalFamily?: string }[];\r\n cacheEnabled: boolean;\r\n pixelRatio: number;\r\n}>;\r\n","export const CANVAS_CONFIG = {\r\n DEFAULTS: {\r\n width: 800,\r\n height: 400,\r\n pixelRatio: 2,\r\n fontFamily: \"Roboto\",\r\n fontSize: 48,\r\n color: \"#000000\",\r\n textAlign: \"left\" as const\r\n },\r\n LIMITS: {\r\n minWidth: 1,\r\n maxWidth: 4096,\r\n minHeight: 1,\r\n maxHeight: 4096,\r\n minFontSize: 1,\r\n maxFontSize: 512,\r\n minDuration: 0.1,\r\n maxDuration: 120,\r\n maxTextLength: 10000\r\n },\r\n ANIMATION_TYPES: [\r\n \"typewriter\",\r\n \"fadeIn\",\r\n \"slideIn\",\r\n \"shift\",\r\n \"ascend\",\r\n \"movingLetters\"\r\n ] as const\r\n};\r\n","export interface HBBlob {\r\n destroy(): void;\r\n}\r\n\r\nexport interface HBFace {\r\n destroy(): void;\r\n upem?: number;\r\n}\r\n\r\nexport interface HBFont {\r\n destroy(): void;\r\n glyphToPath(glyphId: number): string;\r\n setScale(xScale: number, yScale: number): void;\r\n}\r\n\r\nexport interface HBGlyphInfo {\r\n g: number;\r\n ax: number;\r\n ay: number;\r\n dx: number;\r\n dy: number;\r\n cl: number;\r\n}\r\n\r\nexport interface HBBuffer {\r\n addText(text: string): void;\r\n guessSegmentProperties(): void;\r\n json(): HBGlyphInfo[];\r\n destroy(): void;\r\n}\r\n\r\nexport interface HB {\r\n createBlob(data: ArrayBuffer): HBBlob;\r\n createFace(blob: HBBlob, index: number): HBFace;\r\n createFont(face: HBFace): HBFont;\r\n createBuffer(): HBBuffer;\r\n shape(font: HBFont, buffer: HBBuffer): void;\r\n}\r\n\r\ninterface HarfBuzzJSModule {\r\n default: Promise<HB> | (() => Promise<HB>) | HB;\r\n}\r\n\r\nlet hbSingleton: HB | null = null;\r\n\r\nexport async function initHB(wasmBaseURL?: string): Promise<HB> {\r\n if (hbSingleton) return hbSingleton;\r\n\r\n try {\r\n const mod = (await import(\"harfbuzzjs\")) as HarfBuzzJSModule;\r\n\r\n const candidate = mod.default;\r\n\r\n let hb: HB;\r\n if (typeof candidate === \"function\") {\r\n hb = await candidate();\r\n } else if (candidate && typeof (candidate as Promise<HB>).then === \"function\") {\r\n hb = await (candidate as Promise<HB>);\r\n } else {\r\n hb = candidate as HB;\r\n }\r\n\r\n if (!hb || typeof hb.createBuffer !== \"function\" || typeof hb.createFont !== \"function\") {\r\n throw new Error(\"Failed to initialize HarfBuzz: unexpected export shape from 'harfbuzzjs'.\");\r\n }\r\n\r\n void wasmBaseURL;\r\n\r\n hbSingleton = hb;\r\n return hbSingleton;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to initialize HarfBuzz: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n}\r\n","// src/core/font-registry.ts\r\nimport { initHB, type HB, type HBBlob, type HBFace, type HBFont } from \"../wasm/hb-loader\";\r\n\r\nexport type FontDescriptor = { family: string; weight?: string | number; style?: string };\r\n\r\nexport class FontRegistry {\r\n private hb!: HB;\r\n private faces = new Map<string, HBFace>();\r\n private fonts = new Map<string, HBFont>();\r\n private blobs = new Map<string, HBBlob>();\r\n private wasmBaseURL?: string;\r\n private initPromise?: Promise<void>;\r\n\r\n private static fallbackLoader?: (desc: FontDescriptor) => Promise<ArrayBuffer | undefined>;\r\n static setFallbackLoader(loader: (desc: FontDescriptor) => Promise<ArrayBuffer | undefined>) {\r\n FontRegistry.fallbackLoader = loader;\r\n }\r\n\r\n constructor(wasmBaseURL?: string) {\r\n this.wasmBaseURL = wasmBaseURL;\r\n }\r\n\r\n async init(): Promise<void> {\r\n if (this.initPromise) {\r\n await this.initPromise;\r\n return;\r\n }\r\n if (this.hb) return;\r\n this.initPromise = this._doInit();\r\n try {\r\n await this.initPromise;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to initialize FontRegistry: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n\r\n private async _doInit(): Promise<void> {\r\n try {\r\n this.hb = await initHB(this.wasmBaseURL);\r\n } catch (error) {\r\n this.initPromise = undefined;\r\n throw error;\r\n }\r\n }\r\n\r\n async getHB(): Promise<HB> {\r\n if (!this.hb) {\r\n try {\r\n await this.init();\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to get HarfBuzz instance: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n return this.hb;\r\n }\r\n\r\n private key(desc: FontDescriptor): string {\r\n return `${desc.family}__${desc.weight ?? \"400\"}__${desc.style ?? \"normal\"}`;\r\n }\r\n\r\n async registerFromBytes(bytes: ArrayBuffer, desc: FontDescriptor): Promise<void> {\r\n try {\r\n if (!this.hb) await this.init();\r\n const k = this.key(desc);\r\n if (this.fonts.has(k)) return;\r\n\r\n const blob = this.hb.createBlob(bytes);\r\n const face = this.hb.createFace(blob, 0);\r\n const font = this.hb.createFont(face);\r\n\r\n const upem = (face as HBFaceWithUpem).upem || 1000;\r\n (font as HBFontWithScale).setScale(upem, upem);\r\n\r\n this.blobs.set(k, blob);\r\n this.faces.set(k, face);\r\n this.fonts.set(k, font);\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to register font \"${desc.family}\": ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n\r\n private async tryFallbackInstall(desc: FontDescriptor): Promise<boolean> {\r\n const loader = FontRegistry.fallbackLoader;\r\n if (!loader) return false;\r\n try {\r\n const bytes = await loader({\r\n family: desc.family,\r\n weight: desc.weight ?? \"400\",\r\n style: desc.style ?? \"normal\",\r\n });\r\n if (!bytes) return false;\r\n await this.registerFromBytes(bytes, {\r\n family: desc.family,\r\n weight: desc.weight ?? \"400\",\r\n style: desc.style ?? \"normal\",\r\n });\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async getFont(desc: FontDescriptor): Promise<HBFont> {\r\n try {\r\n if (!this.hb) await this.init();\r\n const k = this.key(desc);\r\n let f = this.fonts.get(k);\r\n if (!f) {\r\n const installed = await this.tryFallbackInstall(desc);\r\n f = installed ? this.fonts.get(k) : undefined;\r\n }\r\n if (!f) throw new Error(`Font not registered for ${k}`);\r\n return f;\r\n } catch (err) {\r\n if (err instanceof Error && err.message.includes(\"Font not registered\")) {\r\n throw err;\r\n }\r\n throw new Error(\r\n `Failed to get font \"${desc.family}\": ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n\r\n async getFace(desc: FontDescriptor): Promise<HBFace | undefined> {\r\n try {\r\n if (!this.hb) await this.init();\r\n const k = this.key(desc);\r\n let face = this.faces.get(k);\r\n if (!face) {\r\n const installed = await this.tryFallbackInstall(desc);\r\n face = installed ? this.faces.get(k) : undefined;\r\n }\r\n return face;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to get face for \"${desc.family}\": ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n\r\n async getUnitsPerEm(desc: FontDescriptor): Promise<number> {\r\n try {\r\n const face = await this.getFace(desc);\r\n return (face as HBFaceWithUpem)?.upem || 1000;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to get units per em for \"${desc.family}\": ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n\r\n async glyphPath(desc: FontDescriptor, glyphId: number): Promise<string> {\r\n try {\r\n const font = await this.getFont(desc);\r\n const path = font.glyphToPath(glyphId);\r\n return path && path !== \"\" ? path : \"M 0 0\";\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to get glyph path for glyph ${glyphId} in font \"${desc.family}\": ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n\r\n destroy(): void {\r\n try {\r\n for (const [, f] of this.fonts) {\r\n try {\r\n f.destroy();\r\n } catch (err) {\r\n console.error(\r\n `Error destroying font: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n for (const [, f] of this.faces) {\r\n try {\r\n f.destroy();\r\n } catch (err) {\r\n console.error(\r\n `Error destroying face: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n for (const [, b] of this.blobs) {\r\n try {\r\n b.destroy();\r\n } catch (err) {\r\n console.error(\r\n `Error destroying blob: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n this.fonts.clear();\r\n this.faces.clear();\r\n this.blobs.clear();\r\n this.hb = undefined!;\r\n this.initPromise = undefined;\r\n } catch (err) {\r\n console.error(\r\n `Error during FontRegistry cleanup: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n}\r\n\r\ninterface HBFaceWithUpem extends HBFace {\r\n upem?: number;\r\n}\r\ninterface HBFontWithScale extends HBFont {\r\n setScale(xScale: number, yScale: number): void;\r\n}\r\n","import { FontRegistry, FontDescriptor } from \"./font-registry\";\r\nimport { Glyph, ShapedLine } from \"../types\";\r\nimport type { HBGlyphInfo } from \"../wasm/hb-loader\";\r\n\r\nexport type ShapeParams = {\r\n text: string;\r\n width: number;\r\n letterSpacing: number;\r\n fontSize: number;\r\n lineHeight: number;\r\n desc: FontDescriptor;\r\n textTransform: \"none\" | \"uppercase\" | \"lowercase\" | \"capitalize\";\r\n};\r\n\r\nexport class LayoutEngine {\r\n constructor(private fonts: FontRegistry) {}\r\n\r\n private transformText(t: string, tr: ShapeParams[\"textTransform\"]): string {\r\n switch (tr) {\r\n case \"uppercase\":\r\n return t.toUpperCase();\r\n case \"lowercase\":\r\n return t.toLowerCase();\r\n case \"capitalize\":\r\n return t.replace(/\\b\\w/g, (c) => c.toUpperCase());\r\n default:\r\n return t;\r\n }\r\n }\r\n\r\n private async shapeFull(text: string, desc: FontDescriptor): Promise<HBGlyphInfo[]> {\r\n try {\r\n const hb = await this.fonts.getHB();\r\n const buffer = hb.createBuffer();\r\n\r\n try {\r\n buffer.addText(text);\r\n buffer.guessSegmentProperties();\r\n\r\n const font = await this.fonts.getFont(desc);\r\n const face = await this.fonts.getFace(desc);\r\n\r\n const upem = (face as { upem?: number })?.upem || 1000;\r\n (font as { setScale(x: number, y: number): void }).setScale(upem, upem);\r\n\r\n hb.shape(font, buffer);\r\n\r\n const result = buffer.json();\r\n return result;\r\n } finally {\r\n try {\r\n buffer.destroy();\r\n } catch (err) {\r\n console.error(\r\n `Error destroying HarfBuzz buffer: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to shape text with font \"${desc.family}\": ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n\r\n async layout(params: ShapeParams): Promise<ShapedLine[]> {\r\n try {\r\n const { textTransform, desc, fontSize, letterSpacing, width } = params;\r\n const input = this.transformText(params.text, textTransform);\r\n\r\n if (!input || input.length === 0) {\r\n return [];\r\n }\r\n\r\n let shaped: HBGlyphInfo[];\r\n try {\r\n shaped = await this.shapeFull(input, desc);\r\n } catch (err) {\r\n throw new Error(`Text shaping failed: ${err instanceof Error ? err.message : String(err)}`);\r\n }\r\n\r\n let upem: number;\r\n try {\r\n const face = await this.fonts.getFace(desc);\r\n upem = (face as { upem?: number })?.upem || 1000;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to get font metrics: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n\r\n const scale = fontSize / upem;\r\n\r\n const glyphs: Glyph[] = shaped.map((g) => {\r\n const charIndex = g.cl;\r\n let char: string | undefined;\r\n\r\n if (charIndex >= 0 && charIndex < input.length) {\r\n char = input[charIndex];\r\n }\r\n\r\n return {\r\n id: g.g,\r\n xAdvance: g.ax * scale + letterSpacing,\r\n xOffset: g.dx * scale,\r\n yOffset: -g.dy * scale,\r\n cluster: g.cl,\r\n char: char,\r\n };\r\n });\r\n\r\n const lines: ShapedLine[] = [];\r\n let currentLine: Glyph[] = [];\r\n let currentWidth = 0;\r\n\r\n const spaceIndices = new Set<number>();\r\n for (let i = 0; i < input.length; i++) {\r\n if (input[i] === \" \") {\r\n spaceIndices.add(i);\r\n }\r\n }\r\n\r\n let lastBreakIndex = -1;\r\n\r\n for (let i = 0; i < glyphs.length; i++) {\r\n const glyph = glyphs[i];\r\n const glyphWidth = glyph.xAdvance;\r\n\r\n if (glyph.char === \"\\n\") {\r\n if (currentLine.length > 0) {\r\n lines.push({\r\n glyphs: currentLine,\r\n width: currentWidth,\r\n y: 0,\r\n });\r\n }\r\n currentLine = [];\r\n currentWidth = 0;\r\n lastBreakIndex = i;\r\n continue;\r\n }\r\n\r\n if (currentWidth + glyphWidth > width && currentLine.length > 0) {\r\n if (lastBreakIndex > -1) {\r\n const breakPoint = lastBreakIndex - (i - currentLine.length) + 1;\r\n const nextLine = currentLine.splice(breakPoint);\r\n\r\n const lineWidth = currentLine.reduce((sum, g) => sum + g.xAdvance, 0);\r\n\r\n lines.push({\r\n glyphs: currentLine,\r\n width: lineWidth,\r\n y: 0,\r\n });\r\n\r\n currentLine = nextLine;\r\n currentWidth = nextLine.reduce((sum, g) => sum + g.xAdvance, 0);\r\n } else {\r\n lines.push({\r\n glyphs: currentLine,\r\n width: currentWidth,\r\n y: 0,\r\n });\r\n currentLine = [];\r\n currentWidth = 0;\r\n }\r\n lastBreakIndex = -1;\r\n }\r\n\r\n currentLine.push(glyph);\r\n currentWidth += glyphWidth;\r\n\r\n if (spaceIndices.has(glyph.cluster)) {\r\n lastBreakIndex = i;\r\n }\r\n }\r\n\r\n if (currentLine.length > 0) {\r\n lines.push({\r\n glyphs: currentLine,\r\n width: currentWidth,\r\n y: 0,\r\n });\r\n }\r\n\r\n const lineHeight = params.lineHeight * fontSize;\r\n for (let i = 0; i < lines.length; i++) {\r\n lines[i].y = (i + 1) * lineHeight;\r\n }\r\n\r\n return lines;\r\n } catch (err) {\r\n if (err instanceof Error) {\r\n throw err;\r\n }\r\n throw new Error(`Layout failed: ${String(err)}`);\r\n }\r\n }\r\n}\r\n","import { GradientSpec } from \"../types\";\r\n\r\nexport function gradientSpecFrom(\r\n g: { type: \"linear\" | \"radial\"; angle: number; stops: { offset: number; color: string }[] },\r\n opacity: number\r\n): GradientSpec {\r\n if (g.type === \"linear\") {\r\n return { kind: \"linear\", angle: g.angle, stops: g.stops, opacity };\r\n } else {\r\n return { kind: \"radial\", stops: g.stops, opacity };\r\n }\r\n}\r\n","export function decorationGeometry(\r\n kind: \"underline\" | \"line-through\",\r\n p: { baselineY: number; fontSize: number; lineWidth: number; xStart: number }\r\n) {\r\n const thickness = Math.max(1, Math.round(p.fontSize * 0.05));\r\n let y = p.baselineY + Math.round(p.fontSize * 0.1);\r\n if (kind === \"line-through\") y = p.baselineY - Math.round(p.fontSize * 0.3);\r\n return { x1: p.xStart, x2: p.xStart + p.lineWidth, y, width: thickness };\r\n}\r\n","import { DrawOp, GradientSpec, ShapedLine } from \"../types\";\r\nimport { gradientSpecFrom } from \"./gradients\";\r\nimport { decorationGeometry } from \"./decoration\";\r\n\r\nexport type PaintParams = {\r\n canvas: { width: number; height: number; pixelRatio: number };\r\n textRect: { x: number; y: number; width: number; height: number };\r\n lines: ShapedLine[];\r\n font: { family: string; size: number; weight: string | number; style: string; color: string; opacity: number };\r\n style: {\r\n lineHeight: number;\r\n textDecoration: \"none\" | \"underline\" | \"line-through\";\r\n gradient?: { type: \"linear\" | \"radial\"; angle: number; stops: { offset: number; color: string }[] };\r\n };\r\n stroke?: { width: number; color: string; opacity: number };\r\n shadow?: { offsetX: number; offsetY: number; blur: number; color: string; opacity: number };\r\n align: { horizontal: \"left\" | \"center\" | \"right\"; vertical: \"top\" | \"middle\" | \"bottom\" };\r\n background?: { color?: string; opacity: number; borderRadius: number };\r\n glyphPathProvider: (glyphId: number) => Promise<string>;\r\n /** UPEM for scaling glyph paths from font units → px */\r\n getUnitsPerEm: () => Promise<number>;\r\n};\r\n\r\nexport async function buildDrawOps(p: PaintParams): Promise<DrawOp[]> {\r\n const ops: DrawOp[] = [];\r\n\r\n // Begin frame / background\r\n ops.push({\r\n op: \"BeginFrame\",\r\n width: p.canvas.width,\r\n height: p.canvas.height,\r\n pixelRatio: p.canvas.pixelRatio,\r\n clear: true,\r\n bg: p.background && p.background.color\r\n ? { color: p.background.color, opacity: p.background.opacity, radius: p.background.borderRadius }\r\n : undefined\r\n });\r\n\r\n if (p.lines.length === 0) return ops;\r\n\r\n // Font units → px\r\n const upem = Math.max(1, await p.getUnitsPerEm());\r\n const scale = p.font.size / upem;\r\n\r\n // Block metrics\r\n const blockHeight = p.lines[p.lines.length - 1].y;\r\n\r\n // Vertical anchor\r\n let blockY: number;\r\n switch (p.align.vertical) {\r\n case \"top\": blockY = p.font.size; break;\r\n case \"bottom\": blockY = p.textRect.height - blockHeight + p.font.size; break;\r\n case \"middle\":\r\n default: blockY = (p.textRect.height - blockHeight) / 2 + p.font.size; break;\r\n }\r\n\r\n // Fill style (solid or gradient)\r\n const fill: GradientSpec = p.style.gradient\r\n ? gradientSpecFrom(p.style.gradient, 1)\r\n : { kind: \"solid\", color: p.font.color, opacity: p.font.opacity };\r\n\r\n // Decoration/cursor color should match text (for gradient, use the last stop as a representative color)\r\n const decoColor = p.style.gradient\r\n ? p.style.gradient.stops[p.style.gradient.stops.length - 1]?.color ?? p.font.color\r\n : p.font.color;\r\n\r\n // Track global text bounds in world space so painters can build a single gradient\r\n let gMinX = Infinity, gMinY = Infinity, gMaxX = -Infinity, gMaxY = -Infinity;\r\n\r\n for (const line of p.lines) {\r\n // Horizontal anchor\r\n let lineX: number;\r\n switch (p.align.horizontal) {\r\n case \"left\": lineX = 0; break;\r\n case \"right\": lineX = p.textRect.width - line.width; break;\r\n case \"center\":\r\n default: lineX = (p.textRect.width - line.width) / 2; break;\r\n }\r\n\r\n let xCursor = lineX;\r\n const baselineY = blockY + line.y - p.font.size;\r\n\r\n for (const glyph of line.glyphs) {\r\n const path = await p.glyphPathProvider(glyph.id);\r\n if (!path || path === \"M 0 0\") {\r\n xCursor += glyph.xAdvance;\r\n continue;\r\n }\r\n\r\n const glyphX = xCursor + glyph.xOffset;\r\n const glyphY = baselineY + glyph.yOffset;\r\n\r\n // Update global bbox using path's local bounds mapped to world (scale s, flip Y)\r\n const pb = computePathBounds(path);\r\n const x1 = glyphX + scale * pb.x;\r\n const x2 = glyphX + scale * (pb.x + pb.w);\r\n const y1 = glyphY - scale * (pb.y + pb.h);\r\n const y2 = glyphY - scale * pb.y;\r\n if (x1 < gMinX) gMinX = x1;\r\n if (y1 < gMinY) gMinY = y1;\r\n if (x2 > gMaxX) gMaxX = x2;\r\n if (y2 > gMaxY) gMaxY = y2;\r\n\r\n // 1) Shadow (under everything)\r\n if (p.shadow && p.shadow.blur > 0) {\r\n ops.push({\r\n isShadow: true,\r\n op: \"FillPath\",\r\n path,\r\n x: glyphX + p.shadow.offsetX,\r\n y: glyphY + p.shadow.offsetY,\r\n scale,\r\n fill: { kind: \"solid\", color: p.shadow.color, opacity: p.shadow.opacity }\r\n });\r\n }\r\n\r\n // 2) Stroke (under fill)\r\n if (p.stroke && p.stroke.width > 0) {\r\n ops.push({\r\n op: \"StrokePath\",\r\n path,\r\n x: glyphX,\r\n y: glyphY,\r\n scale,\r\n width: p.stroke.width,\r\n color: p.stroke.color,\r\n opacity: p.stroke.opacity\r\n });\r\n }\r\n\r\n // 3) Fill (on top)\r\n ops.push({\r\n op: \"FillPath\",\r\n path,\r\n x: glyphX,\r\n y: glyphY,\r\n scale,\r\n fill\r\n });\r\n\r\n xCursor += glyph.xAdvance;\r\n }\r\n\r\n // Decoration lines (use text/deco color)\r\n if (p.style.textDecoration !== \"none\") {\r\n const deco = decorationGeometry(p.style.textDecoration, {\r\n baselineY,\r\n fontSize: p.font.size,\r\n lineWidth: line.width,\r\n xStart: lineX\r\n });\r\n\r\n ops.push({\r\n op: \"DecorationLine\",\r\n from: { x: deco.x1, y: deco.y },\r\n to: { x: deco.x2, y: deco.y },\r\n width: deco.width,\r\n color: decoColor,\r\n opacity: p.font.opacity\r\n });\r\n }\r\n }\r\n\r\n // Attach a full-text gradient bbox to all glyph fills (stable across typewriter)\r\n if (gMinX !== Infinity) {\r\n const gbox = { x: gMinX, y: gMinY, w: Math.max(1, gMaxX - gMinX), h: Math.max(1, gMaxY - gMinY) };\r\n for (const op of ops) {\r\n if (op.op === \"FillPath\" && !(op).isShadow) {\r\n (op).gradientBBox = gbox;\r\n }\r\n }\r\n }\r\n\r\n return ops;\r\n}\r\n\r\n/* ----------------- local helpers ----------------- */\r\nfunction tokenizePath(d: string): string[] {\r\n return d.match(/[MLCQZ]|-?\\d*\\.?\\d+(?:e[-+]?\\d+)?/gi) ?? [];\r\n}\r\nfunction computePathBounds(d: string) {\r\n const t = tokenizePath(d);\r\n let i = 0;\r\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\r\n const touch = (x: number, y: number) => { if (x < minX) minX = x; if (y < minY) minY = y; if (x > maxX) maxX = x; if (y > maxY) maxY = y; };\r\n while (i < t.length) {\r\n const cmd = t[i++];\r\n switch (cmd) {\r\n case \"M\":\r\n case \"L\": { const x = parseFloat(t[i++]); const y = parseFloat(t[i++]); touch(x, y); break; }\r\n case \"C\": {\r\n const c1x = parseFloat(t[i++]); const c1y = parseFloat(t[i++]);\r\n const c2x = parseFloat(t[i++]); const c2y = parseFloat(t[i++]);\r\n const x = parseFloat(t[i++]); const y = parseFloat(t[i++]);\r\n touch(c1x, c1y); touch(c2x, c2y); touch(x, y); break;\r\n }\r\n case \"Q\": { const cx = parseFloat(t[i++]); const cy = parseFloat(t[i++]); const x = parseFloat(t[i++]); const y = parseFloat(t[i++]); touch(cx, cy); touch(x, y); break; }\r\n case \"Z\": break;\r\n }\r\n }\r\n if (minX === Infinity) return { x: 0, y: 0, w: 0, h: 0 };\r\n return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };\r\n}","import { DrawOp, Glyph, ShapedLine } from \"../types\";\r\n\r\nexport type AnimationInput = {\r\n preset?: \"typewriter\" | \"fadeIn\" | \"slideIn\" | \"shift\" | \"ascend\" | \"movingLetters\";\r\n speed: number;\r\n duration?: number;\r\n style?: \"character\" | \"word\";\r\n direction?: \"left\" | \"right\" | \"up\" | \"down\";\r\n};\r\n\r\nconst DECORATION_DONE_THRESHOLD = 0.999;\r\n\r\nexport function applyAnimation(\r\n ops: DrawOp[],\r\n lines: ShapedLine[],\r\n p: { t: number; fontSize: number; anim?: AnimationInput }\r\n): DrawOp[] {\r\n if (!p.anim || !p.anim.preset) return ops;\r\n\r\n const { preset } = p.anim;\r\n const totalGlyphs = lines.reduce((s, l) => s + l.glyphs.length, 0);\r\n const duration = p.anim.duration ?? Math.max(0.3, totalGlyphs / 30 / p.anim.speed);\r\n const progress = Math.max(0, Math.min(1, p.t / duration));\r\n\r\n switch (preset) {\r\n case \"typewriter\":\r\n return applyTypewriterAnimation(\r\n ops,\r\n lines,\r\n progress,\r\n p.anim.style,\r\n p.fontSize,\r\n p.t,\r\n duration\r\n );\r\n case \"fadeIn\":\r\n return applyFadeInAnimation(ops, progress);\r\n case \"slideIn\":\r\n return applySlideInAnimation(ops, progress, p.anim.direction ?? \"left\", p.fontSize);\r\n case \"shift\":\r\n return applyShiftAnimation(\r\n ops,\r\n lines,\r\n progress,\r\n p.anim.direction ?? \"left\",\r\n p.fontSize,\r\n p.anim.style,\r\n duration\r\n );\r\n case \"ascend\":\r\n return applyAscendAnimation(\r\n ops,\r\n lines,\r\n progress,\r\n p.anim.direction ?? \"up\",\r\n p.fontSize,\r\n duration\r\n );\r\n case \"movingLetters\":\r\n return applyMovingLettersAnimation(ops, progress, p.anim.direction ?? \"up\", p.fontSize);\r\n default:\r\n return ops;\r\n }\r\n}\r\n\r\n// ---- helpers\r\nconst isShadowFill = (op: DrawOp) => op.op === \"FillPath\" && (op).isShadow === true;\r\nconst isGlyphFill = (op: DrawOp) => op.op === \"FillPath\" && !(op).isShadow === true;\r\n\r\n// Try to derive a text color from the first fill we find\r\nfunction getTextColorFromOps(ops: DrawOp[]): string {\r\n for (const op of ops) {\r\n if (op.op === \"FillPath\") {\r\n const fill: any = (op).fill;\r\n if (fill?.kind === \"solid\") return fill.color;\r\n if (\r\n (fill?.kind === \"linear\" || fill?.kind === \"radial\") &&\r\n Array.isArray(fill.stops) &&\r\n fill.stops.length\r\n ) {\r\n return fill.stops[fill.stops.length - 1].color || \"#000000\";\r\n }\r\n }\r\n }\r\n return \"#000000\";\r\n}\r\n\r\n// ---------- TYPEWRITER ----------\r\nfunction applyTypewriterAnimation(\r\n ops: DrawOp[],\r\n lines: ShapedLine[],\r\n progress: number,\r\n style: \"character\" | \"word\" | undefined,\r\n fontSize: number,\r\n time: number,\r\n duration: number\r\n): DrawOp[] {\r\n const byWord = style === \"word\";\r\n\r\n if (byWord) {\r\n const wordSegments = getWordSegments(lines);\r\n const totalWords = wordSegments.length;\r\n const visibleWords = Math.floor(progress * totalWords);\r\n if (visibleWords === 0) return ops.filter((x) => x.op === \"BeginFrame\");\r\n\r\n let totalVisibleGlyphs = 0;\r\n for (let i = 0; i < Math.min(visibleWords, wordSegments.length); i++) {\r\n totalVisibleGlyphs += wordSegments[i].glyphCount;\r\n }\r\n const visibleOpsRaw = sliceGlyphOps(ops, totalVisibleGlyphs);\r\n\r\n const visibleOps =\r\n progress >= DECORATION_DONE_THRESHOLD\r\n ? visibleOpsRaw\r\n : visibleOpsRaw.filter((o) => o.op !== \"DecorationLine\");\r\n\r\n if (progress < 1 && totalVisibleGlyphs > 0) {\r\n return addTypewriterCursor(visibleOps, totalVisibleGlyphs, fontSize, time);\r\n }\r\n return visibleOps;\r\n } else {\r\n const totalGlyphs = lines.reduce((s, l) => s + l.glyphs.length, 0);\r\n const visibleGlyphs = Math.floor(progress * totalGlyphs);\r\n if (visibleGlyphs === 0) return ops.filter((x) => x.op === \"BeginFrame\");\r\n\r\n const visibleOpsRaw = sliceGlyphOps(ops, visibleGlyphs);\r\n\r\n const visibleOps =\r\n progress >= DECORATION_DONE_THRESHOLD\r\n ? visibleOpsRaw\r\n : visibleOpsRaw.filter((o) => o.op !== \"DecorationLine\");\r\n\r\n if (progress < 1 && visibleGlyphs > 0) {\r\n return addTypewriterCursor(visibleOps, visibleGlyphs, fontSize, time);\r\n }\r\n return visibleOps;\r\n }\r\n}\r\n\r\n// ---------- ASCEND ----------\r\nfunction applyAscendAnimation(\r\n ops: DrawOp[],\r\n lines: ShapedLine[],\r\n progress: number,\r\n direction: \"left\" | \"right\" | \"up\" | \"down\",\r\n fontSize: number,\r\n duration: number\r\n): DrawOp[] {\r\n const wordSegments = getWordSegments(lines);\r\n const totalWords = wordSegments.length;\r\n if (totalWords === 0) return ops;\r\n\r\n const result: DrawOp[] = [];\r\n let glyphIndex = 0;\r\n\r\n for (const op of ops) {\r\n if (op.op === \"BeginFrame\") {\r\n result.push(op);\r\n break;\r\n }\r\n }\r\n\r\n for (const op of ops) {\r\n if (op.op === \"FillPath\" || op.op === \"StrokePath\") {\r\n // which word owns this glyph\r\n let wordIndex = -1,\r\n acc = 0;\r\n for (let i = 0; i < wordSegments.length; i++) {\r\n const gcount = wordSegments[i].glyphCount;\r\n if (glyphIndex >= acc && glyphIndex < acc + gcount) {\r\n wordIndex = i;\r\n break;\r\n }\r\n acc += gcount;\r\n }\r\n if (wordIndex >= 0) {\r\n const startF = (wordIndex / Math.max(1, totalWords)) * (duration / duration);\r\n const endF = Math.min(1, startF + 0.3);\r\n if (progress >= endF) {\r\n result.push(op);\r\n } else if (progress > startF) {\r\n const local = (progress - startF) / Math.max(1e-6, endF - startF);\r\n const ease = easeOutCubic(Math.min(1, local));\r\n const startOffset = direction === \"up\" ? fontSize * 0.4 : -fontSize * 0.4;\r\n const animated: any = { ...op, y: op.y + startOffset * (1 - ease) };\r\n if (op.op === \"FillPath\") {\r\n if (animated.fill.kind === \"solid\")\r\n animated.fill = { ...animated.fill, opacity: animated.fill.opacity * ease };\r\n else animated.fill = { ...animated.fill, opacity: (animated.fill.opacity ?? 1) * ease };\r\n } else {\r\n animated.opacity = animated.opacity * ease;\r\n }\r\n result.push(animated);\r\n }\r\n }\r\n if (isGlyphFill(op)) glyphIndex++;\r\n } else if (op.op === \"DecorationLine\") {\r\n if (progress >= DECORATION_DONE_THRESHOLD) {\r\n result.push(op);\r\n }\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n// ---------- SHIFT ----------\r\nfunction applyShiftAnimation(\r\n ops: DrawOp[],\r\n lines: ShapedLine[],\r\n progress: number,\r\n direction: \"left\" | \"right\" | \"up\" | \"down\",\r\n fontSize: number,\r\n style: \"character\" | \"word\" | undefined,\r\n duration: number\r\n): DrawOp[] {\r\n const byWord = style === \"word\";\r\n const startOffsets = {\r\n left: { x: fontSize * 0.6, y: 0 },\r\n right: { x: -fontSize * 0.6, y: 0 },\r\n up: { x: 0, y: fontSize * 0.6 },\r\n down: { x: 0, y: -fontSize * 0.6 },\r\n };\r\n const offset = startOffsets[direction];\r\n\r\n const wordSegments = byWord ? getWordSegments(lines) : [];\r\n const totalGlyphs = lines.reduce((s, l) => s + l.glyphs.length, 0);\r\n const totalUnits = byWord ? wordSegments.length : totalGlyphs;\r\n if (totalUnits === 0) return ops;\r\n\r\n const result: DrawOp[] = [];\r\n for (const op of ops) {\r\n if (op.op === \"BeginFrame\") {\r\n result.push(op);\r\n break;\r\n }\r\n }\r\n\r\n const windowDuration = 0.3; // each unit animates for 0.3s of total duration\r\n const overlapFactor = 0.7; // overlapping reveal\r\n const staggerDelay = (duration * overlapFactor) / Math.max(1, totalUnits - 1);\r\n\r\n const windowFor = (unitIdx: number) => {\r\n const startTime = unitIdx * staggerDelay;\r\n const startF = startTime / duration;\r\n const endF = Math.min(1, (startTime + windowDuration) / duration);\r\n return { startF, endF };\r\n };\r\n\r\n let glyphIndex = 0;\r\n for (const op of ops) {\r\n if (op.op !== \"FillPath\" && op.op !== \"StrokePath\") {\r\n if (op.op === \"DecorationLine\" && progress > 0.8) result.push(op);\r\n continue;\r\n }\r\n\r\n let unitIndex: number;\r\n if (!byWord) {\r\n unitIndex = glyphIndex;\r\n } else {\r\n let wordIndex = -1,\r\n acc = 0;\r\n for (let i = 0; i < wordSegments.length; i++) {\r\n const gcount = wordSegments[i].glyphCount;\r\n if (glyphIndex >= acc && glyphIndex < acc + gcount) {\r\n wordIndex = i;\r\n break;\r\n }\r\n acc += gcount;\r\n }\r\n unitIndex = Math.max(0, wordIndex);\r\n }\r\n\r\n const { startF, endF } = windowFor(unitIndex);\r\n\r\n if (progress <= startF) {\r\n const animated: any = { ...op, x: op.x + offset.x, y: op.y + offset.y };\r\n if (op.op === \"FillPath\") {\r\n if (animated.fill.kind === \"solid\") animated.fill = { ...animated.fill, opacity: 0 };\r\n else animated.fill = { ...animated.fill, opacity: 0 };\r\n } else {\r\n animated.opacity = 0;\r\n }\r\n result.push(animated);\r\n } else if (progress >= endF) {\r\n result.push(op);\r\n } else {\r\n const local = (progress - startF) / Math.max(1e-6, endF - startF);\r\n const ease = easeOutCubic(Math.min(1, local));\r\n const dx = offset.x * (1 - ease);\r\n const dy = offset.y * (1 - ease);\r\n const animated: any = { ...op, x: op.x + dx, y: op.y + dy };\r\n\r\n if (op.op === \"FillPath\") {\r\n const targetOpacity =\r\n animated.fill.kind === \"solid\" ? animated.fill.opacity : animated.fill.opacity ?? 1;\r\n if (animated.fill.kind === \"solid\")\r\n animated.fill = { ...animated.fill, opacity: targetOpacity * ease };\r\n else animated.fill = { ...animated.fill, opacity: targetOpacity * ease };\r\n } else {\r\n animated.opacity = animated.opacity * ease;\r\n }\r\n result.push(animated);\r\n }\r\n\r\n if (isGlyphFill(op)) glyphIndex++;\r\n }\r\n return result;\r\n}\r\n\r\n// ---------- FADE / SLIDE / WAVE ----------\r\nfunction applyFadeInAnimation(ops: DrawOp[], progress: number): DrawOp[] {\r\n const alpha = easeOutQuad(progress);\r\n const scale = 0.95 + 0.05 * alpha;\r\n return scaleAndFade(ops, alpha, scale);\r\n}\r\nfunction applySlideInAnimation(\r\n ops: DrawOp[],\r\n progress: number,\r\n direction: \"left\" | \"right\" | \"up\" | \"down\",\r\n fontSize: number\r\n): DrawOp[] {\r\n const easeProgress = easeOutCubic(progress);\r\n const shift = shiftFor(1 - easeProgress, direction, fontSize * 2);\r\n const alpha = easeOutQuad(progress);\r\n return translateGlyphOps(ops, shift.dx, shift.dy, alpha);\r\n}\r\nfunction applyMovingLettersAnimation(\r\n ops: DrawOp[],\r\n progress: number,\r\n direction: \"left\" | \"right\" | \"up\" | \"down\",\r\n fontSize: number\r\n): DrawOp[] {\r\n const amp = fontSize * 0.3;\r\n return waveTransform(ops, direction, amp, progress);\r\n}\r\n\r\n// ---------- word segmentation / slicing ----------\r\nfunction getWordSegments(lines: ShapedLine[]) {\r\n const segments: any = [];\r\n let totalGlyphIndex = 0;\r\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\r\n const line = lines[lineIndex];\r\n const words = segmentLineBySpaces(line);\r\n for (const word of words) {\r\n if (word.length > 0)\r\n segments.push({ startGlyph: totalGlyphIndex, glyphCount: word.length, lineIndex });\r\n totalGlyphIndex += word.length;\r\n }\r\n }\r\n return segments;\r\n}\r\nfunction segmentLineBySpaces(line: ShapedLine): Glyph[][] {\r\n const words: Glyph[][] = [];\r\n let current: Glyph[] = [];\r\n for (const g of line.glyphs) {\r\n const isSpace = g.char === \" \" || g.char === \"\\t\" || g.char === \"\\n\";\r\n if (isSpace) {\r\n if (current.length) {\r\n words.push([...current]);\r\n current = [];\r\n }\r\n } else {\r\n current.push(g);\r\n }\r\n }\r\n if (current.length) words.push(current);\r\n return words;\r\n}\r\n\r\n/** Include BOTH stroke+fill for the first `maxGlyphs` glyphs; nothing from later glyphs.\r\n * Stroke is only included if its corresponding fill will be shown (so it never appears early). */\r\nfunction sliceGlyphOps(ops: DrawOp[], maxGlyphs: number): DrawOp[] {\r\n const result: DrawOp[] = [];\r\n let glyphCount = 0;\r\n let foundGlyphs = false;\r\n\r\n for (const op of ops) {\r\n if (op.op === \"BeginFrame\") {\r\n result.push(op);\r\n continue;\r\n }\r\n\r\n if (op.op === \"FillPath\" && !isShadowFill(op)) {\r\n if (glyphCount < maxGlyphs) {\r\n result.push(op);\r\n foundGlyphs = true;\r\n }\r\n glyphCount++; // count only real glyph fills\r\n continue;\r\n }\r\n\r\n if (op.op === \"StrokePath\") {\r\n // Include stroke only if the upcoming fill is within range\r\n if (glyphCount < maxGlyphs) result.push(op);\r\n continue;\r\n }\r\n\r\n if (op.op === \"FillPath\" && isShadowFill(op)) {\r\n if (glyphCount < maxGlyphs) result.push(op);\r\n continue;\r\n }\r\n\r\n if (op.op === \"DecorationLine\" && foundGlyphs) {\r\n result.push(op);\r\n continue;\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction addTypewriterCursor(\r\n ops: DrawOp[],\r\n glyphCount: number,\r\n fontSize: number,\r\n time: number\r\n): DrawOp[] {\r\n const blinkRate = 2;\r\n const cursorVisible = Math.floor(time * blinkRate * 2) % 2 === 0;\r\n if (!cursorVisible || glyphCount === 0) return ops;\r\n\r\n let last: DrawOp | null = null;\r\n let count = 0;\r\n for (const op of ops) {\r\n if (op.op === \"FillPath\" && !isShadowFill(op)) {\r\n count++;\r\n if (count === glyphCount) {\r\n last = op;\r\n break;\r\n }\r\n }\r\n }\r\n if (last && last.op === \"FillPath\") {\r\n const color = getTextColorFromOps(ops);\r\n const cursorX = last.x + fontSize * 0.5;\r\n const cursorY = last.y;\r\n\r\n const cursorOp: DrawOp = {\r\n op: \"DecorationLine\",\r\n from: { x: cursorX, y: cursorY - fontSize * 0.7 },\r\n to: { x: cursorX, y: cursorY + fontSize * 0.1 },\r\n width: Math.max(2, fontSize / 25),\r\n color,\r\n opacity: 1,\r\n };\r\n return [...ops, cursorOp];\r\n }\r\n return ops;\r\n}\r\n\r\n// ---------- transforms ----------\r\nfunction scaleAndFade(ops: DrawOp[], alpha: number, scale: number): DrawOp[] {\r\n let cx = 0,\r\n cy = 0,\r\n n = 0;\r\n ops.forEach((op) => {\r\n if (op.op === \"FillPath\") {\r\n cx += op.x;\r\n cy += op.y;\r\n n++;\r\n }\r\n });\r\n if (n > 0) {\r\n cx /= n;\r\n cy /= n;\r\n }\r\n\r\n return ops.map((op) => {\r\n if (op.op === \"FillPath\") {\r\n const out: any = { ...op };\r\n if (out.fill.kind === \"solid\") out.fill = { ...out.fill, opacity: out.fill.opacity * alpha };\r\n else out.fill = { ...out.fill, opacity: (out.fill.opacity ?? 1) * alpha };\r\n if (scale !== 1 && n > 0) {\r\n const dx = op.x - cx,\r\n dy = op.y - cy;\r\n out.x = cx + dx * scale;\r\n out.y = cy + dy * scale;\r\n }\r\n return out;\r\n }\r\n if (op.op === \"StrokePath\") {\r\n const out: any = { ...op, opacity: op.opacity * alpha };\r\n if (scale !== 1 && n > 0) {\r\n const dx = op.x - cx,\r\n dy = op.y - cy;\r\n out.x = cx + dx * scale;\r\n out.y = cy + dy * scale;\r\n }\r\n return out;\r\n }\r\n if (op.op === \"DecorationLine\") return { ...op, opacity: op.opacity * alpha };\r\n return op;\r\n });\r\n}\r\n\r\nfunction translateGlyphOps(ops: DrawOp[], dx: number, dy: number, alpha: number = 1): DrawOp[] {\r\n return ops.map((op) => {\r\n if (op.op === \"FillPath\") {\r\n const out: any = { ...op, x: op.x + dx, y: op.y + dy };\r\n if (alpha < 1) {\r\n if (out.fill.kind === \"solid\")\r\n out.fill = { ...out.fill, opacity: out.fill.opacity * alpha };\r\n else out.fill = { ...out.fill, opacity: (out.fill.opacity ?? 1) * alpha };\r\n }\r\n return out;\r\n }\r\n if (op.op === \"StrokePath\")\r\n return { ...op, x: op.x + dx, y: op.y + dy, opacity: op.opacity * alpha };\r\n if (op.op === \"DecorationLine\") {\r\n return {\r\n ...op,\r\n from: { x: op.from.x + dx, y: op.from.y + dy },\r\n to: { x: op.to.x + dx, y: op.to.y + dy },\r\n opacity: op.opacity * alpha,\r\n };\r\n }\r\n return op;\r\n });\r\n}\r\n\r\nfunction waveTransform(\r\n ops: DrawOp[],\r\n dir: \"left\" | \"right\" | \"up\" | \"down\",\r\n amp: number,\r\n p: number\r\n): DrawOp[] {\r\n let glyphIndex = 0;\r\n return ops.map((op) => {\r\n if (op.op === \"FillPath\" || op.op === \"StrokePath\") {\r\n const phase = Math.sin((glyphIndex / 5) * Math.PI + p * Math.PI * 4);\r\n const dx = dir === \"left\" || dir === \"right\" ? phase * amp * (dir === \"left\" ? -1 : 1) : 0;\r\n const dy = dir === \"up\" || dir === \"down\" ? phase * amp * (dir === \"up\" ? -1 : 1) : 0;\r\n const waveAlpha = Math.min(1, p * 2);\r\n if (op.op === \"FillPath\") {\r\n if (!isShadowFill(op)) glyphIndex++;\r\n const out: any = { ...op, x: op.x + dx, y: op.y + dy };\r\n if (out.fill.kind === \"solid\")\r\n out.fill = { ...out.fill, opacity: out.fill.opacity * waveAlpha };\r\n else out.fill = { ...out.fill, opacity: (out.fill.opacity ?? 1) * waveAlpha };\r\n return out;\r\n }\r\n return { ...op, x: op.x + dx, y: op.y + dy, opacity: op.opacity * waveAlpha };\r\n }\r\n return op;\r\n });\r\n}\r\n\r\n// ---------- misc ----------\r\nfunction shiftFor(progress: number, dir: \"left\" | \"right\" | \"up\" | \"down\", dist: number) {\r\n const d = progress * dist;\r\n switch (dir) {\r\n case \"left\":\r\n return { dx: -d, dy: 0 };\r\n case \"right\":\r\n return { dx: d, dy: 0 };\r\n case \"up\":\r\n return { dx: 0, dy: -d };\r\n case \"down\":\r\n return { dx: 0, dy: d };\r\n }\r\n}\r\nfunction easeOutQuad(t: number) {\r\n return t * (2 - t);\r\n}\r\nfunction easeOutCubic(t: number) {\r\n return 1 - Math.pow(1 - t, 3);\r\n}\r\nfunction easeInOutQuad(t: number) {\r\n return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;\r\n}\r\n","import { RGBA } from \"../types\";\r\n\r\nexport function parseHex6(hex: string, alpha = 1): RGBA {\r\n const m = /^#?([a-f0-9]{6})$/i.exec(hex);\r\n if (!m) throw new Error(`Invalid color ${hex}`);\r\n const n = parseInt(m[1], 16);\r\n const r = (n >> 16) & 0xff;\r\n const g = (n >> 8) & 0xff;\r\n const b = n & 0xff;\r\n return { r, g, b, a: alpha };\r\n}\r\n","import type { DrawOp, GradientSpec } from \"../types\";\r\nimport { parseHex6 } from \"../core/colors\";\r\n\r\ninterface BoundingBox {\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n}\r\n\r\ninterface FillPathOp extends Extract<DrawOp, { op: \"FillPath\" }> {\r\n scale?: number;\r\n gradientBBox?: BoundingBox;\r\n isShadow?: boolean;\r\n}\r\n\r\ninterface StrokePathOp extends Extract<DrawOp, { op: \"StrokePath\" }> {\r\n scale?: number;\r\n}\r\n\r\ninterface NodeCanvas {\r\n width: number;\r\n height: number;\r\n getContext(contextId: \"2d\"): NodeCanvasRenderingContext2D;\r\n toBuffer(mimeType: \"image/png\"): Buffer;\r\n}\r\n\r\ninterface NodeCanvasRenderingContext2D {\r\n canvas: NodeCanvas;\r\n fillStyle: string | CanvasGradient | CanvasPattern;\r\n strokeStyle: string | CanvasGradient | CanvasPattern;\r\n lineWidth: number;\r\n lineJoin: CanvasLineJoin;\r\n lineCap: CanvasLineCap;\r\n\r\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void;\r\n clearRect(x: number, y: number, w: number, h: number): void;\r\n fillRect(x: number, y: number, w: number, h: number): void;\r\n save(): void;\r\n restore(): void;\r\n translate(x: number, y: number): void;\r\n scale(x: number, y: number): void;\r\n beginPath(): void;\r\n closePath(): void;\r\n moveTo(x: number, y: number): void;\r\n lineTo(x: number, y: number): void;\r\n arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;\r\n bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;\r\n quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;\r\n fill(): void;\r\n stroke(): void;\r\n createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;\r\n createRadialGradient(\r\n x0: number,\r\n y0: number,\r\n r0: number,\r\n x1: number,\r\n y1: number,\r\n r1: number\r\n ): CanvasGradient;\r\n}\r\n\r\ninterface CanvasModule {\r\n createCanvas(width: number, height: number): NodeCanvas;\r\n}\r\n\r\nexport async function createNodePainter(opts: {\r\n width: number;\r\n height: number;\r\n pixelRatio: number;\r\n}) {\r\n const canvasMod = (await import(\"canvas\")) as CanvasModule;\r\n const { createCanvas } = canvasMod;\r\n\r\n const canvas = createCanvas(\r\n Math.floor(opts.width * opts.pixelRatio),\r\n Math.floor(opts.height * opts.pixelRatio)\r\n );\r\n const ctx: NodeCanvasRenderingContext2D = canvas.getContext(\"2d\");\r\n if (!ctx) throw new Error(\"2D context unavailable in Node (canvas).\");\r\n\r\n const api = {\r\n async render(ops: DrawOp[]): Promise<void> {\r\n const globalBox = computeGlobalTextBounds(ops);\r\n\r\n for (const op of ops) {\r\n if (op.op === \"BeginFrame\") {\r\n if (op.clear) ctx.clearRect(0, 0, op.width, op.height);\r\n const dpr = op.pixelRatio ?? opts.pixelRatio;\r\n const wantW = Math.floor(op.width * dpr);\r\n const wantH = Math.floor(op.height * dpr);\r\n\r\n if (canvas.width !== wantW || canvas.height !== wantH) {\r\n canvas.width = wantW;\r\n canvas.height = wantH;\r\n }\r\n\r\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\r\n\r\n // ctx.save();\r\n // ctx.fillRect(0, 0, canvas.width, canvas.height);\r\n // ctx.restore();\r\n\r\n if (op.bg && op.bg.color) {\r\n const { color, opacity, radius } = op.bg;\r\n if (color) {\r\n const c = parseHex6(color, opacity);\r\n ctx.fillStyle = `rgba(${c.r},${c.g},${c.b},${c.a})`;\r\n if (radius && radius > 0) {\r\n ctx.save();\r\n ctx.beginPath();\r\n roundRectPath(ctx, 0, 0, op.width, op.height, radius);\r\n ctx.fill();\r\n ctx.restore();\r\n } else {\r\n ctx.fillRect(0, 0, op.width, op.height);\r\n }\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (op.op === \"FillPath\") {\r\n const fillOp = op as FillPathOp;\r\n ctx.save();\r\n ctx.translate(fillOp.x, fillOp.y);\r\n\r\n const s = fillOp.scale ?? 1;\r\n ctx.scale(s, -s);\r\n\r\n ctx.beginPath();\r\n drawSvgPathOnCtx(ctx, fillOp.path);\r\n\r\n const bbox = fillOp.gradientBBox ?? globalBox;\r\n const fill = makeGradientFromBBox(ctx, fillOp.fill, bbox);\r\n ctx.fillStyle = fill;\r\n ctx.fill();\r\n\r\n ctx.restore();\r\n continue;\r\n }\r\n\r\n if (op.op === \"StrokePath\") {\r\n const strokeOp = op as StrokePathOp;\r\n ctx.save();\r\n ctx.translate(strokeOp.x, strokeOp.y);\r\n\r\n const s = strokeOp.scale ?? 1;\r\n ctx.scale(s, -s);\r\n const invAbs = 1 / Math.abs(s);\r\n\r\n ctx.beginPath();\r\n drawSvgPathOnCtx(ctx, strokeOp.path);\r\n\r\n const c = parseHex6(strokeOp.color, strokeOp.opacity);\r\n ctx.strokeStyle = `rgba(${c.r},${c.g},${c.b},${c.a})`;\r\n ctx.lineWidth = strokeOp.width * invAbs;\r\n ctx.lineJoin = \"round\";\r\n ctx.lineCap = \"round\";\r\n ctx.stroke();\r\n\r\n ctx.restore();\r\n continue;\r\n }\r\n\r\n if (op.op === \"DecorationLine\") {\r\n ctx.save();\r\n const c = parseHex6(op.color, op.opacity);\r\n ctx.strokeStyle = `rgba(${c.r},${c.g},${c.b},${c.a})`;\r\n ctx.lineWidth = op.width;\r\n ctx.beginPath();\r\n ctx.moveTo(op.from.x, op.from.y);\r\n ctx.lineTo(op.to.x, op.to.y);\r\n ctx.stroke();\r\n ctx.restore();\r\n continue;\r\n }\r\n }\r\n },\r\n\r\n async toPNG(): Promise<Buffer> {\r\n return canvas.toBuffer(\"image/png\");\r\n },\r\n };\r\n\r\n return api;\r\n}\r\n\r\nfunction makeGradientFromBBox(\r\n ctx: NodeCanvasRenderingContext2D,\r\n spec: GradientSpec,\r\n box: BoundingBox\r\n): CanvasGradient | string {\r\n if (spec.kind === \"solid\") {\r\n const c = parseHex6(spec.color, spec.opacity);\r\n return `rgba(${c.r},${c.g},${c.b},${c.a})`;\r\n }\r\n\r\n const cx = box.x + box.w / 2;\r\n const cy = box.y + box.h / 2;\r\n const r = Math.max(box.w, box.h) / 2;\r\n\r\n const addStops = (g: CanvasGradient): CanvasGradient => {\r\n const opacity = spec.kind === \"linear\" || spec.kind === \"radial\" ? spec.opacity : 1;\r\n const stops = spec.kind === \"linear\" || spec.kind === \"radial\" ? spec.stops : [];\r\n\r\n for (const s of stops) {\r\n const c = parseHex6(s.color, opacity);\r\n g.addColorStop(s.offset, `rgba(${c.r},${c.g},${c.b},${c.a})`);\r\n }\r\n return g;\r\n };\r\n\r\n if (spec.kind === \"linear\") {\r\n const rad = (spec.angle * Math.PI) / 180;\r\n const x1 = cx + Math.cos(rad + Math.PI) * r;\r\n const y1 = cy + Math.sin(rad + Math.PI) * r;\r\n const x2 = cx + Math.cos(rad) * r;\r\n const y2 = cy + Math.sin(rad) * r;\r\n return addStops(ctx.createLinearGradient(x1, y1, x2, y2));\r\n } else {\r\n return addStops(ctx.createRadialGradient(cx, cy, 0, cx, cy, r));\r\n }\r\n}\r\n\r\nfunction computeGlobalTextBounds(ops: DrawOp[]): BoundingBox {\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n\r\n for (const op of ops) {\r\n if (op.op !== \"FillPath\") continue;\r\n\r\n const fillOp = op as FillPathOp;\r\n if (fillOp.isShadow) continue;\r\n\r\n const b = computePathBounds(fillOp.path);\r\n const s = fillOp.scale ?? 1;\r\n const x1 = fillOp.x + s * b.x;\r\n const x2 = fillOp.x + s * (b.x + b.w);\r\n const y1 = fillOp.y - s * (b.y + b.h);\r\n const y2 = fillOp.y - s * b.y;\r\n\r\n if (x1 < minX) minX = x1;\r\n if (y1 < minY) minY = y1;\r\n if (x2 > maxX) maxX = x2;\r\n if (y2 > maxY) maxY = y2;\r\n }\r\n\r\n if (minX === Infinity) {\r\n return { x: 0, y: 0, w: 1, h: 1 };\r\n }\r\n\r\n return {\r\n x: minX,\r\n y: minY,\r\n w: Math.max(1, maxX - minX),\r\n h: Math.max(1, maxY - minY),\r\n };\r\n}\r\n\r\nfunction drawSvgPathOnCtx(ctx: NodeCanvasRenderingContext2D, d: string): void {\r\n const t = tokenizePath(d);\r\n let i = 0;\r\n while (i < t.length) {\r\n const cmd = t[i++];\r\n switch (cmd) {\r\n case \"M\": {\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n ctx.moveTo(x, y);\r\n break;\r\n }\r\n case \"L\": {\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n ctx.lineTo(x, y);\r\n break;\r\n }\r\n case \"C\": {\r\n const c1x = parseFloat(t[i++]);\r\n const c1y = parseFloat(t[i++]);\r\n const c2x = parseFloat(t[i++]);\r\n const c2y = parseFloat(t[i++]);\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n ctx.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);\r\n break;\r\n }\r\n case \"Q\": {\r\n const cx = parseFloat(t[i++]);\r\n const cy = parseFloat(t[i++]);\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n ctx.quadraticCurveTo(cx, cy, x, y);\r\n break;\r\n }\r\n case \"Z\": {\r\n ctx.closePath();\r\n break;\r\n }\r\n default:\r\n break;\r\n }\r\n }\r\n}\r\n\r\nfunction computePathBounds(d: string): BoundingBox {\r\n const t = tokenizePath(d);\r\n let i = 0;\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n\r\n const touch = (x: number, y: number): void => {\r\n if (x < minX) minX = x;\r\n if (y < minY) minY = y;\r\n if (x > maxX) maxX = x;\r\n if (y > maxY) maxY = y;\r\n };\r\n\r\n while (i < t.length) {\r\n const cmd = t[i++];\r\n switch (cmd) {\r\n case \"M\":\r\n case \"L\": {\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n touch(x, y);\r\n break;\r\n }\r\n case \"C\": {\r\n const c1x = parseFloat(t[i++]);\r\n const c1y = parseFloat(t[i++]);\r\n const c2x = parseFloat(t[i++]);\r\n const c2y = parseFloat(t[i++]);\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n touch(c1x, c1y);\r\n touch(c2x, c2y);\r\n touch(x, y);\r\n break;\r\n }\r\n case \"Q\": {\r\n const cx = parseFloat(t[i++]);\r\n const cy = parseFloat(t[i++]);\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n touch(cx, cy);\r\n touch(x, y);\r\n break;\r\n }\r\n case \"Z\":\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n if (minX === Infinity) {\r\n return { x: 0, y: 0, w: 0, h: 0 };\r\n }\r\n\r\n return {\r\n x: minX,\r\n y: minY,\r\n w: maxX - minX,\r\n h: maxY - minY,\r\n };\r\n}\r\n\r\nfunction roundRectPath(\r\n ctx: NodeCanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n w: number,\r\n h: number,\r\n r: number\r\n): void {\r\n ctx.moveTo(x + r, y);\r\n ctx.arcTo(x + w, y, x + w, y + h, r);\r\n ctx.arcTo(x + w, y + h, x, y + h, r);\r\n ctx.arcTo(x, y + h, x, y, r);\r\n ctx.arcTo(x, y, x + w, y, r);\r\n ctx.closePath();\r\n}\r\n\r\nfunction tokenizePath(d: string): string[] {\r\n return d.match(/[MLCQZ]|-?\\d*\\.?\\d+(?:e[-+]?\\d+)?/gi) ?? [];\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport * as http from \"node:http\";\r\nimport * as https from \"node:https\";\r\n\r\nfunction bufferToArrayBuffer(buf: Buffer): ArrayBuffer {\r\n const { buffer, byteOffset, byteLength } = buf as unknown as {\r\n buffer: ArrayBuffer | SharedArrayBuffer;\r\n byteOffset: number;\r\n byteLength: number;\r\n };\r\n\r\n if (typeof SharedArrayBuffer !== \"undefined\" && buffer instanceof SharedArrayBuffer) {\r\n const ab = new ArrayBuffer(byteLength);\r\n new Uint8Array(ab).set(buf);\r\n return ab;\r\n }\r\n\r\n const ab = buffer as ArrayBuffer;\r\n\r\n return ab.slice(byteOffset, byteOffset + byteLength);\r\n}\r\n\r\nexport async function loadFileOrHttpToArrayBuffer(pathOrUrl: string): Promise<ArrayBuffer> {\r\n try {\r\n if (/^https?:\\/\\//.test(pathOrUrl)) {\r\n const client = pathOrUrl.startsWith(\"https:\") ? https : http;\r\n\r\n const buf: Buffer = await new Promise<Buffer>((resolve, reject) => {\r\n const request = client.get(pathOrUrl, (res) => {\r\n const { statusCode } = res;\r\n\r\n if (statusCode && (statusCode < 200 || statusCode >= 300)) {\r\n reject(new Error(`HTTP request failed with status ${statusCode} for ${pathOrUrl}`));\r\n res.resume();\r\n return;\r\n }\r\n\r\n const chunks: Buffer[] = [];\r\n\r\n res.on(\"data\", (chunk: Buffer) => {\r\n chunks.push(chunk);\r\n });\r\n\r\n res.on(\"end\", () => {\r\n try {\r\n resolve(Buffer.concat(chunks));\r\n } catch (err) {\r\n reject(\r\n new Error(\r\n `Failed to concatenate response chunks: ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n )\r\n );\r\n }\r\n });\r\n\r\n res.on(\"error\", (err) => {\r\n reject(new Error(`Response error for ${pathOrUrl}: ${err.message}`));\r\n });\r\n });\r\n\r\n request.on(\"error\", (err) => {\r\n reject(new Error(`Request error for ${pathOrUrl}: ${err.message}`));\r\n });\r\n\r\n request.setTimeout(30000, () => {\r\n request.destroy();\r\n reject(new Error(`Request timeout after 30s for ${pathOrUrl}`));\r\n });\r\n });\r\n\r\n return bufferToArrayBuffer(buf);\r\n }\r\n\r\n const buf = await readFile(pathOrUrl);\r\n return bufferToArrayBuffer(buf);\r\n } catch (err) {\r\n if (err instanceof Error) {\r\n throw new Error(`Failed to load ${pathOrUrl}: ${err.message}`);\r\n }\r\n throw new Error(`Failed to load ${pathOrUrl}: ${String(err)}`);\r\n }\r\n}\r\n","import type { DrawOp } from \"../types\";\r\nimport { createNodePainter } from \"../painters/node\";\r\nimport { spawn } from \"child_process\";\r\nimport fs from \"node:fs\";\r\n\r\nexport interface VideoGenerationOptions {\r\n width: number;\r\n height: number;\r\n fps: number;\r\n duration: number;\r\n outputPath: string;\r\n pixelRatio?: number;\r\n\r\n crf?: number;\r\n preset?:\r\n | \"ultrafast\"\r\n | \"superfast\"\r\n | \"veryfast\"\r\n | \"faster\"\r\n | \"fast\"\r\n | \"medium\"\r\n | \"slow\"\r\n | \"slower\"\r\n | \"veryslow\";\r\n tune?:\r\n | \"film\"\r\n | \"animation\"\r\n | \"grain\"\r\n | \"stillimage\"\r\n | \"psnr\"\r\n | \"ssim\"\r\n | \"fastdecode\"\r\n | \"zerolatency\";\r\n profile?: \"baseline\" | \"main\" | \"high\";\r\n level?: string;\r\n pixFmt?: string;\r\n ffmpegPath?: string;\r\n}\r\n\r\nexport class VideoGenerator {\r\n private ffmpegPath: string | null = null;\r\n\r\n private trySetPath(p?: string | null) {\r\n if (p && fs.existsSync(p)) {\r\n this.ffmpegPath = p;\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n async init(opts?: { ffmpegPath?: string }) {\r\n if (typeof window !== \"undefined\") {\r\n throw new Error(\"VideoGenerator is only available in Node.js environment\");\r\n }\r\n\r\n if (this.trySetPath(opts?.ffmpegPath)) return;\r\n\r\n if (this.trySetPath(process.env.FFMPEG_PATH)) return;\r\n if (this.trySetPath(process.env.FFMPEG_BIN)) return;\r\n\r\n if (this.trySetPath(\"/opt/bin/ffmpeg\")) return;\r\n\r\n try {\r\n const ffmpegStatic = await import(\"ffmpeg-static\");\r\n const p = (ffmpegStatic).default as string | undefined;\r\n if (this.trySetPath(p)) return;\r\n } catch {\r\n /* no-op, fall through */\r\n }\r\n\r\n throw new Error(\"FFmpeg not available. Please install ffmpeg-static or provide FFMPEG_PATH.\");\r\n }\r\n\r\n async generateVideo(\r\n frameGenerator: (time: number) => Promise<DrawOp[]>,\r\n options: VideoGenerationOptions\r\n ): Promise<void> {\r\n if (!this.ffmpegPath) await this.init({ ffmpegPath: options.ffmpegPath });\r\n\r\n const {\r\n width,\r\n height,\r\n fps,\r\n duration,\r\n outputPath,\r\n pixelRatio = 1,\r\n crf = 17,\r\n preset = \"slow\",\r\n tune = \"animation\",\r\n profile = \"high\",\r\n level = \"4.2\",\r\n pixFmt = \"yuv420p\",\r\n } = options;\r\n\r\n const totalFrames = Math.max(2, Math.round(duration * fps) + 1);\r\n\r\n console.log(\r\n `🎬 Generating video: ${width}x${height} @ ${fps}fps, ${duration}s (${totalFrames} frames)\\n` +\r\n ` CRF=${crf}, preset=${preset}, tune=${tune}, profile=${profile}, level=${level}, pix_fmt=${pixFmt}`\r\n );\r\n\r\n return new Promise(async (resolve, reject) => {\r\n const args = [\r\n \"-y\",\r\n \"-f\",\r\n \"image2pipe\",\r\n \"-vcodec\",\r\n \"png\",\r\n \"-framerate\",\r\n String(fps),\r\n \"-i\",\r\n \"-\",\r\n \"-c:v\",\r\n \"libx264\",\r\n \"-preset\",\r\n preset,\r\n \"-crf\",\r\n String(crf),\r\n \"-tune\",\r\n tune,\r\n \"-profile:v\",\r\n profile,\r\n \"-level\",\r\n level,\r\n \"-pix_fmt\",\r\n pixFmt,\r\n \"-r\",\r\n String(fps),\r\n \"-movflags\",\r\n \"+faststart\",\r\n outputPath,\r\n ];\r\n\r\n const ffmpeg = spawn(this.ffmpegPath!, args, { stdio: [\"pipe\", \"inherit\", \"pipe\"] });\r\n let ffmpegError = \"\";\r\n\r\n ffmpeg.stderr.on(\"data\", (data) => {\r\n const message = data.toString();\r\n const m = message.match(/time=(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?/);\r\n if (m) {\r\n const hh = parseInt(m[1], 10);\r\n const mm = parseInt(m[2], 10);\r\n const ss = parseInt(m[3], 10);\r\n const ff = m[4] ? parseFloat(`0.${m[4]}`) : 0;\r\n const currentTime = hh * 3600 + mm * 60 + ss + ff;\r\n const pct = Math.min(100, Math.round((currentTime / duration) * 100));\r\n if (pct % 10 === 0) console.log(`📹 Encoding: ${pct}%`);\r\n }\r\n ffmpegError += message;\r\n });\r\n\r\n ffmpeg.on(\"close\", (code) => {\r\n if (code === 0) {\r\n console.log(\"✅ Video generation complete!\");\r\n resolve();\r\n } else {\r\n console.error(\"FFmpeg stderr:\", ffmpegError);\r\n reject(new Error(`FFmpeg exited with code ${code}`));\r\n }\r\n });\r\n\r\n ffmpeg.on(\"error\", (err) => {\r\n console.error(\"❌ FFmpeg spawn error:\", err);\r\n reject(err);\r\n });\r\n\r\n try {\r\n const painter = await createNodePainter({ width, height, pixelRatio });\r\n for (let frame = 0; frame < totalFrames; frame++) {\r\n const t = (frame / (totalFrames - 1)) * duration;\r\n const ops = await frameGenerator(t);\r\n await painter.render(ops);\r\n const png = await painter.toPNG();\r\n\r\n const ok = ffmpeg.stdin.write(png);\r\n if (!ok) await new Promise((r) => ffmpeg.stdin.once(\"drain\", r));\r\n\r\n if (frame % Math.max(1, Math.floor(fps / 2)) === 0) {\r\n const pct = Math.round(((frame + 1) / totalFrames) * 100);\r\n console.log(`🎞️ Rendering frames: ${pct}%`);\r\n }\r\n }\r\n ffmpeg.stdin.end();\r\n } catch (err) {\r\n console.error(\"Frame generation error:\", err);\r\n ffmpeg.kill(\"SIGKILL\");\r\n reject(err);\r\n }\r\n });\r\n }\r\n}\r\n","import type { RichTextValidated } from \"./schema/asset-schema\";\r\n\r\nexport type RGBA = { r: number; g: number; b: number; a: number };\r\n\r\nexport type GradientSpec =\r\n | { kind: \"solid\"; color: string; opacity: number }\r\n | { kind: \"linear\"; angle: number; stops: { offset: number; color: string }[]; opacity: number }\r\n | { kind: \"radial\"; stops: { offset: number; color: string }[]; opacity: number };\r\n\r\nexport type Glyph = {\r\n id: number;\r\n xAdvance: number;\r\n xOffset: number;\r\n yOffset: number;\r\n cluster: number;\r\n char?: string;\r\n};\r\n\r\nexport type ShapedLine = {\r\n glyphs: Glyph[];\r\n width: number;\r\n y: number; // baseline y\r\n};\r\n\r\nexport type DrawOp =\r\n | {\r\n op: \"BeginFrame\";\r\n width: number;\r\n height: number;\r\n pixelRatio: number;\r\n clear: boolean;\r\n bg?: { color?: string; opacity: number; radius: number };\r\n }\r\n | {\r\n op: \"FillPath\";\r\n path: string;\r\n x: number;\r\n y: number;\r\n fill: GradientSpec;\r\n scale?: number;\r\n gradientBBox?: { x: number; y: number; w: number; h: number };\r\n isShadow?: boolean;\r\n }\r\n | {\r\n op: \"StrokePath\";\r\n path: string;\r\n x: number;\r\n y: number;\r\n width: number;\r\n color: string;\r\n opacity: number;\r\n scale?: number;\r\n }\r\n | {\r\n op: \"DecorationLine\";\r\n from: { x: number; y: number };\r\n to: { x: number; y: number };\r\n width: number;\r\n color: string;\r\n opacity: number;\r\n };\r\n\r\nexport type EngineInit = { width: number; height: number; pixelRatio?: number; fps?: number };\r\n\r\nexport type Renderer = { render(ops: DrawOp[]): Promise<void>; toPNG?: () => Promise<Buffer> };\r\n\r\nexport type ValidAsset = RichTextValidated;\r\n\r\nexport const isShadowFill = (\r\n op: DrawOp\r\n): op is Extract<DrawOp, { op: \"FillPath\" }> & { isShadow: true } => {\r\n return op.op === \"FillPath\" && (op as Extract<DrawOp, { op: \"FillPath\" }>).isShadow === true;\r\n};\r\n\r\nexport const isGlyphFill = (\r\n op: DrawOp\r\n): op is Extract<DrawOp, { op: \"FillPath\" }> & { isShadow?: false } => {\r\n return op.op === \"FillPath\" && (op as Extract<DrawOp, { op: \"FillPath\" }>).isShadow !== true;\r\n};\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,qBAAAA;AAAA,EAAA,oBAAAC;AAAA;AAAA;;;ACAA,iBAAgB;;;ACAT,IAAM,gBAAgB;AAAA,EAC3B,UAAU;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,IACV,WAAW;AAAA,IACX,WAAW;AAAA,IACX,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,iBAAiB;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AD1BA,IAAM,OAAO;AAEb,IAAM,iBAAiB,WAAAC,QAAI,OAAO;AAAA,EAChC,MAAM,WAAAA,QAAI,OAAO,EAAE,MAAM,UAAU,QAAQ,EAAE,QAAQ,QAAQ;AAAA,EAC7D,OAAO,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,CAAC;AAAA,EAC7C,OAAO,WAAAA,QAAI,MAAM,EACd;AAAA,IACC,WAAAA,QAAI,OAAO;AAAA,MACT,QAAQ,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,MAC5C,OAAO,WAAAA,QAAI,OAAO,EAAE,QAAQ,IAAI,EAAE,SAAS;AAAA,IAC7C,CAAC,EAAE,QAAQ,KAAK;AAAA,EAClB,EACC,IAAI,CAAC,EACL,SAAS;AACd,CAAC,EAAE,QAAQ,KAAK;AAEhB,IAAM,eAAe,WAAAA,QAAI,OAAO;AAAA,EAC9B,SAAS,WAAAA,QAAI,OAAO,EAAE,QAAQ,CAAC;AAAA,EAC/B,SAAS,WAAAA,QAAI,OAAO,EAAE,QAAQ,CAAC;AAAA,EAC/B,MAAM,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EACnC,OAAO,WAAAA,QAAI,OAAO,EAAE,QAAQ,IAAI,EAAE,QAAQ,SAAS;AAAA,EACnD,SAAS,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AACjD,CAAC,EAAE,QAAQ,KAAK;AAEhB,IAAM,eAAe,WAAAA,QAAI,OAAO;AAAA,EAC9B,OAAO,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EACpC,OAAO,WAAAA,QAAI,OAAO,EAAE,QAAQ,IAAI,EAAE,QAAQ,SAAS;AAAA,EACnD,SAAS,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAC/C,CAAC,EAAE,QAAQ,KAAK;AAEhB,IAAM,aAAa,WAAAA,QAAI,OAAO;AAAA,EAC5B,QAAQ,WAAAA,QAAI,OAAO,EAAE,QAAQ,cAAc,SAAS,UAAU;AAAA,EAC9D,MAAM,WAAAA,QAAI,OAAO,EACd,IAAI,cAAc,OAAO,WAAW,EACpC,IAAI,cAAc,OAAO,WAAW,EACpC,QAAQ,cAAc,SAAS,QAAQ;AAAA,EAC1C,QAAQ,WAAAA,QAAI,aAAa,EAAE,IAAI,WAAAA,QAAI,OAAO,GAAG,WAAAA,QAAI,OAAO,CAAC,EAAE,QAAQ,KAAK;AAAA,EACxE,OAAO,WAAAA,QAAI,OAAO,EAAE,MAAM,UAAU,UAAU,SAAS,EAAE,QAAQ,QAAQ;AAAA,EACzE,OAAO,WAAAA,QAAI,OAAO,EAAE,QAAQ,IAAI,EAAE,QAAQ,cAAc,SAAS,KAAK;AAAA,EACtE,SAAS,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAC/C,CAAC,EAAE,QAAQ,KAAK;AAEhB,IAAM,cAAc,WAAAA,QAAI,OAAO;AAAA,EAC7B,eAAe,WAAAA,QAAI,OAAO,EAAE,QAAQ,CAAC;AAAA,EACrC,YAAY,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,GAAG;AAAA,EACnD,eAAe,WAAAA,QAAI,OAAO,EAAE,MAAM,QAAQ,aAAa,aAAa,YAAY,EAAE,QAAQ,MAAM;AAAA,EAChG,gBAAgB,WAAAA,QAAI,OAAO,EAAE,MAAM,QAAQ,aAAa,cAAc,EAAE,QAAQ,MAAM;AAAA,EACtF,UAAU,eAAe,SAAS;AACpC,CAAC,EAAE,QAAQ,KAAK;AAEhB,IAAM,kBAAkB,WAAAA,QAAI,OAAO;AAAA,EACjC,YAAY,WAAAA,QAAI,OAAO,EACpB,MAAM,QAAQ,UAAU,OAAO,EAC/B,QAAQ,cAAc,SAAS,SAAS;AAAA,EAC3C,UAAU,WAAAA,QAAI,OAAO,EAAE,MAAM,OAAO,UAAU,QAAQ,EAAE,QAAQ,QAAQ;AAC1E,CAAC,EAAE,QAAQ,KAAK;AAEhB,IAAM,kBAAkB,WAAAA,QAAI,OAAO;AAAA,EACjC,QAAQ,WAAAA,QAAI,OAAO,EAAE,MAAM,GAAG,cAAc,eAAoC;AAAA,EAChF,OAAO,WAAAA,QAAI,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC;AAAA,EAC9C,UAAU,WAAAA,QAAI,OAAO,EAClB,IAAI,cAAc,OAAO,WAAW,EACpC,IAAI,cAAc,OAAO,WAAW,EACpC,SAAS;AAAA,EACZ,OAAO,WAAAA,QAAI,OAAO,EACf,MAAM,aAAa,MAAM,EACzB,SAAS,EACT,KAAK,UAAU;AAAA,IACd,IAAI,WAAAA,QAAI,MAAM,cAAc,OAAO;AAAA,IACnC,MAAM,WAAAA,QAAI,SAAS;AAAA,IACnB,WAAW,WAAAA,QAAI,UAAU;AAAA,EAC3B,CAAC;AAAA,EACH,WAAW,WAAAA,QAAI,OAAO,EACnB,SAAS,EACT,KAAK,UAAU;AAAA,IACd,QAAQ;AAAA,MACN,EAAE,IAAI,UAAU,MAAM,WAAAA,QAAI,MAAM,MAAM,MAAM,EAAE;AAAA,MAC9C,EAAE,IAAI,SAAS,MAAM,WAAAA,QAAI,MAAM,QAAQ,SAAS,MAAM,MAAM,EAAE;AAAA,MAC9D,EAAE,IAAI,WAAW,MAAM,WAAAA,QAAI,MAAM,QAAQ,SAAS,MAAM,MAAM,EAAE;AAAA,MAChE,EAAE,IAAI,iBAAiB,MAAM,WAAAA,QAAI,MAAM,QAAQ,SAAS,MAAM,MAAM,EAAE;AAAA,IACxE;AAAA,IACA,WAAW,WAAAA,QAAI,UAAU;AAAA,EAC3B,CAAC;AACL,CAAC,EAAE,QAAQ,KAAK;AAEhB,IAAM,mBAAmB,WAAAA,QAAI,OAAO;AAAA,EAClC,OAAO,WAAAA,QAAI,OAAO,EAAE,QAAQ,IAAI,EAAE,SAAS;AAAA,EAC3C,SAAS,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EAC7C,cAAc,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAC7C,CAAC,EAAE,QAAQ,KAAK;AAEhB,IAAM,mBAAmB,WAAAA,QAAI,OAAO;AAAA,EAClC,KAAK,WAAAA,QAAI,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACjC,QAAQ,WAAAA,QAAI,OAAO,EAAE,SAAS;AAAA,EAC9B,QAAQ,WAAAA,QAAI,aAAa,EAAE,IAAI,WAAAA,QAAI,OAAO,GAAG,WAAAA,QAAI,OAAO,CAAC,EAAE,SAAS;AAAA,EACpE,OAAO,WAAAA,QAAI,OAAO,EAAE,SAAS;AAAA,EAC7B,gBAAgB,WAAAA,QAAI,OAAO,EAAE,SAAS;AACxC,CAAC,EAAE,QAAQ,KAAK;AAET,IAAM,sBAAsB,WAAAA,QAAI,OAAO;AAAA,EAC5C,MAAM,WAAAA,QAAI,OAAO,EAAE,MAAM,WAAW,EAAE,SAAS;AAAA,EAC/C,MAAM,WAAAA,QAAI,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,cAAc,OAAO,aAAa,EAAE,QAAQ,EAAE;AAAA,EAC/E,OAAO,WAAAA,QAAI,OAAO,EACf,IAAI,cAAc,OAAO,QAAQ,EACjC,IAAI,cAAc,OAAO,QAAQ,EACjC,QAAQ,cAAc,SAAS,KAAK,EACpC,SAAS;AAAA,EACZ,QAAQ,WAAAA,QAAI,OAAO,EAChB,IAAI,cAAc,OAAO,SAAS,EAClC,IAAI,cAAc,OAAO,SAAS,EAClC,QAAQ,cAAc,SAAS,MAAM,EACrC,SAAS;AAAA,EACZ,MAAM,WAAW,SAAS;AAAA,EAC1B,OAAO,YAAY,SAAS;AAAA,EAC5B,QAAQ,aAAa,SAAS;AAAA,EAC9B,QAAQ,aAAa,SAAS;AAAA,EAC9B,YAAY,iBAAiB,SAAS;AAAA,EACtC,OAAO,gBAAgB,SAAS;AAAA,EAChC,WAAW,gBAAgB,SAAS;AAAA,EACpC,aAAa,WAAAA,QAAI,MAAM,EAAE,MAAM,gBAAgB,EAAE,SAAS;AAAA,EAC1D,cAAc,WAAAA,QAAI,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACxC,YAAY,WAAAA,QAAI,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,cAAc,SAAS,UAAU;AAClF,CAAC,EAAE,QAAQ,KAAK;;;AElFhB,IAAI,cAAyB;AAE7B,eAAsB,OAAO,aAAmC;AAC9D,MAAI,YAAa,QAAO;AAExB,MAAI;AACF,UAAM,MAAO,MAAM,OAAO,YAAY;AAEtC,UAAM,YAAY,IAAI;AAEtB,QAAI;AACJ,QAAI,OAAO,cAAc,YAAY;AACnC,WAAK,MAAM,UAAU;AAAA,IACvB,WAAW,aAAa,OAAQ,UAA0B,SAAS,YAAY;AAC7E,WAAK,MAAO;AAAA,IACd,OAAO;AACL,WAAK;AAAA,IACP;AAEA,QAAI,CAAC,MAAM,OAAO,GAAG,iBAAiB,cAAc,OAAO,GAAG,eAAe,YAAY;AACvF,YAAM,IAAI,MAAM,2EAA2E;AAAA,IAC7F;AAEA,SAAK;AAEL,kBAAc;AACd,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,kCAAkC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IACpF;AAAA,EACF;AACF;;;ACtEO,IAAM,eAAN,MAAM,cAAa;AAAA,EAChB;AAAA,EACA,QAAQ,oBAAI,IAAoB;AAAA,EAChC,QAAQ,oBAAI,IAAoB;AAAA,EAChC,QAAQ,oBAAI,IAAoB;AAAA,EAChC;AAAA,EACA;AAAA,EAER,OAAe;AAAA,EACf,OAAO,kBAAkB,QAAoE;AAC3F,kBAAa,iBAAiB;AAAA,EAChC;AAAA,EAEA,YAAY,aAAsB;AAChC,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI,KAAK,aAAa;AACpB,YAAM,KAAK;AACX;AAAA,IACF;AACA,QAAI,KAAK,GAAI;AACb,SAAK,cAAc,KAAK,QAAQ;AAChC,QAAI;AACF,YAAM,KAAK;AAAA,IACb,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,sCAAsC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,UAAyB;AACrC,QAAI;AACF,WAAK,KAAK,MAAM,OAAO,KAAK,WAAW;AAAA,IACzC,SAAS,OAAO;AACd,WAAK,cAAc;AACnB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,QAAqB;AACzB,QAAI,CAAC,KAAK,IAAI;AACZ,UAAI;AACF,cAAM,KAAK,KAAK;AAAA,MAClB,SAAS,KAAK;AACZ,cAAM,IAAI;AAAA,UACR,oCAAoC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,IAAI,MAA8B;AACxC,WAAO,GAAG,KAAK,MAAM,KAAK,KAAK,UAAU,KAAK,KAAK,KAAK,SAAS,QAAQ;AAAA,EAC3E;AAAA,EAEA,MAAM,kBAAkB,OAAoB,MAAqC;AAC/E,QAAI;AACF,UAAI,CAAC,KAAK,GAAI,OAAM,KAAK,KAAK;AAC9B,YAAM,IAAI,KAAK,IAAI,IAAI;AACvB,UAAI,KAAK,MAAM,IAAI,CAAC,EAAG;AAEvB,YAAM,OAAO,KAAK,GAAG,WAAW,KAAK;AACrC,YAAM,OAAO,KAAK,GAAG,WAAW,MAAM,CAAC;AACvC,YAAM,OAAO,KAAK,GAAG,WAAW,IAAI;AAEpC,YAAM,OAAQ,KAAwB,QAAQ;AAC9C,MAAC,KAAyB,SAAS,MAAM,IAAI;AAE7C,WAAK,MAAM,IAAI,GAAG,IAAI;AACtB,WAAK,MAAM,IAAI,GAAG,IAAI;AACtB,WAAK,MAAM,IAAI,GAAG,IAAI;AAAA,IACxB,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,4BAA4B,KAAK,MAAM,MACrC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,mBAAmB,MAAwC;AACvE,UAAM,SAAS,cAAa;AAC5B,QAAI,CAAC,OAAQ,QAAO;AACpB,QAAI;AACF,YAAM,QAAQ,MAAM,OAAO;AAAA,QACzB,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK,UAAU;AAAA,QACvB,OAAO,KAAK,SAAS;AAAA,MACvB,CAAC;AACD,UAAI,CAAC,MAAO,QAAO;AACnB,YAAM,KAAK,kBAAkB,OAAO;AAAA,QAClC,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK,UAAU;AAAA,QACvB,OAAO,KAAK,SAAS;AAAA,MACvB,CAAC;AACD,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,MAAuC;AACnD,QAAI;AACF,UAAI,CAAC,KAAK,GAAI,OAAM,KAAK,KAAK;AAC9B,YAAM,IAAI,KAAK,IAAI,IAAI;AACvB,UAAI,IAAI,KAAK,MAAM,IAAI,CAAC;AACxB,UAAI,CAAC,GAAG;AACN,cAAM,YAAY,MAAM,KAAK,mBAAmB,IAAI;AACpD,YAAI,YAAY,KAAK,MAAM,IAAI,CAAC,IAAI;AAAA,MACtC;AACA,UAAI,CAAC,EAAG,OAAM,IAAI,MAAM,2BAA2B,CAAC,EAAE;AACtD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,eAAe,SAAS,IAAI,QAAQ,SAAS,qBAAqB,GAAG;AACvE,cAAM;AAAA,MACR;AACA,YAAM,IAAI;AAAA,QACR,uBAAuB,KAAK,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MAC1F;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,MAAmD;AAC/D,QAAI;AACF,UAAI,CAAC,KAAK,GAAI,OAAM,KAAK,KAAK;AAC9B,YAAM,IAAI,KAAK,IAAI,IAAI;AACvB,UAAI,OAAO,KAAK,MAAM,IAAI,CAAC;AAC3B,UAAI,CAAC,MAAM;AACT,cAAM,YAAY,MAAM,KAAK,mBAAmB,IAAI;AACpD,eAAO,YAAY,KAAK,MAAM,IAAI,CAAC,IAAI;AAAA,MACzC;AACA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,2BAA2B,KAAK,MAAM,MACpC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,MAAuC;AACzD,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,QAAQ,IAAI;AACpC,aAAQ,MAAyB,QAAQ;AAAA,IAC3C,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,mCAAmC,KAAK,MAAM,MAC5C,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,MAAsB,SAAkC;AACtE,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,QAAQ,IAAI;AACpC,YAAM,OAAO,KAAK,YAAY,OAAO;AACrC,aAAO,QAAQ,SAAS,KAAK,OAAO;AAAA,IACtC,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,sCAAsC,OAAO,aAAa,KAAK,MAAM,MACnE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,UAAgB;AACd,QAAI;AACF,iBAAW,CAAC,EAAE,CAAC,KAAK,KAAK,OAAO;AAC9B,YAAI;AACF,YAAE,QAAQ;AAAA,QACZ,SAAS,KAAK;AACZ,kBAAQ;AAAA,YACN,0BAA0B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAC5E;AAAA,QACF;AAAA,MACF;AACA,iBAAW,CAAC,EAAE,CAAC,KAAK,KAAK,OAAO;AAC9B,YAAI;AACF,YAAE,QAAQ;AAAA,QACZ,SAAS,KAAK;AACZ,kBAAQ;AAAA,YACN,0BAA0B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAC5E;AAAA,QACF;AAAA,MACF;AACA,iBAAW,CAAC,EAAE,CAAC,KAAK,KAAK,OAAO;AAC9B,YAAI;AACF,YAAE,QAAQ;AAAA,QACZ,SAAS,KAAK;AACZ,kBAAQ;AAAA,YACN,0BAA0B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAC5E;AAAA,QACF;AAAA,MACF;AACA,WAAK,MAAM,MAAM;AACjB,WAAK,MAAM,MAAM;AACjB,WAAK,MAAM,MAAM;AACjB,WAAK,KAAK;AACV,WAAK,cAAc;AAAA,IACrB,SAAS,KAAK;AACZ,cAAQ;AAAA,QACN,sCAAsC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MACxF;AAAA,IACF;AAAA,EACF;AACF;;;AC3MO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,OAAqB;AAArB;AAAA,EAAsB;AAAA,EAElC,cAAc,GAAW,IAA0C;AACzE,YAAQ,IAAI;AAAA,MACV,KAAK;AACH,eAAO,EAAE,YAAY;AAAA,MACvB,KAAK;AACH,eAAO,EAAE,YAAY;AAAA,MACvB,KAAK;AACH,eAAO,EAAE,QAAQ,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,MAClD;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA,EAEA,MAAc,UAAU,MAAc,MAA8C;AAClF,QAAI;AACF,YAAM,KAAK,MAAM,KAAK,MAAM,MAAM;AAClC,YAAM,SAAS,GAAG,aAAa;AAE/B,UAAI;AACF,eAAO,QAAQ,IAAI;AACnB,eAAO,uBAAuB;AAE9B,cAAM,OAAO,MAAM,KAAK,MAAM,QAAQ,IAAI;AAC1C,cAAM,OAAO,MAAM,KAAK,MAAM,QAAQ,IAAI;AAE1C,cAAM,OAAQ,MAA4B,QAAQ;AAClD,QAAC,KAAkD,SAAS,MAAM,IAAI;AAEtE,WAAG,MAAM,MAAM,MAAM;AAErB,cAAM,SAAS,OAAO,KAAK;AAC3B,eAAO;AAAA,MACT,UAAE;AACA,YAAI;AACF,iBAAO,QAAQ;AAAA,QACjB,SAAS,KAAK;AACZ,kBAAQ;AAAA,YACN,qCAAqC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UACvF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,mCAAmC,KAAK,MAAM,MAC5C,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,QAA4C;AACvD,QAAI;AACF,YAAM,EAAE,eAAe,MAAM,UAAU,eAAe,MAAM,IAAI;AAChE,YAAM,QAAQ,KAAK,cAAc,OAAO,MAAM,aAAa;AAE3D,UAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,eAAO,CAAC;AAAA,MACV;AAEA,UAAI;AACJ,UAAI;AACF,iBAAS,MAAM,KAAK,UAAU,OAAO,IAAI;AAAA,MAC3C,SAAS,KAAK;AACZ,cAAM,IAAI,MAAM,wBAAwB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAC5F;AAEA,UAAI;AACJ,UAAI;AACF,cAAM,OAAO,MAAM,KAAK,MAAM,QAAQ,IAAI;AAC1C,eAAQ,MAA4B,QAAQ;AAAA,MAC9C,SAAS,KAAK;AACZ,cAAM,IAAI;AAAA,UACR,+BAA+B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACjF;AAAA,MACF;AAEA,YAAM,QAAQ,WAAW;AAEzB,YAAM,SAAkB,OAAO,IAAI,CAAC,MAAM;AACxC,cAAM,YAAY,EAAE;AACpB,YAAI;AAEJ,YAAI,aAAa,KAAK,YAAY,MAAM,QAAQ;AAC9C,iBAAO,MAAM,SAAS;AAAA,QACxB;AAEA,eAAO;AAAA,UACL,IAAI,EAAE;AAAA,UACN,UAAU,EAAE,KAAK,QAAQ;AAAA,UACzB,SAAS,EAAE,KAAK;AAAA,UAChB,SAAS,CAAC,EAAE,KAAK;AAAA,UACjB,SAAS,EAAE;AAAA,UACX;AAAA,QACF;AAAA,MACF,CAAC;AAED,YAAM,QAAsB,CAAC;AAC7B,UAAI,cAAuB,CAAC;AAC5B,UAAI,eAAe;AAEnB,YAAM,eAAe,oBAAI,IAAY;AACrC,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAI,MAAM,CAAC,MAAM,KAAK;AACpB,uBAAa,IAAI,CAAC;AAAA,QACpB;AAAA,MACF;AAEA,UAAI,iBAAiB;AAErB,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,cAAM,QAAQ,OAAO,CAAC;AACtB,cAAM,aAAa,MAAM;AAEzB,YAAI,MAAM,SAAS,MAAM;AACvB,cAAI,YAAY,SAAS,GAAG;AAC1B,kBAAM,KAAK;AAAA,cACT,QAAQ;AAAA,cACR,OAAO;AAAA,cACP,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AACA,wBAAc,CAAC;AACf,yBAAe;AACf,2BAAiB;AACjB;AAAA,QACF;AAEA,YAAI,eAAe,aAAa,SAAS,YAAY,SAAS,GAAG;AAC/D,cAAI,iBAAiB,IAAI;AACvB,kBAAM,aAAa,kBAAkB,IAAI,YAAY,UAAU;AAC/D,kBAAM,WAAW,YAAY,OAAO,UAAU;AAE9C,kBAAM,YAAY,YAAY,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,UAAU,CAAC;AAEpE,kBAAM,KAAK;AAAA,cACT,QAAQ;AAAA,cACR,OAAO;AAAA,cACP,GAAG;AAAA,YACL,CAAC;AAED,0BAAc;AACd,2BAAe,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,UAAU,CAAC;AAAA,UAChE,OAAO;AACL,kBAAM,KAAK;AAAA,cACT,QAAQ;AAAA,cACR,OAAO;AAAA,cACP,GAAG;AAAA,YACL,CAAC;AACD,0BAAc,CAAC;AACf,2BAAe;AAAA,UACjB;AACA,2BAAiB;AAAA,QACnB;AAEA,oBAAY,KAAK,KAAK;AACtB,wBAAgB;AAEhB,YAAI,aAAa,IAAI,MAAM,OAAO,GAAG;AACnC,2BAAiB;AAAA,QACnB;AAAA,MACF;AAEA,UAAI,YAAY,SAAS,GAAG;AAC1B,cAAM,KAAK;AAAA,UACT,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,GAAG;AAAA,QACL,CAAC;AAAA,MACH;AAEA,YAAM,aAAa,OAAO,aAAa;AACvC,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAM,CAAC,EAAE,KAAK,IAAI,KAAK;AAAA,MACzB;AAEA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,eAAe,OAAO;AACxB,cAAM;AAAA,MACR;AACA,YAAM,IAAI,MAAM,kBAAkB,OAAO,GAAG,CAAC,EAAE;AAAA,IACjD;AAAA,EACF;AACF;;;ACtMO,SAAS,iBACd,GACA,SACc;AACd,MAAI,EAAE,SAAS,UAAU;AACvB,WAAO,EAAE,MAAM,UAAU,OAAO,EAAE,OAAO,OAAO,EAAE,OAAO,QAAQ;AAAA,EACnE,OAAO;AACL,WAAO,EAAE,MAAM,UAAU,OAAO,EAAE,OAAO,QAAQ;AAAA,EACnD;AACF;;;ACXO,SAAS,mBACd,MACA,GACA;AACA,QAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,WAAW,IAAI,CAAC;AAC3D,MAAI,IAAI,EAAE,YAAY,KAAK,MAAM,EAAE,WAAW,GAAG;AACjD,MAAI,SAAS,eAAgB,KAAI,EAAE,YAAY,KAAK,MAAM,EAAE,WAAW,GAAG;AAC1E,SAAO,EAAE,IAAI,EAAE,QAAQ,IAAI,EAAE,SAAS,EAAE,WAAW,GAAG,OAAO,UAAU;AACzE;;;ACeA,eAAsB,aAAa,GAAmC;AACpE,QAAM,MAAgB,CAAC;AAGvB,MAAI,KAAK;AAAA,IACP,IAAI;AAAA,IACJ,OAAO,EAAE,OAAO;AAAA,IAChB,QAAQ,EAAE,OAAO;AAAA,IACjB,YAAY,EAAE,OAAO;AAAA,IACrB,OAAO;AAAA,IACP,IAAI,EAAE,cAAc,EAAE,WAAW,QAC7B,EAAE,OAAO,EAAE,WAAW,OAAO,SAAS,EAAE,WAAW,SAAS,QAAQ,EAAE,WAAW,aAAa,IAC9F;AAAA,EACN,CAAC;AAED,MAAI,EAAE,MAAM,WAAW,EAAG,QAAO;AAGjC,QAAM,OAAO,KAAK,IAAI,GAAG,MAAM,EAAE,cAAc,CAAC;AAChD,QAAM,QAAQ,EAAE,KAAK,OAAO;AAG5B,QAAM,cAAc,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC,EAAE;AAGhD,MAAI;AACJ,UAAQ,EAAE,MAAM,UAAU;AAAA,IACxB,KAAK;AAAO,eAAS,EAAE,KAAK;AAAM;AAAA,IAClC,KAAK;AAAU,eAAS,EAAE,SAAS,SAAS,cAAc,EAAE,KAAK;AAAM;AAAA,IACvE,KAAK;AAAA,IACL;AAAS,gBAAU,EAAE,SAAS,SAAS,eAAe,IAAI,EAAE,KAAK;AAAM;AAAA,EACzE;AAGA,QAAM,OAAqB,EAAE,MAAM,WAC/B,iBAAiB,EAAE,MAAM,UAAU,CAAC,IACpC,EAAE,MAAM,SAAS,OAAO,EAAE,KAAK,OAAO,SAAS,EAAE,KAAK,QAAQ;AAGlE,QAAM,YAAY,EAAE,MAAM,WACtB,EAAE,MAAM,SAAS,MAAM,EAAE,MAAM,SAAS,MAAM,SAAS,CAAC,GAAG,SAAS,EAAE,KAAK,QAC3E,EAAE,KAAK;AAGX,MAAI,QAAQ,UAAU,QAAQ,UAAU,QAAQ,WAAW,QAAQ;AAEnE,aAAW,QAAQ,EAAE,OAAO;AAE1B,QAAI;AACJ,YAAQ,EAAE,MAAM,YAAY;AAAA,MAC1B,KAAK;AAAQ,gBAAQ;AAAG;AAAA,MACxB,KAAK;AAAS,gBAAQ,EAAE,SAAS,QAAQ,KAAK;AAAO;AAAA,MACrD,KAAK;AAAA,MACL;AAAS,iBAAS,EAAE,SAAS,QAAQ,KAAK,SAAS;AAAG;AAAA,IACxD;AAEA,QAAI,UAAU;AACd,UAAM,YAAY,SAAS,KAAK,IAAI,EAAE,KAAK;AAE3C,eAAW,SAAS,KAAK,QAAQ;AAC/B,YAAM,OAAO,MAAM,EAAE,kBAAkB,MAAM,EAAE;AAC/C,UAAI,CAAC,QAAQ,SAAS,SAAS;AAC7B,mBAAW,MAAM;AACjB;AAAA,MACF;AAEA,YAAM,SAAS,UAAU,MAAM;AAC/B,YAAM,SAAS,YAAY,MAAM;AAGjC,YAAM,KAAK,kBAAkB,IAAI;AACjC,YAAM,KAAK,SAAS,QAAQ,GAAG;AAC/B,YAAM,KAAK,SAAS,SAAS,GAAG,IAAI,GAAG;AACvC,YAAM,KAAK,SAAS,SAAS,GAAG,IAAI,GAAG;AACvC,YAAM,KAAK,SAAS,QAAQ,GAAG;AAC/B,UAAI,KAAK,MAAO,SAAQ;AACxB,UAAI,KAAK,MAAO,SAAQ;AACxB,UAAI,KAAK,MAAO,SAAQ;AACxB,UAAI,KAAK,MAAO,SAAQ;AAGxB,UAAI,EAAE,UAAU,EAAE,OAAO,OAAO,GAAG;AACjC,YAAI,KAAK;AAAA,UACP,UAAU;AAAA,UACV,IAAI;AAAA,UACJ;AAAA,UACA,GAAG,SAAS,EAAE,OAAO;AAAA,UACrB,GAAG,SAAS,EAAE,OAAO;AAAA,UACrB;AAAA,UACA,MAAM,EAAE,MAAM,SAAS,OAAO,EAAE,OAAO,OAAO,SAAS,EAAE,OAAO,QAAQ;AAAA,QAC1E,CAAC;AAAA,MACH;AAGA,UAAI,EAAE,UAAU,EAAE,OAAO,QAAQ,GAAG;AAClC,YAAI,KAAK;AAAA,UACP,IAAI;AAAA,UACJ;AAAA,UACA,GAAG;AAAA,UACH,GAAG;AAAA,UACH;AAAA,UACA,OAAO,EAAE,OAAO;AAAA,UAChB,OAAO,EAAE,OAAO;AAAA,UAChB,SAAS,EAAE,OAAO;AAAA,QACpB,CAAC;AAAA,MACH;AAGA,UAAI,KAAK;AAAA,QACP,IAAI;AAAA,QACJ;AAAA,QACA,GAAG;AAAA,QACH,GAAG;AAAA,QACH;AAAA,QACA;AAAA,MACF,CAAC;AAED,iBAAW,MAAM;AAAA,IACnB;AAGA,QAAI,EAAE,MAAM,mBAAmB,QAAQ;AACrC,YAAM,OAAO,mBAAmB,EAAE,MAAM,gBAAgB;AAAA,QACtD;AAAA,QACA,UAAU,EAAE,KAAK;AAAA,QACjB,WAAW,KAAK;AAAA,QAChB,QAAQ;AAAA,MACV,CAAC;AAED,UAAI,KAAK;AAAA,QACP,IAAI;AAAA,QACJ,MAAM,EAAE,GAAG,KAAK,IAAI,GAAG,KAAK,EAAE;AAAA,QAC9B,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,KAAK,EAAE;AAAA,QAC5B,OAAO,KAAK;AAAA,QACZ,OAAO;AAAA,QACP,SAAS,EAAE,KAAK;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,UAAU,UAAU;AACtB,UAAM,OAAO,EAAE,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,IAAI,GAAG,QAAQ,KAAK,GAAG,GAAG,KAAK,IAAI,GAAG,QAAQ,KAAK,EAAE;AAChG,eAAW,MAAM,KAAK;AACpB,UAAI,GAAG,OAAO,cAAc,CAAE,GAAI,UAAU;AAC1C,QAAC,GAAI,eAAe;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,aAAa,GAAqB;AACzC,SAAO,EAAE,MAAM,qCAAqC,KAAK,CAAC;AAC5D;AACA,SAAS,kBAAkB,GAAW;AACpC,QAAM,IAAI,aAAa,CAAC;AACxB,MAAI,IAAI;AACR,MAAI,OAAO,UAAU,OAAO,UAAU,OAAO,WAAW,OAAO;AAC/D,QAAM,QAAQ,CAAC,GAAW,MAAc;AAAE,QAAI,IAAI,KAAM,QAAO;AAAG,QAAI,IAAI,KAAM,QAAO;AAAG,QAAI,IAAI,KAAM,QAAO;AAAG,QAAI,IAAI,KAAM,QAAO;AAAA,EAAG;AAC1I,SAAO,IAAI,EAAE,QAAQ;AACnB,UAAM,MAAM,EAAE,GAAG;AACjB,YAAQ,KAAK;AAAA,MACX,KAAK;AAAA,MACL,KAAK,KAAK;AAAE,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAAG,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAAG,cAAM,GAAG,CAAC;AAAG;AAAA,MAAO;AAAA,MAC5F,KAAK,KAAK;AACR,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAAG,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAC7D,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAAG,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAC7D,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAAG,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AACzD,cAAM,KAAK,GAAG;AAAG,cAAM,KAAK,GAAG;AAAG,cAAM,GAAG,CAAC;AAAG;AAAA,MACjD;AAAA,MACA,KAAK,KAAK;AAAE,cAAM,KAAK,WAAW,EAAE,GAAG,CAAC;AAAG,cAAM,KAAK,WAAW,EAAE,GAAG,CAAC;AAAG,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAAG,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAAG,cAAM,IAAI,EAAE;AAAG,cAAM,GAAG,CAAC;AAAG;AAAA,MAAO;AAAA,MACzK,KAAK;AAAK;AAAA,IACZ;AAAA,EACF;AACA,MAAI,SAAS,SAAU,QAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AACvD,SAAO,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,MAAM,GAAG,OAAO,KAAK;AAC5D;;;AChMA,IAAM,4BAA4B;AAE3B,SAAS,eACd,KACA,OACA,GACU;AACV,MAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,KAAK,OAAQ,QAAO;AAEtC,QAAM,EAAE,OAAO,IAAI,EAAE;AACrB,QAAM,cAAc,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,QAAQ,CAAC;AACjE,QAAM,WAAW,EAAE,KAAK,YAAY,KAAK,IAAI,KAAK,cAAc,KAAK,EAAE,KAAK,KAAK;AACjF,QAAM,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE,IAAI,QAAQ,CAAC;AAExD,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,EAAE,KAAK;AAAA,QACP,EAAE;AAAA,QACF,EAAE;AAAA,QACF;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO,qBAAqB,KAAK,QAAQ;AAAA,IAC3C,KAAK;AACH,aAAO,sBAAsB,KAAK,UAAU,EAAE,KAAK,aAAa,QAAQ,EAAE,QAAQ;AAAA,IACpF,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,EAAE,KAAK,aAAa;AAAA,QACpB,EAAE;AAAA,QACF,EAAE,KAAK;AAAA,QACP;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,EAAE,KAAK,aAAa;AAAA,QACpB,EAAE;AAAA,QACF;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO,4BAA4B,KAAK,UAAU,EAAE,KAAK,aAAa,MAAM,EAAE,QAAQ;AAAA,IACxF;AACE,aAAO;AAAA,EACX;AACF;AAGA,IAAM,eAAe,CAAC,OAAe,GAAG,OAAO,cAAe,GAAI,aAAa;AAC/E,IAAM,cAAc,CAAC,OAAe,GAAG,OAAO,cAAc,CAAE,GAAI,aAAa;AAG/E,SAAS,oBAAoB,KAAuB;AAClD,aAAW,MAAM,KAAK;AACpB,QAAI,GAAG,OAAO,YAAY;AACxB,YAAM,OAAa,GAAI;AACvB,UAAI,MAAM,SAAS,QAAS,QAAO,KAAK;AACxC,WACG,MAAM,SAAS,YAAY,MAAM,SAAS,aAC3C,MAAM,QAAQ,KAAK,KAAK,KACxB,KAAK,MAAM,QACX;AACA,eAAO,KAAK,MAAM,KAAK,MAAM,SAAS,CAAC,EAAE,SAAS;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,yBACP,KACA,OACA,UACA,OACA,UACA,MACA,UACU;AACV,QAAM,SAAS,UAAU;AAEzB,MAAI,QAAQ;AACV,UAAM,eAAe,gBAAgB,KAAK;AAC1C,UAAM,aAAa,aAAa;AAChC,UAAM,eAAe,KAAK,MAAM,WAAW,UAAU;AACrD,QAAI,iBAAiB,EAAG,QAAO,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,YAAY;AAEtE,QAAI,qBAAqB;AACzB,aAAS,IAAI,GAAG,IAAI,KAAK,IAAI,cAAc,aAAa,MAAM,GAAG,KAAK;AACpE,4BAAsB,aAAa,CAAC,EAAE;AAAA,IACxC;AACA,UAAM,gBAAgB,cAAc,KAAK,kBAAkB;AAE3D,UAAM,aACJ,YAAY,4BACR,gBACA,cAAc,OAAO,CAAC,MAAM,EAAE,OAAO,gBAAgB;AAE3D,QAAI,WAAW,KAAK,qBAAqB,GAAG;AAC1C,aAAO,oBAAoB,YAAY,oBAAoB,UAAU,IAAI;AAAA,IAC3E;AACA,WAAO;AAAA,EACT,OAAO;AACL,UAAM,cAAc,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,QAAQ,CAAC;AACjE,UAAM,gBAAgB,KAAK,MAAM,WAAW,WAAW;AACvD,QAAI,kBAAkB,EAAG,QAAO,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,YAAY;AAEvE,UAAM,gBAAgB,cAAc,KAAK,aAAa;AAEtD,UAAM,aACJ,YAAY,4BACR,gBACA,cAAc,OAAO,CAAC,MAAM,EAAE,OAAO,gBAAgB;AAE3D,QAAI,WAAW,KAAK,gBAAgB,GAAG;AACrC,aAAO,oBAAoB,YAAY,eAAe,UAAU,IAAI;AAAA,IACtE;AACA,WAAO;AAAA,EACT;AACF;AAGA,SAAS,qBACP,KACA,OACA,UACA,WACA,UACA,UACU;AACV,QAAM,eAAe,gBAAgB,KAAK;AAC1C,QAAM,aAAa,aAAa;AAChC,MAAI,eAAe,EAAG,QAAO;AAE7B,QAAM,SAAmB,CAAC;AAC1B,MAAI,aAAa;AAEjB,aAAW,MAAM,KAAK;AACpB,QAAI,GAAG,OAAO,cAAc;AAC1B,aAAO,KAAK,EAAE;AACd;AAAA,IACF;AAAA,EACF;AAEA,aAAW,MAAM,KAAK;AACpB,QAAI,GAAG,OAAO,cAAc,GAAG,OAAO,cAAc;AAElD,UAAI,YAAY,IACd,MAAM;AACR,eAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,cAAM,SAAS,aAAa,CAAC,EAAE;AAC/B,YAAI,cAAc,OAAO,aAAa,MAAM,QAAQ;AAClD,sBAAY;AACZ;AAAA,QACF;AACA,eAAO;AAAA,MACT;AACA,UAAI,aAAa,GAAG;AAClB,cAAM,SAAU,YAAY,KAAK,IAAI,GAAG,UAAU,KAAM,WAAW;AACnE,cAAM,OAAO,KAAK,IAAI,GAAG,SAAS,GAAG;AACrC,YAAI,YAAY,MAAM;AACpB,iBAAO,KAAK,EAAE;AAAA,QAChB,WAAW,WAAW,QAAQ;AAC5B,gBAAM,SAAS,WAAW,UAAU,KAAK,IAAI,MAAM,OAAO,MAAM;AAChE,gBAAM,OAAO,aAAa,KAAK,IAAI,GAAG,KAAK,CAAC;AAC5C,gBAAM,cAAc,cAAc,OAAO,WAAW,MAAM,CAAC,WAAW;AACtE,gBAAM,WAAgB,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,eAAe,IAAI,MAAM;AAClE,cAAI,GAAG,OAAO,YAAY;AACxB,gBAAI,SAAS,KAAK,SAAS;AACzB,uBAAS,OAAO,EAAE,GAAG,SAAS,MAAM,SAAS,SAAS,KAAK,UAAU,KAAK;AAAA,gBACvE,UAAS,OAAO,EAAE,GAAG,SAAS,MAAM,UAAU,SAAS,KAAK,WAAW,KAAK,KAAK;AAAA,UACxF,OAAO;AACL,qBAAS,UAAU,SAAS,UAAU;AAAA,UACxC;AACA,iBAAO,KAAK,QAAQ;AAAA,QACtB;AAAA,MACF;AACA,UAAI,YAAY,EAAE,EAAG;AAAA,IACvB,WAAW,GAAG,OAAO,kBAAkB;AACrC,UAAI,YAAY,2BAA2B;AACzC,eAAO,KAAK,EAAE;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,oBACP,KACA,OACA,UACA,WACA,UACA,OACA,UACU;AACV,QAAM,SAAS,UAAU;AACzB,QAAM,eAAe;AAAA,IACnB,MAAM,EAAE,GAAG,WAAW,KAAK,GAAG,EAAE;AAAA,IAChC,OAAO,EAAE,GAAG,CAAC,WAAW,KAAK,GAAG,EAAE;AAAA,IAClC,IAAI,EAAE,GAAG,GAAG,GAAG,WAAW,IAAI;AAAA,IAC9B,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC,WAAW,IAAI;AAAA,EACnC;AACA,QAAM,SAAS,aAAa,SAAS;AAErC,QAAM,eAAe,SAAS,gBAAgB,KAAK,IAAI,CAAC;AACxD,QAAM,cAAc,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,QAAQ,CAAC;AACjE,QAAM,aAAa,SAAS,aAAa,SAAS;AAClD,MAAI,eAAe,EAAG,QAAO;AAE7B,QAAM,SAAmB,CAAC;AAC1B,aAAW,MAAM,KAAK;AACpB,QAAI,GAAG,OAAO,cAAc;AAC1B,aAAO,KAAK,EAAE;AACd;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB;AACvB,QAAM,gBAAgB;AACtB,QAAM,eAAgB,WAAW,gBAAiB,KAAK,IAAI,GAAG,aAAa,CAAC;AAE5E,QAAM,YAAY,CAAC,YAAoB;AACrC,UAAM,YAAY,UAAU;AAC5B,UAAM,SAAS,YAAY;AAC3B,UAAM,OAAO,KAAK,IAAI,IAAI,YAAY,kBAAkB,QAAQ;AAChE,WAAO,EAAE,QAAQ,KAAK;AAAA,EACxB;AAEA,MAAI,aAAa;AACjB,aAAW,MAAM,KAAK;AACpB,QAAI,GAAG,OAAO,cAAc,GAAG,OAAO,cAAc;AAClD,UAAI,GAAG,OAAO,oBAAoB,WAAW,IAAK,QAAO,KAAK,EAAE;AAChE;AAAA,IACF;AAEA,QAAI;AACJ,QAAI,CAAC,QAAQ;AACX,kBAAY;AAAA,IACd,OAAO;AACL,UAAI,YAAY,IACd,MAAM;AACR,eAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,cAAM,SAAS,aAAa,CAAC,EAAE;AAC/B,YAAI,cAAc,OAAO,aAAa,MAAM,QAAQ;AAClD,sBAAY;AACZ;AAAA,QACF;AACA,eAAO;AAAA,MACT;AACA,kBAAY,KAAK,IAAI,GAAG,SAAS;AAAA,IACnC;AAEA,UAAM,EAAE,QAAQ,KAAK,IAAI,UAAU,SAAS;AAE5C,QAAI,YAAY,QAAQ;AACtB,YAAM,WAAgB,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,GAAG,GAAG,IAAI,OAAO,EAAE;AACtE,UAAI,GAAG,OAAO,YAAY;AACxB,YAAI,SAAS,KAAK,SAAS,QAAS,UAAS,OAAO,EAAE,GAAG,SAAS,MAAM,SAAS,EAAE;AAAA,YAC9E,UAAS,OAAO,EAAE,GAAG,SAAS,MAAM,SAAS,EAAE;AAAA,MACtD,OAAO;AACL,iBAAS,UAAU;AAAA,MACrB;AACA,aAAO,KAAK,QAAQ;AAAA,IACtB,WAAW,YAAY,MAAM;AAC3B,aAAO,KAAK,EAAE;AAAA,IAChB,OAAO;AACL,YAAM,SAAS,WAAW,UAAU,KAAK,IAAI,MAAM,OAAO,MAAM;AAChE,YAAM,OAAO,aAAa,KAAK,IAAI,GAAG,KAAK,CAAC;AAC5C,YAAM,KAAK,OAAO,KAAK,IAAI;AAC3B,YAAM,KAAK,OAAO,KAAK,IAAI;AAC3B,YAAM,WAAgB,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,GAAG;AAE1D,UAAI,GAAG,OAAO,YAAY;AACxB,cAAM,gBACJ,SAAS,KAAK,SAAS,UAAU,SAAS,KAAK,UAAU,SAAS,KAAK,WAAW;AACpF,YAAI,SAAS,KAAK,SAAS;AACzB,mBAAS,OAAO,EAAE,GAAG,SAAS,MAAM,SAAS,gBAAgB,KAAK;AAAA,YAC/D,UAAS,OAAO,EAAE,GAAG,SAAS,MAAM,SAAS,gBAAgB,KAAK;AAAA,MACzE,OAAO;AACL,iBAAS,UAAU,SAAS,UAAU;AAAA,MACxC;AACA,aAAO,KAAK,QAAQ;AAAA,IACtB;AAEA,QAAI,YAAY,EAAE,EAAG;AAAA,EACvB;AACA,SAAO;AACT;AAGA,SAAS,qBAAqB,KAAe,UAA4B;AACvE,QAAM,QAAQ,YAAY,QAAQ;AAClC,QAAM,QAAQ,OAAO,OAAO;AAC5B,SAAO,aAAa,KAAK,OAAO,KAAK;AACvC;AACA,SAAS,sBACP,KACA,UACA,WACA,UACU;AACV,QAAM,eAAe,aAAa,QAAQ;AAC1C,QAAM,QAAQ,SAAS,IAAI,cAAc,WAAW,WAAW,CAAC;AAChE,QAAM,QAAQ,YAAY,QAAQ;AAClC,SAAO,kBAAkB,KAAK,MAAM,IAAI,MAAM,IAAI,KAAK;AACzD;AACA,SAAS,4BACP,KACA,UACA,WACA,UACU;AACV,QAAM,MAAM,WAAW;AACvB,SAAO,cAAc,KAAK,WAAW,KAAK,QAAQ;AACpD;AAGA,SAAS,gBAAgB,OAAqB;AAC5C,QAAM,WAAgB,CAAC;AACvB,MAAI,kBAAkB;AACtB,WAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAC7D,UAAM,OAAO,MAAM,SAAS;AAC5B,UAAM,QAAQ,oBAAoB,IAAI;AACtC,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,SAAS;AAChB,iBAAS,KAAK,EAAE,YAAY,iBAAiB,YAAY,KAAK,QAAQ,UAAU,CAAC;AACnF,yBAAmB,KAAK;AAAA,IAC1B;AAAA,EACF;AACA,SAAO;AACT;AACA,SAAS,oBAAoB,MAA6B;AACxD,QAAM,QAAmB,CAAC;AAC1B,MAAI,UAAmB,CAAC;AACxB,aAAW,KAAK,KAAK,QAAQ;AAC3B,UAAM,UAAU,EAAE,SAAS,OAAO,EAAE,SAAS,OAAQ,EAAE,SAAS;AAChE,QAAI,SAAS;AACX,UAAI,QAAQ,QAAQ;AAClB,cAAM,KAAK,CAAC,GAAG,OAAO,CAAC;AACvB,kBAAU,CAAC;AAAA,MACb;AAAA,IACF,OAAO;AACL,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACA,MAAI,QAAQ,OAAQ,OAAM,KAAK,OAAO;AACtC,SAAO;AACT;AAIA,SAAS,cAAc,KAAe,WAA6B;AACjE,QAAM,SAAmB,CAAC;AAC1B,MAAI,aAAa;AACjB,MAAI,cAAc;AAElB,aAAW,MAAM,KAAK;AACpB,QAAI,GAAG,OAAO,cAAc;AAC1B,aAAO,KAAK,EAAE;AACd;AAAA,IACF;AAEA,QAAI,GAAG,OAAO,cAAc,CAAC,aAAa,EAAE,GAAG;AAC7C,UAAI,aAAa,WAAW;AAC1B,eAAO,KAAK,EAAE;AACd,sBAAc;AAAA,MAChB;AACA;AACA;AAAA,IACF;AAEA,QAAI,GAAG,OAAO,cAAc;AAE1B,UAAI,aAAa,UAAW,QAAO,KAAK,EAAE;AAC1C;AAAA,IACF;AAEA,QAAI,GAAG,OAAO,cAAc,aAAa,EAAE,GAAG;AAC5C,UAAI,aAAa,UAAW,QAAO,KAAK,EAAE;AAC1C;AAAA,IACF;AAEA,QAAI,GAAG,OAAO,oBAAoB,aAAa;AAC7C,aAAO,KAAK,EAAE;AACd;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,oBACP,KACA,YACA,UACA,MACU;AACV,QAAM,YAAY;AAClB,QAAM,gBAAgB,KAAK,MAAM,OAAO,YAAY,CAAC,IAAI,MAAM;AAC/D,MAAI,CAAC,iBAAiB,eAAe,EAAG,QAAO;AAE/C,MAAI,OAAsB;AAC1B,MAAI,QAAQ;AACZ,aAAW,MAAM,KAAK;AACpB,QAAI,GAAG,OAAO,cAAc,CAAC,aAAa,EAAE,GAAG;AAC7C;AACA,UAAI,UAAU,YAAY;AACxB,eAAO;AACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,KAAK,OAAO,YAAY;AAClC,UAAM,QAAQ,oBAAoB,GAAG;AACrC,UAAM,UAAU,KAAK,IAAI,WAAW;AACpC,UAAM,UAAU,KAAK;AAErB,UAAM,WAAmB;AAAA,MACvB,IAAI;AAAA,MACJ,MAAM,EAAE,GAAG,SAAS,GAAG,UAAU,WAAW,IAAI;AAAA,MAChD,IAAI,EAAE,GAAG,SAAS,GAAG,UAAU,WAAW,IAAI;AAAA,MAC9C,OAAO,KAAK,IAAI,GAAG,WAAW,EAAE;AAAA,MAChC;AAAA,MACA,SAAS;AAAA,IACX;AACA,WAAO,CAAC,GAAG,KAAK,QAAQ;AAAA,EAC1B;AACA,SAAO;AACT;AAGA,SAAS,aAAa,KAAe,OAAe,OAAyB;AAC3E,MAAI,KAAK,GACP,KAAK,GACL,IAAI;AACN,MAAI,QAAQ,CAAC,OAAO;AAClB,QAAI,GAAG,OAAO,YAAY;AACxB,YAAM,GAAG;AACT,YAAM,GAAG;AACT;AAAA,IACF;AAAA,EACF,CAAC;AACD,MAAI,IAAI,GAAG;AACT,UAAM;AACN,UAAM;AAAA,EACR;AAEA,SAAO,IAAI,IAAI,CAAC,OAAO;AACrB,QAAI,GAAG,OAAO,YAAY;AACxB,YAAM,MAAW,EAAE,GAAG,GAAG;AACzB,UAAI,IAAI,KAAK,SAAS,QAAS,KAAI,OAAO,EAAE,GAAG,IAAI,MAAM,SAAS,IAAI,KAAK,UAAU,MAAM;AAAA,UACtF,KAAI,OAAO,EAAE,GAAG,IAAI,MAAM,UAAU,IAAI,KAAK,WAAW,KAAK,MAAM;AACxE,UAAI,UAAU,KAAK,IAAI,GAAG;AACxB,cAAM,KAAK,GAAG,IAAI,IAChB,KAAK,GAAG,IAAI;AACd,YAAI,IAAI,KAAK,KAAK;AAClB,YAAI,IAAI,KAAK,KAAK;AAAA,MACpB;AACA,aAAO;AAAA,IACT;AACA,QAAI,GAAG,OAAO,cAAc;AAC1B,YAAM,MAAW,EAAE,GAAG,IAAI,SAAS,GAAG,UAAU,MAAM;AACtD,UAAI,UAAU,KAAK,IAAI,GAAG;AACxB,cAAM,KAAK,GAAG,IAAI,IAChB,KAAK,GAAG,IAAI;AACd,YAAI,IAAI,KAAK,KAAK;AAClB,YAAI,IAAI,KAAK,KAAK;AAAA,MACpB;AACA,aAAO;AAAA,IACT;AACA,QAAI,GAAG,OAAO,iBAAkB,QAAO,EAAE,GAAG,IAAI,SAAS,GAAG,UAAU,MAAM;AAC5E,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,kBAAkB,KAAe,IAAY,IAAY,QAAgB,GAAa;AAC7F,SAAO,IAAI,IAAI,CAAC,OAAO;AACrB,QAAI,GAAG,OAAO,YAAY;AACxB,YAAM,MAAW,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,GAAG;AACrD,UAAI,QAAQ,GAAG;AACb,YAAI,IAAI,KAAK,SAAS;AACpB,cAAI,OAAO,EAAE,GAAG,IAAI,MAAM,SAAS,IAAI,KAAK,UAAU,MAAM;AAAA,YACzD,KAAI,OAAO,EAAE,GAAG,IAAI,MAAM,UAAU,IAAI,KAAK,WAAW,KAAK,MAAM;AAAA,MAC1E;AACA,aAAO;AAAA,IACT;AACA,QAAI,GAAG,OAAO;AACZ,aAAO,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,IAAI,SAAS,GAAG,UAAU,MAAM;AAC1E,QAAI,GAAG,OAAO,kBAAkB;AAC9B,aAAO;AAAA,QACL,GAAG;AAAA,QACH,MAAM,EAAE,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,GAAG,KAAK,IAAI,GAAG;AAAA,QAC7C,IAAI,EAAE,GAAG,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG;AAAA,QACvC,SAAS,GAAG,UAAU;AAAA,MACxB;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,cACP,KACA,KACA,KACA,GACU;AACV,MAAI,aAAa;AACjB,SAAO,IAAI,IAAI,CAAC,OAAO;AACrB,QAAI,GAAG,OAAO,cAAc,GAAG,OAAO,cAAc;AAClD,YAAM,QAAQ,KAAK,IAAK,aAAa,IAAK,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AACnE,YAAM,KAAK,QAAQ,UAAU,QAAQ,UAAU,QAAQ,OAAO,QAAQ,SAAS,KAAK,KAAK;AACzF,YAAM,KAAK,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,OAAO,QAAQ,OAAO,KAAK,KAAK;AACpF,YAAM,YAAY,KAAK,IAAI,GAAG,IAAI,CAAC;AACnC,UAAI,GAAG,OAAO,YAAY;AACxB,YAAI,CAAC,aAAa,EAAE,EAAG;AACvB,cAAM,MAAW,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,GAAG;AACrD,YAAI,IAAI,KAAK,SAAS;AACpB,cAAI,OAAO,EAAE,GAAG,IAAI,MAAM,SAAS,IAAI,KAAK,UAAU,UAAU;AAAA,YAC7D,KAAI,OAAO,EAAE,GAAG,IAAI,MAAM,UAAU,IAAI,KAAK,WAAW,KAAK,UAAU;AAC5E,eAAO;AAAA,MACT;AACA,aAAO,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,IAAI,SAAS,GAAG,UAAU,UAAU;AAAA,IAC9E;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAGA,SAAS,SAAS,UAAkB,KAAuC,MAAc;AACvF,QAAM,IAAI,WAAW;AACrB,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE;AAAA,IACzB,KAAK;AACH,aAAO,EAAE,IAAI,GAAG,IAAI,EAAE;AAAA,IACxB,KAAK;AACH,aAAO,EAAE,IAAI,GAAG,IAAI,CAAC,EAAE;AAAA,IACzB,KAAK;AACH,aAAO,EAAE,IAAI,GAAG,IAAI,EAAE;AAAA,EAC1B;AACF;AACA,SAAS,YAAY,GAAW;AAC9B,SAAO,KAAK,IAAI;AAClB;AACA,SAAS,aAAa,GAAW;AAC/B,SAAO,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AAC9B;;;ACpjBO,SAAS,UAAU,KAAa,QAAQ,GAAS;AACtD,QAAM,IAAI,qBAAqB,KAAK,GAAG;AACvC,MAAI,CAAC,EAAG,OAAM,IAAI,MAAM,iBAAiB,GAAG,EAAE;AAC9C,QAAM,IAAI,SAAS,EAAE,CAAC,GAAG,EAAE;AAC3B,QAAM,IAAK,KAAK,KAAM;AACtB,QAAM,IAAK,KAAK,IAAK;AACrB,QAAM,IAAI,IAAI;AACd,SAAO,EAAE,GAAG,GAAG,GAAG,GAAG,MAAM;AAC7B;;;ACwDA,eAAsB,kBAAkB,MAIrC;AACD,QAAM,YAAa,MAAM,OAAO,QAAQ;AACxC,QAAM,EAAE,aAAa,IAAI;AAEzB,QAAM,SAAS;AAAA,IACb,KAAK,MAAM,KAAK,QAAQ,KAAK,UAAU;AAAA,IACvC,KAAK,MAAM,KAAK,SAAS,KAAK,UAAU;AAAA,EAC1C;AACA,QAAM,MAAoC,OAAO,WAAW,IAAI;AAChE,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,0CAA0C;AAEpE,QAAM,MAAM;AAAA,IACV,MAAM,OAAO,KAA8B;AACzC,YAAM,YAAY,wBAAwB,GAAG;AAE7C,iBAAW,MAAM,KAAK;AACpB,YAAI,GAAG,OAAO,cAAc;AAC1B,cAAI,GAAG,MAAO,KAAI,UAAU,GAAG,GAAG,GAAG,OAAO,GAAG,MAAM;AACrD,gBAAM,MAAM,GAAG,cAAc,KAAK;AAClC,gBAAM,QAAQ,KAAK,MAAM,GAAG,QAAQ,GAAG;AACvC,gBAAM,QAAQ,KAAK,MAAM,GAAG,SAAS,GAAG;AAExC,cAAI,OAAO,UAAU,SAAS,OAAO,WAAW,OAAO;AACrD,mBAAO,QAAQ;AACf,mBAAO,SAAS;AAAA,UAClB;AAEA,cAAI,aAAa,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC;AAMrC,cAAI,GAAG,MAAM,GAAG,GAAG,OAAO;AACxB,kBAAM,EAAE,OAAO,SAAS,OAAO,IAAI,GAAG;AACtC,gBAAI,OAAO;AACT,oBAAM,IAAI,UAAU,OAAO,OAAO;AAClC,kBAAI,YAAY,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAChD,kBAAI,UAAU,SAAS,GAAG;AACxB,oBAAI,KAAK;AACT,oBAAI,UAAU;AACd,8BAAc,KAAK,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,MAAM;AACpD,oBAAI,KAAK;AACT,oBAAI,QAAQ;AAAA,cACd,OAAO;AACL,oBAAI,SAAS,GAAG,GAAG,GAAG,OAAO,GAAG,MAAM;AAAA,cACxC;AAAA,YACF;AAAA,UACF;AACA;AAAA,QACF;AAEA,YAAI,GAAG,OAAO,YAAY;AACxB,gBAAM,SAAS;AACf,cAAI,KAAK;AACT,cAAI,UAAU,OAAO,GAAG,OAAO,CAAC;AAEhC,gBAAM,IAAI,OAAO,SAAS;AAC1B,cAAI,MAAM,GAAG,CAAC,CAAC;AAEf,cAAI,UAAU;AACd,2BAAiB,KAAK,OAAO,IAAI;AAEjC,gBAAM,OAAO,OAAO,gBAAgB;AACpC,gBAAM,OAAO,qBAAqB,KAAK,OAAO,MAAM,IAAI;AACxD,cAAI,YAAY;AAChB,cAAI,KAAK;AAET,cAAI,QAAQ;AACZ;AAAA,QACF;AAEA,YAAI,GAAG,OAAO,cAAc;AAC1B,gBAAM,WAAW;AACjB,cAAI,KAAK;AACT,cAAI,UAAU,SAAS,GAAG,SAAS,CAAC;AAEpC,gBAAM,IAAI,SAAS,SAAS;AAC5B,cAAI,MAAM,GAAG,CAAC,CAAC;AACf,gBAAM,SAAS,IAAI,KAAK,IAAI,CAAC;AAE7B,cAAI,UAAU;AACd,2BAAiB,KAAK,SAAS,IAAI;AAEnC,gBAAM,IAAI,UAAU,SAAS,OAAO,SAAS,OAAO;AACpD,cAAI,cAAc,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAClD,cAAI,YAAY,SAAS,QAAQ;AACjC,cAAI,WAAW;AACf,cAAI,UAAU;AACd,cAAI,OAAO;AAEX,cAAI,QAAQ;AACZ;AAAA,QACF;AAEA,YAAI,GAAG,OAAO,kBAAkB;AAC9B,cAAI,KAAK;AACT,gBAAM,IAAI,UAAU,GAAG,OAAO,GAAG,OAAO;AACxC,cAAI,cAAc,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAClD,cAAI,YAAY,GAAG;AACnB,cAAI,UAAU;AACd,cAAI,OAAO,GAAG,KAAK,GAAG,GAAG,KAAK,CAAC;AAC/B,cAAI,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC3B,cAAI,OAAO;AACX,cAAI,QAAQ;AACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,QAAyB;AAC7B,aAAO,OAAO,SAAS,WAAW;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,qBACP,KACA,MACA,KACyB;AACzB,MAAI,KAAK,SAAS,SAAS;AACzB,UAAM,IAAI,UAAU,KAAK,OAAO,KAAK,OAAO;AAC5C,WAAO,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EACzC;AAEA,QAAM,KAAK,IAAI,IAAI,IAAI,IAAI;AAC3B,QAAM,KAAK,IAAI,IAAI,IAAI,IAAI;AAC3B,QAAM,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI;AAEnC,QAAM,WAAW,CAAC,MAAsC;AACtD,UAAM,UAAU,KAAK,SAAS,YAAY,KAAK,SAAS,WAAW,KAAK,UAAU;AAClF,UAAM,QAAQ,KAAK,SAAS,YAAY,KAAK,SAAS,WAAW,KAAK,QAAQ,CAAC;AAE/E,eAAW,KAAK,OAAO;AACrB,YAAM,IAAI,UAAU,EAAE,OAAO,OAAO;AACpC,QAAE,aAAa,EAAE,QAAQ,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG;AAAA,IAC9D;AACA,WAAO;AAAA,EACT;AAEA,MAAI,KAAK,SAAS,UAAU;AAC1B,UAAM,MAAO,KAAK,QAAQ,KAAK,KAAM;AACrC,UAAM,KAAK,KAAK,KAAK,IAAI,MAAM,KAAK,EAAE,IAAI;AAC1C,UAAM,KAAK,KAAK,KAAK,IAAI,MAAM,KAAK,EAAE,IAAI;AAC1C,UAAM,KAAK,KAAK,KAAK,IAAI,GAAG,IAAI;AAChC,UAAM,KAAK,KAAK,KAAK,IAAI,GAAG,IAAI;AAChC,WAAO,SAAS,IAAI,qBAAqB,IAAI,IAAI,IAAI,EAAE,CAAC;AAAA,EAC1D,OAAO;AACL,WAAO,SAAS,IAAI,qBAAqB,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC;AAAA,EAChE;AACF;AAEA,SAAS,wBAAwB,KAA4B;AAC3D,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AAEX,aAAW,MAAM,KAAK;AACpB,QAAI,GAAG,OAAO,WAAY;AAE1B,UAAM,SAAS;AACf,QAAI,OAAO,SAAU;AAErB,UAAM,IAAIC,mBAAkB,OAAO,IAAI;AACvC,UAAM,IAAI,OAAO,SAAS;AAC1B,UAAM,KAAK,OAAO,IAAI,IAAI,EAAE;AAC5B,UAAM,KAAK,OAAO,IAAI,KAAK,EAAE,IAAI,EAAE;AACnC,UAAM,KAAK,OAAO,IAAI,KAAK,EAAE,IAAI,EAAE;AACnC,UAAM,KAAK,OAAO,IAAI,IAAI,EAAE;AAE5B,QAAI,KAAK,KAAM,QAAO;AACtB,QAAI,KAAK,KAAM,QAAO;AACtB,QAAI,KAAK,KAAM,QAAO;AACtB,QAAI,KAAK,KAAM,QAAO;AAAA,EACxB;AAEA,MAAI,SAAS,UAAU;AACrB,WAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAClC;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG,KAAK,IAAI,GAAG,OAAO,IAAI;AAAA,IAC1B,GAAG,KAAK,IAAI,GAAG,OAAO,IAAI;AAAA,EAC5B;AACF;AAEA,SAAS,iBAAiB,KAAmC,GAAiB;AAC5E,QAAM,IAAIC,cAAa,CAAC;AACxB,MAAI,IAAI;AACR,SAAO,IAAI,EAAE,QAAQ;AACnB,UAAM,MAAM,EAAE,GAAG;AACjB,YAAQ,KAAK;AAAA,MACX,KAAK,KAAK;AACR,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,YAAI,OAAO,GAAG,CAAC;AACf;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AACR,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,YAAI,OAAO,GAAG,CAAC;AACf;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AACR,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAC7B,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAC7B,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAC7B,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAC7B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,YAAI,cAAc,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAC1C;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AACR,cAAM,KAAK,WAAW,EAAE,GAAG,CAAC;AAC5B,cAAM,KAAK,WAAW,EAAE,GAAG,CAAC;AAC5B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,YAAI,iBAAiB,IAAI,IAAI,GAAG,CAAC;AACjC;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AACR,YAAI,UAAU;AACd;AAAA,MACF;AAAA,MACA;AACE;AAAA,IACJ;AAAA,EACF;AACF;AAEA,SAASD,mBAAkB,GAAwB;AACjD,QAAM,IAAIC,cAAa,CAAC;AACxB,MAAI,IAAI;AACR,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO;AAEX,QAAM,QAAQ,CAAC,GAAW,MAAoB;AAC5C,QAAI,IAAI,KAAM,QAAO;AACrB,QAAI,IAAI,KAAM,QAAO;AACrB,QAAI,IAAI,KAAM,QAAO;AACrB,QAAI,IAAI,KAAM,QAAO;AAAA,EACvB;AAEA,SAAO,IAAI,EAAE,QAAQ;AACnB,UAAM,MAAM,EAAE,GAAG;AACjB,YAAQ,KAAK;AAAA,MACX,KAAK;AAAA,MACL,KAAK,KAAK;AACR,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,cAAM,GAAG,CAAC;AACV;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AACR,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAC7B,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAC7B,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAC7B,cAAM,MAAM,WAAW,EAAE,GAAG,CAAC;AAC7B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,cAAM,KAAK,GAAG;AACd,cAAM,KAAK,GAAG;AACd,cAAM,GAAG,CAAC;AACV;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AACR,cAAM,KAAK,WAAW,EAAE,GAAG,CAAC;AAC5B,cAAM,KAAK,WAAW,EAAE,GAAG,CAAC;AAC5B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,cAAM,IAAI,WAAW,EAAE,GAAG,CAAC;AAC3B,cAAM,IAAI,EAAE;AACZ,cAAM,GAAG,CAAC;AACV;AAAA,MACF;AAAA,MACA,KAAK;AACH;AAAA,MACF;AACE;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,SAAS,UAAU;AACrB,WAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAClC;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG,OAAO;AAAA,IACV,GAAG,OAAO;AAAA,EACZ;AACF;AAEA,SAAS,cACP,KACA,GACA,GACA,GACA,GACA,GACM;AACN,MAAI,OAAO,IAAI,GAAG,CAAC;AACnB,MAAI,MAAM,IAAI,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC;AACnC,MAAI,MAAM,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC;AACnC,MAAI,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC;AAC3B,MAAI,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC;AAC3B,MAAI,UAAU;AAChB;AAEA,SAASA,cAAa,GAAqB;AACzC,SAAO,EAAE,MAAM,qCAAqC,KAAK,CAAC;AAC5D;;;ACvYA,sBAAyB;AACzB,WAAsB;AACtB,YAAuB;AAEvB,SAAS,oBAAoB,KAA0B;AACrD,QAAM,EAAE,QAAQ,YAAY,WAAW,IAAI;AAM3C,MAAI,OAAO,sBAAsB,eAAe,kBAAkB,mBAAmB;AACnF,UAAMC,MAAK,IAAI,YAAY,UAAU;AACrC,QAAI,WAAWA,GAAE,EAAE,IAAI,GAAG;AAC1B,WAAOA;AAAA,EACT;AAEA,QAAM,KAAK;AAEX,SAAO,GAAG,MAAM,YAAY,aAAa,UAAU;AACrD;AAEA,eAAsB,4BAA4B,WAAyC;AACzF,MAAI;AACF,QAAI,eAAe,KAAK,SAAS,GAAG;AAClC,YAAM,SAAS,UAAU,WAAW,QAAQ,IAAI,QAAQ;AAExD,YAAMC,OAAc,MAAM,IAAI,QAAgB,CAAC,SAAS,WAAW;AACjE,cAAM,UAAU,OAAO,IAAI,WAAW,CAAC,QAAQ;AAC7C,gBAAM,EAAE,WAAW,IAAI;AAEvB,cAAI,eAAe,aAAa,OAAO,cAAc,MAAM;AACzD,mBAAO,IAAI,MAAM,mCAAmC,UAAU,QAAQ,SAAS,EAAE,CAAC;AAClF,gBAAI,OAAO;AACX;AAAA,UACF;AAEA,gBAAM,SAAmB,CAAC;AAE1B,cAAI,GAAG,QAAQ,CAAC,UAAkB;AAChC,mBAAO,KAAK,KAAK;AAAA,UACnB,CAAC;AAED,cAAI,GAAG,OAAO,MAAM;AAClB,gBAAI;AACF,sBAAQ,OAAO,OAAO,MAAM,CAAC;AAAA,YAC/B,SAAS,KAAK;AACZ;AAAA,gBACE,IAAI;AAAA,kBACF,0CACE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF,CAAC;AAED,cAAI,GAAG,SAAS,CAAC,QAAQ;AACvB,mBAAO,IAAI,MAAM,sBAAsB,SAAS,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,UACrE,CAAC;AAAA,QACH,CAAC;AAED,gBAAQ,GAAG,SAAS,CAAC,QAAQ;AAC3B,iBAAO,IAAI,MAAM,qBAAqB,SAAS,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,QACpE,CAAC;AAED,gBAAQ,WAAW,KAAO,MAAM;AAC9B,kBAAQ,QAAQ;AAChB,iBAAO,IAAI,MAAM,iCAAiC,SAAS,EAAE,CAAC;AAAA,QAChE,CAAC;AAAA,MACH,CAAC;AAED,aAAO,oBAAoBA,IAAG;AAAA,IAChC;AAEA,UAAM,MAAM,UAAM,0BAAS,SAAS;AACpC,WAAO,oBAAoB,GAAG;AAAA,EAChC,SAAS,KAAK;AACZ,QAAI,eAAe,OAAO;AACxB,YAAM,IAAI,MAAM,kBAAkB,SAAS,KAAK,IAAI,OAAO,EAAE;AAAA,IAC/D;AACA,UAAM,IAAI,MAAM,kBAAkB,SAAS,KAAK,OAAO,GAAG,CAAC,EAAE;AAAA,EAC/D;AACF;;;ACjFA,2BAAsB;AACtB,qBAAe;AAoCR,IAAM,iBAAN,MAAqB;AAAA,EAClB,aAA4B;AAAA,EAE5B,WAAW,GAAmB;AACpC,QAAI,KAAK,eAAAC,QAAG,WAAW,CAAC,GAAG;AACzB,WAAK,aAAa;AAClB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,MAAgC;AACzC,QAAI,OAAO,WAAW,aAAa;AACjC,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC3E;AAEA,QAAI,KAAK,WAAW,MAAM,UAAU,EAAG;AAEvC,QAAI,KAAK,WAAW,QAAQ,IAAI,WAAW,EAAG;AAC9C,QAAI,KAAK,WAAW,QAAQ,IAAI,UAAU,EAAG;AAE7C,QAAI,KAAK,WAAW,iBAAiB,EAAG;AAExC,QAAI;AACF,YAAM,eAAe,MAAM,OAAO,eAAe;AACjD,YAAM,IAAK,aAAc;AACzB,UAAI,KAAK,WAAW,CAAC,EAAG;AAAA,IAC1B,QAAQ;AAAA,IAER;AAEA,UAAM,IAAI,MAAM,4EAA4E;AAAA,EAC9F;AAAA,EAEA,MAAM,cACJ,gBACA,SACe;AACf,QAAI,CAAC,KAAK,WAAY,OAAM,KAAK,KAAK,EAAE,YAAY,QAAQ,WAAW,CAAC;AAExE,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,IAAI;AAEJ,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,GAAG,IAAI,CAAC;AAE9D,YAAQ;AAAA,MACN,+BAAwB,KAAK,IAAI,MAAM,MAAM,GAAG,QAAQ,QAAQ,MAAM,WAAW;AAAA,UACpE,GAAG,YAAY,MAAM,UAAU,IAAI,aAAa,OAAO,WAAW,KAAK,aAAa,MAAM;AAAA,IACzG;AAEA,WAAO,IAAI,QAAQ,OAAO,SAAS,WAAW;AAC5C,YAAM,OAAO;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,GAAG;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,GAAG;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,GAAG;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,YAAM,aAAS,4BAAM,KAAK,YAAa,MAAM,EAAE,OAAO,CAAC,QAAQ,WAAW,MAAM,EAAE,CAAC;AACnF,UAAI,cAAc;AAElB,aAAO,OAAO,GAAG,QAAQ,CAAC,SAAS;AACjC,cAAM,UAAU,KAAK,SAAS;AAC9B,cAAM,IAAI,QAAQ,MAAM,0CAA0C;AAClE,YAAI,GAAG;AACL,gBAAM,KAAK,SAAS,EAAE,CAAC,GAAG,EAAE;AAC5B,gBAAM,KAAK,SAAS,EAAE,CAAC,GAAG,EAAE;AAC5B,gBAAM,KAAK,SAAS,EAAE,CAAC,GAAG,EAAE;AAC5B,gBAAM,KAAK,EAAE,CAAC,IAAI,WAAW,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI;AAC5C,gBAAM,cAAc,KAAK,OAAO,KAAK,KAAK,KAAK;AAC/C,gBAAM,MAAM,KAAK,IAAI,KAAK,KAAK,MAAO,cAAc,WAAY,GAAG,CAAC;AACpE,cAAI,MAAM,OAAO,EAAG,SAAQ,IAAI,uBAAgB,GAAG,GAAG;AAAA,QACxD;AACA,uBAAe;AAAA,MACjB,CAAC;AAED,aAAO,GAAG,SAAS,CAAC,SAAS;AAC3B,YAAI,SAAS,GAAG;AACd,kBAAQ,IAAI,mCAA8B;AAC1C,kBAAQ;AAAA,QACV,OAAO;AACL,kBAAQ,MAAM,kBAAkB,WAAW;AAC3C,iBAAO,IAAI,MAAM,2BAA2B,IAAI,EAAE,CAAC;AAAA,QACrD;AAAA,MACF,CAAC;AAED,aAAO,GAAG,SAAS,CAAC,QAAQ;AAC1B,gBAAQ,MAAM,8BAAyB,GAAG;AAC1C,eAAO,GAAG;AAAA,MACZ,CAAC;AAED,UAAI;AACF,cAAM,UAAU,MAAM,kBAAkB,EAAE,OAAO,QAAQ,WAAW,CAAC;AACrE,iBAAS,QAAQ,GAAG,QAAQ,aAAa,SAAS;AAChD,gBAAM,IAAK,SAAS,cAAc,KAAM;AACxC,gBAAM,MAAM,MAAM,eAAe,CAAC;AAClC,gBAAM,QAAQ,OAAO,GAAG;AACxB,gBAAM,MAAM,MAAM,QAAQ,MAAM;AAEhC,gBAAM,KAAK,OAAO,MAAM,MAAM,GAAG;AACjC,cAAI,CAAC,GAAI,OAAM,IAAI,QAAQ,CAAC,MAAM,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC;AAE/D,cAAI,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC,CAAC,MAAM,GAAG;AAClD,kBAAM,MAAM,KAAK,OAAQ,QAAQ,KAAK,cAAe,GAAG;AACxD,oBAAQ,IAAI,qCAAyB,GAAG,GAAG;AAAA,UAC7C;AAAA,QACF;AACA,eAAO,MAAM,IAAI;AAAA,MACnB,SAAS,KAAK;AACZ,gBAAQ,MAAM,2BAA2B,GAAG;AAC5C,eAAO,KAAK,SAAS;AACrB,eAAO,GAAG;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC1HO,IAAMC,gBAAe,CAC1B,OACmE;AACnE,SAAO,GAAG,OAAO,cAAe,GAA2C,aAAa;AAC1F;AAEO,IAAMC,eAAc,CACzB,OACqE;AACrE,SAAO,GAAG,OAAO,cAAe,GAA2C,aAAa;AAC1F;;;AdpEA,eAAsB,iBACpB,OAMI,CAAC,GACL;AACA,QAAM,QAAQ,KAAK,SAAS,cAAc,SAAS;AACnD,QAAM,SAAS,KAAK,UAAU,cAAc,SAAS;AACrD,QAAM,aAAa,KAAK,cAAc,cAAc,SAAS;AAC7D,QAAM,MAAM,KAAK,OAAO;AACxB,QAAM,cAAc,KAAK;AAEzB,QAAM,QAAQ,IAAI,aAAa,WAAW;AAC1C,QAAM,SAAS,IAAI,aAAa,KAAK;AACrC,QAAM,iBAAiB,IAAI,eAAe;AAE1C,MAAI;AACF,UAAM,MAAM,KAAK;AAAA,EACnB,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,uCAAuC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IACzF;AAAA,EACF;AAEA,iBAAe,YAAY,OAA0B;AACnD,QAAI;AACF,UAAI,MAAM,aAAa;AACrB,mBAAW,MAAM,MAAM,aAAa;AAClC,cAAI;AACF,kBAAM,QAAQ,MAAM,4BAA4B,GAAG,GAAG;AACtD,kBAAM,MAAM,kBAAkB,OAAO;AAAA,cACnC,QAAQ,GAAG;AAAA,cACX,QAAQ,GAAG,UAAU;AAAA,cACrB,OAAO,GAAG,SAAS;AAAA,YACrB,CAAC;AAAA,UACH,SAAS,KAAK;AACZ,kBAAM,IAAI;AAAA,cACR,+BAA+B,GAAG,MAAM,UAAU,GAAG,GAAG,KACtD,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAM,OAAO,MAAM,QAAQ;AAAA,QACzB,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS;AAAA,MACX;AACA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,eAAe,OAAO;AACxB,cAAM;AAAA,MACR;AACA,YAAM,IAAI,MAAM,2BAA2B,OAAO,GAAG,CAAC,EAAE;AAAA,IAC1D;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,OAA8C;AACrD,UAAI;AACF,cAAM,EAAE,OAAO,MAAM,IAAI,oBAAoB,SAAS,OAAO;AAAA,UAC3D,YAAY;AAAA,UACZ,SAAS;AAAA,QACX,CAAC;AACD,YAAI,MAAO,OAAM;AACjB,eAAO,EAAE,MAAkC;AAAA,MAC7C,SAAS,KAAK;AACZ,YAAI,eAAe,OAAO;AACxB,gBAAM,IAAI,MAAM,sBAAsB,IAAI,OAAO,EAAE;AAAA,QACrD;AACA,cAAM,IAAI,MAAM,sBAAsB,OAAO,GAAG,CAAC,EAAE;AAAA,MACrD;AAAA,IACF;AAAA,IAEA,MAAM,qBACJ,MACA,MACe;AACf,UAAI;AACF,cAAM,QAAQ,MAAM,4BAA4B,IAAI;AACpD,cAAM,MAAM,kBAAkB,OAAO,IAAI;AAAA,MAC3C,SAAS,KAAK;AACZ,cAAM,IAAI;AAAA,UACR,4BAA4B,KAAK,MAAM,eAAe,IAAI,KACxD,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,oBACJ,KACA,MACe;AACf,UAAI;AACF,cAAM,QAAQ,MAAM,4BAA4B,GAAG;AACnD,cAAM,MAAM,kBAAkB,OAAO,IAAI;AAAA,MAC3C,SAAS,KAAK;AACZ,cAAM,IAAI;AAAA,UACR,4BAA4B,KAAK,MAAM,cAAc,GAAG,KACtD,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,OAA0B,UAAkB;AAC5D,UAAI;AACF,cAAM,OAAO,MAAM,YAAY,KAAK;AACpC,cAAM,OAAO,EAAE,QAAQ,KAAK,QAAQ,QAAQ,GAAG,KAAK,MAAM,IAAI,OAAO,KAAK,MAAM;AAEhF,YAAI;AACJ,YAAI;AACF,kBAAQ,MAAM,OAAO,OAAO;AAAA,YAC1B,MAAM,MAAM;AAAA,YACZ,OAAO,MAAM,SAAS;AAAA,YACtB,eAAe,MAAM,OAAO,iBAAiB;AAAA,YAC7C,UAAU,KAAK;AAAA,YACf,YAAY,MAAM,OAAO,cAAc;AAAA,YACvC;AAAA,YACA,eAAe,MAAM,OAAO,iBAAiB;AAAA,UAC/C,CAAC;AAAA,QACH,SAAS,KAAK;AACZ,gBAAM,IAAI;AAAA,YACR,0BAA0B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAC5E;AAAA,QACF;AAEA,cAAM,WAAW;AAAA,UACf,GAAG;AAAA,UACH,GAAG;AAAA,UACH,OAAO,MAAM,SAAS;AAAA,UACtB,QAAQ,MAAM,UAAU;AAAA,QAC1B;AAEA,cAAM,UAAU,MAAM,SAAS;AAC/B,cAAM,UAAU,MAAM,UAAU;AAChC,cAAM,WAAW,MAAM,cAAc;AAErC,YAAI;AACJ,YAAI;AACF,iBAAO,MAAM,aAAa;AAAA,YACxB,QAAQ,EAAE,OAAO,SAAS,QAAQ,SAAS,YAAY,SAAS;AAAA,YAChE;AAAA,YACA;AAAA,YACA,MAAM;AAAA,cACJ,QAAQ,KAAK;AAAA,cACb,MAAM,KAAK;AAAA,cACX,QAAQ,GAAG,KAAK,MAAM;AAAA,cACtB,OAAO,KAAK;AAAA,cACZ,OAAO,KAAK;AAAA,cACZ,SAAS,KAAK;AAAA,YAChB;AAAA,YACA,OAAO;AAAA,cACL,YAAY,MAAM,OAAO,cAAc;AAAA,cACvC,gBAAgB,MAAM,OAAO,kBAAkB;AAAA,cAC/C,UAAU,MAAM,OAAO;AAAA,YACzB;AAAA,YACA,QAAQ,MAAM;AAAA,YACd,QAAQ,MAAM;AAAA,YACd,OAAO,MAAM,SAAS,EAAE,YAAY,QAAQ,UAAU,SAAS;AAAA,YAC/D,YAAY,MAAM;AAAA,YAClB,mBAAmB,CAAC,QAAQ,MAAM,UAAU,MAAM,GAAG;AAAA,YACrD,eAAe,MAAM,MAAM,cAAc,IAAI;AAAA,UAC/C,CAAC;AAAA,QACH,SAAS,KAAK;AACZ,gBAAM,IAAI;AAAA,YACR,oCAAoC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UACtF;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,MAAM,eAAe,MAAM,OAAO;AAAA,YACtC,GAAG;AAAA,YACH,UAAU,KAAK;AAAA,YACf,MAAM,MAAM,YACR;AAAA,cACE,QAAQ,MAAM,UAAU;AAAA,cACxB,OAAO,MAAM,UAAU;AAAA,cACvB,UAAU,MAAM,UAAU;AAAA,cAC1B,OAAO,MAAM,UAAU;AAAA,cACvB,WAAW,MAAM,UAAU;AAAA,YAC7B,IACA;AAAA,UACN,CAAC;AAED,iBAAO;AAAA,QACT,SAAS,KAAK;AACZ,gBAAM,IAAI;AAAA,YACR,8BAA8B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAChF;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,eAAe,OAAO;AACxB,gBAAM;AAAA,QACR;AACA,cAAM,IAAI,MAAM,kCAAkC,QAAQ,MAAM,OAAO,GAAG,CAAC,EAAE;AAAA,MAC/E;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,GAA6D;AAChF,UAAI;AACF,eAAO,MAAM,kBAAkB;AAAA,UAC7B,OAAO,EAAE,SAAS;AAAA,UAClB,QAAQ,EAAE,UAAU;AAAA,UACpB,YAAY,EAAE,cAAc;AAAA,QAC9B,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,cAAM,IAAI;AAAA,UACR,8BAA8B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QAChF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,cACJ,OACA,SACe;AACf,UAAI;AACF,cAAM,eAAuC;AAAA,UAC3C,OAAO,MAAM,SAAS;AAAA,UACtB,QAAQ,MAAM,UAAU;AAAA,UACxB;AAAA,UACA,UAAU,MAAM,WAAW,YAAY;AAAA,UACvC,YAAY,QAAQ,cAAc;AAAA,UAClC,YAAY,MAAM,cAAc;AAAA,QAClC;AAEA,cAAM,iBAAiB,OAAO,SAAiB;AAC7C,iBAAO,KAAK,YAAY,OAAO,IAAI;AAAA,QACrC;AAEA,cAAM,eAAe,cAAc,gBAAgB,YAAY;AAAA,MACjE,SAAS,KAAK;AACZ,cAAM,IAAI;AAAA,UACR,6BAA6B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QAC/E;AAAA,MACF;AAAA,IACF;AAAA,IAEA,UAAgB;AACd,UAAI;AACF,cAAM,QAAQ;AAAA,MAChB,SAAS,KAAK;AACZ,gBAAQ,MAAM,yBAAyB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,MAC3F;AAAA,IACF;AAAA,EACF;AACF;","names":["isGlyphFill","isShadowFill","Joi","computePathBounds","tokenizePath","ab","buf","fs","isShadowFill","isGlyphFill"]}
1
+ {"version":3,"sources":["../src/env/entry.node.ts","../src/schema/asset-schema.ts","../src/config/canvas-constants.ts","../src/wasm/hb-loader.ts","../src/core/font-registry.ts","../src/core/layout.ts","../src/core/gradients.ts","../src/core/decoration.ts","../src/core/drawops.ts","../src/core/animations.ts","../src/core/colors.ts","../src/painters/node.ts","../src/io/node.ts","../src/core/video-generator.ts","../src/types.ts"],"sourcesContent":["import { RichTextAssetSchema, type RichTextValidated } from \"../schema/asset-schema\";\r\nimport { CANVAS_CONFIG } from \"../config/canvas-constants\";\r\nimport { FontRegistry } from \"../core/font-registry\";\r\nimport { LayoutEngine } from \"../core/layout\";\r\nimport { buildDrawOps } from \"../core/drawops\";\r\nimport { applyAnimation } from \"../core/animations\";\r\nimport { createNodePainter } from \"../painters/node\";\r\nimport { loadFileOrHttpToArrayBuffer } from \"../io/node\";\r\nimport { VideoGenerator, VideoGenerationOptions } from \"../core/video-generator\";\r\n\r\nexport async function createTextEngine(\r\n opts: {\r\n width?: number;\r\n height?: number;\r\n pixelRatio?: number;\r\n fps?: number;\r\n wasmBaseURL?: string;\r\n } = {}\r\n) {\r\n const width = opts.width ?? CANVAS_CONFIG.DEFAULTS.width;\r\n const height = opts.height ?? CANVAS_CONFIG.DEFAULTS.height;\r\n const pixelRatio = opts.pixelRatio ?? CANVAS_CONFIG.DEFAULTS.pixelRatio;\r\n const fps = opts.fps ?? 30;\r\n const wasmBaseURL = opts.wasmBaseURL;\r\n\r\n const fonts = new FontRegistry(wasmBaseURL);\r\n const layout = new LayoutEngine(fonts);\r\n const videoGenerator = new VideoGenerator();\r\n\r\n try {\r\n await fonts.init();\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to initialize font registry: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n\r\n async function ensureFonts(asset: RichTextValidated) {\r\n try {\r\n if (asset.customFonts) {\r\n for (const cf of asset.customFonts) {\r\n try {\r\n const bytes = await loadFileOrHttpToArrayBuffer(cf.src);\r\n await fonts.registerFromBytes(bytes, {\r\n family: cf.family,\r\n weight: cf.weight ?? \"400\",\r\n style: cf.style ?? \"normal\",\r\n });\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to load custom font \"${cf.family}\" from ${cf.src}: ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n }\r\n const main = asset.font ?? {\r\n family: \"Roboto\",\r\n weight: \"400\",\r\n style: \"normal\",\r\n size: 48,\r\n color: \"#000000\",\r\n opacity: 1,\r\n };\r\n return main;\r\n } catch (err) {\r\n if (err instanceof Error) {\r\n throw err;\r\n }\r\n throw new Error(`Failed to ensure fonts: ${String(err)}`);\r\n }\r\n }\r\n\r\n return {\r\n validate(input: unknown): { value: RichTextValidated } {\r\n try {\r\n const { value, error } = RichTextAssetSchema.validate(input, {\r\n abortEarly: false,\r\n convert: true,\r\n });\r\n if (error) throw error;\r\n return { value: value as RichTextValidated };\r\n } catch (err) {\r\n if (err instanceof Error) {\r\n throw new Error(`Validation failed: ${err.message}`);\r\n }\r\n throw new Error(`Validation failed: ${String(err)}`);\r\n }\r\n },\r\n\r\n async registerFontFromFile(\r\n path: string,\r\n desc: { family: string; weight?: string | number; style?: string }\r\n ): Promise<void> {\r\n try {\r\n const bytes = await loadFileOrHttpToArrayBuffer(path);\r\n await fonts.registerFromBytes(bytes, desc);\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to register font \"${desc.family}\" from file ${path}: ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n },\r\n\r\n async registerFontFromUrl(\r\n url: string,\r\n desc: { family: string; weight?: string | number; style?: string }\r\n ): Promise<void> {\r\n try {\r\n const bytes = await loadFileOrHttpToArrayBuffer(url);\r\n await fonts.registerFromBytes(bytes, desc);\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to register font \"${desc.family}\" from URL ${url}: ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n },\r\n\r\n async renderFrame(asset: RichTextValidated, tSeconds: number) {\r\n try {\r\n const main = await ensureFonts(asset);\r\n const desc = { family: main.family, weight: `${main.weight}`, style: main.style };\r\n\r\n let lines;\r\n try {\r\n lines = await layout.layout({\r\n text: asset.text,\r\n width: asset.width ?? width,\r\n letterSpacing: asset.style?.letterSpacing ?? 0,\r\n fontSize: main.size,\r\n lineHeight: asset.style?.lineHeight ?? 1.2,\r\n desc,\r\n textTransform: asset.style?.textTransform ?? \"none\",\r\n });\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to layout text: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n\r\n const textRect = {\r\n x: 0,\r\n y: 0,\r\n width: asset.width ?? width,\r\n height: asset.height ?? height,\r\n };\r\n\r\n const canvasW = asset.width ?? width;\r\n const canvasH = asset.height ?? height;\r\n const canvasPR = asset.pixelRatio ?? pixelRatio;\r\n\r\n let ops0;\r\n try {\r\n ops0 = await buildDrawOps({\r\n canvas: { width: canvasW, height: canvasH, pixelRatio: canvasPR },\r\n textRect,\r\n lines,\r\n font: {\r\n family: main.family,\r\n size: main.size,\r\n weight: `${main.weight}`,\r\n style: main.style,\r\n color: main.color,\r\n opacity: main.opacity,\r\n },\r\n style: {\r\n lineHeight: asset.style?.lineHeight ?? 1.2,\r\n textDecoration: asset.style?.textDecoration ?? \"none\",\r\n gradient: asset.style?.gradient,\r\n },\r\n stroke: asset.stroke,\r\n shadow: asset.shadow,\r\n align: asset.align ?? { horizontal: \"left\", vertical: \"middle\" },\r\n background: asset.background,\r\n glyphPathProvider: (gid) => fonts.glyphPath(desc, gid),\r\n getUnitsPerEm: () => fonts.getUnitsPerEm(desc),\r\n });\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to build draw operations: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n\r\n try {\r\n const ops = applyAnimation(ops0, lines, {\r\n t: tSeconds,\r\n fontSize: main.size,\r\n anim: asset.animation\r\n ? {\r\n preset: asset.animation.preset,\r\n speed: asset.animation.speed,\r\n duration: asset.animation.duration,\r\n style: asset.animation.style,\r\n direction: asset.animation.direction,\r\n }\r\n : undefined,\r\n });\r\n\r\n return ops;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to apply animation: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n } catch (err) {\r\n if (err instanceof Error) {\r\n throw err;\r\n }\r\n throw new Error(`Failed to render frame at time ${tSeconds}s: ${String(err)}`);\r\n }\r\n },\r\n\r\n async createRenderer(p: { width?: number; height?: number; pixelRatio?: number }) {\r\n try {\r\n return await createNodePainter({\r\n width: p.width ?? width,\r\n height: p.height ?? height,\r\n pixelRatio: p.pixelRatio ?? pixelRatio,\r\n });\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to create renderer: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n },\r\n\r\n async generateVideo(\r\n asset: RichTextValidated,\r\n options: Partial<VideoGenerationOptions>\r\n ): Promise<void> {\r\n try {\r\n const finalOptions: VideoGenerationOptions = {\r\n width: asset.width ?? width,\r\n height: asset.height ?? height,\r\n fps: fps,\r\n duration: asset.animation?.duration ?? 3,\r\n outputPath: options.outputPath ?? \"output.mp4\",\r\n pixelRatio: asset.pixelRatio ?? pixelRatio,\r\n };\r\n\r\n const frameGenerator = async (time: number) => {\r\n return this.renderFrame(asset, time);\r\n };\r\n\r\n await videoGenerator.generateVideo(frameGenerator, finalOptions);\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to generate video: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n },\r\n\r\n destroy(): void {\r\n try {\r\n fonts.destroy();\r\n } catch (err) {\r\n console.error(`Error during cleanup: ${err instanceof Error ? err.message : String(err)}`);\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport * from \"../types\";\r\n","import Joi from \"joi\";\r\nimport { CANVAS_CONFIG } from \"../config/canvas-constants\";\r\n\r\nconst HEX6 = /^#[A-Fa-f0-9]{6}$/;\r\n\r\nconst gradientSchema = Joi.object({\r\n type: Joi.string().valid(\"linear\", \"radial\").default(\"linear\"),\r\n angle: Joi.number().min(0).max(360).default(0),\r\n stops: Joi.array()\r\n .items(\r\n Joi.object({\r\n offset: Joi.number().min(0).max(1).required(),\r\n color: Joi.string().pattern(HEX6).required()\r\n }).unknown(false)\r\n )\r\n .min(2)\r\n .required()\r\n}).unknown(false);\r\n\r\nconst shadowSchema = Joi.object({\r\n offsetX: Joi.number().default(0),\r\n offsetY: Joi.number().default(0),\r\n blur: Joi.number().min(0).default(0),\r\n color: Joi.string().pattern(HEX6).default(\"#000000\"),\r\n opacity: Joi.number().min(0).max(1).default(0.5)\r\n}).unknown(false);\r\n\r\nconst strokeSchema = Joi.object({\r\n width: Joi.number().min(0).default(0),\r\n color: Joi.string().pattern(HEX6).default(\"#000000\"),\r\n opacity: Joi.number().min(0).max(1).default(1)\r\n}).unknown(false);\r\n\r\nconst fontSchema = Joi.object({\r\n family: Joi.string().default(CANVAS_CONFIG.DEFAULTS.fontFamily),\r\n size: Joi.number()\r\n .min(CANVAS_CONFIG.LIMITS.minFontSize)\r\n .max(CANVAS_CONFIG.LIMITS.maxFontSize)\r\n .default(CANVAS_CONFIG.DEFAULTS.fontSize),\r\n weight: Joi.alternatives().try(Joi.string(), Joi.number()).default(\"400\"),\r\n style: Joi.string().valid(\"normal\", \"italic\", \"oblique\").default(\"normal\"),\r\n color: Joi.string().pattern(HEX6).default(CANVAS_CONFIG.DEFAULTS.color),\r\n opacity: Joi.number().min(0).max(1).default(1)\r\n}).unknown(false);\r\n\r\nconst styleSchema = Joi.object({\r\n letterSpacing: Joi.number().default(0),\r\n lineHeight: Joi.number().min(0).max(10).default(1.2),\r\n textTransform: Joi.string().valid(\"none\", \"uppercase\", \"lowercase\", \"capitalize\").default(\"none\"),\r\n textDecoration: Joi.string().valid(\"none\", \"underline\", \"line-through\").default(\"none\"),\r\n gradient: gradientSchema.optional()\r\n}).unknown(false);\r\n\r\nconst alignmentSchema = Joi.object({\r\n horizontal: Joi.string()\r\n .valid(\"left\", \"center\", \"right\")\r\n .default(CANVAS_CONFIG.DEFAULTS.textAlign),\r\n vertical: Joi.string().valid(\"top\", \"middle\", \"bottom\").default(\"middle\")\r\n}).unknown(false);\r\n\r\nconst animationSchema = Joi.object({\r\n preset: Joi.string().valid(...CANVAS_CONFIG.ANIMATION_TYPES as readonly string[]),\r\n speed: Joi.number().min(0.1).max(10).default(1),\r\n duration: Joi.number()\r\n .min(CANVAS_CONFIG.LIMITS.minDuration)\r\n .max(CANVAS_CONFIG.LIMITS.maxDuration)\r\n .optional(),\r\n style: Joi.string()\r\n .valid(\"character\", \"word\")\r\n .optional()\r\n .when(\"preset\", {\r\n is: Joi.valid(\"typewriter\", \"shift\"),\r\n then: Joi.optional(),\r\n otherwise: Joi.forbidden()\r\n }),\r\n direction: Joi.string()\r\n .optional()\r\n .when(\"preset\", {\r\n switch: [\r\n { is: \"ascend\", then: Joi.valid(\"up\", \"down\") },\r\n { is: \"shift\", then: Joi.valid(\"left\", \"right\", \"up\", \"down\") },\r\n { is: \"slideIn\", then: Joi.valid(\"left\", \"right\", \"up\", \"down\") },\r\n { is: \"movingLetters\", then: Joi.valid(\"left\", \"right\", \"up\", \"down\") }\r\n ],\r\n otherwise: Joi.forbidden()\r\n })\r\n}).unknown(false);\r\n\r\nconst backgroundSchema = Joi.object({\r\n color: Joi.string().pattern(HEX6).optional(),\r\n opacity: Joi.number().min(0).max(1).default(1),\r\n borderRadius: Joi.number().min(0).default(0)\r\n}).unknown(false);\r\n\r\nconst customFontSchema = Joi.object({\r\n src: Joi.string().uri().required(),\r\n family: Joi.string().required(),\r\n weight: Joi.alternatives().try(Joi.string(), Joi.number()).optional(),\r\n style: Joi.string().optional(),\r\n originalFamily: Joi.string().optional()\r\n}).unknown(false);\r\n\r\nexport const RichTextAssetSchema = Joi.object({\r\n type: Joi.string().valid(\"rich-text\").required(),\r\n text: Joi.string().allow(\"\").max(CANVAS_CONFIG.LIMITS.maxTextLength).default(\"\"),\r\n width: Joi.number()\r\n .min(CANVAS_CONFIG.LIMITS.minWidth)\r\n .max(CANVAS_CONFIG.LIMITS.maxWidth)\r\n .default(CANVAS_CONFIG.DEFAULTS.width)\r\n .optional(),\r\n height: Joi.number()\r\n .min(CANVAS_CONFIG.LIMITS.minHeight)\r\n .max(CANVAS_CONFIG.LIMITS.maxHeight)\r\n .default(CANVAS_CONFIG.DEFAULTS.height)\r\n .optional(),\r\n font: fontSchema.optional(),\r\n style: styleSchema.optional(),\r\n stroke: strokeSchema.optional(),\r\n shadow: shadowSchema.optional(),\r\n background: backgroundSchema.optional(),\r\n align: alignmentSchema.optional(),\r\n animation: animationSchema.optional(),\r\n customFonts: Joi.array().items(customFontSchema).optional(),\r\n cacheEnabled: Joi.boolean().default(true),\r\n pixelRatio: Joi.number().min(1).max(3).default(CANVAS_CONFIG.DEFAULTS.pixelRatio)\r\n}).unknown(false);\r\n\r\nexport type RichTextValidated = Required<{\r\n type: \"rich-text\";\r\n text: string;\r\n width?: number;\r\n height?: number;\r\n font?: {\r\n family: string;\r\n size: number;\r\n weight: string | number;\r\n style: \"normal\" | \"italic\" | \"oblique\";\r\n color: string;\r\n opacity: number;\r\n };\r\n style?: {\r\n letterSpacing: number;\r\n lineHeight: number;\r\n textTransform: \"none\" | \"uppercase\" | \"lowercase\" | \"capitalize\";\r\n textDecoration: \"none\" | \"underline\" | \"line-through\";\r\n gradient?: {\r\n type: \"linear\" | \"radial\";\r\n angle: number;\r\n stops: { offset: number; color: string }[];\r\n };\r\n };\r\n stroke?: { width: number; color: string; opacity: number };\r\n shadow?: { offsetX: number; offsetY: number; blur: number; color: string; opacity: number };\r\n background?: { color?: string; opacity: number; borderRadius: number };\r\n align?: { horizontal: \"left\" | \"center\" | \"right\"; vertical: \"top\" | \"middle\" | \"bottom\" };\r\n animation?: {\r\n preset: typeof CANVAS_CONFIG.ANIMATION_TYPES[number];\r\n speed: number;\r\n duration?: number;\r\n style?: \"character\" | \"word\";\r\n direction?: \"left\" | \"right\" | \"up\" | \"down\";\r\n };\r\n customFonts?: { src: string; family: string; weight?: string | number; style?: string; originalFamily?: string }[];\r\n cacheEnabled: boolean;\r\n pixelRatio: number;\r\n}>;\r\n","export const CANVAS_CONFIG = {\r\n DEFAULTS: {\r\n width: 800,\r\n height: 400,\r\n pixelRatio: 2,\r\n fontFamily: \"Roboto\",\r\n fontSize: 48,\r\n color: \"#000000\",\r\n textAlign: \"left\" as const\r\n },\r\n LIMITS: {\r\n minWidth: 1,\r\n maxWidth: 4096,\r\n minHeight: 1,\r\n maxHeight: 4096,\r\n minFontSize: 1,\r\n maxFontSize: 512,\r\n minDuration: 0.1,\r\n maxDuration: 120,\r\n maxTextLength: 10000\r\n },\r\n ANIMATION_TYPES: [\r\n \"typewriter\",\r\n \"fadeIn\",\r\n \"slideIn\",\r\n \"shift\",\r\n \"ascend\",\r\n \"movingLetters\"\r\n ] as const\r\n};\r\n","export interface HBBlob {\r\n destroy(): void;\r\n}\r\n\r\nexport interface HBFace {\r\n destroy(): void;\r\n upem?: number;\r\n}\r\n\r\nexport interface HBFont {\r\n destroy(): void;\r\n glyphToPath(glyphId: number): string;\r\n setScale(xScale: number, yScale: number): void;\r\n}\r\n\r\nexport interface HBGlyphInfo {\r\n g: number;\r\n ax: number;\r\n ay: number;\r\n dx: number;\r\n dy: number;\r\n cl: number;\r\n}\r\n\r\nexport interface HBBuffer {\r\n addText(text: string): void;\r\n guessSegmentProperties(): void;\r\n json(): HBGlyphInfo[];\r\n destroy(): void;\r\n}\r\n\r\nexport interface HB {\r\n createBlob(data: ArrayBuffer): HBBlob;\r\n createFace(blob: HBBlob, index: number): HBFace;\r\n createFont(face: HBFace): HBFont;\r\n createBuffer(): HBBuffer;\r\n shape(font: HBFont, buffer: HBBuffer): void;\r\n}\r\n\r\ninterface HarfBuzzJSModule {\r\n default: Promise<HB> | (() => Promise<HB>) | HB;\r\n}\r\n\r\nlet hbSingleton: HB | null = null;\r\n\r\nexport async function initHB(wasmBaseURL?: string): Promise<HB> {\r\n if (hbSingleton) return hbSingleton;\r\n\r\n try {\r\n const mod = (await import(\"harfbuzzjs\")) as HarfBuzzJSModule;\r\n\r\n const candidate = mod.default;\r\n\r\n let hb: HB;\r\n if (typeof candidate === \"function\") {\r\n hb = await candidate();\r\n } else if (candidate && typeof (candidate as Promise<HB>).then === \"function\") {\r\n hb = await (candidate as Promise<HB>);\r\n } else {\r\n hb = candidate as HB;\r\n }\r\n\r\n if (!hb || typeof hb.createBuffer !== \"function\" || typeof hb.createFont !== \"function\") {\r\n throw new Error(\"Failed to initialize HarfBuzz: unexpected export shape from 'harfbuzzjs'.\");\r\n }\r\n\r\n void wasmBaseURL;\r\n\r\n hbSingleton = hb;\r\n return hbSingleton;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to initialize HarfBuzz: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n}\r\n","// src/core/font-registry.ts\r\nimport { initHB, type HB, type HBBlob, type HBFace, type HBFont } from \"../wasm/hb-loader\";\r\n\r\nexport type FontDescriptor = { family: string; weight?: string | number; style?: string };\r\n\r\nexport class FontRegistry {\r\n private hb!: HB;\r\n private faces = new Map<string, HBFace>();\r\n private fonts = new Map<string, HBFont>();\r\n private blobs = new Map<string, HBBlob>();\r\n private wasmBaseURL?: string;\r\n private initPromise?: Promise<void>;\r\n\r\n private static fallbackLoader?: (desc: FontDescriptor) => Promise<ArrayBuffer | undefined>;\r\n static setFallbackLoader(loader: (desc: FontDescriptor) => Promise<ArrayBuffer | undefined>) {\r\n FontRegistry.fallbackLoader = loader;\r\n }\r\n\r\n constructor(wasmBaseURL?: string) {\r\n this.wasmBaseURL = wasmBaseURL;\r\n }\r\n\r\n async init(): Promise<void> {\r\n if (this.initPromise) {\r\n await this.initPromise;\r\n return;\r\n }\r\n if (this.hb) return;\r\n this.initPromise = this._doInit();\r\n try {\r\n await this.initPromise;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to initialize FontRegistry: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n\r\n private async _doInit(): Promise<void> {\r\n try {\r\n this.hb = await initHB(this.wasmBaseURL);\r\n } catch (error) {\r\n this.initPromise = undefined;\r\n throw error;\r\n }\r\n }\r\n\r\n async getHB(): Promise<HB> {\r\n if (!this.hb) {\r\n try {\r\n await this.init();\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to get HarfBuzz instance: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n return this.hb;\r\n }\r\n\r\n private key(desc: FontDescriptor): string {\r\n return `${desc.family}__${desc.weight ?? \"400\"}__${desc.style ?? \"normal\"}`;\r\n }\r\n\r\n async registerFromBytes(bytes: ArrayBuffer, desc: FontDescriptor): Promise<void> {\r\n try {\r\n if (!this.hb) await this.init();\r\n const k = this.key(desc);\r\n if (this.fonts.has(k)) return;\r\n\r\n const blob = this.hb.createBlob(bytes);\r\n const face = this.hb.createFace(blob, 0);\r\n const font = this.hb.createFont(face);\r\n\r\n const upem = (face as HBFaceWithUpem).upem || 1000;\r\n (font as HBFontWithScale).setScale(upem, upem);\r\n\r\n this.blobs.set(k, blob);\r\n this.faces.set(k, face);\r\n this.fonts.set(k, font);\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to register font \"${desc.family}\": ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n\r\n private async tryFallbackInstall(desc: FontDescriptor): Promise<boolean> {\r\n const loader = FontRegistry.fallbackLoader;\r\n if (!loader) return false;\r\n try {\r\n const bytes = await loader({\r\n family: desc.family,\r\n weight: desc.weight ?? \"400\",\r\n style: desc.style ?? \"normal\",\r\n });\r\n if (!bytes) return false;\r\n await this.registerFromBytes(bytes, {\r\n family: desc.family,\r\n weight: desc.weight ?? \"400\",\r\n style: desc.style ?? \"normal\",\r\n });\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n async getFont(desc: FontDescriptor): Promise<HBFont> {\r\n try {\r\n if (!this.hb) await this.init();\r\n const k = this.key(desc);\r\n let f = this.fonts.get(k);\r\n if (!f) {\r\n const installed = await this.tryFallbackInstall(desc);\r\n f = installed ? this.fonts.get(k) : undefined;\r\n }\r\n if (!f) throw new Error(`Font not registered for ${k}`);\r\n return f;\r\n } catch (err) {\r\n if (err instanceof Error && err.message.includes(\"Font not registered\")) {\r\n throw err;\r\n }\r\n throw new Error(\r\n `Failed to get font \"${desc.family}\": ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n\r\n async getFace(desc: FontDescriptor): Promise<HBFace | undefined> {\r\n try {\r\n if (!this.hb) await this.init();\r\n const k = this.key(desc);\r\n let face = this.faces.get(k);\r\n if (!face) {\r\n const installed = await this.tryFallbackInstall(desc);\r\n face = installed ? this.faces.get(k) : undefined;\r\n }\r\n return face;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to get face for \"${desc.family}\": ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n\r\n async getUnitsPerEm(desc: FontDescriptor): Promise<number> {\r\n try {\r\n const face = await this.getFace(desc);\r\n return (face as HBFaceWithUpem)?.upem || 1000;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to get units per em for \"${desc.family}\": ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n\r\n async glyphPath(desc: FontDescriptor, glyphId: number): Promise<string> {\r\n try {\r\n const font = await this.getFont(desc);\r\n const path = font.glyphToPath(glyphId);\r\n return path && path !== \"\" ? path : \"M 0 0\";\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to get glyph path for glyph ${glyphId} in font \"${desc.family}\": ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n\r\n destroy(): void {\r\n try {\r\n for (const [, f] of this.fonts) {\r\n try {\r\n f.destroy();\r\n } catch (err) {\r\n console.error(\r\n `Error destroying font: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n for (const [, f] of this.faces) {\r\n try {\r\n f.destroy();\r\n } catch (err) {\r\n console.error(\r\n `Error destroying face: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n for (const [, b] of this.blobs) {\r\n try {\r\n b.destroy();\r\n } catch (err) {\r\n console.error(\r\n `Error destroying blob: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n this.fonts.clear();\r\n this.faces.clear();\r\n this.blobs.clear();\r\n this.hb = undefined!;\r\n this.initPromise = undefined;\r\n } catch (err) {\r\n console.error(\r\n `Error during FontRegistry cleanup: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n}\r\n\r\ninterface HBFaceWithUpem extends HBFace {\r\n upem?: number;\r\n}\r\ninterface HBFontWithScale extends HBFont {\r\n setScale(xScale: number, yScale: number): void;\r\n}\r\n","import { FontRegistry, FontDescriptor } from \"./font-registry\";\r\nimport { Glyph, ShapedLine } from \"../types\";\r\nimport type { HBGlyphInfo } from \"../wasm/hb-loader\";\r\n\r\nexport type ShapeParams = {\r\n text: string;\r\n width: number;\r\n letterSpacing: number;\r\n fontSize: number;\r\n lineHeight: number;\r\n desc: FontDescriptor;\r\n textTransform: \"none\" | \"uppercase\" | \"lowercase\" | \"capitalize\";\r\n};\r\n\r\nexport class LayoutEngine {\r\n constructor(private fonts: FontRegistry) {}\r\n\r\n private transformText(t: string, tr: ShapeParams[\"textTransform\"]): string {\r\n switch (tr) {\r\n case \"uppercase\":\r\n return t.toUpperCase();\r\n case \"lowercase\":\r\n return t.toLowerCase();\r\n case \"capitalize\":\r\n return t.replace(/\\b\\w/g, (c) => c.toUpperCase());\r\n default:\r\n return t;\r\n }\r\n }\r\n\r\n private async shapeFull(text: string, desc: FontDescriptor): Promise<HBGlyphInfo[]> {\r\n try {\r\n const hb = await this.fonts.getHB();\r\n const buffer = hb.createBuffer();\r\n\r\n try {\r\n buffer.addText(text);\r\n buffer.guessSegmentProperties();\r\n\r\n const font = await this.fonts.getFont(desc);\r\n const face = await this.fonts.getFace(desc);\r\n\r\n const upem = (face as { upem?: number })?.upem || 1000;\r\n (font as { setScale(x: number, y: number): void }).setScale(upem, upem);\r\n\r\n hb.shape(font, buffer);\r\n\r\n const result = buffer.json();\r\n return result;\r\n } finally {\r\n try {\r\n buffer.destroy();\r\n } catch (err) {\r\n console.error(\r\n `Error destroying HarfBuzz buffer: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n }\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to shape text with font \"${desc.family}\": ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n );\r\n }\r\n }\r\n\r\n async layout(params: ShapeParams): Promise<ShapedLine[]> {\r\n try {\r\n const { textTransform, desc, fontSize, letterSpacing, width } = params;\r\n const input = this.transformText(params.text, textTransform);\r\n\r\n if (!input || input.length === 0) {\r\n return [];\r\n }\r\n\r\n let shaped: HBGlyphInfo[];\r\n try {\r\n shaped = await this.shapeFull(input, desc);\r\n } catch (err) {\r\n throw new Error(`Text shaping failed: ${err instanceof Error ? err.message : String(err)}`);\r\n }\r\n\r\n let upem: number;\r\n try {\r\n const face = await this.fonts.getFace(desc);\r\n upem = (face as { upem?: number })?.upem || 1000;\r\n } catch (err) {\r\n throw new Error(\r\n `Failed to get font metrics: ${err instanceof Error ? err.message : String(err)}`\r\n );\r\n }\r\n\r\n const scale = fontSize / upem;\r\n\r\n const glyphs: Glyph[] = shaped.map((g) => {\r\n const charIndex = g.cl;\r\n let char: string | undefined;\r\n\r\n if (charIndex >= 0 && charIndex < input.length) {\r\n char = input[charIndex];\r\n }\r\n\r\n return {\r\n id: g.g,\r\n xAdvance: g.ax * scale + letterSpacing,\r\n xOffset: g.dx * scale,\r\n yOffset: -g.dy * scale,\r\n cluster: g.cl,\r\n char: char,\r\n };\r\n });\r\n\r\n const lines: ShapedLine[] = [];\r\n let currentLine: Glyph[] = [];\r\n let currentWidth = 0;\r\n\r\n const spaceIndices = new Set<number>();\r\n for (let i = 0; i < input.length; i++) {\r\n if (input[i] === \" \") {\r\n spaceIndices.add(i);\r\n }\r\n }\r\n\r\n let lastBreakIndex = -1;\r\n\r\n for (let i = 0; i < glyphs.length; i++) {\r\n const glyph = glyphs[i];\r\n const glyphWidth = glyph.xAdvance;\r\n\r\n if (glyph.char === \"\\n\") {\r\n if (currentLine.length > 0) {\r\n lines.push({\r\n glyphs: currentLine,\r\n width: currentWidth,\r\n y: 0,\r\n });\r\n }\r\n currentLine = [];\r\n currentWidth = 0;\r\n lastBreakIndex = i;\r\n continue;\r\n }\r\n\r\n if (currentWidth + glyphWidth > width && currentLine.length > 0) {\r\n if (lastBreakIndex > -1) {\r\n const breakPoint = lastBreakIndex - (i - currentLine.length) + 1;\r\n const nextLine = currentLine.splice(breakPoint);\r\n\r\n const lineWidth = currentLine.reduce((sum, g) => sum + g.xAdvance, 0);\r\n\r\n lines.push({\r\n glyphs: currentLine,\r\n width: lineWidth,\r\n y: 0,\r\n });\r\n\r\n currentLine = nextLine;\r\n currentWidth = nextLine.reduce((sum, g) => sum + g.xAdvance, 0);\r\n } else {\r\n lines.push({\r\n glyphs: currentLine,\r\n width: currentWidth,\r\n y: 0,\r\n });\r\n currentLine = [];\r\n currentWidth = 0;\r\n }\r\n lastBreakIndex = -1;\r\n }\r\n\r\n currentLine.push(glyph);\r\n currentWidth += glyphWidth;\r\n\r\n if (spaceIndices.has(glyph.cluster)) {\r\n lastBreakIndex = i;\r\n }\r\n }\r\n\r\n if (currentLine.length > 0) {\r\n lines.push({\r\n glyphs: currentLine,\r\n width: currentWidth,\r\n y: 0,\r\n });\r\n }\r\n\r\n const lineHeight = params.lineHeight * fontSize;\r\n for (let i = 0; i < lines.length; i++) {\r\n lines[i].y = (i + 1) * lineHeight;\r\n }\r\n\r\n return lines;\r\n } catch (err) {\r\n if (err instanceof Error) {\r\n throw err;\r\n }\r\n throw new Error(`Layout failed: ${String(err)}`);\r\n }\r\n }\r\n}\r\n","import { GradientSpec } from \"../types\";\r\n\r\nexport function gradientSpecFrom(\r\n g: { type: \"linear\" | \"radial\"; angle: number; stops: { offset: number; color: string }[] },\r\n opacity: number\r\n): GradientSpec {\r\n if (g.type === \"linear\") {\r\n return { kind: \"linear\", angle: g.angle, stops: g.stops, opacity };\r\n } else {\r\n return { kind: \"radial\", stops: g.stops, opacity };\r\n }\r\n}\r\n","export function decorationGeometry(\r\n kind: \"underline\" | \"line-through\",\r\n p: { baselineY: number; fontSize: number; lineWidth: number; xStart: number }\r\n) {\r\n const thickness = Math.max(1, Math.round(p.fontSize * 0.05));\r\n let y = p.baselineY + Math.round(p.fontSize * 0.1);\r\n if (kind === \"line-through\") y = p.baselineY - Math.round(p.fontSize * 0.3);\r\n return { x1: p.xStart, x2: p.xStart + p.lineWidth, y, width: thickness };\r\n}\r\n","import { DrawOp, GradientSpec, ShapedLine } from \"../types\";\r\nimport { gradientSpecFrom } from \"./gradients\";\r\nimport { decorationGeometry } from \"./decoration\";\r\n\r\nexport type PaintParams = {\r\n canvas: { width: number; height: number; pixelRatio: number };\r\n textRect: { x: number; y: number; width: number; height: number };\r\n lines: ShapedLine[];\r\n font: { family: string; size: number; weight: string | number; style: string; color: string; opacity: number };\r\n style: {\r\n lineHeight: number;\r\n textDecoration: \"none\" | \"underline\" | \"line-through\";\r\n gradient?: { type: \"linear\" | \"radial\"; angle: number; stops: { offset: number; color: string }[] };\r\n };\r\n stroke?: { width: number; color: string; opacity: number };\r\n shadow?: { offsetX: number; offsetY: number; blur: number; color: string; opacity: number };\r\n align: { horizontal: \"left\" | \"center\" | \"right\"; vertical: \"top\" | \"middle\" | \"bottom\" };\r\n background?: { color?: string; opacity: number; borderRadius: number };\r\n glyphPathProvider: (glyphId: number) => Promise<string>;\r\n /** UPEM for scaling glyph paths from font units → px */\r\n getUnitsPerEm: () => Promise<number>;\r\n};\r\n\r\nexport async function buildDrawOps(p: PaintParams): Promise<DrawOp[]> {\r\n const ops: DrawOp[] = [];\r\n\r\n // Begin frame / background\r\n ops.push({\r\n op: \"BeginFrame\",\r\n width: p.canvas.width,\r\n height: p.canvas.height,\r\n pixelRatio: p.canvas.pixelRatio,\r\n clear: true,\r\n bg: p.background && p.background.color\r\n ? { color: p.background.color, opacity: p.background.opacity, radius: p.background.borderRadius }\r\n : undefined\r\n });\r\n\r\n if (p.lines.length === 0) return ops;\r\n\r\n // Font units → px\r\n const upem = Math.max(1, await p.getUnitsPerEm());\r\n const scale = p.font.size / upem;\r\n\r\n // Block metrics\r\n const blockHeight = p.lines[p.lines.length - 1].y;\r\n\r\n // Vertical anchor\r\n let blockY: number;\r\n switch (p.align.vertical) {\r\n case \"top\": blockY = p.font.size; break;\r\n case \"bottom\": blockY = p.textRect.height - blockHeight + p.font.size; break;\r\n case \"middle\":\r\n default: blockY = (p.textRect.height - blockHeight) / 2 + p.font.size; break;\r\n }\r\n\r\n // Fill style (solid or gradient)\r\n const fill: GradientSpec = p.style.gradient\r\n ? gradientSpecFrom(p.style.gradient, 1)\r\n : { kind: \"solid\", color: p.font.color, opacity: p.font.opacity };\r\n\r\n // Decoration/cursor color should match text (for gradient, use the last stop as a representative color)\r\n const decoColor = p.style.gradient\r\n ? p.style.gradient.stops[p.style.gradient.stops.length - 1]?.color ?? p.font.color\r\n : p.font.color;\r\n\r\n // Track global text bounds in world space so painters can build a single gradient\r\n let gMinX = Infinity, gMinY = Infinity, gMaxX = -Infinity, gMaxY = -Infinity;\r\n\r\n for (const line of p.lines) {\r\n // Horizontal anchor\r\n let lineX: number;\r\n switch (p.align.horizontal) {\r\n case \"left\": lineX = 0; break;\r\n case \"right\": lineX = p.textRect.width - line.width; break;\r\n case \"center\":\r\n default: lineX = (p.textRect.width - line.width) / 2; break;\r\n }\r\n\r\n let xCursor = lineX;\r\n const baselineY = blockY + line.y - p.font.size;\r\n\r\n for (const glyph of line.glyphs) {\r\n const path = await p.glyphPathProvider(glyph.id);\r\n if (!path || path === \"M 0 0\") {\r\n xCursor += glyph.xAdvance;\r\n continue;\r\n }\r\n\r\n const glyphX = xCursor + glyph.xOffset;\r\n const glyphY = baselineY + glyph.yOffset;\r\n\r\n // Update global bbox using path's local bounds mapped to world (scale s, flip Y)\r\n const pb = computePathBounds(path);\r\n const x1 = glyphX + scale * pb.x;\r\n const x2 = glyphX + scale * (pb.x + pb.w);\r\n const y1 = glyphY - scale * (pb.y + pb.h);\r\n const y2 = glyphY - scale * pb.y;\r\n if (x1 < gMinX) gMinX = x1;\r\n if (y1 < gMinY) gMinY = y1;\r\n if (x2 > gMaxX) gMaxX = x2;\r\n if (y2 > gMaxY) gMaxY = y2;\r\n\r\n // 1) Shadow (under everything)\r\n if (p.shadow && p.shadow.blur > 0) {\r\n ops.push({\r\n isShadow: true,\r\n op: \"FillPath\",\r\n path,\r\n x: glyphX + p.shadow.offsetX,\r\n y: glyphY + p.shadow.offsetY,\r\n scale,\r\n fill: { kind: \"solid\", color: p.shadow.color, opacity: p.shadow.opacity }\r\n });\r\n }\r\n\r\n // 2) Stroke (under fill)\r\n if (p.stroke && p.stroke.width > 0) {\r\n ops.push({\r\n op: \"StrokePath\",\r\n path,\r\n x: glyphX,\r\n y: glyphY,\r\n scale,\r\n width: p.stroke.width,\r\n color: p.stroke.color,\r\n opacity: p.stroke.opacity\r\n });\r\n }\r\n\r\n // 3) Fill (on top)\r\n ops.push({\r\n op: \"FillPath\",\r\n path,\r\n x: glyphX,\r\n y: glyphY,\r\n scale,\r\n fill\r\n });\r\n\r\n xCursor += glyph.xAdvance;\r\n }\r\n\r\n // Decoration lines (use text/deco color)\r\n if (p.style.textDecoration !== \"none\") {\r\n const deco = decorationGeometry(p.style.textDecoration, {\r\n baselineY,\r\n fontSize: p.font.size,\r\n lineWidth: line.width,\r\n xStart: lineX\r\n });\r\n\r\n ops.push({\r\n op: \"DecorationLine\",\r\n from: { x: deco.x1, y: deco.y },\r\n to: { x: deco.x2, y: deco.y },\r\n width: deco.width,\r\n color: decoColor,\r\n opacity: p.font.opacity\r\n });\r\n }\r\n }\r\n\r\n // Attach a full-text gradient bbox to all glyph fills (stable across typewriter)\r\n if (gMinX !== Infinity) {\r\n const gbox = { x: gMinX, y: gMinY, w: Math.max(1, gMaxX - gMinX), h: Math.max(1, gMaxY - gMinY) };\r\n for (const op of ops) {\r\n if (op.op === \"FillPath\" && !(op).isShadow) {\r\n (op).gradientBBox = gbox;\r\n }\r\n }\r\n }\r\n\r\n return ops;\r\n}\r\n\r\n/* ----------------- local helpers ----------------- */\r\nfunction tokenizePath(d: string): string[] {\r\n return d.match(/[MLCQZ]|-?\\d*\\.?\\d+(?:e[-+]?\\d+)?/gi) ?? [];\r\n}\r\nfunction computePathBounds(d: string) {\r\n const t = tokenizePath(d);\r\n let i = 0;\r\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\r\n const touch = (x: number, y: number) => { if (x < minX) minX = x; if (y < minY) minY = y; if (x > maxX) maxX = x; if (y > maxY) maxY = y; };\r\n while (i < t.length) {\r\n const cmd = t[i++];\r\n switch (cmd) {\r\n case \"M\":\r\n case \"L\": { const x = parseFloat(t[i++]); const y = parseFloat(t[i++]); touch(x, y); break; }\r\n case \"C\": {\r\n const c1x = parseFloat(t[i++]); const c1y = parseFloat(t[i++]);\r\n const c2x = parseFloat(t[i++]); const c2y = parseFloat(t[i++]);\r\n const x = parseFloat(t[i++]); const y = parseFloat(t[i++]);\r\n touch(c1x, c1y); touch(c2x, c2y); touch(x, y); break;\r\n }\r\n case \"Q\": { const cx = parseFloat(t[i++]); const cy = parseFloat(t[i++]); const x = parseFloat(t[i++]); const y = parseFloat(t[i++]); touch(cx, cy); touch(x, y); break; }\r\n case \"Z\": break;\r\n }\r\n }\r\n if (minX === Infinity) return { x: 0, y: 0, w: 0, h: 0 };\r\n return { x: minX, y: minY, w: maxX - minX, h: maxY - minY };\r\n}","import { DrawOp, Glyph, ShapedLine } from \"../types\";\r\n\r\nexport type AnimationInput = {\r\n preset?: \"typewriter\" | \"fadeIn\" | \"slideIn\" | \"shift\" | \"ascend\" | \"movingLetters\";\r\n speed: number;\r\n duration?: number;\r\n style?: \"character\" | \"word\";\r\n direction?: \"left\" | \"right\" | \"up\" | \"down\";\r\n};\r\n\r\nconst DECORATION_DONE_THRESHOLD = 0.999;\r\n\r\nexport function applyAnimation(\r\n ops: DrawOp[],\r\n lines: ShapedLine[],\r\n p: { t: number; fontSize: number; anim?: AnimationInput }\r\n): DrawOp[] {\r\n if (!p.anim || !p.anim.preset) return ops;\r\n\r\n const { preset } = p.anim;\r\n const totalGlyphs = lines.reduce((s, l) => s + l.glyphs.length, 0);\r\n const duration = p.anim.duration ?? Math.max(0.3, totalGlyphs / 30 / p.anim.speed);\r\n const progress = Math.max(0, Math.min(1, p.t / duration));\r\n\r\n switch (preset) {\r\n case \"typewriter\":\r\n return applyTypewriterAnimation(\r\n ops,\r\n lines,\r\n progress,\r\n p.anim.style,\r\n p.fontSize,\r\n p.t,\r\n duration\r\n );\r\n case \"fadeIn\":\r\n return applyFadeInAnimation(ops, progress);\r\n case \"slideIn\":\r\n return applySlideInAnimation(ops, progress, p.anim.direction ?? \"left\", p.fontSize);\r\n case \"shift\":\r\n return applyShiftAnimation(\r\n ops,\r\n lines,\r\n progress,\r\n p.anim.direction ?? \"left\",\r\n p.fontSize,\r\n p.anim.style,\r\n duration\r\n );\r\n case \"ascend\":\r\n return applyAscendAnimation(\r\n ops,\r\n lines,\r\n progress,\r\n p.anim.direction ?? \"up\",\r\n p.fontSize,\r\n duration\r\n );\r\n case \"movingLetters\":\r\n return applyMovingLettersAnimation(ops, progress, p.anim.direction ?? \"up\", p.fontSize);\r\n default:\r\n return ops;\r\n }\r\n}\r\n\r\n// ---- helpers\r\nconst isShadowFill = (op: DrawOp) => op.op === \"FillPath\" && (op).isShadow === true;\r\nconst isGlyphFill = (op: DrawOp) => op.op === \"FillPath\" && !(op).isShadow === true;\r\n\r\n// Try to derive a text color from the first fill we find\r\nfunction getTextColorFromOps(ops: DrawOp[]): string {\r\n for (const op of ops) {\r\n if (op.op === \"FillPath\") {\r\n const fill: any = (op).fill;\r\n if (fill?.kind === \"solid\") return fill.color;\r\n if (\r\n (fill?.kind === \"linear\" || fill?.kind === \"radial\") &&\r\n Array.isArray(fill.stops) &&\r\n fill.stops.length\r\n ) {\r\n return fill.stops[fill.stops.length - 1].color || \"#000000\";\r\n }\r\n }\r\n }\r\n return \"#000000\";\r\n}\r\n\r\n// ---------- TYPEWRITER ----------\r\nfunction applyTypewriterAnimation(\r\n ops: DrawOp[],\r\n lines: ShapedLine[],\r\n progress: number,\r\n style: \"character\" | \"word\" | undefined,\r\n fontSize: number,\r\n time: number,\r\n duration: number\r\n): DrawOp[] {\r\n const byWord = style === \"word\";\r\n\r\n if (byWord) {\r\n const wordSegments = getWordSegments(lines);\r\n const totalWords = wordSegments.length;\r\n const visibleWords = Math.floor(progress * totalWords);\r\n if (visibleWords === 0) return ops.filter((x) => x.op === \"BeginFrame\");\r\n\r\n let totalVisibleGlyphs = 0;\r\n for (let i = 0; i < Math.min(visibleWords, wordSegments.length); i++) {\r\n totalVisibleGlyphs += wordSegments[i].glyphCount;\r\n }\r\n const visibleOpsRaw = sliceGlyphOps(ops, totalVisibleGlyphs);\r\n\r\n const visibleOps =\r\n progress >= DECORATION_DONE_THRESHOLD\r\n ? visibleOpsRaw\r\n : visibleOpsRaw.filter((o) => o.op !== \"DecorationLine\");\r\n\r\n if (progress < 1 && totalVisibleGlyphs > 0) {\r\n return addTypewriterCursor(visibleOps, totalVisibleGlyphs, fontSize, time);\r\n }\r\n return visibleOps;\r\n } else {\r\n const totalGlyphs = lines.reduce((s, l) => s + l.glyphs.length, 0);\r\n const visibleGlyphs = Math.floor(progress * totalGlyphs);\r\n if (visibleGlyphs === 0) return ops.filter((x) => x.op === \"BeginFrame\");\r\n\r\n const visibleOpsRaw = sliceGlyphOps(ops, visibleGlyphs);\r\n\r\n const visibleOps =\r\n progress >= DECORATION_DONE_THRESHOLD\r\n ? visibleOpsRaw\r\n : visibleOpsRaw.filter((o) => o.op !== \"DecorationLine\");\r\n\r\n if (progress < 1 && visibleGlyphs > 0) {\r\n return addTypewriterCursor(visibleOps, visibleGlyphs, fontSize, time);\r\n }\r\n return visibleOps;\r\n }\r\n}\r\n\r\n// ---------- ASCEND ----------\r\nfunction applyAscendAnimation(\r\n ops: DrawOp[],\r\n lines: ShapedLine[],\r\n progress: number,\r\n direction: \"left\" | \"right\" | \"up\" | \"down\",\r\n fontSize: number,\r\n duration: number\r\n): DrawOp[] {\r\n const wordSegments = getWordSegments(lines);\r\n const totalWords = wordSegments.length;\r\n if (totalWords === 0) return ops;\r\n\r\n const result: DrawOp[] = [];\r\n let glyphIndex = 0;\r\n\r\n for (const op of ops) {\r\n if (op.op === \"BeginFrame\") {\r\n result.push(op);\r\n break;\r\n }\r\n }\r\n\r\n for (const op of ops) {\r\n if (op.op === \"FillPath\" || op.op === \"StrokePath\") {\r\n // which word owns this glyph\r\n let wordIndex = -1,\r\n acc = 0;\r\n for (let i = 0; i < wordSegments.length; i++) {\r\n const gcount = wordSegments[i].glyphCount;\r\n if (glyphIndex >= acc && glyphIndex < acc + gcount) {\r\n wordIndex = i;\r\n break;\r\n }\r\n acc += gcount;\r\n }\r\n if (wordIndex >= 0) {\r\n const startF = (wordIndex / Math.max(1, totalWords)) * (duration / duration);\r\n const endF = Math.min(1, startF + 0.3);\r\n if (progress >= endF) {\r\n result.push(op);\r\n } else if (progress > startF) {\r\n const local = (progress - startF) / Math.max(1e-6, endF - startF);\r\n const ease = easeOutCubic(Math.min(1, local));\r\n const startOffset = direction === \"up\" ? fontSize * 0.4 : -fontSize * 0.4;\r\n const animated: any = { ...op, y: op.y + startOffset * (1 - ease) };\r\n if (op.op === \"FillPath\") {\r\n if (animated.fill.kind === \"solid\")\r\n animated.fill = { ...animated.fill, opacity: animated.fill.opacity * ease };\r\n else animated.fill = { ...animated.fill, opacity: (animated.fill.opacity ?? 1) * ease };\r\n } else {\r\n animated.opacity = animated.opacity * ease;\r\n }\r\n result.push(animated);\r\n }\r\n }\r\n if (isGlyphFill(op)) glyphIndex++;\r\n } else if (op.op === \"DecorationLine\") {\r\n if (progress >= DECORATION_DONE_THRESHOLD) {\r\n result.push(op);\r\n }\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n// ---------- SHIFT ----------\r\nfunction applyShiftAnimation(\r\n ops: DrawOp[],\r\n lines: ShapedLine[],\r\n progress: number,\r\n direction: \"left\" | \"right\" | \"up\" | \"down\",\r\n fontSize: number,\r\n style: \"character\" | \"word\" | undefined,\r\n duration: number\r\n): DrawOp[] {\r\n const byWord = style === \"word\";\r\n const startOffsets = {\r\n left: { x: fontSize * 0.6, y: 0 },\r\n right: { x: -fontSize * 0.6, y: 0 },\r\n up: { x: 0, y: fontSize * 0.6 },\r\n down: { x: 0, y: -fontSize * 0.6 },\r\n };\r\n const offset = startOffsets[direction];\r\n\r\n const wordSegments = byWord ? getWordSegments(lines) : [];\r\n const totalGlyphs = lines.reduce((s, l) => s + l.glyphs.length, 0);\r\n const totalUnits = byWord ? wordSegments.length : totalGlyphs;\r\n if (totalUnits === 0) return ops;\r\n\r\n const result: DrawOp[] = [];\r\n for (const op of ops) {\r\n if (op.op === \"BeginFrame\") {\r\n result.push(op);\r\n break;\r\n }\r\n }\r\n\r\n const windowDuration = 0.3; // each unit animates for 0.3s of total duration\r\n const overlapFactor = 0.7; // overlapping reveal\r\n const staggerDelay = (duration * overlapFactor) / Math.max(1, totalUnits - 1);\r\n\r\n const windowFor = (unitIdx: number) => {\r\n const startTime = unitIdx * staggerDelay;\r\n const startF = startTime / duration;\r\n const endF = Math.min(1, (startTime + windowDuration) / duration);\r\n return { startF, endF };\r\n };\r\n\r\n let glyphIndex = 0;\r\n for (const op of ops) {\r\n if (op.op !== \"FillPath\" && op.op !== \"StrokePath\") {\r\n if (op.op === \"DecorationLine\" && progress > 0.8) result.push(op);\r\n continue;\r\n }\r\n\r\n let unitIndex: number;\r\n if (!byWord) {\r\n unitIndex = glyphIndex;\r\n } else {\r\n let wordIndex = -1,\r\n acc = 0;\r\n for (let i = 0; i < wordSegments.length; i++) {\r\n const gcount = wordSegments[i].glyphCount;\r\n if (glyphIndex >= acc && glyphIndex < acc + gcount) {\r\n wordIndex = i;\r\n break;\r\n }\r\n acc += gcount;\r\n }\r\n unitIndex = Math.max(0, wordIndex);\r\n }\r\n\r\n const { startF, endF } = windowFor(unitIndex);\r\n\r\n if (progress <= startF) {\r\n const animated: any = { ...op, x: op.x + offset.x, y: op.y + offset.y };\r\n if (op.op === \"FillPath\") {\r\n if (animated.fill.kind === \"solid\") animated.fill = { ...animated.fill, opacity: 0 };\r\n else animated.fill = { ...animated.fill, opacity: 0 };\r\n } else {\r\n animated.opacity = 0;\r\n }\r\n result.push(animated);\r\n } else if (progress >= endF) {\r\n result.push(op);\r\n } else {\r\n const local = (progress - startF) / Math.max(1e-6, endF - startF);\r\n const ease = easeOutCubic(Math.min(1, local));\r\n const dx = offset.x * (1 - ease);\r\n const dy = offset.y * (1 - ease);\r\n const animated: any = { ...op, x: op.x + dx, y: op.y + dy };\r\n\r\n if (op.op === \"FillPath\") {\r\n const targetOpacity =\r\n animated.fill.kind === \"solid\" ? animated.fill.opacity : animated.fill.opacity ?? 1;\r\n if (animated.fill.kind === \"solid\")\r\n animated.fill = { ...animated.fill, opacity: targetOpacity * ease };\r\n else animated.fill = { ...animated.fill, opacity: targetOpacity * ease };\r\n } else {\r\n animated.opacity = animated.opacity * ease;\r\n }\r\n result.push(animated);\r\n }\r\n\r\n if (isGlyphFill(op)) glyphIndex++;\r\n }\r\n return result;\r\n}\r\n\r\n// ---------- FADE / SLIDE / WAVE ----------\r\nfunction applyFadeInAnimation(ops: DrawOp[], progress: number): DrawOp[] {\r\n const alpha = easeOutQuad(progress);\r\n const scale = 0.95 + 0.05 * alpha;\r\n return scaleAndFade(ops, alpha, scale);\r\n}\r\nfunction applySlideInAnimation(\r\n ops: DrawOp[],\r\n progress: number,\r\n direction: \"left\" | \"right\" | \"up\" | \"down\",\r\n fontSize: number\r\n): DrawOp[] {\r\n const easeProgress = easeOutCubic(progress);\r\n const shift = shiftFor(1 - easeProgress, direction, fontSize * 2);\r\n const alpha = easeOutQuad(progress);\r\n return translateGlyphOps(ops, shift.dx, shift.dy, alpha);\r\n}\r\nfunction applyMovingLettersAnimation(\r\n ops: DrawOp[],\r\n progress: number,\r\n direction: \"left\" | \"right\" | \"up\" | \"down\",\r\n fontSize: number\r\n): DrawOp[] {\r\n const amp = fontSize * 0.3;\r\n return waveTransform(ops, direction, amp, progress);\r\n}\r\n\r\n// ---------- word segmentation / slicing ----------\r\nfunction getWordSegments(lines: ShapedLine[]) {\r\n const segments: any = [];\r\n let totalGlyphIndex = 0;\r\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\r\n const line = lines[lineIndex];\r\n const words = segmentLineBySpaces(line);\r\n for (const word of words) {\r\n if (word.length > 0)\r\n segments.push({ startGlyph: totalGlyphIndex, glyphCount: word.length, lineIndex });\r\n totalGlyphIndex += word.length;\r\n }\r\n }\r\n return segments;\r\n}\r\nfunction segmentLineBySpaces(line: ShapedLine): Glyph[][] {\r\n const words: Glyph[][] = [];\r\n let current: Glyph[] = [];\r\n for (const g of line.glyphs) {\r\n const isSpace = g.char === \" \" || g.char === \"\\t\" || g.char === \"\\n\";\r\n if (isSpace) {\r\n if (current.length) {\r\n words.push([...current]);\r\n current = [];\r\n }\r\n } else {\r\n current.push(g);\r\n }\r\n }\r\n if (current.length) words.push(current);\r\n return words;\r\n}\r\n\r\n/** Include BOTH stroke+fill for the first `maxGlyphs` glyphs; nothing from later glyphs.\r\n * Stroke is only included if its corresponding fill will be shown (so it never appears early). */\r\nfunction sliceGlyphOps(ops: DrawOp[], maxGlyphs: number): DrawOp[] {\r\n const result: DrawOp[] = [];\r\n let glyphCount = 0;\r\n let foundGlyphs = false;\r\n\r\n for (const op of ops) {\r\n if (op.op === \"BeginFrame\") {\r\n result.push(op);\r\n continue;\r\n }\r\n\r\n if (op.op === \"FillPath\" && !isShadowFill(op)) {\r\n if (glyphCount < maxGlyphs) {\r\n result.push(op);\r\n foundGlyphs = true;\r\n }\r\n glyphCount++; // count only real glyph fills\r\n continue;\r\n }\r\n\r\n if (op.op === \"StrokePath\") {\r\n // Include stroke only if the upcoming fill is within range\r\n if (glyphCount < maxGlyphs) result.push(op);\r\n continue;\r\n }\r\n\r\n if (op.op === \"FillPath\" && isShadowFill(op)) {\r\n if (glyphCount < maxGlyphs) result.push(op);\r\n continue;\r\n }\r\n\r\n if (op.op === \"DecorationLine\" && foundGlyphs) {\r\n result.push(op);\r\n continue;\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction addTypewriterCursor(\r\n ops: DrawOp[],\r\n glyphCount: number,\r\n fontSize: number,\r\n time: number\r\n): DrawOp[] {\r\n const blinkRate = 2;\r\n const cursorVisible = Math.floor(time * blinkRate * 2) % 2 === 0;\r\n if (!cursorVisible || glyphCount === 0) return ops;\r\n\r\n let last: DrawOp | null = null;\r\n let count = 0;\r\n for (const op of ops) {\r\n if (op.op === \"FillPath\" && !isShadowFill(op)) {\r\n count++;\r\n if (count === glyphCount) {\r\n last = op;\r\n break;\r\n }\r\n }\r\n }\r\n if (last && last.op === \"FillPath\") {\r\n const color = getTextColorFromOps(ops);\r\n const cursorX = last.x + fontSize * 0.5;\r\n const cursorY = last.y;\r\n\r\n const cursorOp: DrawOp = {\r\n op: \"DecorationLine\",\r\n from: { x: cursorX, y: cursorY - fontSize * 0.7 },\r\n to: { x: cursorX, y: cursorY + fontSize * 0.1 },\r\n width: Math.max(2, fontSize / 25),\r\n color,\r\n opacity: 1,\r\n };\r\n return [...ops, cursorOp];\r\n }\r\n return ops;\r\n}\r\n\r\n// ---------- transforms ----------\r\nfunction scaleAndFade(ops: DrawOp[], alpha: number, scale: number): DrawOp[] {\r\n let cx = 0,\r\n cy = 0,\r\n n = 0;\r\n ops.forEach((op) => {\r\n if (op.op === \"FillPath\") {\r\n cx += op.x;\r\n cy += op.y;\r\n n++;\r\n }\r\n });\r\n if (n > 0) {\r\n cx /= n;\r\n cy /= n;\r\n }\r\n\r\n return ops.map((op) => {\r\n if (op.op === \"FillPath\") {\r\n const out: any = { ...op };\r\n if (out.fill.kind === \"solid\") out.fill = { ...out.fill, opacity: out.fill.opacity * alpha };\r\n else out.fill = { ...out.fill, opacity: (out.fill.opacity ?? 1) * alpha };\r\n if (scale !== 1 && n > 0) {\r\n const dx = op.x - cx,\r\n dy = op.y - cy;\r\n out.x = cx + dx * scale;\r\n out.y = cy + dy * scale;\r\n }\r\n return out;\r\n }\r\n if (op.op === \"StrokePath\") {\r\n const out: any = { ...op, opacity: op.opacity * alpha };\r\n if (scale !== 1 && n > 0) {\r\n const dx = op.x - cx,\r\n dy = op.y - cy;\r\n out.x = cx + dx * scale;\r\n out.y = cy + dy * scale;\r\n }\r\n return out;\r\n }\r\n if (op.op === \"DecorationLine\") return { ...op, opacity: op.opacity * alpha };\r\n return op;\r\n });\r\n}\r\n\r\nfunction translateGlyphOps(ops: DrawOp[], dx: number, dy: number, alpha: number = 1): DrawOp[] {\r\n return ops.map((op) => {\r\n if (op.op === \"FillPath\") {\r\n const out: any = { ...op, x: op.x + dx, y: op.y + dy };\r\n if (alpha < 1) {\r\n if (out.fill.kind === \"solid\")\r\n out.fill = { ...out.fill, opacity: out.fill.opacity * alpha };\r\n else out.fill = { ...out.fill, opacity: (out.fill.opacity ?? 1) * alpha };\r\n }\r\n return out;\r\n }\r\n if (op.op === \"StrokePath\")\r\n return { ...op, x: op.x + dx, y: op.y + dy, opacity: op.opacity * alpha };\r\n if (op.op === \"DecorationLine\") {\r\n return {\r\n ...op,\r\n from: { x: op.from.x + dx, y: op.from.y + dy },\r\n to: { x: op.to.x + dx, y: op.to.y + dy },\r\n opacity: op.opacity * alpha,\r\n };\r\n }\r\n return op;\r\n });\r\n}\r\n\r\nfunction waveTransform(\r\n ops: DrawOp[],\r\n dir: \"left\" | \"right\" | \"up\" | \"down\",\r\n amp: number,\r\n p: number\r\n): DrawOp[] {\r\n let glyphIndex = 0;\r\n return ops.map((op) => {\r\n if (op.op === \"FillPath\" || op.op === \"StrokePath\") {\r\n const phase = Math.sin((glyphIndex / 5) * Math.PI + p * Math.PI * 4);\r\n const dx = dir === \"left\" || dir === \"right\" ? phase * amp * (dir === \"left\" ? -1 : 1) : 0;\r\n const dy = dir === \"up\" || dir === \"down\" ? phase * amp * (dir === \"up\" ? -1 : 1) : 0;\r\n const waveAlpha = Math.min(1, p * 2);\r\n if (op.op === \"FillPath\") {\r\n if (!isShadowFill(op)) glyphIndex++;\r\n const out: any = { ...op, x: op.x + dx, y: op.y + dy };\r\n if (out.fill.kind === \"solid\")\r\n out.fill = { ...out.fill, opacity: out.fill.opacity * waveAlpha };\r\n else out.fill = { ...out.fill, opacity: (out.fill.opacity ?? 1) * waveAlpha };\r\n return out;\r\n }\r\n return { ...op, x: op.x + dx, y: op.y + dy, opacity: op.opacity * waveAlpha };\r\n }\r\n return op;\r\n });\r\n}\r\n\r\n// ---------- misc ----------\r\nfunction shiftFor(progress: number, dir: \"left\" | \"right\" | \"up\" | \"down\", dist: number) {\r\n const d = progress * dist;\r\n switch (dir) {\r\n case \"left\":\r\n return { dx: -d, dy: 0 };\r\n case \"right\":\r\n return { dx: d, dy: 0 };\r\n case \"up\":\r\n return { dx: 0, dy: -d };\r\n case \"down\":\r\n return { dx: 0, dy: d };\r\n }\r\n}\r\nfunction easeOutQuad(t: number) {\r\n return t * (2 - t);\r\n}\r\nfunction easeOutCubic(t: number) {\r\n return 1 - Math.pow(1 - t, 3);\r\n}\r\nfunction easeInOutQuad(t: number) {\r\n return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;\r\n}\r\n","import { RGBA } from \"../types\";\r\n\r\nexport function parseHex6(hex: string, alpha = 1): RGBA {\r\n const m = /^#?([a-f0-9]{6})$/i.exec(hex);\r\n if (!m) throw new Error(`Invalid color ${hex}`);\r\n const n = parseInt(m[1], 16);\r\n const r = (n >> 16) & 0xff;\r\n const g = (n >> 8) & 0xff;\r\n const b = n & 0xff;\r\n return { r, g, b, a: alpha };\r\n}\r\n","import type { DrawOp, GradientSpec } from \"../types\";\r\nimport { parseHex6 } from \"../core/colors\";\r\n\r\ninterface BoundingBox {\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n}\r\n\r\ninterface FillPathOp extends Extract<DrawOp, { op: \"FillPath\" }> {\r\n scale?: number;\r\n gradientBBox?: BoundingBox;\r\n isShadow?: boolean;\r\n}\r\n\r\ninterface StrokePathOp extends Extract<DrawOp, { op: \"StrokePath\" }> {\r\n scale?: number;\r\n}\r\n\r\ninterface NodeCanvas {\r\n width: number;\r\n height: number;\r\n getContext(contextId: \"2d\"): NodeCanvasRenderingContext2D;\r\n toBuffer(mimeType: \"image/png\"): Buffer;\r\n}\r\n\r\ninterface NodeCanvasRenderingContext2D {\r\n canvas: NodeCanvas;\r\n fillStyle: string | CanvasGradient | CanvasPattern;\r\n strokeStyle: string | CanvasGradient | CanvasPattern;\r\n lineWidth: number;\r\n lineJoin: CanvasLineJoin;\r\n lineCap: CanvasLineCap;\r\n\r\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void;\r\n clearRect(x: number, y: number, w: number, h: number): void;\r\n fillRect(x: number, y: number, w: number, h: number): void;\r\n save(): void;\r\n restore(): void;\r\n translate(x: number, y: number): void;\r\n scale(x: number, y: number): void;\r\n beginPath(): void;\r\n closePath(): void;\r\n moveTo(x: number, y: number): void;\r\n lineTo(x: number, y: number): void;\r\n arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;\r\n bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;\r\n quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;\r\n fill(): void;\r\n stroke(): void;\r\n createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;\r\n createRadialGradient(\r\n x0: number,\r\n y0: number,\r\n r0: number,\r\n x1: number,\r\n y1: number,\r\n r1: number\r\n ): CanvasGradient;\r\n}\r\n\r\ninterface CanvasModule {\r\n createCanvas(width: number, height: number): NodeCanvas;\r\n}\r\n\r\nexport async function createNodePainter(opts: {\r\n width: number;\r\n height: number;\r\n pixelRatio: number;\r\n}) {\r\n const canvasMod = (await import(\"canvas\")) as CanvasModule;\r\n const { createCanvas } = canvasMod;\r\n\r\n const canvas = createCanvas(\r\n Math.floor(opts.width * opts.pixelRatio),\r\n Math.floor(opts.height * opts.pixelRatio)\r\n );\r\n\r\n const ctx: NodeCanvasRenderingContext2D = canvas.getContext(\"2d\");\r\n if (!ctx) throw new Error(\"2D context unavailable in Node (canvas).\");\r\n\r\n const offscreenCanvas = createCanvas(canvas.width, canvas.height);\r\n const offscreenCtx: NodeCanvasRenderingContext2D = offscreenCanvas.getContext(\"2d\");\r\n\r\n const api = {\r\n async render(ops: DrawOp[]): Promise<void> {\r\n const globalBox = computeGlobalTextBounds(ops);\r\n let needsAlphaExtraction = false;\r\n\r\n for (const op of ops) {\r\n if (op.op === \"BeginFrame\") {\r\n const dpr = op.pixelRatio ?? opts.pixelRatio;\r\n const wantW = Math.floor(op.width * dpr);\r\n const wantH = Math.floor(op.height * dpr);\r\n\r\n if (canvas.width !== wantW || canvas.height !== wantH) {\r\n canvas.width = wantW;\r\n canvas.height = wantH;\r\n offscreenCanvas.width = wantW;\r\n offscreenCanvas.height = wantH;\r\n }\r\n\r\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\r\n offscreenCtx.setTransform(dpr, 0, 0, dpr, 0, 0);\r\n\r\n const hasBackground = !!(op.bg && op.bg.color);\r\n needsAlphaExtraction = !hasBackground;\r\n\r\n if (op.bg && op.bg.color) {\r\n const { color, opacity, radius } = op.bg;\r\n const c = parseHex6(color, opacity);\r\n ctx.fillStyle = `rgba(${c.r},${c.g},${c.b},${c.a})`;\r\n\r\n if (radius && radius > 0) {\r\n ctx.save();\r\n ctx.beginPath();\r\n roundRectPath(ctx, 0, 0, op.width, op.height, radius);\r\n ctx.fill();\r\n ctx.restore();\r\n } else {\r\n ctx.fillRect(0, 0, op.width, op.height);\r\n }\r\n } else {\r\n ctx.fillStyle = \"rgb(255, 255, 255)\";\r\n ctx.fillRect(0, 0, op.width, op.height);\r\n\r\n offscreenCtx.fillStyle = \"rgb(0, 0, 0)\";\r\n offscreenCtx.fillRect(0, 0, op.width, op.height);\r\n }\r\n continue;\r\n }\r\n\r\n const renderToBoth = (renderFn: (context: NodeCanvasRenderingContext2D) => void) => {\r\n if (needsAlphaExtraction) {\r\n renderFn(ctx);\r\n renderFn(offscreenCtx);\r\n } else {\r\n renderFn(ctx);\r\n }\r\n };\r\n\r\n if (op.op === \"FillPath\") {\r\n const fillOp = op as FillPathOp;\r\n\r\n renderToBoth((context) => {\r\n context.save();\r\n context.translate(fillOp.x, fillOp.y);\r\n const s = fillOp.scale ?? 1;\r\n context.scale(s, -s);\r\n\r\n context.beginPath();\r\n drawSvgPathOnCtx(context, fillOp.path);\r\n\r\n const bbox = fillOp.gradientBBox ?? globalBox;\r\n const fill = makeGradientFromBBox(context, fillOp.fill, bbox);\r\n context.fillStyle = fill;\r\n context.fill();\r\n\r\n context.restore();\r\n });\r\n continue;\r\n }\r\n\r\n if (op.op === \"StrokePath\") {\r\n const strokeOp = op as StrokePathOp;\r\n\r\n renderToBoth((context) => {\r\n context.save();\r\n context.translate(strokeOp.x, strokeOp.y);\r\n const s = strokeOp.scale ?? 1;\r\n context.scale(s, -s);\r\n const invAbs = 1 / Math.abs(s);\r\n\r\n context.beginPath();\r\n drawSvgPathOnCtx(context, strokeOp.path);\r\n\r\n const c = parseHex6(strokeOp.color, strokeOp.opacity);\r\n context.strokeStyle = `rgba(${c.r},${c.g},${c.b},${c.a})`;\r\n context.lineWidth = strokeOp.width * invAbs;\r\n context.lineJoin = \"round\";\r\n context.lineCap = \"round\";\r\n context.stroke();\r\n\r\n context.restore();\r\n });\r\n continue;\r\n }\r\n\r\n if (op.op === \"DecorationLine\") {\r\n renderToBoth((context) => {\r\n context.save();\r\n const c = parseHex6(op.color, op.opacity);\r\n context.strokeStyle = `rgba(${c.r},${c.g},${c.b},${c.a})`;\r\n context.lineWidth = op.width;\r\n context.beginPath();\r\n context.moveTo(op.from.x, op.from.y);\r\n context.lineTo(op.to.x, op.to.y);\r\n context.stroke();\r\n context.restore();\r\n });\r\n continue;\r\n }\r\n }\r\n\r\n if (needsAlphaExtraction) {\r\n const whiteData = (ctx as any).getImageData(0, 0, canvas.width, canvas.height);\r\n const blackData = (offscreenCtx as any).getImageData(0, 0, canvas.width, canvas.height);\r\n\r\n const white = whiteData.data;\r\n const black = blackData.data;\r\n\r\n for (let i = 0; i < white.length; i += 4) {\r\n const wr = white[i];\r\n const wg = white[i + 1];\r\n const wb = white[i + 2];\r\n\r\n const br = black[i];\r\n const bg = black[i + 1];\r\n const bb = black[i + 2];\r\n\r\n const alpha = 255 - Math.max(wr - br, wg - bg, wb - bb);\r\n\r\n if (alpha <= 2) {\r\n white[i] = 0;\r\n white[i + 1] = 0;\r\n white[i + 2] = 0;\r\n white[i + 3] = 0;\r\n } else if (alpha >= 253) {\r\n white[i] = br;\r\n white[i + 1] = bg;\r\n white[i + 2] = bb;\r\n white[i + 3] = 255;\r\n } else {\r\n const alphaFactor = 255 / alpha;\r\n\r\n white[i] = Math.min(255, Math.max(0, Math.round(br * alphaFactor)));\r\n white[i + 1] = Math.min(255, Math.max(0, Math.round(bg * alphaFactor)));\r\n white[i + 2] = Math.min(255, Math.max(0, Math.round(bb * alphaFactor)));\r\n white[i + 3] = alpha;\r\n }\r\n }\r\n\r\n (ctx as any).putImageData(whiteData, 0, 0);\r\n }\r\n },\r\n\r\n async toPNG(): Promise<Buffer> {\r\n return canvas.toBuffer(\"image/png\");\r\n },\r\n };\r\n\r\n return api;\r\n}\r\n\r\nfunction makeGradientFromBBox(\r\n ctx: NodeCanvasRenderingContext2D,\r\n spec: GradientSpec,\r\n box: BoundingBox\r\n): CanvasGradient | string {\r\n if (spec.kind === \"solid\") {\r\n const c = parseHex6(spec.color, spec.opacity);\r\n return `rgba(${c.r},${c.g},${c.b},${c.a})`;\r\n }\r\n\r\n const cx = box.x + box.w / 2;\r\n const cy = box.y + box.h / 2;\r\n const r = Math.max(box.w, box.h) / 2;\r\n\r\n const addStops = (g: CanvasGradient): CanvasGradient => {\r\n const opacity = spec.kind === \"linear\" || spec.kind === \"radial\" ? spec.opacity : 1;\r\n const stops = spec.kind === \"linear\" || spec.kind === \"radial\" ? spec.stops : [];\r\n\r\n for (const s of stops) {\r\n const c = parseHex6(s.color, opacity);\r\n g.addColorStop(s.offset, `rgba(${c.r},${c.g},${c.b},${c.a})`);\r\n }\r\n return g;\r\n };\r\n\r\n if (spec.kind === \"linear\") {\r\n const rad = (spec.angle * Math.PI) / 180;\r\n const x1 = cx + Math.cos(rad + Math.PI) * r;\r\n const y1 = cy + Math.sin(rad + Math.PI) * r;\r\n const x2 = cx + Math.cos(rad) * r;\r\n const y2 = cy + Math.sin(rad) * r;\r\n return addStops(ctx.createLinearGradient(x1, y1, x2, y2));\r\n } else {\r\n return addStops(ctx.createRadialGradient(cx, cy, 0, cx, cy, r));\r\n }\r\n}\r\n\r\nfunction computeGlobalTextBounds(ops: DrawOp[]): BoundingBox {\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n\r\n for (const op of ops) {\r\n if (op.op !== \"FillPath\") continue;\r\n\r\n const fillOp = op as FillPathOp;\r\n if (fillOp.isShadow) continue;\r\n\r\n const b = computePathBounds(fillOp.path);\r\n const s = fillOp.scale ?? 1;\r\n const x1 = fillOp.x + s * b.x;\r\n const x2 = fillOp.x + s * (b.x + b.w);\r\n const y1 = fillOp.y - s * (b.y + b.h);\r\n const y2 = fillOp.y - s * b.y;\r\n\r\n if (x1 < minX) minX = x1;\r\n if (y1 < minY) minY = y1;\r\n if (x2 > maxX) maxX = x2;\r\n if (y2 > maxY) maxY = y2;\r\n }\r\n\r\n if (minX === Infinity) {\r\n return { x: 0, y: 0, w: 1, h: 1 };\r\n }\r\n\r\n return {\r\n x: minX,\r\n y: minY,\r\n w: Math.max(1, maxX - minX),\r\n h: Math.max(1, maxY - minY),\r\n };\r\n}\r\n\r\nfunction drawSvgPathOnCtx(ctx: NodeCanvasRenderingContext2D, d: string): void {\r\n const t = tokenizePath(d);\r\n let i = 0;\r\n while (i < t.length) {\r\n const cmd = t[i++];\r\n switch (cmd) {\r\n case \"M\": {\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n ctx.moveTo(x, y);\r\n break;\r\n }\r\n case \"L\": {\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n ctx.lineTo(x, y);\r\n break;\r\n }\r\n case \"C\": {\r\n const c1x = parseFloat(t[i++]);\r\n const c1y = parseFloat(t[i++]);\r\n const c2x = parseFloat(t[i++]);\r\n const c2y = parseFloat(t[i++]);\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n ctx.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);\r\n break;\r\n }\r\n case \"Q\": {\r\n const cx = parseFloat(t[i++]);\r\n const cy = parseFloat(t[i++]);\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n ctx.quadraticCurveTo(cx, cy, x, y);\r\n break;\r\n }\r\n case \"Z\": {\r\n ctx.closePath();\r\n break;\r\n }\r\n default:\r\n break;\r\n }\r\n }\r\n}\r\n\r\nfunction computePathBounds(d: string): BoundingBox {\r\n const t = tokenizePath(d);\r\n let i = 0;\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n\r\n const touch = (x: number, y: number): void => {\r\n if (x < minX) minX = x;\r\n if (y < minY) minY = y;\r\n if (x > maxX) maxX = x;\r\n if (y > maxY) maxY = y;\r\n };\r\n\r\n while (i < t.length) {\r\n const cmd = t[i++];\r\n switch (cmd) {\r\n case \"M\":\r\n case \"L\": {\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n touch(x, y);\r\n break;\r\n }\r\n case \"C\": {\r\n const c1x = parseFloat(t[i++]);\r\n const c1y = parseFloat(t[i++]);\r\n const c2x = parseFloat(t[i++]);\r\n const c2y = parseFloat(t[i++]);\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n touch(c1x, c1y);\r\n touch(c2x, c2y);\r\n touch(x, y);\r\n break;\r\n }\r\n case \"Q\": {\r\n const cx = parseFloat(t[i++]);\r\n const cy = parseFloat(t[i++]);\r\n const x = parseFloat(t[i++]);\r\n const y = parseFloat(t[i++]);\r\n touch(cx, cy);\r\n touch(x, y);\r\n break;\r\n }\r\n case \"Z\":\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n if (minX === Infinity) {\r\n return { x: 0, y: 0, w: 0, h: 0 };\r\n }\r\n\r\n return {\r\n x: minX,\r\n y: minY,\r\n w: maxX - minX,\r\n h: maxY - minY,\r\n };\r\n}\r\n\r\nfunction roundRectPath(\r\n ctx: NodeCanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n w: number,\r\n h: number,\r\n r: number\r\n): void {\r\n ctx.moveTo(x + r, y);\r\n ctx.arcTo(x + w, y, x + w, y + h, r);\r\n ctx.arcTo(x + w, y + h, x, y + h, r);\r\n ctx.arcTo(x, y + h, x, y, r);\r\n ctx.arcTo(x, y, x + w, y, r);\r\n ctx.closePath();\r\n}\r\n\r\nfunction tokenizePath(d: string): string[] {\r\n return d.match(/[MLCQZ]|-?\\d*\\.?\\d+(?:e[-+]?\\d+)?/gi) ?? [];\r\n}\r\n","import { readFile } from \"node:fs/promises\";\r\nimport * as http from \"node:http\";\r\nimport * as https from \"node:https\";\r\n\r\nfunction bufferToArrayBuffer(buf: Buffer): ArrayBuffer {\r\n const { buffer, byteOffset, byteLength } = buf as unknown as {\r\n buffer: ArrayBuffer | SharedArrayBuffer;\r\n byteOffset: number;\r\n byteLength: number;\r\n };\r\n\r\n if (typeof SharedArrayBuffer !== \"undefined\" && buffer instanceof SharedArrayBuffer) {\r\n const ab = new ArrayBuffer(byteLength);\r\n new Uint8Array(ab).set(buf);\r\n return ab;\r\n }\r\n\r\n const ab = buffer as ArrayBuffer;\r\n\r\n return ab.slice(byteOffset, byteOffset + byteLength);\r\n}\r\n\r\nexport async function loadFileOrHttpToArrayBuffer(pathOrUrl: string): Promise<ArrayBuffer> {\r\n try {\r\n if (/^https?:\\/\\//.test(pathOrUrl)) {\r\n const client = pathOrUrl.startsWith(\"https:\") ? https : http;\r\n\r\n const buf: Buffer = await new Promise<Buffer>((resolve, reject) => {\r\n const request = client.get(pathOrUrl, (res) => {\r\n const { statusCode } = res;\r\n\r\n if (statusCode && (statusCode < 200 || statusCode >= 300)) {\r\n reject(new Error(`HTTP request failed with status ${statusCode} for ${pathOrUrl}`));\r\n res.resume();\r\n return;\r\n }\r\n\r\n const chunks: Buffer[] = [];\r\n\r\n res.on(\"data\", (chunk: Buffer) => {\r\n chunks.push(chunk);\r\n });\r\n\r\n res.on(\"end\", () => {\r\n try {\r\n resolve(Buffer.concat(chunks));\r\n } catch (err) {\r\n reject(\r\n new Error(\r\n `Failed to concatenate response chunks: ${\r\n err instanceof Error ? err.message : String(err)\r\n }`\r\n )\r\n );\r\n }\r\n });\r\n\r\n res.on(\"error\", (err) => {\r\n reject(new Error(`Response error for ${pathOrUrl}: ${err.message}`));\r\n });\r\n });\r\n\r\n request.on(\"error\", (err) => {\r\n reject(new Error(`Request error for ${pathOrUrl}: ${err.message}`));\r\n });\r\n\r\n request.setTimeout(30000, () => {\r\n request.destroy();\r\n reject(new Error(`Request timeout after 30s for ${pathOrUrl}`));\r\n });\r\n });\r\n\r\n return bufferToArrayBuffer(buf);\r\n }\r\n\r\n const buf = await readFile(pathOrUrl);\r\n return bufferToArrayBuffer(buf);\r\n } catch (err) {\r\n if (err instanceof Error) {\r\n throw new Error(`Failed to load ${pathOrUrl}: ${err.message}`);\r\n }\r\n throw new Error(`Failed to load ${pathOrUrl}: ${String(err)}`);\r\n }\r\n}\r\n","import type { DrawOp } from \"../types\";\r\nimport { createNodePainter } from \"../painters/node\";\r\nimport { spawn } from \"child_process\";\r\nimport fs from \"node:fs\";\r\n\r\nexport interface VideoGenerationOptions {\r\n width: number;\r\n height: number;\r\n fps: number;\r\n duration: number;\r\n outputPath: string;\r\n pixelRatio?: number;\r\n\r\n crf?: number;\r\n preset?:\r\n | \"ultrafast\"\r\n | \"superfast\"\r\n | \"veryfast\"\r\n | \"faster\"\r\n | \"fast\"\r\n | \"medium\"\r\n | \"slow\"\r\n | \"slower\"\r\n | \"veryslow\";\r\n tune?:\r\n | \"film\"\r\n | \"animation\"\r\n | \"grain\"\r\n | \"stillimage\"\r\n | \"psnr\"\r\n | \"ssim\"\r\n | \"fastdecode\"\r\n | \"zerolatency\";\r\n profile?: \"baseline\" | \"main\" | \"high\";\r\n level?: string;\r\n pixFmt?: string;\r\n ffmpegPath?: string;\r\n}\r\n\r\nexport class VideoGenerator {\r\n private ffmpegPath: string | null = null;\r\n\r\n private trySetPath(p?: string | null) {\r\n if (p && fs.existsSync(p)) {\r\n this.ffmpegPath = p;\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n async init(opts?: { ffmpegPath?: string }) {\r\n if (typeof window !== \"undefined\") {\r\n throw new Error(\"VideoGenerator is only available in Node.js environment\");\r\n }\r\n\r\n if (this.trySetPath(opts?.ffmpegPath)) return;\r\n\r\n if (this.trySetPath(process.env.FFMPEG_PATH)) return;\r\n if (this.trySetPath(process.env.FFMPEG_BIN)) return;\r\n\r\n if (this.trySetPath(\"/opt/bin/ffmpeg\")) return;\r\n\r\n try {\r\n const ffmpegStatic = await import(\"ffmpeg-static\");\r\n const p = (ffmpegStatic).default as string | undefined;\r\n if (this.trySetPath(p)) return;\r\n } catch {\r\n /* no-op, fall through */\r\n }\r\n\r\n throw new Error(\"FFmpeg not available. Please install ffmpeg-static or provide FFMPEG_PATH.\");\r\n }\r\n\r\n async generateVideo(\r\n frameGenerator: (time: number) => Promise<DrawOp[]>,\r\n options: VideoGenerationOptions\r\n ): Promise<void> {\r\n if (!this.ffmpegPath) await this.init({ ffmpegPath: options.ffmpegPath });\r\n\r\n const {\r\n width,\r\n height,\r\n fps,\r\n duration,\r\n outputPath,\r\n pixelRatio = 1,\r\n crf = 17,\r\n preset = \"slow\",\r\n tune = \"animation\",\r\n profile = \"high\",\r\n level = \"4.2\",\r\n pixFmt = \"yuv420p\",\r\n } = options;\r\n\r\n const totalFrames = Math.max(2, Math.round(duration * fps) + 1);\r\n\r\n console.log(\r\n `🎬 Generating video: ${width}x${height} @ ${fps}fps, ${duration}s (${totalFrames} frames)\\n` +\r\n ` CRF=${crf}, preset=${preset}, tune=${tune}, profile=${profile}, level=${level}, pix_fmt=${pixFmt}`\r\n );\r\n\r\n return new Promise(async (resolve, reject) => {\r\n const args = [\r\n \"-y\",\r\n \"-f\",\r\n \"image2pipe\",\r\n \"-vcodec\",\r\n \"png\",\r\n \"-framerate\",\r\n String(fps),\r\n \"-i\",\r\n \"-\",\r\n \"-c:v\",\r\n \"libx264\",\r\n \"-preset\",\r\n preset,\r\n \"-crf\",\r\n String(crf),\r\n \"-tune\",\r\n tune,\r\n \"-profile:v\",\r\n profile,\r\n \"-level\",\r\n level,\r\n \"-pix_fmt\",\r\n pixFmt,\r\n \"-r\",\r\n String(fps),\r\n \"-movflags\",\r\n \"+faststart\",\r\n outputPath,\r\n ];\r\n\r\n const ffmpeg = spawn(this.ffmpegPath!, args, { stdio: [\"pipe\", \"inherit\", \"pipe\"] });\r\n let ffmpegError = \"\";\r\n\r\n ffmpeg.stderr.on(\"data\", (data) => {\r\n const message = data.toString();\r\n const m = message.match(/time=(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?/);\r\n if (m) {\r\n const hh = parseInt(m[1], 10);\r\n const mm = parseInt(m[2], 10);\r\n const ss = parseInt(m[3], 10);\r\n const ff = m[4] ? parseFloat(`0.${m[4]}`) : 0;\r\n const currentTime = hh * 3600 + mm * 60 + ss + ff;\r\n const pct = Math.min(100, Math.round((currentTime / duration) * 100));\r\n if (pct % 10 === 0) console.log(`📹 Encoding: ${pct}%`);\r\n }\r\n ffmpegError += message;\r\n });\r\n\r\n ffmpeg.on(\"close\", (code) => {\r\n if (code === 0) {\r\n console.log(\"✅ Video generation complete!\");\r\n resolve();\r\n } else {\r\n console.error(\"FFmpeg stderr:\", ffmpegError);\r\n reject(new Error(`FFmpeg exited with code ${code}`));\r\n }\r\n });\r\n\r\n ffmpeg.on(\"error\", (err) => {\r\n console.error(\"❌ FFmpeg spawn error:\", err);\r\n reject(err);\r\n });\r\n\r\n try {\r\n const painter = await createNodePainter({ width, height, pixelRatio });\r\n for (let frame = 0; frame < totalFrames; frame++) {\r\n const t = (frame / (totalFrames - 1)) * duration;\r\n const ops = await frameGenerator(t);\r\n await painter.render(ops);\r\n const png = await painter.toPNG();\r\n\r\n const ok = ffmpeg.stdin.write(png);\r\n if (!ok) await new Promise((r) => ffmpeg.stdin.once(\"drain\", r));\r\n\r\n if (frame % Math.max(1, Math.floor(fps / 2)) === 0) {\r\n const pct = Math.round(((frame + 1) / totalFrames) * 100);\r\n console.log(`🎞️ Rendering frames: ${pct}%`);\r\n }\r\n }\r\n ffmpeg.stdin.end();\r\n } catch (err) {\r\n console.error(\"Frame generation error:\", err);\r\n ffmpeg.kill(\"SIGKILL\");\r\n reject(err);\r\n }\r\n });\r\n }\r\n}\r\n","import type { RichTextValidated } from \"./schema/asset-schema\";\r\n\r\nexport type RGBA = { r: number; g: number; b: number; a: number };\r\n\r\nexport type GradientSpec =\r\n | { kind: \"solid\"; color: string; opacity: number }\r\n | { kind: \"linear\"; angle: number; stops: { offset: number; color: string }[]; opacity: number }\r\n | { kind: \"radial\"; stops: { offset: number; color: string }[]; opacity: number };\r\n\r\nexport type Glyph = {\r\n id: number;\r\n xAdvance: number;\r\n xOffset: number;\r\n yOffset: number;\r\n cluster: number;\r\n char?: string;\r\n};\r\n\r\nexport type ShapedLine = {\r\n glyphs: Glyph[];\r\n width: number;\r\n y: number; // baseline y\r\n};\r\n\r\nexport type DrawOp =\r\n | {\r\n op: \"BeginFrame\";\r\n width: number;\r\n height: number;\r\n pixelRatio: number;\r\n clear: boolean;\r\n bg?: { color?: string; opacity: number; radius: number };\r\n }\r\n | {\r\n op: \"FillPath\";\r\n path: string;\r\n x: number;\r\n y: number;\r\n fill: GradientSpec;\r\n scale?: number;\r\n gradientBBox?: { x: number; y: number; w: number; h: number };\r\n isShadow?: boolean;\r\n }\r\n | {\r\n op: \"StrokePath\";\r\n path: string;\r\n x: number;\r\n y: number;\r\n width: number;\r\n color: string;\r\n opacity: number;\r\n scale?: number;\r\n }\r\n | {\r\n op: \"DecorationLine\";\r\n from: { x: number; y: number };\r\n to: { x: number; y: number };\r\n width: number;\r\n color: string;\r\n opacity: number;\r\n };\r\n\r\nexport type EngineInit = { width: number; height: number; pixelRatio?: number; fps?: number };\r\n\r\nexport type Renderer = { render(ops: DrawOp[]): Promise<void>; toPNG?: () => Promise<Buffer> };\r\n\r\nexport type ValidAsset = RichTextValidated;\r\n\r\nexport const isShadowFill = (\r\n op: DrawOp\r\n): op is Extract<DrawOp, { op: \"FillPath\" }> & { isShadow: true } => {\r\n return op.op === \"FillPath\" && (op as Extract<DrawOp, { op: \"FillPath\" }>).isShadow === true;\r\n};\r\n\r\nexport const isGlyphFill = (\r\n op: DrawOp\r\n): op is Extract<DrawOp, { op: \"FillPath\" }> & { isShadow?: false } => {\r\n return op.op === \"FillPath\" && (op as Extract<DrawOp, { op: \"FillPath\" }>).isShadow !== true;\r\n};\r\n"],"mappings":"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","names":["isGlyphFill","isShadowFill","Joi","computePathBounds","tokenizePath","ab","buf","fs","isShadowFill","isGlyphFill"]}