@spark-apps/piclet 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +311 -23
- package/dist/cli.js.map +1 -1
- package/dist/gui/css/theme.css +16 -10
- package/dist/gui/piclet.html +319 -15
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/cli/index.ts","../src/lib/banner.ts","../src/cli/commands/border.ts","../src/tools/border.ts","../src/lib/gui-server.ts","../src/lib/presets.ts","../src/lib/logger.ts","../src/lib/magick.ts","../src/lib/paths.ts","../src/lib/prompts.ts","../src/cli/utils.ts","../src/tools/extract-frames.ts","../src/tools/filter.ts","../src/tools/iconpack.ts","../src/tools/makeicon.ts","../src/tools/piclet-main.ts","../src/tools/recolor.ts","../src/tools/remove-bg.ts","../src/lib/config.ts","../src/tools/rescale.ts","../src/tools/storepack.ts","../src/tools/transform.ts","../src/cli/tools.ts","../src/cli/commands/config.ts","../src/cli/commands/extract-frames.ts","../src/cli/commands/filter.ts","../src/cli/commands/help.ts","../src/cli/commands/iconpack.ts","../src/cli/commands/install.ts","../src/lib/registry.ts","../src/cli/registry.ts","../src/cli/commands/makeicon.ts","../src/cli/commands/piclet.ts","../src/cli/commands/recolor.ts","../src/cli/commands/remove-bg.ts","../src/cli/commands/scale.ts","../src/cli/commands/storepack.ts","../src/cli/commands/transform.ts","../src/cli/commands/uninstall.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport chalk from 'chalk';\nimport { createProgram } from './cli/index.js';\n\nconst program = createProgram();\n\nprogram.parseAsync(process.argv).catch((error) => {\n\tconsole.error(chalk.red(`Error: ${error.message}`));\n\tprocess.exit(1);\n});\n","import chalk from 'chalk';\nimport { Command } from 'commander';\nimport { showBanner } from '../lib/banner.js';\nimport { registerBorderCommand } from './commands/border.js';\nimport { registerConfigCommand } from './commands/config.js';\nimport { registerExtractFramesCommand } from './commands/extract-frames.js';\nimport { registerFilterCommand } from './commands/filter.js';\nimport { registerHelpCommand } from './commands/help.js';\nimport { registerIconpackCommand } from './commands/iconpack.js';\nimport { registerInstallCommand } from './commands/install.js';\nimport { registerMakeiconCommand } from './commands/makeicon.js';\nimport { registerPicletCommand } from './commands/piclet.js';\nimport { registerRecolorCommand } from './commands/recolor.js';\nimport { registerRemoveBgCommand } from './commands/remove-bg.js';\nimport { registerScaleCommand } from './commands/scale.js';\nimport { registerStorepackCommand } from './commands/storepack.js';\nimport { registerTransformCommand } from './commands/transform.js';\nimport { registerUninstallCommand } from './commands/uninstall.js';\n\nexport function showHelp(): void {\n\tshowBanner();\n\n\tconst dim = chalk.gray;\n\tconst cmd = chalk.cyan;\n\tconst arg = chalk.yellow;\n\tconst opt = chalk.green;\n\tconst head = chalk.white.bold;\n\n\tconsole.log(\n\t\t` ${head('Usage:')} piclet ${cmd('<command>')} ${arg('<file>')} ${opt('[options]')}`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Unified'));\n\tconsole.log(\n\t\t` ${cmd('piclet')} ${arg('<file>')} Open all tools in one window`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Individual Tools'));\n\tconsole.log(\n\t\t` ${cmd('makeicon')} ${arg('<file>')} Convert PNG to multi-resolution ICO`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('remove-bg')} ${arg('<file>')} Remove solid background from image`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('scale')} ${arg('<file>')} Resize image with optional padding`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('transform')} ${arg('<file>')} Flip or rotate images`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('filter')} ${arg('<file>')} Apply color filters (grayscale, sepia)`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('border')} ${arg('<file>')} Add solid color border`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('recolor')} ${arg('<file>')} Replace one color with another`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('frames')} ${arg('<file>')} Extract frames from animated GIF`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('iconpack')} ${arg('<file>')} Generate icon sets for Web/Android/iOS`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('storepack')} ${arg('<file>')} Generate assets for app stores`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Setup'));\n\tconsole.log(\n\t\t` ${cmd('install')} Add Windows right-click menu`,\n\t);\n\tconsole.log(` ${cmd('uninstall')} Remove right-click menu`);\n\tconsole.log();\n\tconsole.log(head(' Config'));\n\tconsole.log(` ${cmd('config')} Display current settings`);\n\tconsole.log(` ${cmd('config reset')} Restore defaults`);\n\tconsole.log();\n\tconsole.log(head(' Examples'));\n\tconsole.log(` ${dim('$')} piclet ${cmd('piclet')} ${arg('image.png')} ${dim('# All tools in one window')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('makeicon')} ${arg('logo.png')} ${dim('# Interactive')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('makeicon')} ${arg('*.png')} ${opt('-y')} ${dim('# Batch with defaults')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('remove-bg')} ${arg('photo.png')} ${dim('# Interactive prompts')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('scale')} ${arg('image.jpg')} ${dim('# Interactive resize')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('iconpack')} ${arg('icon.png')} ${opt('-y')} ${dim('# All platforms')}`);\n\tconsole.log();\n\tconsole.log(head(' Requirements'));\n\tconsole.log(' - WSL (Windows Subsystem for Linux)');\n\tconsole.log(' - ImageMagick: sudo apt install imagemagick');\n\tconsole.log();\n}\n\nexport function createProgram(): Command {\n\tconst program = new Command();\n\n\t// Override default help\n\tprogram.helpInformation = () => '';\n\tprogram.on('--help', () => {});\n\n\tprogram\n\t\t.name('piclet')\n\t\t.description('Image manipulation utility toolkit with Windows shell integration')\n\t\t.version('1.0.0')\n\t\t.action(() => {\n\t\t\tshowHelp();\n\t\t});\n\n\t// Register all commands\n\tregisterHelpCommand(program);\n\tregisterInstallCommand(program);\n\tregisterUninstallCommand(program);\n\tregisterMakeiconCommand(program);\n\tregisterRemoveBgCommand(program);\n\tregisterScaleCommand(program);\n\tregisterTransformCommand(program);\n\tregisterFilterCommand(program);\n\tregisterBorderCommand(program);\n\tregisterRecolorCommand(program);\n\tregisterExtractFramesCommand(program);\n\tregisterIconpackCommand(program);\n\tregisterStorepackCommand(program);\n\tregisterPicletCommand(program);\n\tregisterConfigCommand(program);\n\n\treturn program;\n}\n\nexport * from './tools.js';\nexport * from './utils.js';\nexport * from './registry.js';\n","import figlet from 'figlet';\nimport gradient from 'gradient-string';\n\nconst GRADIENT_COLORS = ['#22c55e', '#84cc16', '#eab308', '#fcd34d'];\n\n/**\n * Render the PicLet ASCII art logo with gradient colors\n */\nfunction renderLogo(): string {\n\tconst ascii = figlet.textSync('PicLet', {\n\t\tfont: 'Slant',\n\t\thorizontalLayout: 'default',\n\t});\n\treturn gradient(GRADIENT_COLORS)(ascii);\n}\n\n/**\n * Display the PicLet banner with gradient colors\n */\nexport function showBanner(\n\tsubtitle = 'Image manipulation utility toolkit with Windows shell integration',\n): void {\n\ttry {\n\t\tconsole.log(`\\n${renderLogo()}`);\n\t\tif (subtitle) {\n\t\t\tconst subtleGradient = gradient(['#a8a8a8', '#d4d4d4']);\n\t\t\tconsole.log(subtleGradient(` ${subtitle}\\n`));\n\t\t}\n\t} catch {\n\t\t// Fallback if rendering fails\n\t\tconsole.log('\\n\\x1b[1mPicLet\\x1b[0m');\n\t\tif (subtitle) {\n\t\t\tconsole.log(`\\x1b[2m ${subtitle}\\x1b[0m\\n`);\n\t\t}\n\t}\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as border from '../../tools/border.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerBorderCommand(program: Command): void {\n\tprogram\n\t\t.command('border <files...>')\n\t\t.description('Add solid color border to images')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, border.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await border.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'border',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\taddBorder,\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tgetDimensions,\n\tisMultiFrame,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tnumber as promptNumber,\n\tpauseOnError,\n\ttext as promptText,\n} from '../lib/prompts.js';\n\n/** Processing options for border */\ninterface ProcessOptions {\n\twidth: number;\n\tcolor: string;\n}\n\n/**\n * Core processing logic for border\n */\nasync function processImage(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_border${outputExt}`;\n\n\twip(`Adding ${options.width}px ${options.color} border...`);\n\n\tconst success = await addBorder(input, output, options.width, options.color);\n\n\tif (!success) {\n\t\twipDone(false, 'Border failed');\n\t\treturn false;\n\t}\n\twipDone(true, 'Border added');\n\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tconsole.log(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tconsole.log(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Border Settings:${RESET}`);\n\tconsole.log(` ${DIM}Width: How thick the border should be (in pixels)${RESET}`);\n\tconsole.log(` ${DIM}Color: Hex color (#fff), named color (white), or rgb(...)${RESET}`);\n\tconsole.log('');\n\n\tlet width = await promptNumber('Border width (px)', 10, 1, 200);\n\tif (width < 1) {\n\t\twidth = 10;\n\t}\n\n\tconsole.log('');\n\tlet color = await promptText('Border color', '#ffffff');\n\tif (!color) {\n\t\tcolor = '#ffffff';\n\t}\n\n\treturn { width, color };\n}\n\n/**\n * Add border to image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Border');\n\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\tconst options = await collectOptionsCLI();\n\n\tconsole.log('');\n\treturn processImage(input, options);\n}\n\n/**\n * Add border to image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\treturn startGuiServer({\n\t\thtmlFile: 'border.html',\n\t\ttitle: 'PicLet - Border',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\twidth: 10,\n\t\t\tcolor: '#ffffff',\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst width = (opts.width as number) ?? 10;\n\t\t\tconst color = (opts.color as string) ?? '#ffffff';\n\t\t\treturn generatePreview(input, { width, color });\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst width = (opts.width as number) ?? 10;\n\t\t\tconst color = (opts.color as string) ?? '#ffffff';\n\t\t\tconst options: ProcessOptions = { width, color };\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_border${outputExt}`;\n\n\t\t\tlogs.push({ type: 'info', message: `Adding ${width}px border...` });\n\n\t\t\tconst success = await addBorder(input, output, width, color);\n\n\t\t\tif (success) {\n\t\t\t\tlogs.push({ type: 'success', message: 'Border added' });\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Border failed' });\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\tconst success = await addBorder(previewInput, tempOutput, options.width, options.color);\n\n\t\tif (!success) {\n\t\t\tcleanup(tempSource, tempOutput);\n\t\t\treturn { success: false, error: 'Border failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\n\t\tcleanup(tempSource, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempSource, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'border',\n\tname: 'Add Border',\n\ticon: 'border.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],\n};\n","/**\n * GUI Server - Serves HTML interface and handles API calls\n */\nimport { spawn } from 'node:child_process';\nimport { createServer } from 'node:http';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport express from 'express';\nimport { deletePreset, savePreset, type Preset } from './presets.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Signal the loading HTA to close by creating a temp file\n */\nfunction signalReady(): void {\n\t// Write ready signal to Windows temp directory using PowerShell (no window flash)\n\tspawn('powershell.exe', ['-WindowStyle', 'Hidden', '-Command', 'New-Item -Path $env:TEMP\\\\piclet-ready.tmp -ItemType File -Force | Out-Null'], {\n\t\tstdio: 'ignore',\n\t\twindowsHide: true,\n\t});\n}\n\n/**\n * Open URL in Edge app mode (standalone window without browser UI)\n */\nfunction openAppWindow(url: string): void {\n\t// Use PowerShell with hidden window to launch Edge - prevents terminal flash\n\tspawn('powershell.exe', [\n\t\t'-WindowStyle', 'Hidden',\n\t\t'-Command',\n\t\t`Start-Process msedge -ArgumentList '--app=${url}'`\n\t], {\n\t\tdetached: true,\n\t\tstdio: 'ignore',\n\t\twindowsHide: true,\n\t}).unref();\n\n\t// Signal loading window to close immediately - Edge starts fast\n\tsignalReady();\n}\n\nexport interface GuiServerOptions {\n\thtmlFile: string;\n\ttitle: string;\n\timageInfo: {\n\t\tfilePath: string;\n\t\tfileName: string;\n\t\twidth: number;\n\t\theight: number;\n\t\tborderColor: string | null;\n\t\tframeCount?: number;\n\t};\n\tdefaults: Record<string, unknown>;\n\tonPreview?: (options: Record<string, unknown>) => Promise<{\n\t\tsuccess: boolean;\n\t\timageData?: string; // Base64 data URL\n\t\twidth?: number;\n\t\theight?: number;\n\t\terror?: string;\n\t}>;\n\tonProcess: (options: Record<string, unknown>) => Promise<{\n\t\tsuccess: boolean;\n\t\toutput?: string;\n\t\terror?: string;\n\t\tlogs: Array<{ type: string; message: string }>;\n\t}>;\n\tonLoadImage?: (data: { fileName: string; data: string; mimeType: string }) => Promise<{\n\t\tsuccess: boolean;\n\t\tfilePath?: string;\n\t\tfileName?: string;\n\t\twidth?: number;\n\t\theight?: number;\n\t\tborderColor?: string | null;\n\t\tframeCount?: number;\n\t\terror?: string;\n\t}>;\n\tonFrameThumbnail?: (frameIndex: number) => Promise<{\n\t\tsuccess: boolean;\n\t\timageData?: string;\n\t\terror?: string;\n\t}>;\n\tonFramePreview?: (frameIndex: number, options: Record<string, unknown>) => Promise<{\n\t\tsuccess: boolean;\n\t\timageData?: string;\n\t\terror?: string;\n\t}>;\n}\n\n/**\n * Start GUI server and open Edge app window\n * Returns a promise that resolves when the window is closed\n */\nexport function startGuiServer(options: GuiServerOptions): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst app = express();\n\t\tapp.use(express.json({ limit: '50mb' })); // Allow large base64 images\n\n\t\t// Handle JSON parse errors\n\t\tapp.use((err: Error, _req: express.Request, res: express.Response, next: express.NextFunction) => {\n\t\t\tif (err instanceof SyntaxError && 'body' in err) {\n\t\t\t\tres.status(400).json({ success: false, error: 'Invalid JSON: ' + err.message });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnext(err);\n\t\t});\n\n\t\tlet processResult: boolean | null = null;\n\t\tlet server: ReturnType<typeof createServer> | null = null;\n\n\t\t// Serve static files (CSS, JS, etc.)\n\t\tconst guiDir = join(__dirname, 'gui');\n\t\tconst iconsDir = join(__dirname, 'icons');\n\t\tapp.use(express.static(guiDir));\n\t\tapp.use('/icons', express.static(iconsDir));\n\n\t\t// Serve favicon from icons directory\n\t\tapp.get('/favicon.ico', (_req, res) => {\n\t\t\tres.sendFile(join(iconsDir, 'banana.ico'));\n\t\t});\n\n\t\t// API: Get image info and defaults\n\t\tapp.get('/api/info', (_req, res) => {\n\t\t\tres.json({\n\t\t\t\tfileName: options.imageInfo.fileName,\n\t\t\t\twidth: options.imageInfo.width,\n\t\t\t\theight: options.imageInfo.height,\n\t\t\t\tborderColor: options.imageInfo.borderColor,\n\t\t\t\tframeCount: options.imageInfo.frameCount || 1,\n\t\t\t\tdefaults: options.defaults,\n\t\t\t});\n\t\t});\n\n\t\t// API: Get frame thumbnail (for GIFs)\n\t\tapp.post('/api/frame-thumbnail', async (req, res) => {\n\t\t\tif (!options.onFrameThumbnail) {\n\t\t\t\tres.json({ success: false, error: 'Frame thumbnails not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst frameIndex = (req.body.frameIndex as number) ?? 0;\n\t\t\t\tconst result = await options.onFrameThumbnail(frameIndex);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Get processed frame preview (for GIFs)\n\t\tapp.post('/api/frame-preview', async (req, res) => {\n\t\t\tif (!options.onFramePreview) {\n\t\t\t\tres.json({ success: false, error: 'Frame preview not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst { frameIndex, ...opts } = req.body;\n\t\t\t\tconst result = await options.onFramePreview(frameIndex ?? 0, opts);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Preview image (if supported)\n\t\tapp.post('/api/preview', async (req, res) => {\n\t\t\tif (!options.onPreview) {\n\t\t\t\tres.json({ success: false, error: 'Preview not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await options.onPreview(req.body);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (err as Error).message,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// API: Process image\n\t\tapp.post('/api/process', async (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst result = await options.onProcess(req.body);\n\t\t\t\tprocessResult = result.success;\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tprocessResult = false;\n\t\t\t\tres.json({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (err as Error).message,\n\t\t\t\t\tlogs: [{ type: 'error', message: (err as Error).message }],\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// API: Load new image\n\t\tapp.post('/api/load', async (req, res) => {\n\t\t\tif (!options.onLoadImage) {\n\t\t\t\tres.json({ success: false, error: 'Load not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await options.onLoadImage(req.body);\n\t\t\t\tif (result.success) {\n\t\t\t\t\t// Update current image info\n\t\t\t\t\toptions.imageInfo.filePath = result.filePath!;\n\t\t\t\t\toptions.imageInfo.fileName = result.fileName!;\n\t\t\t\t\toptions.imageInfo.width = result.width!;\n\t\t\t\t\toptions.imageInfo.height = result.height!;\n\t\t\t\t\toptions.imageInfo.borderColor = result.borderColor ?? null;\n\t\t\t\t}\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Cancel/close\n\t\tapp.post('/api/cancel', (_req, res) => {\n\t\t\tprocessResult = false;\n\t\t\tres.json({ ok: true });\n\t\t\tshutdown();\n\t\t});\n\n\t\t// API: Close after completion\n\t\tapp.post('/api/close', (_req, res) => {\n\t\t\tres.json({ ok: true });\n\t\t\tshutdown();\n\t\t});\n\n\t\t// API: Save preset\n\t\tapp.post('/api/save-preset', (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst preset = req.body as Preset;\n\t\t\t\tif (!preset.id || !preset.name || !preset.icons?.length) {\n\t\t\t\t\tres.json({ success: false, error: 'Invalid preset data' });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsavePreset(preset);\n\t\t\t\tres.json({ success: true });\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Delete preset\n\t\tapp.post('/api/delete-preset', (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst { id } = req.body;\n\t\t\t\tif (!id) {\n\t\t\t\t\tres.json({ success: false, error: 'Missing preset ID' });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = deletePreset(id);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Open URL in default browser\n\t\tapp.post('/api/open-url', (req, res) => {\n\t\t\tconst { url } = req.body;\n\t\t\tif (!url || typeof url !== 'string') {\n\t\t\t\tres.json({ success: false, error: 'Missing URL' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Use PowerShell Start-Process which opens in default browser\n\t\t\tspawn('powershell.exe', ['-WindowStyle', 'Hidden', '-Command', `Start-Process '${url}'`], {\n\t\t\t\tdetached: true,\n\t\t\t\tstdio: 'ignore',\n\t\t\t\twindowsHide: true,\n\t\t\t}).unref();\n\t\t\tres.json({ success: true });\n\t\t});\n\n\t\t// API: Open output folder in Explorer\n\t\tapp.post('/api/open-folder', (_req, res) => {\n\t\t\t// Get directory from current image path (output goes to same folder)\n\t\t\tconst filePath = options.imageInfo.filePath;\n\t\t\t// Convert WSL path to Windows path for explorer\n\t\t\t// /mnt/c/path -> C:\\path\n\t\t\tlet winPath = filePath;\n\t\t\tconst wslMatch = filePath.match(/^\\/mnt\\/([a-z])\\/(.*)$/);\n\t\t\tif (wslMatch) {\n\t\t\t\tconst drive = wslMatch[1].toUpperCase();\n\t\t\t\tconst rest = wslMatch[2].replace(/\\//g, '\\\\');\n\t\t\t\twinPath = `${drive}:\\\\${rest}`;\n\t\t\t}\n\t\t\t// Get directory and open in Explorer\n\t\t\tconst dir = winPath.substring(0, winPath.lastIndexOf('\\\\')) || winPath.substring(0, winPath.lastIndexOf('/'));\n\t\t\tspawn('powershell.exe', ['-WindowStyle', 'Hidden', '-Command', `explorer.exe \"${dir}\"`], {\n\t\t\t\tdetached: true,\n\t\t\t\tstdio: 'ignore',\n\t\t\t\twindowsHide: true,\n\t\t\t}).unref();\n\t\t\tres.json({ success: true });\n\t\t});\n\n\t\tfunction shutdown() {\n\t\t\tsetTimeout(() => {\n\t\t\t\tserver?.close();\n\t\t\t\tresolve(processResult ?? false);\n\t\t\t}, 100);\n\t\t}\n\n\t\t// Find available port and start\n\t\tserver = createServer(app);\n\t\tserver.listen(0, '127.0.0.1', () => {\n\t\t\tconst addr = server!.address();\n\t\t\tif (typeof addr === 'object' && addr) {\n\t\t\t\tconst port = addr.port;\n\t\t\t\tconst url = `http://127.0.0.1:${port}/${options.htmlFile}`;\n\n\t\t\t\topenAppWindow(url);\n\n\t\t\t\t// Auto-close after 5 minutes of inactivity\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (processResult === null) {\n\t\t\t\t\t\tshutdown();\n\t\t\t\t\t}\n\t\t\t\t}, 5 * 60 * 1000);\n\t\t\t}\n\t\t});\n\n\t\tserver.on('error', (err) => {\n\t\t\tconsole.error('GUI server error:', err.message);\n\t\t\tresolve(false);\n\t\t});\n\t});\n}\n","/**\n * Presets configuration for store icon packs\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\n\n/** Single icon definition in a preset */\nexport interface PresetIcon {\n\tfilename: string;\n\twidth: number;\n\theight: number;\n}\n\n/** A complete preset definition */\nexport interface Preset {\n\tid: string;\n\tname: string;\n\tdescription: string;\n\ticons: PresetIcon[];\n}\n\n/** Presets file structure */\nexport interface PresetsConfig {\n\tversion: number;\n\tpresets: Preset[];\n}\n\n/** Built-in presets */\nconst BUILT_IN_PRESETS: Preset[] = [\n\t// ── Game Asset Stores ──\n\t{\n\t\tid: 'unity-asset',\n\t\tname: 'Unity Asset Store',\n\t\tdescription: 'Unity Asset Store package images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-160.png', width: 160, height: 160 },\n\t\t\t{ filename: 'card-420x280.png', width: 420, height: 280 },\n\t\t\t{ filename: 'cover-1200x630.png', width: 1200, height: 630 },\n\t\t\t{ filename: 'screenshot-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'unreal-fab',\n\t\tname: 'Unreal / Fab',\n\t\tdescription: 'Unreal Marketplace & Fab assets',\n\t\ticons: [\n\t\t\t{ filename: 'icon-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'thumbnail-284.png', width: 284, height: 284 },\n\t\t\t{ filename: 'featured-894x488.png', width: 894, height: 488 },\n\t\t\t{ filename: 'gallery-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'godot-asset',\n\t\tname: 'Godot Asset Library',\n\t\tdescription: 'Godot Asset Library images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-64.png', width: 64, height: 64 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'screenshot-1280x720.png', width: 1280, height: 720 },\n\t\t\t{ filename: 'screenshot-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'blender-market',\n\t\tname: 'Blender Market',\n\t\tdescription: 'Blender Market product images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'thumbnail-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'preview-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'steam',\n\t\tname: 'Steam',\n\t\tdescription: 'Steam store assets',\n\t\ticons: [\n\t\t\t{ filename: 'capsule-small-231x87.png', width: 231, height: 87 },\n\t\t\t{ filename: 'capsule-main-616x353.png', width: 616, height: 353 },\n\t\t\t{ filename: 'header-460x215.png', width: 460, height: 215 },\n\t\t\t{ filename: 'hero-1920x620.png', width: 1920, height: 620 },\n\t\t\t{ filename: 'library-capsule-600x900.png', width: 600, height: 900 },\n\t\t\t{ filename: 'library-hero-3840x1240.png', width: 3840, height: 1240 },\n\t\t],\n\t},\n\t{\n\t\tid: 'itch-io',\n\t\tname: 'itch.io',\n\t\tdescription: 'itch.io game page assets',\n\t\ticons: [\n\t\t\t{ filename: 'cover-630x500.png', width: 630, height: 500 },\n\t\t\t{ filename: 'thumbnail-315x250.png', width: 315, height: 250 },\n\t\t\t{ filename: 'banner-960x540.png', width: 960, height: 540 },\n\t\t],\n\t},\n\t// ── Extensions & Packages ──\n\t{\n\t\tid: 'chrome-extension',\n\t\tname: 'Chrome Extension',\n\t\tdescription: 'Chrome Web Store extension icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-16.png', width: 16, height: 16 },\n\t\t\t{ filename: 'icon-32.png', width: 32, height: 32 },\n\t\t\t{ filename: 'icon-48.png', width: 48, height: 48 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'promo-440x280.png', width: 440, height: 280 },\n\t\t\t{ filename: 'promo-1400x560.png', width: 1400, height: 560 },\n\t\t],\n\t},\n\t{\n\t\tid: 'firefox-addon',\n\t\tname: 'Firefox Add-on',\n\t\tdescription: 'Firefox Add-ons icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-48.png', width: 48, height: 48 },\n\t\t\t{ filename: 'icon-96.png', width: 96, height: 96 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t],\n\t},\n\t{\n\t\tid: 'vscode-extension',\n\t\tname: 'VS Code Extension',\n\t\tdescription: 'VS Code Marketplace icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'icon-256.png', width: 256, height: 256 },\n\t\t],\n\t},\n\t{\n\t\tid: 'npm-package',\n\t\tname: 'npm Package',\n\t\tdescription: 'npm package icons',\n\t\ticons: [\n\t\t\t{ filename: 'logo-64.png', width: 64, height: 64 },\n\t\t\t{ filename: 'logo-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'logo-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'banner-1200x600.png', width: 1200, height: 600 },\n\t\t],\n\t},\n\t{\n\t\tid: 'windows-store',\n\t\tname: 'Windows Store',\n\t\tdescription: 'Microsoft Store app icons',\n\t\ticons: [\n\t\t\t{ filename: 'Square44x44Logo.png', width: 44, height: 44 },\n\t\t\t{ filename: 'Square150x150Logo.png', width: 150, height: 150 },\n\t\t\t{ filename: 'Square310x310Logo.png', width: 310, height: 310 },\n\t\t\t{ filename: 'Wide310x150Logo.png', width: 310, height: 150 },\n\t\t\t{ filename: 'StoreLogo-50.png', width: 50, height: 50 },\n\t\t\t{ filename: 'SplashScreen-620x300.png', width: 620, height: 300 },\n\t\t],\n\t},\n];\n\n/** Get presets file path */\nexport function getPresetsPath(): string {\n\tconst picletDir = join(homedir(), '.piclet');\n\treturn join(picletDir, 'presets.json');\n}\n\n/** Ensure presets directory exists */\nfunction ensurePresetsDir(): void {\n\tconst presetsPath = getPresetsPath();\n\tconst dir = dirname(presetsPath);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n}\n\n/** Load presets (built-in + user-defined) */\nexport function loadPresets(): Preset[] {\n\tconst presetsPath = getPresetsPath();\n\tlet userPresets: Preset[] = [];\n\n\tif (existsSync(presetsPath)) {\n\t\ttry {\n\t\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\t\tuserPresets = config.presets || [];\n\t\t} catch {\n\t\t\t// Ignore parse errors, use built-in only\n\t\t}\n\t}\n\n\t// Merge: built-in first, then user presets (user can override built-in by ID)\n\tconst presetMap = new Map<string, Preset>();\n\tfor (const preset of BUILT_IN_PRESETS) {\n\t\tpresetMap.set(preset.id, preset);\n\t}\n\tfor (const preset of userPresets) {\n\t\tpresetMap.set(preset.id, preset);\n\t}\n\n\treturn Array.from(presetMap.values());\n}\n\n/** Get a single preset by ID */\nexport function getPreset(id: string): Preset | undefined {\n\tconst presets = loadPresets();\n\treturn presets.find((p) => p.id === id);\n}\n\n/** Save user presets */\nexport function savePresets(presets: Preset[]): void {\n\tensurePresetsDir();\n\tconst config: PresetsConfig = {\n\t\tversion: 1,\n\t\tpresets,\n\t};\n\twriteFileSync(getPresetsPath(), JSON.stringify(config, null, 2));\n}\n\n/** Add or update a preset */\nexport function savePreset(preset: Preset): void {\n\tconst presetsPath = getPresetsPath();\n\tlet userPresets: Preset[] = [];\n\n\tif (existsSync(presetsPath)) {\n\t\ttry {\n\t\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\t\tuserPresets = config.presets || [];\n\t\t} catch {\n\t\t\t// Start fresh\n\t\t}\n\t}\n\n\t// Update or add\n\tconst idx = userPresets.findIndex((p) => p.id === preset.id);\n\tif (idx >= 0) {\n\t\tuserPresets[idx] = preset;\n\t} else {\n\t\tuserPresets.push(preset);\n\t}\n\n\tsavePresets(userPresets);\n}\n\n/** Get built-in preset IDs (for UI distinction) */\nexport function getBuiltInPresetIds(): string[] {\n\treturn BUILT_IN_PRESETS.map((p) => p.id);\n}\n\n/** Delete a user-defined preset by ID */\nexport function deletePreset(id: string): { success: boolean; error?: string } {\n\t// Cannot delete built-in presets\n\tif (BUILT_IN_PRESETS.some((p) => p.id === id)) {\n\t\treturn { success: false, error: 'Cannot delete built-in presets' };\n\t}\n\n\tconst presetsPath = getPresetsPath();\n\tif (!existsSync(presetsPath)) {\n\t\treturn { success: false, error: 'Preset not found' };\n\t}\n\n\ttry {\n\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\tconst userPresets = config.presets || [];\n\n\t\tconst idx = userPresets.findIndex((p) => p.id === id);\n\t\tif (idx < 0) {\n\t\t\treturn { success: false, error: 'Preset not found' };\n\t\t}\n\n\t\tuserPresets.splice(idx, 1);\n\t\tsavePresets(userPresets);\n\t\treturn { success: true };\n\t} catch {\n\t\treturn { success: false, error: 'Failed to delete preset' };\n\t}\n}\n","/**\n * Colored console output utilities\n */\n\n// ANSI color codes\nconst RED = '\\x1b[31m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst BLUE = '\\x1b[34m';\nconst CYAN = '\\x1b[36m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\n\n// Status symbols\nconst CHECK = '✓';\nconst CROSS = '✗';\nconst ARROW = '→';\nconst BULLET = '•';\nconst SPINNER = '⠋';\n\n/** Print success message with checkmark */\nexport function success(message: string): void {\n\tconsole.log(`${GREEN}${CHECK}${RESET} ${message}`);\n}\n\n/** Print error message with X */\nexport function error(message: string): void {\n\tconsole.log(`${RED}${CROSS}${RESET} ${message}`);\n}\n\n/** Print warning message */\nexport function warn(message: string): void {\n\tconsole.log(`${YELLOW}${BULLET}${RESET} ${message}`);\n}\n\n/** Print info message */\nexport function info(message: string): void {\n\tconsole.log(`${BLUE}${ARROW}${RESET} ${message}`);\n}\n\n/** Print step message (for multi-step processes) */\nexport function step(message: string): void {\n\tconsole.log(`${CYAN}${BULLET}${RESET} ${message}`);\n}\n\n/** Print header with separator */\nexport function header(title: string): void {\n\tconsole.log('');\n\tconsole.log(`${BOLD}${title}${RESET}`);\n\tconsole.log(`${DIM}${'─'.repeat(40)}${RESET}`);\n}\n\n/** Print separator line */\nexport function separator(): void {\n\tconsole.log(`${DIM}${'─'.repeat(40)}${RESET}`);\n}\n\n/** Work-in-progress indicator (inline, no newline) */\nexport function wip(message: string): void {\n\tprocess.stdout.write(`${YELLOW}${SPINNER}${RESET} ${message}`);\n}\n\n/** Complete a WIP indicator with result */\nexport function wipDone(isSuccess: boolean, message: string): void {\n\t// Clear line and print result\n\tprocess.stdout.write('\\r\\x1b[K');\n\tif (isSuccess) {\n\t\tsuccess(message);\n\t} else {\n\t\terror(message);\n\t}\n}\n\n/** Clear current line */\nexport function clearLine(): void {\n\tprocess.stdout.write('\\r\\x1b[K');\n}\n\nexport { RESET, BOLD, DIM, GREEN, RED, YELLOW, BLUE, CYAN };\n","import { exec } from 'node:child_process';\nimport { copyFileSync, existsSync, mkdirSync, unlinkSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\n/**\n * Get input path with frame selector for multi-frame formats (ICO)\n * ICO files contain multiple resolutions - [0] selects the largest\n * Used for operations that need a single frame (icon generation)\n */\nfunction getInputSelector(imagePath: string): string {\n\tconst lowerPath = imagePath.toLowerCase();\n\tif (lowerPath.endsWith('.ico')) {\n\t\treturn `\"${imagePath}[0]\"`;\n\t}\n\treturn `\"${imagePath}\"`;\n}\n\n/**\n * Get input path for preview (first frame only for GIFs and ICOs)\n * This prevents slow processing of all animation frames during preview\n */\nfunction getPreviewInputSelector(imagePath: string): string {\n\tconst lowerPath = imagePath.toLowerCase();\n\tif (lowerPath.endsWith('.ico') || lowerPath.endsWith('.gif')) {\n\t\treturn `\"${imagePath}[0]\"`;\n\t}\n\treturn `\"${imagePath}\"`;\n}\n\n/**\n * Check if file is an animated GIF\n */\nfunction isGif(imagePath: string): boolean {\n\treturn imagePath.toLowerCase().endsWith('.gif');\n}\n\n/**\n * Get GIF-optimized output command suffix\n * Uses -layers Optimize to properly save animated GIFs\n */\nfunction getGifOutputSuffix(outputPath: string): string {\n\treturn isGif(outputPath) ? ' -layers Optimize' : '';\n}\n\n/**\n * Get coalesce prefix for GIF input (processes all frames properly)\n */\nfunction getCoalescePrefix(inputPath: string): string {\n\treturn isGif(inputPath) ? '-coalesce ' : '';\n}\n\n/**\n * Check if ImageMagick is installed\n */\nexport async function checkImageMagick(): Promise<boolean> {\n\ttry {\n\t\tawait execAsync('command -v convert');\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get image dimensions\n * Returns [width, height] or null on error\n * Uses first frame only for multi-frame formats (GIF, ICO)\n */\nexport async function getDimensions(\n\timagePath: string,\n): Promise<[number, number] | null> {\n\ttry {\n\t\tconst input = getPreviewInputSelector(imagePath);\n\t\tconst { stdout } = await execAsync(\n\t\t\t`convert ${input} -ping -format \"%w %h\" info:`,\n\t\t);\n\t\tconst [w, h] = stdout.trim().split(' ').map(Number);\n\t\tif (Number.isNaN(w) || Number.isNaN(h)) return null;\n\t\treturn [w, h];\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Get border color (samples top-left pixel)\n * Uses first frame only for multi-frame formats (GIF, ICO)\n */\nexport async function getBorderColor(\n\timagePath: string,\n): Promise<string | null> {\n\ttry {\n\t\tconst input = getPreviewInputSelector(imagePath);\n\t\tconst { stdout } = await execAsync(\n\t\t\t`convert ${input} -format \"%[pixel:u.p{0,0}]\" info:`,\n\t\t);\n\t\treturn stdout.trim();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Trim transparent/whitespace edges from image\n * Preserves animation for GIF files\n */\nexport async function trim(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(`convert \"${inputPath}\" ${coalesce}-trim +repage${gifSuffix} \"${outputPath}\"`);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Make image square by adding transparent padding\n * Preserves animation for GIF files\n */\nexport async function squarify(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\tconst dims = await getDimensions(inputPath);\n\tif (!dims) return false;\n\n\tconst [width, height] = dims;\n\n\t// Already square - just copy\n\tif (width === height) {\n\t\tif (inputPath !== outputPath) {\n\t\t\tcopyFileSync(inputPath, outputPath);\n\t\t}\n\t\treturn true;\n\t}\n\n\tconst size = Math.max(width, height);\n\tconst coalesce = getCoalescePrefix(inputPath);\n\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-background none -gravity center -extent ${size}x${size}${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to specific size with transparent padding\n */\nexport async function scaleToSize(\n\tinputPath: string,\n\toutputPath: string,\n\tsize: number,\n): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -resize ${size}x${size} -background none -gravity center -extent ${size}x${size} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image with custom dimensions and padding\n * Preserves animation for GIF files\n */\nexport async function scaleWithPadding(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-resize ${width}x${height} -background none -gravity center -extent ${width}x${height}${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to exact dimensions (may distort)\n * Preserves animation for GIF files\n */\nexport async function resize(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-resize ${width}x${height}!${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to fill area and crop to exact size (cover mode)\n * Preserves animation for GIF files\n */\nexport async function scaleFillCrop(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-resize ${width}x${height}^ -background none -gravity center -extent ${width}x${height}${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Remove background color from image\n * Preserves animation for GIF files\n */\nexport async function removeBackground(\n\tinputPath: string,\n\toutputPath: string,\n\tcolor: string,\n\tfuzz: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-fuzz ${fuzz}% -transparent \"${color}\"${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Remove background using flood-fill from edges only\n * Preserves animation for GIF files\n */\nexport async function removeBackgroundBorderOnly(\n\tinputPath: string,\n\toutputPath: string,\n\tcolor: string,\n\tfuzz: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-bordercolor \"${color}\" -border 1x1 -fill none -fuzz ${fuzz}% -draw \"matte 0,0 floodfill\" -shave 1x1${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Create ICO file with multiple resolutions\n */\nexport async function createIco(\n\tinputPath: string,\n\toutputPath: string,\n\tsizes: number[] = [256, 128, 64, 48, 32, 16],\n): Promise<boolean> {\n\ttry {\n\t\tconst sizeStr = sizes.join(',');\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -define icon:auto-resize=${sizeStr} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Create ICO from multiple PNG files\n */\nexport async function createIcoFromMultiple(\n\tpngPaths: string[],\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst inputs = pngPaths.map((p) => `\"${p}\"`).join(' ');\n\t\tawait execAsync(`convert ${inputs} \"${outputPath}\"`);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Ensure output directory exists\n */\nexport function ensureDir(filePath: string): void {\n\tconst dir = dirname(filePath);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n}\n\n/**\n * Clean up temporary files\n */\nexport function cleanup(...files: string[]): void {\n\tfor (const file of files) {\n\t\ttry {\n\t\t\tif (existsSync(file)) {\n\t\t\t\tunlinkSync(file);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t}\n}\n\n/**\n * Extract a frame from GIF/ICO for preview\n * @param frameIndex - Which frame to extract (default 0 = first frame)\n * Returns the input path if not a multi-frame format\n */\nexport async function extractFirstFrame(\n\tinputPath: string,\n\toutputPath: string,\n\tframeIndex = 0,\n): Promise<boolean> {\n\tconst lowerPath = inputPath.toLowerCase();\n\tif (!lowerPath.endsWith('.gif') && !lowerPath.endsWith('.ico')) {\n\t\t// Not a multi-frame format, just copy\n\t\ttry {\n\t\t\tcopyFileSync(inputPath, outputPath);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\ttry {\n\t\tif (lowerPath.endsWith('.gif')) {\n\t\t\t// GIFs need coalescing first to handle delta-encoded frames\n\t\t\t// Coalesce composites all frames properly, then we extract the specific frame\n\t\t\tawait execAsync(`convert \"${inputPath}\" -coalesce miff:- | convert \"miff:-[${frameIndex}]\" \"${outputPath}\"`);\n\t\t} else {\n\t\t\t// ICO files don't need coalescing\n\t\t\tawait execAsync(`convert \"${inputPath}[${frameIndex}]\" \"${outputPath}\"`);\n\t\t}\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if file is a multi-frame format (GIF or ICO)\n */\nexport function isMultiFrame(imagePath: string): boolean {\n\tconst lowerPath = imagePath.toLowerCase();\n\treturn lowerPath.endsWith('.gif') || lowerPath.endsWith('.ico');\n}\n\n/**\n * Get frame count from animated GIF\n */\nexport async function getFrameCount(imagePath: string): Promise<number> {\n\ttry {\n\t\tconst { stdout } = await execAsync(\n\t\t\t`identify -format \"%n\\\\n\" \"${imagePath}\" | head -1`,\n\t\t);\n\t\tconst count = parseInt(stdout.trim(), 10);\n\t\treturn Number.isNaN(count) ? 1 : count;\n\t} catch {\n\t\treturn 1;\n\t}\n}\n\n/**\n * Extract all frames from animated GIF to individual PNG files\n * Returns array of output file paths\n */\nexport async function extractAllFrames(\n\tinputPath: string,\n\toutputDir: string,\n\tbaseName: string,\n): Promise<string[]> {\n\ttry {\n\t\t// Ensure output directory exists\n\t\tensureDir(`${outputDir}/dummy`);\n\n\t\t// Extract frames - ImageMagick will create baseName-0.png, baseName-1.png, etc.\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -coalesce \"${outputDir}/${baseName}-%04d.png\"`,\n\t\t);\n\n\t\t// Get list of created files\n\t\tconst { stdout } = await execAsync(`ls -1 \"${outputDir}/${baseName}\"-*.png 2>/dev/null || true`);\n\t\tconst files = stdout.trim().split('\\n').filter(f => f.length > 0);\n\t\treturn files;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Flip image horizontally (mirror)\n * Preserves animation for GIF files\n */\nexport async function flipHorizontal(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-flop${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Flip image vertically\n * Preserves animation for GIF files\n */\nexport async function flipVertical(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-flip${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Rotate image by specified degrees\n * Preserves animation for GIF files\n */\nexport async function rotate(\n\tinputPath: string,\n\toutputPath: string,\n\tdegrees: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-rotate ${degrees} -background none${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Apply grayscale filter\n * Preserves animation for GIF files\n */\nexport async function filterGrayscale(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-colorspace Gray${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Apply sepia tone filter\n * Preserves animation for GIF files\n */\nexport async function filterSepia(\n\tinputPath: string,\n\toutputPath: string,\n\tintensity = 80,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-sepia-tone ${intensity}%${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Invert image colors (negative)\n * Preserves animation for GIF files\n */\nexport async function filterInvert(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-negate${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Apply vintage filter (desaturate + warm tint)\n * Preserves animation for GIF files\n */\nexport async function filterVintage(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-modulate 100,70,100 -fill \"#704214\" -colorize 15%${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Increase saturation (vivid colors)\n * Preserves animation for GIF files\n */\nexport async function filterVivid(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-modulate 100,130,100${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Add solid color border to image\n * Preserves animation for GIF files\n */\nexport async function addBorder(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\tcolor: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-bordercolor \"${color}\" -border ${width}${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Replace one color with another\n * Preserves animation for GIF files\n */\nexport async function replaceColor(\n\tinputPath: string,\n\toutputPath: string,\n\tfromColor: string,\n\ttoColor: string,\n\tfuzz: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-fuzz ${fuzz}% -fill \"${toColor}\" -opaque \"${fromColor}\"${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","import { basename, dirname, extname, resolve } from 'node:path';\n\n/**\n * Convert Windows path to WSL path\n * C:\\Users\\... → /mnt/c/Users/...\n */\nexport function windowsToWsl(winPath: string): string {\n\t// Already a WSL path\n\tif (winPath.startsWith('/mnt/')) {\n\t\treturn winPath;\n\t}\n\n\t// Windows path pattern: C:\\... or C:/...\n\tconst match = winPath.match(/^([A-Za-z]):[/\\\\](.*)$/);\n\tif (match) {\n\t\tconst drive = match[1].toLowerCase();\n\t\tconst rest = match[2].replace(/\\\\/g, '/');\n\t\treturn `/mnt/${drive}/${rest}`;\n\t}\n\n\treturn winPath;\n}\n\n/**\n * Convert WSL path to Windows path\n * /mnt/c/Users/... → C:\\Users\\...\n */\nexport function wslToWindows(wslPath: string): string {\n\tconst match = wslPath.match(/^\\/mnt\\/([a-z])\\/(.*)$/i);\n\tif (match) {\n\t\tconst drive = match[1].toUpperCase();\n\t\tconst rest = match[2].replace(/\\//g, '\\\\');\n\t\treturn `${drive}:\\\\${rest}`;\n\t}\n\treturn wslPath;\n}\n\n/**\n * Normalize a path - convert Windows paths if needed, resolve relative paths\n */\nexport function normalizePath(inputPath: string): string {\n\tif (/^[A-Za-z]:[/\\\\]/.test(inputPath)) {\n\t\treturn windowsToWsl(inputPath);\n\t}\n\treturn resolve(inputPath);\n}\n\n/**\n * Get file info from a path\n */\nexport interface FileInfo {\n\tdirname: string;\n\tbasename: string;\n\tfilename: string;\n\textension: string;\n}\n\nexport function getFileInfo(filePath: string): FileInfo {\n\tconst dir = dirname(filePath);\n\tconst base = basename(filePath);\n\tconst ext = extname(filePath);\n\tconst name = base.slice(0, -ext.length);\n\n\treturn {\n\t\tdirname: dir,\n\t\tbasename: base,\n\t\tfilename: name,\n\t\textension: ext,\n\t};\n}\n\n/**\n * Generate output path with suffix\n */\nexport function getOutputPath(\n\tinputPath: string,\n\tsuffix: string,\n\tnewExtension?: string,\n): string {\n\tconst info = getFileInfo(inputPath);\n\tconst ext = newExtension ?? info.extension;\n\treturn `${info.dirname}/${info.filename}${suffix}${ext}`;\n}\n","import prompts from 'prompts';\n\n/** When true, all prompts return their default values without user interaction */\nlet useDefaults = false;\n\n/** Override values from CLI arguments - keyed by prompt message substring */\nconst overrides: Record<string, string | number | boolean | string[]> = {};\n\n/**\n * Enable or disable default mode (for --yes flag)\n */\nexport function setUseDefaults(value: boolean): void {\n\tuseDefaults = value;\n}\n\n/**\n * Check if defaults mode is enabled\n */\nexport function isUsingDefaults(): boolean {\n\treturn useDefaults;\n}\n\n/**\n * Set override values from CLI arguments\n */\nexport function setOverrides(values: Record<string, string | number | boolean | string[]>): void {\n\tObject.assign(overrides, values);\n}\n\n/**\n * Clear all overrides\n */\nexport function clearOverrides(): void {\n\tfor (const key of Object.keys(overrides)) {\n\t\tdelete overrides[key];\n\t}\n}\n\n/**\n * Get override value for a prompt message (matches substring)\n */\nfunction getOverride(message: string): string | number | boolean | string[] | undefined {\n\tconst msgLower = message.toLowerCase();\n\tfor (const [key, value] of Object.entries(overrides)) {\n\t\tif (msgLower.includes(key.toLowerCase())) {\n\t\t\treturn value;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Prompt for text input with optional default\n */\nexport async function text(\n\tmessage: string,\n\tdefaultValue?: string,\n): Promise<string> {\n\tif (useDefaults) return defaultValue ?? '';\n\n\tconst response = await prompts({\n\t\ttype: 'text',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t});\n\treturn response.value ?? defaultValue ?? '';\n}\n\n/**\n * Prompt for number input with optional default\n */\nexport async function number(\n\tmessage: string,\n\tdefaultValue?: number,\n\tmin?: number,\n\tmax?: number,\n): Promise<number> {\n\tconst override = getOverride(message);\n\tif (override !== undefined) return Number(override);\n\tif (useDefaults) return defaultValue ?? 0;\n\n\tconst response = await prompts({\n\t\ttype: 'number',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t\tmin,\n\t\tmax,\n\t});\n\treturn response.value ?? defaultValue ?? 0;\n}\n\n/**\n * Prompt for yes/no confirmation\n */\nexport async function confirm(\n\tmessage: string,\n\tdefaultValue = true,\n): Promise<boolean> {\n\tconst override = getOverride(message);\n\tif (override !== undefined) return Boolean(override);\n\tif (useDefaults) return defaultValue;\n\n\tconst response = await prompts({\n\t\ttype: 'confirm',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t});\n\treturn response.value ?? defaultValue;\n}\n\n/**\n * Single-select from options\n */\nexport interface SelectOption {\n\ttitle: string;\n\tvalue: string | number;\n\tdescription?: string;\n}\n\nexport async function select<T extends string | number>(\n\tmessage: string,\n\toptions: SelectOption[],\n\tdefaultValue?: T,\n): Promise<T | null> {\n\tif (useDefaults) return defaultValue ?? (options[0]?.value as T) ?? null;\n\n\tconst response = await prompts({\n\t\ttype: 'select',\n\t\tname: 'value',\n\t\tmessage,\n\t\tchoices: options.map((opt) => ({\n\t\t\ttitle: opt.title,\n\t\t\tvalue: opt.value,\n\t\t\tdescription: opt.description,\n\t\t})),\n\t});\n\treturn (response.value as T) ?? null;\n}\n\n/**\n * Multi-select from options\n */\nexport async function multiSelect<T extends string | number>(\n\tmessage: string,\n\toptions: SelectOption[],\n\tdefaultValues?: T[],\n): Promise<T[]> {\n\tif (useDefaults) return defaultValues ?? [];\n\n\tconst response = await prompts({\n\t\ttype: 'multiselect',\n\t\tname: 'value',\n\t\tmessage,\n\t\tchoices: options.map((opt) => ({\n\t\t\ttitle: opt.title,\n\t\t\tvalue: opt.value,\n\t\t\tdescription: opt.description,\n\t\t})),\n\t\tinstructions: false,\n\t\thint: '- Space to select, Enter to confirm',\n\t});\n\treturn (response.value as T[]) ?? [];\n}\n\n/**\n * Handle Ctrl+C gracefully\n */\nexport function onCancel(): void {\n\tprompts.override({ value: undefined });\n}\n\n// Set up cancel handler\nprompts.override({});\n\n/**\n * Pause and wait for user to press Enter (useful for errors in batch mode)\n * Only pauses when running with -y flag so user can see error messages\n */\nexport async function pauseOnError(message = 'Press Enter to close...'): Promise<void> {\n\tif (!useDefaults) return; // Interactive mode - no need to pause\n\n\tconsole.log();\n\tawait prompts({\n\t\ttype: 'text',\n\t\tname: 'value',\n\t\tmessage,\n\t});\n}\n","import { extname } from 'node:path';\nimport { dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport chalk from 'chalk';\nimport { setUseDefaults } from '../lib/prompts.js';\nimport { getTool } from './tools.js';\n\n/** Get dist directory (where cli.js lives after bundling) */\nexport function getDistDir(): string {\n\tconst currentFile = fileURLToPath(import.meta.url);\n\t// tsup bundles everything into dist/cli.js, so dirname gives dist/\n\treturn dirname(currentFile);\n}\n\n/** Get registry base path for PicLet menu on an extension */\nexport function getMenuBasePath(extension: string): string {\n\treturn `HKCU\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n}\n\n/** Validate files have correct extensions for the tool */\nexport function validateExtensions(\n\tfiles: string[],\n\tallowedExtensions: string[],\n): { valid: string[]; invalid: string[] } {\n\tconst valid: string[] = [];\n\tconst invalid: string[] = [];\n\n\tfor (const file of files) {\n\t\tconst ext = extname(file).toLowerCase();\n\t\tif (allowedExtensions.includes(ext)) {\n\t\t\tvalid.push(file);\n\t\t} else {\n\t\t\tinvalid.push(file);\n\t\t}\n\t}\n\n\treturn { valid, invalid };\n}\n\n/** Run tool on multiple files */\nexport async function runToolOnFiles(\n\ttoolId: string,\n\tfiles: string[],\n\tuseYes: boolean,\n): Promise<boolean> {\n\tconst tool = getTool(toolId);\n\tif (!tool) {\n\t\tconsole.error(chalk.red(`Tool not found: ${toolId}`));\n\t\treturn false;\n\t}\n\n\t// Validate extensions\n\tconst { valid, invalid } = validateExtensions(files, tool.config.extensions);\n\n\tif (invalid.length > 0) {\n\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\tfor (const file of invalid) {\n\t\t\tconsole.error(chalk.red(` ✗ ${file}`));\n\t\t}\n\t\tconsole.error(\n\t\t\tchalk.yellow(\n\t\t\t\t`\\nSupported extensions: ${tool.config.extensions.join(', ')}`,\n\t\t\t),\n\t\t);\n\t\tif (valid.length === 0) return false;\n\t\tconsole.log();\n\t}\n\n\t// Enable defaults mode if --yes flag or multiple files\n\tif (useYes || valid.length > 1) {\n\t\tsetUseDefaults(true);\n\t}\n\n\t// Process files\n\tlet allSuccess = true;\n\tfor (let i = 0; i < valid.length; i++) {\n\t\tconst file = valid[i];\n\t\tif (valid.length > 1) {\n\t\t\tconsole.log(chalk.cyan(`\\n[${i + 1}/${valid.length}] ${file}`));\n\t\t}\n\t\tconst success = await tool.run(file);\n\t\tif (!success) allSuccess = false;\n\t}\n\n\treturn allSuccess;\n}\n","import { existsSync, mkdirSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\tsuccess,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractAllFrames,\n\textractFirstFrame,\n\tgetDimensions,\n\tgetFrameCount,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tconfirm as promptConfirm,\n\tpauseOnError,\n} from '../lib/prompts.js';\n\n/**\n * Extract frames from animated GIF (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Extract Frames');\n\n\twip('Analyzing GIF...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\n\tconst frameCount = await getFrameCount(input);\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}, ${frameCount} frames`);\n\n\tif (frameCount <= 1) {\n\t\tinfo('Image has only 1 frame, nothing to extract');\n\t\treturn true;\n\t}\n\n\tconsole.log('');\n\tconsole.log(`${BOLD}Extract Frames:${RESET}`);\n\tconsole.log(` ${DIM}This will create ${frameCount} PNG files${RESET}`);\n\tconsole.log('');\n\n\tconst proceed = await promptConfirm(`Extract ${frameCount} frames?`, true);\n\tif (!proceed) {\n\t\tinfo('Cancelled');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_frames`;\n\n\tconsole.log('');\n\twip('Extracting frames...');\n\n\tmkdirSync(outputDir, { recursive: true });\n\tconst frames = await extractAllFrames(input, outputDir, 'frame');\n\n\tif (frames.length === 0) {\n\t\twipDone(false, 'Extraction failed');\n\t\treturn false;\n\t}\n\n\twipDone(true, `Extracted ${frames.length} frames`);\n\n\tconsole.log('');\n\tsuccess(`Output: ${outputDir}/`);\n\treturn true;\n}\n\n/**\n * Extract frames from animated GIF (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst frameCount = await getFrameCount(input);\n\tconst fileInfo = getFileInfo(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'extract-frames.html',\n\t\ttitle: 'PicLet - Extract Frames',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tframeCount,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst frameIndex = (opts.frameIndex as number) ?? 0;\n\t\t\treturn generateFramePreview(input, frameIndex);\n\t\t},\n\t\tonProcess: async () => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Extracting ${frameCount} frames...` });\n\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_frames`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\tconst frames = await extractAllFrames(input, outputDir, 'frame');\n\n\t\t\tif (frames.length > 0) {\n\t\t\t\tlogs.push({ type: 'success', message: `Extracted ${frames.length} frames` });\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${frames.length} frames -> ${fileInfo.filename}_frames/`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Extraction failed' });\n\t\t\treturn { success: false, error: 'Extraction failed', logs };\n\t\t},\n\t});\n}\n\n/**\n * Generate preview for a specific frame\n */\nasync function generateFramePreview(\n\tinput: string,\n\tframeIndex: number,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempOutput = join(tempDir, `piclet-frame-${timestamp}.png`);\n\n\ttry {\n\t\tif (!(await extractFirstFrame(input, tempOutput, frameIndex))) {\n\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\t\tcleanup(tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'extract-frames',\n\tname: 'Extract Frames',\n\ticon: 'extract.ico',\n\textensions: ['.gif'],\n};\n","import { existsSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tfilterGrayscale,\n\tfilterInvert,\n\tfilterSepia,\n\tfilterVintage,\n\tfilterVivid,\n\tgetDimensions,\n\tisMultiFrame,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tpauseOnError,\n\tselect as promptSelect,\n} from '../lib/prompts.js';\n\n/** Filter types */\ntype FilterType = 'grayscale' | 'sepia' | 'invert' | 'vintage' | 'vivid';\n\n/** Processing options for filter */\ninterface ProcessOptions {\n\tfilter: FilterType;\n}\n\nconst FILTER_LABELS: Record<FilterType, string> = {\n\t'grayscale': 'Grayscale',\n\t'sepia': 'Sepia',\n\t'invert': 'Invert',\n\t'vintage': 'Vintage',\n\t'vivid': 'Vivid',\n};\n\n/**\n * Apply filter to image file\n */\nasync function applyFilter(\n\tinput: string,\n\toutput: string,\n\tfilter: FilterType,\n): Promise<boolean> {\n\tswitch (filter) {\n\t\tcase 'grayscale':\n\t\t\treturn filterGrayscale(input, output);\n\t\tcase 'sepia':\n\t\t\treturn filterSepia(input, output);\n\t\tcase 'invert':\n\t\t\treturn filterInvert(input, output);\n\t\tcase 'vintage':\n\t\t\treturn filterVintage(input, output);\n\t\tcase 'vivid':\n\t\t\treturn filterVivid(input, output);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Core processing logic for filter\n */\nasync function processImage(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_${options.filter}${outputExt}`;\n\n\twip(`Applying ${FILTER_LABELS[options.filter]} filter...`);\n\n\tconst success = await applyFilter(input, output, options.filter);\n\n\tif (!success) {\n\t\twipDone(false, 'Filter failed');\n\t\treturn false;\n\t}\n\twipDone(true, FILTER_LABELS[options.filter]);\n\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tconsole.log(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tconsole.log(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Filter Options:${RESET}`);\n\tconsole.log(` ${DIM}1. Grayscale - Black and white${RESET}`);\n\tconsole.log(` ${DIM}2. Sepia - Warm brownish tint${RESET}`);\n\tconsole.log(` ${DIM}3. Invert - Negative colors${RESET}`);\n\tconsole.log(` ${DIM}4. Vintage - Desaturated warm tone${RESET}`);\n\tconsole.log(` ${DIM}5. Vivid - Increased saturation${RESET}`);\n\tconsole.log('');\n\n\tconst filter = await promptSelect<FilterType>(\n\t\t'Select filter',\n\t\t[\n\t\t\t{ value: 'grayscale', title: 'Grayscale' },\n\t\t\t{ value: 'sepia', title: 'Sepia' },\n\t\t\t{ value: 'invert', title: 'Invert' },\n\t\t\t{ value: 'vintage', title: 'Vintage' },\n\t\t\t{ value: 'vivid', title: 'Vivid' },\n\t\t],\n\t\t'grayscale',\n\t);\n\n\treturn { filter: filter ?? 'grayscale' };\n}\n\n/**\n * Apply filter to image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Filter');\n\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\tconst options = await collectOptionsCLI();\n\n\tconsole.log('');\n\treturn processImage(input, options);\n}\n\n/**\n * Apply filter to image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\treturn startGuiServer({\n\t\thtmlFile: 'filter.html',\n\t\ttitle: 'PicLet - Filter',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tfilter: 'grayscale',\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst filter = (opts.filter as FilterType) ?? 'grayscale';\n\t\t\treturn generatePreview(input, { filter });\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst filter = (opts.filter as FilterType) ?? 'grayscale';\n\t\t\tconst options: ProcessOptions = { filter };\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_${filter}${outputExt}`;\n\n\t\t\tlogs.push({ type: 'info', message: `Applying ${FILTER_LABELS[filter]} filter...` });\n\n\t\t\tconst success = await applyFilter(input, output, filter);\n\n\t\t\tif (success) {\n\t\t\t\tlogs.push({ type: 'success', message: 'Filter applied' });\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Filter failed' });\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\tconst success = await applyFilter(previewInput, tempOutput, options.filter);\n\n\t\tif (!success) {\n\t\t\tcleanup(tempSource, tempOutput);\n\t\t\treturn { success: false, error: 'Filter failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\n\t\tcleanup(tempSource, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempSource, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'filter',\n\tname: 'Filter',\n\ticon: 'filter.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],\n};\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { basename, dirname } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tDIM,\n\tRESET,\n\tclearLine,\n\terror,\n\theader,\n\tinfo,\n\tseparator,\n\tstep,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tcreateIcoFromMultiple,\n\tgetDimensions,\n\tscaleToSize,\n\tsquarify,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { multiSelect as promptMultiSelect, pauseOnError } from '../lib/prompts.js';\n\n// Icon definitions for each platform\ninterface IconDef {\n\tfilename: string;\n\tsize: number;\n}\n\nconst WEB_ICONS: IconDef[] = [\n\t{ filename: 'favicon-16x16.png', size: 16 },\n\t{ filename: 'favicon-32x32.png', size: 32 },\n\t{ filename: 'favicon-48x48.png', size: 48 },\n\t{ filename: 'apple-touch-icon.png', size: 180 },\n\t{ filename: 'android-chrome-192x192.png', size: 192 },\n\t{ filename: 'android-chrome-512x512.png', size: 512 },\n\t{ filename: 'mstile-150x150.png', size: 150 },\n];\n\nconst ANDROID_ICONS: IconDef[] = [\n\t{ filename: 'mipmap-mdpi/ic_launcher.png', size: 48 },\n\t{ filename: 'mipmap-hdpi/ic_launcher.png', size: 72 },\n\t{ filename: 'mipmap-xhdpi/ic_launcher.png', size: 96 },\n\t{ filename: 'mipmap-xxhdpi/ic_launcher.png', size: 144 },\n\t{ filename: 'mipmap-xxxhdpi/ic_launcher.png', size: 192 },\n\t{ filename: 'playstore-icon.png', size: 512 },\n];\n\nconst IOS_ICONS: IconDef[] = [\n\t// 20pt - Notifications\n\t{ filename: 'AppIcon-20.png', size: 20 },\n\t{ filename: 'AppIcon-20@2x.png', size: 40 },\n\t{ filename: 'AppIcon-20@3x.png', size: 60 },\n\t// 29pt - Settings\n\t{ filename: 'AppIcon-29.png', size: 29 },\n\t{ filename: 'AppIcon-29@2x.png', size: 58 },\n\t{ filename: 'AppIcon-29@3x.png', size: 87 },\n\t// 40pt - Spotlight\n\t{ filename: 'AppIcon-40.png', size: 40 },\n\t{ filename: 'AppIcon-40@2x.png', size: 80 },\n\t{ filename: 'AppIcon-40@3x.png', size: 120 },\n\t// 60pt - iPhone App\n\t{ filename: 'AppIcon-60@2x.png', size: 120 },\n\t{ filename: 'AppIcon-60@3x.png', size: 180 },\n\t// 76pt - iPad App\n\t{ filename: 'AppIcon-76.png', size: 76 },\n\t{ filename: 'AppIcon-76@2x.png', size: 152 },\n\t// 83.5pt - iPad Pro\n\t{ filename: 'AppIcon-83.5@2x.png', size: 167 },\n\t// App Store\n\t{ filename: 'AppIcon-1024.png', size: 1024 },\n];\n\n/**\n * Generate icons for a platform\n */\nasync function generateIcons(\n\toutputDir: string,\n\tsourceImg: string,\n\ticons: IconDef[],\n): Promise<number> {\n\tconst total = icons.length;\n\tlet current = 0;\n\tlet failed = 0;\n\n\tfor (const icon of icons) {\n\t\tcurrent++;\n\t\tconst outputPath = `${outputDir}/${icon.filename}`;\n\n\t\t// Create subdirectory if needed\n\t\tconst subdir = dirname(outputPath);\n\t\tif (!existsSync(subdir)) {\n\t\t\tmkdirSync(subdir, { recursive: true });\n\t\t}\n\n\t\tclearLine();\n\t\twip(`[${current}/${total}] Generating ${icon.filename}...`);\n\n\t\tif (await scaleToSize(sourceImg, outputPath, icon.size)) {\n\t\t\tclearLine();\n\t\t\tsuccess(\n\t\t\t\t`[${current}/${total}] ${icon.filename} (${icon.size}x${icon.size})`,\n\t\t\t);\n\t\t} else {\n\t\t\tclearLine();\n\t\t\terror(`[${current}/${total}] Failed: ${icon.filename}`);\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Generate favicon.ico from multiple sizes\n */\nasync function generateFavicon(\n\toutputDir: string,\n\tsourceImg: string,\n): Promise<boolean> {\n\twip('Generating favicon.ico...');\n\n\tconst temp16 = `${outputDir}/.temp_16.png`;\n\tconst temp32 = `${outputDir}/.temp_32.png`;\n\tconst temp48 = `${outputDir}/.temp_48.png`;\n\n\tawait scaleToSize(sourceImg, temp16, 16);\n\tawait scaleToSize(sourceImg, temp32, 32);\n\tawait scaleToSize(sourceImg, temp48, 48);\n\n\tconst result = await createIcoFromMultiple(\n\t\t[temp16, temp32, temp48],\n\t\t`${outputDir}/favicon.ico`,\n\t);\n\n\tcleanup(temp16, temp32, temp48);\n\n\tif (result) {\n\t\twipDone(true, 'favicon.ico (16, 32, 48)');\n\t\treturn true;\n\t}\n\twipDone(false, 'favicon.ico failed');\n\treturn false;\n}\n\n/**\n * Generate icon sets for Web, Android, iOS platforms\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Get file info\n\tconst fileInfo = getFileInfo(input);\n\n\theader('PicLet Icon Pack Generator');\n\n\t// Analyze source image\n\twip('Analyzing source image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\tconst [origW, origH] = dims;\n\twipDone(true, `Source: ${origW}x${origH}`);\n\n\t// Warn if small source\n\tif (origW < 1024 || origH < 1024) {\n\t\twarn(\n\t\t\t'Source image is smaller than 1024px. Larger images produce better quality.',\n\t\t);\n\t}\n\n\t// Check if square\n\tif (origW !== origH) {\n\t\twarn('Image is not square. Will add transparent padding.');\n\t}\n\n\t// Select platforms\n\tconsole.log('');\n\tconst platforms = await promptMultiSelect<string>(\n\t\t'Select target platforms:',\n\t\t[\n\t\t\t{ title: 'Web (PWA, favicon, apple-touch-icon)', value: 'web' },\n\t\t\t{ title: 'Android (mipmap icons, Play Store)', value: 'android' },\n\t\t\t{ title: 'iOS (App icons, App Store)', value: 'ios' },\n\t\t],\n\t\t['web', 'android', 'ios'], // Default: all platforms\n\t);\n\n\tif (platforms.length === 0) {\n\t\terror('No platforms selected');\n\t\treturn false;\n\t}\n\n\tconst doWeb = platforms.includes('web');\n\tconst doAndroid = platforms.includes('android');\n\tconst doIos = platforms.includes('ios');\n\n\t// Create output directory\n\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\tmkdirSync(outputDir, { recursive: true });\n\tinfo(`Output directory: ${outputDir}`);\n\n\t// Prepare source: make square and scale to 1024px for best quality\n\tconsole.log('');\n\twip('Preparing source image...');\n\tconst tempSource = `${outputDir}/.source_1024.png`;\n\tconst tempSquare = `${outputDir}/.temp_square.png`;\n\n\t// First squarify\n\tif (!(await squarify(input, tempSquare))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\treturn false;\n\t}\n\n\t// Then scale to 1024 for high quality source\n\tif (!(await scaleToSize(tempSquare, tempSource, 1024))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\tcleanup(tempSquare);\n\t\treturn false;\n\t}\n\tcleanup(tempSquare);\n\twipDone(true, 'Prepared 1024x1024 source');\n\n\tlet totalFailed = 0;\n\n\t// Generate Web icons\n\tif (doWeb) {\n\t\tconsole.log('');\n\t\theader('Web Icons');\n\t\tconst webDir = `${outputDir}/web`;\n\t\tmkdirSync(webDir, { recursive: true });\n\n\t\tif (!(await generateFavicon(webDir, tempSource))) {\n\t\t\ttotalFailed++;\n\t\t}\n\n\t\ttotalFailed += await generateIcons(webDir, tempSource, WEB_ICONS);\n\t}\n\n\t// Generate Android icons\n\tif (doAndroid) {\n\t\tconsole.log('');\n\t\theader('Android Icons');\n\t\tconst androidDir = `${outputDir}/android`;\n\t\tmkdirSync(androidDir, { recursive: true });\n\n\t\ttotalFailed += await generateIcons(androidDir, tempSource, ANDROID_ICONS);\n\t}\n\n\t// Generate iOS icons\n\tif (doIos) {\n\t\tconsole.log('');\n\t\theader('iOS Icons');\n\t\tconst iosDir = `${outputDir}/ios`;\n\t\tmkdirSync(iosDir, { recursive: true });\n\n\t\ttotalFailed += await generateIcons(iosDir, tempSource, IOS_ICONS);\n\t}\n\n\t// Cleanup\n\tcleanup(tempSource);\n\n\t// Summary\n\tconsole.log('');\n\tseparator();\n\n\tif (totalFailed === 0) {\n\t\tsuccess('All icons generated successfully!');\n\t} else {\n\t\twarn(`${totalFailed} icon(s) failed to generate`);\n\t}\n\n\tconsole.log('');\n\tinfo(`Icons saved to: ${outputDir}`);\n\n\tif (doWeb) {\n\t\tstep('web/ - Favicon, PWA icons, Apple touch icon');\n\t}\n\tif (doAndroid) {\n\t\tstep('android/ - mipmap folders, Play Store icon');\n\t}\n\tif (doIos) {\n\t\tstep('ios/ - All iOS app icon sizes');\n\t}\n\n\treturn totalFailed === 0;\n}\n\n/**\n * Generate icon pack (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'iconpack.html',\n\t\ttitle: 'PicLet - Icon Pack',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tweb: true,\n\t\t\tandroid: true,\n\t\t\tios: true,\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst doWeb = (opts.web as boolean) ?? true;\n\t\t\tconst doAndroid = (opts.android as boolean) ?? true;\n\t\t\tconst doIos = (opts.ios as boolean) ?? true;\n\n\t\t\tif (!doWeb && !doAndroid && !doIos) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'No platforms selected',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'No platforms selected' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Create output directory\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\t\t\tlogs.push({ type: 'info', message: `Output: ${outputDir}` });\n\n\t\t\t// Prepare source: make square and scale to 1024px\n\t\t\tlogs.push({ type: 'info', message: 'Preparing source image...' });\n\t\t\tconst tempSource = `${outputDir}/.source_1024.png`;\n\t\t\tconst tempSquare = `${outputDir}/.temp_square.png`;\n\n\t\t\tif (!(await squarify(input, tempSquare))) {\n\t\t\t\treturn { success: false, error: 'Failed to prepare source', logs };\n\t\t\t}\n\n\t\t\tif (!(await scaleToSize(tempSquare, tempSource, 1024))) {\n\t\t\t\tcleanup(tempSquare);\n\t\t\t\treturn { success: false, error: 'Failed to prepare source', logs };\n\t\t\t}\n\t\t\tcleanup(tempSquare);\n\t\t\tlogs.push({ type: 'success', message: 'Prepared 1024x1024 source' });\n\n\t\t\tlet totalFailed = 0;\n\n\t\t\t// Generate Web icons\n\t\t\tif (doWeb) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating Web icons...' });\n\t\t\t\tconst webDir = `${outputDir}/web`;\n\t\t\t\tmkdirSync(webDir, { recursive: true });\n\n\t\t\t\tif (!(await generateFaviconSilent(webDir, tempSource))) {\n\t\t\t\t\ttotalFailed++;\n\t\t\t\t}\n\t\t\t\ttotalFailed += await generateIconsSilent(webDir, tempSource, WEB_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `Web: ${WEB_ICONS.length + 1} icons` });\n\t\t\t}\n\n\t\t\t// Generate Android icons\n\t\t\tif (doAndroid) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating Android icons...' });\n\t\t\t\tconst androidDir = `${outputDir}/android`;\n\t\t\t\tmkdirSync(androidDir, { recursive: true });\n\t\t\t\ttotalFailed += await generateIconsSilent(androidDir, tempSource, ANDROID_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `Android: ${ANDROID_ICONS.length} icons` });\n\t\t\t}\n\n\t\t\t// Generate iOS icons\n\t\t\tif (doIos) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating iOS icons...' });\n\t\t\t\tconst iosDir = `${outputDir}/ios`;\n\t\t\t\tmkdirSync(iosDir, { recursive: true });\n\t\t\t\ttotalFailed += await generateIconsSilent(iosDir, tempSource, IOS_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `iOS: ${IOS_ICONS.length} icons` });\n\t\t\t}\n\n\t\t\tcleanup(tempSource);\n\n\t\t\tif (totalFailed === 0) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `Icons saved to ${fileInfo.filename}_icons/`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `${totalFailed} icon(s) failed`,\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Silent version of generateIcons for GUI mode\n */\nasync function generateIconsSilent(\n\toutputDir: string,\n\tsourceImg: string,\n\ticons: IconDef[],\n\t_logs: Array<{ type: string; message: string }>,\n): Promise<number> {\n\tlet failed = 0;\n\n\tfor (const icon of icons) {\n\t\tconst outputPath = `${outputDir}/${icon.filename}`;\n\t\tconst subdir = dirname(outputPath);\n\t\tif (!existsSync(subdir)) {\n\t\t\tmkdirSync(subdir, { recursive: true });\n\t\t}\n\n\t\tif (!(await scaleToSize(sourceImg, outputPath, icon.size))) {\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Silent version of generateFavicon for GUI mode\n */\nasync function generateFaviconSilent(\n\toutputDir: string,\n\tsourceImg: string,\n): Promise<boolean> {\n\tconst temp16 = `${outputDir}/.temp_16.png`;\n\tconst temp32 = `${outputDir}/.temp_32.png`;\n\tconst temp48 = `${outputDir}/.temp_48.png`;\n\n\tawait scaleToSize(sourceImg, temp16, 16);\n\tawait scaleToSize(sourceImg, temp32, 32);\n\tawait scaleToSize(sourceImg, temp48, 48);\n\n\tconst result = await createIcoFromMultiple(\n\t\t[temp16, temp32, temp48],\n\t\t`${outputDir}/favicon.ico`,\n\t);\n\n\tcleanup(temp16, temp32, temp48);\n\treturn result;\n}\n\nexport const config = {\n\tid: 'iconpack',\n\tname: 'Icon Pack',\n\ticon: 'iconpack.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif'],\n};\n","import { existsSync, readFileSync } from 'node:fs';\r\nimport { tmpdir } from 'node:os';\r\nimport { basename, join } from 'node:path';\r\nimport { startGuiServer } from '../lib/gui-server.js';\r\nimport { error, header, success, wip, wipDone } from '../lib/logger.js';\r\nimport {\r\n\tcheckImageMagick,\r\n\tcleanup,\r\n\tcreateIco,\r\n\tgetDimensions,\r\n\tscaleToSize,\r\n\tsquarify,\r\n\ttrim,\r\n} from '../lib/magick.js';\r\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\r\nimport { pauseOnError } from '../lib/prompts.js';\r\n\r\n/** Processing options for makeicon */\r\ninterface ProcessOptions {\r\n\ttrim: boolean;\r\n\tmakeSquare: boolean;\r\n}\r\n\r\n/**\r\n * Convert PNG to ICO with multiple resolutions\r\n */\r\nexport async function run(inputRaw: string): Promise<boolean> {\r\n\t// Check dependencies\r\n\tif (!(await checkImageMagick())) {\r\n\t\terror('ImageMagick not found. Please install it:');\r\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\r\n\t\tawait pauseOnError();\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Normalize path\r\n\tconst input = normalizePath(inputRaw);\r\n\r\n\tif (!existsSync(input)) {\r\n\t\terror(`File not found: ${input}`);\r\n\t\tawait pauseOnError();\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Get file info\r\n\tconst fileInfo = getFileInfo(input);\r\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\r\n\tconst tempTrimmed = `${fileInfo.dirname}/${fileInfo.filename}_trimmed.png`;\r\n\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square.png`;\r\n\tconst tempScaled = `${fileInfo.dirname}/${fileInfo.filename}_scaled.png`;\r\n\r\n\theader('PicLet Make Icon');\r\n\r\n\t// Get original dimensions\r\n\twip('Analyzing image...');\r\n\tconst dims = await getDimensions(input);\r\n\tif (!dims) {\r\n\t\twipDone(false, 'Failed to read image');\r\n\t\treturn false;\r\n\t}\r\n\twipDone(true, `Original size: ${dims[0]}x${dims[1]}`);\r\n\r\n\t// Step 1: Trim transparent areas\r\n\twip('Trimming transparent areas...');\r\n\tif (!(await trim(input, tempTrimmed))) {\r\n\t\twipDone(false, 'Trim failed');\r\n\t\tcleanup(tempTrimmed);\r\n\t\treturn false;\r\n\t}\r\n\twipDone(true, 'Trimmed');\r\n\r\n\t// Step 2: Make square\r\n\twip('Making square...');\r\n\tif (!(await squarify(tempTrimmed, tempSquare))) {\r\n\t\twipDone(false, 'Square padding failed');\r\n\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempTrimmed);\r\n\twipDone(true, 'Made square');\r\n\r\n\t// Step 3: Scale to 512px for best quality source\r\n\twip('Scaling to 512px...');\r\n\tif (!(await scaleToSize(tempSquare, tempScaled, 512))) {\r\n\t\twipDone(false, 'Scaling failed');\r\n\t\tcleanup(tempSquare, tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempSquare);\r\n\twipDone(true, 'Scaled to 512x512');\r\n\r\n\t// Step 4: Create ICO with multiple resolutions\r\n\twip('Creating icon (256, 128, 64, 48, 32, 16)...');\r\n\tif (!(await createIco(tempScaled, output))) {\r\n\t\twipDone(false, 'Icon creation failed');\r\n\t\tcleanup(tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempScaled);\r\n\twipDone(true, 'Icon created');\r\n\r\n\tconsole.log('');\r\n\tsuccess(`Output: ${output}`);\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * Process image for icon creation (shared logic)\r\n */\r\nasync function processForIcon(\r\n\tinput: string,\r\n\toutput: string,\r\n\toptions: ProcessOptions,\r\n\tlogs?: Array<{ type: string; message: string }>,\r\n): Promise<boolean> {\r\n\tconst fileInfo = getFileInfo(input);\r\n\tconst tempTrimmed = `${fileInfo.dirname}/${fileInfo.filename}_trimmed.png`;\r\n\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square.png`;\r\n\tconst tempScaled = `${fileInfo.dirname}/${fileInfo.filename}_scaled.png`;\r\n\r\n\tlet currentInput = input;\r\n\r\n\t// Step 1: Trim (optional)\r\n\tif (options.trim) {\r\n\t\tlogs?.push({ type: 'info', message: 'Trimming transparent areas...' });\r\n\t\tif (!(await trim(currentInput, tempTrimmed))) {\r\n\t\t\tcleanup(tempTrimmed);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tcurrentInput = tempTrimmed;\r\n\t\tlogs?.push({ type: 'success', message: 'Trimmed' });\r\n\t}\r\n\r\n\t// Step 2: Squarify (optional)\r\n\tif (options.makeSquare) {\r\n\t\tlogs?.push({ type: 'info', message: 'Making square...' });\r\n\t\tif (!(await squarify(currentInput, tempSquare))) {\r\n\t\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tif (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\t\tcurrentInput = tempSquare;\r\n\t\tlogs?.push({ type: 'success', message: 'Made square' });\r\n\t}\r\n\r\n\t// Step 3: Scale to 512px\r\n\tlogs?.push({ type: 'info', message: 'Scaling to 512px...' });\r\n\tif (!(await scaleToSize(currentInput, tempScaled, 512))) {\r\n\t\tcleanup(tempTrimmed, tempSquare, tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tif (currentInput === tempSquare) cleanup(tempSquare);\r\n\telse if (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\tlogs?.push({ type: 'success', message: 'Scaled to 512x512' });\r\n\r\n\t// Step 4: Create ICO\r\n\tlogs?.push({ type: 'info', message: 'Creating icon (256, 128, 64, 48, 32, 16)...' });\r\n\tif (!(await createIco(tempScaled, output))) {\r\n\t\tcleanup(tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempScaled);\r\n\tlogs?.push({ type: 'success', message: 'Icon created' });\r\n\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * Generate preview image as base64 data URL\r\n */\r\nasync function generatePreview(\r\n\tinput: string,\r\n\toptions: ProcessOptions,\r\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\r\n\tconst tempDir = tmpdir();\r\n\tconst timestamp = Date.now();\r\n\tconst tempTrimmed = join(tempDir, `piclet-preview-trimmed-${timestamp}.png`);\r\n\tconst tempSquare = join(tempDir, `piclet-preview-square-${timestamp}.png`);\r\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\r\n\r\n\ttry {\r\n\t\tlet currentInput = input;\r\n\r\n\t\t// Trim if enabled\r\n\t\tif (options.trim) {\r\n\t\t\tif (!(await trim(currentInput, tempTrimmed))) {\r\n\t\t\t\tcleanup(tempTrimmed);\r\n\t\t\t\treturn { success: false, error: 'Trim failed' };\r\n\t\t\t}\r\n\t\t\tcurrentInput = tempTrimmed;\r\n\t\t}\r\n\r\n\t\t// Squarify if enabled\r\n\t\tif (options.makeSquare) {\r\n\t\t\tif (!(await squarify(currentInput, tempSquare))) {\r\n\t\t\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\t\t\treturn { success: false, error: 'Square failed' };\r\n\t\t\t}\r\n\t\t\tif (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\t\t\tcurrentInput = tempSquare;\r\n\t\t}\r\n\r\n\t\t// Scale to preview size (256px)\r\n\t\tif (!(await scaleToSize(currentInput, tempOutput, 256))) {\r\n\t\t\tcleanup(tempTrimmed, tempSquare, tempOutput);\r\n\t\t\treturn { success: false, error: 'Scale failed' };\r\n\t\t}\r\n\t\tif (currentInput === tempSquare) cleanup(tempSquare);\r\n\t\telse if (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\r\n\t\tconst buffer = readFileSync(tempOutput);\r\n\t\tconst base64 = buffer.toString('base64');\r\n\t\tconst imageData = `data:image/png;base64,${base64}`;\r\n\r\n\t\tconst dims = await getDimensions(tempOutput);\r\n\t\tcleanup(tempOutput);\r\n\r\n\t\treturn {\r\n\t\t\tsuccess: true,\r\n\t\t\timageData,\r\n\t\t\twidth: dims?.[0],\r\n\t\t\theight: dims?.[1],\r\n\t\t};\r\n\t} catch (err) {\r\n\t\tcleanup(tempTrimmed, tempSquare, tempOutput);\r\n\t\treturn { success: false, error: (err as Error).message };\r\n\t}\r\n}\r\n\r\n/**\r\n * Convert PNG to ICO (GUI mode)\r\n */\r\nexport async function runGUI(inputRaw: string): Promise<boolean> {\r\n\tconst input = normalizePath(inputRaw);\r\n\r\n\tif (!existsSync(input)) {\r\n\t\terror(`File not found: ${input}`);\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst dims = await getDimensions(input);\r\n\tif (!dims) {\r\n\t\terror('Failed to read image dimensions');\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst fileInfo = getFileInfo(input);\r\n\r\n\treturn startGuiServer({\r\n\t\thtmlFile: 'makeicon.html',\r\n\t\ttitle: 'PicLet - Make Icon',\r\n\t\timageInfo: {\r\n\t\t\tfilePath: input,\r\n\t\t\tfileName: basename(input),\r\n\t\t\twidth: dims[0],\r\n\t\t\theight: dims[1],\r\n\t\t\tborderColor: null,\r\n\t\t},\r\n\t\tdefaults: {\r\n\t\t\ttrim: true,\r\n\t\t\tmakeSquare: true,\r\n\t\t},\r\n\t\tonPreview: async (opts) => {\r\n\t\t\tconst options: ProcessOptions = {\r\n\t\t\t\ttrim: (opts.trim as boolean) ?? true,\r\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? true,\r\n\t\t\t};\r\n\t\t\treturn generatePreview(input, options);\r\n\t\t},\r\n\t\tonProcess: async (opts) => {\r\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\r\n\r\n\t\t\tif (!(await checkImageMagick())) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: false,\r\n\t\t\t\t\terror: 'ImageMagick not found',\r\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\tconst options: ProcessOptions = {\r\n\t\t\t\ttrim: (opts.trim as boolean) ?? true,\r\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? true,\r\n\t\t\t};\r\n\r\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\r\n\r\n\t\t\tconst success = await processForIcon(input, output, options, logs);\r\n\r\n\t\t\tif (success) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: true,\r\n\t\t\t\t\toutput: `${fileInfo.filename}.ico`,\r\n\t\t\t\t\tlogs,\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\treturn { success: false, error: 'Icon creation failed', logs };\r\n\t\t},\r\n\t});\r\n}\r\n\r\nexport const config = {\r\n\tid: 'makeicon',\r\n\tname: 'Make Icon',\r\n\ticon: 'makeicon.ico',\r\n\textensions: ['.png', '.gif'],\r\n};\r\n","/**\n * Unified PicLet tool - combines all tools with chaining support\n */\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, dirname, extname, join } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport { error } from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tcreateIco,\n\tcreateIcoFromMultiple,\n\textractAllFrames,\n\textractFirstFrame,\n\tgetBorderColor,\n\tgetDimensions,\n\tgetFrameCount,\n\tisMultiFrame,\n\tremoveBackground,\n\tremoveBackgroundBorderOnly,\n\tresize,\n\tscaleFillCrop,\n\tscaleToSize,\n\tscaleWithPadding,\n\tsquarify,\n\ttrim,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { loadPresets } from '../lib/presets.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface PreviewResult {\n\tsuccess: boolean;\n\timageData?: string;\n\twidth?: number;\n\theight?: number;\n\terror?: string;\n}\n\ninterface ProcessResult {\n\tsuccess: boolean;\n\toutput?: string;\n\terror?: string;\n\tlogs: Array<{ type: string; message: string }>;\n}\n\ninterface Dimension {\n\twidth: number;\n\theight: number;\n\tfilename?: string;\n}\n\ninterface ToolOptions {\n\ttools: string[];\n\toriginal?: boolean;\n\tremovebg?: { fuzz: number; trim: boolean; preserveInner: boolean };\n\tscale?: { width: number; height: number; makeSquare: boolean };\n\ticons?: {\n\t\ttrim: boolean;\n\t\tmakeSquare: boolean;\n\t\tico: boolean;\n\t\tweb: boolean;\n\t\tandroid: boolean;\n\t\tios: boolean;\n\t};\n\tstorepack?: { dimensions: Dimension[]; scaleMode: string; presetName?: string };\n}\n\n// Tool execution order (for chaining)\nconst TOOL_ORDER = ['removebg', 'scale', 'icons', 'storepack'];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Preview - Chains enabled tools\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function generateCombinedPreview(\n\tinput: string,\n\tborderColor: string | null,\n\topts: ToolOptions,\n): Promise<PreviewResult> {\n\tconst tempDir = tmpdir();\n\tconst ts = Date.now();\n\tconst temps: string[] = [];\n\n\tconst makeTempPath = (suffix: string) => {\n\t\tconst p = join(tempDir, `piclet-${ts}-${suffix}.png`);\n\t\ttemps.push(p);\n\t\treturn p;\n\t};\n\n\ttry {\n\t\tlet current = input;\n\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tif (isMultiFrame(input)) {\n\t\t\tconst frameTemp = makeTempPath('frame');\n\t\t\tif (await extractFirstFrame(input, frameTemp)) {\n\t\t\t\tcurrent = frameTemp;\n\t\t\t}\n\t\t}\n\n\t\t// If just showing original, scale it for preview and return\n\t\tif (opts.original || opts.tools.length === 0) {\n\t\t\tconst dims = await getDimensions(current);\n\t\t\tlet previewPath = current;\n\n\t\t\tif (dims && (dims[0] > 512 || dims[1] > 512)) {\n\t\t\t\tconst scaled = makeTempPath('orig-preview');\n\t\t\t\tconst targetSize = Math.min(512, Math.max(dims[0], dims[1]));\n\t\t\t\tif (await scaleToSize(current, scaled, targetSize)) {\n\t\t\t\t\tpreviewPath = scaled;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst buffer = readFileSync(previewPath);\n\t\t\tconst finalDims = await getDimensions(previewPath);\n\t\t\tcleanup(...temps);\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\t\twidth: finalDims?.[0] ?? dims?.[0],\n\t\t\t\theight: finalDims?.[1] ?? dims?.[1],\n\t\t\t};\n\t\t}\n\n\t\t// Get ordered list of active tools\n\t\tconst activeTools = TOOL_ORDER.filter(t => opts.tools.includes(t));\n\n\t\t// Process each tool in order\n\t\tfor (const tool of activeTools) {\n\t\t\tswitch (tool) {\n\t\t\t\tcase 'removebg': {\n\t\t\t\t\tconst rbOpts = opts.removebg!;\n\t\t\t\t\tconst out = makeTempPath('removebg');\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tif (rbOpts.preserveInner && borderColor) {\n\t\t\t\t\t\tsuccess = await removeBackgroundBorderOnly(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\t}\n\t\t\t\t\tif (!success && borderColor) {\n\t\t\t\t\t\tsuccess = await removeBackground(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\t}\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\t\treturn { success: false, error: 'Background removal failed' };\n\t\t\t\t\t}\n\n\t\t\t\t\t// Trim if enabled\n\t\t\t\t\tif (rbOpts.trim) {\n\t\t\t\t\t\tconst trimOut = makeTempPath('trim');\n\t\t\t\t\t\tif (await trim(out, trimOut)) {\n\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase 'scale': {\n\t\t\t\t\tconst scOpts = opts.scale!;\n\t\t\t\t\tconst out = makeTempPath('scale');\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tif (scOpts.makeSquare) {\n\t\t\t\t\t\tconst max = Math.max(scOpts.width, scOpts.height);\n\t\t\t\t\t\tsuccess = await scaleWithPadding(current, out, max, max);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsuccess = await resize(current, out, scOpts.width, scOpts.height);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\t\treturn { success: false, error: 'Scale failed' };\n\t\t\t\t\t}\n\t\t\t\t\tcurrent = out;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase 'icons': {\n\t\t\t\t\t// For preview, show what the icon source would look like after trim/squarify\n\t\t\t\t\tconst icOpts = opts.icons!;\n\n\t\t\t\t\tif (icOpts.trim && current === input) {\n\t\t\t\t\t\tconst trimOut = makeTempPath('ic-trim');\n\t\t\t\t\t\tif (await trim(current, trimOut)) {\n\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.makeSquare) {\n\t\t\t\t\t\tconst sqOut = makeTempPath('ic-sq');\n\t\t\t\t\t\tif (await squarify(current, sqOut)) {\n\t\t\t\t\t\t\tcurrent = sqOut;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// storepack doesn't affect preview\n\t\t\t}\n\t\t}\n\n\t\t// Scale down for preview display if needed\n\t\tconst dims = await getDimensions(current);\n\t\tlet previewPath = current;\n\n\t\tif (dims && (dims[0] > 512 || dims[1] > 512)) {\n\t\t\tconst scaled = makeTempPath('preview');\n\t\t\tconst targetSize = Math.min(512, Math.max(dims[0], dims[1]));\n\t\t\tif (await scaleToSize(current, scaled, targetSize)) {\n\t\t\t\tpreviewPath = scaled;\n\t\t\t}\n\t\t}\n\n\t\tconst buffer = readFileSync(previewPath);\n\t\tconst finalDims = await getDimensions(previewPath);\n\t\tcleanup(...temps);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\twidth: finalDims?.[0],\n\t\t\theight: finalDims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(...temps);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Process - Chains enabled tools and produces output\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function processCombined(\n\tinput: string,\n\tborderColor: string | null,\n\topts: ToolOptions,\n\tlogs: Array<{ type: string; message: string }>,\n): Promise<string[]> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputs: string[] = [];\n\tconst temps: string[] = [];\n\t// Preserve GIF extension for animated files, use PNG for others\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\n\tconst makeTempPath = (suffix: string) => {\n\t\tconst p = `${fileInfo.dirname}/${fileInfo.filename}_${suffix}${outputExt}`;\n\t\ttemps.push(p);\n\t\treturn p;\n\t};\n\n\tlet current = input;\n\tconst activeTools = TOOL_ORDER.filter(t => opts.tools.includes(t));\n\n\tfor (const tool of activeTools) {\n\t\tswitch (tool) {\n\t\t\tcase 'removebg': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Removing background...' });\n\t\t\t\tconst rbOpts = opts.removebg!;\n\t\t\t\tconst out = makeTempPath('nobg');\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (rbOpts.preserveInner && borderColor) {\n\t\t\t\t\tsuccess = await removeBackgroundBorderOnly(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tlogs.push({ type: 'warn', message: 'Border-only failed, trying full removal' });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!success && borderColor) {\n\t\t\t\t\tsuccess = await removeBackground(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t}\n\t\t\t\tif (!success) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Background removal failed' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\tlogs.push({ type: 'success', message: 'Background removed' });\n\n\t\t\t\tif (rbOpts.trim) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Trimming edges...' });\n\t\t\t\t\tconst trimOut = makeTempPath('trimmed');\n\t\t\t\t\tif (await trim(out, trimOut)) {\n\t\t\t\t\t\tcleanup(out);\n\t\t\t\t\t\ttemps.splice(temps.indexOf(out), 1);\n\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcurrent = out;\n\t\t\t\t}\n\n\t\t\t\t// If this is the last tool, save output\n\t\t\t\tif (activeTools.indexOf(tool) === activeTools.length - 1) {\n\t\t\t\t\tconst finalOut = `${fileInfo.dirname}/${fileInfo.filename}_nobg${outputExt}`;\n\t\t\t\t\trenameSync(current, finalOut);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t\toutputs.push(basename(finalOut));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'scale': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Scaling image...' });\n\t\t\t\tconst scOpts = opts.scale!;\n\t\t\t\tconst out = makeTempPath('scaled');\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (scOpts.makeSquare) {\n\t\t\t\t\tconst max = Math.max(scOpts.width, scOpts.height);\n\t\t\t\t\tsuccess = await scaleWithPadding(current, out, max, max);\n\t\t\t\t} else {\n\t\t\t\t\tsuccess = await resize(current, out, scOpts.width, scOpts.height);\n\t\t\t\t}\n\n\t\t\t\tif (!success) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Scale failed' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\tconst dims = await getDimensions(out);\n\t\t\t\tlogs.push({ type: 'success', message: `Scaled to ${dims?.[0]}×${dims?.[1]}` });\n\n\t\t\t\t// Clean up previous temp if it's not the input\n\t\t\t\tif (current !== input && temps.includes(current)) {\n\t\t\t\t\tcleanup(current);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t}\n\t\t\t\tcurrent = out;\n\n\t\t\t\t// If this is the last tool, save output\n\t\t\t\tif (activeTools.indexOf(tool) === activeTools.length - 1) {\n\t\t\t\t\tconst finalOut = `${fileInfo.dirname}/${fileInfo.filename}_scaled${outputExt}`;\n\t\t\t\t\trenameSync(current, finalOut);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t\toutputs.push(basename(finalOut));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'icons': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating icons...' });\n\t\t\t\tconst icOpts = opts.icons!;\n\n\t\t\t\t// Need at least one output format\n\t\t\t\tif (!icOpts.ico && !icOpts.web && !icOpts.android && !icOpts.ios) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'No output format selected' });\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\t// Prepare source - apply trim and squarify\n\t\t\t\tlet iconSource = current;\n\n\t\t\t\tif (icOpts.trim && current === input) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Trimming edges...' });\n\t\t\t\t\tconst trimOut = makeTempPath('ic-trim');\n\t\t\t\t\tif (await trim(current, trimOut)) {\n\t\t\t\t\t\ticonSource = trimOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (icOpts.makeSquare) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Making square...' });\n\t\t\t\t\tconst sqOut = makeTempPath('ic-sq');\n\t\t\t\t\tif (await squarify(iconSource, sqOut)) {\n\t\t\t\t\t\tif (iconSource !== current && iconSource !== input) cleanup(iconSource);\n\t\t\t\t\t\ticonSource = sqOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Made square' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Prepare high-res source (1024px for packs, 512px for ICO only)\n\t\t\t\tconst maxSize = icOpts.web || icOpts.android || icOpts.ios ? 1024 : 512;\n\t\t\t\tconst srcTemp = makeTempPath('ic-src');\n\t\t\t\tif (!(await scaleToSize(iconSource, srcTemp, maxSize))) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Failed to prepare icon source' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\tif (iconSource !== current && iconSource !== input) cleanup(iconSource);\n\n\t\t\t\tlet totalCount = 0;\n\n\t\t\t\t// Generate ICO file\n\t\t\t\tif (icOpts.ico) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Creating ICO file...' });\n\t\t\t\t\tconst icoOut = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\n\t\t\t\t\tif (await createIco(srcTemp, icoOut)) {\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'ICO: 6 sizes (256, 128, 64, 48, 32, 16)' });\n\t\t\t\t\t\toutputs.push(basename(icoOut));\n\t\t\t\t\t\ttotalCount += 6;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogs.push({ type: 'warn', message: 'ICO creation failed' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Generate icon packs (Web, Android, iOS)\n\t\t\t\tconst needsPacks = icOpts.web || icOpts.android || icOpts.ios;\n\t\t\t\tif (needsPacks) {\n\t\t\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\t\t\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\t\t\tif (icOpts.web) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating Web icons...' });\n\t\t\t\t\t\tconst webDir = `${outputDir}/web`;\n\t\t\t\t\t\tmkdirSync(webDir, { recursive: true });\n\n\t\t\t\t\t\t// Favicon.ico\n\t\t\t\t\t\tconst t16 = `${webDir}/.t16.png`, t32 = `${webDir}/.t32.png`, t48 = `${webDir}/.t48.png`;\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t16, 16);\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t32, 32);\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t48, 48);\n\t\t\t\t\t\tawait createIcoFromMultiple([t16, t32, t48], `${webDir}/favicon.ico`);\n\t\t\t\t\t\tcleanup(t16, t32, t48);\n\t\t\t\t\t\ttotalCount++;\n\n\t\t\t\t\t\tconst webIcons = [\n\t\t\t\t\t\t\t{ name: 'favicon-16x16.png', size: 16 }, { name: 'favicon-32x32.png', size: 32 },\n\t\t\t\t\t\t\t{ name: 'apple-touch-icon.png', size: 180 }, { name: 'android-chrome-192x192.png', size: 192 },\n\t\t\t\t\t\t\t{ name: 'android-chrome-512x512.png', size: 512 }, { name: 'mstile-150x150.png', size: 150 },\n\t\t\t\t\t\t];\n\t\t\t\t\t\tfor (const i of webIcons) {\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, `${webDir}/${i.name}`, i.size);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Web: 7 icons' });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.android) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating Android icons...' });\n\t\t\t\t\t\tconst androidDir = `${outputDir}/android`;\n\t\t\t\t\t\tconst androidIcons = [\n\t\t\t\t\t\t\t{ name: 'mipmap-mdpi/ic_launcher.png', size: 48 },\n\t\t\t\t\t\t\t{ name: 'mipmap-hdpi/ic_launcher.png', size: 72 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xhdpi/ic_launcher.png', size: 96 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xxhdpi/ic_launcher.png', size: 144 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xxxhdpi/ic_launcher.png', size: 192 },\n\t\t\t\t\t\t\t{ name: 'playstore-icon.png', size: 512 },\n\t\t\t\t\t\t];\n\t\t\t\t\t\tfor (const i of androidIcons) {\n\t\t\t\t\t\t\tconst p = `${androidDir}/${i.name}`;\n\t\t\t\t\t\t\tmkdirSync(dirname(p), { recursive: true });\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, p, i.size);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Android: 6 icons' });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.ios) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating iOS icons...' });\n\t\t\t\t\t\tconst iosDir = `${outputDir}/ios`;\n\t\t\t\t\t\tmkdirSync(iosDir, { recursive: true });\n\t\t\t\t\t\tconst iosSizes = [20, 29, 40, 58, 60, 76, 80, 87, 120, 152, 167, 180, 1024];\n\t\t\t\t\t\tfor (const s of iosSizes) {\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, `${iosDir}/AppIcon-${s}.png`, s);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: `iOS: ${iosSizes.length} icons` });\n\t\t\t\t\t}\n\n\t\t\t\t\toutputs.push(`${totalCount} icons → ${fileInfo.filename}_icons/`);\n\t\t\t\t}\n\n\t\t\t\tcleanup(srcTemp);\n\t\t\t\tlogs.push({ type: 'success', message: `Generated ${totalCount} total icons` });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'storepack': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating store assets...' });\n\t\t\t\tconst spOpts = opts.storepack!;\n\n\t\t\t\tif (!spOpts.dimensions || spOpts.dimensions.length === 0) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'No dimensions specified' });\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\tconst folderName = spOpts.presetName || 'assets';\n\t\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${folderName}`;\n\t\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\t\tlet count = 0;\n\t\t\t\tfor (const dim of spOpts.dimensions) {\n\t\t\t\t\tconst filename = dim.filename || `${dim.width}x${dim.height}.png`;\n\t\t\t\t\tconst out = join(outputDir, filename);\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tswitch (spOpts.scaleMode) {\n\t\t\t\t\t\tcase 'fill':\n\t\t\t\t\t\t\tsuccess = await scaleFillCrop(current, out, dim.width, dim.height);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'stretch':\n\t\t\t\t\t\t\tsuccess = await resize(current, out, dim.width, dim.height);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tsuccess = await scaleWithPadding(current, out, dim.width, dim.height);\n\t\t\t\t\t}\n\t\t\t\t\tif (success) count++;\n\t\t\t\t}\n\n\t\t\t\tlogs.push({ type: 'success', message: `Generated ${count}/${spOpts.dimensions.length} images` });\n\t\t\t\toutputs.push(`${count} images → ${fileInfo.filename}_${folderName}/`);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Cleanup any remaining temps\n\tcleanup(...temps);\n\treturn outputs;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Main GUI Entry Point\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tlet currentInput = normalizePath(inputRaw);\n\n\tif (!existsSync(currentInput)) {\n\t\terror(`File not found: ${currentInput}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(currentInput);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tlet currentBorderColor = await getBorderColor(currentInput);\n\tlet currentFrameCount = isMultiFrame(currentInput) ? await getFrameCount(currentInput) : 1;\n\tconst presets = loadPresets();\n\n\t// Helper to generate frame thumbnail\n\tasync function generateFrameThumbnail(frameIndex: number): Promise<{ success: boolean; imageData?: string; error?: string }> {\n\t\tconst tempDir = tmpdir();\n\t\tconst tempOutput = join(tempDir, `piclet-frame-${Date.now()}-${frameIndex}.png`);\n\t\ttry {\n\t\t\tif (!(await extractFirstFrame(currentInput, tempOutput, frameIndex))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\t// Scale down for thumbnail\n\t\t\tconst thumbOutput = join(tempDir, `piclet-thumb-${Date.now()}-${frameIndex}.png`);\n\t\t\tawait scaleToSize(tempOutput, thumbOutput, 96);\n\t\t\tconst buffer = readFileSync(thumbOutput);\n\t\t\tcleanup(tempOutput, thumbOutput);\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tcleanup(tempOutput);\n\t\t\treturn { success: false, error: (err as Error).message };\n\t\t}\n\t}\n\n\t// Helper to generate processed frame preview (for thumbnails)\n\tasync function generateFramePreview(\n\t\tframeIndex: number,\n\t\topts: ToolOptions,\n\t): Promise<{ success: boolean; imageData?: string; error?: string }> {\n\t\tconst tempDir = tmpdir();\n\t\tconst ts = Date.now();\n\t\tconst frameFile = join(tempDir, `piclet-fp-${ts}-${frameIndex}.png`);\n\t\tconst temps: string[] = [frameFile];\n\n\t\ttry {\n\t\t\t// Extract single frame\n\t\t\tif (!(await extractFirstFrame(currentInput, frameFile, frameIndex))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\n\t\t\tlet current = frameFile;\n\n\t\t\t// Apply tools in order\n\t\t\tconst activeTools = ['removebg', 'scale', 'icons'].filter(t => opts.tools.includes(t));\n\n\t\t\tfor (const tool of activeTools) {\n\t\t\t\tconst tempOut = join(tempDir, `piclet-fp-${ts}-${frameIndex}-${tool}.png`);\n\t\t\t\ttemps.push(tempOut);\n\n\t\t\t\tswitch (tool) {\n\t\t\t\t\tcase 'removebg': {\n\t\t\t\t\t\tconst rbOpts = opts.removebg!;\n\t\t\t\t\t\tlet success = false;\n\t\t\t\t\t\tif (rbOpts.preserveInner && currentBorderColor) {\n\t\t\t\t\t\t\tsuccess = await removeBackgroundBorderOnly(current, tempOut, currentBorderColor, rbOpts.fuzz);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!success && currentBorderColor) {\n\t\t\t\t\t\t\tsuccess = await removeBackground(current, tempOut, currentBorderColor, rbOpts.fuzz);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (success) {\n\t\t\t\t\t\t\tif (rbOpts.trim) {\n\t\t\t\t\t\t\t\tconst trimOut = join(tempDir, `piclet-fp-${ts}-${frameIndex}-trim.png`);\n\t\t\t\t\t\t\t\ttemps.push(trimOut);\n\t\t\t\t\t\t\t\tif (await trim(tempOut, trimOut)) {\n\t\t\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurrent = tempOut;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcurrent = tempOut;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'scale': {\n\t\t\t\t\t\tconst scOpts = opts.scale!;\n\t\t\t\t\t\tif (scOpts.makeSquare) {\n\t\t\t\t\t\t\tconst max = Math.max(scOpts.width, scOpts.height);\n\t\t\t\t\t\t\tif (await scaleWithPadding(current, tempOut, max, max)) {\n\t\t\t\t\t\t\t\tcurrent = tempOut;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (await resize(current, tempOut, scOpts.width, scOpts.height)) {\n\t\t\t\t\t\t\t\tcurrent = tempOut;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'icons': {\n\t\t\t\t\t\tconst icOpts = opts.icons!;\n\t\t\t\t\t\tif (icOpts.trim) {\n\t\t\t\t\t\t\tconst trimOut = join(tempDir, `piclet-fp-${ts}-${frameIndex}-ictrim.png`);\n\t\t\t\t\t\t\ttemps.push(trimOut);\n\t\t\t\t\t\t\tif (await trim(current, trimOut)) {\n\t\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (icOpts.makeSquare) {\n\t\t\t\t\t\t\tif (await squarify(current, tempOut)) {\n\t\t\t\t\t\t\t\tcurrent = tempOut;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Scale down for thumbnail\n\t\t\tconst thumbOut = join(tempDir, `piclet-fp-${ts}-${frameIndex}-thumb.png`);\n\t\t\ttemps.push(thumbOut);\n\t\t\tawait scaleToSize(current, thumbOut, 96);\n\n\t\t\tconst buffer = readFileSync(thumbOut);\n\t\t\tcleanup(...temps);\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tcleanup(...temps);\n\t\t\treturn { success: false, error: (err as Error).message };\n\t\t}\n\t}\n\n\treturn startGuiServer({\n\t\thtmlFile: 'piclet.html',\n\t\ttitle: 'PicLet',\n\t\timageInfo: {\n\t\t\tfilePath: currentInput,\n\t\t\tfileName: basename(currentInput),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: currentBorderColor,\n\t\t\tframeCount: currentFrameCount,\n\t\t},\n\t\tdefaults: {\n\t\t\t// Return full preset data for the UI\n\t\t\tpresets: presets.map(p => ({\n\t\t\t\tid: p.id,\n\t\t\t\tname: p.name,\n\t\t\t\tdescription: p.description,\n\t\t\t\ticons: p.icons,\n\t\t\t})),\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst toolOpts = opts as unknown as ToolOptions & { frameIndex?: number };\n\t\t\t// Allow empty tools array - will show original image\n\t\t\tif (!toolOpts.tools) {\n\t\t\t\ttoolOpts.tools = [];\n\t\t\t}\n\n\t\t\t// For GIFs with frameIndex, preview that specific frame\n\t\t\tif (isMultiFrame(currentInput) && typeof toolOpts.frameIndex === 'number') {\n\t\t\t\tconst tempDir = tmpdir();\n\t\t\t\tconst ts = Date.now();\n\t\t\t\tconst frameFile = join(tempDir, `piclet-prev-${ts}.png`);\n\n\t\t\t\tif (!(await extractFirstFrame(currentInput, frameFile, toolOpts.frameIndex))) {\n\t\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t\t}\n\n\t\t\t\t// Generate preview with the extracted frame\n\t\t\t\tconst result = await generateCombinedPreview(frameFile, currentBorderColor, toolOpts);\n\t\t\t\tcleanup(frameFile);\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\treturn generateCombinedPreview(currentInput, currentBorderColor, toolOpts);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\t\t\tconst toolOpts = opts as unknown as ToolOptions & {\n\t\t\t\texportMode?: 'frame' | 'all-frames' | 'gif';\n\t\t\t\tframeIndex?: number;\n\t\t\t};\n\n\t\t\t// Handle GIF export modes\n\t\t\tif (toolOpts.exportMode && isMultiFrame(currentInput)) {\n\t\t\t\treturn processGifExport(currentInput, currentBorderColor, toolOpts, logs);\n\t\t\t}\n\n\t\t\tif (!toolOpts.tools || toolOpts.tools.length === 0) {\n\t\t\t\treturn { success: false, error: 'No tools selected', logs };\n\t\t\t}\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst outputs = await processCombined(currentInput, currentBorderColor, toolOpts, logs);\n\n\t\t\tif (outputs.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: outputs.join('\\n'),\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn { success: false, error: 'Processing failed', logs };\n\t\t},\n\t\tonLoadImage: async (data) => {\n\t\t\ttry {\n\t\t\t\t// Save base64 data to temp file\n\t\t\t\tconst ext = extname(data.fileName) || '.png';\n\t\t\t\tconst tempPath = join(tmpdir(), `piclet-load-${Date.now()}${ext}`);\n\t\t\t\tconst buffer = Buffer.from(data.data, 'base64');\n\t\t\t\twriteFileSync(tempPath, buffer);\n\n\t\t\t\t// Get dimensions and border color\n\t\t\t\tconst newDims = await getDimensions(tempPath);\n\t\t\t\tif (!newDims) {\n\t\t\t\t\tcleanup(tempPath);\n\t\t\t\t\treturn { success: false, error: 'Failed to read image dimensions' };\n\t\t\t\t}\n\n\t\t\t\tconst newBorderColor = await getBorderColor(tempPath);\n\t\t\t\tconst newFrameCount = isMultiFrame(tempPath) ? await getFrameCount(tempPath) : 1;\n\n\t\t\t\t// Update current image\n\t\t\t\tcurrentInput = tempPath;\n\t\t\t\tcurrentBorderColor = newBorderColor;\n\t\t\t\tcurrentFrameCount = newFrameCount;\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tfilePath: tempPath,\n\t\t\t\t\tfileName: data.fileName,\n\t\t\t\t\twidth: newDims[0],\n\t\t\t\t\theight: newDims[1],\n\t\t\t\t\tborderColor: newBorderColor,\n\t\t\t\t\tframeCount: newFrameCount,\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\treturn { success: false, error: (err as Error).message };\n\t\t\t}\n\t\t},\n\t\tonFrameThumbnail: generateFrameThumbnail,\n\t\tonFramePreview: async (frameIndex, opts) => {\n\t\t\tconst toolOpts = opts as unknown as ToolOptions;\n\t\t\tif (!toolOpts.tools) toolOpts.tools = [];\n\t\t\treturn generateFramePreview(frameIndex, toolOpts);\n\t\t},\n\t});\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// GIF Export Processing\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function processGifExport(\n\tinput: string,\n\tborderColor: string | null,\n\topts: ToolOptions & { exportMode?: string; frameIndex?: number },\n\tlogs: Array<{ type: string; message: string }>,\n): Promise<{ success: boolean; output?: string; error?: string; logs: Array<{ type: string; message: string }> }> {\n\tif (!(await checkImageMagick())) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: 'ImageMagick not found',\n\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t};\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\tconst tempDir = tmpdir();\n\tconst ts = Date.now();\n\n\tswitch (opts.exportMode) {\n\t\tcase 'frame': {\n\t\t\t// Export single selected frame\n\t\t\tconst frameIndex = opts.frameIndex ?? 0;\n\t\t\tlogs.push({ type: 'info', message: `Exporting frame ${frameIndex + 1}...` });\n\n\t\t\tconst frameFile = join(tempDir, `piclet-export-${ts}.png`);\n\t\t\tif (!(await extractFirstFrame(input, frameFile, frameIndex))) {\n\t\t\t\tlogs.push({ type: 'error', message: 'Failed to extract frame' });\n\t\t\t\treturn { success: false, error: 'Failed to extract frame', logs };\n\t\t\t}\n\n\t\t\t// Apply tools if any\n\t\t\tlet outputFile = frameFile;\n\t\t\tif (opts.tools && opts.tools.length > 0) {\n\t\t\t\tconst processedLogs: Array<{ type: string; message: string }> = [];\n\t\t\t\tconst outputs = await processCombined(frameFile, borderColor, opts, processedLogs);\n\t\t\t\tlogs.push(...processedLogs);\n\n\t\t\t\tif (outputs.length === 0) {\n\t\t\t\t\tcleanup(frameFile);\n\t\t\t\t\treturn { success: false, error: 'Processing failed', logs };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Move to final location\n\t\t\tconst finalOutput = `${fileInfo.dirname}/${fileInfo.filename}_frame${frameIndex + 1}.png`;\n\t\t\tif (outputFile === frameFile) {\n\t\t\t\trenameSync(frameFile, finalOutput);\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'success', message: `Exported frame ${frameIndex + 1}` });\n\t\t\treturn { success: true, output: basename(finalOutput), logs };\n\t\t}\n\n\t\tcase 'all-frames': {\n\t\t\t// Export all frames as PNGs\n\t\t\tlogs.push({ type: 'info', message: 'Extracting all frames...' });\n\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_frames`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\tconst frames = await extractAllFrames(input, outputDir, 'frame');\n\n\t\t\tif (frames.length === 0) {\n\t\t\t\tlogs.push({ type: 'error', message: 'Failed to extract frames' });\n\t\t\t\treturn { success: false, error: 'Failed to extract frames', logs };\n\t\t\t}\n\n\t\t\t// Apply tools to each frame if any\n\t\t\tif (opts.tools && opts.tools.length > 0) {\n\t\t\t\tlogs.push({ type: 'info', message: `Processing ${frames.length} frames...` });\n\t\t\t\tfor (let i = 0; i < frames.length; i++) {\n\t\t\t\t\tconst frameLogs: Array<{ type: string; message: string }> = [];\n\t\t\t\t\tawait processCombined(frames[i], borderColor, opts, frameLogs);\n\t\t\t\t}\n\t\t\t\tlogs.push({ type: 'success', message: `Processed ${frames.length} frames` });\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'success', message: `Exported ${frames.length} frames` });\n\t\t\treturn { success: true, output: `${frames.length} frames -> ${fileInfo.filename}_frames/`, logs };\n\t\t}\n\n\t\tcase 'gif': {\n\t\t\t// Process and export as GIF\n\t\t\tlogs.push({ type: 'info', message: 'Processing GIF...' });\n\n\t\t\t// Use standard processing which handles GIFs with -coalesce\n\t\t\tconst outputs = await processCombined(input, borderColor, opts, logs);\n\n\t\t\tif (outputs.length > 0) {\n\t\t\t\treturn { success: true, output: outputs.join('\\n'), logs };\n\t\t\t}\n\n\t\t\treturn { success: false, error: 'Processing failed', logs };\n\t\t}\n\n\t\tdefault:\n\t\t\treturn { success: false, error: 'Unknown export mode', logs };\n\t}\n}\n\nexport const config = {\n\tid: 'piclet',\n\tname: 'PicLet',\n\ticon: 'banana.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico'],\n};\n","import { existsSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tgetBorderColor,\n\tgetDimensions,\n\tisMultiFrame,\n\treplaceColor,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tnumber as promptNumber,\n\tpauseOnError,\n\ttext as promptText,\n} from '../lib/prompts.js';\n\n/** Processing options for color replace */\ninterface ProcessOptions {\n\tfromColor: string;\n\ttoColor: string;\n\tfuzz: number;\n}\n\n/**\n * Core processing logic for color replace\n */\nasync function processImage(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_recolor${outputExt}`;\n\n\twip(`Replacing ${options.fromColor} with ${options.toColor}...`);\n\n\tconst success = await replaceColor(\n\t\tinput,\n\t\toutput,\n\t\toptions.fromColor,\n\t\toptions.toColor,\n\t\toptions.fuzz,\n\t);\n\n\tif (!success) {\n\t\twipDone(false, 'Color replacement failed');\n\t\treturn false;\n\t}\n\twipDone(true, 'Color replaced');\n\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tconsole.log(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tconsole.log(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(detectedColor: string | null): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Color Replacement:${RESET}`);\n\tconsole.log(` ${DIM}Replace one color with another${RESET}`);\n\tconsole.log(` ${DIM}Colors can be hex (#fff), named (white), or rgb(...)${RESET}`);\n\tconsole.log('');\n\n\tconst defaultFrom = detectedColor || '#ffffff';\n\tlet fromColor = await promptText('Color to replace', defaultFrom);\n\tif (!fromColor) {\n\t\tfromColor = defaultFrom;\n\t}\n\n\tconsole.log('');\n\tlet toColor = await promptText('New color', '#000000');\n\tif (!toColor) {\n\t\ttoColor = '#000000';\n\t}\n\n\tconsole.log('');\n\tconsole.log(`${BOLD}Fuzz Value:${RESET} Controls color matching sensitivity`);\n\tconsole.log(` ${DIM}0-10% = Exact match only${RESET}`);\n\tconsole.log(` ${DIM}10-30% = Similar colors${RESET}`);\n\tconsole.log(` ${DIM}30-50% = Wider range${RESET}`);\n\tconsole.log('');\n\n\tlet fuzz = await promptNumber('Fuzz value (0-100)', 10, 0, 100);\n\tif (fuzz < 0 || fuzz > 100) {\n\t\tfuzz = 10;\n\t}\n\n\treturn { fromColor, toColor, fuzz };\n}\n\n/**\n * Replace color in image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Recolor');\n\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\n\tconst borderColor = await getBorderColor(input);\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\tif (borderColor) {\n\t\tinfo(`Detected corner color: ${borderColor}`);\n\t}\n\n\tconst options = await collectOptionsCLI(borderColor);\n\n\tconsole.log('');\n\treturn processImage(input, options);\n}\n\n/**\n * Replace color in image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst borderColor = await getBorderColor(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'recolor.html',\n\t\ttitle: 'PicLet - Recolor',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor,\n\t\t},\n\t\tdefaults: {\n\t\t\tfromColor: borderColor || '#ffffff',\n\t\t\ttoColor: '#000000',\n\t\t\tfuzz: 10,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst fromColor = (opts.fromColor as string) ?? '#ffffff';\n\t\t\tconst toColor = (opts.toColor as string) ?? '#000000';\n\t\t\tconst fuzz = (opts.fuzz as number) ?? 10;\n\t\t\treturn generatePreview(input, { fromColor, toColor, fuzz });\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst fromColor = (opts.fromColor as string) ?? '#ffffff';\n\t\t\tconst toColor = (opts.toColor as string) ?? '#000000';\n\t\t\tconst fuzz = (opts.fuzz as number) ?? 10;\n\t\t\tconst options: ProcessOptions = { fromColor, toColor, fuzz };\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_recolor${outputExt}`;\n\n\t\t\tlogs.push({ type: 'info', message: `Replacing ${fromColor} → ${toColor}...` });\n\n\t\t\tconst success = await replaceColor(input, output, fromColor, toColor, fuzz);\n\n\t\t\tif (success) {\n\t\t\t\tlogs.push({ type: 'success', message: 'Color replaced' });\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Color replacement failed' });\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\tconst success = await replaceColor(\n\t\t\tpreviewInput,\n\t\t\ttempOutput,\n\t\t\toptions.fromColor,\n\t\t\toptions.toColor,\n\t\t\toptions.fuzz,\n\t\t);\n\n\t\tif (!success) {\n\t\t\tcleanup(tempSource, tempOutput);\n\t\t\treturn { success: false, error: 'Color replacement failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\n\t\tcleanup(tempSource, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempSource, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'recolor',\n\tname: 'Recolor',\n\ticon: 'recolor.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],\n};\n","import { existsSync, readFileSync, renameSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, dirname, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tgetBorderColor,\n\tgetDimensions,\n\tisMultiFrame,\n\tremoveBackground,\n\tremoveBackgroundBorderOnly,\n\tsquarify,\n\ttrim,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tconfirm as promptConfirm,\n\tisUsingDefaults,\n\tnumber as promptNumber,\n\tpauseOnError,\n} from '../lib/prompts.js';\n\n/** Processing options for remove-bg */\ninterface ProcessOptions {\n\tfuzz: number;\n\tdoTrim: boolean;\n\tpreserveInner: boolean;\n\tmakeSquare: boolean;\n}\n\n/**\n * Core processing logic for background removal\n */\nasync function processImage(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\t// Preserve original extension for GIF files, use PNG for others\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg${outputExt}`;\n\tconst tempFile = `${fileInfo.dirname}/${fileInfo.filename}_temp${outputExt}`;\n\n\twip('Removing background...');\n\n\tlet bgRemoved = false;\n\tif (options.preserveInner && borderColor) {\n\t\tbgRemoved = await removeBackgroundBorderOnly(\n\t\t\tinput,\n\t\t\ttempFile,\n\t\t\tborderColor,\n\t\t\toptions.fuzz,\n\t\t);\n\t\tif (!bgRemoved) {\n\t\t\twarn('Border-only removal failed, using standard method');\n\t\t}\n\t}\n\n\tif (!bgRemoved && borderColor) {\n\t\tbgRemoved = await removeBackground(input, tempFile, borderColor, options.fuzz);\n\t}\n\n\tif (!bgRemoved) {\n\t\twipDone(false, 'Background removal failed');\n\t\tcleanup(tempFile);\n\t\treturn false;\n\t}\n\twipDone(true, 'Background removed');\n\n\t// Trim if requested\n\tif (options.doTrim) {\n\t\twip('Trimming transparent edges...');\n\t\tif (await trim(tempFile, output)) {\n\t\t\twipDone(true, 'Trimmed');\n\t\t\tcleanup(tempFile);\n\t\t} else {\n\t\t\twipDone(false, 'Trim failed, keeping untrimmed');\n\t\t\trenameSync(tempFile, output);\n\t\t}\n\t} else {\n\t\trenameSync(tempFile, output);\n\t}\n\n\t// Make square if requested\n\tif (options.makeSquare) {\n\t\twip('Making square...');\n\t\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square_temp${outputExt}`;\n\t\tif (await squarify(output, tempSquare)) {\n\t\t\trenameSync(tempSquare, output);\n\t\t\twipDone(true, 'Made square');\n\t\t} else {\n\t\t\twipDone(false, 'Square padding failed');\n\t\t\tcleanup(tempSquare);\n\t\t}\n\t}\n\n\t// Final dimensions\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tsuccess(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tsuccess(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Fuzz Value:${RESET} Controls color matching strictness`);\n\tconsole.log(` ${DIM}0-10% = Only exact or very similar colors${RESET}`);\n\tconsole.log(` ${DIM}10-30% = Somewhat similar colors${RESET}`);\n\tconsole.log(` ${DIM}30-70% = Aggressive removal${RESET}`);\n\tconsole.log(` ${DIM}70-100% = May affect non-background areas${RESET}`);\n\tconsole.log('');\n\n\tlet fuzz = await promptNumber('Fuzz value (0-100)', 10, 0, 100);\n\tif (fuzz < 0 || fuzz > 100) {\n\t\twarn('Invalid fuzz value, using 10');\n\t\tfuzz = 10;\n\t}\n\n\tconsole.log('');\n\tconst doTrim = await promptConfirm(\n\t\t'Trim transparent edges after removal?',\n\t\ttrue,\n\t);\n\n\tconsole.log('');\n\tconst preserveInner = await promptConfirm(\n\t\t'Preserve inner areas of same color? (border-only removal)',\n\t\tfalse,\n\t);\n\n\tconsole.log('');\n\tconst makeSquare = await promptConfirm(\n\t\t'Make output square with transparent padding?',\n\t\tfalse,\n\t);\n\n\treturn { fuzz, doTrim, preserveInner, makeSquare };\n}\n\n\n/**\n * Remove solid background from image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Remove Background');\n\n\t// Get original dimensions\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\n\t// Detect border color\n\tconst borderColor = await getBorderColor(input);\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\tif (borderColor) {\n\t\tinfo(`Detected border color: ${borderColor}`);\n\t}\n\n\t// Collect options via CLI or TUI\n\tconst options = await collectOptionsCLI();\n\n\tconsole.log('');\n\treturn processImage(input, borderColor, options);\n}\n\n/**\n * Remove solid background from image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\t// Get original dimensions\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\t// Detect border color\n\tconst borderColor = await getBorderColor(input);\n\n\t// Load config defaults\n\tconst config = loadConfig();\n\tconst defaults = config.removeBg;\n\n\t// Start GUI server\n\treturn startGuiServer({\n\t\thtmlFile: 'remove-bg.html',\n\t\ttitle: 'PicLet - Remove Background',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor,\n\t\t},\n\t\tdefaults: {\n\t\t\tfuzz: defaults.fuzz,\n\t\t\ttrim: defaults.trim,\n\t\t\tpreserveInner: defaults.preserveInner,\n\t\t\tmakeSquare: defaults.makeSquare,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\tfuzz: (opts.fuzz as number) ?? defaults.fuzz,\n\t\t\t\tdoTrim: (opts.trim as boolean) ?? defaults.trim,\n\t\t\t\tpreserveInner: (opts.preserveInner as boolean) ?? defaults.preserveInner,\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? defaults.makeSquare,\n\t\t\t};\n\t\t\treturn generatePreview(input, borderColor, options);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\t// Check dependencies\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\tfuzz: (opts.fuzz as number) ?? defaults.fuzz,\n\t\t\t\tdoTrim: (opts.trim as boolean) ?? defaults.trim,\n\t\t\t\tpreserveInner: (opts.preserveInner as boolean) ?? defaults.preserveInner,\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? defaults.makeSquare,\n\t\t\t};\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;\n\n\t\t\t// Process the image\n\t\t\tlogs.push({ type: 'info', message: 'Removing background...' });\n\n\t\t\tconst success = await processImageSilent(input, borderColor, options, logs);\n\n\t\t\tif (success) {\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Silent version of processImage for GUI mode (logs to array instead of console)\n */\nasync function processImageSilent(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n\tlogs: Array<{ type: string; message: string }>,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\t// Preserve original extension for GIF files, use PNG for others\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg${outputExt}`;\n\tconst tempFile = `${fileInfo.dirname}/${fileInfo.filename}_temp${outputExt}`;\n\n\tlet bgRemoved = false;\n\tif (options.preserveInner && borderColor) {\n\t\tbgRemoved = await removeBackgroundBorderOnly(\n\t\t\tinput,\n\t\t\ttempFile,\n\t\t\tborderColor,\n\t\t\toptions.fuzz,\n\t\t);\n\t\tif (!bgRemoved) {\n\t\t\tlogs.push({ type: 'warn', message: 'Border-only removal failed, using standard method' });\n\t\t}\n\t}\n\n\tif (!bgRemoved && borderColor) {\n\t\tbgRemoved = await removeBackground(input, tempFile, borderColor, options.fuzz);\n\t}\n\n\tif (!bgRemoved) {\n\t\tlogs.push({ type: 'error', message: 'Background removal failed' });\n\t\tcleanup(tempFile);\n\t\treturn false;\n\t}\n\tlogs.push({ type: 'success', message: 'Background removed' });\n\n\t// Trim if requested\n\tif (options.doTrim) {\n\t\tlogs.push({ type: 'info', message: 'Trimming transparent edges...' });\n\t\tif (await trim(tempFile, output)) {\n\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\tcleanup(tempFile);\n\t\t} else {\n\t\t\tlogs.push({ type: 'warn', message: 'Trim failed, keeping untrimmed' });\n\t\t\trenameSync(tempFile, output);\n\t\t}\n\t} else {\n\t\trenameSync(tempFile, output);\n\t}\n\n\t// Make square if requested\n\tif (options.makeSquare) {\n\t\tlogs.push({ type: 'info', message: 'Making square...' });\n\t\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square_temp${outputExt}`;\n\t\tif (await squarify(output, tempSquare)) {\n\t\t\trenameSync(tempSquare, output);\n\t\t\tlogs.push({ type: 'success', message: 'Made square' });\n\t\t} else {\n\t\t\tlogs.push({ type: 'warn', message: 'Square padding failed' });\n\t\t\tcleanup(tempSquare);\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempFile = join(tempDir, `piclet-preview-${timestamp}.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}-out.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\t// Remove background\n\t\tlet bgRemoved = false;\n\t\tif (options.preserveInner && borderColor) {\n\t\t\tbgRemoved = await removeBackgroundBorderOnly(previewInput, tempFile, borderColor, options.fuzz);\n\t\t}\n\t\tif (!bgRemoved && borderColor) {\n\t\t\tbgRemoved = await removeBackground(previewInput, tempFile, borderColor, options.fuzz);\n\t\t}\n\t\tif (!bgRemoved) {\n\t\t\tcleanup(tempSource);\n\t\t\treturn { success: false, error: 'Background removal failed' };\n\t\t}\n\n\t\t// Trim if requested\n\t\tlet currentFile = tempFile;\n\t\tif (options.doTrim) {\n\t\t\tif (await trim(tempFile, tempOutput)) {\n\t\t\t\tcleanup(tempFile);\n\t\t\t\tcurrentFile = tempOutput;\n\t\t\t}\n\t\t}\n\n\t\t// Make square if requested\n\t\tif (options.makeSquare) {\n\t\t\tconst squareFile = join(tempDir, `piclet-preview-${timestamp}-sq.png`);\n\t\t\tif (await squarify(currentFile, squareFile)) {\n\t\t\t\tcleanup(currentFile);\n\t\t\t\tcurrentFile = squareFile;\n\t\t\t}\n\t\t}\n\n\t\t// Read as base64\n\t\tconst buffer = readFileSync(currentFile);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\t// Get dimensions\n\t\tconst dims = await getDimensions(currentFile);\n\n\t\t// Cleanup\n\t\tcleanup(currentFile, tempFile, tempOutput, tempSource);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempFile, tempOutput, tempSource);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'remove-bg',\n\tname: 'Remove Background',\n\ticon: 'removebg.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.ico', '.gif'],\n};\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\n\n/** PicLet configuration */\nexport interface PicLetConfig {\n\tremoveBg: {\n\t\tfuzz: number;\n\t\ttrim: boolean;\n\t\tpreserveInner: boolean;\n\t\tmakeSquare: boolean;\n\t};\n\trescale: {\n\t\tdefaultScale: number;\n\t\tmakeSquare: boolean;\n\t};\n\ticonpack: {\n\t\tplatforms: ('web' | 'android' | 'ios')[];\n\t};\n}\n\n/** Default configuration */\nexport const DEFAULT_CONFIG: PicLetConfig = {\n\tremoveBg: {\n\t\tfuzz: 10,\n\t\ttrim: true,\n\t\tpreserveInner: false,\n\t\tmakeSquare: false,\n\t},\n\trescale: {\n\t\tdefaultScale: 50,\n\t\tmakeSquare: false,\n\t},\n\ticonpack: {\n\t\tplatforms: ['web', 'android', 'ios'],\n\t},\n};\n\n/** Get config directory path */\nfunction getConfigDir(): string {\n\treturn join(homedir(), '.config', 'piclet');\n}\n\n/** Get config file path */\nexport function getConfigPath(): string {\n\treturn join(getConfigDir(), 'config.json');\n}\n\n/** Load configuration from file */\nexport function loadConfig(): PicLetConfig {\n\tconst configPath = getConfigPath();\n\n\tif (!existsSync(configPath)) {\n\t\treturn { ...DEFAULT_CONFIG };\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(configPath, 'utf-8');\n\t\tconst loaded = JSON.parse(content) as Partial<PicLetConfig>;\n\t\treturn {\n\t\t\tremoveBg: { ...DEFAULT_CONFIG.removeBg, ...loaded.removeBg },\n\t\t\trescale: { ...DEFAULT_CONFIG.rescale, ...loaded.rescale },\n\t\t\ticonpack: { ...DEFAULT_CONFIG.iconpack, ...loaded.iconpack },\n\t\t};\n\t} catch {\n\t\treturn { ...DEFAULT_CONFIG };\n\t}\n}\n\n/** Save configuration to file */\nexport function saveConfig(config: PicLetConfig): void {\n\tconst configPath = getConfigPath();\n\tconst configDir = dirname(configPath);\n\n\tif (!existsSync(configDir)) {\n\t\tmkdirSync(configDir, { recursive: true });\n\t}\n\n\twriteFileSync(configPath, JSON.stringify(config, null, 2));\n}\n\n/** Reset configuration to defaults */\nexport function resetConfig(): void {\n\tconst configPath = getConfigPath();\n\tconst configDir = dirname(configPath);\n\n\tif (!existsSync(configDir)) {\n\t\tmkdirSync(configDir, { recursive: true });\n\t}\n\n\twriteFileSync(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2));\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tgetDimensions,\n\tisMultiFrame,\n\tresize,\n\tscaleWithPadding,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tconfirm as promptConfirm,\n\tnumber as promptNumber,\n\tpauseOnError,\n} from '../lib/prompts.js';\n\n/** Processing options for rescale */\ninterface ProcessOptions {\n\twidth: number;\n\theight: number;\n\tmakeSquare: boolean;\n}\n\n/**\n * Scale image with optional padding\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Get file info\n\tconst fileInfo = getFileInfo(input);\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_scaled${fileInfo.extension}`;\n\n\theader('PicLet Scale Image');\n\n\t// Get original dimensions\n\twip('Reading image dimensions...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\tconst [origW, origH] = dims;\n\twipDone(true, `Original size: ${origW}x${origH}`);\n\n\t// Check if image is square\n\tif (origW !== origH) {\n\t\twarn(`Image is not square (${origW}x${origH})`);\n\t}\n\n\tconsole.log('');\n\tconsole.log(`${BOLD}Scaling Options:${RESET}`);\n\tconsole.log(\n\t\t` ${DIM}Enter 0 for auto-calculate based on other dimension${RESET}`,\n\t);\n\tconsole.log(\n\t\t` ${DIM}Enter single number for both to make square output${RESET}`,\n\t);\n\tconsole.log('');\n\n\t// Get target dimensions\n\tlet targetW = await promptNumber('Width (0 for auto)', 0, 0);\n\tlet targetH = await promptNumber('Height (0 for auto)', 0, 0);\n\n\t// Determine scaling mode\n\tlet makeSquare = false;\n\n\tif (targetW === 0 && targetH === 0) {\n\t\t// Default: scale to 50%\n\t\ttargetW = Math.floor(origW / 2);\n\t\ttargetH = Math.floor(origH / 2);\n\t\tinfo(`Using default: 50% scale (${targetW}x${targetH})`);\n\t} else if (targetW > 0 && targetH === 0) {\n\t\t// Width specified, calculate height\n\t\ttargetH = Math.floor((targetW * origH) / origW);\n\t\tinfo(`Calculated height: ${targetH}`);\n\t} else if (targetW === 0 && targetH > 0) {\n\t\t// Height specified, calculate width\n\t\ttargetW = Math.floor((targetH * origW) / origH);\n\t\tinfo(`Calculated width: ${targetW}`);\n\t}\n\n\t// Ask about square padding\n\tconsole.log('');\n\tmakeSquare = await promptConfirm(\n\t\t'Make output square with transparent padding?',\n\t\tfalse,\n\t);\n\n\tif (makeSquare) {\n\t\tconst maxDim = Math.max(targetW, targetH);\n\t\ttargetW = maxDim;\n\t\ttargetH = maxDim;\n\t\tinfo(`Output will be ${targetW}x${targetH} (square with padding)`);\n\t}\n\n\tconsole.log('');\n\twip('Scaling image...');\n\n\tlet scaled = false;\n\tif (makeSquare) {\n\t\t// Scale and add transparent padding for square output\n\t\tscaled = await scaleWithPadding(input, output, targetW, targetH);\n\t} else {\n\t\t// Standard resize\n\t\tscaled = await resize(input, output, targetW, targetH);\n\t}\n\n\tif (!scaled || !existsSync(output)) {\n\t\twipDone(false, 'Scaling failed');\n\t\treturn false;\n\t}\n\n\t// Get final dimensions\n\tconst finalDims = await getDimensions(output);\n\tif (finalDims) {\n\t\twipDone(true, `Scaled to ${finalDims[0]}x${finalDims[1]}`);\n\t} else {\n\t\twipDone(true, 'Scaled');\n\t}\n\n\tconsole.log('');\n\tsuccess(`Output: ${output}`);\n\treturn true;\n}\n\n/**\n * Scale image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'rescale.html',\n\t\ttitle: 'PicLet - Scale Image',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tmakeSquare: false,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\twidth: (opts.width as number) ?? Math.round(dims[0] / 2),\n\t\t\t\theight: (opts.height as number) ?? Math.round(dims[1] / 2),\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? false,\n\t\t\t};\n\t\t\treturn generatePreview(input, options);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\twidth: (opts.width as number) ?? Math.round(dims[0] / 2),\n\t\t\t\theight: (opts.height as number) ?? Math.round(dims[1] / 2),\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? false,\n\t\t\t};\n\n\t\t\tlogs.push({ type: 'info', message: `Scaling to ${options.width}x${options.height}...` });\n\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_scaled${fileInfo.extension}`;\n\t\t\tlet scaled = false;\n\n\t\t\tif (options.makeSquare) {\n\t\t\t\tconst maxDim = Math.max(options.width, options.height);\n\t\t\t\tscaled = await scaleWithPadding(input, output, maxDim, maxDim);\n\t\t\t} else {\n\t\t\t\tscaled = await resize(input, output, options.width, options.height);\n\t\t\t}\n\n\t\t\tif (scaled && existsSync(output)) {\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\tlogs.push({ type: 'success', message: 'Scaled successfully' });\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Scaling failed' });\n\t\t\treturn { success: false, error: 'Scaling failed', logs };\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\tlet scaled = false;\n\t\tlet targetW = options.width;\n\t\tlet targetH = options.height;\n\n\t\tif (options.makeSquare) {\n\t\t\tconst maxDim = Math.max(targetW, targetH);\n\t\t\ttargetW = maxDim;\n\t\t\ttargetH = maxDim;\n\t\t\tscaled = await scaleWithPadding(previewInput, tempOutput, targetW, targetH);\n\t\t} else {\n\t\t\tscaled = await resize(previewInput, tempOutput, targetW, targetH);\n\t\t}\n\n\t\tif (!scaled || !existsSync(tempOutput)) {\n\t\t\tcleanup(tempSource);\n\t\t\treturn { success: false, error: 'Scaling failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\t\tcleanup(tempSource, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempSource, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'rescale',\n\tname: 'Scale Image',\n\ticon: 'rescale.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],\n};\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { basename, join } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport { error, header, info, success, wip, wipDone } from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tgetDimensions,\n\tresize,\n\tscaleFillCrop,\n\tscaleWithPadding,\n\tsquarify,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { loadPresets, type Preset } from '../lib/presets.js';\nimport { pauseOnError, select as promptSelect } from '../lib/prompts.js';\n\ntype ScaleMode = 'fit' | 'fill' | 'stretch';\n\n/**\n * Scale image using the specified mode\n */\nasync function scaleImage(\n\tinput: string,\n\toutput: string,\n\twidth: number,\n\theight: number,\n\tmode: ScaleMode,\n): Promise<boolean> {\n\tswitch (mode) {\n\t\tcase 'fill':\n\t\t\treturn scaleFillCrop(input, output, width, height);\n\t\tcase 'stretch':\n\t\t\treturn resize(input, output, width, height);\n\t\tcase 'fit':\n\t\tdefault:\n\t\t\treturn scaleWithPadding(input, output, width, height);\n\t}\n}\n\n/**\n * Generate images for a preset\n */\nasync function generatePresetImages(\n\tsourceImg: string,\n\toutputDir: string,\n\tpreset: Preset,\n\tscaleMode: ScaleMode = 'fit',\n\tlogs?: Array<{ type: string; message: string }>,\n): Promise<number> {\n\tlet failed = 0;\n\tconst total = preset.icons.length;\n\n\tfor (let i = 0; i < total; i++) {\n\t\tconst icon = preset.icons[i];\n\t\tconst outputPath = join(outputDir, icon.filename);\n\n\t\tif (logs) {\n\t\t\tlogs.push({ type: 'info', message: `[${i + 1}/${total}] ${icon.filename}` });\n\t\t} else {\n\t\t\twip(`[${i + 1}/${total}] Generating ${icon.filename}...`);\n\t\t}\n\n\t\tconst scaled = await scaleImage(\n\t\t\tsourceImg,\n\t\t\toutputPath,\n\t\t\ticon.width,\n\t\t\ticon.height,\n\t\t\tscaleMode,\n\t\t);\n\n\t\tif (scaled) {\n\t\t\tif (!logs) {\n\t\t\t\twipDone(true, `[${i + 1}/${total}] ${icon.filename} (${icon.width}x${icon.height})`);\n\t\t\t}\n\t\t} else {\n\t\t\tif (logs) {\n\t\t\t\tlogs.push({ type: 'error', message: `Failed: ${icon.filename}` });\n\t\t\t} else {\n\t\t\t\twipDone(false, `[${i + 1}/${total}] Failed: ${icon.filename}`);\n\t\t\t}\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Generate store assets (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\theader('PicLet Store Pack');\n\n\t// Analyze source image\n\twip('Analyzing source image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\twipDone(true, `Source: ${dims[0]}x${dims[1]}`);\n\n\t// Load presets\n\tconst presets = loadPresets();\n\tconst choices = presets.map((p) => ({\n\t\ttitle: p.name,\n\t\tvalue: p.id,\n\t\tdescription: p.description,\n\t}));\n\n\t// Select preset\n\tconsole.log('');\n\tconst selectedId = await promptSelect('Select target store:', choices, presets[0].id);\n\tconst preset = presets.find((p) => p.id === selectedId);\n\n\tif (!preset) {\n\t\terror('Preset not found');\n\t\treturn false;\n\t}\n\n\t// Create output directory\n\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${preset.id}`;\n\tmkdirSync(outputDir, { recursive: true });\n\tinfo(`Output: ${outputDir}`);\n\n\t// Prepare source (make square for consistent scaling)\n\tconsole.log('');\n\twip('Preparing source...');\n\tconst tempSource = join(outputDir, '.source.png');\n\n\tif (!(await squarify(input, tempSource))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\treturn false;\n\t}\n\twipDone(true, 'Source prepared');\n\n\t// Generate images\n\tconsole.log('');\n\theader(`Generating ${preset.name} Images`);\n\n\tconst failed = await generatePresetImages(tempSource, outputDir, preset);\n\tcleanup(tempSource);\n\n\tconsole.log('');\n\tif (failed === 0) {\n\t\tsuccess(`All ${preset.icons.length} images generated!`);\n\t} else {\n\t\terror(`${failed}/${preset.icons.length} images failed`);\n\t}\n\n\tinfo(`Output: ${outputDir}`);\n\treturn failed === 0;\n}\n\n/**\n * Generate store assets (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\tconst presets = loadPresets();\n\n\treturn startGuiServer({\n\t\thtmlFile: 'storepack.html',\n\t\ttitle: 'PicLet - Store Pack',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tpresets: presets.map((p) => ({\n\t\t\t\tid: p.id,\n\t\t\t\tname: p.name,\n\t\t\t\tdescription: p.description,\n\t\t\t\ticons: p.icons,\n\t\t\t})),\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst presetId = opts.preset as string;\n\t\t\tconst scaleMode = (opts.scaleMode as ScaleMode) || 'fit';\n\t\t\tconst preset = presets.find((p) => p.id === presetId);\n\n\t\t\tif (!preset) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'Preset not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'No preset selected' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Create output directory\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${preset.id}`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\t\t\tlogs.push({ type: 'info', message: `Output: ${outputDir}` });\n\t\t\tlogs.push({ type: 'info', message: `Scale mode: ${scaleMode}` });\n\n\t\t\t// Generate images directly from source\n\t\t\tlogs.push({ type: 'info', message: `Generating ${preset.icons.length} images...` });\n\t\t\tconst failed = await generatePresetImages(input, outputDir, preset, scaleMode, logs);\n\n\t\t\tif (failed === 0) {\n\t\t\t\tlogs.push({ type: 'success', message: `All ${preset.icons.length} images generated` });\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${preset.icons.length} images saved to ${fileInfo.filename}_${preset.id}/`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `${failed} image(s) failed`,\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\nexport const config = {\n\tid: 'storepack',\n\tname: 'Store Pack',\n\ticon: 'storepack.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif'],\n};\n","import { existsSync, readFileSync, renameSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tflipHorizontal,\n\tflipVertical,\n\tgetDimensions,\n\tisMultiFrame,\n\trotate,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tisUsingDefaults,\n\tpauseOnError,\n\tselect as promptSelect,\n} from '../lib/prompts.js';\n\n/** Transform operation types */\ntype TransformType = 'flip-h' | 'flip-v' | 'rotate-90' | 'rotate-180' | 'rotate-270';\n\n/** Processing options for transform */\ninterface ProcessOptions {\n\ttransform: TransformType;\n}\n\nconst TRANSFORM_LABELS: Record<TransformType, string> = {\n\t'flip-h': 'Flip Horizontal',\n\t'flip-v': 'Flip Vertical',\n\t'rotate-90': 'Rotate 90°',\n\t'rotate-180': 'Rotate 180°',\n\t'rotate-270': 'Rotate 270°',\n};\n\n/**\n * Core processing logic for transform\n */\nasync function processImage(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst suffix = options.transform.replace('-', '');\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_${suffix}${outputExt}`;\n\n\twip(`Applying ${TRANSFORM_LABELS[options.transform]}...`);\n\n\tlet success = false;\n\tswitch (options.transform) {\n\t\tcase 'flip-h':\n\t\t\tsuccess = await flipHorizontal(input, output);\n\t\t\tbreak;\n\t\tcase 'flip-v':\n\t\t\tsuccess = await flipVertical(input, output);\n\t\t\tbreak;\n\t\tcase 'rotate-90':\n\t\t\tsuccess = await rotate(input, output, 90);\n\t\t\tbreak;\n\t\tcase 'rotate-180':\n\t\t\tsuccess = await rotate(input, output, 180);\n\t\t\tbreak;\n\t\tcase 'rotate-270':\n\t\t\tsuccess = await rotate(input, output, 270);\n\t\t\tbreak;\n\t}\n\n\tif (!success) {\n\t\twipDone(false, 'Transform failed');\n\t\treturn false;\n\t}\n\twipDone(true, TRANSFORM_LABELS[options.transform]);\n\n\t// Final dimensions\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tconsole.log(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tconsole.log(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Transform Options:${RESET}`);\n\tconsole.log(` ${DIM}1. Flip Horizontal (mirror)${RESET}`);\n\tconsole.log(` ${DIM}2. Flip Vertical${RESET}`);\n\tconsole.log(` ${DIM}3. Rotate 90° clockwise${RESET}`);\n\tconsole.log(` ${DIM}4. Rotate 180°${RESET}`);\n\tconsole.log(` ${DIM}5. Rotate 270° clockwise${RESET}`);\n\tconsole.log('');\n\n\tconst transform = await promptSelect<TransformType>(\n\t\t'Select transform',\n\t\t[\n\t\t\t{ value: 'flip-h', title: 'Flip Horizontal' },\n\t\t\t{ value: 'flip-v', title: 'Flip Vertical' },\n\t\t\t{ value: 'rotate-90', title: 'Rotate 90°' },\n\t\t\t{ value: 'rotate-180', title: 'Rotate 180°' },\n\t\t\t{ value: 'rotate-270', title: 'Rotate 270°' },\n\t\t],\n\t\t'flip-h',\n\t);\n\n\treturn { transform: transform ?? 'flip-h' };\n}\n\n/**\n * Transform image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Transform');\n\n\t// Get original dimensions\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\t// Collect options via CLI\n\tconst options = await collectOptionsCLI();\n\n\tconsole.log('');\n\treturn processImage(input, options);\n}\n\n/**\n * Transform image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\treturn startGuiServer({\n\t\thtmlFile: 'transform.html',\n\t\ttitle: 'PicLet - Transform',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\ttransform: 'flip-h',\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst transform = (opts.transform as TransformType) ?? 'flip-h';\n\t\t\treturn generatePreview(input, { transform });\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst transform = (opts.transform as TransformType) ?? 'flip-h';\n\t\t\tconst options: ProcessOptions = { transform };\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\t\t\tconst suffix = transform.replace('-', '');\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_${suffix}${outputExt}`;\n\n\t\t\tlogs.push({ type: 'info', message: `Applying ${TRANSFORM_LABELS[transform]}...` });\n\n\t\t\tlet success = false;\n\t\t\tswitch (transform) {\n\t\t\t\tcase 'flip-h':\n\t\t\t\t\tsuccess = await flipHorizontal(input, output);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'flip-v':\n\t\t\t\t\tsuccess = await flipVertical(input, output);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'rotate-90':\n\t\t\t\t\tsuccess = await rotate(input, output, 90);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'rotate-180':\n\t\t\t\t\tsuccess = await rotate(input, output, 180);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'rotate-270':\n\t\t\t\t\tsuccess = await rotate(input, output, 270);\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (success) {\n\t\t\t\tlogs.push({ type: 'success', message: 'Transform applied' });\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Transform failed' });\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\tlet success = false;\n\t\tswitch (options.transform) {\n\t\t\tcase 'flip-h':\n\t\t\t\tsuccess = await flipHorizontal(previewInput, tempOutput);\n\t\t\t\tbreak;\n\t\t\tcase 'flip-v':\n\t\t\t\tsuccess = await flipVertical(previewInput, tempOutput);\n\t\t\t\tbreak;\n\t\t\tcase 'rotate-90':\n\t\t\t\tsuccess = await rotate(previewInput, tempOutput, 90);\n\t\t\t\tbreak;\n\t\t\tcase 'rotate-180':\n\t\t\t\tsuccess = await rotate(previewInput, tempOutput, 180);\n\t\t\t\tbreak;\n\t\t\tcase 'rotate-270':\n\t\t\t\tsuccess = await rotate(previewInput, tempOutput, 270);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (!success) {\n\t\t\tcleanup(tempSource, tempOutput);\n\t\t\treturn { success: false, error: 'Transform failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\n\t\tcleanup(tempSource, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempSource, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'transform',\n\tname: 'Transform',\n\ticon: 'transform.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico'],\n};\n","import * as border from '../tools/border.js';\nimport * as extractFrames from '../tools/extract-frames.js';\nimport * as filter from '../tools/filter.js';\nimport * as iconpack from '../tools/iconpack.js';\nimport * as makeicon from '../tools/makeicon.js';\nimport * as picletMain from '../tools/piclet-main.js';\nimport * as recolor from '../tools/recolor.js';\nimport * as removeBg from '../tools/remove-bg.js';\nimport * as rescale from '../tools/rescale.js';\nimport * as storepack from '../tools/storepack.js';\nimport * as transform from '../tools/transform.js';\n\n/** Tool configuration */\nexport interface ToolConfig {\n\tid: string;\n\tname: string;\n\ticon: string;\n\textensions: string[];\n}\n\n/** Tool with config and run function */\nexport interface Tool {\n\tconfig: ToolConfig;\n\trun: (file: string) => Promise<boolean>;\n\trunGUI?: (file: string) => Promise<boolean>;\n}\n\n/** Unified tool (GUI only) */\nexport interface UnifiedTool {\n\tconfig: ToolConfig;\n\trunGUI: (file: string) => Promise<boolean>;\n}\n\n/** All available tools (individual) */\nexport const tools: Tool[] = [\n\t{ config: makeicon.config, run: makeicon.run, runGUI: makeicon.runGUI },\n\t{ config: removeBg.config, run: removeBg.run, runGUI: removeBg.runGUI },\n\t{ config: rescale.config, run: rescale.run, runGUI: rescale.runGUI },\n\t{ config: iconpack.config, run: iconpack.run, runGUI: iconpack.runGUI },\n\t{ config: storepack.config, run: storepack.run, runGUI: storepack.runGUI },\n\t{ config: transform.config, run: transform.run, runGUI: transform.runGUI },\n\t{ config: filter.config, run: filter.run, runGUI: filter.runGUI },\n\t{ config: border.config, run: border.run, runGUI: border.runGUI },\n\t{ config: recolor.config, run: recolor.run, runGUI: recolor.runGUI },\n\t{ config: extractFrames.config, run: extractFrames.run, runGUI: extractFrames.runGUI },\n];\n\n/** Unified PicLet tool (all-in-one) */\nexport const picletTool: UnifiedTool = {\n\tconfig: picletMain.config,\n\trunGUI: picletMain.runGUI,\n};\n\n/** Tools that use TUI (terminal GUI) mode */\nexport const tuiTools = ['makeicon', 'remove-bg', 'rescale', 'iconpack', 'storepack', 'transform', 'filter', 'border', 'recolor', 'extract-frames'];\n\n/** Get tool by ID */\nexport function getTool(id: string): Tool | undefined {\n\treturn tools.find((t) => t.config.id === id);\n}\n\n/** Get all unique extensions from tools */\nexport function getAllExtensions(): string[] {\n\tconst extensions = new Set<string>();\n\tfor (const { config } of tools) {\n\t\tfor (const ext of config.extensions) {\n\t\t\textensions.add(ext);\n\t\t}\n\t}\n\treturn Array.from(extensions);\n}\n\n/** Get tools that support a given extension */\nexport function getToolsForExtension(extension: string): Tool[] {\n\treturn tools.filter((t) => t.config.extensions.includes(extension));\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { getConfigPath, loadConfig, resetConfig } from '../../lib/config.js';\n\nexport function registerConfigCommand(program: Command): void {\n\tconst configCmd = program\n\t\t.command('config')\n\t\t.description('Display current settings')\n\t\t.action(() => {\n\t\t\tconst config = loadConfig();\n\t\t\tconsole.log(chalk.white.bold('\\n PicLet Configuration'));\n\t\t\tconsole.log(chalk.gray(` ${getConfigPath()}\\n`));\n\t\t\tconsole.log(JSON.stringify(config, null, 2));\n\t\t\tconsole.log();\n\t\t});\n\n\tconfigCmd\n\t\t.command('reset')\n\t\t.description('Restore defaults')\n\t\t.action(() => {\n\t\t\tresetConfig();\n\t\t\tconsole.log(chalk.green('Configuration reset to defaults.'));\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as extractFrames from '../../tools/extract-frames.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerExtractFramesCommand(program: Command): void {\n\tprogram\n\t\t.command('extract-frames <files...>')\n\t\t.alias('frames')\n\t\t.description('Extract frames from animated GIF')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, extractFrames.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await extractFrames.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'extract-frames',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as filter from '../../tools/filter.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerFilterCommand(program: Command): void {\n\tprogram\n\t\t.command('filter <files...>')\n\t\t.description('Apply color filters (grayscale, sepia, etc.)')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, filter.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await filter.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'filter',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import type { Command } from 'commander';\nimport { showHelp } from '../index.js';\n\nexport function registerHelpCommand(program: Command): void {\n\tprogram\n\t\t.command('help')\n\t\t.description('Show help')\n\t\t.action(() => {\n\t\t\tshowHelp();\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as iconpack from '../../tools/iconpack.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerIconpackCommand(program: Command): void {\n\tprogram\n\t\t.command('iconpack <files...>')\n\t\t.description('Generate icon sets for Web, Android, iOS')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, iconpack.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await iconpack.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'iconpack',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\r\nimport type { Command } from 'commander';\r\nimport { showBanner } from '../../lib/banner.js';\r\nimport { wslToWindows } from '../../lib/paths.js';\r\nimport { isWSL, isWSLInteropEnabled } from '../../lib/registry.js';\r\nimport { generateRegFile, registerAllTools, unregisterAllTools } from '../registry.js';\r\nimport { tools } from '../tools.js';\r\n\r\nexport function registerInstallCommand(program: Command): void {\r\n\tprogram\r\n\t\t.command('install')\r\n\t\t.description('Install Windows shell context menu integration')\r\n\t\t.action(async () => {\r\n\t\t\tshowBanner();\r\n\t\t\tconsole.log(chalk.bold('Installing...\\n'));\r\n\r\n\t\t\tif (!isWSL()) {\r\n\t\t\t\tconsole.log(\r\n\t\t\t\t\tchalk.yellow('! Not running in WSL. Registry integration skipped.'),\r\n\t\t\t\t);\r\n\t\t\t\tconsole.log(\r\n\t\t\t\t\tchalk.yellow('! Run \"piclet install\" from WSL to add context menu.'),\r\n\t\t\t\t);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (!isWSLInteropEnabled()) {\r\n\t\t\t\tconsole.log(chalk.yellow('WSL Interop not available. Generating registry file...\\n'));\r\n\r\n\t\t\t\tconst regPath = await generateRegFile();\r\n\t\t\t\tconst winPath = wslToWindows(regPath);\r\n\r\n\t\t\t\tconsole.log(chalk.green('✓ Generated registry file:'));\r\n\t\t\t\tconsole.log(chalk.cyan(` ${winPath}\\n`));\r\n\t\t\t\tconsole.log(chalk.bold('To install, either:'));\r\n\t\t\t\tconsole.log(chalk.dim(' 1. Double-click the .reg file in Windows Explorer'));\r\n\t\t\t\tconsole.log(chalk.dim(` 2. Run in elevated PowerShell: reg import \"${winPath}\"`));\r\n\t\t\t\tconsole.log();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Clean up existing entries first\r\n\t\t\tconsole.log(chalk.dim('Removing old entries...'));\r\n\t\t\tawait unregisterAllTools();\r\n\t\t\tconsole.log();\r\n\r\n\t\t\tconst results = await registerAllTools();\r\n\t\t\tconst allSuccess = results.every((r) => r.success);\r\n\r\n\t\t\t// Display each tool with its supported extensions\r\n\t\t\tfor (const { config } of tools) {\r\n\t\t\t\tconst extList = config.extensions.join(', ');\r\n\t\t\t\tconsole.log(`${chalk.green('✓')} ${config.name} ${chalk.dim(`[${extList}]`)}`);\r\n\t\t\t}\r\n\r\n\t\t\tconsole.log();\r\n\t\t\tif (allSuccess) {\r\n\t\t\t\tconsole.log(\r\n\t\t\t\t\tchalk.green(`✓ Registered ${tools.length} tools for context menu.`),\r\n\t\t\t\t);\r\n\t\t\t} else {\r\n\t\t\t\tconst successCount = results.filter((r) => r.success).length;\r\n\t\t\t\tconsole.log(\r\n\t\t\t\t\tchalk.yellow(`! Registered ${successCount}/${results.length} entries.`),\r\n\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\tconsole.log(chalk.bold('\\nUsage:'));\r\n\t\t\tconsole.log(' Right-click any supported image in Windows Explorer.');\r\n\t\t\tconsole.log(' Multi-select supported for batch processing.');\r\n\t\t\tconsole.log();\r\n\t\t});\r\n}\r\n","import { exec } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\n/**\n * Check if running inside WSL\n */\nexport function isWSL(): boolean {\n\treturn (\n\t\tprocess.platform === 'linux' &&\n\t\t(process.env.WSL_DISTRO_NAME !== undefined ||\n\t\t\tprocess.env.WSLENV !== undefined)\n\t);\n}\n\n/**\n * Check if WSL interop is enabled (can run Windows executables)\n */\nexport function isWSLInteropEnabled(): boolean {\n\treturn existsSync('/proc/sys/fs/binfmt_misc/WSLInterop');\n}\n\n/**\n * Convert WSL path to Windows path\n */\nexport function wslToWindows(wslPath: string): string {\n\tconst match = wslPath.match(/^\\/mnt\\/([a-z])\\/(.*)$/i);\n\tif (match) {\n\t\tconst drive = match[1].toUpperCase();\n\t\tconst rest = match[2].replace(/\\//g, '\\\\');\n\t\treturn `${drive}:\\\\${rest}`;\n\t}\n\treturn wslPath;\n}\n\n/**\n * Convert Windows path to WSL path\n */\nexport function windowsToWsl(winPath: string): string {\n\tconst match = winPath.match(/^([A-Za-z]):\\\\(.*)$/);\n\tif (match) {\n\t\tconst drive = match[1].toLowerCase();\n\t\tconst rest = match[2].replace(/\\\\/g, '/');\n\t\treturn `/mnt/${drive}/${rest}`;\n\t}\n\treturn winPath;\n}\n\n/**\n * Get the directory where this module is located\n */\nexport function getModuleDir(): string {\n\tconst currentFile = fileURLToPath(import.meta.url);\n\treturn dirname(currentFile);\n}\n\n/**\n * Add a registry key with value\n */\nexport async function addRegistryKey(\n\tkeyPath: string,\n\tvalueName: string,\n\tvalue: string,\n\ttype = 'REG_SZ',\n): Promise<boolean> {\n\tconst valueArg = valueName ? `/v \"${valueName}\"` : '/ve';\n\t// Escape inner quotes for Windows command line\n\tconst escapedValue = value.replace(/\"/g, '\\\\\"');\n\tconst cmd = `reg.exe add \"${keyPath}\" ${valueArg} /t ${type} /d \"${escapedValue}\" /f`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch (error) {\n\t\tconst message = (error as Error).message;\n\t\t// Silently ignore WSL interop errors (can't run reg.exe)\n\t\tconst ignoredErrors = ['Exec format error', 'not found'];\n\t\tconst shouldIgnore = ignoredErrors.some((e) =>\n\t\t\tmessage.toLowerCase().includes(e.toLowerCase()),\n\t\t);\n\t\tif (!shouldIgnore) {\n\t\t\tconsole.error(`Failed to add registry key: ${keyPath}`);\n\t\t\tconsole.error(message);\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Delete a registry key\n */\nexport async function deleteRegistryKey(keyPath: string): Promise<boolean> {\n\tconst cmd = `reg.exe delete \"${keyPath}\" /f`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch (error) {\n\t\tconst message = (error as Error).message;\n\t\t// Silently ignore expected errors:\n\t\t// - \"unable to find\" = key doesn't exist\n\t\t// - \"Exec format error\" = WSL can't run reg.exe (interop disabled)\n\t\t// - \"not found\" = reg.exe not in PATH\n\t\tconst ignoredErrors = ['unable to find', 'Exec format error', 'not found'];\n\t\tconst shouldIgnore = ignoredErrors.some((e) =>\n\t\t\tmessage.toLowerCase().includes(e.toLowerCase()),\n\t\t);\n\t\tif (!shouldIgnore) {\n\t\t\tconsole.error(`Failed to delete registry key: ${keyPath}`);\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if a registry key exists\n */\nexport async function registryKeyExists(keyPath: string): Promise<boolean> {\n\tconst cmd = `reg.exe query \"${keyPath}\" 2>/dev/null`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","import { writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { wslToWindows } from '../lib/paths.js';\nimport { addRegistryKey, deleteRegistryKey } from '../lib/registry.js';\nimport { getAllExtensions, getToolsForExtension, picletTool, tuiTools } from './tools.js';\nimport { getDistDir, getMenuBasePath } from './utils.js';\n\n/** Tool registration result */\nexport interface RegistrationResult {\n\textension: string;\n\ttoolName: string;\n\tsuccess: boolean;\n}\n\n/** Register unified PicLet menu item directly on context menu (no submenu) */\nasync function registerUnifiedMenu(\n\textension: string,\n\ticonsDir: string,\n\tlauncherPath: string,\n): Promise<RegistrationResult> {\n\tconst basePath = `HKCU\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\n\t// Create direct PicLet menu item (not a submenu)\n\tconst menuSuccess = await addRegistryKey(basePath, 'MUIVerb', 'PicLet');\n\tconst iconSuccess = await addRegistryKey(basePath, 'Icon', `${iconsDirWin}\\\\banana.ico`);\n\n\t// Enable multi-select\n\tawait addRegistryKey(basePath, 'MultiSelectModel', 'Player');\n\n\t// Command - opens unified GUI\n\tconst commandValue = `wscript.exe //B \"${launcherWin}\" piclet \"%1\" -g`;\n\tconst cmdSuccess = await addRegistryKey(`${basePath}\\\\command`, '', commandValue);\n\n\treturn {\n\t\textension,\n\t\ttoolName: 'PicLet',\n\t\tsuccess: menuSuccess && iconSuccess && cmdSuccess,\n\t};\n}\n\n/** Register PicLet submenu for a single extension (legacy - individual tools) */\nasync function registerMenuForExtension(\n\textension: string,\n\ticonsDir: string,\n\tlauncherPath: string,\n): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\tconst basePath = getMenuBasePath(extension);\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\tconst extensionTools = getToolsForExtension(extension);\n\n\t// Create parent PicLet menu\n\tawait addRegistryKey(basePath, 'MUIVerb', 'PicLet');\n\tawait addRegistryKey(basePath, 'Icon', `${iconsDirWin}\\\\banana.ico`);\n\tawait addRegistryKey(basePath, 'SubCommands', '');\n\n\t// Create submenu for each tool\n\tfor (const { config } of extensionTools) {\n\t\tconst toolPath = `${basePath}\\\\shell\\\\${config.id}`;\n\n\t\tconst menuSuccess = await addRegistryKey(toolPath, 'MUIVerb', config.name);\n\t\tconst iconSuccess = await addRegistryKey(\n\t\t\ttoolPath,\n\t\t\t'Icon',\n\t\t\t`${iconsDirWin}\\\\${config.icon}`,\n\t\t);\n\n\t\t// Enable multi-select\n\t\tawait addRegistryKey(toolPath, 'MultiSelectModel', 'Player');\n\n\t\t// Command - use VBScript launcher for hidden cmd.exe window\n\t\tlet commandValue: string;\n\t\tif (tuiTools.includes(config.id)) {\n\t\t\t// GUI mode - opens Edge app window\n\t\t\tcommandValue = `wscript.exe //B \"${launcherWin}\" ${config.id} \"%1\" -g`;\n\t\t} else {\n\t\t\t// Run headless with defaults\n\t\t\tcommandValue = `wscript.exe //B \"${launcherWin}\" ${config.id} \"%1\" -y`;\n\t\t}\n\t\tconst cmdSuccess = await addRegistryKey(\n\t\t\t`${toolPath}\\\\command`,\n\t\t\t'',\n\t\t\tcommandValue,\n\t\t);\n\n\t\tresults.push({\n\t\t\textension,\n\t\t\ttoolName: config.name,\n\t\t\tsuccess: menuSuccess && iconSuccess && cmdSuccess,\n\t\t});\n\t}\n\n\treturn results;\n}\n\n/** Unregister PicLet menu for a single extension */\nasync function unregisterMenuForExtension(\n\textension: string,\n): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\tconst basePath = getMenuBasePath(extension);\n\tconst extensionTools = getToolsForExtension(extension);\n\n\t// Delete each tool's submenu\n\tfor (const { config } of extensionTools) {\n\t\tconst toolPath = `${basePath}\\\\shell\\\\${config.id}`;\n\t\tawait deleteRegistryKey(`${toolPath}\\\\command`);\n\t\tconst success = await deleteRegistryKey(toolPath);\n\n\t\tresults.push({\n\t\t\textension,\n\t\t\ttoolName: config.name,\n\t\t\tsuccess,\n\t\t});\n\t}\n\n\t// Delete the shell container\n\tawait deleteRegistryKey(`${basePath}\\\\shell`);\n\n\t// Delete parent PicLet menu\n\tawait deleteRegistryKey(basePath);\n\n\treturn results;\n}\n\n/** Register all tools - unified mode (single PicLet menu item) */\nexport async function registerAllTools(): Promise<RegistrationResult[]> {\n\tconst distDir = getDistDir();\n\tconst iconsDir = join(distDir, 'icons');\n\tconst launcherPath = join(distDir, 'launcher.vbs');\n\tconst results: RegistrationResult[] = [];\n\n\t// Register unified PicLet menu for each supported extension\n\tfor (const extension of picletTool.config.extensions) {\n\t\tconst result = await registerUnifiedMenu(extension, iconsDir, launcherPath);\n\t\tresults.push(result);\n\t}\n\n\treturn results;\n}\n\n/** Legacy tool names that may exist in older installations */\nconst LEGACY_TOOL_NAMES = [\n\t// Old direct menu items (various naming conventions)\n\t'Scale Image',\n\t'Resize Image',\n\t'Eale Image', // Corrupted entry\n\t'Remove Background',\n\t'Remove BG',\n\t'RemoveBG',\n\t'Make Icon',\n\t'MakeIcon',\n\t'Icon Pack',\n\t'IconPack',\n\t'Store Pack',\n\t'StorePack',\n\t'PicLet - Scale',\n\t'PicLet - Remove BG',\n\t'PicLet - Make Icon',\n\t'PicLet - Icon Pack',\n\t'PicLet Scale',\n\t'PicLet RemoveBG',\n\t// Tool IDs that might have been used as menu names\n\t'makeicon',\n\t'remove-bg',\n\t'removebg',\n\t'rescale',\n\t'scale',\n\t'iconpack',\n\t'storepack',\n\t'transform',\n\t'filter',\n\t'border',\n\t'recolor',\n];\n\n/** All extensions that might have legacy entries */\nconst ALL_IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico', '.webp', '.tiff', '.tif'];\n\n/** Clean up legacy registry entries from older installations */\nexport async function cleanupLegacyEntries(): Promise<{ removed: string[]; failed: string[] }> {\n\tconst removed: string[] = [];\n\tconst failed: string[] = [];\n\n\tfor (const ext of ALL_IMAGE_EXTENSIONS) {\n\t\tconst shellBase = `HKCU\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${ext}\\\\shell`;\n\n\t\tfor (const legacyName of LEGACY_TOOL_NAMES) {\n\t\t\tconst keyPath = `${shellBase}\\\\${legacyName}`;\n\n\t\t\t// Try to delete the command subkey first\n\t\t\tawait deleteRegistryKey(`${keyPath}\\\\command`);\n\n\t\t\t// Then delete the main key\n\t\t\tconst success = await deleteRegistryKey(keyPath);\n\t\t\tif (success) {\n\t\t\t\tremoved.push(`${ext} → ${legacyName}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { removed, failed };\n}\n\n/** Unregister all tools */\nexport async function unregisterAllTools(): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\n\t// Unregister from all extensions (both unified and legacy)\n\tconst allExts = new Set([...getAllExtensions(), ...picletTool.config.extensions]);\n\tfor (const extension of allExts) {\n\t\tconst basePath = getMenuBasePath(extension);\n\n\t\t// Try to delete any submenus (legacy)\n\t\tconst extResults = await unregisterMenuForExtension(extension);\n\t\tresults.push(...extResults);\n\n\t\t// Also delete the unified command if it exists\n\t\tawait deleteRegistryKey(`${basePath}\\\\command`);\n\t\tawait deleteRegistryKey(basePath);\n\t}\n\n\treturn results;\n}\n\n/**\n * Escape a string value for .reg file format\n */\nfunction escapeRegValue(value: string): string {\n\treturn value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Generate registry content for unified PicLet menu\n */\nfunction generateRegContent(): string {\n\tconst distDir = getDistDir();\n\tconst iconsDir = join(distDir, 'icons');\n\tconst launcherPath = join(distDir, 'launcher.vbs');\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\n\tconst lines: string[] = ['Windows Registry Editor Version 5.00', ''];\n\n\t// Register unified PicLet menu for each supported extension\n\tfor (const extension of picletTool.config.extensions) {\n\t\tconst basePath = `HKEY_CURRENT_USER\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n\n\t\tlines.push(`[${basePath}]`);\n\t\tlines.push(`\"MUIVerb\"=\"${escapeRegValue('PicLet')}\"`);\n\t\tlines.push(`\"Icon\"=\"${escapeRegValue(`${iconsDirWin}\\\\banana.ico`)}\"`);\n\t\tlines.push('\"MultiSelectModel\"=\"Player\"');\n\t\tlines.push('');\n\n\t\t// Command - opens unified GUI\n\t\tconst commandValue = `wscript.exe //B \"${launcherWin}\" piclet \"%1\" -g`;\n\t\tlines.push(`[${basePath}\\\\command]`);\n\t\tlines.push(`@=\"${escapeRegValue(commandValue)}\"`);\n\t\tlines.push('');\n\t}\n\n\treturn lines.join('\\r\\n');\n}\n\n/**\n * Generate uninstall registry content (deletion entries)\n */\nfunction generateUninstallRegContent(): string {\n\tconst lines: string[] = ['Windows Registry Editor Version 5.00', ''];\n\n\t// Delete from all extensions (both unified and legacy)\n\tconst allExts = new Set([...getAllExtensions(), ...picletTool.config.extensions]);\n\tfor (const extension of allExts) {\n\t\tconst basePath = `HKEY_CURRENT_USER\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n\n\t\t// Delete the entire PicLet key (minus sign deletes)\n\t\tlines.push(`[-${basePath}]`);\n\t\tlines.push('');\n\t}\n\n\t// Also delete legacy entries from older installations\n\tfor (const ext of ALL_IMAGE_EXTENSIONS) {\n\t\tfor (const legacyName of LEGACY_TOOL_NAMES) {\n\t\t\tconst keyPath = `HKEY_CURRENT_USER\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${ext}\\\\shell\\\\${legacyName}`;\n\t\t\tlines.push(`[-${keyPath}]`);\n\t\t}\n\t\tlines.push('');\n\t}\n\n\treturn lines.join('\\r\\n');\n}\n\n/**\n * Generate a .reg file for installation\n * @returns Path to the generated .reg file\n */\nexport async function generateRegFile(): Promise<string> {\n\tconst distDir = getDistDir();\n\tconst regPath = join(distDir, 'piclet-install.reg');\n\tconst content = generateRegContent();\n\tawait writeFile(regPath, content, 'utf-8');\n\treturn regPath;\n}\n\n/**\n * Generate a .reg file for uninstallation\n * @returns Path to the generated .reg file\n */\nexport async function generateUninstallRegFile(): Promise<string> {\n\tconst distDir = getDistDir();\n\tconst regPath = join(distDir, 'piclet-uninstall.reg');\n\tconst content = generateUninstallRegContent();\n\tawait writeFile(regPath, content, 'utf-8');\n\treturn regPath;\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as makeicon from '../../tools/makeicon.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerMakeiconCommand(program: Command): void {\n\tprogram\n\t\t.command('makeicon <files...>')\n\t\t.description('Convert PNG to multi-resolution ICO file')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for confirmation')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, makeicon.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await makeicon.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'makeicon',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { picletTool } from '../tools.js';\nimport { validateExtensions } from '../utils.js';\n\nexport function registerPicletCommand(program: Command): void {\n\tprogram\n\t\t.command('piclet <file>')\n\t\t.description('Open unified PicLet window with all tools')\n\t\t.option('-g, --gui', 'Use GUI (default)')\n\t\t.action(async (file: string) => {\n\t\t\tconst { valid, invalid } = validateExtensions([file], picletTool.config.extensions);\n\t\t\tif (invalid.length > 0) {\n\t\t\t\tconsole.error(chalk.red(`Invalid file type: ${file}`));\n\t\t\t\tconsole.error(chalk.yellow(`Supported: ${picletTool.config.extensions.join(', ')}`));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tconst result = await picletTool.runGUI(valid[0]);\n\t\t\tprocess.exit(result ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as recolor from '../../tools/recolor.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerRecolorCommand(program: Command): void {\n\tprogram\n\t\t.command('recolor <files...>')\n\t\t.alias('replace-color')\n\t\t.description('Replace one color with another')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, recolor.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await recolor.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'recolor',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { clearOverrides, setOverrides } from '../../lib/prompts.js';\nimport * as removeBg from '../../tools/remove-bg.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerRemoveBgCommand(program: Command): void {\n\tprogram\n\t\t.command('remove-bg <files...>')\n\t\t.alias('removebg')\n\t\t.description('Remove solid background from image')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use TUI (terminal GUI) for options')\n\t\t.option('-f, --fuzz <percent>', 'Fuzz tolerance 0-100 (default: 10)')\n\t\t.option('-t, --trim', 'Trim transparent edges (default: true)')\n\t\t.option('--no-trim', 'Do not trim transparent edges')\n\t\t.option('-p, --preserve-inner', 'Preserve inner areas of same color')\n\t\t.option('-s, --square', 'Make output square with padding')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean; fuzz?: string; trim?: boolean; preserveInner?: boolean; square?: boolean }) => {\n\t\t\t// GUI mode - open HTML interface in browser\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, removeBg.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\t// Only process first file in GUI mode\n\t\t\t\tconst result = await removeBg.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\t// Set overrides from CLI args\n\t\t\tif (options.fuzz !== undefined) {\n\t\t\t\tsetOverrides({ 'fuzz': Number(options.fuzz) });\n\t\t\t}\n\t\t\tif (options.trim !== undefined) {\n\t\t\t\tsetOverrides({ 'trim': options.trim });\n\t\t\t}\n\t\t\tif (options.preserveInner) {\n\t\t\t\tsetOverrides({ 'preserve inner': true });\n\t\t\t}\n\t\t\tif (options.square) {\n\t\t\t\tsetOverrides({ 'square': true });\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'remove-bg',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tclearOverrides();\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as rescale from '../../tools/rescale.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerScaleCommand(program: Command): void {\n\tprogram\n\t\t.command('scale <files...>')\n\t\t.alias('rescale')\n\t\t.description('Resize image with optional padding')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, rescale.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await rescale.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'rescale',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as storepack from '../../tools/storepack.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerStorepackCommand(program: Command): void {\n\tprogram\n\t\t.command('storepack <files...>')\n\t\t.description('Generate assets for app stores (Windows, Unity, Steam, etc.)')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, storepack.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await storepack.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'storepack',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as transform from '../../tools/transform.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerTransformCommand(program: Command): void {\n\tprogram\n\t\t.command('transform <files...>')\n\t\t.alias('flip')\n\t\t.description('Flip or rotate images')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, transform.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await transform.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'transform',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { showBanner } from '../../lib/banner.js';\nimport { wslToWindows } from '../../lib/paths.js';\nimport { isWSL, isWSLInteropEnabled } from '../../lib/registry.js';\nimport { cleanupLegacyEntries, generateUninstallRegFile, unregisterAllTools } from '../registry.js';\n\nexport function registerUninstallCommand(program: Command): void {\n\tprogram\n\t\t.command('uninstall')\n\t\t.description('Remove Windows shell context menu integration')\n\t\t.action(async () => {\n\t\t\tshowBanner();\n\t\t\tconsole.log(chalk.bold('Uninstalling...\\n'));\n\n\t\t\tif (!isWSL()) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow('! Not running in WSL. Registry cleanup skipped.'),\n\t\t\t\t);\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t'! Run \"piclet uninstall\" from WSL to remove context menu.',\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isWSLInteropEnabled()) {\n\t\t\t\tconsole.log(chalk.yellow('WSL Interop not available. Generating registry file...\\n'));\n\n\t\t\t\tconst regPath = await generateUninstallRegFile();\n\t\t\t\tconst winPath = wslToWindows(regPath);\n\n\t\t\t\tconsole.log(chalk.green('✓ Generated uninstall registry file:'));\n\t\t\t\tconsole.log(chalk.cyan(` ${winPath}\\n`));\n\t\t\t\tconsole.log(chalk.bold('To uninstall, either:'));\n\t\t\t\tconsole.log(chalk.dim(' 1. Double-click the .reg file in Windows Explorer'));\n\t\t\t\tconsole.log(chalk.dim(` 2. Run in elevated PowerShell: reg import \"${winPath}\"`));\n\t\t\t\tconsole.log();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// First, clean up legacy entries from older installations\n\t\t\tconsole.log(chalk.dim('Cleaning up legacy entries...\\n'));\n\t\t\tconst legacyResult = await cleanupLegacyEntries();\n\n\t\t\tif (legacyResult.removed.length > 0) {\n\t\t\t\tconsole.log(chalk.yellow(`Removed ${legacyResult.removed.length} legacy entries:`));\n\t\t\t\tfor (const entry of legacyResult.removed) {\n\t\t\t\t\tconsole.log(` ${chalk.green('✓')} ${entry}`);\n\t\t\t\t}\n\t\t\t\tconsole.log();\n\t\t\t}\n\n\t\t\t// Then unregister current tools\n\t\t\tconst results = await unregisterAllTools();\n\t\t\tconst removedCount = results.filter((r) => r.success).length;\n\n\t\t\tfor (const result of results) {\n\t\t\t\tif (result.success) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`${chalk.green('✓')} Removed: ${result.extension} → ${result.toolName}`,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`${chalk.gray('-')} Skipped: ${result.extension} → ${result.toolName}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst totalRemoved = removedCount + legacyResult.removed.length;\n\t\t\tconsole.log();\n\t\t\tconsole.log(\n\t\t\t\tchalk.green(\n\t\t\t\t\t`✓ Cleanup complete. Removed ${totalRemoved} entries total.`,\n\t\t\t\t),\n\t\t\t);\n\t\t\tconsole.log(chalk.dim('\\nThanks for using PicLet!\\n'));\n\t\t});\n}\n"],"mappings":"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","names":["chalk","chalk","chalk","existsSync","readFileSync","basename","join","dirname","join","config","config","config","__dirname","dirname","resolve","join","existsSync","mkdirSync","dirname","dirname","existsSync","mkdirSync","dirname","success","existsSync","basename","join","readFileSync","extname","dirname","fileURLToPath","existsSync","mkdirSync","readFileSync","tmpdir","basename","join","run","existsSync","mkdirSync","runGUI","basename","tmpdir","join","readFileSync","config","existsSync","readFileSync","tmpdir","basename","join","processImage","success","collectOptionsCLI","run","existsSync","runGUI","basename","generatePreview","tmpdir","join","readFileSync","config","existsSync","mkdirSync","basename","dirname","dirname","existsSync","mkdirSync","run","runGUI","basename","config","existsSync","readFileSync","tmpdir","basename","join","run","existsSync","generatePreview","tmpdir","join","readFileSync","runGUI","basename","success","config","existsSync","mkdirSync","readFileSync","writeFileSync","tmpdir","basename","dirname","extname","join","tmpdir","join","dims","previewPath","buffer","readFileSync","finalDims","success","basename","mkdirSync","dirname","runGUI","existsSync","generateFramePreview","extname","writeFileSync","config","existsSync","readFileSync","tmpdir","basename","join","processImage","success","collectOptionsCLI","run","existsSync","runGUI","basename","generatePreview","tmpdir","join","readFileSync","config","existsSync","readFileSync","renameSync","tmpdir","basename","join","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","homedir","dirname","existsSync","mkdirSync","writeFileSync","processImage","renameSync","collectOptionsCLI","run","existsSync","runGUI","config","basename","generatePreview","success","tmpdir","join","readFileSync","existsSync","readFileSync","tmpdir","basename","join","run","existsSync","runGUI","basename","generatePreview","tmpdir","join","readFileSync","config","existsSync","mkdirSync","basename","join","join","run","existsSync","mkdirSync","runGUI","basename","config","existsSync","readFileSync","tmpdir","basename","join","processImage","success","collectOptionsCLI","run","existsSync","runGUI","basename","generatePreview","tmpdir","join","readFileSync","config","config","run","runGUI","config","fileURLToPath","dirname","extname","success","program","chalk","success","chalk","program","config","chalk","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","program","chalk","program","config","chalk","runGUI","success","chalk","exec","existsSync","dirname","fileURLToPath","promisify","execAsync","execAsync","error","join","config","success","join","program","chalk","config","chalk","program","config","chalk","runGUI","success","chalk","program","chalk","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","chalk","program","chalk","chalk","program","error","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/cli/index.ts","../src/lib/banner.ts","../src/cli/commands/border.ts","../src/tools/border.ts","../src/lib/gui-server.ts","../src/lib/presets.ts","../src/lib/logger.ts","../src/lib/magick.ts","../src/lib/paths.ts","../src/lib/prompts.ts","../src/cli/utils.ts","../src/tools/extract-frames.ts","../src/tools/filter.ts","../src/tools/iconpack.ts","../src/tools/makeicon.ts","../src/tools/piclet-main.ts","../src/tools/recolor.ts","../src/tools/remove-bg.ts","../src/lib/config.ts","../src/tools/rescale.ts","../src/tools/storepack.ts","../src/tools/transform.ts","../src/cli/tools.ts","../src/cli/commands/config.ts","../src/cli/commands/extract-frames.ts","../src/cli/commands/filter.ts","../src/cli/commands/help.ts","../src/cli/commands/iconpack.ts","../src/cli/commands/install.ts","../src/lib/registry.ts","../src/cli/registry.ts","../src/cli/commands/makeicon.ts","../src/cli/commands/piclet.ts","../src/cli/commands/recolor.ts","../src/cli/commands/remove-bg.ts","../src/cli/commands/scale.ts","../src/cli/commands/storepack.ts","../src/cli/commands/transform.ts","../src/cli/commands/uninstall.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport chalk from 'chalk';\nimport { createProgram } from './cli/index.js';\n\nconst program = createProgram();\n\nprogram.parseAsync(process.argv).catch((error) => {\n\tconsole.error(chalk.red(`Error: ${error.message}`));\n\tprocess.exit(1);\n});\n","import chalk from 'chalk';\nimport { Command } from 'commander';\nimport { showBanner } from '../lib/banner.js';\nimport { registerBorderCommand } from './commands/border.js';\nimport { registerConfigCommand } from './commands/config.js';\nimport { registerExtractFramesCommand } from './commands/extract-frames.js';\nimport { registerFilterCommand } from './commands/filter.js';\nimport { registerHelpCommand } from './commands/help.js';\nimport { registerIconpackCommand } from './commands/iconpack.js';\nimport { registerInstallCommand } from './commands/install.js';\nimport { registerMakeiconCommand } from './commands/makeicon.js';\nimport { registerPicletCommand } from './commands/piclet.js';\nimport { registerRecolorCommand } from './commands/recolor.js';\nimport { registerRemoveBgCommand } from './commands/remove-bg.js';\nimport { registerScaleCommand } from './commands/scale.js';\nimport { registerStorepackCommand } from './commands/storepack.js';\nimport { registerTransformCommand } from './commands/transform.js';\nimport { registerUninstallCommand } from './commands/uninstall.js';\n\nexport function showHelp(): void {\n\tshowBanner();\n\n\tconst dim = chalk.gray;\n\tconst cmd = chalk.cyan;\n\tconst arg = chalk.yellow;\n\tconst opt = chalk.green;\n\tconst head = chalk.white.bold;\n\n\tconsole.log(\n\t\t` ${head('Usage:')} piclet ${cmd('<command>')} ${arg('<file>')} ${opt('[options]')}`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Unified'));\n\tconsole.log(\n\t\t` ${cmd('piclet')} ${arg('<file>')} Open all tools in one window`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Individual Tools'));\n\tconsole.log(\n\t\t` ${cmd('makeicon')} ${arg('<file>')} Convert PNG to multi-resolution ICO`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('remove-bg')} ${arg('<file>')} Remove solid background from image`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('scale')} ${arg('<file>')} Resize image with optional padding`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('transform')} ${arg('<file>')} Flip or rotate images`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('filter')} ${arg('<file>')} Apply color filters (grayscale, sepia)`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('border')} ${arg('<file>')} Add solid color border`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('recolor')} ${arg('<file>')} Replace one color with another`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('frames')} ${arg('<file>')} Extract frames from animated GIF`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('iconpack')} ${arg('<file>')} Generate icon sets for Web/Android/iOS`,\n\t);\n\tconsole.log(\n\t\t` ${cmd('storepack')} ${arg('<file>')} Generate assets for app stores`,\n\t);\n\tconsole.log();\n\tconsole.log(head(' Setup'));\n\tconsole.log(\n\t\t` ${cmd('install')} Add Windows right-click menu`,\n\t);\n\tconsole.log(` ${cmd('uninstall')} Remove right-click menu`);\n\tconsole.log();\n\tconsole.log(head(' Config'));\n\tconsole.log(` ${cmd('config')} Display current settings`);\n\tconsole.log(` ${cmd('config reset')} Restore defaults`);\n\tconsole.log();\n\tconsole.log(head(' Examples'));\n\tconsole.log(` ${dim('$')} piclet ${cmd('piclet')} ${arg('image.png')} ${dim('# All tools in one window')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('makeicon')} ${arg('logo.png')} ${dim('# Interactive')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('makeicon')} ${arg('*.png')} ${opt('-y')} ${dim('# Batch with defaults')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('remove-bg')} ${arg('photo.png')} ${dim('# Interactive prompts')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('scale')} ${arg('image.jpg')} ${dim('# Interactive resize')}`);\n\tconsole.log(` ${dim('$')} piclet ${cmd('iconpack')} ${arg('icon.png')} ${opt('-y')} ${dim('# All platforms')}`);\n\tconsole.log();\n\tconsole.log(head(' Requirements'));\n\tconsole.log(' - WSL (Windows Subsystem for Linux)');\n\tconsole.log(' - ImageMagick: sudo apt install imagemagick');\n\tconsole.log();\n}\n\nexport function createProgram(): Command {\n\tconst program = new Command();\n\n\t// Override default help\n\tprogram.helpInformation = () => '';\n\tprogram.on('--help', () => {});\n\n\tprogram\n\t\t.name('piclet')\n\t\t.description('Image manipulation utility toolkit with Windows shell integration')\n\t\t.version('1.0.0')\n\t\t.action(() => {\n\t\t\tshowHelp();\n\t\t});\n\n\t// Register all commands\n\tregisterHelpCommand(program);\n\tregisterInstallCommand(program);\n\tregisterUninstallCommand(program);\n\tregisterMakeiconCommand(program);\n\tregisterRemoveBgCommand(program);\n\tregisterScaleCommand(program);\n\tregisterTransformCommand(program);\n\tregisterFilterCommand(program);\n\tregisterBorderCommand(program);\n\tregisterRecolorCommand(program);\n\tregisterExtractFramesCommand(program);\n\tregisterIconpackCommand(program);\n\tregisterStorepackCommand(program);\n\tregisterPicletCommand(program);\n\tregisterConfigCommand(program);\n\n\treturn program;\n}\n\nexport * from './tools.js';\nexport * from './utils.js';\nexport * from './registry.js';\n","import figlet from 'figlet';\nimport gradient from 'gradient-string';\n\nconst GRADIENT_COLORS = ['#22c55e', '#84cc16', '#eab308', '#fcd34d'];\n\n/**\n * Render the PicLet ASCII art logo with gradient colors\n */\nfunction renderLogo(): string {\n\tconst ascii = figlet.textSync('PicLet', {\n\t\tfont: 'Slant',\n\t\thorizontalLayout: 'default',\n\t});\n\treturn gradient(GRADIENT_COLORS)(ascii);\n}\n\n/**\n * Display the PicLet banner with gradient colors\n */\nexport function showBanner(\n\tsubtitle = 'Image manipulation utility toolkit with Windows shell integration',\n): void {\n\ttry {\n\t\tconsole.log(`\\n${renderLogo()}`);\n\t\tif (subtitle) {\n\t\t\tconst subtleGradient = gradient(['#a8a8a8', '#d4d4d4']);\n\t\t\tconsole.log(subtleGradient(` ${subtitle}\\n`));\n\t\t}\n\t} catch {\n\t\t// Fallback if rendering fails\n\t\tconsole.log('\\n\\x1b[1mPicLet\\x1b[0m');\n\t\tif (subtitle) {\n\t\t\tconsole.log(`\\x1b[2m ${subtitle}\\x1b[0m\\n`);\n\t\t}\n\t}\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as border from '../../tools/border.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerBorderCommand(program: Command): void {\n\tprogram\n\t\t.command('border <files...>')\n\t\t.description('Add solid color border to images')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, border.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await border.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'border',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\taddBorder,\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tgetDimensions,\n\tisMultiFrame,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tnumber as promptNumber,\n\tpauseOnError,\n\ttext as promptText,\n} from '../lib/prompts.js';\n\n/** Processing options for border */\ninterface ProcessOptions {\n\twidth: number;\n\tcolor: string;\n}\n\n/**\n * Core processing logic for border\n */\nasync function processImage(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_border${outputExt}`;\n\n\twip(`Adding ${options.width}px ${options.color} border...`);\n\n\tconst success = await addBorder(input, output, options.width, options.color);\n\n\tif (!success) {\n\t\twipDone(false, 'Border failed');\n\t\treturn false;\n\t}\n\twipDone(true, 'Border added');\n\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tconsole.log(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tconsole.log(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Border Settings:${RESET}`);\n\tconsole.log(` ${DIM}Width: How thick the border should be (in pixels)${RESET}`);\n\tconsole.log(` ${DIM}Color: Hex color (#fff), named color (white), or rgb(...)${RESET}`);\n\tconsole.log('');\n\n\tlet width = await promptNumber('Border width (px)', 10, 1, 200);\n\tif (width < 1) {\n\t\twidth = 10;\n\t}\n\n\tconsole.log('');\n\tlet color = await promptText('Border color', '#ffffff');\n\tif (!color) {\n\t\tcolor = '#ffffff';\n\t}\n\n\treturn { width, color };\n}\n\n/**\n * Add border to image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Border');\n\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\tconst options = await collectOptionsCLI();\n\n\tconsole.log('');\n\treturn processImage(input, options);\n}\n\n/**\n * Add border to image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\treturn startGuiServer({\n\t\thtmlFile: 'border.html',\n\t\ttitle: 'PicLet - Border',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\twidth: 10,\n\t\t\tcolor: '#ffffff',\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst width = (opts.width as number) ?? 10;\n\t\t\tconst color = (opts.color as string) ?? '#ffffff';\n\t\t\treturn generatePreview(input, { width, color });\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst width = (opts.width as number) ?? 10;\n\t\t\tconst color = (opts.color as string) ?? '#ffffff';\n\t\t\tconst options: ProcessOptions = { width, color };\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_border${outputExt}`;\n\n\t\t\tlogs.push({ type: 'info', message: `Adding ${width}px border...` });\n\n\t\t\tconst success = await addBorder(input, output, width, color);\n\n\t\t\tif (success) {\n\t\t\t\tlogs.push({ type: 'success', message: 'Border added' });\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Border failed' });\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\tconst success = await addBorder(previewInput, tempOutput, options.width, options.color);\n\n\t\tif (!success) {\n\t\t\tcleanup(tempSource, tempOutput);\n\t\t\treturn { success: false, error: 'Border failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\n\t\tcleanup(tempSource, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempSource, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'border',\n\tname: 'Add Border',\n\ticon: 'border.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],\n};\n","/**\n * GUI Server - Serves HTML interface and handles API calls\n */\nimport { spawn } from 'node:child_process';\nimport { createServer } from 'node:http';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport express from 'express';\nimport { deletePreset, savePreset, type Preset } from './presets.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/**\n * Signal the loading HTA to close by creating a temp file\n */\nfunction signalReady(): void {\n\t// Write ready signal to Windows temp directory using PowerShell (no window flash)\n\tspawn('powershell.exe', ['-WindowStyle', 'Hidden', '-Command', 'New-Item -Path $env:TEMP\\\\piclet-ready.tmp -ItemType File -Force | Out-Null'], {\n\t\tstdio: 'ignore',\n\t\twindowsHide: true,\n\t});\n}\n\n/**\n * Open URL in Edge app mode (standalone window without browser UI)\n */\nfunction openAppWindow(url: string): void {\n\t// Use PowerShell with hidden window to launch Edge - prevents terminal flash\n\tspawn('powershell.exe', [\n\t\t'-WindowStyle', 'Hidden',\n\t\t'-Command',\n\t\t`Start-Process msedge -ArgumentList '--app=${url}'`\n\t], {\n\t\tdetached: true,\n\t\tstdio: 'ignore',\n\t\twindowsHide: true,\n\t}).unref();\n\n\t// Signal loading window to close immediately - Edge starts fast\n\tsignalReady();\n}\n\nexport interface GuiServerOptions {\n\thtmlFile: string;\n\ttitle: string;\n\timageInfo: {\n\t\tfilePath: string;\n\t\tfileName: string;\n\t\twidth: number;\n\t\theight: number;\n\t\tborderColor: string | null;\n\t\tframeCount?: number;\n\t};\n\tdefaults: Record<string, unknown>;\n\tonPreview?: (options: Record<string, unknown>) => Promise<{\n\t\tsuccess: boolean;\n\t\timageData?: string; // Base64 data URL\n\t\twidth?: number;\n\t\theight?: number;\n\t\terror?: string;\n\t}>;\n\tonProcess: (options: Record<string, unknown>) => Promise<{\n\t\tsuccess: boolean;\n\t\toutput?: string;\n\t\toutputPath?: string; // Full path to single output file (for preview)\n\t\terror?: string;\n\t\tlogs: Array<{ type: string; message: string }>;\n\t}>;\n\tonLoadImage?: (data: { fileName: string; data: string; mimeType: string }) => Promise<{\n\t\tsuccess: boolean;\n\t\tfilePath?: string;\n\t\tfileName?: string;\n\t\twidth?: number;\n\t\theight?: number;\n\t\tborderColor?: string | null;\n\t\tframeCount?: number;\n\t\terror?: string;\n\t}>;\n\tonFrameThumbnail?: (frameIndex: number) => Promise<{\n\t\tsuccess: boolean;\n\t\timageData?: string;\n\t\terror?: string;\n\t}>;\n\tonFramePreview?: (frameIndex: number, options: Record<string, unknown>) => Promise<{\n\t\tsuccess: boolean;\n\t\timageData?: string;\n\t\terror?: string;\n\t}>;\n\tonSimplifyGif?: (skipFactor: number) => Promise<{\n\t\tsuccess: boolean;\n\t\tfilePath?: string;\n\t\tfileName?: string;\n\t\twidth?: number;\n\t\theight?: number;\n\t\tframeCount?: number;\n\t\terror?: string;\n\t}>;\n\tonDeleteFrame?: (frameIndex: number) => Promise<{\n\t\tsuccess: boolean;\n\t\tframeCount?: number;\n\t\terror?: string;\n\t}>;\n\tonReplaceFrame?: (frameIndex: number, imageData: string) => Promise<{\n\t\tsuccess: boolean;\n\t\tframeCount?: number;\n\t\terror?: string;\n\t}>;\n}\n\n/**\n * Start GUI server and open Edge app window\n * Returns a promise that resolves when the window is closed\n */\nexport function startGuiServer(options: GuiServerOptions): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst app = express();\n\t\tapp.use(express.json({ limit: '50mb' })); // Allow large base64 images\n\n\t\t// Handle JSON parse errors\n\t\tapp.use((err: Error, _req: express.Request, res: express.Response, next: express.NextFunction) => {\n\t\t\tif (err instanceof SyntaxError && 'body' in err) {\n\t\t\t\tres.status(400).json({ success: false, error: 'Invalid JSON: ' + err.message });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnext(err);\n\t\t});\n\n\t\tlet processResult: boolean | null = null;\n\t\tlet server: ReturnType<typeof createServer> | null = null;\n\n\t\t// Serve static files (CSS, JS, etc.)\n\t\tconst guiDir = join(__dirname, 'gui');\n\t\tconst iconsDir = join(__dirname, 'icons');\n\t\tapp.use(express.static(guiDir));\n\t\tapp.use('/icons', express.static(iconsDir));\n\n\t\t// Serve favicon from icons directory\n\t\tapp.get('/favicon.ico', (_req, res) => {\n\t\t\tres.sendFile(join(iconsDir, 'banana.ico'));\n\t\t});\n\n\t\t// API: Get image info and defaults\n\t\tapp.get('/api/info', (_req, res) => {\n\t\t\tres.json({\n\t\t\t\tfileName: options.imageInfo.fileName,\n\t\t\t\twidth: options.imageInfo.width,\n\t\t\t\theight: options.imageInfo.height,\n\t\t\t\tborderColor: options.imageInfo.borderColor,\n\t\t\t\tframeCount: options.imageInfo.frameCount || 1,\n\t\t\t\tdefaults: options.defaults,\n\t\t\t});\n\t\t});\n\n\t\t// API: Get frame thumbnail (for GIFs)\n\t\tapp.post('/api/frame-thumbnail', async (req, res) => {\n\t\t\tif (!options.onFrameThumbnail) {\n\t\t\t\tres.json({ success: false, error: 'Frame thumbnails not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst frameIndex = (req.body.frameIndex as number) ?? 0;\n\t\t\t\tconst result = await options.onFrameThumbnail(frameIndex);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Get processed frame preview (for GIFs)\n\t\tapp.post('/api/frame-preview', async (req, res) => {\n\t\t\tif (!options.onFramePreview) {\n\t\t\t\tres.json({ success: false, error: 'Frame preview not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst { frameIndex, ...opts } = req.body;\n\t\t\t\tconst result = await options.onFramePreview(frameIndex ?? 0, opts);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Simplify GIF by skipping frames\n\t\tapp.post('/api/simplify-gif', async (req, res) => {\n\t\t\tif (!options.onSimplifyGif) {\n\t\t\t\tres.json({ success: false, error: 'GIF simplification not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst skipFactor = (req.body.skipFactor as number) ?? 2;\n\t\t\t\tconst result = await options.onSimplifyGif(skipFactor);\n\t\t\t\tif (result.success) {\n\t\t\t\t\t// Update current image info\n\t\t\t\t\toptions.imageInfo.filePath = result.filePath!;\n\t\t\t\t\toptions.imageInfo.fileName = result.fileName!;\n\t\t\t\t\toptions.imageInfo.width = result.width!;\n\t\t\t\t\toptions.imageInfo.height = result.height!;\n\t\t\t\t\toptions.imageInfo.frameCount = result.frameCount;\n\t\t\t\t}\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Delete a frame from GIF\n\t\tapp.post('/api/delete-frame', async (req, res) => {\n\t\t\tif (!options.onDeleteFrame) {\n\t\t\t\tres.json({ success: false, error: 'Frame deletion not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst frameIndex = req.body.frameIndex as number;\n\t\t\t\tconst result = await options.onDeleteFrame(frameIndex);\n\t\t\t\tif (result.success) {\n\t\t\t\t\toptions.imageInfo.frameCount = result.frameCount;\n\t\t\t\t}\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Replace a frame in GIF\n\t\tapp.post('/api/replace-frame', async (req, res) => {\n\t\t\tif (!options.onReplaceFrame) {\n\t\t\t\tres.json({ success: false, error: 'Frame replacement not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst { frameIndex, imageData } = req.body;\n\t\t\t\tconst result = await options.onReplaceFrame(frameIndex, imageData);\n\t\t\t\tif (result.success) {\n\t\t\t\t\toptions.imageInfo.frameCount = result.frameCount;\n\t\t\t\t}\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Preview image (if supported)\n\t\tapp.post('/api/preview', async (req, res) => {\n\t\t\tif (!options.onPreview) {\n\t\t\t\tres.json({ success: false, error: 'Preview not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await options.onPreview(req.body);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (err as Error).message,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// API: Process image\n\t\tapp.post('/api/process', async (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst result = await options.onProcess(req.body);\n\t\t\t\tprocessResult = result.success;\n\t\t\t\t// Store output path for preview\n\t\t\t\tif (result.outputPath) {\n\t\t\t\t\t(options as { lastOutputPath?: string }).lastOutputPath = result.outputPath;\n\t\t\t\t} else {\n\t\t\t\t\t(options as { lastOutputPath?: string }).lastOutputPath = undefined;\n\t\t\t\t}\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tprocessResult = false;\n\t\t\t\tres.json({\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: (err as Error).message,\n\t\t\t\t\tlogs: [{ type: 'error', message: (err as Error).message }],\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// API: Load new image\n\t\tapp.post('/api/load', async (req, res) => {\n\t\t\tif (!options.onLoadImage) {\n\t\t\t\tres.json({ success: false, error: 'Load not supported' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await options.onLoadImage(req.body);\n\t\t\t\tif (result.success) {\n\t\t\t\t\t// Update current image info\n\t\t\t\t\toptions.imageInfo.filePath = result.filePath!;\n\t\t\t\t\toptions.imageInfo.fileName = result.fileName!;\n\t\t\t\t\toptions.imageInfo.width = result.width!;\n\t\t\t\t\toptions.imageInfo.height = result.height!;\n\t\t\t\t\toptions.imageInfo.borderColor = result.borderColor ?? null;\n\t\t\t\t}\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Cancel/close\n\t\tapp.post('/api/cancel', (_req, res) => {\n\t\t\tprocessResult = false;\n\t\t\tres.json({ ok: true });\n\t\t\tshutdown();\n\t\t});\n\n\t\t// API: Close after completion\n\t\tapp.post('/api/close', (_req, res) => {\n\t\t\tres.json({ ok: true });\n\t\t\tshutdown();\n\t\t});\n\n\t\t// API: Save preset\n\t\tapp.post('/api/save-preset', (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst preset = req.body as Preset;\n\t\t\t\tif (!preset.id || !preset.name || !preset.icons?.length) {\n\t\t\t\t\tres.json({ success: false, error: 'Invalid preset data' });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsavePreset(preset);\n\t\t\t\tres.json({ success: true });\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Delete preset\n\t\tapp.post('/api/delete-preset', (req, res) => {\n\t\t\ttry {\n\t\t\t\tconst { id } = req.body;\n\t\t\t\tif (!id) {\n\t\t\t\t\tres.json({ success: false, error: 'Missing preset ID' });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = deletePreset(id);\n\t\t\t\tres.json(result);\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Open URL in default browser\n\t\tapp.post('/api/open-url', (req, res) => {\n\t\t\tconst { url } = req.body;\n\t\t\tif (!url || typeof url !== 'string') {\n\t\t\t\tres.json({ success: false, error: 'Missing URL' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Use PowerShell Start-Process which opens in default browser\n\t\t\tspawn('powershell.exe', ['-WindowStyle', 'Hidden', '-Command', `Start-Process '${url}'`], {\n\t\t\t\tdetached: true,\n\t\t\t\tstdio: 'ignore',\n\t\t\t\twindowsHide: true,\n\t\t\t}).unref();\n\t\t\tres.json({ success: true });\n\t\t});\n\n\t\t// API: Get output file as base64 for preview\n\t\tapp.get('/api/output-preview', (_req, res) => {\n\t\t\tconst outputPath = (options as { lastOutputPath?: string }).lastOutputPath;\n\t\t\tif (!outputPath) {\n\t\t\t\tres.json({ success: false, error: 'No output file' });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst fs = require('node:fs');\n\t\t\t\tconst path = require('node:path');\n\t\t\t\tif (!fs.existsSync(outputPath)) {\n\t\t\t\t\tres.json({ success: false, error: 'Output file not found' });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst buffer = fs.readFileSync(outputPath);\n\t\t\t\tconst ext = path.extname(outputPath).toLowerCase();\n\t\t\t\tconst mimeTypes: Record<string, string> = {\n\t\t\t\t\t'.png': 'image/png',\n\t\t\t\t\t'.jpg': 'image/jpeg',\n\t\t\t\t\t'.jpeg': 'image/jpeg',\n\t\t\t\t\t'.gif': 'image/gif',\n\t\t\t\t\t'.ico': 'image/x-icon',\n\t\t\t\t};\n\t\t\t\tconst mimeType = mimeTypes[ext] || 'image/png';\n\t\t\t\tres.json({\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\timageData: `data:${mimeType};base64,${buffer.toString('base64')}`,\n\t\t\t\t\tisGif: ext === '.gif',\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tres.json({ success: false, error: (err as Error).message });\n\t\t\t}\n\t\t});\n\n\t\t// API: Open output folder in Explorer\n\t\tapp.post('/api/open-folder', (_req, res) => {\n\t\t\t// Use output path if available, otherwise fall back to input file directory\n\t\t\tconst outputPath = (options as { lastOutputPath?: string }).lastOutputPath;\n\t\t\tconst filePath = outputPath || options.imageInfo.filePath;\n\n\t\t\t// Convert WSL path to Windows path for explorer\n\t\t\t// /mnt/c/path -> C:\\path\n\t\t\tlet winPath = filePath;\n\t\t\tconst wslMatch = filePath.match(/^\\/mnt\\/([a-z])\\/(.*)$/);\n\t\t\tif (wslMatch) {\n\t\t\t\tconst drive = wslMatch[1].toUpperCase();\n\t\t\t\tconst rest = wslMatch[2].replace(/\\//g, '\\\\');\n\t\t\t\twinPath = `${drive}:\\\\${rest}`;\n\t\t\t}\n\n\t\t\t// Get directory from the file path\n\t\t\tconst lastSep = Math.max(winPath.lastIndexOf('\\\\'), winPath.lastIndexOf('/'));\n\t\t\tconst dir = lastSep > 0 ? winPath.substring(0, lastSep) : winPath;\n\n\t\t\t// Open folder and select the file if we have an output path\n\t\t\tconst explorerCmd = outputPath\n\t\t\t\t? `explorer.exe /select,\"${winPath}\"`\n\t\t\t\t: `explorer.exe \"${dir}\"`;\n\n\t\t\tspawn('powershell.exe', ['-WindowStyle', 'Hidden', '-Command', explorerCmd], {\n\t\t\t\tdetached: true,\n\t\t\t\tstdio: 'ignore',\n\t\t\t\twindowsHide: true,\n\t\t\t}).unref();\n\t\t\tres.json({ success: true });\n\t\t});\n\n\t\tfunction shutdown() {\n\t\t\tsetTimeout(() => {\n\t\t\t\tserver?.close();\n\t\t\t\tresolve(processResult ?? false);\n\t\t\t}, 100);\n\t\t}\n\n\t\t// Find available port and start\n\t\tserver = createServer(app);\n\t\tserver.listen(0, '127.0.0.1', () => {\n\t\t\tconst addr = server!.address();\n\t\t\tif (typeof addr === 'object' && addr) {\n\t\t\t\tconst port = addr.port;\n\t\t\t\tconst url = `http://127.0.0.1:${port}/${options.htmlFile}`;\n\n\t\t\t\topenAppWindow(url);\n\n\t\t\t\t// Auto-close after 5 minutes of inactivity\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (processResult === null) {\n\t\t\t\t\t\tshutdown();\n\t\t\t\t\t}\n\t\t\t\t}, 5 * 60 * 1000);\n\t\t\t}\n\t\t});\n\n\t\tserver.on('error', (err) => {\n\t\t\tconsole.error('GUI server error:', err.message);\n\t\t\tresolve(false);\n\t\t});\n\t});\n}\n","/**\n * Presets configuration for store icon packs\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\n\n/** Single icon definition in a preset */\nexport interface PresetIcon {\n\tfilename: string;\n\twidth: number;\n\theight: number;\n}\n\n/** A complete preset definition */\nexport interface Preset {\n\tid: string;\n\tname: string;\n\tdescription: string;\n\ticons: PresetIcon[];\n}\n\n/** Presets file structure */\nexport interface PresetsConfig {\n\tversion: number;\n\tpresets: Preset[];\n}\n\n/** Built-in presets */\nconst BUILT_IN_PRESETS: Preset[] = [\n\t// ── Game Asset Stores ──\n\t{\n\t\tid: 'unity-asset',\n\t\tname: 'Unity Asset Store',\n\t\tdescription: 'Unity Asset Store package images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-160.png', width: 160, height: 160 },\n\t\t\t{ filename: 'card-420x280.png', width: 420, height: 280 },\n\t\t\t{ filename: 'cover-1200x630.png', width: 1200, height: 630 },\n\t\t\t{ filename: 'screenshot-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'unreal-fab',\n\t\tname: 'Unreal / Fab',\n\t\tdescription: 'Unreal Marketplace & Fab assets',\n\t\ticons: [\n\t\t\t{ filename: 'icon-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'thumbnail-284.png', width: 284, height: 284 },\n\t\t\t{ filename: 'featured-894x488.png', width: 894, height: 488 },\n\t\t\t{ filename: 'gallery-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'godot-asset',\n\t\tname: 'Godot Asset Library',\n\t\tdescription: 'Godot Asset Library images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-64.png', width: 64, height: 64 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'screenshot-1280x720.png', width: 1280, height: 720 },\n\t\t\t{ filename: 'screenshot-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'blender-market',\n\t\tname: 'Blender Market',\n\t\tdescription: 'Blender Market product images',\n\t\ticons: [\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'thumbnail-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'preview-1920x1080.png', width: 1920, height: 1080 },\n\t\t],\n\t},\n\t{\n\t\tid: 'steam',\n\t\tname: 'Steam',\n\t\tdescription: 'Steam store assets',\n\t\ticons: [\n\t\t\t{ filename: 'capsule-small-231x87.png', width: 231, height: 87 },\n\t\t\t{ filename: 'capsule-main-616x353.png', width: 616, height: 353 },\n\t\t\t{ filename: 'header-460x215.png', width: 460, height: 215 },\n\t\t\t{ filename: 'hero-1920x620.png', width: 1920, height: 620 },\n\t\t\t{ filename: 'library-capsule-600x900.png', width: 600, height: 900 },\n\t\t\t{ filename: 'library-hero-3840x1240.png', width: 3840, height: 1240 },\n\t\t],\n\t},\n\t{\n\t\tid: 'itch-io',\n\t\tname: 'itch.io',\n\t\tdescription: 'itch.io game page assets',\n\t\ticons: [\n\t\t\t{ filename: 'cover-630x500.png', width: 630, height: 500 },\n\t\t\t{ filename: 'thumbnail-315x250.png', width: 315, height: 250 },\n\t\t\t{ filename: 'banner-960x540.png', width: 960, height: 540 },\n\t\t],\n\t},\n\t// ── Extensions & Packages ──\n\t{\n\t\tid: 'chrome-extension',\n\t\tname: 'Chrome Extension',\n\t\tdescription: 'Chrome Web Store extension icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-16.png', width: 16, height: 16 },\n\t\t\t{ filename: 'icon-32.png', width: 32, height: 32 },\n\t\t\t{ filename: 'icon-48.png', width: 48, height: 48 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'promo-440x280.png', width: 440, height: 280 },\n\t\t\t{ filename: 'promo-1400x560.png', width: 1400, height: 560 },\n\t\t],\n\t},\n\t{\n\t\tid: 'firefox-addon',\n\t\tname: 'Firefox Add-on',\n\t\tdescription: 'Firefox Add-ons icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-48.png', width: 48, height: 48 },\n\t\t\t{ filename: 'icon-96.png', width: 96, height: 96 },\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t],\n\t},\n\t{\n\t\tid: 'vscode-extension',\n\t\tname: 'VS Code Extension',\n\t\tdescription: 'VS Code Marketplace icons',\n\t\ticons: [\n\t\t\t{ filename: 'icon-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'icon-256.png', width: 256, height: 256 },\n\t\t],\n\t},\n\t{\n\t\tid: 'npm-package',\n\t\tname: 'npm Package',\n\t\tdescription: 'npm package icons',\n\t\ticons: [\n\t\t\t{ filename: 'logo-64.png', width: 64, height: 64 },\n\t\t\t{ filename: 'logo-128.png', width: 128, height: 128 },\n\t\t\t{ filename: 'logo-256.png', width: 256, height: 256 },\n\t\t\t{ filename: 'banner-1200x600.png', width: 1200, height: 600 },\n\t\t],\n\t},\n\t{\n\t\tid: 'windows-store',\n\t\tname: 'Windows Store',\n\t\tdescription: 'Microsoft Store app icons',\n\t\ticons: [\n\t\t\t{ filename: 'Square44x44Logo.png', width: 44, height: 44 },\n\t\t\t{ filename: 'Square150x150Logo.png', width: 150, height: 150 },\n\t\t\t{ filename: 'Square310x310Logo.png', width: 310, height: 310 },\n\t\t\t{ filename: 'Wide310x150Logo.png', width: 310, height: 150 },\n\t\t\t{ filename: 'StoreLogo-50.png', width: 50, height: 50 },\n\t\t\t{ filename: 'SplashScreen-620x300.png', width: 620, height: 300 },\n\t\t],\n\t},\n];\n\n/** Get presets file path */\nexport function getPresetsPath(): string {\n\tconst picletDir = join(homedir(), '.piclet');\n\treturn join(picletDir, 'presets.json');\n}\n\n/** Ensure presets directory exists */\nfunction ensurePresetsDir(): void {\n\tconst presetsPath = getPresetsPath();\n\tconst dir = dirname(presetsPath);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n}\n\n/** Load presets (built-in + user-defined) */\nexport function loadPresets(): Preset[] {\n\tconst presetsPath = getPresetsPath();\n\tlet userPresets: Preset[] = [];\n\n\tif (existsSync(presetsPath)) {\n\t\ttry {\n\t\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\t\tuserPresets = config.presets || [];\n\t\t} catch {\n\t\t\t// Ignore parse errors, use built-in only\n\t\t}\n\t}\n\n\t// Merge: built-in first, then user presets (user can override built-in by ID)\n\tconst presetMap = new Map<string, Preset>();\n\tfor (const preset of BUILT_IN_PRESETS) {\n\t\tpresetMap.set(preset.id, preset);\n\t}\n\tfor (const preset of userPresets) {\n\t\tpresetMap.set(preset.id, preset);\n\t}\n\n\treturn Array.from(presetMap.values());\n}\n\n/** Get a single preset by ID */\nexport function getPreset(id: string): Preset | undefined {\n\tconst presets = loadPresets();\n\treturn presets.find((p) => p.id === id);\n}\n\n/** Save user presets */\nexport function savePresets(presets: Preset[]): void {\n\tensurePresetsDir();\n\tconst config: PresetsConfig = {\n\t\tversion: 1,\n\t\tpresets,\n\t};\n\twriteFileSync(getPresetsPath(), JSON.stringify(config, null, 2));\n}\n\n/** Add or update a preset */\nexport function savePreset(preset: Preset): void {\n\tconst presetsPath = getPresetsPath();\n\tlet userPresets: Preset[] = [];\n\n\tif (existsSync(presetsPath)) {\n\t\ttry {\n\t\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\t\tuserPresets = config.presets || [];\n\t\t} catch {\n\t\t\t// Start fresh\n\t\t}\n\t}\n\n\t// Update or add\n\tconst idx = userPresets.findIndex((p) => p.id === preset.id);\n\tif (idx >= 0) {\n\t\tuserPresets[idx] = preset;\n\t} else {\n\t\tuserPresets.push(preset);\n\t}\n\n\tsavePresets(userPresets);\n}\n\n/** Get built-in preset IDs (for UI distinction) */\nexport function getBuiltInPresetIds(): string[] {\n\treturn BUILT_IN_PRESETS.map((p) => p.id);\n}\n\n/** Delete a user-defined preset by ID */\nexport function deletePreset(id: string): { success: boolean; error?: string } {\n\t// Cannot delete built-in presets\n\tif (BUILT_IN_PRESETS.some((p) => p.id === id)) {\n\t\treturn { success: false, error: 'Cannot delete built-in presets' };\n\t}\n\n\tconst presetsPath = getPresetsPath();\n\tif (!existsSync(presetsPath)) {\n\t\treturn { success: false, error: 'Preset not found' };\n\t}\n\n\ttry {\n\t\tconst data = readFileSync(presetsPath, 'utf-8');\n\t\tconst config: PresetsConfig = JSON.parse(data);\n\t\tconst userPresets = config.presets || [];\n\n\t\tconst idx = userPresets.findIndex((p) => p.id === id);\n\t\tif (idx < 0) {\n\t\t\treturn { success: false, error: 'Preset not found' };\n\t\t}\n\n\t\tuserPresets.splice(idx, 1);\n\t\tsavePresets(userPresets);\n\t\treturn { success: true };\n\t} catch {\n\t\treturn { success: false, error: 'Failed to delete preset' };\n\t}\n}\n","/**\n * Colored console output utilities\n */\n\n// ANSI color codes\nconst RED = '\\x1b[31m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst BLUE = '\\x1b[34m';\nconst CYAN = '\\x1b[36m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\n\n// Status symbols\nconst CHECK = '✓';\nconst CROSS = '✗';\nconst ARROW = '→';\nconst BULLET = '•';\nconst SPINNER = '⠋';\n\n/** Print success message with checkmark */\nexport function success(message: string): void {\n\tconsole.log(`${GREEN}${CHECK}${RESET} ${message}`);\n}\n\n/** Print error message with X */\nexport function error(message: string): void {\n\tconsole.log(`${RED}${CROSS}${RESET} ${message}`);\n}\n\n/** Print warning message */\nexport function warn(message: string): void {\n\tconsole.log(`${YELLOW}${BULLET}${RESET} ${message}`);\n}\n\n/** Print info message */\nexport function info(message: string): void {\n\tconsole.log(`${BLUE}${ARROW}${RESET} ${message}`);\n}\n\n/** Print step message (for multi-step processes) */\nexport function step(message: string): void {\n\tconsole.log(`${CYAN}${BULLET}${RESET} ${message}`);\n}\n\n/** Print header with separator */\nexport function header(title: string): void {\n\tconsole.log('');\n\tconsole.log(`${BOLD}${title}${RESET}`);\n\tconsole.log(`${DIM}${'─'.repeat(40)}${RESET}`);\n}\n\n/** Print separator line */\nexport function separator(): void {\n\tconsole.log(`${DIM}${'─'.repeat(40)}${RESET}`);\n}\n\n/** Work-in-progress indicator (inline, no newline) */\nexport function wip(message: string): void {\n\tprocess.stdout.write(`${YELLOW}${SPINNER}${RESET} ${message}`);\n}\n\n/** Complete a WIP indicator with result */\nexport function wipDone(isSuccess: boolean, message: string): void {\n\t// Clear line and print result\n\tprocess.stdout.write('\\r\\x1b[K');\n\tif (isSuccess) {\n\t\tsuccess(message);\n\t} else {\n\t\terror(message);\n\t}\n}\n\n/** Clear current line */\nexport function clearLine(): void {\n\tprocess.stdout.write('\\r\\x1b[K');\n}\n\nexport { RESET, BOLD, DIM, GREEN, RED, YELLOW, BLUE, CYAN };\n","import { exec } from 'node:child_process';\nimport { copyFileSync, existsSync, mkdirSync, unlinkSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\n/**\n * Get input path with frame selector for multi-frame formats (ICO)\n * ICO files contain multiple resolutions - [0] selects the largest\n * Used for operations that need a single frame (icon generation)\n */\nfunction getInputSelector(imagePath: string): string {\n\tconst lowerPath = imagePath.toLowerCase();\n\tif (lowerPath.endsWith('.ico')) {\n\t\treturn `\"${imagePath}[0]\"`;\n\t}\n\treturn `\"${imagePath}\"`;\n}\n\n/**\n * Get input path for preview (first frame only for GIFs and ICOs)\n * This prevents slow processing of all animation frames during preview\n */\nfunction getPreviewInputSelector(imagePath: string): string {\n\tconst lowerPath = imagePath.toLowerCase();\n\tif (lowerPath.endsWith('.ico') || lowerPath.endsWith('.gif')) {\n\t\treturn `\"${imagePath}[0]\"`;\n\t}\n\treturn `\"${imagePath}\"`;\n}\n\n/**\n * Check if file is an animated GIF\n */\nfunction isGif(imagePath: string): boolean {\n\treturn imagePath.toLowerCase().endsWith('.gif');\n}\n\n/**\n * Get GIF output command suffix\n * Uses -layers OptimizePlus for better quality than Optimize\n * Also sets disposal method to restore background to prevent frame blending\n */\nfunction getGifOutputSuffix(outputPath: string): string {\n\treturn isGif(outputPath) ? ' -dispose Background -layers OptimizePlus' : '';\n}\n\n/**\n * Get coalesce prefix for GIF input (processes all frames properly)\n */\nfunction getCoalescePrefix(inputPath: string): string {\n\treturn isGif(inputPath) ? '-coalesce ' : '';\n}\n\n/**\n * Check if ImageMagick is installed\n */\nexport async function checkImageMagick(): Promise<boolean> {\n\ttry {\n\t\tawait execAsync('command -v convert');\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Get image dimensions\n * Returns [width, height] or null on error\n * Uses first frame only for multi-frame formats (GIF, ICO)\n */\nexport async function getDimensions(\n\timagePath: string,\n): Promise<[number, number] | null> {\n\ttry {\n\t\tconst input = getPreviewInputSelector(imagePath);\n\t\tconst { stdout } = await execAsync(\n\t\t\t`convert ${input} -ping -format \"%w %h\" info:`,\n\t\t);\n\t\tconst [w, h] = stdout.trim().split(' ').map(Number);\n\t\tif (Number.isNaN(w) || Number.isNaN(h)) return null;\n\t\treturn [w, h];\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Get border color (samples top-left pixel)\n * Uses first frame only for multi-frame formats (GIF, ICO)\n */\nexport async function getBorderColor(\n\timagePath: string,\n): Promise<string | null> {\n\ttry {\n\t\tconst input = getPreviewInputSelector(imagePath);\n\t\tconst { stdout } = await execAsync(\n\t\t\t`convert ${input} -format \"%[pixel:u.p{0,0}]\" info:`,\n\t\t);\n\t\treturn stdout.trim();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Trim transparent/whitespace edges from image\n * Preserves animation for GIF files\n */\nexport async function trim(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(`convert \"${inputPath}\" ${coalesce}-trim +repage${gifSuffix} \"${outputPath}\"`);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Make image square by adding transparent padding\n * Preserves animation for GIF files\n */\nexport async function squarify(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\tconst dims = await getDimensions(inputPath);\n\tif (!dims) return false;\n\n\tconst [width, height] = dims;\n\n\t// Already square - just copy\n\tif (width === height) {\n\t\tif (inputPath !== outputPath) {\n\t\t\tcopyFileSync(inputPath, outputPath);\n\t\t}\n\t\treturn true;\n\t}\n\n\tconst size = Math.max(width, height);\n\tconst coalesce = getCoalescePrefix(inputPath);\n\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-background none -gravity center -extent ${size}x${size}${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to specific size with transparent padding\n */\nexport async function scaleToSize(\n\tinputPath: string,\n\toutputPath: string,\n\tsize: number,\n): Promise<boolean> {\n\ttry {\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -resize ${size}x${size} -background none -gravity center -extent ${size}x${size} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image with custom dimensions and padding\n * Preserves animation for GIF files\n */\nexport async function scaleWithPadding(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-resize ${width}x${height} -background none -gravity center -extent ${width}x${height}${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to exact dimensions (may distort)\n * Preserves animation for GIF files\n */\nexport async function resize(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-resize ${width}x${height}!${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Scale image to fill area and crop to exact size (cover mode)\n * Preserves animation for GIF files\n */\nexport async function scaleFillCrop(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\theight: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-resize ${width}x${height}^ -background none -gravity center -extent ${width}x${height}${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Remove background color from image\n * Preserves animation for GIF files\n */\nexport async function removeBackground(\n\tinputPath: string,\n\toutputPath: string,\n\tcolor: string,\n\tfuzz: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-fuzz ${fuzz}% -transparent \"${color}\"${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Remove background using flood-fill from edges only\n * Preserves animation for GIF files\n */\nexport async function removeBackgroundBorderOnly(\n\tinputPath: string,\n\toutputPath: string,\n\tcolor: string,\n\tfuzz: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-bordercolor \"${color}\" -border 1x1 -fill none -fuzz ${fuzz}% -draw \"matte 0,0 floodfill\" -shave 1x1${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Remove background with edge feathering for smoother cutouts\n * Uses flood-fill from borders, then applies edge feathering for soft transitions\n * This produces cleaner edges without harsh jagged boundaries\n *\n * @param featherAmount - Edge feathering radius (0-100, higher = softer edges)\n */\nexport async function removeBackgroundEdgeAware(\n\tinputPath: string,\n\toutputPath: string,\n\tcolor: string,\n\tfuzz: number,\n\tfeatherAmount = 50,\n): Promise<boolean> {\n\t// For GIFs, fall back to standard method (feathering per-frame is slow)\n\tif (isGif(inputPath)) {\n\t\treturn removeBackgroundBorderOnly(inputPath, outputPath, color, fuzz);\n\t}\n\n\ttry {\n\t\t// Map feather amount (0-100) to blur radius (0.5 to 3 pixels)\n\t\tconst featherRadius = 0.5 + (featherAmount / 100) * 2.5;\n\n\t\t// Two-step process:\n\t\t// 1. Remove background using flood-fill from borders\n\t\t// 2. Apply alpha channel feathering to smooth edges\n\t\t//\n\t\t// The feathering uses a blur on the alpha channel edges only,\n\t\t// preserving the interior while softening the boundary\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ` +\n\t\t\t`-bordercolor \"${color}\" -border 1x1 ` +\n\t\t\t`-fill none -fuzz ${fuzz}% -draw \"matte 0,0 floodfill\" ` +\n\t\t\t`-shave 1x1 ` +\n\t\t\t// Extract and feather the alpha channel\n\t\t\t`\\\\( +clone -alpha extract -blur 0x${featherRadius} \\\\) ` +\n\t\t\t`-compose CopyOpacity -composite ` +\n\t\t\t`\"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\t// Fall back to standard border-only method\n\t\treturn removeBackgroundBorderOnly(inputPath, outputPath, color, fuzz);\n\t}\n}\n\n/**\n * Create ICO file with multiple resolutions\n */\nexport async function createIco(\n\tinputPath: string,\n\toutputPath: string,\n\tsizes: number[] = [256, 128, 64, 48, 32, 16],\n): Promise<boolean> {\n\ttry {\n\t\tconst sizeStr = sizes.join(',');\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -define icon:auto-resize=${sizeStr} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Create ICO from multiple PNG files\n */\nexport async function createIcoFromMultiple(\n\tpngPaths: string[],\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst inputs = pngPaths.map((p) => `\"${p}\"`).join(' ');\n\t\tawait execAsync(`convert ${inputs} \"${outputPath}\"`);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Ensure output directory exists\n */\nexport function ensureDir(filePath: string): void {\n\tconst dir = dirname(filePath);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n}\n\n/**\n * Clean up temporary files\n */\nexport function cleanup(...files: string[]): void {\n\tfor (const file of files) {\n\t\ttry {\n\t\t\tif (existsSync(file)) {\n\t\t\t\tunlinkSync(file);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t}\n}\n\n/**\n * Extract a frame from GIF/ICO for preview\n * @param frameIndex - Which frame to extract (default 0 = first frame)\n * Returns the input path if not a multi-frame format\n *\n * OPTIMIZED: Instead of coalescing ALL frames then extracting one,\n * we only coalesce frames 0 through frameIndex, which is much faster\n * for GIFs with many frames.\n */\nexport async function extractFirstFrame(\n\tinputPath: string,\n\toutputPath: string,\n\tframeIndex = 0,\n): Promise<boolean> {\n\tconst lowerPath = inputPath.toLowerCase();\n\tif (!lowerPath.endsWith('.gif') && !lowerPath.endsWith('.ico')) {\n\t\t// Not a multi-frame format, just copy\n\t\ttry {\n\t\t\tcopyFileSync(inputPath, outputPath);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\ttry {\n\t\tif (lowerPath.endsWith('.gif')) {\n\t\t\tif (frameIndex === 0) {\n\t\t\t\t// Frame 0 is always complete - no coalescing needed\n\t\t\t\tawait execAsync(`convert \"${inputPath}[0]\" \"${outputPath}\"`);\n\t\t\t} else {\n\t\t\t\t// Only load and coalesce frames 0 through frameIndex, then keep only the last one\n\t\t\t\t// This is MUCH faster than coalescing all frames\n\t\t\t\tawait execAsync(\n\t\t\t\t\t`convert \"${inputPath}[0-${frameIndex}]\" -coalesce -delete 0--2 \"${outputPath}\"`,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// ICO files don't need coalescing\n\t\t\tawait execAsync(`convert \"${inputPath}[${frameIndex}]\" \"${outputPath}\"`);\n\t\t}\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if file is a multi-frame format (GIF or ICO)\n */\nexport function isMultiFrame(imagePath: string): boolean {\n\tconst lowerPath = imagePath.toLowerCase();\n\treturn lowerPath.endsWith('.gif') || lowerPath.endsWith('.ico');\n}\n\n/**\n * Get frame count from animated GIF\n */\nexport async function getFrameCount(imagePath: string): Promise<number> {\n\ttry {\n\t\tconst { stdout } = await execAsync(\n\t\t\t`identify -format \"%n\\\\n\" \"${imagePath}\" | head -1`,\n\t\t);\n\t\tconst count = parseInt(stdout.trim(), 10);\n\t\treturn Number.isNaN(count) ? 1 : count;\n\t} catch {\n\t\treturn 1;\n\t}\n}\n\n/**\n * Extract all frames from animated GIF to individual PNG files\n * Returns array of output file paths\n *\n * OPTIMIZED: Uses +adjoin for direct file output without intermediate buffering\n */\nexport async function extractAllFrames(\n\tinputPath: string,\n\toutputDir: string,\n\tbaseName: string,\n): Promise<string[]> {\n\ttry {\n\t\t// Ensure output directory exists\n\t\tensureDir(`${outputDir}/dummy`);\n\n\t\t// Extract frames with optimizations:\n\t\t// - coalesce: properly handle delta-encoded frames\n\t\t// - +adjoin: write frames directly to separate files (more efficient)\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -coalesce +adjoin \"${outputDir}/${baseName}-%04d.png\"`,\n\t\t);\n\n\t\t// Get list of created files\n\t\tconst { stdout } = await execAsync(`ls -1 \"${outputDir}/${baseName}\"-*.png 2>/dev/null || true`);\n\t\tconst files = stdout.trim().split('\\n').filter(f => f.length > 0);\n\t\treturn files;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Flip image horizontally (mirror)\n * Preserves animation for GIF files\n */\nexport async function flipHorizontal(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-flop${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Flip image vertically\n * Preserves animation for GIF files\n */\nexport async function flipVertical(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-flip${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Rotate image by specified degrees\n * Preserves animation for GIF files\n */\nexport async function rotate(\n\tinputPath: string,\n\toutputPath: string,\n\tdegrees: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-rotate ${degrees} -background none${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Apply grayscale filter\n * Preserves animation for GIF files\n */\nexport async function filterGrayscale(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-colorspace Gray${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Apply sepia tone filter\n * Preserves animation for GIF files\n */\nexport async function filterSepia(\n\tinputPath: string,\n\toutputPath: string,\n\tintensity = 80,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-sepia-tone ${intensity}%${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Invert image colors (negative)\n * Preserves animation for GIF files\n */\nexport async function filterInvert(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-negate${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Apply vintage filter (desaturate + warm tint)\n * Preserves animation for GIF files\n */\nexport async function filterVintage(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-modulate 100,70,100 -fill \"#704214\" -colorize 15%${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Increase saturation (vivid colors)\n * Preserves animation for GIF files\n */\nexport async function filterVivid(\n\tinputPath: string,\n\toutputPath: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-modulate 100,130,100${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Add solid color border to image\n * Preserves animation for GIF files\n */\nexport async function addBorder(\n\tinputPath: string,\n\toutputPath: string,\n\twidth: number,\n\tcolor: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-bordercolor \"${color}\" -border ${width}${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Replace one color with another\n * Preserves animation for GIF files\n */\nexport async function replaceColor(\n\tinputPath: string,\n\toutputPath: string,\n\tfromColor: string,\n\ttoColor: string,\n\tfuzz: number,\n): Promise<boolean> {\n\ttry {\n\t\tconst coalesce = getCoalescePrefix(inputPath);\n\t\tconst gifSuffix = getGifOutputSuffix(outputPath);\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" ${coalesce}-fuzz ${fuzz}% -fill \"${toColor}\" -opaque \"${fromColor}\"${gifSuffix} \"${outputPath}\"`,\n\t\t);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Delete a frame from animated GIF\n * @returns Object with success status and new frame count\n */\nexport async function deleteGifFrame(\n\tinputPath: string,\n\toutputPath: string,\n\tframeIndex: number,\n): Promise<{ success: boolean; frameCount?: number }> {\n\ttry {\n\t\tconst originalCount = await getFrameCount(inputPath);\n\t\tif (originalCount <= 1) {\n\t\t\treturn { success: false }; // Can't delete the only frame\n\t\t}\n\t\tif (frameIndex < 0 || frameIndex >= originalCount) {\n\t\t\treturn { success: false };\n\t\t}\n\n\t\t// Coalesce first, then delete the specific frame\n\t\t// -dispose Background prevents frame blending artifacts\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}\" -coalesce -delete ${frameIndex} -dispose Background -layers OptimizePlus \"${outputPath}\"`,\n\t\t);\n\n\t\tconst newCount = await getFrameCount(outputPath);\n\t\treturn { success: true, frameCount: newCount };\n\t} catch {\n\t\treturn { success: false };\n\t}\n}\n\n/**\n * Replace a frame in animated GIF with another image\n * The replacement image is scaled/cropped to match GIF dimensions\n * @returns Object with success status\n */\nexport async function replaceGifFrame(\n\tinputPath: string,\n\toutputPath: string,\n\tframeIndex: number,\n\treplacementPath: string,\n): Promise<{ success: boolean; frameCount?: number }> {\n\ttry {\n\t\tconst frameCount = await getFrameCount(inputPath);\n\t\tif (frameIndex < 0 || frameIndex >= frameCount) {\n\t\t\treturn { success: false };\n\t\t}\n\n\t\t// Get GIF dimensions\n\t\tconst dims = await getDimensions(inputPath);\n\t\tif (!dims) return { success: false };\n\n\t\t// Scale/crop replacement to match GIF dimensions (cover mode + crop)\n\t\tconst tempReplacement = `${outputPath}.tmp.png`;\n\t\tawait execAsync(\n\t\t\t`convert \"${replacementPath}\" -resize ${dims[0]}x${dims[1]}^ -gravity center -extent ${dims[0]}x${dims[1]} \"${tempReplacement}\"`,\n\t\t);\n\n\t\t// Build frame list: all frames except the one being replaced\n\t\t// Then insert the replacement at the right position\n\t\t// -dispose Background prevents frame blending artifacts\n\t\tif (frameIndex === 0) {\n\t\t\t// Replace first frame\n\t\t\tawait execAsync(\n\t\t\t\t`convert \"${tempReplacement}\" \\\\( \"${inputPath}\" -coalesce \\\\) -delete 1 -dispose Background -layers OptimizePlus \"${outputPath}\"`,\n\t\t\t);\n\t\t} else if (frameIndex === frameCount - 1) {\n\t\t\t// Replace last frame\n\t\t\tawait execAsync(\n\t\t\t\t`convert \\\\( \"${inputPath}\" -coalesce -delete -1 \\\\) \"${tempReplacement}\" -dispose Background -layers OptimizePlus \"${outputPath}\"`,\n\t\t\t);\n\t\t} else {\n\t\t\t// Replace middle frame - need to split and rejoin\n\t\t\tawait execAsync(\n\t\t\t\t`convert \\\\( \"${inputPath}\" -coalesce \\\\) -delete ${frameIndex} \"${outputPath}.frames.gif\" && ` +\n\t\t\t\t`convert \"${outputPath}.frames.gif[0-${frameIndex - 1}]\" \"${tempReplacement}\" \"${outputPath}.frames.gif[${frameIndex}-]\" -dispose Background -layers OptimizePlus \"${outputPath}\" && ` +\n\t\t\t\t`rm -f \"${outputPath}.frames.gif\"`,\n\t\t\t);\n\t\t}\n\n\t\t// Cleanup temp file\n\t\ttry { unlinkSync(tempReplacement); } catch { /* ignore */ }\n\n\t\tconst newCount = await getFrameCount(outputPath);\n\t\treturn { success: true, frameCount: newCount };\n\t} catch {\n\t\treturn { success: false };\n\t}\n}\n\n/**\n * Simplify animated GIF by keeping only every Nth frame\n * @param skipFactor - Keep every Nth frame (2 = keep every 2nd, 3 = every 3rd, etc.)\n * @returns Object with success status and new frame count\n *\n * This is useful for large GIFs that would be slow to process.\n * Skipping frames reduces processing time proportionally.\n */\nexport async function simplifyGif(\n\tinputPath: string,\n\toutputPath: string,\n\tskipFactor: number,\n): Promise<{ success: boolean; frameCount?: number }> {\n\tif (skipFactor < 2) {\n\t\t// No simplification needed\n\t\tif (inputPath !== outputPath) {\n\t\t\ttry {\n\t\t\t\tcopyFileSync(inputPath, outputPath);\n\t\t\t\tconst count = await getFrameCount(outputPath);\n\t\t\t\treturn { success: true, frameCount: count };\n\t\t\t} catch {\n\t\t\t\treturn { success: false };\n\t\t\t}\n\t\t}\n\t\tconst count = await getFrameCount(inputPath);\n\t\treturn { success: true, frameCount: count };\n\t}\n\n\ttry {\n\t\t// Get original frame count\n\t\tconst originalCount = await getFrameCount(inputPath);\n\t\tif (originalCount <= 1) {\n\t\t\t// Not an animated GIF\n\t\t\tcopyFileSync(inputPath, outputPath);\n\t\t\treturn { success: true, frameCount: 1 };\n\t\t}\n\n\t\t// Build frame index list: 0, N, 2N, 3N, ...\n\t\tconst frameIndices: number[] = [];\n\t\tfor (let i = 0; i < originalCount; i += skipFactor) {\n\t\t\tframeIndices.push(i);\n\t\t}\n\n\t\t// Use ImageMagick to extract specific frames and reconstruct GIF\n\t\t// The -coalesce ensures proper rendering of delta-encoded frames\n\t\t// -dispose Background prevents frame blending artifacts\n\t\tconst keepPattern = frameIndices.join(',');\n\n\t\tawait execAsync(\n\t\t\t`convert \"${inputPath}[${keepPattern}]\" -coalesce -dispose Background -layers OptimizePlus \"${outputPath}\"`,\n\t\t);\n\n\t\tconst newCount = await getFrameCount(outputPath);\n\t\treturn { success: true, frameCount: newCount };\n\t} catch {\n\t\treturn { success: false };\n\t}\n}\n","import { basename, dirname, extname, resolve } from 'node:path';\n\n/**\n * Convert Windows path to WSL path\n * C:\\Users\\... → /mnt/c/Users/...\n */\nexport function windowsToWsl(winPath: string): string {\n\t// Already a WSL path\n\tif (winPath.startsWith('/mnt/')) {\n\t\treturn winPath;\n\t}\n\n\t// Windows path pattern: C:\\... or C:/...\n\tconst match = winPath.match(/^([A-Za-z]):[/\\\\](.*)$/);\n\tif (match) {\n\t\tconst drive = match[1].toLowerCase();\n\t\tconst rest = match[2].replace(/\\\\/g, '/');\n\t\treturn `/mnt/${drive}/${rest}`;\n\t}\n\n\treturn winPath;\n}\n\n/**\n * Convert WSL path to Windows path\n * /mnt/c/Users/... → C:\\Users\\...\n */\nexport function wslToWindows(wslPath: string): string {\n\tconst match = wslPath.match(/^\\/mnt\\/([a-z])\\/(.*)$/i);\n\tif (match) {\n\t\tconst drive = match[1].toUpperCase();\n\t\tconst rest = match[2].replace(/\\//g, '\\\\');\n\t\treturn `${drive}:\\\\${rest}`;\n\t}\n\treturn wslPath;\n}\n\n/**\n * Normalize a path - convert Windows paths if needed, resolve relative paths\n */\nexport function normalizePath(inputPath: string): string {\n\tif (/^[A-Za-z]:[/\\\\]/.test(inputPath)) {\n\t\treturn windowsToWsl(inputPath);\n\t}\n\treturn resolve(inputPath);\n}\n\n/**\n * Get file info from a path\n */\nexport interface FileInfo {\n\tdirname: string;\n\tbasename: string;\n\tfilename: string;\n\textension: string;\n}\n\nexport function getFileInfo(filePath: string): FileInfo {\n\tconst dir = dirname(filePath);\n\tconst base = basename(filePath);\n\tconst ext = extname(filePath);\n\tconst name = base.slice(0, -ext.length);\n\n\treturn {\n\t\tdirname: dir,\n\t\tbasename: base,\n\t\tfilename: name,\n\t\textension: ext,\n\t};\n}\n\n/**\n * Generate output path with suffix\n */\nexport function getOutputPath(\n\tinputPath: string,\n\tsuffix: string,\n\tnewExtension?: string,\n): string {\n\tconst info = getFileInfo(inputPath);\n\tconst ext = newExtension ?? info.extension;\n\treturn `${info.dirname}/${info.filename}${suffix}${ext}`;\n}\n","import prompts from 'prompts';\n\n/** When true, all prompts return their default values without user interaction */\nlet useDefaults = false;\n\n/** Override values from CLI arguments - keyed by prompt message substring */\nconst overrides: Record<string, string | number | boolean | string[]> = {};\n\n/**\n * Enable or disable default mode (for --yes flag)\n */\nexport function setUseDefaults(value: boolean): void {\n\tuseDefaults = value;\n}\n\n/**\n * Check if defaults mode is enabled\n */\nexport function isUsingDefaults(): boolean {\n\treturn useDefaults;\n}\n\n/**\n * Set override values from CLI arguments\n */\nexport function setOverrides(values: Record<string, string | number | boolean | string[]>): void {\n\tObject.assign(overrides, values);\n}\n\n/**\n * Clear all overrides\n */\nexport function clearOverrides(): void {\n\tfor (const key of Object.keys(overrides)) {\n\t\tdelete overrides[key];\n\t}\n}\n\n/**\n * Get override value for a prompt message (matches substring)\n */\nfunction getOverride(message: string): string | number | boolean | string[] | undefined {\n\tconst msgLower = message.toLowerCase();\n\tfor (const [key, value] of Object.entries(overrides)) {\n\t\tif (msgLower.includes(key.toLowerCase())) {\n\t\t\treturn value;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Prompt for text input with optional default\n */\nexport async function text(\n\tmessage: string,\n\tdefaultValue?: string,\n): Promise<string> {\n\tif (useDefaults) return defaultValue ?? '';\n\n\tconst response = await prompts({\n\t\ttype: 'text',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t});\n\treturn response.value ?? defaultValue ?? '';\n}\n\n/**\n * Prompt for number input with optional default\n */\nexport async function number(\n\tmessage: string,\n\tdefaultValue?: number,\n\tmin?: number,\n\tmax?: number,\n): Promise<number> {\n\tconst override = getOverride(message);\n\tif (override !== undefined) return Number(override);\n\tif (useDefaults) return defaultValue ?? 0;\n\n\tconst response = await prompts({\n\t\ttype: 'number',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t\tmin,\n\t\tmax,\n\t});\n\treturn response.value ?? defaultValue ?? 0;\n}\n\n/**\n * Prompt for yes/no confirmation\n */\nexport async function confirm(\n\tmessage: string,\n\tdefaultValue = true,\n): Promise<boolean> {\n\tconst override = getOverride(message);\n\tif (override !== undefined) return Boolean(override);\n\tif (useDefaults) return defaultValue;\n\n\tconst response = await prompts({\n\t\ttype: 'confirm',\n\t\tname: 'value',\n\t\tmessage,\n\t\tinitial: defaultValue,\n\t});\n\treturn response.value ?? defaultValue;\n}\n\n/**\n * Single-select from options\n */\nexport interface SelectOption {\n\ttitle: string;\n\tvalue: string | number;\n\tdescription?: string;\n}\n\nexport async function select<T extends string | number>(\n\tmessage: string,\n\toptions: SelectOption[],\n\tdefaultValue?: T,\n): Promise<T | null> {\n\tif (useDefaults) return defaultValue ?? (options[0]?.value as T) ?? null;\n\n\tconst response = await prompts({\n\t\ttype: 'select',\n\t\tname: 'value',\n\t\tmessage,\n\t\tchoices: options.map((opt) => ({\n\t\t\ttitle: opt.title,\n\t\t\tvalue: opt.value,\n\t\t\tdescription: opt.description,\n\t\t})),\n\t});\n\treturn (response.value as T) ?? null;\n}\n\n/**\n * Multi-select from options\n */\nexport async function multiSelect<T extends string | number>(\n\tmessage: string,\n\toptions: SelectOption[],\n\tdefaultValues?: T[],\n): Promise<T[]> {\n\tif (useDefaults) return defaultValues ?? [];\n\n\tconst response = await prompts({\n\t\ttype: 'multiselect',\n\t\tname: 'value',\n\t\tmessage,\n\t\tchoices: options.map((opt) => ({\n\t\t\ttitle: opt.title,\n\t\t\tvalue: opt.value,\n\t\t\tdescription: opt.description,\n\t\t})),\n\t\tinstructions: false,\n\t\thint: '- Space to select, Enter to confirm',\n\t});\n\treturn (response.value as T[]) ?? [];\n}\n\n/**\n * Handle Ctrl+C gracefully\n */\nexport function onCancel(): void {\n\tprompts.override({ value: undefined });\n}\n\n// Set up cancel handler\nprompts.override({});\n\n/**\n * Pause and wait for user to press Enter (useful for errors in batch mode)\n * Only pauses when running with -y flag so user can see error messages\n */\nexport async function pauseOnError(message = 'Press Enter to close...'): Promise<void> {\n\tif (!useDefaults) return; // Interactive mode - no need to pause\n\n\tconsole.log();\n\tawait prompts({\n\t\ttype: 'text',\n\t\tname: 'value',\n\t\tmessage,\n\t});\n}\n","import { extname } from 'node:path';\nimport { dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport chalk from 'chalk';\nimport { setUseDefaults } from '../lib/prompts.js';\nimport { getTool } from './tools.js';\n\n/** Get dist directory (where cli.js lives after bundling) */\nexport function getDistDir(): string {\n\tconst currentFile = fileURLToPath(import.meta.url);\n\t// tsup bundles everything into dist/cli.js, so dirname gives dist/\n\treturn dirname(currentFile);\n}\n\n/** Get registry base path for PicLet menu on an extension */\nexport function getMenuBasePath(extension: string): string {\n\treturn `HKCU\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n}\n\n/** Validate files have correct extensions for the tool */\nexport function validateExtensions(\n\tfiles: string[],\n\tallowedExtensions: string[],\n): { valid: string[]; invalid: string[] } {\n\tconst valid: string[] = [];\n\tconst invalid: string[] = [];\n\n\tfor (const file of files) {\n\t\tconst ext = extname(file).toLowerCase();\n\t\tif (allowedExtensions.includes(ext)) {\n\t\t\tvalid.push(file);\n\t\t} else {\n\t\t\tinvalid.push(file);\n\t\t}\n\t}\n\n\treturn { valid, invalid };\n}\n\n/** Run tool on multiple files */\nexport async function runToolOnFiles(\n\ttoolId: string,\n\tfiles: string[],\n\tuseYes: boolean,\n): Promise<boolean> {\n\tconst tool = getTool(toolId);\n\tif (!tool) {\n\t\tconsole.error(chalk.red(`Tool not found: ${toolId}`));\n\t\treturn false;\n\t}\n\n\t// Validate extensions\n\tconst { valid, invalid } = validateExtensions(files, tool.config.extensions);\n\n\tif (invalid.length > 0) {\n\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\tfor (const file of invalid) {\n\t\t\tconsole.error(chalk.red(` ✗ ${file}`));\n\t\t}\n\t\tconsole.error(\n\t\t\tchalk.yellow(\n\t\t\t\t`\\nSupported extensions: ${tool.config.extensions.join(', ')}`,\n\t\t\t),\n\t\t);\n\t\tif (valid.length === 0) return false;\n\t\tconsole.log();\n\t}\n\n\t// Enable defaults mode if --yes flag or multiple files\n\tif (useYes || valid.length > 1) {\n\t\tsetUseDefaults(true);\n\t}\n\n\t// Process files\n\tlet allSuccess = true;\n\tfor (let i = 0; i < valid.length; i++) {\n\t\tconst file = valid[i];\n\t\tif (valid.length > 1) {\n\t\t\tconsole.log(chalk.cyan(`\\n[${i + 1}/${valid.length}] ${file}`));\n\t\t}\n\t\tconst success = await tool.run(file);\n\t\tif (!success) allSuccess = false;\n\t}\n\n\treturn allSuccess;\n}\n","import { existsSync, mkdirSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\tsuccess,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractAllFrames,\n\textractFirstFrame,\n\tgetDimensions,\n\tgetFrameCount,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tconfirm as promptConfirm,\n\tpauseOnError,\n} from '../lib/prompts.js';\n\n/**\n * Extract frames from animated GIF (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Extract Frames');\n\n\twip('Analyzing GIF...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\n\tconst frameCount = await getFrameCount(input);\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}, ${frameCount} frames`);\n\n\tif (frameCount <= 1) {\n\t\tinfo('Image has only 1 frame, nothing to extract');\n\t\treturn true;\n\t}\n\n\tconsole.log('');\n\tconsole.log(`${BOLD}Extract Frames:${RESET}`);\n\tconsole.log(` ${DIM}This will create ${frameCount} PNG files${RESET}`);\n\tconsole.log('');\n\n\tconst proceed = await promptConfirm(`Extract ${frameCount} frames?`, true);\n\tif (!proceed) {\n\t\tinfo('Cancelled');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_frames`;\n\n\tconsole.log('');\n\twip('Extracting frames...');\n\n\tmkdirSync(outputDir, { recursive: true });\n\tconst frames = await extractAllFrames(input, outputDir, 'frame');\n\n\tif (frames.length === 0) {\n\t\twipDone(false, 'Extraction failed');\n\t\treturn false;\n\t}\n\n\twipDone(true, `Extracted ${frames.length} frames`);\n\n\tconsole.log('');\n\tsuccess(`Output: ${outputDir}/`);\n\treturn true;\n}\n\n/**\n * Extract frames from animated GIF (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst frameCount = await getFrameCount(input);\n\tconst fileInfo = getFileInfo(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'extract-frames.html',\n\t\ttitle: 'PicLet - Extract Frames',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tframeCount,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst frameIndex = (opts.frameIndex as number) ?? 0;\n\t\t\treturn generateFramePreview(input, frameIndex);\n\t\t},\n\t\tonProcess: async () => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Extracting ${frameCount} frames...` });\n\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_frames`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\tconst frames = await extractAllFrames(input, outputDir, 'frame');\n\n\t\t\tif (frames.length > 0) {\n\t\t\t\tlogs.push({ type: 'success', message: `Extracted ${frames.length} frames` });\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${frames.length} frames -> ${fileInfo.filename}_frames/`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Extraction failed' });\n\t\t\treturn { success: false, error: 'Extraction failed', logs };\n\t\t},\n\t});\n}\n\n/**\n * Generate preview for a specific frame\n */\nasync function generateFramePreview(\n\tinput: string,\n\tframeIndex: number,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempOutput = join(tempDir, `piclet-frame-${timestamp}.png`);\n\n\ttry {\n\t\tif (!(await extractFirstFrame(input, tempOutput, frameIndex))) {\n\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\t\tcleanup(tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'extract-frames',\n\tname: 'Extract Frames',\n\ticon: 'extract.ico',\n\textensions: ['.gif'],\n};\n","import { existsSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tfilterGrayscale,\n\tfilterInvert,\n\tfilterSepia,\n\tfilterVintage,\n\tfilterVivid,\n\tgetDimensions,\n\tisMultiFrame,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tpauseOnError,\n\tselect as promptSelect,\n} from '../lib/prompts.js';\n\n/** Filter types */\ntype FilterType = 'grayscale' | 'sepia' | 'invert' | 'vintage' | 'vivid';\n\n/** Processing options for filter */\ninterface ProcessOptions {\n\tfilter: FilterType;\n}\n\nconst FILTER_LABELS: Record<FilterType, string> = {\n\t'grayscale': 'Grayscale',\n\t'sepia': 'Sepia',\n\t'invert': 'Invert',\n\t'vintage': 'Vintage',\n\t'vivid': 'Vivid',\n};\n\n/**\n * Apply filter to image file\n */\nasync function applyFilter(\n\tinput: string,\n\toutput: string,\n\tfilter: FilterType,\n): Promise<boolean> {\n\tswitch (filter) {\n\t\tcase 'grayscale':\n\t\t\treturn filterGrayscale(input, output);\n\t\tcase 'sepia':\n\t\t\treturn filterSepia(input, output);\n\t\tcase 'invert':\n\t\t\treturn filterInvert(input, output);\n\t\tcase 'vintage':\n\t\t\treturn filterVintage(input, output);\n\t\tcase 'vivid':\n\t\t\treturn filterVivid(input, output);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\n/**\n * Core processing logic for filter\n */\nasync function processImage(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_${options.filter}${outputExt}`;\n\n\twip(`Applying ${FILTER_LABELS[options.filter]} filter...`);\n\n\tconst success = await applyFilter(input, output, options.filter);\n\n\tif (!success) {\n\t\twipDone(false, 'Filter failed');\n\t\treturn false;\n\t}\n\twipDone(true, FILTER_LABELS[options.filter]);\n\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tconsole.log(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tconsole.log(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Filter Options:${RESET}`);\n\tconsole.log(` ${DIM}1. Grayscale - Black and white${RESET}`);\n\tconsole.log(` ${DIM}2. Sepia - Warm brownish tint${RESET}`);\n\tconsole.log(` ${DIM}3. Invert - Negative colors${RESET}`);\n\tconsole.log(` ${DIM}4. Vintage - Desaturated warm tone${RESET}`);\n\tconsole.log(` ${DIM}5. Vivid - Increased saturation${RESET}`);\n\tconsole.log('');\n\n\tconst filter = await promptSelect<FilterType>(\n\t\t'Select filter',\n\t\t[\n\t\t\t{ value: 'grayscale', title: 'Grayscale' },\n\t\t\t{ value: 'sepia', title: 'Sepia' },\n\t\t\t{ value: 'invert', title: 'Invert' },\n\t\t\t{ value: 'vintage', title: 'Vintage' },\n\t\t\t{ value: 'vivid', title: 'Vivid' },\n\t\t],\n\t\t'grayscale',\n\t);\n\n\treturn { filter: filter ?? 'grayscale' };\n}\n\n/**\n * Apply filter to image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Filter');\n\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\tconst options = await collectOptionsCLI();\n\n\tconsole.log('');\n\treturn processImage(input, options);\n}\n\n/**\n * Apply filter to image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\treturn startGuiServer({\n\t\thtmlFile: 'filter.html',\n\t\ttitle: 'PicLet - Filter',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tfilter: 'grayscale',\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst filter = (opts.filter as FilterType) ?? 'grayscale';\n\t\t\treturn generatePreview(input, { filter });\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst filter = (opts.filter as FilterType) ?? 'grayscale';\n\t\t\tconst options: ProcessOptions = { filter };\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_${filter}${outputExt}`;\n\n\t\t\tlogs.push({ type: 'info', message: `Applying ${FILTER_LABELS[filter]} filter...` });\n\n\t\t\tconst success = await applyFilter(input, output, filter);\n\n\t\t\tif (success) {\n\t\t\t\tlogs.push({ type: 'success', message: 'Filter applied' });\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Filter failed' });\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\tconst success = await applyFilter(previewInput, tempOutput, options.filter);\n\n\t\tif (!success) {\n\t\t\tcleanup(tempSource, tempOutput);\n\t\t\treturn { success: false, error: 'Filter failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\n\t\tcleanup(tempSource, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempSource, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'filter',\n\tname: 'Filter',\n\ticon: 'filter.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],\n};\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { basename, dirname } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tDIM,\n\tRESET,\n\tclearLine,\n\terror,\n\theader,\n\tinfo,\n\tseparator,\n\tstep,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tcreateIcoFromMultiple,\n\tgetDimensions,\n\tscaleToSize,\n\tsquarify,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { multiSelect as promptMultiSelect, pauseOnError } from '../lib/prompts.js';\n\n// Icon definitions for each platform\ninterface IconDef {\n\tfilename: string;\n\tsize: number;\n}\n\nconst WEB_ICONS: IconDef[] = [\n\t{ filename: 'favicon-16x16.png', size: 16 },\n\t{ filename: 'favicon-32x32.png', size: 32 },\n\t{ filename: 'favicon-48x48.png', size: 48 },\n\t{ filename: 'apple-touch-icon.png', size: 180 },\n\t{ filename: 'android-chrome-192x192.png', size: 192 },\n\t{ filename: 'android-chrome-512x512.png', size: 512 },\n\t{ filename: 'mstile-150x150.png', size: 150 },\n];\n\nconst ANDROID_ICONS: IconDef[] = [\n\t{ filename: 'mipmap-mdpi/ic_launcher.png', size: 48 },\n\t{ filename: 'mipmap-hdpi/ic_launcher.png', size: 72 },\n\t{ filename: 'mipmap-xhdpi/ic_launcher.png', size: 96 },\n\t{ filename: 'mipmap-xxhdpi/ic_launcher.png', size: 144 },\n\t{ filename: 'mipmap-xxxhdpi/ic_launcher.png', size: 192 },\n\t{ filename: 'playstore-icon.png', size: 512 },\n];\n\nconst IOS_ICONS: IconDef[] = [\n\t// 20pt - Notifications\n\t{ filename: 'AppIcon-20.png', size: 20 },\n\t{ filename: 'AppIcon-20@2x.png', size: 40 },\n\t{ filename: 'AppIcon-20@3x.png', size: 60 },\n\t// 29pt - Settings\n\t{ filename: 'AppIcon-29.png', size: 29 },\n\t{ filename: 'AppIcon-29@2x.png', size: 58 },\n\t{ filename: 'AppIcon-29@3x.png', size: 87 },\n\t// 40pt - Spotlight\n\t{ filename: 'AppIcon-40.png', size: 40 },\n\t{ filename: 'AppIcon-40@2x.png', size: 80 },\n\t{ filename: 'AppIcon-40@3x.png', size: 120 },\n\t// 60pt - iPhone App\n\t{ filename: 'AppIcon-60@2x.png', size: 120 },\n\t{ filename: 'AppIcon-60@3x.png', size: 180 },\n\t// 76pt - iPad App\n\t{ filename: 'AppIcon-76.png', size: 76 },\n\t{ filename: 'AppIcon-76@2x.png', size: 152 },\n\t// 83.5pt - iPad Pro\n\t{ filename: 'AppIcon-83.5@2x.png', size: 167 },\n\t// App Store\n\t{ filename: 'AppIcon-1024.png', size: 1024 },\n];\n\n/**\n * Generate icons for a platform\n */\nasync function generateIcons(\n\toutputDir: string,\n\tsourceImg: string,\n\ticons: IconDef[],\n): Promise<number> {\n\tconst total = icons.length;\n\tlet current = 0;\n\tlet failed = 0;\n\n\tfor (const icon of icons) {\n\t\tcurrent++;\n\t\tconst outputPath = `${outputDir}/${icon.filename}`;\n\n\t\t// Create subdirectory if needed\n\t\tconst subdir = dirname(outputPath);\n\t\tif (!existsSync(subdir)) {\n\t\t\tmkdirSync(subdir, { recursive: true });\n\t\t}\n\n\t\tclearLine();\n\t\twip(`[${current}/${total}] Generating ${icon.filename}...`);\n\n\t\tif (await scaleToSize(sourceImg, outputPath, icon.size)) {\n\t\t\tclearLine();\n\t\t\tsuccess(\n\t\t\t\t`[${current}/${total}] ${icon.filename} (${icon.size}x${icon.size})`,\n\t\t\t);\n\t\t} else {\n\t\t\tclearLine();\n\t\t\terror(`[${current}/${total}] Failed: ${icon.filename}`);\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Generate favicon.ico from multiple sizes\n */\nasync function generateFavicon(\n\toutputDir: string,\n\tsourceImg: string,\n): Promise<boolean> {\n\twip('Generating favicon.ico...');\n\n\tconst temp16 = `${outputDir}/.temp_16.png`;\n\tconst temp32 = `${outputDir}/.temp_32.png`;\n\tconst temp48 = `${outputDir}/.temp_48.png`;\n\n\tawait scaleToSize(sourceImg, temp16, 16);\n\tawait scaleToSize(sourceImg, temp32, 32);\n\tawait scaleToSize(sourceImg, temp48, 48);\n\n\tconst result = await createIcoFromMultiple(\n\t\t[temp16, temp32, temp48],\n\t\t`${outputDir}/favicon.ico`,\n\t);\n\n\tcleanup(temp16, temp32, temp48);\n\n\tif (result) {\n\t\twipDone(true, 'favicon.ico (16, 32, 48)');\n\t\treturn true;\n\t}\n\twipDone(false, 'favicon.ico failed');\n\treturn false;\n}\n\n/**\n * Generate icon sets for Web, Android, iOS platforms\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Get file info\n\tconst fileInfo = getFileInfo(input);\n\n\theader('PicLet Icon Pack Generator');\n\n\t// Analyze source image\n\twip('Analyzing source image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\tconst [origW, origH] = dims;\n\twipDone(true, `Source: ${origW}x${origH}`);\n\n\t// Warn if small source\n\tif (origW < 1024 || origH < 1024) {\n\t\twarn(\n\t\t\t'Source image is smaller than 1024px. Larger images produce better quality.',\n\t\t);\n\t}\n\n\t// Check if square\n\tif (origW !== origH) {\n\t\twarn('Image is not square. Will add transparent padding.');\n\t}\n\n\t// Select platforms\n\tconsole.log('');\n\tconst platforms = await promptMultiSelect<string>(\n\t\t'Select target platforms:',\n\t\t[\n\t\t\t{ title: 'Web (PWA, favicon, apple-touch-icon)', value: 'web' },\n\t\t\t{ title: 'Android (mipmap icons, Play Store)', value: 'android' },\n\t\t\t{ title: 'iOS (App icons, App Store)', value: 'ios' },\n\t\t],\n\t\t['web', 'android', 'ios'], // Default: all platforms\n\t);\n\n\tif (platforms.length === 0) {\n\t\terror('No platforms selected');\n\t\treturn false;\n\t}\n\n\tconst doWeb = platforms.includes('web');\n\tconst doAndroid = platforms.includes('android');\n\tconst doIos = platforms.includes('ios');\n\n\t// Create output directory\n\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\tmkdirSync(outputDir, { recursive: true });\n\tinfo(`Output directory: ${outputDir}`);\n\n\t// Prepare source: make square and scale to 1024px for best quality\n\tconsole.log('');\n\twip('Preparing source image...');\n\tconst tempSource = `${outputDir}/.source_1024.png`;\n\tconst tempSquare = `${outputDir}/.temp_square.png`;\n\n\t// First squarify\n\tif (!(await squarify(input, tempSquare))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\treturn false;\n\t}\n\n\t// Then scale to 1024 for high quality source\n\tif (!(await scaleToSize(tempSquare, tempSource, 1024))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\tcleanup(tempSquare);\n\t\treturn false;\n\t}\n\tcleanup(tempSquare);\n\twipDone(true, 'Prepared 1024x1024 source');\n\n\tlet totalFailed = 0;\n\n\t// Generate Web icons\n\tif (doWeb) {\n\t\tconsole.log('');\n\t\theader('Web Icons');\n\t\tconst webDir = `${outputDir}/web`;\n\t\tmkdirSync(webDir, { recursive: true });\n\n\t\tif (!(await generateFavicon(webDir, tempSource))) {\n\t\t\ttotalFailed++;\n\t\t}\n\n\t\ttotalFailed += await generateIcons(webDir, tempSource, WEB_ICONS);\n\t}\n\n\t// Generate Android icons\n\tif (doAndroid) {\n\t\tconsole.log('');\n\t\theader('Android Icons');\n\t\tconst androidDir = `${outputDir}/android`;\n\t\tmkdirSync(androidDir, { recursive: true });\n\n\t\ttotalFailed += await generateIcons(androidDir, tempSource, ANDROID_ICONS);\n\t}\n\n\t// Generate iOS icons\n\tif (doIos) {\n\t\tconsole.log('');\n\t\theader('iOS Icons');\n\t\tconst iosDir = `${outputDir}/ios`;\n\t\tmkdirSync(iosDir, { recursive: true });\n\n\t\ttotalFailed += await generateIcons(iosDir, tempSource, IOS_ICONS);\n\t}\n\n\t// Cleanup\n\tcleanup(tempSource);\n\n\t// Summary\n\tconsole.log('');\n\tseparator();\n\n\tif (totalFailed === 0) {\n\t\tsuccess('All icons generated successfully!');\n\t} else {\n\t\twarn(`${totalFailed} icon(s) failed to generate`);\n\t}\n\n\tconsole.log('');\n\tinfo(`Icons saved to: ${outputDir}`);\n\n\tif (doWeb) {\n\t\tstep('web/ - Favicon, PWA icons, Apple touch icon');\n\t}\n\tif (doAndroid) {\n\t\tstep('android/ - mipmap folders, Play Store icon');\n\t}\n\tif (doIos) {\n\t\tstep('ios/ - All iOS app icon sizes');\n\t}\n\n\treturn totalFailed === 0;\n}\n\n/**\n * Generate icon pack (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'iconpack.html',\n\t\ttitle: 'PicLet - Icon Pack',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tweb: true,\n\t\t\tandroid: true,\n\t\t\tios: true,\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst doWeb = (opts.web as boolean) ?? true;\n\t\t\tconst doAndroid = (opts.android as boolean) ?? true;\n\t\t\tconst doIos = (opts.ios as boolean) ?? true;\n\n\t\t\tif (!doWeb && !doAndroid && !doIos) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'No platforms selected',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'No platforms selected' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Create output directory\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\t\t\tlogs.push({ type: 'info', message: `Output: ${outputDir}` });\n\n\t\t\t// Prepare source: make square and scale to 1024px\n\t\t\tlogs.push({ type: 'info', message: 'Preparing source image...' });\n\t\t\tconst tempSource = `${outputDir}/.source_1024.png`;\n\t\t\tconst tempSquare = `${outputDir}/.temp_square.png`;\n\n\t\t\tif (!(await squarify(input, tempSquare))) {\n\t\t\t\treturn { success: false, error: 'Failed to prepare source', logs };\n\t\t\t}\n\n\t\t\tif (!(await scaleToSize(tempSquare, tempSource, 1024))) {\n\t\t\t\tcleanup(tempSquare);\n\t\t\t\treturn { success: false, error: 'Failed to prepare source', logs };\n\t\t\t}\n\t\t\tcleanup(tempSquare);\n\t\t\tlogs.push({ type: 'success', message: 'Prepared 1024x1024 source' });\n\n\t\t\tlet totalFailed = 0;\n\n\t\t\t// Generate Web icons\n\t\t\tif (doWeb) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating Web icons...' });\n\t\t\t\tconst webDir = `${outputDir}/web`;\n\t\t\t\tmkdirSync(webDir, { recursive: true });\n\n\t\t\t\tif (!(await generateFaviconSilent(webDir, tempSource))) {\n\t\t\t\t\ttotalFailed++;\n\t\t\t\t}\n\t\t\t\ttotalFailed += await generateIconsSilent(webDir, tempSource, WEB_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `Web: ${WEB_ICONS.length + 1} icons` });\n\t\t\t}\n\n\t\t\t// Generate Android icons\n\t\t\tif (doAndroid) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating Android icons...' });\n\t\t\t\tconst androidDir = `${outputDir}/android`;\n\t\t\t\tmkdirSync(androidDir, { recursive: true });\n\t\t\t\ttotalFailed += await generateIconsSilent(androidDir, tempSource, ANDROID_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `Android: ${ANDROID_ICONS.length} icons` });\n\t\t\t}\n\n\t\t\t// Generate iOS icons\n\t\t\tif (doIos) {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating iOS icons...' });\n\t\t\t\tconst iosDir = `${outputDir}/ios`;\n\t\t\t\tmkdirSync(iosDir, { recursive: true });\n\t\t\t\ttotalFailed += await generateIconsSilent(iosDir, tempSource, IOS_ICONS, logs);\n\t\t\t\tlogs.push({ type: 'success', message: `iOS: ${IOS_ICONS.length} icons` });\n\t\t\t}\n\n\t\t\tcleanup(tempSource);\n\n\t\t\tif (totalFailed === 0) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `Icons saved to ${fileInfo.filename}_icons/`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `${totalFailed} icon(s) failed`,\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Silent version of generateIcons for GUI mode\n */\nasync function generateIconsSilent(\n\toutputDir: string,\n\tsourceImg: string,\n\ticons: IconDef[],\n\t_logs: Array<{ type: string; message: string }>,\n): Promise<number> {\n\tlet failed = 0;\n\n\tfor (const icon of icons) {\n\t\tconst outputPath = `${outputDir}/${icon.filename}`;\n\t\tconst subdir = dirname(outputPath);\n\t\tif (!existsSync(subdir)) {\n\t\t\tmkdirSync(subdir, { recursive: true });\n\t\t}\n\n\t\tif (!(await scaleToSize(sourceImg, outputPath, icon.size))) {\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Silent version of generateFavicon for GUI mode\n */\nasync function generateFaviconSilent(\n\toutputDir: string,\n\tsourceImg: string,\n): Promise<boolean> {\n\tconst temp16 = `${outputDir}/.temp_16.png`;\n\tconst temp32 = `${outputDir}/.temp_32.png`;\n\tconst temp48 = `${outputDir}/.temp_48.png`;\n\n\tawait scaleToSize(sourceImg, temp16, 16);\n\tawait scaleToSize(sourceImg, temp32, 32);\n\tawait scaleToSize(sourceImg, temp48, 48);\n\n\tconst result = await createIcoFromMultiple(\n\t\t[temp16, temp32, temp48],\n\t\t`${outputDir}/favicon.ico`,\n\t);\n\n\tcleanup(temp16, temp32, temp48);\n\treturn result;\n}\n\nexport const config = {\n\tid: 'iconpack',\n\tname: 'Icon Pack',\n\ticon: 'iconpack.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif'],\n};\n","import { existsSync, readFileSync } from 'node:fs';\r\nimport { tmpdir } from 'node:os';\r\nimport { basename, join } from 'node:path';\r\nimport { startGuiServer } from '../lib/gui-server.js';\r\nimport { error, header, success, wip, wipDone } from '../lib/logger.js';\r\nimport {\r\n\tcheckImageMagick,\r\n\tcleanup,\r\n\tcreateIco,\r\n\tgetDimensions,\r\n\tscaleToSize,\r\n\tsquarify,\r\n\ttrim,\r\n} from '../lib/magick.js';\r\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\r\nimport { pauseOnError } from '../lib/prompts.js';\r\n\r\n/** Processing options for makeicon */\r\ninterface ProcessOptions {\r\n\ttrim: boolean;\r\n\tmakeSquare: boolean;\r\n}\r\n\r\n/**\r\n * Convert PNG to ICO with multiple resolutions\r\n */\r\nexport async function run(inputRaw: string): Promise<boolean> {\r\n\t// Check dependencies\r\n\tif (!(await checkImageMagick())) {\r\n\t\terror('ImageMagick not found. Please install it:');\r\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\r\n\t\tawait pauseOnError();\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Normalize path\r\n\tconst input = normalizePath(inputRaw);\r\n\r\n\tif (!existsSync(input)) {\r\n\t\terror(`File not found: ${input}`);\r\n\t\tawait pauseOnError();\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Get file info\r\n\tconst fileInfo = getFileInfo(input);\r\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\r\n\tconst tempTrimmed = `${fileInfo.dirname}/${fileInfo.filename}_trimmed.png`;\r\n\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square.png`;\r\n\tconst tempScaled = `${fileInfo.dirname}/${fileInfo.filename}_scaled.png`;\r\n\r\n\theader('PicLet Make Icon');\r\n\r\n\t// Get original dimensions\r\n\twip('Analyzing image...');\r\n\tconst dims = await getDimensions(input);\r\n\tif (!dims) {\r\n\t\twipDone(false, 'Failed to read image');\r\n\t\treturn false;\r\n\t}\r\n\twipDone(true, `Original size: ${dims[0]}x${dims[1]}`);\r\n\r\n\t// Step 1: Trim transparent areas\r\n\twip('Trimming transparent areas...');\r\n\tif (!(await trim(input, tempTrimmed))) {\r\n\t\twipDone(false, 'Trim failed');\r\n\t\tcleanup(tempTrimmed);\r\n\t\treturn false;\r\n\t}\r\n\twipDone(true, 'Trimmed');\r\n\r\n\t// Step 2: Make square\r\n\twip('Making square...');\r\n\tif (!(await squarify(tempTrimmed, tempSquare))) {\r\n\t\twipDone(false, 'Square padding failed');\r\n\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempTrimmed);\r\n\twipDone(true, 'Made square');\r\n\r\n\t// Step 3: Scale to 512px for best quality source\r\n\twip('Scaling to 512px...');\r\n\tif (!(await scaleToSize(tempSquare, tempScaled, 512))) {\r\n\t\twipDone(false, 'Scaling failed');\r\n\t\tcleanup(tempSquare, tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempSquare);\r\n\twipDone(true, 'Scaled to 512x512');\r\n\r\n\t// Step 4: Create ICO with multiple resolutions\r\n\twip('Creating icon (256, 128, 64, 48, 32, 16)...');\r\n\tif (!(await createIco(tempScaled, output))) {\r\n\t\twipDone(false, 'Icon creation failed');\r\n\t\tcleanup(tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempScaled);\r\n\twipDone(true, 'Icon created');\r\n\r\n\tconsole.log('');\r\n\tsuccess(`Output: ${output}`);\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * Process image for icon creation (shared logic)\r\n */\r\nasync function processForIcon(\r\n\tinput: string,\r\n\toutput: string,\r\n\toptions: ProcessOptions,\r\n\tlogs?: Array<{ type: string; message: string }>,\r\n): Promise<boolean> {\r\n\tconst fileInfo = getFileInfo(input);\r\n\tconst tempTrimmed = `${fileInfo.dirname}/${fileInfo.filename}_trimmed.png`;\r\n\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square.png`;\r\n\tconst tempScaled = `${fileInfo.dirname}/${fileInfo.filename}_scaled.png`;\r\n\r\n\tlet currentInput = input;\r\n\r\n\t// Step 1: Trim (optional)\r\n\tif (options.trim) {\r\n\t\tlogs?.push({ type: 'info', message: 'Trimming transparent areas...' });\r\n\t\tif (!(await trim(currentInput, tempTrimmed))) {\r\n\t\t\tcleanup(tempTrimmed);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tcurrentInput = tempTrimmed;\r\n\t\tlogs?.push({ type: 'success', message: 'Trimmed' });\r\n\t}\r\n\r\n\t// Step 2: Squarify (optional)\r\n\tif (options.makeSquare) {\r\n\t\tlogs?.push({ type: 'info', message: 'Making square...' });\r\n\t\tif (!(await squarify(currentInput, tempSquare))) {\r\n\t\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\tif (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\t\tcurrentInput = tempSquare;\r\n\t\tlogs?.push({ type: 'success', message: 'Made square' });\r\n\t}\r\n\r\n\t// Step 3: Scale to 512px\r\n\tlogs?.push({ type: 'info', message: 'Scaling to 512px...' });\r\n\tif (!(await scaleToSize(currentInput, tempScaled, 512))) {\r\n\t\tcleanup(tempTrimmed, tempSquare, tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tif (currentInput === tempSquare) cleanup(tempSquare);\r\n\telse if (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\tlogs?.push({ type: 'success', message: 'Scaled to 512x512' });\r\n\r\n\t// Step 4: Create ICO\r\n\tlogs?.push({ type: 'info', message: 'Creating icon (256, 128, 64, 48, 32, 16)...' });\r\n\tif (!(await createIco(tempScaled, output))) {\r\n\t\tcleanup(tempScaled);\r\n\t\treturn false;\r\n\t}\r\n\tcleanup(tempScaled);\r\n\tlogs?.push({ type: 'success', message: 'Icon created' });\r\n\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * Generate preview image as base64 data URL\r\n */\r\nasync function generatePreview(\r\n\tinput: string,\r\n\toptions: ProcessOptions,\r\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\r\n\tconst tempDir = tmpdir();\r\n\tconst timestamp = Date.now();\r\n\tconst tempTrimmed = join(tempDir, `piclet-preview-trimmed-${timestamp}.png`);\r\n\tconst tempSquare = join(tempDir, `piclet-preview-square-${timestamp}.png`);\r\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\r\n\r\n\ttry {\r\n\t\tlet currentInput = input;\r\n\r\n\t\t// Trim if enabled\r\n\t\tif (options.trim) {\r\n\t\t\tif (!(await trim(currentInput, tempTrimmed))) {\r\n\t\t\t\tcleanup(tempTrimmed);\r\n\t\t\t\treturn { success: false, error: 'Trim failed' };\r\n\t\t\t}\r\n\t\t\tcurrentInput = tempTrimmed;\r\n\t\t}\r\n\r\n\t\t// Squarify if enabled\r\n\t\tif (options.makeSquare) {\r\n\t\t\tif (!(await squarify(currentInput, tempSquare))) {\r\n\t\t\t\tcleanup(tempTrimmed, tempSquare);\r\n\t\t\t\treturn { success: false, error: 'Square failed' };\r\n\t\t\t}\r\n\t\t\tif (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\t\t\tcurrentInput = tempSquare;\r\n\t\t}\r\n\r\n\t\t// Scale to preview size (256px)\r\n\t\tif (!(await scaleToSize(currentInput, tempOutput, 256))) {\r\n\t\t\tcleanup(tempTrimmed, tempSquare, tempOutput);\r\n\t\t\treturn { success: false, error: 'Scale failed' };\r\n\t\t}\r\n\t\tif (currentInput === tempSquare) cleanup(tempSquare);\r\n\t\telse if (currentInput === tempTrimmed) cleanup(tempTrimmed);\r\n\r\n\t\tconst buffer = readFileSync(tempOutput);\r\n\t\tconst base64 = buffer.toString('base64');\r\n\t\tconst imageData = `data:image/png;base64,${base64}`;\r\n\r\n\t\tconst dims = await getDimensions(tempOutput);\r\n\t\tcleanup(tempOutput);\r\n\r\n\t\treturn {\r\n\t\t\tsuccess: true,\r\n\t\t\timageData,\r\n\t\t\twidth: dims?.[0],\r\n\t\t\theight: dims?.[1],\r\n\t\t};\r\n\t} catch (err) {\r\n\t\tcleanup(tempTrimmed, tempSquare, tempOutput);\r\n\t\treturn { success: false, error: (err as Error).message };\r\n\t}\r\n}\r\n\r\n/**\r\n * Convert PNG to ICO (GUI mode)\r\n */\r\nexport async function runGUI(inputRaw: string): Promise<boolean> {\r\n\tconst input = normalizePath(inputRaw);\r\n\r\n\tif (!existsSync(input)) {\r\n\t\terror(`File not found: ${input}`);\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst dims = await getDimensions(input);\r\n\tif (!dims) {\r\n\t\terror('Failed to read image dimensions');\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst fileInfo = getFileInfo(input);\r\n\r\n\treturn startGuiServer({\r\n\t\thtmlFile: 'makeicon.html',\r\n\t\ttitle: 'PicLet - Make Icon',\r\n\t\timageInfo: {\r\n\t\t\tfilePath: input,\r\n\t\t\tfileName: basename(input),\r\n\t\t\twidth: dims[0],\r\n\t\t\theight: dims[1],\r\n\t\t\tborderColor: null,\r\n\t\t},\r\n\t\tdefaults: {\r\n\t\t\ttrim: true,\r\n\t\t\tmakeSquare: true,\r\n\t\t},\r\n\t\tonPreview: async (opts) => {\r\n\t\t\tconst options: ProcessOptions = {\r\n\t\t\t\ttrim: (opts.trim as boolean) ?? true,\r\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? true,\r\n\t\t\t};\r\n\t\t\treturn generatePreview(input, options);\r\n\t\t},\r\n\t\tonProcess: async (opts) => {\r\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\r\n\r\n\t\t\tif (!(await checkImageMagick())) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: false,\r\n\t\t\t\t\terror: 'ImageMagick not found',\r\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\tconst options: ProcessOptions = {\r\n\t\t\t\ttrim: (opts.trim as boolean) ?? true,\r\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? true,\r\n\t\t\t};\r\n\r\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\r\n\r\n\t\t\tconst success = await processForIcon(input, output, options, logs);\r\n\r\n\t\t\tif (success) {\r\n\t\t\t\treturn {\r\n\t\t\t\t\tsuccess: true,\r\n\t\t\t\t\toutput: `${fileInfo.filename}.ico`,\r\n\t\t\t\t\tlogs,\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\treturn { success: false, error: 'Icon creation failed', logs };\r\n\t\t},\r\n\t});\r\n}\r\n\r\nexport const config = {\r\n\tid: 'makeicon',\r\n\tname: 'Make Icon',\r\n\ticon: 'makeicon.ico',\r\n\textensions: ['.png', '.gif'],\r\n};\r\n","/**\n * Unified PicLet tool - combines all tools with chaining support\n */\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, dirname, extname, join } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport { error } from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tcreateIco,\n\tcreateIcoFromMultiple,\n\tdeleteGifFrame,\n\textractAllFrames,\n\textractFirstFrame,\n\tgetBorderColor,\n\tgetDimensions,\n\tgetFrameCount,\n\tisMultiFrame,\n\tremoveBackground,\n\tremoveBackgroundBorderOnly,\n\tremoveBackgroundEdgeAware,\n\treplaceGifFrame,\n\tresize,\n\tscaleFillCrop,\n\tscaleToSize,\n\tscaleWithPadding,\n\tsimplifyGif,\n\tsquarify,\n\ttrim,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { loadPresets } from '../lib/presets.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface PreviewResult {\n\tsuccess: boolean;\n\timageData?: string;\n\twidth?: number;\n\theight?: number;\n\terror?: string;\n}\n\ninterface ProcessResult {\n\tsuccess: boolean;\n\toutput?: string;\n\terror?: string;\n\tlogs: Array<{ type: string; message: string }>;\n}\n\ninterface Dimension {\n\twidth: number;\n\theight: number;\n\tfilename?: string;\n}\n\ninterface ToolOptions {\n\ttools: string[];\n\toriginal?: boolean;\n\tremovebg?: { fuzz: number; trim: boolean; preserveInner: boolean; edgeDetect: boolean; edgeStrength: number };\n\tscale?: { width: number; height: number; makeSquare: boolean };\n\ticons?: {\n\t\ttrim: boolean;\n\t\tmakeSquare: boolean;\n\t\tico: boolean;\n\t\tweb: boolean;\n\t\tandroid: boolean;\n\t\tios: boolean;\n\t};\n\tstorepack?: { dimensions: Dimension[]; scaleMode: string; presetName?: string };\n}\n\n// Tool execution order (for chaining)\nconst TOOL_ORDER = ['removebg', 'scale', 'icons', 'storepack'];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Preview - Chains enabled tools\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function generateCombinedPreview(\n\tinput: string,\n\tborderColor: string | null,\n\topts: ToolOptions,\n): Promise<PreviewResult> {\n\tconst tempDir = tmpdir();\n\tconst ts = Date.now();\n\tconst temps: string[] = [];\n\n\tconst makeTempPath = (suffix: string) => {\n\t\tconst p = join(tempDir, `piclet-${ts}-${suffix}.png`);\n\t\ttemps.push(p);\n\t\treturn p;\n\t};\n\n\ttry {\n\t\tlet current = input;\n\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tif (isMultiFrame(input)) {\n\t\t\tconst frameTemp = makeTempPath('frame');\n\t\t\tif (await extractFirstFrame(input, frameTemp)) {\n\t\t\t\tcurrent = frameTemp;\n\t\t\t}\n\t\t}\n\n\t\t// If just showing original, scale it for preview and return\n\t\tif (opts.original || opts.tools.length === 0) {\n\t\t\tconst dims = await getDimensions(current);\n\t\t\tlet previewPath = current;\n\n\t\t\tif (dims && (dims[0] > 512 || dims[1] > 512)) {\n\t\t\t\tconst scaled = makeTempPath('orig-preview');\n\t\t\t\tconst targetSize = Math.min(512, Math.max(dims[0], dims[1]));\n\t\t\t\tif (await scaleToSize(current, scaled, targetSize)) {\n\t\t\t\t\tpreviewPath = scaled;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst buffer = readFileSync(previewPath);\n\t\t\tconst finalDims = await getDimensions(previewPath);\n\t\t\tcleanup(...temps);\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\t\twidth: finalDims?.[0] ?? dims?.[0],\n\t\t\t\theight: finalDims?.[1] ?? dims?.[1],\n\t\t\t};\n\t\t}\n\n\t\t// Get ordered list of active tools\n\t\tconst activeTools = TOOL_ORDER.filter(t => opts.tools.includes(t));\n\n\t\t// Process each tool in order\n\t\tfor (const tool of activeTools) {\n\t\t\tswitch (tool) {\n\t\t\t\tcase 'removebg': {\n\t\t\t\t\tconst rbOpts = opts.removebg!;\n\t\t\t\t\tconst out = makeTempPath('removebg');\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tif (rbOpts.edgeDetect && borderColor) {\n\t\t\t\t\t\t// Use edge feathering for smoother cutouts\n\t\t\t\t\t\tsuccess = await removeBackgroundEdgeAware(current, out, borderColor, rbOpts.fuzz, rbOpts.edgeStrength);\n\t\t\t\t\t} else if (rbOpts.preserveInner && borderColor) {\n\t\t\t\t\t\tsuccess = await removeBackgroundBorderOnly(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\t}\n\t\t\t\t\tif (!success && borderColor) {\n\t\t\t\t\t\tsuccess = await removeBackground(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\t}\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\t\treturn { success: false, error: 'Background removal failed' };\n\t\t\t\t\t}\n\n\t\t\t\t\t// Trim if enabled\n\t\t\t\t\tif (rbOpts.trim) {\n\t\t\t\t\t\tconst trimOut = makeTempPath('trim');\n\t\t\t\t\t\tif (await trim(out, trimOut)) {\n\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase 'scale': {\n\t\t\t\t\tconst scOpts = opts.scale!;\n\t\t\t\t\tconst out = makeTempPath('scale');\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tif (scOpts.makeSquare) {\n\t\t\t\t\t\tconst max = Math.max(scOpts.width, scOpts.height);\n\t\t\t\t\t\tsuccess = await scaleWithPadding(current, out, max, max);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsuccess = await resize(current, out, scOpts.width, scOpts.height);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\t\treturn { success: false, error: 'Scale failed' };\n\t\t\t\t\t}\n\t\t\t\t\tcurrent = out;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase 'icons': {\n\t\t\t\t\t// For preview, show what the icon source would look like after trim/squarify\n\t\t\t\t\tconst icOpts = opts.icons!;\n\n\t\t\t\t\tif (icOpts.trim && current === input) {\n\t\t\t\t\t\tconst trimOut = makeTempPath('ic-trim');\n\t\t\t\t\t\tif (await trim(current, trimOut)) {\n\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.makeSquare) {\n\t\t\t\t\t\tconst sqOut = makeTempPath('ic-sq');\n\t\t\t\t\t\tif (await squarify(current, sqOut)) {\n\t\t\t\t\t\t\tcurrent = sqOut;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// storepack doesn't affect preview\n\t\t\t}\n\t\t}\n\n\t\t// Scale down for preview display if needed\n\t\tconst dims = await getDimensions(current);\n\t\tlet previewPath = current;\n\n\t\tif (dims && (dims[0] > 512 || dims[1] > 512)) {\n\t\t\tconst scaled = makeTempPath('preview');\n\t\t\tconst targetSize = Math.min(512, Math.max(dims[0], dims[1]));\n\t\t\tif (await scaleToSize(current, scaled, targetSize)) {\n\t\t\t\tpreviewPath = scaled;\n\t\t\t}\n\t\t}\n\n\t\tconst buffer = readFileSync(previewPath);\n\t\tconst finalDims = await getDimensions(previewPath);\n\t\tcleanup(...temps);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\twidth: finalDims?.[0],\n\t\t\theight: finalDims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(...temps);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Process - Chains enabled tools and produces output\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface ProcessedResult {\n\toutputs: string[];\n\tsingleFilePath?: string; // Full path if single file output (for preview)\n}\n\nasync function processCombined(\n\tinput: string,\n\tborderColor: string | null,\n\topts: ToolOptions,\n\tlogs: Array<{ type: string; message: string }>,\n): Promise<ProcessedResult> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputs: string[] = [];\n\tconst temps: string[] = [];\n\tlet singleFilePath: string | undefined;\n\t// Preserve GIF extension for animated files, use PNG for others\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\n\tconst makeTempPath = (suffix: string) => {\n\t\tconst p = `${fileInfo.dirname}/${fileInfo.filename}_${suffix}${outputExt}`;\n\t\ttemps.push(p);\n\t\treturn p;\n\t};\n\n\tlet current = input;\n\tconst activeTools = TOOL_ORDER.filter(t => opts.tools.includes(t));\n\n\tfor (const tool of activeTools) {\n\t\tswitch (tool) {\n\t\t\tcase 'removebg': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Removing background...' });\n\t\t\t\tconst rbOpts = opts.removebg!;\n\t\t\t\tconst out = makeTempPath('nobg');\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (rbOpts.edgeDetect && borderColor) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Using edge feathering...' });\n\t\t\t\t\tsuccess = await removeBackgroundEdgeAware(current, out, borderColor, rbOpts.fuzz, rbOpts.edgeStrength);\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tlogs.push({ type: 'warn', message: 'Edge feathering failed, trying standard removal' });\n\t\t\t\t\t}\n\t\t\t\t} else if (rbOpts.preserveInner && borderColor) {\n\t\t\t\t\tsuccess = await removeBackgroundBorderOnly(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tlogs.push({ type: 'warn', message: 'Border-only failed, trying full removal' });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!success && borderColor) {\n\t\t\t\t\tsuccess = await removeBackground(current, out, borderColor, rbOpts.fuzz);\n\t\t\t\t}\n\t\t\t\tif (!success) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Background removal failed' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn { outputs: [] };\n\t\t\t\t}\n\t\t\t\tlogs.push({ type: 'success', message: 'Background removed' });\n\n\t\t\t\tif (rbOpts.trim) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Trimming edges...' });\n\t\t\t\t\tconst trimOut = makeTempPath('trimmed');\n\t\t\t\t\tif (await trim(out, trimOut)) {\n\t\t\t\t\t\tcleanup(out);\n\t\t\t\t\t\ttemps.splice(temps.indexOf(out), 1);\n\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent = out;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcurrent = out;\n\t\t\t\t}\n\n\t\t\t\t// If this is the last tool, save output\n\t\t\t\tif (activeTools.indexOf(tool) === activeTools.length - 1) {\n\t\t\t\t\tconst finalOut = `${fileInfo.dirname}/${fileInfo.filename}_nobg${outputExt}`;\n\t\t\t\t\trenameSync(current, finalOut);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t\toutputs.push(basename(finalOut));\n\t\t\t\t\tsingleFilePath = finalOut;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'scale': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Scaling image...' });\n\t\t\t\tconst scOpts = opts.scale!;\n\t\t\t\tconst out = makeTempPath('scaled');\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (scOpts.makeSquare) {\n\t\t\t\t\tconst max = Math.max(scOpts.width, scOpts.height);\n\t\t\t\t\tsuccess = await scaleWithPadding(current, out, max, max);\n\t\t\t\t} else {\n\t\t\t\t\tsuccess = await resize(current, out, scOpts.width, scOpts.height);\n\t\t\t\t}\n\n\t\t\t\tif (!success) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Scale failed' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn { outputs: [] };\n\t\t\t\t}\n\n\t\t\t\tconst dims = await getDimensions(out);\n\t\t\t\tlogs.push({ type: 'success', message: `Scaled to ${dims?.[0]}×${dims?.[1]}` });\n\n\t\t\t\t// Clean up previous temp if it's not the input\n\t\t\t\tif (current !== input && temps.includes(current)) {\n\t\t\t\t\tcleanup(current);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t}\n\t\t\t\tcurrent = out;\n\n\t\t\t\t// If this is the last tool, save output\n\t\t\t\tif (activeTools.indexOf(tool) === activeTools.length - 1) {\n\t\t\t\t\tconst finalOut = `${fileInfo.dirname}/${fileInfo.filename}_scaled${outputExt}`;\n\t\t\t\t\trenameSync(current, finalOut);\n\t\t\t\t\ttemps.splice(temps.indexOf(current), 1);\n\t\t\t\t\toutputs.push(basename(finalOut));\n\t\t\t\t\tsingleFilePath = finalOut;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'icons': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating icons...' });\n\t\t\t\tconst icOpts = opts.icons!;\n\n\t\t\t\t// Need at least one output format\n\t\t\t\tif (!icOpts.ico && !icOpts.web && !icOpts.android && !icOpts.ios) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'No output format selected' });\n\t\t\t\t\treturn { outputs: [] };\n\t\t\t\t}\n\n\t\t\t\t// Prepare source - apply trim and squarify\n\t\t\t\tlet iconSource = current;\n\n\t\t\t\tif (icOpts.trim && current === input) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Trimming edges...' });\n\t\t\t\t\tconst trimOut = makeTempPath('ic-trim');\n\t\t\t\t\tif (await trim(current, trimOut)) {\n\t\t\t\t\t\ticonSource = trimOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (icOpts.makeSquare) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Making square...' });\n\t\t\t\t\tconst sqOut = makeTempPath('ic-sq');\n\t\t\t\t\tif (await squarify(iconSource, sqOut)) {\n\t\t\t\t\t\tif (iconSource !== current && iconSource !== input) cleanup(iconSource);\n\t\t\t\t\t\ticonSource = sqOut;\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Made square' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Prepare high-res source (1024px for packs, 512px for ICO only)\n\t\t\t\tconst maxSize = icOpts.web || icOpts.android || icOpts.ios ? 1024 : 512;\n\t\t\t\tconst srcTemp = makeTempPath('ic-src');\n\t\t\t\tif (!(await scaleToSize(iconSource, srcTemp, maxSize))) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'Failed to prepare icon source' });\n\t\t\t\t\tcleanup(...temps);\n\t\t\t\t\treturn { outputs: [] };\n\t\t\t\t}\n\t\t\t\tif (iconSource !== current && iconSource !== input) cleanup(iconSource);\n\n\t\t\t\tlet totalCount = 0;\n\n\t\t\t\t// Generate ICO file\n\t\t\t\tif (icOpts.ico) {\n\t\t\t\t\tlogs.push({ type: 'info', message: 'Creating ICO file...' });\n\t\t\t\t\tconst icoOut = `${fileInfo.dirname}/${fileInfo.filename}.ico`;\n\t\t\t\t\tif (await createIco(srcTemp, icoOut)) {\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'ICO: 6 sizes (256, 128, 64, 48, 32, 16)' });\n\t\t\t\t\t\toutputs.push(basename(icoOut));\n\t\t\t\t\t\ttotalCount += 6;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogs.push({ type: 'warn', message: 'ICO creation failed' });\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Generate icon packs (Web, Android, iOS)\n\t\t\t\tconst needsPacks = icOpts.web || icOpts.android || icOpts.ios;\n\t\t\t\tif (needsPacks) {\n\t\t\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_icons`;\n\t\t\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\t\t\tif (icOpts.web) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating Web icons...' });\n\t\t\t\t\t\tconst webDir = `${outputDir}/web`;\n\t\t\t\t\t\tmkdirSync(webDir, { recursive: true });\n\n\t\t\t\t\t\t// Favicon.ico\n\t\t\t\t\t\tconst t16 = `${webDir}/.t16.png`, t32 = `${webDir}/.t32.png`, t48 = `${webDir}/.t48.png`;\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t16, 16);\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t32, 32);\n\t\t\t\t\t\tawait scaleToSize(srcTemp, t48, 48);\n\t\t\t\t\t\tawait createIcoFromMultiple([t16, t32, t48], `${webDir}/favicon.ico`);\n\t\t\t\t\t\tcleanup(t16, t32, t48);\n\t\t\t\t\t\ttotalCount++;\n\n\t\t\t\t\t\tconst webIcons = [\n\t\t\t\t\t\t\t{ name: 'favicon-16x16.png', size: 16 }, { name: 'favicon-32x32.png', size: 32 },\n\t\t\t\t\t\t\t{ name: 'apple-touch-icon.png', size: 180 }, { name: 'android-chrome-192x192.png', size: 192 },\n\t\t\t\t\t\t\t{ name: 'android-chrome-512x512.png', size: 512 }, { name: 'mstile-150x150.png', size: 150 },\n\t\t\t\t\t\t];\n\t\t\t\t\t\tfor (const i of webIcons) {\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, `${webDir}/${i.name}`, i.size);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Web: 7 icons' });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.android) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating Android icons...' });\n\t\t\t\t\t\tconst androidDir = `${outputDir}/android`;\n\t\t\t\t\t\tconst androidIcons = [\n\t\t\t\t\t\t\t{ name: 'mipmap-mdpi/ic_launcher.png', size: 48 },\n\t\t\t\t\t\t\t{ name: 'mipmap-hdpi/ic_launcher.png', size: 72 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xhdpi/ic_launcher.png', size: 96 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xxhdpi/ic_launcher.png', size: 144 },\n\t\t\t\t\t\t\t{ name: 'mipmap-xxxhdpi/ic_launcher.png', size: 192 },\n\t\t\t\t\t\t\t{ name: 'playstore-icon.png', size: 512 },\n\t\t\t\t\t\t];\n\t\t\t\t\t\tfor (const i of androidIcons) {\n\t\t\t\t\t\t\tconst p = `${androidDir}/${i.name}`;\n\t\t\t\t\t\t\tmkdirSync(dirname(p), { recursive: true });\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, p, i.size);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: 'Android: 6 icons' });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (icOpts.ios) {\n\t\t\t\t\t\tlogs.push({ type: 'info', message: 'Generating iOS icons...' });\n\t\t\t\t\t\tconst iosDir = `${outputDir}/ios`;\n\t\t\t\t\t\tmkdirSync(iosDir, { recursive: true });\n\t\t\t\t\t\tconst iosSizes = [20, 29, 40, 58, 60, 76, 80, 87, 120, 152, 167, 180, 1024];\n\t\t\t\t\t\tfor (const s of iosSizes) {\n\t\t\t\t\t\t\tawait scaleToSize(srcTemp, `${iosDir}/AppIcon-${s}.png`, s);\n\t\t\t\t\t\t\ttotalCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogs.push({ type: 'success', message: `iOS: ${iosSizes.length} icons` });\n\t\t\t\t\t}\n\n\t\t\t\t\toutputs.push(`${totalCount} icons → ${fileInfo.filename}_icons/`);\n\t\t\t\t}\n\n\t\t\t\tcleanup(srcTemp);\n\t\t\t\tlogs.push({ type: 'success', message: `Generated ${totalCount} total icons` });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase 'storepack': {\n\t\t\t\tlogs.push({ type: 'info', message: 'Generating store assets...' });\n\t\t\t\tconst spOpts = opts.storepack!;\n\n\t\t\t\tif (!spOpts.dimensions || spOpts.dimensions.length === 0) {\n\t\t\t\t\tlogs.push({ type: 'error', message: 'No dimensions specified' });\n\t\t\t\t\treturn { outputs: [] };\n\t\t\t\t}\n\n\t\t\t\tconst folderName = spOpts.presetName || 'assets';\n\t\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${folderName}`;\n\t\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\t\tlet count = 0;\n\t\t\t\tfor (const dim of spOpts.dimensions) {\n\t\t\t\t\tconst filename = dim.filename || `${dim.width}x${dim.height}.png`;\n\t\t\t\t\tconst out = join(outputDir, filename);\n\t\t\t\t\tlet success = false;\n\n\t\t\t\t\tswitch (spOpts.scaleMode) {\n\t\t\t\t\t\tcase 'fill':\n\t\t\t\t\t\t\tsuccess = await scaleFillCrop(current, out, dim.width, dim.height);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'stretch':\n\t\t\t\t\t\t\tsuccess = await resize(current, out, dim.width, dim.height);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tsuccess = await scaleWithPadding(current, out, dim.width, dim.height);\n\t\t\t\t\t}\n\t\t\t\t\tif (success) count++;\n\t\t\t\t}\n\n\t\t\t\tlogs.push({ type: 'success', message: `Generated ${count}/${spOpts.dimensions.length} images` });\n\t\t\t\toutputs.push(`${count} images → ${fileInfo.filename}_${folderName}/`);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Cleanup any remaining temps\n\tcleanup(...temps);\n\treturn { outputs, singleFilePath };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Main GUI Entry Point\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tlet currentInput = normalizePath(inputRaw);\n\n\tif (!existsSync(currentInput)) {\n\t\terror(`File not found: ${currentInput}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(currentInput);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tlet currentBorderColor = await getBorderColor(currentInput);\n\tlet currentFrameCount = isMultiFrame(currentInput) ? await getFrameCount(currentInput) : 1;\n\tconst presets = loadPresets();\n\n\t// Helper to generate frame thumbnail\n\tasync function generateFrameThumbnail(frameIndex: number): Promise<{ success: boolean; imageData?: string; error?: string }> {\n\t\tconst tempDir = tmpdir();\n\t\tconst tempOutput = join(tempDir, `piclet-frame-${Date.now()}-${frameIndex}.png`);\n\t\ttry {\n\t\t\tif (!(await extractFirstFrame(currentInput, tempOutput, frameIndex))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\t// Scale down for thumbnail\n\t\t\tconst thumbOutput = join(tempDir, `piclet-thumb-${Date.now()}-${frameIndex}.png`);\n\t\t\tawait scaleToSize(tempOutput, thumbOutput, 96);\n\t\t\tconst buffer = readFileSync(thumbOutput);\n\t\t\tcleanup(tempOutput, thumbOutput);\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tcleanup(tempOutput);\n\t\t\treturn { success: false, error: (err as Error).message };\n\t\t}\n\t}\n\n\t// Helper to generate processed frame preview (for thumbnails)\n\tasync function generateFramePreview(\n\t\tframeIndex: number,\n\t\topts: ToolOptions,\n\t): Promise<{ success: boolean; imageData?: string; error?: string }> {\n\t\tconst tempDir = tmpdir();\n\t\tconst ts = Date.now();\n\t\tconst frameFile = join(tempDir, `piclet-fp-${ts}-${frameIndex}.png`);\n\t\tconst temps: string[] = [frameFile];\n\n\t\ttry {\n\t\t\t// Extract single frame\n\t\t\tif (!(await extractFirstFrame(currentInput, frameFile, frameIndex))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\n\t\t\tlet current = frameFile;\n\n\t\t\t// Apply tools in order\n\t\t\tconst activeTools = ['removebg', 'scale', 'icons'].filter(t => opts.tools.includes(t));\n\n\t\t\tfor (const tool of activeTools) {\n\t\t\t\tconst tempOut = join(tempDir, `piclet-fp-${ts}-${frameIndex}-${tool}.png`);\n\t\t\t\ttemps.push(tempOut);\n\n\t\t\t\tswitch (tool) {\n\t\t\t\t\tcase 'removebg': {\n\t\t\t\t\t\tconst rbOpts = opts.removebg!;\n\t\t\t\t\t\tlet success = false;\n\t\t\t\t\t\tif (rbOpts.preserveInner && currentBorderColor) {\n\t\t\t\t\t\t\tsuccess = await removeBackgroundBorderOnly(current, tempOut, currentBorderColor, rbOpts.fuzz);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!success && currentBorderColor) {\n\t\t\t\t\t\t\tsuccess = await removeBackground(current, tempOut, currentBorderColor, rbOpts.fuzz);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (success) {\n\t\t\t\t\t\t\tif (rbOpts.trim) {\n\t\t\t\t\t\t\t\tconst trimOut = join(tempDir, `piclet-fp-${ts}-${frameIndex}-trim.png`);\n\t\t\t\t\t\t\t\ttemps.push(trimOut);\n\t\t\t\t\t\t\t\tif (await trim(tempOut, trimOut)) {\n\t\t\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurrent = tempOut;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcurrent = tempOut;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'scale': {\n\t\t\t\t\t\tconst scOpts = opts.scale!;\n\t\t\t\t\t\tif (scOpts.makeSquare) {\n\t\t\t\t\t\t\tconst max = Math.max(scOpts.width, scOpts.height);\n\t\t\t\t\t\t\tif (await scaleWithPadding(current, tempOut, max, max)) {\n\t\t\t\t\t\t\t\tcurrent = tempOut;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (await resize(current, tempOut, scOpts.width, scOpts.height)) {\n\t\t\t\t\t\t\t\tcurrent = tempOut;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'icons': {\n\t\t\t\t\t\tconst icOpts = opts.icons!;\n\t\t\t\t\t\tif (icOpts.trim) {\n\t\t\t\t\t\t\tconst trimOut = join(tempDir, `piclet-fp-${ts}-${frameIndex}-ictrim.png`);\n\t\t\t\t\t\t\ttemps.push(trimOut);\n\t\t\t\t\t\t\tif (await trim(current, trimOut)) {\n\t\t\t\t\t\t\t\tcurrent = trimOut;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (icOpts.makeSquare) {\n\t\t\t\t\t\t\tif (await squarify(current, tempOut)) {\n\t\t\t\t\t\t\t\tcurrent = tempOut;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Scale down for thumbnail\n\t\t\tconst thumbOut = join(tempDir, `piclet-fp-${ts}-${frameIndex}-thumb.png`);\n\t\t\ttemps.push(thumbOut);\n\t\t\tawait scaleToSize(current, thumbOut, 96);\n\n\t\t\tconst buffer = readFileSync(thumbOut);\n\t\t\tcleanup(...temps);\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\timageData: `data:image/png;base64,${buffer.toString('base64')}`,\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tcleanup(...temps);\n\t\t\treturn { success: false, error: (err as Error).message };\n\t\t}\n\t}\n\n\treturn startGuiServer({\n\t\thtmlFile: 'piclet.html',\n\t\ttitle: 'PicLet',\n\t\timageInfo: {\n\t\t\tfilePath: currentInput,\n\t\t\tfileName: basename(currentInput),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: currentBorderColor,\n\t\t\tframeCount: currentFrameCount,\n\t\t},\n\t\tdefaults: {\n\t\t\t// Return full preset data for the UI\n\t\t\tpresets: presets.map(p => ({\n\t\t\t\tid: p.id,\n\t\t\t\tname: p.name,\n\t\t\t\tdescription: p.description,\n\t\t\t\ticons: p.icons,\n\t\t\t})),\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst toolOpts = opts as unknown as ToolOptions & { frameIndex?: number };\n\t\t\t// Allow empty tools array - will show original image\n\t\t\tif (!toolOpts.tools) {\n\t\t\t\ttoolOpts.tools = [];\n\t\t\t}\n\n\t\t\t// For GIFs with frameIndex, preview that specific frame\n\t\t\tif (isMultiFrame(currentInput) && typeof toolOpts.frameIndex === 'number') {\n\t\t\t\tconst tempDir = tmpdir();\n\t\t\t\tconst ts = Date.now();\n\t\t\t\tconst frameFile = join(tempDir, `piclet-prev-${ts}.png`);\n\n\t\t\t\tif (!(await extractFirstFrame(currentInput, frameFile, toolOpts.frameIndex))) {\n\t\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t\t}\n\n\t\t\t\t// Generate preview with the extracted frame\n\t\t\t\tconst result = await generateCombinedPreview(frameFile, currentBorderColor, toolOpts);\n\t\t\t\tcleanup(frameFile);\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\treturn generateCombinedPreview(currentInput, currentBorderColor, toolOpts);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\t\t\tconst toolOpts = opts as unknown as ToolOptions & {\n\t\t\t\texportMode?: 'frame' | 'all-frames' | 'gif';\n\t\t\t\tframeIndex?: number;\n\t\t\t};\n\n\t\t\t// Handle GIF export modes\n\t\t\tif (toolOpts.exportMode && isMultiFrame(currentInput)) {\n\t\t\t\treturn processGifExport(currentInput, currentBorderColor, toolOpts, logs);\n\t\t\t}\n\n\t\t\tif (!toolOpts.tools || toolOpts.tools.length === 0) {\n\t\t\t\treturn { success: false, error: 'No tools selected', logs };\n\t\t\t}\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst result = await processCombined(currentInput, currentBorderColor, toolOpts, logs);\n\n\t\t\tif (result.outputs.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: result.outputs.join('\\n'),\n\t\t\t\t\toutputPath: result.singleFilePath,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn { success: false, error: 'Processing failed', logs };\n\t\t},\n\t\tonLoadImage: async (data) => {\n\t\t\ttry {\n\t\t\t\t// Save base64 data to temp file\n\t\t\t\tconst ext = extname(data.fileName) || '.png';\n\t\t\t\tconst tempPath = join(tmpdir(), `piclet-load-${Date.now()}${ext}`);\n\t\t\t\tconst buffer = Buffer.from(data.data, 'base64');\n\t\t\t\twriteFileSync(tempPath, buffer);\n\n\t\t\t\t// Get dimensions and border color\n\t\t\t\tconst newDims = await getDimensions(tempPath);\n\t\t\t\tif (!newDims) {\n\t\t\t\t\tcleanup(tempPath);\n\t\t\t\t\treturn { success: false, error: 'Failed to read image dimensions' };\n\t\t\t\t}\n\n\t\t\t\tconst newBorderColor = await getBorderColor(tempPath);\n\t\t\t\tconst newFrameCount = isMultiFrame(tempPath) ? await getFrameCount(tempPath) : 1;\n\n\t\t\t\t// Update current image\n\t\t\t\tcurrentInput = tempPath;\n\t\t\t\tcurrentBorderColor = newBorderColor;\n\t\t\t\tcurrentFrameCount = newFrameCount;\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tfilePath: tempPath,\n\t\t\t\t\tfileName: data.fileName,\n\t\t\t\t\twidth: newDims[0],\n\t\t\t\t\theight: newDims[1],\n\t\t\t\t\tborderColor: newBorderColor,\n\t\t\t\t\tframeCount: newFrameCount,\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\treturn { success: false, error: (err as Error).message };\n\t\t\t}\n\t\t},\n\t\tonFrameThumbnail: generateFrameThumbnail,\n\t\tonFramePreview: async (frameIndex, opts) => {\n\t\t\tconst toolOpts = opts as unknown as ToolOptions;\n\t\t\tif (!toolOpts.tools) toolOpts.tools = [];\n\t\t\treturn generateFramePreview(frameIndex, toolOpts);\n\t\t},\n\t\tonSimplifyGif: async (skipFactor) => {\n\t\t\ttry {\n\t\t\t\t// Create simplified GIF in temp location\n\t\t\t\tconst tempPath = join(tmpdir(), `piclet-simplified-${Date.now()}.gif`);\n\t\t\t\tconst result = await simplifyGif(currentInput, tempPath, skipFactor);\n\n\t\t\t\tif (!result.success) {\n\t\t\t\t\treturn { success: false, error: 'Failed to simplify GIF' };\n\t\t\t\t}\n\n\t\t\t\t// Get dimensions of simplified GIF\n\t\t\t\tconst newDims = await getDimensions(tempPath);\n\t\t\t\tif (!newDims) {\n\t\t\t\t\tcleanup(tempPath);\n\t\t\t\t\treturn { success: false, error: 'Failed to read simplified GIF dimensions' };\n\t\t\t\t}\n\n\t\t\t\t// Update current input to the simplified version\n\t\t\t\tcurrentInput = tempPath;\n\t\t\t\tcurrentFrameCount = result.frameCount ?? 1;\n\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tfilePath: tempPath,\n\t\t\t\t\tfileName: basename(currentInput),\n\t\t\t\t\twidth: newDims[0],\n\t\t\t\t\theight: newDims[1],\n\t\t\t\t\tframeCount: currentFrameCount,\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\treturn { success: false, error: (err as Error).message };\n\t\t\t}\n\t\t},\n\t\tonDeleteFrame: async (frameIndex) => {\n\t\t\ttry {\n\t\t\t\tconst tempPath = join(tmpdir(), `piclet-edited-${Date.now()}.gif`);\n\t\t\t\tconst result = await deleteGifFrame(currentInput, tempPath, frameIndex);\n\n\t\t\t\tif (!result.success) {\n\t\t\t\t\treturn { success: false, error: 'Failed to delete frame' };\n\t\t\t\t}\n\n\t\t\t\t// Update current input\n\t\t\t\tcurrentInput = tempPath;\n\t\t\t\tcurrentFrameCount = result.frameCount ?? 1;\n\n\t\t\t\treturn { success: true, frameCount: currentFrameCount };\n\t\t\t} catch (err) {\n\t\t\t\treturn { success: false, error: (err as Error).message };\n\t\t\t}\n\t\t},\n\t\tonReplaceFrame: async (frameIndex, imageData) => {\n\t\t\ttry {\n\t\t\t\t// Save base64 image data to temp file\n\t\t\t\tconst buffer = Buffer.from(imageData, 'base64');\n\t\t\t\tconst tempImagePath = join(tmpdir(), `piclet-replace-${Date.now()}.png`);\n\t\t\t\twriteFileSync(tempImagePath, buffer);\n\n\t\t\t\tconst tempPath = join(tmpdir(), `piclet-edited-${Date.now()}.gif`);\n\t\t\t\tconst result = await replaceGifFrame(currentInput, tempPath, frameIndex, tempImagePath);\n\n\t\t\t\t// Cleanup temp image\n\t\t\t\tcleanup(tempImagePath);\n\n\t\t\t\tif (!result.success) {\n\t\t\t\t\treturn { success: false, error: 'Failed to replace frame' };\n\t\t\t\t}\n\n\t\t\t\t// Update current input\n\t\t\t\tcurrentInput = tempPath;\n\t\t\t\tcurrentFrameCount = result.frameCount ?? currentFrameCount;\n\n\t\t\t\treturn { success: true, frameCount: currentFrameCount };\n\t\t\t} catch (err) {\n\t\t\t\treturn { success: false, error: (err as Error).message };\n\t\t\t}\n\t\t},\n\t});\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// GIF Export Processing\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function processGifExport(\n\tinput: string,\n\tborderColor: string | null,\n\topts: ToolOptions & { exportMode?: string; frameIndex?: number },\n\tlogs: Array<{ type: string; message: string }>,\n): Promise<{ success: boolean; output?: string; outputPath?: string; error?: string; logs: Array<{ type: string; message: string }> }> {\n\tif (!(await checkImageMagick())) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: 'ImageMagick not found',\n\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t};\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\tconst tempDir = tmpdir();\n\tconst ts = Date.now();\n\n\tswitch (opts.exportMode) {\n\t\tcase 'frame': {\n\t\t\t// Export single selected frame\n\t\t\tconst frameIndex = opts.frameIndex ?? 0;\n\t\t\tlogs.push({ type: 'info', message: `Exporting frame ${frameIndex + 1}...` });\n\n\t\t\tconst frameFile = join(tempDir, `piclet-export-${ts}.png`);\n\t\t\tif (!(await extractFirstFrame(input, frameFile, frameIndex))) {\n\t\t\t\tlogs.push({ type: 'error', message: 'Failed to extract frame' });\n\t\t\t\treturn { success: false, error: 'Failed to extract frame', logs };\n\t\t\t}\n\n\t\t\t// Apply tools if any\n\t\t\tlet outputFile = frameFile;\n\t\t\tif (opts.tools && opts.tools.length > 0) {\n\t\t\t\tconst processedLogs: Array<{ type: string; message: string }> = [];\n\t\t\t\tconst result = await processCombined(frameFile, borderColor, opts, processedLogs);\n\t\t\t\tlogs.push(...processedLogs);\n\n\t\t\t\tif (result.outputs.length === 0) {\n\t\t\t\t\tcleanup(frameFile);\n\t\t\t\t\treturn { success: false, error: 'Processing failed', logs };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Move to final location\n\t\t\tconst finalOutput = `${fileInfo.dirname}/${fileInfo.filename}_frame${frameIndex + 1}.png`;\n\t\t\tif (outputFile === frameFile) {\n\t\t\t\trenameSync(frameFile, finalOutput);\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'success', message: `Exported frame ${frameIndex + 1}` });\n\t\t\treturn { success: true, output: basename(finalOutput), logs };\n\t\t}\n\n\t\tcase 'all-frames': {\n\t\t\t// Export all frames as PNGs\n\t\t\tlogs.push({ type: 'info', message: 'Extracting all frames...' });\n\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_frames`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\n\t\t\tconst frames = await extractAllFrames(input, outputDir, 'frame');\n\n\t\t\tif (frames.length === 0) {\n\t\t\t\tlogs.push({ type: 'error', message: 'Failed to extract frames' });\n\t\t\t\treturn { success: false, error: 'Failed to extract frames', logs };\n\t\t\t}\n\n\t\t\t// Apply tools to each frame if any\n\t\t\tif (opts.tools && opts.tools.length > 0) {\n\t\t\t\tlogs.push({ type: 'info', message: `Processing ${frames.length} frames...` });\n\t\t\t\tfor (let i = 0; i < frames.length; i++) {\n\t\t\t\t\tconst frameLogs: Array<{ type: string; message: string }> = [];\n\t\t\t\t\tawait processCombined(frames[i], borderColor, opts, frameLogs);\n\t\t\t\t}\n\t\t\t\tlogs.push({ type: 'success', message: `Processed ${frames.length} frames` });\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'success', message: `Exported ${frames.length} frames` });\n\t\t\treturn { success: true, output: `${frames.length} frames -> ${fileInfo.filename}_frames/`, logs };\n\t\t}\n\n\t\tcase 'gif': {\n\t\t\t// Process and export as GIF\n\t\t\tlogs.push({ type: 'info', message: 'Processing GIF...' });\n\n\t\t\t// Use standard processing which handles GIFs with -coalesce\n\t\t\tconst result = await processCombined(input, borderColor, opts, logs);\n\n\t\t\tif (result.outputs.length > 0) {\n\t\t\t\treturn { success: true, output: result.outputs.join('\\n'), outputPath: result.singleFilePath, logs };\n\t\t\t}\n\n\t\t\treturn { success: false, error: 'Processing failed', logs };\n\t\t}\n\n\t\tdefault:\n\t\t\treturn { success: false, error: 'Unknown export mode', logs };\n\t}\n}\n\nexport const config = {\n\tid: 'piclet',\n\tname: 'PicLet',\n\ticon: 'banana.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico'],\n};\n","import { existsSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tgetBorderColor,\n\tgetDimensions,\n\tisMultiFrame,\n\treplaceColor,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tnumber as promptNumber,\n\tpauseOnError,\n\ttext as promptText,\n} from '../lib/prompts.js';\n\n/** Processing options for color replace */\ninterface ProcessOptions {\n\tfromColor: string;\n\ttoColor: string;\n\tfuzz: number;\n}\n\n/**\n * Core processing logic for color replace\n */\nasync function processImage(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_recolor${outputExt}`;\n\n\twip(`Replacing ${options.fromColor} with ${options.toColor}...`);\n\n\tconst success = await replaceColor(\n\t\tinput,\n\t\toutput,\n\t\toptions.fromColor,\n\t\toptions.toColor,\n\t\toptions.fuzz,\n\t);\n\n\tif (!success) {\n\t\twipDone(false, 'Color replacement failed');\n\t\treturn false;\n\t}\n\twipDone(true, 'Color replaced');\n\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tconsole.log(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tconsole.log(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(detectedColor: string | null): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Color Replacement:${RESET}`);\n\tconsole.log(` ${DIM}Replace one color with another${RESET}`);\n\tconsole.log(` ${DIM}Colors can be hex (#fff), named (white), or rgb(...)${RESET}`);\n\tconsole.log('');\n\n\tconst defaultFrom = detectedColor || '#ffffff';\n\tlet fromColor = await promptText('Color to replace', defaultFrom);\n\tif (!fromColor) {\n\t\tfromColor = defaultFrom;\n\t}\n\n\tconsole.log('');\n\tlet toColor = await promptText('New color', '#000000');\n\tif (!toColor) {\n\t\ttoColor = '#000000';\n\t}\n\n\tconsole.log('');\n\tconsole.log(`${BOLD}Fuzz Value:${RESET} Controls color matching sensitivity`);\n\tconsole.log(` ${DIM}0-10% = Exact match only${RESET}`);\n\tconsole.log(` ${DIM}10-30% = Similar colors${RESET}`);\n\tconsole.log(` ${DIM}30-50% = Wider range${RESET}`);\n\tconsole.log('');\n\n\tlet fuzz = await promptNumber('Fuzz value (0-100)', 10, 0, 100);\n\tif (fuzz < 0 || fuzz > 100) {\n\t\tfuzz = 10;\n\t}\n\n\treturn { fromColor, toColor, fuzz };\n}\n\n/**\n * Replace color in image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Recolor');\n\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\n\tconst borderColor = await getBorderColor(input);\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\tif (borderColor) {\n\t\tinfo(`Detected corner color: ${borderColor}`);\n\t}\n\n\tconst options = await collectOptionsCLI(borderColor);\n\n\tconsole.log('');\n\treturn processImage(input, options);\n}\n\n/**\n * Replace color in image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst borderColor = await getBorderColor(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'recolor.html',\n\t\ttitle: 'PicLet - Recolor',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor,\n\t\t},\n\t\tdefaults: {\n\t\t\tfromColor: borderColor || '#ffffff',\n\t\t\ttoColor: '#000000',\n\t\t\tfuzz: 10,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst fromColor = (opts.fromColor as string) ?? '#ffffff';\n\t\t\tconst toColor = (opts.toColor as string) ?? '#000000';\n\t\t\tconst fuzz = (opts.fuzz as number) ?? 10;\n\t\t\treturn generatePreview(input, { fromColor, toColor, fuzz });\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst fromColor = (opts.fromColor as string) ?? '#ffffff';\n\t\t\tconst toColor = (opts.toColor as string) ?? '#000000';\n\t\t\tconst fuzz = (opts.fuzz as number) ?? 10;\n\t\t\tconst options: ProcessOptions = { fromColor, toColor, fuzz };\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_recolor${outputExt}`;\n\n\t\t\tlogs.push({ type: 'info', message: `Replacing ${fromColor} → ${toColor}...` });\n\n\t\t\tconst success = await replaceColor(input, output, fromColor, toColor, fuzz);\n\n\t\t\tif (success) {\n\t\t\t\tlogs.push({ type: 'success', message: 'Color replaced' });\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Color replacement failed' });\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\tconst success = await replaceColor(\n\t\t\tpreviewInput,\n\t\t\ttempOutput,\n\t\t\toptions.fromColor,\n\t\t\toptions.toColor,\n\t\t\toptions.fuzz,\n\t\t);\n\n\t\tif (!success) {\n\t\t\tcleanup(tempSource, tempOutput);\n\t\t\treturn { success: false, error: 'Color replacement failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\n\t\tcleanup(tempSource, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempSource, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'recolor',\n\tname: 'Recolor',\n\ticon: 'recolor.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],\n};\n","import { existsSync, readFileSync, renameSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, dirname, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tgetBorderColor,\n\tgetDimensions,\n\tisMultiFrame,\n\tremoveBackground,\n\tremoveBackgroundBorderOnly,\n\tsquarify,\n\ttrim,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tconfirm as promptConfirm,\n\tisUsingDefaults,\n\tnumber as promptNumber,\n\tpauseOnError,\n} from '../lib/prompts.js';\n\n/** Processing options for remove-bg */\ninterface ProcessOptions {\n\tfuzz: number;\n\tdoTrim: boolean;\n\tpreserveInner: boolean;\n\tmakeSquare: boolean;\n}\n\n/**\n * Core processing logic for background removal\n */\nasync function processImage(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\t// Preserve original extension for GIF files, use PNG for others\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg${outputExt}`;\n\tconst tempFile = `${fileInfo.dirname}/${fileInfo.filename}_temp${outputExt}`;\n\n\twip('Removing background...');\n\n\tlet bgRemoved = false;\n\tif (options.preserveInner && borderColor) {\n\t\tbgRemoved = await removeBackgroundBorderOnly(\n\t\t\tinput,\n\t\t\ttempFile,\n\t\t\tborderColor,\n\t\t\toptions.fuzz,\n\t\t);\n\t\tif (!bgRemoved) {\n\t\t\twarn('Border-only removal failed, using standard method');\n\t\t}\n\t}\n\n\tif (!bgRemoved && borderColor) {\n\t\tbgRemoved = await removeBackground(input, tempFile, borderColor, options.fuzz);\n\t}\n\n\tif (!bgRemoved) {\n\t\twipDone(false, 'Background removal failed');\n\t\tcleanup(tempFile);\n\t\treturn false;\n\t}\n\twipDone(true, 'Background removed');\n\n\t// Trim if requested\n\tif (options.doTrim) {\n\t\twip('Trimming transparent edges...');\n\t\tif (await trim(tempFile, output)) {\n\t\t\twipDone(true, 'Trimmed');\n\t\t\tcleanup(tempFile);\n\t\t} else {\n\t\t\twipDone(false, 'Trim failed, keeping untrimmed');\n\t\t\trenameSync(tempFile, output);\n\t\t}\n\t} else {\n\t\trenameSync(tempFile, output);\n\t}\n\n\t// Make square if requested\n\tif (options.makeSquare) {\n\t\twip('Making square...');\n\t\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square_temp${outputExt}`;\n\t\tif (await squarify(output, tempSquare)) {\n\t\t\trenameSync(tempSquare, output);\n\t\t\twipDone(true, 'Made square');\n\t\t} else {\n\t\t\twipDone(false, 'Square padding failed');\n\t\t\tcleanup(tempSquare);\n\t\t}\n\t}\n\n\t// Final dimensions\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tsuccess(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tsuccess(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Fuzz Value:${RESET} Controls color matching strictness`);\n\tconsole.log(` ${DIM}0-10% = Only exact or very similar colors${RESET}`);\n\tconsole.log(` ${DIM}10-30% = Somewhat similar colors${RESET}`);\n\tconsole.log(` ${DIM}30-70% = Aggressive removal${RESET}`);\n\tconsole.log(` ${DIM}70-100% = May affect non-background areas${RESET}`);\n\tconsole.log('');\n\n\tlet fuzz = await promptNumber('Fuzz value (0-100)', 10, 0, 100);\n\tif (fuzz < 0 || fuzz > 100) {\n\t\twarn('Invalid fuzz value, using 10');\n\t\tfuzz = 10;\n\t}\n\n\tconsole.log('');\n\tconst doTrim = await promptConfirm(\n\t\t'Trim transparent edges after removal?',\n\t\ttrue,\n\t);\n\n\tconsole.log('');\n\tconst preserveInner = await promptConfirm(\n\t\t'Preserve inner areas of same color? (border-only removal)',\n\t\tfalse,\n\t);\n\n\tconsole.log('');\n\tconst makeSquare = await promptConfirm(\n\t\t'Make output square with transparent padding?',\n\t\tfalse,\n\t);\n\n\treturn { fuzz, doTrim, preserveInner, makeSquare };\n}\n\n\n/**\n * Remove solid background from image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Remove Background');\n\n\t// Get original dimensions\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\n\t// Detect border color\n\tconst borderColor = await getBorderColor(input);\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\tif (borderColor) {\n\t\tinfo(`Detected border color: ${borderColor}`);\n\t}\n\n\t// Collect options via CLI or TUI\n\tconst options = await collectOptionsCLI();\n\n\tconsole.log('');\n\treturn processImage(input, borderColor, options);\n}\n\n/**\n * Remove solid background from image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\t// Get original dimensions\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\t// Detect border color\n\tconst borderColor = await getBorderColor(input);\n\n\t// Load config defaults\n\tconst config = loadConfig();\n\tconst defaults = config.removeBg;\n\n\t// Start GUI server\n\treturn startGuiServer({\n\t\thtmlFile: 'remove-bg.html',\n\t\ttitle: 'PicLet - Remove Background',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor,\n\t\t},\n\t\tdefaults: {\n\t\t\tfuzz: defaults.fuzz,\n\t\t\ttrim: defaults.trim,\n\t\t\tpreserveInner: defaults.preserveInner,\n\t\t\tmakeSquare: defaults.makeSquare,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\tfuzz: (opts.fuzz as number) ?? defaults.fuzz,\n\t\t\t\tdoTrim: (opts.trim as boolean) ?? defaults.trim,\n\t\t\t\tpreserveInner: (opts.preserveInner as boolean) ?? defaults.preserveInner,\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? defaults.makeSquare,\n\t\t\t};\n\t\t\treturn generatePreview(input, borderColor, options);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\t// Check dependencies\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\tfuzz: (opts.fuzz as number) ?? defaults.fuzz,\n\t\t\t\tdoTrim: (opts.trim as boolean) ?? defaults.trim,\n\t\t\t\tpreserveInner: (opts.preserveInner as boolean) ?? defaults.preserveInner,\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? defaults.makeSquare,\n\t\t\t};\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg.png`;\n\n\t\t\t// Process the image\n\t\t\tlogs.push({ type: 'info', message: 'Removing background...' });\n\n\t\t\tconst success = await processImageSilent(input, borderColor, options, logs);\n\n\t\t\tif (success) {\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Silent version of processImage for GUI mode (logs to array instead of console)\n */\nasync function processImageSilent(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n\tlogs: Array<{ type: string; message: string }>,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\t// Preserve original extension for GIF files, use PNG for others\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_nobg${outputExt}`;\n\tconst tempFile = `${fileInfo.dirname}/${fileInfo.filename}_temp${outputExt}`;\n\n\tlet bgRemoved = false;\n\tif (options.preserveInner && borderColor) {\n\t\tbgRemoved = await removeBackgroundBorderOnly(\n\t\t\tinput,\n\t\t\ttempFile,\n\t\t\tborderColor,\n\t\t\toptions.fuzz,\n\t\t);\n\t\tif (!bgRemoved) {\n\t\t\tlogs.push({ type: 'warn', message: 'Border-only removal failed, using standard method' });\n\t\t}\n\t}\n\n\tif (!bgRemoved && borderColor) {\n\t\tbgRemoved = await removeBackground(input, tempFile, borderColor, options.fuzz);\n\t}\n\n\tif (!bgRemoved) {\n\t\tlogs.push({ type: 'error', message: 'Background removal failed' });\n\t\tcleanup(tempFile);\n\t\treturn false;\n\t}\n\tlogs.push({ type: 'success', message: 'Background removed' });\n\n\t// Trim if requested\n\tif (options.doTrim) {\n\t\tlogs.push({ type: 'info', message: 'Trimming transparent edges...' });\n\t\tif (await trim(tempFile, output)) {\n\t\t\tlogs.push({ type: 'success', message: 'Trimmed' });\n\t\t\tcleanup(tempFile);\n\t\t} else {\n\t\t\tlogs.push({ type: 'warn', message: 'Trim failed, keeping untrimmed' });\n\t\t\trenameSync(tempFile, output);\n\t\t}\n\t} else {\n\t\trenameSync(tempFile, output);\n\t}\n\n\t// Make square if requested\n\tif (options.makeSquare) {\n\t\tlogs.push({ type: 'info', message: 'Making square...' });\n\t\tconst tempSquare = `${fileInfo.dirname}/${fileInfo.filename}_square_temp${outputExt}`;\n\t\tif (await squarify(output, tempSquare)) {\n\t\t\trenameSync(tempSquare, output);\n\t\t\tlogs.push({ type: 'success', message: 'Made square' });\n\t\t} else {\n\t\t\tlogs.push({ type: 'warn', message: 'Square padding failed' });\n\t\t\tcleanup(tempSquare);\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\tborderColor: string | null,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempFile = join(tempDir, `piclet-preview-${timestamp}.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}-out.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\t// Remove background\n\t\tlet bgRemoved = false;\n\t\tif (options.preserveInner && borderColor) {\n\t\t\tbgRemoved = await removeBackgroundBorderOnly(previewInput, tempFile, borderColor, options.fuzz);\n\t\t}\n\t\tif (!bgRemoved && borderColor) {\n\t\t\tbgRemoved = await removeBackground(previewInput, tempFile, borderColor, options.fuzz);\n\t\t}\n\t\tif (!bgRemoved) {\n\t\t\tcleanup(tempSource);\n\t\t\treturn { success: false, error: 'Background removal failed' };\n\t\t}\n\n\t\t// Trim if requested\n\t\tlet currentFile = tempFile;\n\t\tif (options.doTrim) {\n\t\t\tif (await trim(tempFile, tempOutput)) {\n\t\t\t\tcleanup(tempFile);\n\t\t\t\tcurrentFile = tempOutput;\n\t\t\t}\n\t\t}\n\n\t\t// Make square if requested\n\t\tif (options.makeSquare) {\n\t\t\tconst squareFile = join(tempDir, `piclet-preview-${timestamp}-sq.png`);\n\t\t\tif (await squarify(currentFile, squareFile)) {\n\t\t\t\tcleanup(currentFile);\n\t\t\t\tcurrentFile = squareFile;\n\t\t\t}\n\t\t}\n\n\t\t// Read as base64\n\t\tconst buffer = readFileSync(currentFile);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\t// Get dimensions\n\t\tconst dims = await getDimensions(currentFile);\n\n\t\t// Cleanup\n\t\tcleanup(currentFile, tempFile, tempOutput, tempSource);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempFile, tempOutput, tempSource);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'remove-bg',\n\tname: 'Remove Background',\n\ticon: 'removebg.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.ico', '.gif'],\n};\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\n\n/** PicLet configuration */\nexport interface PicLetConfig {\n\tremoveBg: {\n\t\tfuzz: number;\n\t\ttrim: boolean;\n\t\tpreserveInner: boolean;\n\t\tmakeSquare: boolean;\n\t};\n\trescale: {\n\t\tdefaultScale: number;\n\t\tmakeSquare: boolean;\n\t};\n\ticonpack: {\n\t\tplatforms: ('web' | 'android' | 'ios')[];\n\t};\n}\n\n/** Default configuration */\nexport const DEFAULT_CONFIG: PicLetConfig = {\n\tremoveBg: {\n\t\tfuzz: 10,\n\t\ttrim: true,\n\t\tpreserveInner: false,\n\t\tmakeSquare: false,\n\t},\n\trescale: {\n\t\tdefaultScale: 50,\n\t\tmakeSquare: false,\n\t},\n\ticonpack: {\n\t\tplatforms: ['web', 'android', 'ios'],\n\t},\n};\n\n/** Get config directory path */\nfunction getConfigDir(): string {\n\treturn join(homedir(), '.config', 'piclet');\n}\n\n/** Get config file path */\nexport function getConfigPath(): string {\n\treturn join(getConfigDir(), 'config.json');\n}\n\n/** Load configuration from file */\nexport function loadConfig(): PicLetConfig {\n\tconst configPath = getConfigPath();\n\n\tif (!existsSync(configPath)) {\n\t\treturn { ...DEFAULT_CONFIG };\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(configPath, 'utf-8');\n\t\tconst loaded = JSON.parse(content) as Partial<PicLetConfig>;\n\t\treturn {\n\t\t\tremoveBg: { ...DEFAULT_CONFIG.removeBg, ...loaded.removeBg },\n\t\t\trescale: { ...DEFAULT_CONFIG.rescale, ...loaded.rescale },\n\t\t\ticonpack: { ...DEFAULT_CONFIG.iconpack, ...loaded.iconpack },\n\t\t};\n\t} catch {\n\t\treturn { ...DEFAULT_CONFIG };\n\t}\n}\n\n/** Save configuration to file */\nexport function saveConfig(config: PicLetConfig): void {\n\tconst configPath = getConfigPath();\n\tconst configDir = dirname(configPath);\n\n\tif (!existsSync(configDir)) {\n\t\tmkdirSync(configDir, { recursive: true });\n\t}\n\n\twriteFileSync(configPath, JSON.stringify(config, null, 2));\n}\n\n/** Reset configuration to defaults */\nexport function resetConfig(): void {\n\tconst configPath = getConfigPath();\n\tconst configDir = dirname(configPath);\n\n\tif (!existsSync(configDir)) {\n\t\tmkdirSync(configDir, { recursive: true });\n\t}\n\n\twriteFileSync(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2));\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\tinfo,\n\tsuccess,\n\twarn,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tgetDimensions,\n\tisMultiFrame,\n\tresize,\n\tscaleWithPadding,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tconfirm as promptConfirm,\n\tnumber as promptNumber,\n\tpauseOnError,\n} from '../lib/prompts.js';\n\n/** Processing options for rescale */\ninterface ProcessOptions {\n\twidth: number;\n\theight: number;\n\tmakeSquare: boolean;\n}\n\n/**\n * Scale image with optional padding\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Get file info\n\tconst fileInfo = getFileInfo(input);\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_scaled${fileInfo.extension}`;\n\n\theader('PicLet Scale Image');\n\n\t// Get original dimensions\n\twip('Reading image dimensions...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\tconst [origW, origH] = dims;\n\twipDone(true, `Original size: ${origW}x${origH}`);\n\n\t// Check if image is square\n\tif (origW !== origH) {\n\t\twarn(`Image is not square (${origW}x${origH})`);\n\t}\n\n\tconsole.log('');\n\tconsole.log(`${BOLD}Scaling Options:${RESET}`);\n\tconsole.log(\n\t\t` ${DIM}Enter 0 for auto-calculate based on other dimension${RESET}`,\n\t);\n\tconsole.log(\n\t\t` ${DIM}Enter single number for both to make square output${RESET}`,\n\t);\n\tconsole.log('');\n\n\t// Get target dimensions\n\tlet targetW = await promptNumber('Width (0 for auto)', 0, 0);\n\tlet targetH = await promptNumber('Height (0 for auto)', 0, 0);\n\n\t// Determine scaling mode\n\tlet makeSquare = false;\n\n\tif (targetW === 0 && targetH === 0) {\n\t\t// Default: scale to 50%\n\t\ttargetW = Math.floor(origW / 2);\n\t\ttargetH = Math.floor(origH / 2);\n\t\tinfo(`Using default: 50% scale (${targetW}x${targetH})`);\n\t} else if (targetW > 0 && targetH === 0) {\n\t\t// Width specified, calculate height\n\t\ttargetH = Math.floor((targetW * origH) / origW);\n\t\tinfo(`Calculated height: ${targetH}`);\n\t} else if (targetW === 0 && targetH > 0) {\n\t\t// Height specified, calculate width\n\t\ttargetW = Math.floor((targetH * origW) / origH);\n\t\tinfo(`Calculated width: ${targetW}`);\n\t}\n\n\t// Ask about square padding\n\tconsole.log('');\n\tmakeSquare = await promptConfirm(\n\t\t'Make output square with transparent padding?',\n\t\tfalse,\n\t);\n\n\tif (makeSquare) {\n\t\tconst maxDim = Math.max(targetW, targetH);\n\t\ttargetW = maxDim;\n\t\ttargetH = maxDim;\n\t\tinfo(`Output will be ${targetW}x${targetH} (square with padding)`);\n\t}\n\n\tconsole.log('');\n\twip('Scaling image...');\n\n\tlet scaled = false;\n\tif (makeSquare) {\n\t\t// Scale and add transparent padding for square output\n\t\tscaled = await scaleWithPadding(input, output, targetW, targetH);\n\t} else {\n\t\t// Standard resize\n\t\tscaled = await resize(input, output, targetW, targetH);\n\t}\n\n\tif (!scaled || !existsSync(output)) {\n\t\twipDone(false, 'Scaling failed');\n\t\treturn false;\n\t}\n\n\t// Get final dimensions\n\tconst finalDims = await getDimensions(output);\n\tif (finalDims) {\n\t\twipDone(true, `Scaled to ${finalDims[0]}x${finalDims[1]}`);\n\t} else {\n\t\twipDone(true, 'Scaled');\n\t}\n\n\tconsole.log('');\n\tsuccess(`Output: ${output}`);\n\treturn true;\n}\n\n/**\n * Scale image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\treturn startGuiServer({\n\t\thtmlFile: 'rescale.html',\n\t\ttitle: 'PicLet - Scale Image',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tmakeSquare: false,\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\twidth: (opts.width as number) ?? Math.round(dims[0] / 2),\n\t\t\t\theight: (opts.height as number) ?? Math.round(dims[1] / 2),\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? false,\n\t\t\t};\n\t\t\treturn generatePreview(input, options);\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst options: ProcessOptions = {\n\t\t\t\twidth: (opts.width as number) ?? Math.round(dims[0] / 2),\n\t\t\t\theight: (opts.height as number) ?? Math.round(dims[1] / 2),\n\t\t\t\tmakeSquare: (opts.makeSquare as boolean) ?? false,\n\t\t\t};\n\n\t\t\tlogs.push({ type: 'info', message: `Scaling to ${options.width}x${options.height}...` });\n\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_scaled${fileInfo.extension}`;\n\t\t\tlet scaled = false;\n\n\t\t\tif (options.makeSquare) {\n\t\t\t\tconst maxDim = Math.max(options.width, options.height);\n\t\t\t\tscaled = await scaleWithPadding(input, output, maxDim, maxDim);\n\t\t\t} else {\n\t\t\t\tscaled = await resize(input, output, options.width, options.height);\n\t\t\t}\n\n\t\t\tif (scaled && existsSync(output)) {\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\tlogs.push({ type: 'success', message: 'Scaled successfully' });\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Scaling failed' });\n\t\t\treturn { success: false, error: 'Scaling failed', logs };\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\tlet scaled = false;\n\t\tlet targetW = options.width;\n\t\tlet targetH = options.height;\n\n\t\tif (options.makeSquare) {\n\t\t\tconst maxDim = Math.max(targetW, targetH);\n\t\t\ttargetW = maxDim;\n\t\t\ttargetH = maxDim;\n\t\t\tscaled = await scaleWithPadding(previewInput, tempOutput, targetW, targetH);\n\t\t} else {\n\t\t\tscaled = await resize(previewInput, tempOutput, targetW, targetH);\n\t\t}\n\n\t\tif (!scaled || !existsSync(tempOutput)) {\n\t\t\tcleanup(tempSource);\n\t\t\treturn { success: false, error: 'Scaling failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\t\tcleanup(tempSource, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempSource, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'rescale',\n\tname: 'Scale Image',\n\ticon: 'rescale.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],\n};\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { basename, join } from 'node:path';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport { error, header, info, success, wip, wipDone } from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\tgetDimensions,\n\tresize,\n\tscaleFillCrop,\n\tscaleWithPadding,\n\tsquarify,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport { loadPresets, type Preset } from '../lib/presets.js';\nimport { pauseOnError, select as promptSelect } from '../lib/prompts.js';\n\ntype ScaleMode = 'fit' | 'fill' | 'stretch';\n\n/**\n * Scale image using the specified mode\n */\nasync function scaleImage(\n\tinput: string,\n\toutput: string,\n\twidth: number,\n\theight: number,\n\tmode: ScaleMode,\n): Promise<boolean> {\n\tswitch (mode) {\n\t\tcase 'fill':\n\t\t\treturn scaleFillCrop(input, output, width, height);\n\t\tcase 'stretch':\n\t\t\treturn resize(input, output, width, height);\n\t\tcase 'fit':\n\t\tdefault:\n\t\t\treturn scaleWithPadding(input, output, width, height);\n\t}\n}\n\n/**\n * Generate images for a preset\n */\nasync function generatePresetImages(\n\tsourceImg: string,\n\toutputDir: string,\n\tpreset: Preset,\n\tscaleMode: ScaleMode = 'fit',\n\tlogs?: Array<{ type: string; message: string }>,\n): Promise<number> {\n\tlet failed = 0;\n\tconst total = preset.icons.length;\n\n\tfor (let i = 0; i < total; i++) {\n\t\tconst icon = preset.icons[i];\n\t\tconst outputPath = join(outputDir, icon.filename);\n\n\t\tif (logs) {\n\t\t\tlogs.push({ type: 'info', message: `[${i + 1}/${total}] ${icon.filename}` });\n\t\t} else {\n\t\t\twip(`[${i + 1}/${total}] Generating ${icon.filename}...`);\n\t\t}\n\n\t\tconst scaled = await scaleImage(\n\t\t\tsourceImg,\n\t\t\toutputPath,\n\t\t\ticon.width,\n\t\t\ticon.height,\n\t\t\tscaleMode,\n\t\t);\n\n\t\tif (scaled) {\n\t\t\tif (!logs) {\n\t\t\t\twipDone(true, `[${i + 1}/${total}] ${icon.filename} (${icon.width}x${icon.height})`);\n\t\t\t}\n\t\t} else {\n\t\t\tif (logs) {\n\t\t\t\tlogs.push({ type: 'error', message: `Failed: ${icon.filename}` });\n\t\t\t} else {\n\t\t\t\twipDone(false, `[${i + 1}/${total}] Failed: ${icon.filename}`);\n\t\t\t}\n\t\t\tfailed++;\n\t\t}\n\t}\n\n\treturn failed;\n}\n\n/**\n * Generate store assets (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\n\theader('PicLet Store Pack');\n\n\t// Analyze source image\n\twip('Analyzing source image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\twipDone(true, `Source: ${dims[0]}x${dims[1]}`);\n\n\t// Load presets\n\tconst presets = loadPresets();\n\tconst choices = presets.map((p) => ({\n\t\ttitle: p.name,\n\t\tvalue: p.id,\n\t\tdescription: p.description,\n\t}));\n\n\t// Select preset\n\tconsole.log('');\n\tconst selectedId = await promptSelect('Select target store:', choices, presets[0].id);\n\tconst preset = presets.find((p) => p.id === selectedId);\n\n\tif (!preset) {\n\t\terror('Preset not found');\n\t\treturn false;\n\t}\n\n\t// Create output directory\n\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${preset.id}`;\n\tmkdirSync(outputDir, { recursive: true });\n\tinfo(`Output: ${outputDir}`);\n\n\t// Prepare source (make square for consistent scaling)\n\tconsole.log('');\n\twip('Preparing source...');\n\tconst tempSource = join(outputDir, '.source.png');\n\n\tif (!(await squarify(input, tempSource))) {\n\t\twipDone(false, 'Failed to prepare source');\n\t\treturn false;\n\t}\n\twipDone(true, 'Source prepared');\n\n\t// Generate images\n\tconsole.log('');\n\theader(`Generating ${preset.name} Images`);\n\n\tconst failed = await generatePresetImages(tempSource, outputDir, preset);\n\tcleanup(tempSource);\n\n\tconsole.log('');\n\tif (failed === 0) {\n\t\tsuccess(`All ${preset.icons.length} images generated!`);\n\t} else {\n\t\terror(`${failed}/${preset.icons.length} images failed`);\n\t}\n\n\tinfo(`Output: ${outputDir}`);\n\treturn failed === 0;\n}\n\n/**\n * Generate store assets (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\tconst fileInfo = getFileInfo(input);\n\tconst presets = loadPresets();\n\n\treturn startGuiServer({\n\t\thtmlFile: 'storepack.html',\n\t\ttitle: 'PicLet - Store Pack',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\tpresets: presets.map((p) => ({\n\t\t\t\tid: p.id,\n\t\t\t\tname: p.name,\n\t\t\t\tdescription: p.description,\n\t\t\t\ticons: p.icons,\n\t\t\t})),\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst presetId = opts.preset as string;\n\t\t\tconst scaleMode = (opts.scaleMode as ScaleMode) || 'fit';\n\t\t\tconst preset = presets.find((p) => p.id === presetId);\n\n\t\t\tif (!preset) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'Preset not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'No preset selected' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Create output directory\n\t\t\tconst outputDir = `${fileInfo.dirname}/${fileInfo.filename}_${preset.id}`;\n\t\t\tmkdirSync(outputDir, { recursive: true });\n\t\t\tlogs.push({ type: 'info', message: `Output: ${outputDir}` });\n\t\t\tlogs.push({ type: 'info', message: `Scale mode: ${scaleMode}` });\n\n\t\t\t// Generate images directly from source\n\t\t\tlogs.push({ type: 'info', message: `Generating ${preset.icons.length} images...` });\n\t\t\tconst failed = await generatePresetImages(input, outputDir, preset, scaleMode, logs);\n\n\t\t\tif (failed === 0) {\n\t\t\t\tlogs.push({ type: 'success', message: `All ${preset.icons.length} images generated` });\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${preset.icons.length} images saved to ${fileInfo.filename}_${preset.id}/`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `${failed} image(s) failed`,\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\nexport const config = {\n\tid: 'storepack',\n\tname: 'Store Pack',\n\ticon: 'storepack.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif'],\n};\n","import { existsSync, readFileSync, renameSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../lib/config.js';\nimport { startGuiServer } from '../lib/gui-server.js';\nimport {\n\tBOLD,\n\tDIM,\n\tRESET,\n\terror,\n\theader,\n\twip,\n\twipDone,\n} from '../lib/logger.js';\nimport {\n\tcheckImageMagick,\n\tcleanup,\n\textractFirstFrame,\n\tflipHorizontal,\n\tflipVertical,\n\tgetDimensions,\n\tisMultiFrame,\n\trotate,\n} from '../lib/magick.js';\nimport { getFileInfo, normalizePath } from '../lib/paths.js';\nimport {\n\tisUsingDefaults,\n\tpauseOnError,\n\tselect as promptSelect,\n} from '../lib/prompts.js';\n\n/** Transform operation types */\ntype TransformType = 'flip-h' | 'flip-v' | 'rotate-90' | 'rotate-180' | 'rotate-270';\n\n/** Processing options for transform */\ninterface ProcessOptions {\n\ttransform: TransformType;\n}\n\nconst TRANSFORM_LABELS: Record<TransformType, string> = {\n\t'flip-h': 'Flip Horizontal',\n\t'flip-v': 'Flip Vertical',\n\t'rotate-90': 'Rotate 90°',\n\t'rotate-180': 'Rotate 180°',\n\t'rotate-270': 'Rotate 270°',\n};\n\n/**\n * Core processing logic for transform\n */\nasync function processImage(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<boolean> {\n\tconst fileInfo = getFileInfo(input);\n\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\tconst suffix = options.transform.replace('-', '');\n\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_${suffix}${outputExt}`;\n\n\twip(`Applying ${TRANSFORM_LABELS[options.transform]}...`);\n\n\tlet success = false;\n\tswitch (options.transform) {\n\t\tcase 'flip-h':\n\t\t\tsuccess = await flipHorizontal(input, output);\n\t\t\tbreak;\n\t\tcase 'flip-v':\n\t\t\tsuccess = await flipVertical(input, output);\n\t\t\tbreak;\n\t\tcase 'rotate-90':\n\t\t\tsuccess = await rotate(input, output, 90);\n\t\t\tbreak;\n\t\tcase 'rotate-180':\n\t\t\tsuccess = await rotate(input, output, 180);\n\t\t\tbreak;\n\t\tcase 'rotate-270':\n\t\t\tsuccess = await rotate(input, output, 270);\n\t\t\tbreak;\n\t}\n\n\tif (!success) {\n\t\twipDone(false, 'Transform failed');\n\t\treturn false;\n\t}\n\twipDone(true, TRANSFORM_LABELS[options.transform]);\n\n\t// Final dimensions\n\tconst finalDims = await getDimensions(output);\n\n\tconsole.log('');\n\tif (finalDims) {\n\t\tconsole.log(`Output: ${output} (${finalDims[0]}x${finalDims[1]})`);\n\t} else {\n\t\tconsole.log(`Output: ${output}`);\n\t}\n\treturn true;\n}\n\n/**\n * Collect options via CLI prompts\n */\nasync function collectOptionsCLI(): Promise<ProcessOptions> {\n\tconsole.log('');\n\tconsole.log(`${BOLD}Transform Options:${RESET}`);\n\tconsole.log(` ${DIM}1. Flip Horizontal (mirror)${RESET}`);\n\tconsole.log(` ${DIM}2. Flip Vertical${RESET}`);\n\tconsole.log(` ${DIM}3. Rotate 90° clockwise${RESET}`);\n\tconsole.log(` ${DIM}4. Rotate 180°${RESET}`);\n\tconsole.log(` ${DIM}5. Rotate 270° clockwise${RESET}`);\n\tconsole.log('');\n\n\tconst transform = await promptSelect<TransformType>(\n\t\t'Select transform',\n\t\t[\n\t\t\t{ value: 'flip-h', title: 'Flip Horizontal' },\n\t\t\t{ value: 'flip-v', title: 'Flip Vertical' },\n\t\t\t{ value: 'rotate-90', title: 'Rotate 90°' },\n\t\t\t{ value: 'rotate-180', title: 'Rotate 180°' },\n\t\t\t{ value: 'rotate-270', title: 'Rotate 270°' },\n\t\t],\n\t\t'flip-h',\n\t);\n\n\treturn { transform: transform ?? 'flip-h' };\n}\n\n/**\n * Transform image (CLI mode)\n */\nexport async function run(inputRaw: string): Promise<boolean> {\n\t// Check dependencies\n\tif (!(await checkImageMagick())) {\n\t\terror('ImageMagick not found. Please install it:');\n\t\tconsole.log(' sudo apt update && sudo apt install imagemagick');\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\t// Normalize path\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\tawait pauseOnError();\n\t\treturn false;\n\t}\n\n\theader('PicLet Transform');\n\n\t// Get original dimensions\n\twip('Analyzing image...');\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\twipDone(false, 'Failed to read image');\n\t\treturn false;\n\t}\n\twipDone(true, `Size: ${dims[0]}x${dims[1]}`);\n\n\t// Collect options via CLI\n\tconst options = await collectOptionsCLI();\n\n\tconsole.log('');\n\treturn processImage(input, options);\n}\n\n/**\n * Transform image (GUI mode)\n */\nexport async function runGUI(inputRaw: string): Promise<boolean> {\n\tconst input = normalizePath(inputRaw);\n\n\tif (!existsSync(input)) {\n\t\terror(`File not found: ${input}`);\n\t\treturn false;\n\t}\n\n\tconst dims = await getDimensions(input);\n\tif (!dims) {\n\t\terror('Failed to read image dimensions');\n\t\treturn false;\n\t}\n\n\treturn startGuiServer({\n\t\thtmlFile: 'transform.html',\n\t\ttitle: 'PicLet - Transform',\n\t\timageInfo: {\n\t\t\tfilePath: input,\n\t\t\tfileName: basename(input),\n\t\t\twidth: dims[0],\n\t\t\theight: dims[1],\n\t\t\tborderColor: null,\n\t\t},\n\t\tdefaults: {\n\t\t\ttransform: 'flip-h',\n\t\t},\n\t\tonPreview: async (opts) => {\n\t\t\tconst transform = (opts.transform as TransformType) ?? 'flip-h';\n\t\t\treturn generatePreview(input, { transform });\n\t\t},\n\t\tonProcess: async (opts) => {\n\t\t\tconst logs: Array<{ type: string; message: string }> = [];\n\n\t\t\tif (!(await checkImageMagick())) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: 'ImageMagick not found',\n\t\t\t\t\tlogs: [{ type: 'error', message: 'ImageMagick not found. Install with: sudo apt install imagemagick' }],\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'info', message: `Processing ${basename(input)}...` });\n\n\t\t\tconst transform = (opts.transform as TransformType) ?? 'flip-h';\n\t\t\tconst options: ProcessOptions = { transform };\n\n\t\t\tconst fileInfo = getFileInfo(input);\n\t\t\tconst outputExt = fileInfo.extension.toLowerCase() === '.gif' ? '.gif' : '.png';\n\t\t\tconst suffix = transform.replace('-', '');\n\t\t\tconst output = `${fileInfo.dirname}/${fileInfo.filename}_${suffix}${outputExt}`;\n\n\t\t\tlogs.push({ type: 'info', message: `Applying ${TRANSFORM_LABELS[transform]}...` });\n\n\t\t\tlet success = false;\n\t\t\tswitch (transform) {\n\t\t\t\tcase 'flip-h':\n\t\t\t\t\tsuccess = await flipHorizontal(input, output);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'flip-v':\n\t\t\t\t\tsuccess = await flipVertical(input, output);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'rotate-90':\n\t\t\t\t\tsuccess = await rotate(input, output, 90);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'rotate-180':\n\t\t\t\t\tsuccess = await rotate(input, output, 180);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'rotate-270':\n\t\t\t\t\tsuccess = await rotate(input, output, 270);\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (success) {\n\t\t\t\tlogs.push({ type: 'success', message: 'Transform applied' });\n\t\t\t\tconst finalDims = await getDimensions(output);\n\t\t\t\tconst sizeStr = finalDims ? ` (${finalDims[0]}x${finalDims[1]})` : '';\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\toutput: `${basename(output)}${sizeStr}`,\n\t\t\t\t\tlogs,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlogs.push({ type: 'error', message: 'Transform failed' });\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: 'Processing failed',\n\t\t\t\tlogs,\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * Generate preview image as base64 data URL\n */\nasync function generatePreview(\n\tinput: string,\n\toptions: ProcessOptions,\n): Promise<{ success: boolean; imageData?: string; width?: number; height?: number; error?: string }> {\n\tconst tempDir = tmpdir();\n\tconst timestamp = Date.now();\n\tconst tempSource = join(tempDir, `piclet-preview-${timestamp}-src.png`);\n\tconst tempOutput = join(tempDir, `piclet-preview-${timestamp}.png`);\n\n\ttry {\n\t\t// For GIFs, extract first frame only for fast preview\n\t\tlet previewInput = input;\n\t\tif (isMultiFrame(input)) {\n\t\t\tif (!(await extractFirstFrame(input, tempSource))) {\n\t\t\t\treturn { success: false, error: 'Failed to extract frame' };\n\t\t\t}\n\t\t\tpreviewInput = tempSource;\n\t\t}\n\n\t\tlet success = false;\n\t\tswitch (options.transform) {\n\t\t\tcase 'flip-h':\n\t\t\t\tsuccess = await flipHorizontal(previewInput, tempOutput);\n\t\t\t\tbreak;\n\t\t\tcase 'flip-v':\n\t\t\t\tsuccess = await flipVertical(previewInput, tempOutput);\n\t\t\t\tbreak;\n\t\t\tcase 'rotate-90':\n\t\t\t\tsuccess = await rotate(previewInput, tempOutput, 90);\n\t\t\t\tbreak;\n\t\t\tcase 'rotate-180':\n\t\t\t\tsuccess = await rotate(previewInput, tempOutput, 180);\n\t\t\t\tbreak;\n\t\t\tcase 'rotate-270':\n\t\t\t\tsuccess = await rotate(previewInput, tempOutput, 270);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (!success) {\n\t\t\tcleanup(tempSource, tempOutput);\n\t\t\treturn { success: false, error: 'Transform failed' };\n\t\t}\n\n\t\tconst buffer = readFileSync(tempOutput);\n\t\tconst base64 = buffer.toString('base64');\n\t\tconst imageData = `data:image/png;base64,${base64}`;\n\n\t\tconst dims = await getDimensions(tempOutput);\n\n\t\tcleanup(tempSource, tempOutput);\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\timageData,\n\t\t\twidth: dims?.[0],\n\t\t\theight: dims?.[1],\n\t\t};\n\t} catch (err) {\n\t\tcleanup(tempSource, tempOutput);\n\t\treturn { success: false, error: (err as Error).message };\n\t}\n}\n\nexport const config = {\n\tid: 'transform',\n\tname: 'Transform',\n\ticon: 'transform.ico',\n\textensions: ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico'],\n};\n","import * as border from '../tools/border.js';\nimport * as extractFrames from '../tools/extract-frames.js';\nimport * as filter from '../tools/filter.js';\nimport * as iconpack from '../tools/iconpack.js';\nimport * as makeicon from '../tools/makeicon.js';\nimport * as picletMain from '../tools/piclet-main.js';\nimport * as recolor from '../tools/recolor.js';\nimport * as removeBg from '../tools/remove-bg.js';\nimport * as rescale from '../tools/rescale.js';\nimport * as storepack from '../tools/storepack.js';\nimport * as transform from '../tools/transform.js';\n\n/** Tool configuration */\nexport interface ToolConfig {\n\tid: string;\n\tname: string;\n\ticon: string;\n\textensions: string[];\n}\n\n/** Tool with config and run function */\nexport interface Tool {\n\tconfig: ToolConfig;\n\trun: (file: string) => Promise<boolean>;\n\trunGUI?: (file: string) => Promise<boolean>;\n}\n\n/** Unified tool (GUI only) */\nexport interface UnifiedTool {\n\tconfig: ToolConfig;\n\trunGUI: (file: string) => Promise<boolean>;\n}\n\n/** All available tools (individual) */\nexport const tools: Tool[] = [\n\t{ config: makeicon.config, run: makeicon.run, runGUI: makeicon.runGUI },\n\t{ config: removeBg.config, run: removeBg.run, runGUI: removeBg.runGUI },\n\t{ config: rescale.config, run: rescale.run, runGUI: rescale.runGUI },\n\t{ config: iconpack.config, run: iconpack.run, runGUI: iconpack.runGUI },\n\t{ config: storepack.config, run: storepack.run, runGUI: storepack.runGUI },\n\t{ config: transform.config, run: transform.run, runGUI: transform.runGUI },\n\t{ config: filter.config, run: filter.run, runGUI: filter.runGUI },\n\t{ config: border.config, run: border.run, runGUI: border.runGUI },\n\t{ config: recolor.config, run: recolor.run, runGUI: recolor.runGUI },\n\t{ config: extractFrames.config, run: extractFrames.run, runGUI: extractFrames.runGUI },\n];\n\n/** Unified PicLet tool (all-in-one) */\nexport const picletTool: UnifiedTool = {\n\tconfig: picletMain.config,\n\trunGUI: picletMain.runGUI,\n};\n\n/** Tools that use TUI (terminal GUI) mode */\nexport const tuiTools = ['makeicon', 'remove-bg', 'rescale', 'iconpack', 'storepack', 'transform', 'filter', 'border', 'recolor', 'extract-frames'];\n\n/** Get tool by ID */\nexport function getTool(id: string): Tool | undefined {\n\treturn tools.find((t) => t.config.id === id);\n}\n\n/** Get all unique extensions from tools */\nexport function getAllExtensions(): string[] {\n\tconst extensions = new Set<string>();\n\tfor (const { config } of tools) {\n\t\tfor (const ext of config.extensions) {\n\t\t\textensions.add(ext);\n\t\t}\n\t}\n\treturn Array.from(extensions);\n}\n\n/** Get tools that support a given extension */\nexport function getToolsForExtension(extension: string): Tool[] {\n\treturn tools.filter((t) => t.config.extensions.includes(extension));\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { getConfigPath, loadConfig, resetConfig } from '../../lib/config.js';\n\nexport function registerConfigCommand(program: Command): void {\n\tconst configCmd = program\n\t\t.command('config')\n\t\t.description('Display current settings')\n\t\t.action(() => {\n\t\t\tconst config = loadConfig();\n\t\t\tconsole.log(chalk.white.bold('\\n PicLet Configuration'));\n\t\t\tconsole.log(chalk.gray(` ${getConfigPath()}\\n`));\n\t\t\tconsole.log(JSON.stringify(config, null, 2));\n\t\t\tconsole.log();\n\t\t});\n\n\tconfigCmd\n\t\t.command('reset')\n\t\t.description('Restore defaults')\n\t\t.action(() => {\n\t\t\tresetConfig();\n\t\t\tconsole.log(chalk.green('Configuration reset to defaults.'));\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as extractFrames from '../../tools/extract-frames.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerExtractFramesCommand(program: Command): void {\n\tprogram\n\t\t.command('extract-frames <files...>')\n\t\t.alias('frames')\n\t\t.description('Extract frames from animated GIF')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, extractFrames.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await extractFrames.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'extract-frames',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as filter from '../../tools/filter.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerFilterCommand(program: Command): void {\n\tprogram\n\t\t.command('filter <files...>')\n\t\t.description('Apply color filters (grayscale, sepia, etc.)')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, filter.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await filter.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'filter',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import type { Command } from 'commander';\nimport { showHelp } from '../index.js';\n\nexport function registerHelpCommand(program: Command): void {\n\tprogram\n\t\t.command('help')\n\t\t.description('Show help')\n\t\t.action(() => {\n\t\t\tshowHelp();\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as iconpack from '../../tools/iconpack.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerIconpackCommand(program: Command): void {\n\tprogram\n\t\t.command('iconpack <files...>')\n\t\t.description('Generate icon sets for Web, Android, iOS')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, iconpack.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await iconpack.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'iconpack',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\r\nimport type { Command } from 'commander';\r\nimport { showBanner } from '../../lib/banner.js';\r\nimport { wslToWindows } from '../../lib/paths.js';\r\nimport { isWSL, isWSLInteropEnabled } from '../../lib/registry.js';\r\nimport { generateRegFile, registerAllTools, unregisterAllTools } from '../registry.js';\r\nimport { tools } from '../tools.js';\r\n\r\nexport function registerInstallCommand(program: Command): void {\r\n\tprogram\r\n\t\t.command('install')\r\n\t\t.description('Install Windows shell context menu integration')\r\n\t\t.action(async () => {\r\n\t\t\tshowBanner();\r\n\t\t\tconsole.log(chalk.bold('Installing...\\n'));\r\n\r\n\t\t\tif (!isWSL()) {\r\n\t\t\t\tconsole.log(\r\n\t\t\t\t\tchalk.yellow('! Not running in WSL. Registry integration skipped.'),\r\n\t\t\t\t);\r\n\t\t\t\tconsole.log(\r\n\t\t\t\t\tchalk.yellow('! Run \"piclet install\" from WSL to add context menu.'),\r\n\t\t\t\t);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (!isWSLInteropEnabled()) {\r\n\t\t\t\tconsole.log(chalk.yellow('WSL Interop not available. Generating registry file...\\n'));\r\n\r\n\t\t\t\tconst regPath = await generateRegFile();\r\n\t\t\t\tconst winPath = wslToWindows(regPath);\r\n\r\n\t\t\t\tconsole.log(chalk.green('✓ Generated registry file:'));\r\n\t\t\t\tconsole.log(chalk.cyan(` ${winPath}\\n`));\r\n\t\t\t\tconsole.log(chalk.bold('To install, either:'));\r\n\t\t\t\tconsole.log(chalk.dim(' 1. Double-click the .reg file in Windows Explorer'));\r\n\t\t\t\tconsole.log(chalk.dim(` 2. Run in elevated PowerShell: reg import \"${winPath}\"`));\r\n\t\t\t\tconsole.log();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Clean up existing entries first\r\n\t\t\tconsole.log(chalk.dim('Removing old entries...'));\r\n\t\t\tawait unregisterAllTools();\r\n\t\t\tconsole.log();\r\n\r\n\t\t\tconst results = await registerAllTools();\r\n\t\t\tconst allSuccess = results.every((r) => r.success);\r\n\r\n\t\t\t// Display each tool with its supported extensions\r\n\t\t\tfor (const { config } of tools) {\r\n\t\t\t\tconst extList = config.extensions.join(', ');\r\n\t\t\t\tconsole.log(`${chalk.green('✓')} ${config.name} ${chalk.dim(`[${extList}]`)}`);\r\n\t\t\t}\r\n\r\n\t\t\tconsole.log();\r\n\t\t\tif (allSuccess) {\r\n\t\t\t\tconsole.log(\r\n\t\t\t\t\tchalk.green(`✓ Registered ${tools.length} tools for context menu.`),\r\n\t\t\t\t);\r\n\t\t\t} else {\r\n\t\t\t\tconst successCount = results.filter((r) => r.success).length;\r\n\t\t\t\tconsole.log(\r\n\t\t\t\t\tchalk.yellow(`! Registered ${successCount}/${results.length} entries.`),\r\n\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\tconsole.log(chalk.bold('\\nContext Menu Usage:'));\r\n\t\t\tconsole.log(' Right-click any supported image in Windows Explorer.');\r\n\t\t\tconsole.log(' Multi-select supported for batch processing.');\r\n\r\n\t\t\tconsole.log(chalk.bold('\\nCLI Usage:'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet <image>') + chalk.dim(' Open GUI editor'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet makeicon <img>') + chalk.dim(' Convert to .ico'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet remove-bg <img>') + chalk.dim(' Remove background'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet scale <img>') + chalk.dim(' Resize image'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet iconpack <img>') + chalk.dim(' Generate icon pack'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet storepack <img>') + chalk.dim(' Generate store assets'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet transform <img>') + chalk.dim(' Rotate/flip image'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet filter <img>') + chalk.dim(' Apply filters'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet border <img>') + chalk.dim(' Add border'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet recolor <img>') + chalk.dim(' Replace colors'));\r\n\t\t\tconsole.log(chalk.cyan(' piclet extract-frames <gif>') + chalk.dim(' Extract GIF frames'));\r\n\t\t\tconsole.log(chalk.dim('\\n Run \"piclet --help\" for full documentation.'));\r\n\t\t\tconsole.log();\r\n\t\t});\r\n}\r\n","import { exec } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\n/**\n * Check if running inside WSL\n */\nexport function isWSL(): boolean {\n\treturn (\n\t\tprocess.platform === 'linux' &&\n\t\t(process.env.WSL_DISTRO_NAME !== undefined ||\n\t\t\tprocess.env.WSLENV !== undefined)\n\t);\n}\n\n/**\n * Check if WSL interop is enabled (can run Windows executables)\n */\nexport function isWSLInteropEnabled(): boolean {\n\treturn existsSync('/proc/sys/fs/binfmt_misc/WSLInterop');\n}\n\n/**\n * Convert WSL path to Windows path\n */\nexport function wslToWindows(wslPath: string): string {\n\tconst match = wslPath.match(/^\\/mnt\\/([a-z])\\/(.*)$/i);\n\tif (match) {\n\t\tconst drive = match[1].toUpperCase();\n\t\tconst rest = match[2].replace(/\\//g, '\\\\');\n\t\treturn `${drive}:\\\\${rest}`;\n\t}\n\treturn wslPath;\n}\n\n/**\n * Convert Windows path to WSL path\n */\nexport function windowsToWsl(winPath: string): string {\n\tconst match = winPath.match(/^([A-Za-z]):\\\\(.*)$/);\n\tif (match) {\n\t\tconst drive = match[1].toLowerCase();\n\t\tconst rest = match[2].replace(/\\\\/g, '/');\n\t\treturn `/mnt/${drive}/${rest}`;\n\t}\n\treturn winPath;\n}\n\n/**\n * Get the directory where this module is located\n */\nexport function getModuleDir(): string {\n\tconst currentFile = fileURLToPath(import.meta.url);\n\treturn dirname(currentFile);\n}\n\n/**\n * Add a registry key with value\n */\nexport async function addRegistryKey(\n\tkeyPath: string,\n\tvalueName: string,\n\tvalue: string,\n\ttype = 'REG_SZ',\n): Promise<boolean> {\n\tconst valueArg = valueName ? `/v \"${valueName}\"` : '/ve';\n\t// Escape inner quotes for Windows command line\n\tconst escapedValue = value.replace(/\"/g, '\\\\\"');\n\tconst cmd = `reg.exe add \"${keyPath}\" ${valueArg} /t ${type} /d \"${escapedValue}\" /f`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch (error) {\n\t\tconst message = (error as Error).message;\n\t\t// Silently ignore WSL interop errors (can't run reg.exe)\n\t\tconst ignoredErrors = ['Exec format error', 'not found'];\n\t\tconst shouldIgnore = ignoredErrors.some((e) =>\n\t\t\tmessage.toLowerCase().includes(e.toLowerCase()),\n\t\t);\n\t\tif (!shouldIgnore) {\n\t\t\tconsole.error(`Failed to add registry key: ${keyPath}`);\n\t\t\tconsole.error(message);\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Delete a registry key\n */\nexport async function deleteRegistryKey(keyPath: string): Promise<boolean> {\n\tconst cmd = `reg.exe delete \"${keyPath}\" /f`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch (error) {\n\t\tconst message = (error as Error).message;\n\t\t// Silently ignore expected errors:\n\t\t// - \"unable to find\" = key doesn't exist\n\t\t// - \"Exec format error\" = WSL can't run reg.exe (interop disabled)\n\t\t// - \"not found\" = reg.exe not in PATH\n\t\tconst ignoredErrors = ['unable to find', 'Exec format error', 'not found'];\n\t\tconst shouldIgnore = ignoredErrors.some((e) =>\n\t\t\tmessage.toLowerCase().includes(e.toLowerCase()),\n\t\t);\n\t\tif (!shouldIgnore) {\n\t\t\tconsole.error(`Failed to delete registry key: ${keyPath}`);\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if a registry key exists\n */\nexport async function registryKeyExists(keyPath: string): Promise<boolean> {\n\tconst cmd = `reg.exe query \"${keyPath}\" 2>/dev/null`;\n\n\ttry {\n\t\tawait execAsync(cmd);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","import { writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { wslToWindows } from '../lib/paths.js';\nimport { addRegistryKey, deleteRegistryKey } from '../lib/registry.js';\nimport { getAllExtensions, getToolsForExtension, picletTool, tuiTools } from './tools.js';\nimport { getDistDir, getMenuBasePath } from './utils.js';\n\n/** Tool registration result */\nexport interface RegistrationResult {\n\textension: string;\n\ttoolName: string;\n\tsuccess: boolean;\n}\n\n/** Register unified PicLet menu item directly on context menu (no submenu) */\nasync function registerUnifiedMenu(\n\textension: string,\n\ticonsDir: string,\n\tlauncherPath: string,\n): Promise<RegistrationResult> {\n\tconst basePath = `HKCU\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\n\t// Create direct PicLet menu item (not a submenu)\n\tconst menuSuccess = await addRegistryKey(basePath, 'MUIVerb', 'PicLet');\n\tconst iconSuccess = await addRegistryKey(basePath, 'Icon', `${iconsDirWin}\\\\banana.ico`);\n\n\t// Enable multi-select\n\tawait addRegistryKey(basePath, 'MultiSelectModel', 'Player');\n\n\t// Command - opens unified GUI\n\tconst commandValue = `wscript.exe //B \"${launcherWin}\" piclet \"%1\" -g`;\n\tconst cmdSuccess = await addRegistryKey(`${basePath}\\\\command`, '', commandValue);\n\n\treturn {\n\t\textension,\n\t\ttoolName: 'PicLet',\n\t\tsuccess: menuSuccess && iconSuccess && cmdSuccess,\n\t};\n}\n\n/** Register PicLet submenu for a single extension (legacy - individual tools) */\nasync function registerMenuForExtension(\n\textension: string,\n\ticonsDir: string,\n\tlauncherPath: string,\n): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\tconst basePath = getMenuBasePath(extension);\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\tconst extensionTools = getToolsForExtension(extension);\n\n\t// Create parent PicLet menu\n\tawait addRegistryKey(basePath, 'MUIVerb', 'PicLet');\n\tawait addRegistryKey(basePath, 'Icon', `${iconsDirWin}\\\\banana.ico`);\n\tawait addRegistryKey(basePath, 'SubCommands', '');\n\n\t// Create submenu for each tool\n\tfor (const { config } of extensionTools) {\n\t\tconst toolPath = `${basePath}\\\\shell\\\\${config.id}`;\n\n\t\tconst menuSuccess = await addRegistryKey(toolPath, 'MUIVerb', config.name);\n\t\tconst iconSuccess = await addRegistryKey(\n\t\t\ttoolPath,\n\t\t\t'Icon',\n\t\t\t`${iconsDirWin}\\\\${config.icon}`,\n\t\t);\n\n\t\t// Enable multi-select\n\t\tawait addRegistryKey(toolPath, 'MultiSelectModel', 'Player');\n\n\t\t// Command - use VBScript launcher for hidden cmd.exe window\n\t\tlet commandValue: string;\n\t\tif (tuiTools.includes(config.id)) {\n\t\t\t// GUI mode - opens Edge app window\n\t\t\tcommandValue = `wscript.exe //B \"${launcherWin}\" ${config.id} \"%1\" -g`;\n\t\t} else {\n\t\t\t// Run headless with defaults\n\t\t\tcommandValue = `wscript.exe //B \"${launcherWin}\" ${config.id} \"%1\" -y`;\n\t\t}\n\t\tconst cmdSuccess = await addRegistryKey(\n\t\t\t`${toolPath}\\\\command`,\n\t\t\t'',\n\t\t\tcommandValue,\n\t\t);\n\n\t\tresults.push({\n\t\t\textension,\n\t\t\ttoolName: config.name,\n\t\t\tsuccess: menuSuccess && iconSuccess && cmdSuccess,\n\t\t});\n\t}\n\n\treturn results;\n}\n\n/** Unregister PicLet menu for a single extension */\nasync function unregisterMenuForExtension(\n\textension: string,\n): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\tconst basePath = getMenuBasePath(extension);\n\tconst extensionTools = getToolsForExtension(extension);\n\n\t// Delete each tool's submenu\n\tfor (const { config } of extensionTools) {\n\t\tconst toolPath = `${basePath}\\\\shell\\\\${config.id}`;\n\t\tawait deleteRegistryKey(`${toolPath}\\\\command`);\n\t\tconst success = await deleteRegistryKey(toolPath);\n\n\t\tresults.push({\n\t\t\textension,\n\t\t\ttoolName: config.name,\n\t\t\tsuccess,\n\t\t});\n\t}\n\n\t// Delete the shell container\n\tawait deleteRegistryKey(`${basePath}\\\\shell`);\n\n\t// Delete parent PicLet menu\n\tawait deleteRegistryKey(basePath);\n\n\treturn results;\n}\n\n/** Register all tools - unified mode (single PicLet menu item) */\nexport async function registerAllTools(): Promise<RegistrationResult[]> {\n\tconst distDir = getDistDir();\n\tconst iconsDir = join(distDir, 'icons');\n\tconst launcherPath = join(distDir, 'launcher.vbs');\n\tconst results: RegistrationResult[] = [];\n\n\t// Register unified PicLet menu for each supported extension\n\tfor (const extension of picletTool.config.extensions) {\n\t\tconst result = await registerUnifiedMenu(extension, iconsDir, launcherPath);\n\t\tresults.push(result);\n\t}\n\n\treturn results;\n}\n\n/** Legacy tool names that may exist in older installations */\nconst LEGACY_TOOL_NAMES = [\n\t// Old direct menu items (various naming conventions)\n\t'Scale Image',\n\t'Resize Image',\n\t'Eale Image', // Corrupted entry\n\t'Remove Background',\n\t'Remove BG',\n\t'RemoveBG',\n\t'Make Icon',\n\t'MakeIcon',\n\t'Icon Pack',\n\t'IconPack',\n\t'Store Pack',\n\t'StorePack',\n\t'PicLet - Scale',\n\t'PicLet - Remove BG',\n\t'PicLet - Make Icon',\n\t'PicLet - Icon Pack',\n\t'PicLet Scale',\n\t'PicLet RemoveBG',\n\t// Tool IDs that might have been used as menu names\n\t'makeicon',\n\t'remove-bg',\n\t'removebg',\n\t'rescale',\n\t'scale',\n\t'iconpack',\n\t'storepack',\n\t'transform',\n\t'filter',\n\t'border',\n\t'recolor',\n];\n\n/** All extensions that might have legacy entries */\nconst ALL_IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico', '.webp', '.tiff', '.tif'];\n\n/** Clean up legacy registry entries from older installations */\nexport async function cleanupLegacyEntries(): Promise<{ removed: string[]; failed: string[] }> {\n\tconst removed: string[] = [];\n\tconst failed: string[] = [];\n\n\tfor (const ext of ALL_IMAGE_EXTENSIONS) {\n\t\tconst shellBase = `HKCU\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${ext}\\\\shell`;\n\n\t\tfor (const legacyName of LEGACY_TOOL_NAMES) {\n\t\t\tconst keyPath = `${shellBase}\\\\${legacyName}`;\n\n\t\t\t// Try to delete the command subkey first\n\t\t\tawait deleteRegistryKey(`${keyPath}\\\\command`);\n\n\t\t\t// Then delete the main key\n\t\t\tconst success = await deleteRegistryKey(keyPath);\n\t\t\tif (success) {\n\t\t\t\tremoved.push(`${ext} → ${legacyName}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { removed, failed };\n}\n\n/** Unregister all tools */\nexport async function unregisterAllTools(): Promise<RegistrationResult[]> {\n\tconst results: RegistrationResult[] = [];\n\n\t// Unregister from all extensions (both unified and legacy)\n\tconst allExts = new Set([...getAllExtensions(), ...picletTool.config.extensions]);\n\tfor (const extension of allExts) {\n\t\tconst basePath = getMenuBasePath(extension);\n\n\t\t// Try to delete any submenus (legacy)\n\t\tconst extResults = await unregisterMenuForExtension(extension);\n\t\tresults.push(...extResults);\n\n\t\t// Also delete the unified command if it exists\n\t\tawait deleteRegistryKey(`${basePath}\\\\command`);\n\t\tawait deleteRegistryKey(basePath);\n\t}\n\n\treturn results;\n}\n\n/**\n * Escape a string value for .reg file format\n */\nfunction escapeRegValue(value: string): string {\n\treturn value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Generate registry content for unified PicLet menu\n */\nfunction generateRegContent(): string {\n\tconst distDir = getDistDir();\n\tconst iconsDir = join(distDir, 'icons');\n\tconst launcherPath = join(distDir, 'launcher.vbs');\n\tconst iconsDirWin = wslToWindows(iconsDir);\n\tconst launcherWin = wslToWindows(launcherPath);\n\n\tconst lines: string[] = ['Windows Registry Editor Version 5.00', ''];\n\n\t// Register unified PicLet menu for each supported extension\n\tfor (const extension of picletTool.config.extensions) {\n\t\tconst basePath = `HKEY_CURRENT_USER\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n\n\t\tlines.push(`[${basePath}]`);\n\t\tlines.push(`\"MUIVerb\"=\"${escapeRegValue('PicLet')}\"`);\n\t\tlines.push(`\"Icon\"=\"${escapeRegValue(`${iconsDirWin}\\\\banana.ico`)}\"`);\n\t\tlines.push('\"MultiSelectModel\"=\"Player\"');\n\t\tlines.push('');\n\n\t\t// Command - opens unified GUI\n\t\tconst commandValue = `wscript.exe //B \"${launcherWin}\" piclet \"%1\" -g`;\n\t\tlines.push(`[${basePath}\\\\command]`);\n\t\tlines.push(`@=\"${escapeRegValue(commandValue)}\"`);\n\t\tlines.push('');\n\t}\n\n\treturn lines.join('\\r\\n');\n}\n\n/**\n * Generate uninstall registry content (deletion entries)\n */\nfunction generateUninstallRegContent(): string {\n\tconst lines: string[] = ['Windows Registry Editor Version 5.00', ''];\n\n\t// Delete from all extensions (both unified and legacy)\n\tconst allExts = new Set([...getAllExtensions(), ...picletTool.config.extensions]);\n\tfor (const extension of allExts) {\n\t\tconst basePath = `HKEY_CURRENT_USER\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${extension}\\\\shell\\\\PicLet`;\n\n\t\t// Delete the entire PicLet key (minus sign deletes)\n\t\tlines.push(`[-${basePath}]`);\n\t\tlines.push('');\n\t}\n\n\t// Also delete legacy entries from older installations\n\tfor (const ext of ALL_IMAGE_EXTENSIONS) {\n\t\tfor (const legacyName of LEGACY_TOOL_NAMES) {\n\t\t\tconst keyPath = `HKEY_CURRENT_USER\\\\Software\\\\Classes\\\\SystemFileAssociations\\\\${ext}\\\\shell\\\\${legacyName}`;\n\t\t\tlines.push(`[-${keyPath}]`);\n\t\t}\n\t\tlines.push('');\n\t}\n\n\treturn lines.join('\\r\\n');\n}\n\n/**\n * Generate a .reg file for installation\n * @returns Path to the generated .reg file\n */\nexport async function generateRegFile(): Promise<string> {\n\tconst distDir = getDistDir();\n\tconst regPath = join(distDir, 'piclet-install.reg');\n\tconst content = generateRegContent();\n\tawait writeFile(regPath, content, 'utf-8');\n\treturn regPath;\n}\n\n/**\n * Generate a .reg file for uninstallation\n * @returns Path to the generated .reg file\n */\nexport async function generateUninstallRegFile(): Promise<string> {\n\tconst distDir = getDistDir();\n\tconst regPath = join(distDir, 'piclet-uninstall.reg');\n\tconst content = generateUninstallRegContent();\n\tawait writeFile(regPath, content, 'utf-8');\n\treturn regPath;\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as makeicon from '../../tools/makeicon.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerMakeiconCommand(program: Command): void {\n\tprogram\n\t\t.command('makeicon <files...>')\n\t\t.description('Convert PNG to multi-resolution ICO file')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for confirmation')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, makeicon.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await makeicon.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'makeicon',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { picletTool } from '../tools.js';\nimport { validateExtensions } from '../utils.js';\n\nexport function registerPicletCommand(program: Command): void {\n\tprogram\n\t\t.command('piclet <file>')\n\t\t.description('Open unified PicLet window with all tools')\n\t\t.option('-g, --gui', 'Use GUI (default)')\n\t\t.action(async (file: string) => {\n\t\t\tconst { valid, invalid } = validateExtensions([file], picletTool.config.extensions);\n\t\t\tif (invalid.length > 0) {\n\t\t\t\tconsole.error(chalk.red(`Invalid file type: ${file}`));\n\t\t\t\tconsole.error(chalk.yellow(`Supported: ${picletTool.config.extensions.join(', ')}`));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tconst result = await picletTool.runGUI(valid[0]);\n\t\t\tprocess.exit(result ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as recolor from '../../tools/recolor.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerRecolorCommand(program: Command): void {\n\tprogram\n\t\t.command('recolor <files...>')\n\t\t.alias('replace-color')\n\t\t.description('Replace one color with another')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, recolor.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await recolor.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'recolor',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { clearOverrides, setOverrides } from '../../lib/prompts.js';\nimport * as removeBg from '../../tools/remove-bg.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerRemoveBgCommand(program: Command): void {\n\tprogram\n\t\t.command('remove-bg <files...>')\n\t\t.alias('removebg')\n\t\t.description('Remove solid background from image')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use TUI (terminal GUI) for options')\n\t\t.option('-f, --fuzz <percent>', 'Fuzz tolerance 0-100 (default: 10)')\n\t\t.option('-t, --trim', 'Trim transparent edges (default: true)')\n\t\t.option('--no-trim', 'Do not trim transparent edges')\n\t\t.option('-p, --preserve-inner', 'Preserve inner areas of same color')\n\t\t.option('-s, --square', 'Make output square with padding')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean; fuzz?: string; trim?: boolean; preserveInner?: boolean; square?: boolean }) => {\n\t\t\t// GUI mode - open HTML interface in browser\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, removeBg.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\t// Only process first file in GUI mode\n\t\t\t\tconst result = await removeBg.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\t// Set overrides from CLI args\n\t\t\tif (options.fuzz !== undefined) {\n\t\t\t\tsetOverrides({ 'fuzz': Number(options.fuzz) });\n\t\t\t}\n\t\t\tif (options.trim !== undefined) {\n\t\t\t\tsetOverrides({ 'trim': options.trim });\n\t\t\t}\n\t\t\tif (options.preserveInner) {\n\t\t\t\tsetOverrides({ 'preserve inner': true });\n\t\t\t}\n\t\t\tif (options.square) {\n\t\t\t\tsetOverrides({ 'square': true });\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'remove-bg',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tclearOverrides();\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as rescale from '../../tools/rescale.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerScaleCommand(program: Command): void {\n\tprogram\n\t\t.command('scale <files...>')\n\t\t.alias('rescale')\n\t\t.description('Resize image with optional padding')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, rescale.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await rescale.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'rescale',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as storepack from '../../tools/storepack.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerStorepackCommand(program: Command): void {\n\tprogram\n\t\t.command('storepack <files...>')\n\t\t.description('Generate assets for app stores (Windows, Unity, Steam, etc.)')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\t// GUI mode\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, storepack.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await storepack.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'storepack',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport * as transform from '../../tools/transform.js';\nimport { runToolOnFiles, validateExtensions } from '../utils.js';\n\nexport function registerTransformCommand(program: Command): void {\n\tprogram\n\t\t.command('transform <files...>')\n\t\t.alias('flip')\n\t\t.description('Flip or rotate images')\n\t\t.option('-y, --yes', 'Use defaults, skip prompts')\n\t\t.option('-g, --gui', 'Use GUI for options')\n\t\t.action(async (files: string[], options: { yes?: boolean; gui?: boolean }) => {\n\t\t\tif (options.gui) {\n\t\t\t\tconst { valid, invalid } = validateExtensions(files, transform.config.extensions);\n\t\t\t\tif (invalid.length > 0) {\n\t\t\t\t\tconsole.error(chalk.red('Invalid file types:'));\n\t\t\t\t\tfor (const file of invalid) {\n\t\t\t\t\t\tconsole.error(chalk.red(` - ${file}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (valid.length === 0) {\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tconst result = await transform.runGUI(valid[0]);\n\t\t\t\tprocess.exit(result ? 0 : 1);\n\t\t\t}\n\n\t\t\tconst success = await runToolOnFiles(\n\t\t\t\t'transform',\n\t\t\t\tfiles,\n\t\t\t\toptions.yes ?? false,\n\t\t\t);\n\t\t\tprocess.exit(success ? 0 : 1);\n\t\t});\n}\n","import chalk from 'chalk';\nimport type { Command } from 'commander';\nimport { showBanner } from '../../lib/banner.js';\nimport { wslToWindows } from '../../lib/paths.js';\nimport { isWSL, isWSLInteropEnabled } from '../../lib/registry.js';\nimport { cleanupLegacyEntries, generateUninstallRegFile, unregisterAllTools } from '../registry.js';\n\nexport function registerUninstallCommand(program: Command): void {\n\tprogram\n\t\t.command('uninstall')\n\t\t.description('Remove Windows shell context menu integration')\n\t\t.action(async () => {\n\t\t\tshowBanner();\n\t\t\tconsole.log(chalk.bold('Uninstalling...\\n'));\n\n\t\t\tif (!isWSL()) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow('! Not running in WSL. Registry cleanup skipped.'),\n\t\t\t\t);\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t'! Run \"piclet uninstall\" from WSL to remove context menu.',\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isWSLInteropEnabled()) {\n\t\t\t\tconsole.log(chalk.yellow('WSL Interop not available. Generating registry file...\\n'));\n\n\t\t\t\tconst regPath = await generateUninstallRegFile();\n\t\t\t\tconst winPath = wslToWindows(regPath);\n\n\t\t\t\tconsole.log(chalk.green('✓ Generated uninstall registry file:'));\n\t\t\t\tconsole.log(chalk.cyan(` ${winPath}\\n`));\n\t\t\t\tconsole.log(chalk.bold('To uninstall, either:'));\n\t\t\t\tconsole.log(chalk.dim(' 1. Double-click the .reg file in Windows Explorer'));\n\t\t\t\tconsole.log(chalk.dim(` 2. Run in elevated PowerShell: reg import \"${winPath}\"`));\n\t\t\t\tconsole.log();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// First, clean up legacy entries from older installations\n\t\t\tconsole.log(chalk.dim('Cleaning up legacy entries...\\n'));\n\t\t\tconst legacyResult = await cleanupLegacyEntries();\n\n\t\t\tif (legacyResult.removed.length > 0) {\n\t\t\t\tconsole.log(chalk.yellow(`Removed ${legacyResult.removed.length} legacy entries:`));\n\t\t\t\tfor (const entry of legacyResult.removed) {\n\t\t\t\t\tconsole.log(` ${chalk.green('✓')} ${entry}`);\n\t\t\t\t}\n\t\t\t\tconsole.log();\n\t\t\t}\n\n\t\t\t// Then unregister current tools\n\t\t\tconst results = await unregisterAllTools();\n\t\t\tconst removedCount = results.filter((r) => r.success).length;\n\n\t\t\tfor (const result of results) {\n\t\t\t\tif (result.success) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`${chalk.green('✓')} Removed: ${result.extension} → ${result.toolName}`,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`${chalk.gray('-')} Skipped: ${result.extension} → ${result.toolName}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst totalRemoved = removedCount + legacyResult.removed.length;\n\t\t\tconsole.log();\n\t\t\tconsole.log(\n\t\t\t\tchalk.green(\n\t\t\t\t\t`✓ Cleanup complete. Removed ${totalRemoved} entries total.`,\n\t\t\t\t),\n\t\t\t);\n\t\t\tconsole.log(chalk.dim('\\nThanks for using PicLet!\\n'));\n\t\t});\n}\n"],"mappings":";;;;;;;;;AAEA,OAAOA,aAAW;;;ACFlB,OAAOC,aAAW;AAClB,SAAS,eAAe;;;ACDxB,OAAO,YAAY;AACnB,OAAO,cAAc;AAErB,IAAM,kBAAkB,CAAC,WAAW,WAAW,WAAW,SAAS;AAKnE,SAAS,aAAqB;AAC7B,QAAM,QAAQ,OAAO,SAAS,UAAU;AAAA,IACvC,MAAM;AAAA,IACN,kBAAkB;AAAA,EACnB,CAAC;AACD,SAAO,SAAS,eAAe,EAAE,KAAK;AACvC;AAKO,SAAS,WACf,WAAW,qEACJ;AACP,MAAI;AACH,YAAQ,IAAI;AAAA,EAAK,WAAW,CAAC,EAAE;AAC/B,QAAI,UAAU;AACb,YAAM,iBAAiB,SAAS,CAAC,WAAW,SAAS,CAAC;AACtD,cAAQ,IAAI,eAAe,KAAK,QAAQ;AAAA,CAAI,CAAC;AAAA,IAC9C;AAAA,EACD,QAAQ;AAEP,YAAQ,IAAI,wBAAwB;AACpC,QAAI,UAAU;AACb,cAAQ,IAAI,YAAY,QAAQ;AAAA,CAAW;AAAA,IAC5C;AAAA,EACD;AACD;;;ACnCA,OAAOC,YAAW;;;ACAlB,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AACzC,SAAS,cAAc;AACvB,SAAS,YAAAC,WAAU,QAAAC,aAAY;;;ACC/B,SAAS,aAAa;AACtB,SAAS,oBAAoB;AAC7B,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,SAAS,qBAAqB;AAC9B,OAAO,aAAa;;;ACJpB,SAAS,YAAY,WAAW,cAAc,qBAAqB;AACnE,SAAS,SAAS,YAAY;AAC9B,SAAS,eAAe;AAwBxB,IAAM,mBAA6B;AAAA;AAAA,EAElC;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACpD,EAAE,UAAU,oBAAoB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACxD,EAAE,UAAU,sBAAsB,OAAO,MAAM,QAAQ,IAAI;AAAA,MAC3D,EAAE,UAAU,4BAA4B,OAAO,MAAM,QAAQ,KAAK;AAAA,IACnE;AAAA,EACD;AAAA,EACA;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACpD,EAAE,UAAU,qBAAqB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACzD,EAAE,UAAU,wBAAwB,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC5D,EAAE,UAAU,yBAAyB,OAAO,MAAM,QAAQ,KAAK;AAAA,IAChE;AAAA,EACD;AAAA,EACA;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,eAAe,OAAO,IAAI,QAAQ,GAAG;AAAA,MACjD,EAAE,UAAU,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACpD,EAAE,UAAU,2BAA2B,OAAO,MAAM,QAAQ,IAAI;AAAA,MAChE,EAAE,UAAU,4BAA4B,OAAO,MAAM,QAAQ,KAAK;AAAA,IACnE;AAAA,EACD;AAAA,EACA;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACpD,EAAE,UAAU,qBAAqB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACzD,EAAE,UAAU,yBAAyB,OAAO,MAAM,QAAQ,KAAK;AAAA,IAChE;AAAA,EACD;AAAA,EACA;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,4BAA4B,OAAO,KAAK,QAAQ,GAAG;AAAA,MAC/D,EAAE,UAAU,4BAA4B,OAAO,KAAK,QAAQ,IAAI;AAAA,MAChE,EAAE,UAAU,sBAAsB,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC1D,EAAE,UAAU,qBAAqB,OAAO,MAAM,QAAQ,IAAI;AAAA,MAC1D,EAAE,UAAU,+BAA+B,OAAO,KAAK,QAAQ,IAAI;AAAA,MACnE,EAAE,UAAU,8BAA8B,OAAO,MAAM,QAAQ,KAAK;AAAA,IACrE;AAAA,EACD;AAAA,EACA;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,qBAAqB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACzD,EAAE,UAAU,yBAAyB,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC7D,EAAE,UAAU,sBAAsB,OAAO,KAAK,QAAQ,IAAI;AAAA,IAC3D;AAAA,EACD;AAAA;AAAA,EAEA;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,eAAe,OAAO,IAAI,QAAQ,GAAG;AAAA,MACjD,EAAE,UAAU,eAAe,OAAO,IAAI,QAAQ,GAAG;AAAA,MACjD,EAAE,UAAU,eAAe,OAAO,IAAI,QAAQ,GAAG;AAAA,MACjD,EAAE,UAAU,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACpD,EAAE,UAAU,qBAAqB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACzD,EAAE,UAAU,sBAAsB,OAAO,MAAM,QAAQ,IAAI;AAAA,IAC5D;AAAA,EACD;AAAA,EACA;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,eAAe,OAAO,IAAI,QAAQ,GAAG;AAAA,MACjD,EAAE,UAAU,eAAe,OAAO,IAAI,QAAQ,GAAG;AAAA,MACjD,EAAE,UAAU,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AAAA,IACrD;AAAA,EACD;AAAA,EACA;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACpD,EAAE,UAAU,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AAAA,IACrD;AAAA,EACD;AAAA,EACA;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,eAAe,OAAO,IAAI,QAAQ,GAAG;AAAA,MACjD,EAAE,UAAU,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACpD,EAAE,UAAU,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AAAA,MACpD,EAAE,UAAU,uBAAuB,OAAO,MAAM,QAAQ,IAAI;AAAA,IAC7D;AAAA,EACD;AAAA,EACA;AAAA,IACC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,MACN,EAAE,UAAU,uBAAuB,OAAO,IAAI,QAAQ,GAAG;AAAA,MACzD,EAAE,UAAU,yBAAyB,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC7D,EAAE,UAAU,yBAAyB,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC7D,EAAE,UAAU,uBAAuB,OAAO,KAAK,QAAQ,IAAI;AAAA,MAC3D,EAAE,UAAU,oBAAoB,OAAO,IAAI,QAAQ,GAAG;AAAA,MACtD,EAAE,UAAU,4BAA4B,OAAO,KAAK,QAAQ,IAAI;AAAA,IACjE;AAAA,EACD;AACD;AAGO,SAAS,iBAAyB;AACxC,QAAM,YAAY,KAAK,QAAQ,GAAG,SAAS;AAC3C,SAAO,KAAK,WAAW,cAAc;AACtC;AAGA,SAAS,mBAAyB;AACjC,QAAM,cAAc,eAAe;AACnC,QAAM,MAAM,QAAQ,WAAW;AAC/B,MAAI,CAAC,WAAW,GAAG,GAAG;AACrB,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,EACnC;AACD;AAGO,SAAS,cAAwB;AACvC,QAAM,cAAc,eAAe;AACnC,MAAI,cAAwB,CAAC;AAE7B,MAAI,WAAW,WAAW,GAAG;AAC5B,QAAI;AACH,YAAM,OAAO,aAAa,aAAa,OAAO;AAC9C,YAAMC,WAAwB,KAAK,MAAM,IAAI;AAC7C,oBAAcA,SAAO,WAAW,CAAC;AAAA,IAClC,QAAQ;AAAA,IAER;AAAA,EACD;AAGA,QAAM,YAAY,oBAAI,IAAoB;AAC1C,aAAW,UAAU,kBAAkB;AACtC,cAAU,IAAI,OAAO,IAAI,MAAM;AAAA,EAChC;AACA,aAAW,UAAU,aAAa;AACjC,cAAU,IAAI,OAAO,IAAI,MAAM;AAAA,EAChC;AAEA,SAAO,MAAM,KAAK,UAAU,OAAO,CAAC;AACrC;AASO,SAAS,YAAY,SAAyB;AACpD,mBAAiB;AACjB,QAAMC,WAAwB;AAAA,IAC7B,SAAS;AAAA,IACT;AAAA,EACD;AACA,gBAAc,eAAe,GAAG,KAAK,UAAUA,UAAQ,MAAM,CAAC,CAAC;AAChE;AAGO,SAAS,WAAW,QAAsB;AAChD,QAAM,cAAc,eAAe;AACnC,MAAI,cAAwB,CAAC;AAE7B,MAAI,WAAW,WAAW,GAAG;AAC5B,QAAI;AACH,YAAM,OAAO,aAAa,aAAa,OAAO;AAC9C,YAAMA,WAAwB,KAAK,MAAM,IAAI;AAC7C,oBAAcA,SAAO,WAAW,CAAC;AAAA,IAClC,QAAQ;AAAA,IAER;AAAA,EACD;AAGA,QAAM,MAAM,YAAY,UAAU,CAAC,MAAM,EAAE,OAAO,OAAO,EAAE;AAC3D,MAAI,OAAO,GAAG;AACb,gBAAY,GAAG,IAAI;AAAA,EACpB,OAAO;AACN,gBAAY,KAAK,MAAM;AAAA,EACxB;AAEA,cAAY,WAAW;AACxB;AAQO,SAAS,aAAa,IAAkD;AAE9E,MAAI,iBAAiB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG;AAC9C,WAAO,EAAE,SAAS,OAAO,OAAO,iCAAiC;AAAA,EAClE;AAEA,QAAM,cAAc,eAAe;AACnC,MAAI,CAAC,WAAW,WAAW,GAAG;AAC7B,WAAO,EAAE,SAAS,OAAO,OAAO,mBAAmB;AAAA,EACpD;AAEA,MAAI;AACH,UAAM,OAAO,aAAa,aAAa,OAAO;AAC9C,UAAMC,WAAwB,KAAK,MAAM,IAAI;AAC7C,UAAM,cAAcA,SAAO,WAAW,CAAC;AAEvC,UAAM,MAAM,YAAY,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AACpD,QAAI,MAAM,GAAG;AACZ,aAAO,EAAE,SAAS,OAAO,OAAO,mBAAmB;AAAA,IACpD;AAEA,gBAAY,OAAO,KAAK,CAAC;AACzB,gBAAY,WAAW;AACvB,WAAO,EAAE,SAAS,KAAK;AAAA,EACxB,QAAQ;AACP,WAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,EAC3D;AACD;;;ADvQA,IAAMC,aAAYC,SAAQ,cAAc,YAAY,GAAG,CAAC;AAKxD,SAAS,cAAoB;AAE5B,QAAM,kBAAkB,CAAC,gBAAgB,UAAU,YAAY,6EAA6E,GAAG;AAAA,IAC9I,OAAO;AAAA,IACP,aAAa;AAAA,EACd,CAAC;AACF;AAKA,SAAS,cAAc,KAAmB;AAEzC,QAAM,kBAAkB;AAAA,IACvB;AAAA,IAAgB;AAAA,IAChB;AAAA,IACA,6CAA6C,GAAG;AAAA,EACjD,GAAG;AAAA,IACF,UAAU;AAAA,IACV,OAAO;AAAA,IACP,aAAa;AAAA,EACd,CAAC,EAAE,MAAM;AAGT,cAAY;AACb;AAyEO,SAAS,eAAe,SAA6C;AAC3E,SAAO,IAAI,QAAQ,CAACC,aAAY;AAC/B,UAAM,MAAM,QAAQ;AACpB,QAAI,IAAI,QAAQ,KAAK,EAAE,OAAO,OAAO,CAAC,CAAC;AAGvC,QAAI,IAAI,CAAC,KAAY,MAAuB,KAAuB,SAA+B;AACjG,UAAI,eAAe,eAAe,UAAU,KAAK;AAChD,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,SAAS,OAAO,OAAO,mBAAmB,IAAI,QAAQ,CAAC;AAC9E;AAAA,MACD;AACA,WAAK,GAAG;AAAA,IACT,CAAC;AAED,QAAI,gBAAgC;AACpC,QAAI,SAAiD;AAGrD,UAAM,SAASC,MAAKH,YAAW,KAAK;AACpC,UAAM,WAAWG,MAAKH,YAAW,OAAO;AACxC,QAAI,IAAI,QAAQ,OAAO,MAAM,CAAC;AAC9B,QAAI,IAAI,UAAU,QAAQ,OAAO,QAAQ,CAAC;AAG1C,QAAI,IAAI,gBAAgB,CAAC,MAAM,QAAQ;AACtC,UAAI,SAASG,MAAK,UAAU,YAAY,CAAC;AAAA,IAC1C,CAAC;AAGD,QAAI,IAAI,aAAa,CAAC,MAAM,QAAQ;AACnC,UAAI,KAAK;AAAA,QACR,UAAU,QAAQ,UAAU;AAAA,QAC5B,OAAO,QAAQ,UAAU;AAAA,QACzB,QAAQ,QAAQ,UAAU;AAAA,QAC1B,aAAa,QAAQ,UAAU;AAAA,QAC/B,YAAY,QAAQ,UAAU,cAAc;AAAA,QAC5C,UAAU,QAAQ;AAAA,MACnB,CAAC;AAAA,IACF,CAAC;AAGD,QAAI,KAAK,wBAAwB,OAAO,KAAK,QAAQ;AACpD,UAAI,CAAC,QAAQ,kBAAkB;AAC9B,YAAI,KAAK,EAAE,SAAS,OAAO,OAAO,iCAAiC,CAAC;AACpE;AAAA,MACD;AACA,UAAI;AACH,cAAM,aAAc,IAAI,KAAK,cAAyB;AACtD,cAAM,SAAS,MAAM,QAAQ,iBAAiB,UAAU;AACxD,YAAI,KAAK,MAAM;AAAA,MAChB,SAAS,KAAK;AACb,YAAI,KAAK,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,MAC3D;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,sBAAsB,OAAO,KAAK,QAAQ;AAClD,UAAI,CAAC,QAAQ,gBAAgB;AAC5B,YAAI,KAAK,EAAE,SAAS,OAAO,OAAO,8BAA8B,CAAC;AACjE;AAAA,MACD;AACA,UAAI;AACH,cAAM,EAAE,YAAY,GAAG,KAAK,IAAI,IAAI;AACpC,cAAM,SAAS,MAAM,QAAQ,eAAe,cAAc,GAAG,IAAI;AACjE,YAAI,KAAK,MAAM;AAAA,MAChB,SAAS,KAAK;AACb,YAAI,KAAK,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,MAC3D;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,qBAAqB,OAAO,KAAK,QAAQ;AACjD,UAAI,CAAC,QAAQ,eAAe;AAC3B,YAAI,KAAK,EAAE,SAAS,OAAO,OAAO,mCAAmC,CAAC;AACtE;AAAA,MACD;AACA,UAAI;AACH,cAAM,aAAc,IAAI,KAAK,cAAyB;AACtD,cAAM,SAAS,MAAM,QAAQ,cAAc,UAAU;AACrD,YAAI,OAAO,SAAS;AAEnB,kBAAQ,UAAU,WAAW,OAAO;AACpC,kBAAQ,UAAU,WAAW,OAAO;AACpC,kBAAQ,UAAU,QAAQ,OAAO;AACjC,kBAAQ,UAAU,SAAS,OAAO;AAClC,kBAAQ,UAAU,aAAa,OAAO;AAAA,QACvC;AACA,YAAI,KAAK,MAAM;AAAA,MAChB,SAAS,KAAK;AACb,YAAI,KAAK,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,MAC3D;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,qBAAqB,OAAO,KAAK,QAAQ;AACjD,UAAI,CAAC,QAAQ,eAAe;AAC3B,YAAI,KAAK,EAAE,SAAS,OAAO,OAAO,+BAA+B,CAAC;AAClE;AAAA,MACD;AACA,UAAI;AACH,cAAM,aAAa,IAAI,KAAK;AAC5B,cAAM,SAAS,MAAM,QAAQ,cAAc,UAAU;AACrD,YAAI,OAAO,SAAS;AACnB,kBAAQ,UAAU,aAAa,OAAO;AAAA,QACvC;AACA,YAAI,KAAK,MAAM;AAAA,MAChB,SAAS,KAAK;AACb,YAAI,KAAK,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,MAC3D;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,sBAAsB,OAAO,KAAK,QAAQ;AAClD,UAAI,CAAC,QAAQ,gBAAgB;AAC5B,YAAI,KAAK,EAAE,SAAS,OAAO,OAAO,kCAAkC,CAAC;AACrE;AAAA,MACD;AACA,UAAI;AACH,cAAM,EAAE,YAAY,UAAU,IAAI,IAAI;AACtC,cAAM,SAAS,MAAM,QAAQ,eAAe,YAAY,SAAS;AACjE,YAAI,OAAO,SAAS;AACnB,kBAAQ,UAAU,aAAa,OAAO;AAAA,QACvC;AACA,YAAI,KAAK,MAAM;AAAA,MAChB,SAAS,KAAK;AACb,YAAI,KAAK,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,MAC3D;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,gBAAgB,OAAO,KAAK,QAAQ;AAC5C,UAAI,CAAC,QAAQ,WAAW;AACvB,YAAI,KAAK,EAAE,SAAS,OAAO,OAAO,wBAAwB,CAAC;AAC3D;AAAA,MACD;AACA,UAAI;AACH,cAAM,SAAS,MAAM,QAAQ,UAAU,IAAI,IAAI;AAC/C,YAAI,KAAK,MAAM;AAAA,MAChB,SAAS,KAAK;AACb,YAAI,KAAK;AAAA,UACR,SAAS;AAAA,UACT,OAAQ,IAAc;AAAA,QACvB,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,gBAAgB,OAAO,KAAK,QAAQ;AAC5C,UAAI;AACH,cAAM,SAAS,MAAM,QAAQ,UAAU,IAAI,IAAI;AAC/C,wBAAgB,OAAO;AAEvB,YAAI,OAAO,YAAY;AACtB,UAAC,QAAwC,iBAAiB,OAAO;AAAA,QAClE,OAAO;AACN,UAAC,QAAwC,iBAAiB;AAAA,QAC3D;AACA,YAAI,KAAK,MAAM;AAAA,MAChB,SAAS,KAAK;AACb,wBAAgB;AAChB,YAAI,KAAK;AAAA,UACR,SAAS;AAAA,UACT,OAAQ,IAAc;AAAA,UACtB,MAAM,CAAC,EAAE,MAAM,SAAS,SAAU,IAAc,QAAQ,CAAC;AAAA,QAC1D,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,aAAa,OAAO,KAAK,QAAQ;AACzC,UAAI,CAAC,QAAQ,aAAa;AACzB,YAAI,KAAK,EAAE,SAAS,OAAO,OAAO,qBAAqB,CAAC;AACxD;AAAA,MACD;AACA,UAAI;AACH,cAAM,SAAS,MAAM,QAAQ,YAAY,IAAI,IAAI;AACjD,YAAI,OAAO,SAAS;AAEnB,kBAAQ,UAAU,WAAW,OAAO;AACpC,kBAAQ,UAAU,WAAW,OAAO;AACpC,kBAAQ,UAAU,QAAQ,OAAO;AACjC,kBAAQ,UAAU,SAAS,OAAO;AAClC,kBAAQ,UAAU,cAAc,OAAO,eAAe;AAAA,QACvD;AACA,YAAI,KAAK,MAAM;AAAA,MAChB,SAAS,KAAK;AACb,YAAI,KAAK,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,MAC3D;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,eAAe,CAAC,MAAM,QAAQ;AACtC,sBAAgB;AAChB,UAAI,KAAK,EAAE,IAAI,KAAK,CAAC;AACrB,eAAS;AAAA,IACV,CAAC;AAGD,QAAI,KAAK,cAAc,CAAC,MAAM,QAAQ;AACrC,UAAI,KAAK,EAAE,IAAI,KAAK,CAAC;AACrB,eAAS;AAAA,IACV,CAAC;AAGD,QAAI,KAAK,oBAAoB,CAAC,KAAK,QAAQ;AAC1C,UAAI;AACH,cAAM,SAAS,IAAI;AACnB,YAAI,CAAC,OAAO,MAAM,CAAC,OAAO,QAAQ,CAAC,OAAO,OAAO,QAAQ;AACxD,cAAI,KAAK,EAAE,SAAS,OAAO,OAAO,sBAAsB,CAAC;AACzD;AAAA,QACD;AACA,mBAAW,MAAM;AACjB,YAAI,KAAK,EAAE,SAAS,KAAK,CAAC;AAAA,MAC3B,SAAS,KAAK;AACb,YAAI,KAAK,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,MAC3D;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,sBAAsB,CAAC,KAAK,QAAQ;AAC5C,UAAI;AACH,cAAM,EAAE,GAAG,IAAI,IAAI;AACnB,YAAI,CAAC,IAAI;AACR,cAAI,KAAK,EAAE,SAAS,OAAO,OAAO,oBAAoB,CAAC;AACvD;AAAA,QACD;AACA,cAAM,SAAS,aAAa,EAAE;AAC9B,YAAI,KAAK,MAAM;AAAA,MAChB,SAAS,KAAK;AACb,YAAI,KAAK,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,MAC3D;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,iBAAiB,CAAC,KAAK,QAAQ;AACvC,YAAM,EAAE,IAAI,IAAI,IAAI;AACpB,UAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACpC,YAAI,KAAK,EAAE,SAAS,OAAO,OAAO,cAAc,CAAC;AACjD;AAAA,MACD;AAEA,YAAM,kBAAkB,CAAC,gBAAgB,UAAU,YAAY,kBAAkB,GAAG,GAAG,GAAG;AAAA,QACzF,UAAU;AAAA,QACV,OAAO;AAAA,QACP,aAAa;AAAA,MACd,CAAC,EAAE,MAAM;AACT,UAAI,KAAK,EAAE,SAAS,KAAK,CAAC;AAAA,IAC3B,CAAC;AAGD,QAAI,IAAI,uBAAuB,CAAC,MAAM,QAAQ;AAC7C,YAAM,aAAc,QAAwC;AAC5D,UAAI,CAAC,YAAY;AAChB,YAAI,KAAK,EAAE,SAAS,OAAO,OAAO,iBAAiB,CAAC;AACpD;AAAA,MACD;AACA,UAAI;AACH,cAAM,KAAK,UAAQ,IAAS;AAC5B,cAAM,OAAO,UAAQ,MAAW;AAChC,YAAI,CAAC,GAAG,WAAW,UAAU,GAAG;AAC/B,cAAI,KAAK,EAAE,SAAS,OAAO,OAAO,wBAAwB,CAAC;AAC3D;AAAA,QACD;AACA,cAAM,SAAS,GAAG,aAAa,UAAU;AACzC,cAAM,MAAM,KAAK,QAAQ,UAAU,EAAE,YAAY;AACjD,cAAM,YAAoC;AAAA,UACzC,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ;AAAA,QACT;AACA,cAAM,WAAW,UAAU,GAAG,KAAK;AACnC,YAAI,KAAK;AAAA,UACR,SAAS;AAAA,UACT,WAAW,QAAQ,QAAQ,WAAW,OAAO,SAAS,QAAQ,CAAC;AAAA,UAC/D,OAAO,QAAQ;AAAA,QAChB,CAAC;AAAA,MACF,SAAS,KAAK;AACb,YAAI,KAAK,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ,CAAC;AAAA,MAC3D;AAAA,IACD,CAAC;AAGD,QAAI,KAAK,oBAAoB,CAAC,MAAM,QAAQ;AAE3C,YAAM,aAAc,QAAwC;AAC5D,YAAM,WAAW,cAAc,QAAQ,UAAU;AAIjD,UAAI,UAAU;AACd,YAAM,WAAW,SAAS,MAAM,wBAAwB;AACxD,UAAI,UAAU;AACb,cAAM,QAAQ,SAAS,CAAC,EAAE,YAAY;AACtC,cAAM,OAAO,SAAS,CAAC,EAAE,QAAQ,OAAO,IAAI;AAC5C,kBAAU,GAAG,KAAK,MAAM,IAAI;AAAA,MAC7B;AAGA,YAAM,UAAU,KAAK,IAAI,QAAQ,YAAY,IAAI,GAAG,QAAQ,YAAY,GAAG,CAAC;AAC5E,YAAM,MAAM,UAAU,IAAI,QAAQ,UAAU,GAAG,OAAO,IAAI;AAG1D,YAAM,cAAc,aACjB,yBAAyB,OAAO,MAChC,iBAAiB,GAAG;AAEvB,YAAM,kBAAkB,CAAC,gBAAgB,UAAU,YAAY,WAAW,GAAG;AAAA,QAC5E,UAAU;AAAA,QACV,OAAO;AAAA,QACP,aAAa;AAAA,MACd,CAAC,EAAE,MAAM;AACT,UAAI,KAAK,EAAE,SAAS,KAAK,CAAC;AAAA,IAC3B,CAAC;AAED,aAAS,WAAW;AACnB,iBAAW,MAAM;AAChB,gBAAQ,MAAM;AACd,QAAAD,SAAQ,iBAAiB,KAAK;AAAA,MAC/B,GAAG,GAAG;AAAA,IACP;AAGA,aAAS,aAAa,GAAG;AACzB,WAAO,OAAO,GAAG,aAAa,MAAM;AACnC,YAAM,OAAO,OAAQ,QAAQ;AAC7B,UAAI,OAAO,SAAS,YAAY,MAAM;AACrC,cAAM,OAAO,KAAK;AAClB,cAAM,MAAM,oBAAoB,IAAI,IAAI,QAAQ,QAAQ;AAExD,sBAAc,GAAG;AAGjB,mBAAW,MAAM;AAChB,cAAI,kBAAkB,MAAM;AAC3B,qBAAS;AAAA,UACV;AAAA,QACD,GAAG,IAAI,KAAK,GAAI;AAAA,MACjB;AAAA,IACD,CAAC;AAED,WAAO,GAAG,SAAS,CAAC,QAAQ;AAC3B,cAAQ,MAAM,qBAAqB,IAAI,OAAO;AAC9C,MAAAA,SAAQ,KAAK;AAAA,IACd,CAAC;AAAA,EACF,CAAC;AACF;;;AEvcA,IAAM,MAAM;AACZ,IAAM,QAAQ;AACd,IAAM,SAAS;AACf,IAAM,OAAO;AACb,IAAM,OAAO;AACb,IAAM,OAAO;AACb,IAAM,MAAM;AACZ,IAAM,QAAQ;AAGd,IAAM,QAAQ;AACd,IAAM,QAAQ;AACd,IAAM,QAAQ;AACd,IAAM,SAAS;AACf,IAAM,UAAU;AAGT,SAAS,QAAQ,SAAuB;AAC9C,UAAQ,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,IAAI,OAAO,EAAE;AAClD;AAGO,SAAS,MAAM,SAAuB;AAC5C,UAAQ,IAAI,GAAG,GAAG,GAAG,KAAK,GAAG,KAAK,IAAI,OAAO,EAAE;AAChD;AAGO,SAAS,KAAK,SAAuB;AAC3C,UAAQ,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,IAAI,OAAO,EAAE;AACpD;AAGO,SAAS,KAAK,SAAuB;AAC3C,UAAQ,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,IAAI,OAAO,EAAE;AACjD;AAGO,SAAS,KAAK,SAAuB;AAC3C,UAAQ,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,KAAK,IAAI,OAAO,EAAE;AAClD;AAGO,SAAS,OAAO,OAAqB;AAC3C,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,EAAE;AACrC,UAAQ,IAAI,GAAG,GAAG,GAAG,SAAI,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE;AAC9C;AAGO,SAAS,YAAkB;AACjC,UAAQ,IAAI,GAAG,GAAG,GAAG,SAAI,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE;AAC9C;AAGO,SAAS,IAAI,SAAuB;AAC1C,UAAQ,OAAO,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,IAAI,OAAO,EAAE;AAC9D;AAGO,SAAS,QAAQ,WAAoB,SAAuB;AAElE,UAAQ,OAAO,MAAM,UAAU;AAC/B,MAAI,WAAW;AACd,YAAQ,OAAO;AAAA,EAChB,OAAO;AACN,UAAM,OAAO;AAAA,EACd;AACD;AAGO,SAAS,YAAkB;AACjC,UAAQ,OAAO,MAAM,UAAU;AAChC;;;AC7EA,SAAS,YAAY;AACrB,SAAS,cAAc,cAAAE,aAAY,aAAAC,YAAW,kBAAkB;AAChE,SAAS,WAAAC,gBAAe;AACxB,SAAS,iBAAiB;AAE1B,IAAM,YAAY,UAAU,IAAI;AAmBhC,SAAS,wBAAwB,WAA2B;AAC3D,QAAM,YAAY,UAAU,YAAY;AACxC,MAAI,UAAU,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM,GAAG;AAC7D,WAAO,IAAI,SAAS;AAAA,EACrB;AACA,SAAO,IAAI,SAAS;AACrB;AAKA,SAAS,MAAM,WAA4B;AAC1C,SAAO,UAAU,YAAY,EAAE,SAAS,MAAM;AAC/C;AAOA,SAAS,mBAAmB,YAA4B;AACvD,SAAO,MAAM,UAAU,IAAI,8CAA8C;AAC1E;AAKA,SAAS,kBAAkB,WAA2B;AACrD,SAAO,MAAM,SAAS,IAAI,eAAe;AAC1C;AAKA,eAAsB,mBAAqC;AAC1D,MAAI;AACH,UAAM,UAAU,oBAAoB;AACpC,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAOA,eAAsB,cACrB,WACmC;AACnC,MAAI;AACH,UAAM,QAAQ,wBAAwB,SAAS;AAC/C,UAAM,EAAE,OAAO,IAAI,MAAM;AAAA,MACxB,WAAW,KAAK;AAAA,IACjB;AACA,UAAM,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AAClD,QAAI,OAAO,MAAM,CAAC,KAAK,OAAO,MAAM,CAAC,EAAG,QAAO;AAC/C,WAAO,CAAC,GAAG,CAAC;AAAA,EACb,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,eACrB,WACyB;AACzB,MAAI;AACH,UAAM,QAAQ,wBAAwB,SAAS;AAC/C,UAAM,EAAE,OAAO,IAAI,MAAM;AAAA,MACxB,WAAW,KAAK;AAAA,IACjB;AACA,WAAO,OAAO,KAAK;AAAA,EACpB,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,KACrB,WACA,YACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM,UAAU,YAAY,SAAS,KAAK,QAAQ,gBAAgB,SAAS,KAAK,UAAU,GAAG;AAC7F,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,SACrB,WACA,YACmB;AACnB,QAAM,OAAO,MAAM,cAAc,SAAS;AAC1C,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,CAAC,OAAO,MAAM,IAAI;AAGxB,MAAI,UAAU,QAAQ;AACrB,QAAI,cAAc,YAAY;AAC7B,mBAAa,WAAW,UAAU;AAAA,IACnC;AACA,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,KAAK,IAAI,OAAO,MAAM;AACnC,QAAM,WAAW,kBAAkB,SAAS;AAC5C,QAAM,YAAY,mBAAmB,UAAU;AAE/C,MAAI;AACH,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,4CAA4C,IAAI,IAAI,IAAI,GAAG,SAAS,KAAK,UAAU;AAAA,IACtH;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAKA,eAAsB,YACrB,WACA,YACA,MACmB;AACnB,MAAI;AACH,UAAM;AAAA,MACL,YAAY,SAAS,aAAa,IAAI,IAAI,IAAI,6CAA6C,IAAI,IAAI,IAAI,KAAK,UAAU;AAAA,IACvH;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,iBACrB,WACA,YACA,OACA,QACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,WAAW,KAAK,IAAI,MAAM,6CAA6C,KAAK,IAAI,MAAM,GAAG,SAAS,KAAK,UAAU;AAAA,IACpJ;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,OACrB,WACA,YACA,OACA,QACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,WAAW,KAAK,IAAI,MAAM,IAAI,SAAS,KAAK,UAAU;AAAA,IACzF;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,cACrB,WACA,YACA,OACA,QACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,WAAW,KAAK,IAAI,MAAM,8CAA8C,KAAK,IAAI,MAAM,GAAG,SAAS,KAAK,UAAU;AAAA,IACrJ;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,iBACrB,WACA,YACA,OACA,MACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,SAAS,IAAI,mBAAmB,KAAK,IAAI,SAAS,KAAK,UAAU;AAAA,IACpG;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,2BACrB,WACA,YACA,OACA,MACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,iBAAiB,KAAK,kCAAkC,IAAI,2CAA2C,SAAS,KAAK,UAAU;AAAA,IAClK;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AASA,eAAsB,0BACrB,WACA,YACA,OACA,MACA,gBAAgB,IACG;AAEnB,MAAI,MAAM,SAAS,GAAG;AACrB,WAAO,2BAA2B,WAAW,YAAY,OAAO,IAAI;AAAA,EACrE;AAEA,MAAI;AAEH,UAAM,gBAAgB,MAAO,gBAAgB,MAAO;AAQpD,UAAM;AAAA,MACL,YAAY,SAAS,mBACJ,KAAK,kCACF,IAAI,8EAGa,aAAa,yCAE9C,UAAU;AAAA,IACf;AACA,WAAO;AAAA,EACR,QAAQ;AAEP,WAAO,2BAA2B,WAAW,YAAY,OAAO,IAAI;AAAA,EACrE;AACD;AAKA,eAAsB,UACrB,WACA,YACA,QAAkB,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,EAAE,GACxB;AACnB,MAAI;AACH,UAAM,UAAU,MAAM,KAAK,GAAG;AAC9B,UAAM;AAAA,MACL,YAAY,SAAS,8BAA8B,OAAO,KAAK,UAAU;AAAA,IAC1E;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAKA,eAAsB,sBACrB,UACA,YACmB;AACnB,MAAI;AACH,UAAM,SAAS,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG;AACrD,UAAM,UAAU,WAAW,MAAM,KAAK,UAAU,GAAG;AACnD,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAKO,SAAS,UAAU,UAAwB;AACjD,QAAM,MAAMC,SAAQ,QAAQ;AAC5B,MAAI,CAACC,YAAW,GAAG,GAAG;AACrB,IAAAC,WAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,EACnC;AACD;AAKO,SAAS,WAAW,OAAuB;AACjD,aAAW,QAAQ,OAAO;AACzB,QAAI;AACH,UAAID,YAAW,IAAI,GAAG;AACrB,mBAAW,IAAI;AAAA,MAChB;AAAA,IACD,QAAQ;AAAA,IAER;AAAA,EACD;AACD;AAWA,eAAsB,kBACrB,WACA,YACA,aAAa,GACM;AACnB,QAAM,YAAY,UAAU,YAAY;AACxC,MAAI,CAAC,UAAU,SAAS,MAAM,KAAK,CAAC,UAAU,SAAS,MAAM,GAAG;AAE/D,QAAI;AACH,mBAAa,WAAW,UAAU;AAClC,aAAO;AAAA,IACR,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AAEA,MAAI;AACH,QAAI,UAAU,SAAS,MAAM,GAAG;AAC/B,UAAI,eAAe,GAAG;AAErB,cAAM,UAAU,YAAY,SAAS,SAAS,UAAU,GAAG;AAAA,MAC5D,OAAO;AAGN,cAAM;AAAA,UACL,YAAY,SAAS,MAAM,UAAU,8BAA8B,UAAU;AAAA,QAC9E;AAAA,MACD;AAAA,IACD,OAAO;AAEN,YAAM,UAAU,YAAY,SAAS,IAAI,UAAU,OAAO,UAAU,GAAG;AAAA,IACxE;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAKO,SAAS,aAAa,WAA4B;AACxD,QAAM,YAAY,UAAU,YAAY;AACxC,SAAO,UAAU,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM;AAC/D;AAKA,eAAsB,cAAc,WAAoC;AACvE,MAAI;AACH,UAAM,EAAE,OAAO,IAAI,MAAM;AAAA,MACxB,6BAA6B,SAAS;AAAA,IACvC;AACA,UAAM,QAAQ,SAAS,OAAO,KAAK,GAAG,EAAE;AACxC,WAAO,OAAO,MAAM,KAAK,IAAI,IAAI;AAAA,EAClC,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAQA,eAAsB,iBACrB,WACA,WACA,UACoB;AACpB,MAAI;AAEH,cAAU,GAAG,SAAS,QAAQ;AAK9B,UAAM;AAAA,MACL,YAAY,SAAS,wBAAwB,SAAS,IAAI,QAAQ;AAAA,IACnE;AAGA,UAAM,EAAE,OAAO,IAAI,MAAM,UAAU,UAAU,SAAS,IAAI,QAAQ,6BAA6B;AAC/F,UAAM,QAAQ,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAK,EAAE,SAAS,CAAC;AAChE,WAAO;AAAA,EACR,QAAQ;AACP,WAAO,CAAC;AAAA,EACT;AACD;AAMA,eAAsB,eACrB,WACA,YACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,QAAQ,SAAS,KAAK,UAAU;AAAA,IACnE;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,aACrB,WACA,YACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,QAAQ,SAAS,KAAK,UAAU;AAAA,IACnE;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,OACrB,WACA,YACA,SACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,WAAW,OAAO,oBAAoB,SAAS,KAAK,UAAU;AAAA,IACjG;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,gBACrB,WACA,YACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,mBAAmB,SAAS,KAAK,UAAU;AAAA,IAC9E;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,YACrB,WACA,YACA,YAAY,IACO;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,eAAe,SAAS,IAAI,SAAS,KAAK,UAAU;AAAA,IACvF;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,aACrB,WACA,YACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,UAAU,SAAS,KAAK,UAAU;AAAA,IACrE;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,cACrB,WACA,YACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,qDAAqD,SAAS,KAAK,UAAU;AAAA,IAChH;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,YACrB,WACA,YACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,wBAAwB,SAAS,KAAK,UAAU;AAAA,IACnF;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,UACrB,WACA,YACA,OACA,OACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,iBAAiB,KAAK,aAAa,KAAK,GAAG,SAAS,KAAK,UAAU;AAAA,IACtG;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,aACrB,WACA,YACA,WACA,SACA,MACmB;AACnB,MAAI;AACH,UAAM,WAAW,kBAAkB,SAAS;AAC5C,UAAM,YAAY,mBAAmB,UAAU;AAC/C,UAAM;AAAA,MACL,YAAY,SAAS,KAAK,QAAQ,SAAS,IAAI,YAAY,OAAO,cAAc,SAAS,IAAI,SAAS,KAAK,UAAU;AAAA,IACtH;AACA,WAAO;AAAA,EACR,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAMA,eAAsB,eACrB,WACA,YACA,YACqD;AACrD,MAAI;AACH,UAAM,gBAAgB,MAAM,cAAc,SAAS;AACnD,QAAI,iBAAiB,GAAG;AACvB,aAAO,EAAE,SAAS,MAAM;AAAA,IACzB;AACA,QAAI,aAAa,KAAK,cAAc,eAAe;AAClD,aAAO,EAAE,SAAS,MAAM;AAAA,IACzB;AAIA,UAAM;AAAA,MACL,YAAY,SAAS,uBAAuB,UAAU,8CAA8C,UAAU;AAAA,IAC/G;AAEA,UAAM,WAAW,MAAM,cAAc,UAAU;AAC/C,WAAO,EAAE,SAAS,MAAM,YAAY,SAAS;AAAA,EAC9C,QAAQ;AACP,WAAO,EAAE,SAAS,MAAM;AAAA,EACzB;AACD;AAOA,eAAsB,gBACrB,WACA,YACA,YACA,iBACqD;AACrD,MAAI;AACH,UAAM,aAAa,MAAM,cAAc,SAAS;AAChD,QAAI,aAAa,KAAK,cAAc,YAAY;AAC/C,aAAO,EAAE,SAAS,MAAM;AAAA,IACzB;AAGA,UAAM,OAAO,MAAM,cAAc,SAAS;AAC1C,QAAI,CAAC,KAAM,QAAO,EAAE,SAAS,MAAM;AAGnC,UAAM,kBAAkB,GAAG,UAAU;AACrC,UAAM;AAAA,MACL,YAAY,eAAe,aAAa,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,6BAA6B,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,eAAe;AAAA,IAC9H;AAKA,QAAI,eAAe,GAAG;AAErB,YAAM;AAAA,QACL,YAAY,eAAe,UAAU,SAAS,uEAAuE,UAAU;AAAA,MAChI;AAAA,IACD,WAAW,eAAe,aAAa,GAAG;AAEzC,YAAM;AAAA,QACL,gBAAgB,SAAS,+BAA+B,eAAe,+CAA+C,UAAU;AAAA,MACjI;AAAA,IACD,OAAO;AAEN,YAAM;AAAA,QACL,gBAAgB,SAAS,2BAA2B,UAAU,KAAK,UAAU,4BACjE,UAAU,iBAAiB,aAAa,CAAC,OAAO,eAAe,MAAM,UAAU,eAAe,UAAU,iDAAiD,UAAU,eACrK,UAAU;AAAA,MACrB;AAAA,IACD;AAGA,QAAI;AAAE,iBAAW,eAAe;AAAA,IAAG,QAAQ;AAAA,IAAe;AAE1D,UAAM,WAAW,MAAM,cAAc,UAAU;AAC/C,WAAO,EAAE,SAAS,MAAM,YAAY,SAAS;AAAA,EAC9C,QAAQ;AACP,WAAO,EAAE,SAAS,MAAM;AAAA,EACzB;AACD;AAUA,eAAsB,YACrB,WACA,YACA,YACqD;AACrD,MAAI,aAAa,GAAG;AAEnB,QAAI,cAAc,YAAY;AAC7B,UAAI;AACH,qBAAa,WAAW,UAAU;AAClC,cAAME,SAAQ,MAAM,cAAc,UAAU;AAC5C,eAAO,EAAE,SAAS,MAAM,YAAYA,OAAM;AAAA,MAC3C,QAAQ;AACP,eAAO,EAAE,SAAS,MAAM;AAAA,MACzB;AAAA,IACD;AACA,UAAM,QAAQ,MAAM,cAAc,SAAS;AAC3C,WAAO,EAAE,SAAS,MAAM,YAAY,MAAM;AAAA,EAC3C;AAEA,MAAI;AAEH,UAAM,gBAAgB,MAAM,cAAc,SAAS;AACnD,QAAI,iBAAiB,GAAG;AAEvB,mBAAa,WAAW,UAAU;AAClC,aAAO,EAAE,SAAS,MAAM,YAAY,EAAE;AAAA,IACvC;AAGA,UAAM,eAAyB,CAAC;AAChC,aAAS,IAAI,GAAG,IAAI,eAAe,KAAK,YAAY;AACnD,mBAAa,KAAK,CAAC;AAAA,IACpB;AAKA,UAAM,cAAc,aAAa,KAAK,GAAG;AAEzC,UAAM;AAAA,MACL,YAAY,SAAS,IAAI,WAAW,0DAA0D,UAAU;AAAA,IACzG;AAEA,UAAM,WAAW,MAAM,cAAc,UAAU;AAC/C,WAAO,EAAE,SAAS,MAAM,YAAY,SAAS;AAAA,EAC9C,QAAQ;AACP,WAAO,EAAE,SAAS,MAAM;AAAA,EACzB;AACD;;;ACh1BA,SAAS,UAAU,WAAAC,UAAS,SAAS,eAAe;AAM7C,SAAS,aAAa,SAAyB;AAErD,MAAI,QAAQ,WAAW,OAAO,GAAG;AAChC,WAAO;AAAA,EACR;AAGA,QAAM,QAAQ,QAAQ,MAAM,wBAAwB;AACpD,MAAI,OAAO;AACV,UAAM,QAAQ,MAAM,CAAC,EAAE,YAAY;AACnC,UAAM,OAAO,MAAM,CAAC,EAAE,QAAQ,OAAO,GAAG;AACxC,WAAO,QAAQ,KAAK,IAAI,IAAI;AAAA,EAC7B;AAEA,SAAO;AACR;AAMO,SAAS,aAAa,SAAyB;AACrD,QAAM,QAAQ,QAAQ,MAAM,yBAAyB;AACrD,MAAI,OAAO;AACV,UAAM,QAAQ,MAAM,CAAC,EAAE,YAAY;AACnC,UAAM,OAAO,MAAM,CAAC,EAAE,QAAQ,OAAO,IAAI;AACzC,WAAO,GAAG,KAAK,MAAM,IAAI;AAAA,EAC1B;AACA,SAAO;AACR;AAKO,SAAS,cAAc,WAA2B;AACxD,MAAI,kBAAkB,KAAK,SAAS,GAAG;AACtC,WAAO,aAAa,SAAS;AAAA,EAC9B;AACA,SAAO,QAAQ,SAAS;AACzB;AAYO,SAAS,YAAY,UAA4B;AACvD,QAAM,MAAMA,SAAQ,QAAQ;AAC5B,QAAM,OAAO,SAAS,QAAQ;AAC9B,QAAM,MAAM,QAAQ,QAAQ;AAC5B,QAAM,OAAO,KAAK,MAAM,GAAG,CAAC,IAAI,MAAM;AAEtC,SAAO;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,UAAU;AAAA,IACV,WAAW;AAAA,EACZ;AACD;;;ACrEA,OAAO,aAAa;AAGpB,IAAI,cAAc;AAGlB,IAAM,YAAkE,CAAC;AAKlE,SAAS,eAAe,OAAsB;AACpD,gBAAc;AACf;AAYO,SAAS,aAAa,QAAoE;AAChG,SAAO,OAAO,WAAW,MAAM;AAChC;AAKO,SAAS,iBAAuB;AACtC,aAAW,OAAO,OAAO,KAAK,SAAS,GAAG;AACzC,WAAO,UAAU,GAAG;AAAA,EACrB;AACD;AAKA,SAAS,YAAY,SAAmE;AACvF,QAAM,WAAW,QAAQ,YAAY;AACrC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,GAAG;AACrD,QAAI,SAAS,SAAS,IAAI,YAAY,CAAC,GAAG;AACzC,aAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO;AACR;AAKA,eAAsB,KACrB,SACA,cACkB;AAClB,MAAI,YAAa,QAAO,gBAAgB;AAExC,QAAM,WAAW,MAAM,QAAQ;AAAA,IAC9B,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA,SAAS;AAAA,EACV,CAAC;AACD,SAAO,SAAS,SAAS,gBAAgB;AAC1C;AAKA,eAAsB,OACrB,SACA,cACA,KACA,KACkB;AAClB,QAAM,WAAW,YAAY,OAAO;AACpC,MAAI,aAAa,OAAW,QAAO,OAAO,QAAQ;AAClD,MAAI,YAAa,QAAO,gBAAgB;AAExC,QAAM,WAAW,MAAM,QAAQ;AAAA,IAC9B,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,EACD,CAAC;AACD,SAAO,SAAS,SAAS,gBAAgB;AAC1C;AAKA,eAAsB,QACrB,SACA,eAAe,MACI;AACnB,QAAM,WAAW,YAAY,OAAO;AACpC,MAAI,aAAa,OAAW,QAAO,QAAQ,QAAQ;AACnD,MAAI,YAAa,QAAO;AAExB,QAAM,WAAW,MAAM,QAAQ;AAAA,IAC9B,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA,SAAS;AAAA,EACV,CAAC;AACD,SAAO,SAAS,SAAS;AAC1B;AAWA,eAAsB,OACrB,SACA,SACA,cACoB;AACpB,MAAI,YAAa,QAAO,gBAAiB,QAAQ,CAAC,GAAG,SAAe;AAEpE,QAAM,WAAW,MAAM,QAAQ;AAAA,IAC9B,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA,SAAS,QAAQ,IAAI,CAAC,SAAS;AAAA,MAC9B,OAAO,IAAI;AAAA,MACX,OAAO,IAAI;AAAA,MACX,aAAa,IAAI;AAAA,IAClB,EAAE;AAAA,EACH,CAAC;AACD,SAAQ,SAAS,SAAe;AACjC;AAKA,eAAsB,YACrB,SACA,SACA,eACe;AACf,MAAI,YAAa,QAAO,iBAAiB,CAAC;AAE1C,QAAM,WAAW,MAAM,QAAQ;AAAA,IAC9B,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA,SAAS,QAAQ,IAAI,CAAC,SAAS;AAAA,MAC9B,OAAO,IAAI;AAAA,MACX,OAAO,IAAI;AAAA,MACX,aAAa,IAAI;AAAA,IAClB,EAAE;AAAA,IACF,cAAc;AAAA,IACd,MAAM;AAAA,EACP,CAAC;AACD,SAAQ,SAAS,SAAiB,CAAC;AACpC;AAUA,QAAQ,SAAS,CAAC,CAAC;AAMnB,eAAsB,aAAa,UAAU,2BAA0C;AACtF,MAAI,CAAC,YAAa;AAElB,UAAQ,IAAI;AACZ,QAAM,QAAQ;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,EACD,CAAC;AACF;;;ANxJA,eAAe,aACd,OACA,SACmB;AACnB,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AACzE,QAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,UAAU,SAAS;AAE1E,MAAI,UAAU,QAAQ,KAAK,MAAM,QAAQ,KAAK,YAAY;AAE1D,QAAMC,WAAU,MAAM,UAAU,OAAO,QAAQ,QAAQ,OAAO,QAAQ,KAAK;AAE3E,MAAI,CAACA,UAAS;AACb,YAAQ,OAAO,eAAe;AAC9B,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,cAAc;AAE5B,QAAM,YAAY,MAAM,cAAc,MAAM;AAE5C,UAAQ,IAAI,EAAE;AACd,MAAI,WAAW;AACd,YAAQ,IAAI,WAAW,MAAM,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,GAAG;AAAA,EAClE,OAAO;AACN,YAAQ,IAAI,WAAW,MAAM,EAAE;AAAA,EAChC;AACA,SAAO;AACR;AAKA,eAAe,oBAA6C;AAC3D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,IAAI,mBAAmB,KAAK,EAAE;AAC7C,UAAQ,IAAI,KAAK,GAAG,oDAAoD,KAAK,EAAE;AAC/E,UAAQ,IAAI,KAAK,GAAG,4DAA4D,KAAK,EAAE;AACvF,UAAQ,IAAI,EAAE;AAEd,MAAI,QAAQ,MAAM,OAAa,qBAAqB,IAAI,GAAG,GAAG;AAC9D,MAAI,QAAQ,GAAG;AACd,YAAQ;AAAA,EACT;AAEA,UAAQ,IAAI,EAAE;AACd,MAAI,QAAQ,MAAM,KAAW,gBAAgB,SAAS;AACtD,MAAI,CAAC,OAAO;AACX,YAAQ;AAAA,EACT;AAEA,SAAO,EAAE,OAAO,MAAM;AACvB;AAKA,eAAsB,IAAI,UAAoC;AAC7D,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,UAAM,2CAA2C;AACjD,YAAQ,IAAI,mDAAmD;AAC/D,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACC,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,SAAO,eAAe;AAEtB,MAAI,oBAAoB;AACxB,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,YAAQ,OAAO,sBAAsB;AACrC,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,SAAS,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE;AAE3C,QAAM,UAAU,MAAM,kBAAkB;AAExC,UAAQ,IAAI,EAAE;AACd,SAAO,aAAa,OAAO,OAAO;AACnC;AAKA,eAAsB,OAAO,UAAoC;AAChE,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACA,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAEA,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUC,UAAS,KAAK;AAAA,MACxB,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd,aAAa;AAAA,IACd;AAAA,IACA,UAAU;AAAA,MACT,OAAO;AAAA,MACP,OAAO;AAAA,IACR;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,QAAS,KAAK,SAAoB;AACxC,YAAM,QAAS,KAAK,SAAoB;AACxC,aAAO,gBAAgB,OAAO,EAAE,OAAO,MAAM,CAAC;AAAA,IAC/C;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,OAAiD,CAAC;AAExD,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,oEAAoE,CAAC;AAAA,QACvG;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,cAAcA,UAAS,KAAK,CAAC,MAAM,CAAC;AAEvE,YAAM,QAAS,KAAK,SAAoB;AACxC,YAAM,QAAS,KAAK,SAAoB;AACxC,YAAM,UAA0B,EAAE,OAAO,MAAM;AAE/C,YAAM,WAAW,YAAY,KAAK;AAClC,YAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AACzE,YAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,UAAU,SAAS;AAE1E,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,UAAU,KAAK,eAAe,CAAC;AAElE,YAAMF,WAAU,MAAM,UAAU,OAAO,QAAQ,OAAO,KAAK;AAE3D,UAAIA,UAAS;AACZ,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,eAAe,CAAC;AACtD,cAAM,YAAY,MAAM,cAAc,MAAM;AAC5C,cAAM,UAAU,YAAY,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,MAAM;AACnE,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,GAAGE,UAAS,MAAM,CAAC,GAAG,OAAO;AAAA,UACrC;AAAA,QACD;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,SAAS,SAAS,gBAAgB,CAAC;AACrD,aAAO;AAAA,QACN,SAAS;AAAA,QACT,OAAO;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAKA,eAAe,gBACd,OACA,SACqG;AACrG,QAAM,UAAU,OAAO;AACvB,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,aAAaC,MAAK,SAAS,kBAAkB,SAAS,UAAU;AACtE,QAAM,aAAaA,MAAK,SAAS,kBAAkB,SAAS,MAAM;AAElE,MAAI;AAEH,QAAI,eAAe;AACnB,QAAI,aAAa,KAAK,GAAG;AACxB,UAAI,CAAE,MAAM,kBAAkB,OAAO,UAAU,GAAI;AAClD,eAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,MAC3D;AACA,qBAAe;AAAA,IAChB;AAEA,UAAMH,WAAU,MAAM,UAAU,cAAc,YAAY,QAAQ,OAAO,QAAQ,KAAK;AAEtF,QAAI,CAACA,UAAS;AACb,cAAQ,YAAY,UAAU;AAC9B,aAAO,EAAE,SAAS,OAAO,OAAO,gBAAgB;AAAA,IACjD;AAEA,UAAM,SAASI,cAAa,UAAU;AACtC,UAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,UAAM,YAAY,yBAAyB,MAAM;AAEjD,UAAM,OAAO,MAAM,cAAc,UAAU;AAE3C,YAAQ,YAAY,UAAU;AAE9B,WAAO;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,OAAO,OAAO,CAAC;AAAA,MACf,QAAQ,OAAO,CAAC;AAAA,IACjB;AAAA,EACD,SAAS,KAAK;AACb,YAAQ,YAAY,UAAU;AAC9B,WAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,EACxD;AACD;AAEO,IAAM,SAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,QAAQ,SAAS,QAAQ,MAAM;AACrD;;;AOtQA,SAAS,WAAAC,gBAAe;AACxB,SAAS,WAAAC,gBAAe;AACxB,SAAS,iBAAAC,sBAAqB;AAC9B,OAAO,WAAW;;;ACHlB,SAAS,cAAAC,aAAY,aAAAC,YAAW,gBAAAC,qBAAoB;AACpD,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,WAAU,QAAAC,aAAY;AA8B/B,eAAsBC,KAAI,UAAoC;AAC7D,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,UAAM,2CAA2C;AACjD,YAAQ,IAAI,mDAAmD;AAC/D,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACC,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,SAAO,uBAAuB;AAE9B,MAAI,kBAAkB;AACtB,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,YAAQ,OAAO,sBAAsB;AACrC,WAAO;AAAA,EACR;AAEA,QAAM,aAAa,MAAM,cAAc,KAAK;AAC5C,UAAQ,MAAM,SAAS,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,UAAU,SAAS;AAEjE,MAAI,cAAc,GAAG;AACpB,SAAK,4CAA4C;AACjD,WAAO;AAAA,EACR;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,IAAI,kBAAkB,KAAK,EAAE;AAC5C,UAAQ,IAAI,KAAK,GAAG,oBAAoB,UAAU,aAAa,KAAK,EAAE;AACtE,UAAQ,IAAI,EAAE;AAEd,QAAM,UAAU,MAAM,QAAc,WAAW,UAAU,YAAY,IAAI;AACzE,MAAI,CAAC,SAAS;AACb,SAAK,WAAW;AAChB,WAAO;AAAA,EACR;AAEA,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,YAAY,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAE1D,UAAQ,IAAI,EAAE;AACd,MAAI,sBAAsB;AAE1B,EAAAC,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AACxC,QAAM,SAAS,MAAM,iBAAiB,OAAO,WAAW,OAAO;AAE/D,MAAI,OAAO,WAAW,GAAG;AACxB,YAAQ,OAAO,mBAAmB;AAClC,WAAO;AAAA,EACR;AAEA,UAAQ,MAAM,aAAa,OAAO,MAAM,SAAS;AAEjD,UAAQ,IAAI,EAAE;AACd,UAAQ,WAAW,SAAS,GAAG;AAC/B,SAAO;AACR;AAKA,eAAsBC,QAAO,UAAoC;AAChE,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACF,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAEA,QAAM,aAAa,MAAM,cAAc,KAAK;AAC5C,QAAM,WAAW,YAAY,KAAK;AAElC,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUG,UAAS,KAAK;AAAA,MACxB,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd,aAAa;AAAA,IACd;AAAA,IACA,UAAU;AAAA,MACT;AAAA,IACD;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,aAAc,KAAK,cAAyB;AAClD,aAAO,qBAAqB,OAAO,UAAU;AAAA,IAC9C;AAAA,IACA,WAAW,YAAY;AACtB,YAAM,OAAiD,CAAC;AAExD,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,oEAAoE,CAAC;AAAA,QACvG;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,cAAc,UAAU,aAAa,CAAC;AAEzE,YAAM,YAAY,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAC1D,MAAAF,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAExC,YAAM,SAAS,MAAM,iBAAiB,OAAO,WAAW,OAAO;AAE/D,UAAI,OAAO,SAAS,GAAG;AACtB,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,aAAa,OAAO,MAAM,UAAU,CAAC;AAC3E,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,GAAG,OAAO,MAAM,cAAc,SAAS,QAAQ;AAAA,UACvD;AAAA,QACD;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,SAAS,SAAS,oBAAoB,CAAC;AACzD,aAAO,EAAE,SAAS,OAAO,OAAO,qBAAqB,KAAK;AAAA,IAC3D;AAAA,EACD,CAAC;AACF;AAKA,eAAe,qBACd,OACA,YACqG;AACrG,QAAM,UAAUG,QAAO;AACvB,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,aAAaC,MAAK,SAAS,gBAAgB,SAAS,MAAM;AAEhE,MAAI;AACH,QAAI,CAAE,MAAM,kBAAkB,OAAO,YAAY,UAAU,GAAI;AAC9D,aAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,IAC3D;AAEA,UAAM,SAASC,cAAa,UAAU;AACtC,UAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,UAAM,YAAY,yBAAyB,MAAM;AAEjD,UAAM,OAAO,MAAM,cAAc,UAAU;AAC3C,YAAQ,UAAU;AAElB,WAAO;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,OAAO,OAAO,CAAC;AAAA,MACf,QAAQ,OAAO,CAAC;AAAA,IACjB;AAAA,EACD,SAAS,KAAK;AACb,YAAQ,UAAU;AAClB,WAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,EACxD;AACD;AAEO,IAAMC,UAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,MAAM;AACpB;;;AC/MA,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AACzC,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,WAAU,QAAAC,aAAY;AAsC/B,IAAM,gBAA4C;AAAA,EACjD,aAAa;AAAA,EACb,SAAS;AAAA,EACT,UAAU;AAAA,EACV,WAAW;AAAA,EACX,SAAS;AACV;AAKA,eAAe,YACd,OACA,QACA,QACmB;AACnB,UAAQ,QAAQ;AAAA,IACf,KAAK;AACJ,aAAO,gBAAgB,OAAO,MAAM;AAAA,IACrC,KAAK;AACJ,aAAO,YAAY,OAAO,MAAM;AAAA,IACjC,KAAK;AACJ,aAAO,aAAa,OAAO,MAAM;AAAA,IAClC,KAAK;AACJ,aAAO,cAAc,OAAO,MAAM;AAAA,IACnC,KAAK;AACJ,aAAO,YAAY,OAAO,MAAM;AAAA,IACjC;AACC,aAAO;AAAA,EACT;AACD;AAKA,eAAeC,cACd,OACA,SACmB;AACnB,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AACzE,QAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,IAAI,QAAQ,MAAM,GAAG,SAAS;AAErF,MAAI,YAAY,cAAc,QAAQ,MAAM,CAAC,YAAY;AAEzD,QAAMC,WAAU,MAAM,YAAY,OAAO,QAAQ,QAAQ,MAAM;AAE/D,MAAI,CAACA,UAAS;AACb,YAAQ,OAAO,eAAe;AAC9B,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,cAAc,QAAQ,MAAM,CAAC;AAE3C,QAAM,YAAY,MAAM,cAAc,MAAM;AAE5C,UAAQ,IAAI,EAAE;AACd,MAAI,WAAW;AACd,YAAQ,IAAI,WAAW,MAAM,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,GAAG;AAAA,EAClE,OAAO;AACN,YAAQ,IAAI,WAAW,MAAM,EAAE;AAAA,EAChC;AACA,SAAO;AACR;AAKA,eAAeC,qBAA6C;AAC3D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,IAAI,kBAAkB,KAAK,EAAE;AAC5C,UAAQ,IAAI,KAAK,GAAG,iCAAiC,KAAK,EAAE;AAC5D,UAAQ,IAAI,KAAK,GAAG,gCAAgC,KAAK,EAAE;AAC3D,UAAQ,IAAI,KAAK,GAAG,8BAA8B,KAAK,EAAE;AACzD,UAAQ,IAAI,KAAK,GAAG,qCAAqC,KAAK,EAAE;AAChE,UAAQ,IAAI,KAAK,GAAG,kCAAkC,KAAK,EAAE;AAC7D,UAAQ,IAAI,EAAE;AAEd,QAAM,SAAS,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,MACC,EAAE,OAAO,aAAa,OAAO,YAAY;AAAA,MACzC,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,MACjC,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,MACnC,EAAE,OAAO,WAAW,OAAO,UAAU;AAAA,MACrC,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,IAClC;AAAA,IACA;AAAA,EACD;AAEA,SAAO,EAAE,QAAQ,UAAU,YAAY;AACxC;AAKA,eAAsBC,KAAI,UAAoC;AAC7D,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,UAAM,2CAA2C;AACjD,YAAQ,IAAI,mDAAmD;AAC/D,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACC,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,SAAO,eAAe;AAEtB,MAAI,oBAAoB;AACxB,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,YAAQ,OAAO,sBAAsB;AACrC,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,SAAS,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE;AAE3C,QAAM,UAAU,MAAMF,mBAAkB;AAExC,UAAQ,IAAI,EAAE;AACd,SAAOF,cAAa,OAAO,OAAO;AACnC;AAKA,eAAsBK,QAAO,UAAoC;AAChE,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACD,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAEA,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUE,UAAS,KAAK;AAAA,MACxB,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd,aAAa;AAAA,IACd;AAAA,IACA,UAAU;AAAA,MACT,QAAQ;AAAA,IACT;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,SAAU,KAAK,UAAyB;AAC9C,aAAOC,iBAAgB,OAAO,EAAE,OAAO,CAAC;AAAA,IACzC;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,OAAiD,CAAC;AAExD,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,oEAAoE,CAAC;AAAA,QACvG;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,cAAcD,UAAS,KAAK,CAAC,MAAM,CAAC;AAEvE,YAAM,SAAU,KAAK,UAAyB;AAC9C,YAAM,UAA0B,EAAE,OAAO;AAEzC,YAAM,WAAW,YAAY,KAAK;AAClC,YAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AACzE,YAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,IAAI,MAAM,GAAG,SAAS;AAE7E,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,YAAY,cAAc,MAAM,CAAC,aAAa,CAAC;AAElF,YAAML,WAAU,MAAM,YAAY,OAAO,QAAQ,MAAM;AAEvD,UAAIA,UAAS;AACZ,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,iBAAiB,CAAC;AACxD,cAAM,YAAY,MAAM,cAAc,MAAM;AAC5C,cAAM,UAAU,YAAY,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,MAAM;AACnE,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,GAAGK,UAAS,MAAM,CAAC,GAAG,OAAO;AAAA,UACrC;AAAA,QACD;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,SAAS,SAAS,gBAAgB,CAAC;AACrD,aAAO;AAAA,QACN,SAAS;AAAA,QACT,OAAO;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAKA,eAAeC,iBACd,OACA,SACqG;AACrG,QAAM,UAAUC,QAAO;AACvB,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,aAAaC,MAAK,SAAS,kBAAkB,SAAS,UAAU;AACtE,QAAM,aAAaA,MAAK,SAAS,kBAAkB,SAAS,MAAM;AAElE,MAAI;AAEH,QAAI,eAAe;AACnB,QAAI,aAAa,KAAK,GAAG;AACxB,UAAI,CAAE,MAAM,kBAAkB,OAAO,UAAU,GAAI;AAClD,eAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,MAC3D;AACA,qBAAe;AAAA,IAChB;AAEA,UAAMR,WAAU,MAAM,YAAY,cAAc,YAAY,QAAQ,MAAM;AAE1E,QAAI,CAACA,UAAS;AACb,cAAQ,YAAY,UAAU;AAC9B,aAAO,EAAE,SAAS,OAAO,OAAO,gBAAgB;AAAA,IACjD;AAEA,UAAM,SAASS,cAAa,UAAU;AACtC,UAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,UAAM,YAAY,yBAAyB,MAAM;AAEjD,UAAM,OAAO,MAAM,cAAc,UAAU;AAE3C,YAAQ,YAAY,UAAU;AAE9B,WAAO;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,OAAO,OAAO,CAAC;AAAA,MACf,QAAQ,OAAO,CAAC;AAAA,IACjB;AAAA,EACD,SAAS,KAAK;AACb,YAAQ,YAAY,UAAU;AAC9B,WAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,EACxD;AACD;AAEO,IAAMC,UAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,QAAQ,SAAS,QAAQ,MAAM;AACrD;;;AC5SA,SAAS,cAAAC,aAAY,aAAAC,kBAAiB;AACtC,SAAS,YAAAC,WAAU,WAAAC,gBAAe;AAiClC,IAAM,YAAuB;AAAA,EAC5B,EAAE,UAAU,qBAAqB,MAAM,GAAG;AAAA,EAC1C,EAAE,UAAU,qBAAqB,MAAM,GAAG;AAAA,EAC1C,EAAE,UAAU,qBAAqB,MAAM,GAAG;AAAA,EAC1C,EAAE,UAAU,wBAAwB,MAAM,IAAI;AAAA,EAC9C,EAAE,UAAU,8BAA8B,MAAM,IAAI;AAAA,EACpD,EAAE,UAAU,8BAA8B,MAAM,IAAI;AAAA,EACpD,EAAE,UAAU,sBAAsB,MAAM,IAAI;AAC7C;AAEA,IAAM,gBAA2B;AAAA,EAChC,EAAE,UAAU,+BAA+B,MAAM,GAAG;AAAA,EACpD,EAAE,UAAU,+BAA+B,MAAM,GAAG;AAAA,EACpD,EAAE,UAAU,gCAAgC,MAAM,GAAG;AAAA,EACrD,EAAE,UAAU,iCAAiC,MAAM,IAAI;AAAA,EACvD,EAAE,UAAU,kCAAkC,MAAM,IAAI;AAAA,EACxD,EAAE,UAAU,sBAAsB,MAAM,IAAI;AAC7C;AAEA,IAAM,YAAuB;AAAA;AAAA,EAE5B,EAAE,UAAU,kBAAkB,MAAM,GAAG;AAAA,EACvC,EAAE,UAAU,qBAAqB,MAAM,GAAG;AAAA,EAC1C,EAAE,UAAU,qBAAqB,MAAM,GAAG;AAAA;AAAA,EAE1C,EAAE,UAAU,kBAAkB,MAAM,GAAG;AAAA,EACvC,EAAE,UAAU,qBAAqB,MAAM,GAAG;AAAA,EAC1C,EAAE,UAAU,qBAAqB,MAAM,GAAG;AAAA;AAAA,EAE1C,EAAE,UAAU,kBAAkB,MAAM,GAAG;AAAA,EACvC,EAAE,UAAU,qBAAqB,MAAM,GAAG;AAAA,EAC1C,EAAE,UAAU,qBAAqB,MAAM,IAAI;AAAA;AAAA,EAE3C,EAAE,UAAU,qBAAqB,MAAM,IAAI;AAAA,EAC3C,EAAE,UAAU,qBAAqB,MAAM,IAAI;AAAA;AAAA,EAE3C,EAAE,UAAU,kBAAkB,MAAM,GAAG;AAAA,EACvC,EAAE,UAAU,qBAAqB,MAAM,IAAI;AAAA;AAAA,EAE3C,EAAE,UAAU,uBAAuB,MAAM,IAAI;AAAA;AAAA,EAE7C,EAAE,UAAU,oBAAoB,MAAM,KAAK;AAC5C;AAKA,eAAe,cACd,WACA,WACA,OACkB;AAClB,QAAM,QAAQ,MAAM;AACpB,MAAI,UAAU;AACd,MAAI,SAAS;AAEb,aAAW,QAAQ,OAAO;AACzB;AACA,UAAM,aAAa,GAAG,SAAS,IAAI,KAAK,QAAQ;AAGhD,UAAM,SAASC,SAAQ,UAAU;AACjC,QAAI,CAACC,YAAW,MAAM,GAAG;AACxB,MAAAC,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,IACtC;AAEA,cAAU;AACV,QAAI,IAAI,OAAO,IAAI,KAAK,gBAAgB,KAAK,QAAQ,KAAK;AAE1D,QAAI,MAAM,YAAY,WAAW,YAAY,KAAK,IAAI,GAAG;AACxD,gBAAU;AACV;AAAA,QACC,IAAI,OAAO,IAAI,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI;AAAA,MAClE;AAAA,IACD,OAAO;AACN,gBAAU;AACV,YAAM,IAAI,OAAO,IAAI,KAAK,aAAa,KAAK,QAAQ,EAAE;AACtD;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;AAKA,eAAe,gBACd,WACA,WACmB;AACnB,MAAI,2BAA2B;AAE/B,QAAM,SAAS,GAAG,SAAS;AAC3B,QAAM,SAAS,GAAG,SAAS;AAC3B,QAAM,SAAS,GAAG,SAAS;AAE3B,QAAM,YAAY,WAAW,QAAQ,EAAE;AACvC,QAAM,YAAY,WAAW,QAAQ,EAAE;AACvC,QAAM,YAAY,WAAW,QAAQ,EAAE;AAEvC,QAAM,SAAS,MAAM;AAAA,IACpB,CAAC,QAAQ,QAAQ,MAAM;AAAA,IACvB,GAAG,SAAS;AAAA,EACb;AAEA,UAAQ,QAAQ,QAAQ,MAAM;AAE9B,MAAI,QAAQ;AACX,YAAQ,MAAM,0BAA0B;AACxC,WAAO;AAAA,EACR;AACA,UAAQ,OAAO,oBAAoB;AACnC,SAAO;AACR;AAKA,eAAsBC,KAAI,UAAoC;AAE7D,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,UAAM,2CAA2C;AACjD,YAAQ,IAAI,mDAAmD;AAC/D,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAGA,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACF,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAGA,QAAM,WAAW,YAAY,KAAK;AAElC,SAAO,4BAA4B;AAGnC,MAAI,2BAA2B;AAC/B,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,YAAQ,OAAO,sBAAsB;AACrC,WAAO;AAAA,EACR;AACA,QAAM,CAAC,OAAO,KAAK,IAAI;AACvB,UAAQ,MAAM,WAAW,KAAK,IAAI,KAAK,EAAE;AAGzC,MAAI,QAAQ,QAAQ,QAAQ,MAAM;AACjC;AAAA,MACC;AAAA,IACD;AAAA,EACD;AAGA,MAAI,UAAU,OAAO;AACpB,SAAK,oDAAoD;AAAA,EAC1D;AAGA,UAAQ,IAAI,EAAE;AACd,QAAM,YAAY,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,MACC,EAAE,OAAO,wCAAwC,OAAO,MAAM;AAAA,MAC9D,EAAE,OAAO,sCAAsC,OAAO,UAAU;AAAA,MAChE,EAAE,OAAO,8BAA8B,OAAO,MAAM;AAAA,IACrD;AAAA,IACA,CAAC,OAAO,WAAW,KAAK;AAAA;AAAA,EACzB;AAEA,MAAI,UAAU,WAAW,GAAG;AAC3B,UAAM,uBAAuB;AAC7B,WAAO;AAAA,EACR;AAEA,QAAM,QAAQ,UAAU,SAAS,KAAK;AACtC,QAAM,YAAY,UAAU,SAAS,SAAS;AAC9C,QAAM,QAAQ,UAAU,SAAS,KAAK;AAGtC,QAAM,YAAY,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAC1D,EAAAC,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AACxC,OAAK,qBAAqB,SAAS,EAAE;AAGrC,UAAQ,IAAI,EAAE;AACd,MAAI,2BAA2B;AAC/B,QAAM,aAAa,GAAG,SAAS;AAC/B,QAAM,aAAa,GAAG,SAAS;AAG/B,MAAI,CAAE,MAAM,SAAS,OAAO,UAAU,GAAI;AACzC,YAAQ,OAAO,0BAA0B;AACzC,WAAO;AAAA,EACR;AAGA,MAAI,CAAE,MAAM,YAAY,YAAY,YAAY,IAAI,GAAI;AACvD,YAAQ,OAAO,0BAA0B;AACzC,YAAQ,UAAU;AAClB,WAAO;AAAA,EACR;AACA,UAAQ,UAAU;AAClB,UAAQ,MAAM,2BAA2B;AAEzC,MAAI,cAAc;AAGlB,MAAI,OAAO;AACV,YAAQ,IAAI,EAAE;AACd,WAAO,WAAW;AAClB,UAAM,SAAS,GAAG,SAAS;AAC3B,IAAAA,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAErC,QAAI,CAAE,MAAM,gBAAgB,QAAQ,UAAU,GAAI;AACjD;AAAA,IACD;AAEA,mBAAe,MAAM,cAAc,QAAQ,YAAY,SAAS;AAAA,EACjE;AAGA,MAAI,WAAW;AACd,YAAQ,IAAI,EAAE;AACd,WAAO,eAAe;AACtB,UAAM,aAAa,GAAG,SAAS;AAC/B,IAAAA,WAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAEzC,mBAAe,MAAM,cAAc,YAAY,YAAY,aAAa;AAAA,EACzE;AAGA,MAAI,OAAO;AACV,YAAQ,IAAI,EAAE;AACd,WAAO,WAAW;AAClB,UAAM,SAAS,GAAG,SAAS;AAC3B,IAAAA,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAErC,mBAAe,MAAM,cAAc,QAAQ,YAAY,SAAS;AAAA,EACjE;AAGA,UAAQ,UAAU;AAGlB,UAAQ,IAAI,EAAE;AACd,YAAU;AAEV,MAAI,gBAAgB,GAAG;AACtB,YAAQ,mCAAmC;AAAA,EAC5C,OAAO;AACN,SAAK,GAAG,WAAW,6BAA6B;AAAA,EACjD;AAEA,UAAQ,IAAI,EAAE;AACd,OAAK,mBAAmB,SAAS,EAAE;AAEnC,MAAI,OAAO;AACV,SAAK,6CAA6C;AAAA,EACnD;AACA,MAAI,WAAW;AACd,SAAK,4CAA4C;AAAA,EAClD;AACA,MAAI,OAAO;AACV,SAAK,+BAA+B;AAAA,EACrC;AAEA,SAAO,gBAAgB;AACxB;AAKA,eAAsBE,QAAO,UAAoC;AAChE,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACH,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAEA,QAAM,WAAW,YAAY,KAAK;AAElC,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUI,UAAS,KAAK;AAAA,MACxB,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd,aAAa;AAAA,IACd;AAAA,IACA,UAAU;AAAA,MACT,KAAK;AAAA,MACL,SAAS;AAAA,MACT,KAAK;AAAA,IACN;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,OAAiD,CAAC;AAExD,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,wBAAwB,CAAC;AAAA,QAC3D;AAAA,MACD;AAEA,YAAM,QAAS,KAAK,OAAmB;AACvC,YAAM,YAAa,KAAK,WAAuB;AAC/C,YAAM,QAAS,KAAK,OAAmB;AAEvC,UAAI,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO;AACnC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,wBAAwB,CAAC;AAAA,QAC3D;AAAA,MACD;AAGA,YAAM,YAAY,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAC1D,MAAAH,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AACxC,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,WAAW,SAAS,GAAG,CAAC;AAG3D,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,4BAA4B,CAAC;AAChE,YAAM,aAAa,GAAG,SAAS;AAC/B,YAAM,aAAa,GAAG,SAAS;AAE/B,UAAI,CAAE,MAAM,SAAS,OAAO,UAAU,GAAI;AACzC,eAAO,EAAE,SAAS,OAAO,OAAO,4BAA4B,KAAK;AAAA,MAClE;AAEA,UAAI,CAAE,MAAM,YAAY,YAAY,YAAY,IAAI,GAAI;AACvD,gBAAQ,UAAU;AAClB,eAAO,EAAE,SAAS,OAAO,OAAO,4BAA4B,KAAK;AAAA,MAClE;AACA,cAAQ,UAAU;AAClB,WAAK,KAAK,EAAE,MAAM,WAAW,SAAS,4BAA4B,CAAC;AAEnE,UAAI,cAAc;AAGlB,UAAI,OAAO;AACV,aAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,0BAA0B,CAAC;AAC9D,cAAM,SAAS,GAAG,SAAS;AAC3B,QAAAA,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAErC,YAAI,CAAE,MAAM,sBAAsB,QAAQ,UAAU,GAAI;AACvD;AAAA,QACD;AACA,uBAAe,MAAM,oBAAoB,QAAQ,YAAY,WAAW,IAAI;AAC5E,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,QAAQ,UAAU,SAAS,CAAC,SAAS,CAAC;AAAA,MAC7E;AAGA,UAAI,WAAW;AACd,aAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,8BAA8B,CAAC;AAClE,cAAM,aAAa,GAAG,SAAS;AAC/B,QAAAA,WAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AACzC,uBAAe,MAAM,oBAAoB,YAAY,YAAY,eAAe,IAAI;AACpF,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,YAAY,cAAc,MAAM,SAAS,CAAC;AAAA,MACjF;AAGA,UAAI,OAAO;AACV,aAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,0BAA0B,CAAC;AAC9D,cAAM,SAAS,GAAG,SAAS;AAC3B,QAAAA,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AACrC,uBAAe,MAAM,oBAAoB,QAAQ,YAAY,WAAW,IAAI;AAC5E,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,QAAQ,UAAU,MAAM,SAAS,CAAC;AAAA,MACzE;AAEA,cAAQ,UAAU;AAElB,UAAI,gBAAgB,GAAG;AACtB,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,kBAAkB,SAAS,QAAQ;AAAA,UAC3C;AAAA,QACD;AAAA,MACD;AAEA,aAAO;AAAA,QACN,SAAS;AAAA,QACT,OAAO,GAAG,WAAW;AAAA,QACrB;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAKA,eAAe,oBACd,WACA,WACA,OACA,OACkB;AAClB,MAAI,SAAS;AAEb,aAAW,QAAQ,OAAO;AACzB,UAAM,aAAa,GAAG,SAAS,IAAI,KAAK,QAAQ;AAChD,UAAM,SAASF,SAAQ,UAAU;AACjC,QAAI,CAACC,YAAW,MAAM,GAAG;AACxB,MAAAC,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,IACtC;AAEA,QAAI,CAAE,MAAM,YAAY,WAAW,YAAY,KAAK,IAAI,GAAI;AAC3D;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;AAKA,eAAe,sBACd,WACA,WACmB;AACnB,QAAM,SAAS,GAAG,SAAS;AAC3B,QAAM,SAAS,GAAG,SAAS;AAC3B,QAAM,SAAS,GAAG,SAAS;AAE3B,QAAM,YAAY,WAAW,QAAQ,EAAE;AACvC,QAAM,YAAY,WAAW,QAAQ,EAAE;AACvC,QAAM,YAAY,WAAW,QAAQ,EAAE;AAEvC,QAAM,SAAS,MAAM;AAAA,IACpB,CAAC,QAAQ,QAAQ,MAAM;AAAA,IACvB,GAAG,SAAS;AAAA,EACb;AAEA,UAAQ,QAAQ,QAAQ,MAAM;AAC9B,SAAO;AACR;AAEO,IAAMI,UAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,QAAQ,SAAS,MAAM;AAC7C;;;AC/eA,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AACzC,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,WAAU,QAAAC,aAAY;AAwB/B,eAAsBC,KAAI,UAAoC;AAE7D,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,UAAM,2CAA2C;AACjD,YAAQ,IAAI,mDAAmD;AAC/D,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAGA,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACC,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAGA,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AACvD,QAAM,cAAc,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAC5D,QAAM,aAAa,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAC3D,QAAM,aAAa,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAE3D,SAAO,kBAAkB;AAGzB,MAAI,oBAAoB;AACxB,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,YAAQ,OAAO,sBAAsB;AACrC,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,kBAAkB,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE;AAGpD,MAAI,+BAA+B;AACnC,MAAI,CAAE,MAAM,KAAK,OAAO,WAAW,GAAI;AACtC,YAAQ,OAAO,aAAa;AAC5B,YAAQ,WAAW;AACnB,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,SAAS;AAGvB,MAAI,kBAAkB;AACtB,MAAI,CAAE,MAAM,SAAS,aAAa,UAAU,GAAI;AAC/C,YAAQ,OAAO,uBAAuB;AACtC,YAAQ,aAAa,UAAU;AAC/B,WAAO;AAAA,EACR;AACA,UAAQ,WAAW;AACnB,UAAQ,MAAM,aAAa;AAG3B,MAAI,qBAAqB;AACzB,MAAI,CAAE,MAAM,YAAY,YAAY,YAAY,GAAG,GAAI;AACtD,YAAQ,OAAO,gBAAgB;AAC/B,YAAQ,YAAY,UAAU;AAC9B,WAAO;AAAA,EACR;AACA,UAAQ,UAAU;AAClB,UAAQ,MAAM,mBAAmB;AAGjC,MAAI,6CAA6C;AACjD,MAAI,CAAE,MAAM,UAAU,YAAY,MAAM,GAAI;AAC3C,YAAQ,OAAO,sBAAsB;AACrC,YAAQ,UAAU;AAClB,WAAO;AAAA,EACR;AACA,UAAQ,UAAU;AAClB,UAAQ,MAAM,cAAc;AAE5B,UAAQ,IAAI,EAAE;AACd,UAAQ,WAAW,MAAM,EAAE;AAC3B,SAAO;AACR;AAKA,eAAe,eACd,OACA,QACA,SACA,MACmB;AACnB,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,cAAc,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAC5D,QAAM,aAAa,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAC3D,QAAM,aAAa,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAE3D,MAAI,eAAe;AAGnB,MAAI,QAAQ,MAAM;AACjB,UAAM,KAAK,EAAE,MAAM,QAAQ,SAAS,gCAAgC,CAAC;AACrE,QAAI,CAAE,MAAM,KAAK,cAAc,WAAW,GAAI;AAC7C,cAAQ,WAAW;AACnB,aAAO;AAAA,IACR;AACA,mBAAe;AACf,UAAM,KAAK,EAAE,MAAM,WAAW,SAAS,UAAU,CAAC;AAAA,EACnD;AAGA,MAAI,QAAQ,YAAY;AACvB,UAAM,KAAK,EAAE,MAAM,QAAQ,SAAS,mBAAmB,CAAC;AACxD,QAAI,CAAE,MAAM,SAAS,cAAc,UAAU,GAAI;AAChD,cAAQ,aAAa,UAAU;AAC/B,aAAO;AAAA,IACR;AACA,QAAI,iBAAiB,YAAa,SAAQ,WAAW;AACrD,mBAAe;AACf,UAAM,KAAK,EAAE,MAAM,WAAW,SAAS,cAAc,CAAC;AAAA,EACvD;AAGA,QAAM,KAAK,EAAE,MAAM,QAAQ,SAAS,sBAAsB,CAAC;AAC3D,MAAI,CAAE,MAAM,YAAY,cAAc,YAAY,GAAG,GAAI;AACxD,YAAQ,aAAa,YAAY,UAAU;AAC3C,WAAO;AAAA,EACR;AACA,MAAI,iBAAiB,WAAY,SAAQ,UAAU;AAAA,WAC1C,iBAAiB,YAAa,SAAQ,WAAW;AAC1D,QAAM,KAAK,EAAE,MAAM,WAAW,SAAS,oBAAoB,CAAC;AAG5D,QAAM,KAAK,EAAE,MAAM,QAAQ,SAAS,8CAA8C,CAAC;AACnF,MAAI,CAAE,MAAM,UAAU,YAAY,MAAM,GAAI;AAC3C,YAAQ,UAAU;AAClB,WAAO;AAAA,EACR;AACA,UAAQ,UAAU;AAClB,QAAM,KAAK,EAAE,MAAM,WAAW,SAAS,eAAe,CAAC;AAEvD,SAAO;AACR;AAKA,eAAeC,iBACd,OACA,SACqG;AACrG,QAAM,UAAUC,QAAO;AACvB,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,cAAcC,MAAK,SAAS,0BAA0B,SAAS,MAAM;AAC3E,QAAM,aAAaA,MAAK,SAAS,yBAAyB,SAAS,MAAM;AACzE,QAAM,aAAaA,MAAK,SAAS,kBAAkB,SAAS,MAAM;AAElE,MAAI;AACH,QAAI,eAAe;AAGnB,QAAI,QAAQ,MAAM;AACjB,UAAI,CAAE,MAAM,KAAK,cAAc,WAAW,GAAI;AAC7C,gBAAQ,WAAW;AACnB,eAAO,EAAE,SAAS,OAAO,OAAO,cAAc;AAAA,MAC/C;AACA,qBAAe;AAAA,IAChB;AAGA,QAAI,QAAQ,YAAY;AACvB,UAAI,CAAE,MAAM,SAAS,cAAc,UAAU,GAAI;AAChD,gBAAQ,aAAa,UAAU;AAC/B,eAAO,EAAE,SAAS,OAAO,OAAO,gBAAgB;AAAA,MACjD;AACA,UAAI,iBAAiB,YAAa,SAAQ,WAAW;AACrD,qBAAe;AAAA,IAChB;AAGA,QAAI,CAAE,MAAM,YAAY,cAAc,YAAY,GAAG,GAAI;AACxD,cAAQ,aAAa,YAAY,UAAU;AAC3C,aAAO,EAAE,SAAS,OAAO,OAAO,eAAe;AAAA,IAChD;AACA,QAAI,iBAAiB,WAAY,SAAQ,UAAU;AAAA,aAC1C,iBAAiB,YAAa,SAAQ,WAAW;AAE1D,UAAM,SAASC,cAAa,UAAU;AACtC,UAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,UAAM,YAAY,yBAAyB,MAAM;AAEjD,UAAM,OAAO,MAAM,cAAc,UAAU;AAC3C,YAAQ,UAAU;AAElB,WAAO;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,OAAO,OAAO,CAAC;AAAA,MACf,QAAQ,OAAO,CAAC;AAAA,IACjB;AAAA,EACD,SAAS,KAAK;AACb,YAAQ,aAAa,YAAY,UAAU;AAC3C,WAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,EACxD;AACD;AAKA,eAAsBC,QAAO,UAAoC;AAChE,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACL,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAEA,QAAM,WAAW,YAAY,KAAK;AAElC,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUM,UAAS,KAAK;AAAA,MACxB,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd,aAAa;AAAA,IACd;AAAA,IACA,UAAU;AAAA,MACT,MAAM;AAAA,MACN,YAAY;AAAA,IACb;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,UAA0B;AAAA,QAC/B,MAAO,KAAK,QAAoB;AAAA,QAChC,YAAa,KAAK,cAA0B;AAAA,MAC7C;AACA,aAAOL,iBAAgB,OAAO,OAAO;AAAA,IACtC;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,OAAiD,CAAC;AAExD,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,wBAAwB,CAAC;AAAA,QAC3D;AAAA,MACD;AAEA,YAAM,UAA0B;AAAA,QAC/B,MAAO,KAAK,QAAoB;AAAA,QAChC,YAAa,KAAK,cAA0B;AAAA,MAC7C;AAEA,YAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAEvD,YAAMM,WAAU,MAAM,eAAe,OAAO,QAAQ,SAAS,IAAI;AAEjE,UAAIA,UAAS;AACZ,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,GAAG,SAAS,QAAQ;AAAA,UAC5B;AAAA,QACD;AAAA,MACD;AAEA,aAAO,EAAE,SAAS,OAAO,OAAO,wBAAwB,KAAK;AAAA,IAC9D;AAAA,EACD,CAAC;AACF;AAEO,IAAMC,UAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,MAAM;AAC5B;;;AChTA,SAAS,cAAAC,aAAY,aAAAC,YAAW,gBAAAC,eAAc,YAAY,iBAAAC,sBAAqB;AAC/E,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,WAAU,WAAAC,UAAS,WAAAC,UAAS,QAAAC,aAAY;AAwEjD,IAAM,aAAa,CAAC,YAAY,SAAS,SAAS,WAAW;AAM7D,eAAe,wBACd,OACA,aACA,MACyB;AACzB,QAAM,UAAUC,QAAO;AACvB,QAAM,KAAK,KAAK,IAAI;AACpB,QAAM,QAAkB,CAAC;AAEzB,QAAM,eAAe,CAAC,WAAmB;AACxC,UAAM,IAAIC,MAAK,SAAS,UAAU,EAAE,IAAI,MAAM,MAAM;AACpD,UAAM,KAAK,CAAC;AACZ,WAAO;AAAA,EACR;AAEA,MAAI;AACH,QAAI,UAAU;AAGd,QAAI,aAAa,KAAK,GAAG;AACxB,YAAM,YAAY,aAAa,OAAO;AACtC,UAAI,MAAM,kBAAkB,OAAO,SAAS,GAAG;AAC9C,kBAAU;AAAA,MACX;AAAA,IACD;AAGA,QAAI,KAAK,YAAY,KAAK,MAAM,WAAW,GAAG;AAC7C,YAAMC,QAAO,MAAM,cAAc,OAAO;AACxC,UAAIC,eAAc;AAElB,UAAID,UAASA,MAAK,CAAC,IAAI,OAAOA,MAAK,CAAC,IAAI,MAAM;AAC7C,cAAM,SAAS,aAAa,cAAc;AAC1C,cAAM,aAAa,KAAK,IAAI,KAAK,KAAK,IAAIA,MAAK,CAAC,GAAGA,MAAK,CAAC,CAAC,CAAC;AAC3D,YAAI,MAAM,YAAY,SAAS,QAAQ,UAAU,GAAG;AACnD,UAAAC,eAAc;AAAA,QACf;AAAA,MACD;AAEA,YAAMC,UAASC,cAAaF,YAAW;AACvC,YAAMG,aAAY,MAAM,cAAcH,YAAW;AACjD,cAAQ,GAAG,KAAK;AAEhB,aAAO;AAAA,QACN,SAAS;AAAA,QACT,WAAW,yBAAyBC,QAAO,SAAS,QAAQ,CAAC;AAAA,QAC7D,OAAOE,aAAY,CAAC,KAAKJ,QAAO,CAAC;AAAA,QACjC,QAAQI,aAAY,CAAC,KAAKJ,QAAO,CAAC;AAAA,MACnC;AAAA,IACD;AAGA,UAAM,cAAc,WAAW,OAAO,OAAK,KAAK,MAAM,SAAS,CAAC,CAAC;AAGjE,eAAW,QAAQ,aAAa;AAC/B,cAAQ,MAAM;AAAA,QACb,KAAK,YAAY;AAChB,gBAAM,SAAS,KAAK;AACpB,gBAAM,MAAM,aAAa,UAAU;AACnC,cAAIK,WAAU;AAEd,cAAI,OAAO,cAAc,aAAa;AAErC,YAAAA,WAAU,MAAM,0BAA0B,SAAS,KAAK,aAAa,OAAO,MAAM,OAAO,YAAY;AAAA,UACtG,WAAW,OAAO,iBAAiB,aAAa;AAC/C,YAAAA,WAAU,MAAM,2BAA2B,SAAS,KAAK,aAAa,OAAO,IAAI;AAAA,UAClF;AACA,cAAI,CAACA,YAAW,aAAa;AAC5B,YAAAA,WAAU,MAAM,iBAAiB,SAAS,KAAK,aAAa,OAAO,IAAI;AAAA,UACxE;AACA,cAAI,CAACA,UAAS;AACb,oBAAQ,GAAG,KAAK;AAChB,mBAAO,EAAE,SAAS,OAAO,OAAO,4BAA4B;AAAA,UAC7D;AAGA,cAAI,OAAO,MAAM;AAChB,kBAAM,UAAU,aAAa,MAAM;AACnC,gBAAI,MAAM,KAAK,KAAK,OAAO,GAAG;AAC7B,wBAAU;AAAA,YACX,OAAO;AACN,wBAAU;AAAA,YACX;AAAA,UACD,OAAO;AACN,sBAAU;AAAA,UACX;AACA;AAAA,QACD;AAAA,QAEA,KAAK,SAAS;AACb,gBAAM,SAAS,KAAK;AACpB,gBAAM,MAAM,aAAa,OAAO;AAChC,cAAIA,WAAU;AAEd,cAAI,OAAO,YAAY;AACtB,kBAAM,MAAM,KAAK,IAAI,OAAO,OAAO,OAAO,MAAM;AAChD,YAAAA,WAAU,MAAM,iBAAiB,SAAS,KAAK,KAAK,GAAG;AAAA,UACxD,OAAO;AACN,YAAAA,WAAU,MAAM,OAAO,SAAS,KAAK,OAAO,OAAO,OAAO,MAAM;AAAA,UACjE;AAEA,cAAI,CAACA,UAAS;AACb,oBAAQ,GAAG,KAAK;AAChB,mBAAO,EAAE,SAAS,OAAO,OAAO,eAAe;AAAA,UAChD;AACA,oBAAU;AACV;AAAA,QACD;AAAA,QAEA,KAAK,SAAS;AAEb,gBAAM,SAAS,KAAK;AAEpB,cAAI,OAAO,QAAQ,YAAY,OAAO;AACrC,kBAAM,UAAU,aAAa,SAAS;AACtC,gBAAI,MAAM,KAAK,SAAS,OAAO,GAAG;AACjC,wBAAU;AAAA,YACX;AAAA,UACD;AAEA,cAAI,OAAO,YAAY;AACtB,kBAAM,QAAQ,aAAa,OAAO;AAClC,gBAAI,MAAM,SAAS,SAAS,KAAK,GAAG;AACnC,wBAAU;AAAA,YACX;AAAA,UACD;AACA;AAAA,QACD;AAAA,MAGD;AAAA,IACD;AAGA,UAAM,OAAO,MAAM,cAAc,OAAO;AACxC,QAAI,cAAc;AAElB,QAAI,SAAS,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,MAAM;AAC7C,YAAM,SAAS,aAAa,SAAS;AACrC,YAAM,aAAa,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;AAC3D,UAAI,MAAM,YAAY,SAAS,QAAQ,UAAU,GAAG;AACnD,sBAAc;AAAA,MACf;AAAA,IACD;AAEA,UAAM,SAASF,cAAa,WAAW;AACvC,UAAM,YAAY,MAAM,cAAc,WAAW;AACjD,YAAQ,GAAG,KAAK;AAEhB,WAAO;AAAA,MACN,SAAS;AAAA,MACT,WAAW,yBAAyB,OAAO,SAAS,QAAQ,CAAC;AAAA,MAC7D,OAAO,YAAY,CAAC;AAAA,MACpB,QAAQ,YAAY,CAAC;AAAA,IACtB;AAAA,EACD,SAAS,KAAK;AACb,YAAQ,GAAG,KAAK;AAChB,WAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,EACxD;AACD;AAWA,eAAe,gBACd,OACA,aACA,MACA,MAC2B;AAC3B,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,UAAoB,CAAC;AAC3B,QAAM,QAAkB,CAAC;AACzB,MAAI;AAEJ,QAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AAEzE,QAAM,eAAe,CAAC,WAAmB;AACxC,UAAM,IAAI,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,IAAI,MAAM,GAAG,SAAS;AACxE,UAAM,KAAK,CAAC;AACZ,WAAO;AAAA,EACR;AAEA,MAAI,UAAU;AACd,QAAM,cAAc,WAAW,OAAO,OAAK,KAAK,MAAM,SAAS,CAAC,CAAC;AAEjE,aAAW,QAAQ,aAAa;AAC/B,YAAQ,MAAM;AAAA,MACb,KAAK,YAAY;AAChB,aAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,yBAAyB,CAAC;AAC7D,cAAM,SAAS,KAAK;AACpB,cAAM,MAAM,aAAa,MAAM;AAC/B,YAAIE,WAAU;AAEd,YAAI,OAAO,cAAc,aAAa;AACrC,eAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,2BAA2B,CAAC;AAC/D,UAAAA,WAAU,MAAM,0BAA0B,SAAS,KAAK,aAAa,OAAO,MAAM,OAAO,YAAY;AACrG,cAAI,CAACA,UAAS;AACb,iBAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,kDAAkD,CAAC;AAAA,UACvF;AAAA,QACD,WAAW,OAAO,iBAAiB,aAAa;AAC/C,UAAAA,WAAU,MAAM,2BAA2B,SAAS,KAAK,aAAa,OAAO,IAAI;AACjF,cAAI,CAACA,UAAS;AACb,iBAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,0CAA0C,CAAC;AAAA,UAC/E;AAAA,QACD;AACA,YAAI,CAACA,YAAW,aAAa;AAC5B,UAAAA,WAAU,MAAM,iBAAiB,SAAS,KAAK,aAAa,OAAO,IAAI;AAAA,QACxE;AACA,YAAI,CAACA,UAAS;AACb,eAAK,KAAK,EAAE,MAAM,SAAS,SAAS,4BAA4B,CAAC;AACjE,kBAAQ,GAAG,KAAK;AAChB,iBAAO,EAAE,SAAS,CAAC,EAAE;AAAA,QACtB;AACA,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,qBAAqB,CAAC;AAE5D,YAAI,OAAO,MAAM;AAChB,eAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,oBAAoB,CAAC;AACxD,gBAAM,UAAU,aAAa,SAAS;AACtC,cAAI,MAAM,KAAK,KAAK,OAAO,GAAG;AAC7B,oBAAQ,GAAG;AACX,kBAAM,OAAO,MAAM,QAAQ,GAAG,GAAG,CAAC;AAClC,sBAAU;AACV,iBAAK,KAAK,EAAE,MAAM,WAAW,SAAS,UAAU,CAAC;AAAA,UAClD,OAAO;AACN,sBAAU;AAAA,UACX;AAAA,QACD,OAAO;AACN,oBAAU;AAAA,QACX;AAGA,YAAI,YAAY,QAAQ,IAAI,MAAM,YAAY,SAAS,GAAG;AACzD,gBAAM,WAAW,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,QAAQ,SAAS;AAC1E,qBAAW,SAAS,QAAQ;AAC5B,gBAAM,OAAO,MAAM,QAAQ,OAAO,GAAG,CAAC;AACtC,kBAAQ,KAAKC,UAAS,QAAQ,CAAC;AAC/B,2BAAiB;AAAA,QAClB;AACA;AAAA,MACD;AAAA,MAEA,KAAK,SAAS;AACb,aAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,mBAAmB,CAAC;AACvD,cAAM,SAAS,KAAK;AACpB,cAAM,MAAM,aAAa,QAAQ;AACjC,YAAID,WAAU;AAEd,YAAI,OAAO,YAAY;AACtB,gBAAM,MAAM,KAAK,IAAI,OAAO,OAAO,OAAO,MAAM;AAChD,UAAAA,WAAU,MAAM,iBAAiB,SAAS,KAAK,KAAK,GAAG;AAAA,QACxD,OAAO;AACN,UAAAA,WAAU,MAAM,OAAO,SAAS,KAAK,OAAO,OAAO,OAAO,MAAM;AAAA,QACjE;AAEA,YAAI,CAACA,UAAS;AACb,eAAK,KAAK,EAAE,MAAM,SAAS,SAAS,eAAe,CAAC;AACpD,kBAAQ,GAAG,KAAK;AAChB,iBAAO,EAAE,SAAS,CAAC,EAAE;AAAA,QACtB;AAEA,cAAM,OAAO,MAAM,cAAc,GAAG;AACpC,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,aAAa,OAAO,CAAC,CAAC,OAAI,OAAO,CAAC,CAAC,GAAG,CAAC;AAG7E,YAAI,YAAY,SAAS,MAAM,SAAS,OAAO,GAAG;AACjD,kBAAQ,OAAO;AACf,gBAAM,OAAO,MAAM,QAAQ,OAAO,GAAG,CAAC;AAAA,QACvC;AACA,kBAAU;AAGV,YAAI,YAAY,QAAQ,IAAI,MAAM,YAAY,SAAS,GAAG;AACzD,gBAAM,WAAW,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,UAAU,SAAS;AAC5E,qBAAW,SAAS,QAAQ;AAC5B,gBAAM,OAAO,MAAM,QAAQ,OAAO,GAAG,CAAC;AACtC,kBAAQ,KAAKC,UAAS,QAAQ,CAAC;AAC/B,2BAAiB;AAAA,QAClB;AACA;AAAA,MACD;AAAA,MAEA,KAAK,SAAS;AACb,aAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,sBAAsB,CAAC;AAC1D,cAAM,SAAS,KAAK;AAGpB,YAAI,CAAC,OAAO,OAAO,CAAC,OAAO,OAAO,CAAC,OAAO,WAAW,CAAC,OAAO,KAAK;AACjE,eAAK,KAAK,EAAE,MAAM,SAAS,SAAS,4BAA4B,CAAC;AACjE,iBAAO,EAAE,SAAS,CAAC,EAAE;AAAA,QACtB;AAGA,YAAI,aAAa;AAEjB,YAAI,OAAO,QAAQ,YAAY,OAAO;AACrC,eAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,oBAAoB,CAAC;AACxD,gBAAM,UAAU,aAAa,SAAS;AACtC,cAAI,MAAM,KAAK,SAAS,OAAO,GAAG;AACjC,yBAAa;AACb,iBAAK,KAAK,EAAE,MAAM,WAAW,SAAS,UAAU,CAAC;AAAA,UAClD;AAAA,QACD;AAEA,YAAI,OAAO,YAAY;AACtB,eAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,mBAAmB,CAAC;AACvD,gBAAM,QAAQ,aAAa,OAAO;AAClC,cAAI,MAAM,SAAS,YAAY,KAAK,GAAG;AACtC,gBAAI,eAAe,WAAW,eAAe,MAAO,SAAQ,UAAU;AACtE,yBAAa;AACb,iBAAK,KAAK,EAAE,MAAM,WAAW,SAAS,cAAc,CAAC;AAAA,UACtD;AAAA,QACD;AAGA,cAAM,UAAU,OAAO,OAAO,OAAO,WAAW,OAAO,MAAM,OAAO;AACpE,cAAM,UAAU,aAAa,QAAQ;AACrC,YAAI,CAAE,MAAM,YAAY,YAAY,SAAS,OAAO,GAAI;AACvD,eAAK,KAAK,EAAE,MAAM,SAAS,SAAS,gCAAgC,CAAC;AACrE,kBAAQ,GAAG,KAAK;AAChB,iBAAO,EAAE,SAAS,CAAC,EAAE;AAAA,QACtB;AACA,YAAI,eAAe,WAAW,eAAe,MAAO,SAAQ,UAAU;AAEtE,YAAI,aAAa;AAGjB,YAAI,OAAO,KAAK;AACf,eAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,uBAAuB,CAAC;AAC3D,gBAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AACvD,cAAI,MAAM,UAAU,SAAS,MAAM,GAAG;AACrC,iBAAK,KAAK,EAAE,MAAM,WAAW,SAAS,0CAA0C,CAAC;AACjF,oBAAQ,KAAKA,UAAS,MAAM,CAAC;AAC7B,0BAAc;AAAA,UACf,OAAO;AACN,iBAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,sBAAsB,CAAC;AAAA,UAC3D;AAAA,QACD;AAGA,cAAM,aAAa,OAAO,OAAO,OAAO,WAAW,OAAO;AAC1D,YAAI,YAAY;AACf,gBAAM,YAAY,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAC1D,UAAAC,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAExC,cAAI,OAAO,KAAK;AACf,iBAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,0BAA0B,CAAC;AAC9D,kBAAM,SAAS,GAAG,SAAS;AAC3B,YAAAA,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAGrC,kBAAM,MAAM,GAAG,MAAM,aAAa,MAAM,GAAG,MAAM,aAAa,MAAM,GAAG,MAAM;AAC7E,kBAAM,YAAY,SAAS,KAAK,EAAE;AAClC,kBAAM,YAAY,SAAS,KAAK,EAAE;AAClC,kBAAM,YAAY,SAAS,KAAK,EAAE;AAClC,kBAAM,sBAAsB,CAAC,KAAK,KAAK,GAAG,GAAG,GAAG,MAAM,cAAc;AACpE,oBAAQ,KAAK,KAAK,GAAG;AACrB;AAEA,kBAAM,WAAW;AAAA,cAChB,EAAE,MAAM,qBAAqB,MAAM,GAAG;AAAA,cAAG,EAAE,MAAM,qBAAqB,MAAM,GAAG;AAAA,cAC/E,EAAE,MAAM,wBAAwB,MAAM,IAAI;AAAA,cAAG,EAAE,MAAM,8BAA8B,MAAM,IAAI;AAAA,cAC7F,EAAE,MAAM,8BAA8B,MAAM,IAAI;AAAA,cAAG,EAAE,MAAM,sBAAsB,MAAM,IAAI;AAAA,YAC5F;AACA,uBAAW,KAAK,UAAU;AACzB,oBAAM,YAAY,SAAS,GAAG,MAAM,IAAI,EAAE,IAAI,IAAI,EAAE,IAAI;AACxD;AAAA,YACD;AACA,iBAAK,KAAK,EAAE,MAAM,WAAW,SAAS,eAAe,CAAC;AAAA,UACvD;AAEA,cAAI,OAAO,SAAS;AACnB,iBAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,8BAA8B,CAAC;AAClE,kBAAM,aAAa,GAAG,SAAS;AAC/B,kBAAM,eAAe;AAAA,cACpB,EAAE,MAAM,+BAA+B,MAAM,GAAG;AAAA,cAChD,EAAE,MAAM,+BAA+B,MAAM,GAAG;AAAA,cAChD,EAAE,MAAM,gCAAgC,MAAM,GAAG;AAAA,cACjD,EAAE,MAAM,iCAAiC,MAAM,IAAI;AAAA,cACnD,EAAE,MAAM,kCAAkC,MAAM,IAAI;AAAA,cACpD,EAAE,MAAM,sBAAsB,MAAM,IAAI;AAAA,YACzC;AACA,uBAAW,KAAK,cAAc;AAC7B,oBAAM,IAAI,GAAG,UAAU,IAAI,EAAE,IAAI;AACjC,cAAAA,WAAUC,SAAQ,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;AACzC,oBAAM,YAAY,SAAS,GAAG,EAAE,IAAI;AACpC;AAAA,YACD;AACA,iBAAK,KAAK,EAAE,MAAM,WAAW,SAAS,mBAAmB,CAAC;AAAA,UAC3D;AAEA,cAAI,OAAO,KAAK;AACf,iBAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,0BAA0B,CAAC;AAC9D,kBAAM,SAAS,GAAG,SAAS;AAC3B,YAAAD,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AACrC,kBAAM,WAAW,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI;AAC1E,uBAAW,KAAK,UAAU;AACzB,oBAAM,YAAY,SAAS,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC;AAC1D;AAAA,YACD;AACA,iBAAK,KAAK,EAAE,MAAM,WAAW,SAAS,QAAQ,SAAS,MAAM,SAAS,CAAC;AAAA,UACxE;AAEA,kBAAQ,KAAK,GAAG,UAAU,iBAAY,SAAS,QAAQ,SAAS;AAAA,QACjE;AAEA,gBAAQ,OAAO;AACf,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,aAAa,UAAU,eAAe,CAAC;AAC7E;AAAA,MACD;AAAA,MAEA,KAAK,aAAa;AACjB,aAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,6BAA6B,CAAC;AACjE,cAAM,SAAS,KAAK;AAEpB,YAAI,CAAC,OAAO,cAAc,OAAO,WAAW,WAAW,GAAG;AACzD,eAAK,KAAK,EAAE,MAAM,SAAS,SAAS,0BAA0B,CAAC;AAC/D,iBAAO,EAAE,SAAS,CAAC,EAAE;AAAA,QACtB;AAEA,cAAM,aAAa,OAAO,cAAc;AACxC,cAAM,YAAY,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,IAAI,UAAU;AACxE,QAAAA,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAExC,YAAI,QAAQ;AACZ,mBAAW,OAAO,OAAO,YAAY;AACpC,gBAAM,WAAW,IAAI,YAAY,GAAG,IAAI,KAAK,IAAI,IAAI,MAAM;AAC3D,gBAAM,MAAMR,MAAK,WAAW,QAAQ;AACpC,cAAIM,WAAU;AAEd,kBAAQ,OAAO,WAAW;AAAA,YACzB,KAAK;AACJ,cAAAA,WAAU,MAAM,cAAc,SAAS,KAAK,IAAI,OAAO,IAAI,MAAM;AACjE;AAAA,YACD,KAAK;AACJ,cAAAA,WAAU,MAAM,OAAO,SAAS,KAAK,IAAI,OAAO,IAAI,MAAM;AAC1D;AAAA,YACD;AACC,cAAAA,WAAU,MAAM,iBAAiB,SAAS,KAAK,IAAI,OAAO,IAAI,MAAM;AAAA,UACtE;AACA,cAAIA,SAAS;AAAA,QACd;AAEA,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,aAAa,KAAK,IAAI,OAAO,WAAW,MAAM,UAAU,CAAC;AAC/F,gBAAQ,KAAK,GAAG,KAAK,kBAAa,SAAS,QAAQ,IAAI,UAAU,GAAG;AACpE;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAGA,UAAQ,GAAG,KAAK;AAChB,SAAO,EAAE,SAAS,eAAe;AAClC;AAMA,eAAsBI,QAAO,UAAoC;AAChE,MAAI,eAAe,cAAc,QAAQ;AAEzC,MAAI,CAACC,YAAW,YAAY,GAAG;AAC9B,UAAM,mBAAmB,YAAY,EAAE;AACvC,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,cAAc,YAAY;AAC7C,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAEA,MAAI,qBAAqB,MAAM,eAAe,YAAY;AAC1D,MAAI,oBAAoB,aAAa,YAAY,IAAI,MAAM,cAAc,YAAY,IAAI;AACzF,QAAM,UAAU,YAAY;AAG5B,iBAAe,uBAAuB,YAAuF;AAC5H,UAAM,UAAUZ,QAAO;AACvB,UAAM,aAAaC,MAAK,SAAS,gBAAgB,KAAK,IAAI,CAAC,IAAI,UAAU,MAAM;AAC/E,QAAI;AACH,UAAI,CAAE,MAAM,kBAAkB,cAAc,YAAY,UAAU,GAAI;AACrE,eAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,MAC3D;AAEA,YAAM,cAAcA,MAAK,SAAS,gBAAgB,KAAK,IAAI,CAAC,IAAI,UAAU,MAAM;AAChF,YAAM,YAAY,YAAY,aAAa,EAAE;AAC7C,YAAM,SAASI,cAAa,WAAW;AACvC,cAAQ,YAAY,WAAW;AAC/B,aAAO;AAAA,QACN,SAAS;AAAA,QACT,WAAW,yBAAyB,OAAO,SAAS,QAAQ,CAAC;AAAA,MAC9D;AAAA,IACD,SAAS,KAAK;AACb,cAAQ,UAAU;AAClB,aAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,IACxD;AAAA,EACD;AAGA,iBAAeQ,sBACd,YACA,MACoE;AACpE,UAAM,UAAUb,QAAO;AACvB,UAAM,KAAK,KAAK,IAAI;AACpB,UAAM,YAAYC,MAAK,SAAS,aAAa,EAAE,IAAI,UAAU,MAAM;AACnE,UAAM,QAAkB,CAAC,SAAS;AAElC,QAAI;AAEH,UAAI,CAAE,MAAM,kBAAkB,cAAc,WAAW,UAAU,GAAI;AACpE,eAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,MAC3D;AAEA,UAAI,UAAU;AAGd,YAAM,cAAc,CAAC,YAAY,SAAS,OAAO,EAAE,OAAO,OAAK,KAAK,MAAM,SAAS,CAAC,CAAC;AAErF,iBAAW,QAAQ,aAAa;AAC/B,cAAM,UAAUA,MAAK,SAAS,aAAa,EAAE,IAAI,UAAU,IAAI,IAAI,MAAM;AACzE,cAAM,KAAK,OAAO;AAElB,gBAAQ,MAAM;AAAA,UACb,KAAK,YAAY;AAChB,kBAAM,SAAS,KAAK;AACpB,gBAAIM,WAAU;AACd,gBAAI,OAAO,iBAAiB,oBAAoB;AAC/C,cAAAA,WAAU,MAAM,2BAA2B,SAAS,SAAS,oBAAoB,OAAO,IAAI;AAAA,YAC7F;AACA,gBAAI,CAACA,YAAW,oBAAoB;AACnC,cAAAA,WAAU,MAAM,iBAAiB,SAAS,SAAS,oBAAoB,OAAO,IAAI;AAAA,YACnF;AACA,gBAAIA,UAAS;AACZ,kBAAI,OAAO,MAAM;AAChB,sBAAM,UAAUN,MAAK,SAAS,aAAa,EAAE,IAAI,UAAU,WAAW;AACtE,sBAAM,KAAK,OAAO;AAClB,oBAAI,MAAM,KAAK,SAAS,OAAO,GAAG;AACjC,4BAAU;AAAA,gBACX,OAAO;AACN,4BAAU;AAAA,gBACX;AAAA,cACD,OAAO;AACN,0BAAU;AAAA,cACX;AAAA,YACD;AACA;AAAA,UACD;AAAA,UACA,KAAK,SAAS;AACb,kBAAM,SAAS,KAAK;AACpB,gBAAI,OAAO,YAAY;AACtB,oBAAM,MAAM,KAAK,IAAI,OAAO,OAAO,OAAO,MAAM;AAChD,kBAAI,MAAM,iBAAiB,SAAS,SAAS,KAAK,GAAG,GAAG;AACvD,0BAAU;AAAA,cACX;AAAA,YACD,OAAO;AACN,kBAAI,MAAM,OAAO,SAAS,SAAS,OAAO,OAAO,OAAO,MAAM,GAAG;AAChE,0BAAU;AAAA,cACX;AAAA,YACD;AACA;AAAA,UACD;AAAA,UACA,KAAK,SAAS;AACb,kBAAM,SAAS,KAAK;AACpB,gBAAI,OAAO,MAAM;AAChB,oBAAM,UAAUA,MAAK,SAAS,aAAa,EAAE,IAAI,UAAU,aAAa;AACxE,oBAAM,KAAK,OAAO;AAClB,kBAAI,MAAM,KAAK,SAAS,OAAO,GAAG;AACjC,0BAAU;AAAA,cACX;AAAA,YACD;AACA,gBAAI,OAAO,YAAY;AACtB,kBAAI,MAAM,SAAS,SAAS,OAAO,GAAG;AACrC,0BAAU;AAAA,cACX;AAAA,YACD;AACA;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAGA,YAAM,WAAWA,MAAK,SAAS,aAAa,EAAE,IAAI,UAAU,YAAY;AACxE,YAAM,KAAK,QAAQ;AACnB,YAAM,YAAY,SAAS,UAAU,EAAE;AAEvC,YAAM,SAASI,cAAa,QAAQ;AACpC,cAAQ,GAAG,KAAK;AAEhB,aAAO;AAAA,QACN,SAAS;AAAA,QACT,WAAW,yBAAyB,OAAO,SAAS,QAAQ,CAAC;AAAA,MAC9D;AAAA,IACD,SAAS,KAAK;AACb,cAAQ,GAAG,KAAK;AAChB,aAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,IACxD;AAAA,EACD;AAEA,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUG,UAAS,YAAY;AAAA,MAC/B,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd,aAAa;AAAA,MACb,YAAY;AAAA,IACb;AAAA,IACA,UAAU;AAAA;AAAA,MAET,SAAS,QAAQ,IAAI,QAAM;AAAA,QAC1B,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,aAAa,EAAE;AAAA,QACf,OAAO,EAAE;AAAA,MACV,EAAE;AAAA,IACH;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,WAAW;AAEjB,UAAI,CAAC,SAAS,OAAO;AACpB,iBAAS,QAAQ,CAAC;AAAA,MACnB;AAGA,UAAI,aAAa,YAAY,KAAK,OAAO,SAAS,eAAe,UAAU;AAC1E,cAAM,UAAUR,QAAO;AACvB,cAAM,KAAK,KAAK,IAAI;AACpB,cAAM,YAAYC,MAAK,SAAS,eAAe,EAAE,MAAM;AAEvD,YAAI,CAAE,MAAM,kBAAkB,cAAc,WAAW,SAAS,UAAU,GAAI;AAC7E,iBAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,QAC3D;AAGA,cAAM,SAAS,MAAM,wBAAwB,WAAW,oBAAoB,QAAQ;AACpF,gBAAQ,SAAS;AACjB,eAAO;AAAA,MACR;AAEA,aAAO,wBAAwB,cAAc,oBAAoB,QAAQ;AAAA,IAC1E;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,OAAiD,CAAC;AACxD,YAAM,WAAW;AAMjB,UAAI,SAAS,cAAc,aAAa,YAAY,GAAG;AACtD,eAAO,iBAAiB,cAAc,oBAAoB,UAAU,IAAI;AAAA,MACzE;AAEA,UAAI,CAAC,SAAS,SAAS,SAAS,MAAM,WAAW,GAAG;AACnD,eAAO,EAAE,SAAS,OAAO,OAAO,qBAAqB,KAAK;AAAA,MAC3D;AAEA,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,+DAA+D,CAAC;AAAA,QAClG;AAAA,MACD;AAEA,YAAM,SAAS,MAAM,gBAAgB,cAAc,oBAAoB,UAAU,IAAI;AAErF,UAAI,OAAO,QAAQ,SAAS,GAAG;AAC9B,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,OAAO,QAAQ,KAAK,IAAI;AAAA,UAChC,YAAY,OAAO;AAAA,UACnB;AAAA,QACD;AAAA,MACD;AAEA,aAAO,EAAE,SAAS,OAAO,OAAO,qBAAqB,KAAK;AAAA,IAC3D;AAAA,IACA,aAAa,OAAO,SAAS;AAC5B,UAAI;AAEH,cAAM,MAAMa,SAAQ,KAAK,QAAQ,KAAK;AACtC,cAAM,WAAWb,MAAKD,QAAO,GAAG,eAAe,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE;AACjE,cAAM,SAAS,OAAO,KAAK,KAAK,MAAM,QAAQ;AAC9C,QAAAe,eAAc,UAAU,MAAM;AAG9B,cAAM,UAAU,MAAM,cAAc,QAAQ;AAC5C,YAAI,CAAC,SAAS;AACb,kBAAQ,QAAQ;AAChB,iBAAO,EAAE,SAAS,OAAO,OAAO,kCAAkC;AAAA,QACnE;AAEA,cAAM,iBAAiB,MAAM,eAAe,QAAQ;AACpD,cAAM,gBAAgB,aAAa,QAAQ,IAAI,MAAM,cAAc,QAAQ,IAAI;AAG/E,uBAAe;AACf,6BAAqB;AACrB,4BAAoB;AAEpB,eAAO;AAAA,UACN,SAAS;AAAA,UACT,UAAU;AAAA,UACV,UAAU,KAAK;AAAA,UACf,OAAO,QAAQ,CAAC;AAAA,UAChB,QAAQ,QAAQ,CAAC;AAAA,UACjB,aAAa;AAAA,UACb,YAAY;AAAA,QACb;AAAA,MACD,SAAS,KAAK;AACb,eAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,MACxD;AAAA,IACD;AAAA,IACA,kBAAkB;AAAA,IAClB,gBAAgB,OAAO,YAAY,SAAS;AAC3C,YAAM,WAAW;AACjB,UAAI,CAAC,SAAS,MAAO,UAAS,QAAQ,CAAC;AACvC,aAAOF,sBAAqB,YAAY,QAAQ;AAAA,IACjD;AAAA,IACA,eAAe,OAAO,eAAe;AACpC,UAAI;AAEH,cAAM,WAAWZ,MAAKD,QAAO,GAAG,qBAAqB,KAAK,IAAI,CAAC,MAAM;AACrE,cAAM,SAAS,MAAM,YAAY,cAAc,UAAU,UAAU;AAEnE,YAAI,CAAC,OAAO,SAAS;AACpB,iBAAO,EAAE,SAAS,OAAO,OAAO,yBAAyB;AAAA,QAC1D;AAGA,cAAM,UAAU,MAAM,cAAc,QAAQ;AAC5C,YAAI,CAAC,SAAS;AACb,kBAAQ,QAAQ;AAChB,iBAAO,EAAE,SAAS,OAAO,OAAO,2CAA2C;AAAA,QAC5E;AAGA,uBAAe;AACf,4BAAoB,OAAO,cAAc;AAEzC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,UAAU;AAAA,UACV,UAAUQ,UAAS,YAAY;AAAA,UAC/B,OAAO,QAAQ,CAAC;AAAA,UAChB,QAAQ,QAAQ,CAAC;AAAA,UACjB,YAAY;AAAA,QACb;AAAA,MACD,SAAS,KAAK;AACb,eAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,MACxD;AAAA,IACD;AAAA,IACA,eAAe,OAAO,eAAe;AACpC,UAAI;AACH,cAAM,WAAWP,MAAKD,QAAO,GAAG,iBAAiB,KAAK,IAAI,CAAC,MAAM;AACjE,cAAM,SAAS,MAAM,eAAe,cAAc,UAAU,UAAU;AAEtE,YAAI,CAAC,OAAO,SAAS;AACpB,iBAAO,EAAE,SAAS,OAAO,OAAO,yBAAyB;AAAA,QAC1D;AAGA,uBAAe;AACf,4BAAoB,OAAO,cAAc;AAEzC,eAAO,EAAE,SAAS,MAAM,YAAY,kBAAkB;AAAA,MACvD,SAAS,KAAK;AACb,eAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,MACxD;AAAA,IACD;AAAA,IACA,gBAAgB,OAAO,YAAY,cAAc;AAChD,UAAI;AAEH,cAAM,SAAS,OAAO,KAAK,WAAW,QAAQ;AAC9C,cAAM,gBAAgBC,MAAKD,QAAO,GAAG,kBAAkB,KAAK,IAAI,CAAC,MAAM;AACvE,QAAAe,eAAc,eAAe,MAAM;AAEnC,cAAM,WAAWd,MAAKD,QAAO,GAAG,iBAAiB,KAAK,IAAI,CAAC,MAAM;AACjE,cAAM,SAAS,MAAM,gBAAgB,cAAc,UAAU,YAAY,aAAa;AAGtF,gBAAQ,aAAa;AAErB,YAAI,CAAC,OAAO,SAAS;AACpB,iBAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,QAC3D;AAGA,uBAAe;AACf,4BAAoB,OAAO,cAAc;AAEzC,eAAO,EAAE,SAAS,MAAM,YAAY,kBAAkB;AAAA,MACvD,SAAS,KAAK;AACb,eAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,MACxD;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAMA,eAAe,iBACd,OACA,aACA,MACA,MACsI;AACtI,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,WAAO;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,MACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,wBAAwB,CAAC;AAAA,IAC3D;AAAA,EACD;AAEA,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,UAAUA,QAAO;AACvB,QAAM,KAAK,KAAK,IAAI;AAEpB,UAAQ,KAAK,YAAY;AAAA,IACxB,KAAK,SAAS;AAEb,YAAM,aAAa,KAAK,cAAc;AACtC,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,mBAAmB,aAAa,CAAC,MAAM,CAAC;AAE3E,YAAM,YAAYC,MAAK,SAAS,iBAAiB,EAAE,MAAM;AACzD,UAAI,CAAE,MAAM,kBAAkB,OAAO,WAAW,UAAU,GAAI;AAC7D,aAAK,KAAK,EAAE,MAAM,SAAS,SAAS,0BAA0B,CAAC;AAC/D,eAAO,EAAE,SAAS,OAAO,OAAO,2BAA2B,KAAK;AAAA,MACjE;AAGA,UAAI,aAAa;AACjB,UAAI,KAAK,SAAS,KAAK,MAAM,SAAS,GAAG;AACxC,cAAM,gBAA0D,CAAC;AACjE,cAAM,SAAS,MAAM,gBAAgB,WAAW,aAAa,MAAM,aAAa;AAChF,aAAK,KAAK,GAAG,aAAa;AAE1B,YAAI,OAAO,QAAQ,WAAW,GAAG;AAChC,kBAAQ,SAAS;AACjB,iBAAO,EAAE,SAAS,OAAO,OAAO,qBAAqB,KAAK;AAAA,QAC3D;AAAA,MACD;AAGA,YAAM,cAAc,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,SAAS,aAAa,CAAC;AACnF,UAAI,eAAe,WAAW;AAC7B,mBAAW,WAAW,WAAW;AAAA,MAClC;AAEA,WAAK,KAAK,EAAE,MAAM,WAAW,SAAS,kBAAkB,aAAa,CAAC,GAAG,CAAC;AAC1E,aAAO,EAAE,SAAS,MAAM,QAAQO,UAAS,WAAW,GAAG,KAAK;AAAA,IAC7D;AAAA,IAEA,KAAK,cAAc;AAElB,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,2BAA2B,CAAC;AAE/D,YAAM,YAAY,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAC1D,MAAAC,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAExC,YAAM,SAAS,MAAM,iBAAiB,OAAO,WAAW,OAAO;AAE/D,UAAI,OAAO,WAAW,GAAG;AACxB,aAAK,KAAK,EAAE,MAAM,SAAS,SAAS,2BAA2B,CAAC;AAChE,eAAO,EAAE,SAAS,OAAO,OAAO,4BAA4B,KAAK;AAAA,MAClE;AAGA,UAAI,KAAK,SAAS,KAAK,MAAM,SAAS,GAAG;AACxC,aAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,cAAc,OAAO,MAAM,aAAa,CAAC;AAC5E,iBAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACvC,gBAAM,YAAsD,CAAC;AAC7D,gBAAM,gBAAgB,OAAO,CAAC,GAAG,aAAa,MAAM,SAAS;AAAA,QAC9D;AACA,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,aAAa,OAAO,MAAM,UAAU,CAAC;AAAA,MAC5E;AAEA,WAAK,KAAK,EAAE,MAAM,WAAW,SAAS,YAAY,OAAO,MAAM,UAAU,CAAC;AAC1E,aAAO,EAAE,SAAS,MAAM,QAAQ,GAAG,OAAO,MAAM,cAAc,SAAS,QAAQ,YAAY,KAAK;AAAA,IACjG;AAAA,IAEA,KAAK,OAAO;AAEX,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,oBAAoB,CAAC;AAGxD,YAAM,SAAS,MAAM,gBAAgB,OAAO,aAAa,MAAM,IAAI;AAEnE,UAAI,OAAO,QAAQ,SAAS,GAAG;AAC9B,eAAO,EAAE,SAAS,MAAM,QAAQ,OAAO,QAAQ,KAAK,IAAI,GAAG,YAAY,OAAO,gBAAgB,KAAK;AAAA,MACpG;AAEA,aAAO,EAAE,SAAS,OAAO,OAAO,qBAAqB,KAAK;AAAA,IAC3D;AAAA,IAEA;AACC,aAAO,EAAE,SAAS,OAAO,OAAO,uBAAuB,KAAK;AAAA,EAC9D;AACD;AAEO,IAAMO,UAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,MAAM;AAC7D;;;AC5+BA,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AACzC,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,WAAU,QAAAC,aAAY;AAuC/B,eAAeC,cACd,OACA,SACmB;AACnB,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AACzE,QAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,WAAW,SAAS;AAE3E,MAAI,aAAa,QAAQ,SAAS,SAAS,QAAQ,OAAO,KAAK;AAE/D,QAAMC,WAAU,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACT;AAEA,MAAI,CAACA,UAAS;AACb,YAAQ,OAAO,0BAA0B;AACzC,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,gBAAgB;AAE9B,QAAM,YAAY,MAAM,cAAc,MAAM;AAE5C,UAAQ,IAAI,EAAE;AACd,MAAI,WAAW;AACd,YAAQ,IAAI,WAAW,MAAM,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,GAAG;AAAA,EAClE,OAAO;AACN,YAAQ,IAAI,WAAW,MAAM,EAAE;AAAA,EAChC;AACA,SAAO;AACR;AAKA,eAAeC,mBAAkB,eAAuD;AACvF,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,IAAI,qBAAqB,KAAK,EAAE;AAC/C,UAAQ,IAAI,KAAK,GAAG,iCAAiC,KAAK,EAAE;AAC5D,UAAQ,IAAI,KAAK,GAAG,uDAAuD,KAAK,EAAE;AAClF,UAAQ,IAAI,EAAE;AAEd,QAAM,cAAc,iBAAiB;AACrC,MAAI,YAAY,MAAM,KAAW,oBAAoB,WAAW;AAChE,MAAI,CAAC,WAAW;AACf,gBAAY;AAAA,EACb;AAEA,UAAQ,IAAI,EAAE;AACd,MAAI,UAAU,MAAM,KAAW,aAAa,SAAS;AACrD,MAAI,CAAC,SAAS;AACb,cAAU;AAAA,EACX;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,IAAI,cAAc,KAAK,sCAAsC;AAC5E,UAAQ,IAAI,KAAK,GAAG,6BAA6B,KAAK,EAAE;AACxD,UAAQ,IAAI,KAAK,GAAG,2BAA2B,KAAK,EAAE;AACtD,UAAQ,IAAI,KAAK,GAAG,wBAAwB,KAAK,EAAE;AACnD,UAAQ,IAAI,EAAE;AAEd,MAAI,OAAO,MAAM,OAAa,sBAAsB,IAAI,GAAG,GAAG;AAC9D,MAAI,OAAO,KAAK,OAAO,KAAK;AAC3B,WAAO;AAAA,EACR;AAEA,SAAO,EAAE,WAAW,SAAS,KAAK;AACnC;AAKA,eAAsBC,KAAI,UAAoC;AAC7D,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,UAAM,2CAA2C;AACjD,YAAQ,IAAI,mDAAmD;AAC/D,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACC,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,SAAO,gBAAgB;AAEvB,MAAI,oBAAoB;AACxB,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,YAAQ,OAAO,sBAAsB;AACrC,WAAO;AAAA,EACR;AAEA,QAAM,cAAc,MAAM,eAAe,KAAK;AAC9C,UAAQ,MAAM,SAAS,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE;AAE3C,MAAI,aAAa;AAChB,SAAK,0BAA0B,WAAW,EAAE;AAAA,EAC7C;AAEA,QAAM,UAAU,MAAMF,mBAAkB,WAAW;AAEnD,UAAQ,IAAI,EAAE;AACd,SAAOF,cAAa,OAAO,OAAO;AACnC;AAKA,eAAsBK,QAAO,UAAoC;AAChE,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACD,YAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAEA,QAAM,cAAc,MAAM,eAAe,KAAK;AAE9C,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUE,UAAS,KAAK;AAAA,MACxB,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd;AAAA,IACD;AAAA,IACA,UAAU;AAAA,MACT,WAAW,eAAe;AAAA,MAC1B,SAAS;AAAA,MACT,MAAM;AAAA,IACP;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,YAAa,KAAK,aAAwB;AAChD,YAAM,UAAW,KAAK,WAAsB;AAC5C,YAAM,OAAQ,KAAK,QAAmB;AACtC,aAAOC,iBAAgB,OAAO,EAAE,WAAW,SAAS,KAAK,CAAC;AAAA,IAC3D;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,OAAiD,CAAC;AAExD,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,oEAAoE,CAAC;AAAA,QACvG;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,cAAcD,UAAS,KAAK,CAAC,MAAM,CAAC;AAEvE,YAAM,YAAa,KAAK,aAAwB;AAChD,YAAM,UAAW,KAAK,WAAsB;AAC5C,YAAM,OAAQ,KAAK,QAAmB;AACtC,YAAM,UAA0B,EAAE,WAAW,SAAS,KAAK;AAE3D,YAAM,WAAW,YAAY,KAAK;AAClC,YAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AACzE,YAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,WAAW,SAAS;AAE3E,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,aAAa,SAAS,WAAM,OAAO,MAAM,CAAC;AAE7E,YAAML,WAAU,MAAM,aAAa,OAAO,QAAQ,WAAW,SAAS,IAAI;AAE1E,UAAIA,UAAS;AACZ,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,iBAAiB,CAAC;AACxD,cAAM,YAAY,MAAM,cAAc,MAAM;AAC5C,cAAM,UAAU,YAAY,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,MAAM;AACnE,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,GAAGK,UAAS,MAAM,CAAC,GAAG,OAAO;AAAA,UACrC;AAAA,QACD;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,SAAS,SAAS,2BAA2B,CAAC;AAChE,aAAO;AAAA,QACN,SAAS;AAAA,QACT,OAAO;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAKA,eAAeC,iBACd,OACA,SACqG;AACrG,QAAM,UAAUC,QAAO;AACvB,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,aAAaC,MAAK,SAAS,kBAAkB,SAAS,UAAU;AACtE,QAAM,aAAaA,MAAK,SAAS,kBAAkB,SAAS,MAAM;AAElE,MAAI;AAEH,QAAI,eAAe;AACnB,QAAI,aAAa,KAAK,GAAG;AACxB,UAAI,CAAE,MAAM,kBAAkB,OAAO,UAAU,GAAI;AAClD,eAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,MAC3D;AACA,qBAAe;AAAA,IAChB;AAEA,UAAMR,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,IACT;AAEA,QAAI,CAACA,UAAS;AACb,cAAQ,YAAY,UAAU;AAC9B,aAAO,EAAE,SAAS,OAAO,OAAO,2BAA2B;AAAA,IAC5D;AAEA,UAAM,SAASS,cAAa,UAAU;AACtC,UAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,UAAM,YAAY,yBAAyB,MAAM;AAEjD,UAAM,OAAO,MAAM,cAAc,UAAU;AAE3C,YAAQ,YAAY,UAAU;AAE9B,WAAO;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,OAAO,OAAO,CAAC;AAAA,MACf,QAAQ,OAAO,CAAC;AAAA,IACjB;AAAA,EACD,SAAS,KAAK;AACb,YAAQ,YAAY,UAAU;AAC9B,WAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,EACxD;AACD;AAEO,IAAMC,UAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,QAAQ,SAAS,QAAQ,MAAM;AACrD;;;AC7SA,SAAS,cAAAC,cAAY,gBAAAC,eAAc,cAAAC,mBAAkB;AACrD,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,WAAmB,QAAAC,cAAY;;;ACFxC,SAAS,cAAAC,cAAY,aAAAC,YAAW,gBAAAC,eAAc,iBAAAC,sBAAqB;AACnE,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,SAAS,WAAAC,gBAAe;AAoBjB,IAAM,iBAA+B;AAAA,EAC3C,UAAU;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,eAAe;AAAA,IACf,YAAY;AAAA,EACb;AAAA,EACA,SAAS;AAAA,IACR,cAAc;AAAA,IACd,YAAY;AAAA,EACb;AAAA,EACA,UAAU;AAAA,IACT,WAAW,CAAC,OAAO,WAAW,KAAK;AAAA,EACpC;AACD;AAGA,SAAS,eAAuB;AAC/B,SAAOD,MAAKC,SAAQ,GAAG,WAAW,QAAQ;AAC3C;AAGO,SAAS,gBAAwB;AACvC,SAAOD,MAAK,aAAa,GAAG,aAAa;AAC1C;AAGO,SAAS,aAA2B;AAC1C,QAAM,aAAa,cAAc;AAEjC,MAAI,CAACL,aAAW,UAAU,GAAG;AAC5B,WAAO,EAAE,GAAG,eAAe;AAAA,EAC5B;AAEA,MAAI;AACH,UAAM,UAAUE,cAAa,YAAY,OAAO;AAChD,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,WAAO;AAAA,MACN,UAAU,EAAE,GAAG,eAAe,UAAU,GAAG,OAAO,SAAS;AAAA,MAC3D,SAAS,EAAE,GAAG,eAAe,SAAS,GAAG,OAAO,QAAQ;AAAA,MACxD,UAAU,EAAE,GAAG,eAAe,UAAU,GAAG,OAAO,SAAS;AAAA,IAC5D;AAAA,EACD,QAAQ;AACP,WAAO,EAAE,GAAG,eAAe;AAAA,EAC5B;AACD;AAeO,SAAS,cAAoB;AACnC,QAAM,aAAa,cAAc;AACjC,QAAM,YAAYK,SAAQ,UAAU;AAEpC,MAAI,CAACC,aAAW,SAAS,GAAG;AAC3B,IAAAC,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,EACzC;AAEA,EAAAC,eAAc,YAAY,KAAK,UAAU,gBAAgB,MAAM,CAAC,CAAC;AAClE;;;AD3CA,eAAeC,cACd,OACA,aACA,SACmB;AACnB,QAAM,WAAW,YAAY,KAAK;AAElC,QAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AACzE,QAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,QAAQ,SAAS;AACxE,QAAM,WAAW,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,QAAQ,SAAS;AAE1E,MAAI,wBAAwB;AAE5B,MAAI,YAAY;AAChB,MAAI,QAAQ,iBAAiB,aAAa;AACzC,gBAAY,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACT;AACA,QAAI,CAAC,WAAW;AACf,WAAK,mDAAmD;AAAA,IACzD;AAAA,EACD;AAEA,MAAI,CAAC,aAAa,aAAa;AAC9B,gBAAY,MAAM,iBAAiB,OAAO,UAAU,aAAa,QAAQ,IAAI;AAAA,EAC9E;AAEA,MAAI,CAAC,WAAW;AACf,YAAQ,OAAO,2BAA2B;AAC1C,YAAQ,QAAQ;AAChB,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,oBAAoB;AAGlC,MAAI,QAAQ,QAAQ;AACnB,QAAI,+BAA+B;AACnC,QAAI,MAAM,KAAK,UAAU,MAAM,GAAG;AACjC,cAAQ,MAAM,SAAS;AACvB,cAAQ,QAAQ;AAAA,IACjB,OAAO;AACN,cAAQ,OAAO,gCAAgC;AAC/C,MAAAC,YAAW,UAAU,MAAM;AAAA,IAC5B;AAAA,EACD,OAAO;AACN,IAAAA,YAAW,UAAU,MAAM;AAAA,EAC5B;AAGA,MAAI,QAAQ,YAAY;AACvB,QAAI,kBAAkB;AACtB,UAAM,aAAa,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,eAAe,SAAS;AACnF,QAAI,MAAM,SAAS,QAAQ,UAAU,GAAG;AACvC,MAAAA,YAAW,YAAY,MAAM;AAC7B,cAAQ,MAAM,aAAa;AAAA,IAC5B,OAAO;AACN,cAAQ,OAAO,uBAAuB;AACtC,cAAQ,UAAU;AAAA,IACnB;AAAA,EACD;AAGA,QAAM,YAAY,MAAM,cAAc,MAAM;AAE5C,UAAQ,IAAI,EAAE;AACd,MAAI,WAAW;AACd,YAAQ,WAAW,MAAM,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,GAAG;AAAA,EAC9D,OAAO;AACN,YAAQ,WAAW,MAAM,EAAE;AAAA,EAC5B;AACA,SAAO;AACR;AAKA,eAAeC,qBAA6C;AAC3D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,IAAI,cAAc,KAAK,qCAAqC;AAC3E,UAAQ,IAAI,KAAK,GAAG,8CAA8C,KAAK,EAAE;AACzE,UAAQ,IAAI,KAAK,GAAG,oCAAoC,KAAK,EAAE;AAC/D,UAAQ,IAAI,KAAK,GAAG,+BAA+B,KAAK,EAAE;AAC1D,UAAQ,IAAI,KAAK,GAAG,4CAA4C,KAAK,EAAE;AACvE,UAAQ,IAAI,EAAE;AAEd,MAAI,OAAO,MAAM,OAAa,sBAAsB,IAAI,GAAG,GAAG;AAC9D,MAAI,OAAO,KAAK,OAAO,KAAK;AAC3B,SAAK,8BAA8B;AACnC,WAAO;AAAA,EACR;AAEA,UAAQ,IAAI,EAAE;AACd,QAAM,SAAS,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,EACD;AAEA,UAAQ,IAAI,EAAE;AACd,QAAM,gBAAgB,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,EACD;AAEA,UAAQ,IAAI,EAAE;AACd,QAAM,aAAa,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,EACD;AAEA,SAAO,EAAE,MAAM,QAAQ,eAAe,WAAW;AAClD;AAMA,eAAsBC,KAAI,UAAoC;AAE7D,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,UAAM,2CAA2C;AACjD,YAAQ,IAAI,mDAAmD;AAC/D,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAGA,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACC,aAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,SAAO,0BAA0B;AAGjC,MAAI,oBAAoB;AACxB,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,YAAQ,OAAO,sBAAsB;AACrC,WAAO;AAAA,EACR;AAGA,QAAM,cAAc,MAAM,eAAe,KAAK;AAC9C,UAAQ,MAAM,SAAS,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE;AAE3C,MAAI,aAAa;AAChB,SAAK,0BAA0B,WAAW,EAAE;AAAA,EAC7C;AAGA,QAAM,UAAU,MAAMF,mBAAkB;AAExC,UAAQ,IAAI,EAAE;AACd,SAAOF,cAAa,OAAO,aAAa,OAAO;AAChD;AAKA,eAAsBK,QAAO,UAAoC;AAEhE,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACD,aAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,WAAO;AAAA,EACR;AAGA,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAGA,QAAM,cAAc,MAAM,eAAe,KAAK;AAG9C,QAAME,WAAS,WAAW;AAC1B,QAAM,WAAWA,SAAO;AAGxB,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUC,UAAS,KAAK;AAAA,MACxB,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd;AAAA,IACD;AAAA,IACA,UAAU;AAAA,MACT,MAAM,SAAS;AAAA,MACf,MAAM,SAAS;AAAA,MACf,eAAe,SAAS;AAAA,MACxB,YAAY,SAAS;AAAA,IACtB;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,UAA0B;AAAA,QAC/B,MAAO,KAAK,QAAmB,SAAS;AAAA,QACxC,QAAS,KAAK,QAAoB,SAAS;AAAA,QAC3C,eAAgB,KAAK,iBAA6B,SAAS;AAAA,QAC3D,YAAa,KAAK,cAA0B,SAAS;AAAA,MACtD;AACA,aAAOC,iBAAgB,OAAO,aAAa,OAAO;AAAA,IACnD;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,OAAiD,CAAC;AAGxD,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,oEAAoE,CAAC;AAAA,QACvG;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,cAAcD,UAAS,KAAK,CAAC,MAAM,CAAC;AAEvE,YAAM,UAA0B;AAAA,QAC/B,MAAO,KAAK,QAAmB,SAAS;AAAA,QACxC,QAAS,KAAK,QAAoB,SAAS;AAAA,QAC3C,eAAgB,KAAK,iBAA6B,SAAS;AAAA,QAC3D,YAAa,KAAK,cAA0B,SAAS;AAAA,MACtD;AAEA,YAAM,WAAW,YAAY,KAAK;AAClC,YAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ;AAGvD,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,yBAAyB,CAAC;AAE7D,YAAME,WAAU,MAAM,mBAAmB,OAAO,aAAa,SAAS,IAAI;AAE1E,UAAIA,UAAS;AACZ,cAAM,YAAY,MAAM,cAAc,MAAM;AAC5C,cAAM,UAAU,YAAY,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,MAAM;AACnE,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,GAAGF,UAAS,MAAM,CAAC,GAAG,OAAO;AAAA,UACrC;AAAA,QACD;AAAA,MACD;AAEA,aAAO;AAAA,QACN,SAAS;AAAA,QACT,OAAO;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAKA,eAAe,mBACd,OACA,aACA,SACA,MACmB;AACnB,QAAM,WAAW,YAAY,KAAK;AAElC,QAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AACzE,QAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,QAAQ,SAAS;AACxE,QAAM,WAAW,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,QAAQ,SAAS;AAE1E,MAAI,YAAY;AAChB,MAAI,QAAQ,iBAAiB,aAAa;AACzC,gBAAY,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACT;AACA,QAAI,CAAC,WAAW;AACf,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,oDAAoD,CAAC;AAAA,IACzF;AAAA,EACD;AAEA,MAAI,CAAC,aAAa,aAAa;AAC9B,gBAAY,MAAM,iBAAiB,OAAO,UAAU,aAAa,QAAQ,IAAI;AAAA,EAC9E;AAEA,MAAI,CAAC,WAAW;AACf,SAAK,KAAK,EAAE,MAAM,SAAS,SAAS,4BAA4B,CAAC;AACjE,YAAQ,QAAQ;AAChB,WAAO;AAAA,EACR;AACA,OAAK,KAAK,EAAE,MAAM,WAAW,SAAS,qBAAqB,CAAC;AAG5D,MAAI,QAAQ,QAAQ;AACnB,SAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,gCAAgC,CAAC;AACpE,QAAI,MAAM,KAAK,UAAU,MAAM,GAAG;AACjC,WAAK,KAAK,EAAE,MAAM,WAAW,SAAS,UAAU,CAAC;AACjD,cAAQ,QAAQ;AAAA,IACjB,OAAO;AACN,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,iCAAiC,CAAC;AACrE,MAAAN,YAAW,UAAU,MAAM;AAAA,IAC5B;AAAA,EACD,OAAO;AACN,IAAAA,YAAW,UAAU,MAAM;AAAA,EAC5B;AAGA,MAAI,QAAQ,YAAY;AACvB,SAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,mBAAmB,CAAC;AACvD,UAAM,aAAa,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,eAAe,SAAS;AACnF,QAAI,MAAM,SAAS,QAAQ,UAAU,GAAG;AACvC,MAAAA,YAAW,YAAY,MAAM;AAC7B,WAAK,KAAK,EAAE,MAAM,WAAW,SAAS,cAAc,CAAC;AAAA,IACtD,OAAO;AACN,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,wBAAwB,CAAC;AAC5D,cAAQ,UAAU;AAAA,IACnB;AAAA,EACD;AAEA,SAAO;AACR;AAKA,eAAeO,iBACd,OACA,aACA,SACqG;AACrG,QAAM,UAAUE,QAAO;AACvB,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,aAAaC,OAAK,SAAS,kBAAkB,SAAS,UAAU;AACtE,QAAM,WAAWA,OAAK,SAAS,kBAAkB,SAAS,MAAM;AAChE,QAAM,aAAaA,OAAK,SAAS,kBAAkB,SAAS,UAAU;AAEtE,MAAI;AAEH,QAAI,eAAe;AACnB,QAAI,aAAa,KAAK,GAAG;AACxB,UAAI,CAAE,MAAM,kBAAkB,OAAO,UAAU,GAAI;AAClD,eAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,MAC3D;AACA,qBAAe;AAAA,IAChB;AAGA,QAAI,YAAY;AAChB,QAAI,QAAQ,iBAAiB,aAAa;AACzC,kBAAY,MAAM,2BAA2B,cAAc,UAAU,aAAa,QAAQ,IAAI;AAAA,IAC/F;AACA,QAAI,CAAC,aAAa,aAAa;AAC9B,kBAAY,MAAM,iBAAiB,cAAc,UAAU,aAAa,QAAQ,IAAI;AAAA,IACrF;AACA,QAAI,CAAC,WAAW;AACf,cAAQ,UAAU;AAClB,aAAO,EAAE,SAAS,OAAO,OAAO,4BAA4B;AAAA,IAC7D;AAGA,QAAI,cAAc;AAClB,QAAI,QAAQ,QAAQ;AACnB,UAAI,MAAM,KAAK,UAAU,UAAU,GAAG;AACrC,gBAAQ,QAAQ;AAChB,sBAAc;AAAA,MACf;AAAA,IACD;AAGA,QAAI,QAAQ,YAAY;AACvB,YAAM,aAAaA,OAAK,SAAS,kBAAkB,SAAS,SAAS;AACrE,UAAI,MAAM,SAAS,aAAa,UAAU,GAAG;AAC5C,gBAAQ,WAAW;AACnB,sBAAc;AAAA,MACf;AAAA,IACD;AAGA,UAAM,SAASC,cAAa,WAAW;AACvC,UAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,UAAM,YAAY,yBAAyB,MAAM;AAGjD,UAAM,OAAO,MAAM,cAAc,WAAW;AAG5C,YAAQ,aAAa,UAAU,YAAY,UAAU;AAErD,WAAO;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,OAAO,OAAO,CAAC;AAAA,MACf,QAAQ,OAAO,CAAC;AAAA,IACjB;AAAA,EACD,SAAS,KAAK;AACb,YAAQ,UAAU,YAAY,UAAU;AACxC,WAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,EACxD;AACD;AAEO,IAAMN,UAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,QAAQ,SAAS,QAAQ,MAAM;AACrD;;;AE9cA,SAAS,cAAAO,cAAY,gBAAAC,sBAAoB;AACzC,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,YAAU,QAAAC,cAAY;AAyC/B,eAAsBC,KAAI,UAAoC;AAE7D,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,UAAM,2CAA2C;AACjD,YAAQ,IAAI,mDAAmD;AAC/D,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAGA,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACC,aAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAGA,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,UAAU,SAAS,SAAS;AAEnF,SAAO,oBAAoB;AAG3B,MAAI,6BAA6B;AACjC,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,YAAQ,OAAO,sBAAsB;AACrC,WAAO;AAAA,EACR;AACA,QAAM,CAAC,OAAO,KAAK,IAAI;AACvB,UAAQ,MAAM,kBAAkB,KAAK,IAAI,KAAK,EAAE;AAGhD,MAAI,UAAU,OAAO;AACpB,SAAK,wBAAwB,KAAK,IAAI,KAAK,GAAG;AAAA,EAC/C;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,IAAI,mBAAmB,KAAK,EAAE;AAC7C,UAAQ;AAAA,IACP,KAAK,GAAG,sDAAsD,KAAK;AAAA,EACpE;AACA,UAAQ;AAAA,IACP,KAAK,GAAG,qDAAqD,KAAK;AAAA,EACnE;AACA,UAAQ,IAAI,EAAE;AAGd,MAAI,UAAU,MAAM,OAAa,sBAAsB,GAAG,CAAC;AAC3D,MAAI,UAAU,MAAM,OAAa,uBAAuB,GAAG,CAAC;AAG5D,MAAI,aAAa;AAEjB,MAAI,YAAY,KAAK,YAAY,GAAG;AAEnC,cAAU,KAAK,MAAM,QAAQ,CAAC;AAC9B,cAAU,KAAK,MAAM,QAAQ,CAAC;AAC9B,SAAK,6BAA6B,OAAO,IAAI,OAAO,GAAG;AAAA,EACxD,WAAW,UAAU,KAAK,YAAY,GAAG;AAExC,cAAU,KAAK,MAAO,UAAU,QAAS,KAAK;AAC9C,SAAK,sBAAsB,OAAO,EAAE;AAAA,EACrC,WAAW,YAAY,KAAK,UAAU,GAAG;AAExC,cAAU,KAAK,MAAO,UAAU,QAAS,KAAK;AAC9C,SAAK,qBAAqB,OAAO,EAAE;AAAA,EACpC;AAGA,UAAQ,IAAI,EAAE;AACd,eAAa,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,EACD;AAEA,MAAI,YAAY;AACf,UAAM,SAAS,KAAK,IAAI,SAAS,OAAO;AACxC,cAAU;AACV,cAAU;AACV,SAAK,kBAAkB,OAAO,IAAI,OAAO,wBAAwB;AAAA,EAClE;AAEA,UAAQ,IAAI,EAAE;AACd,MAAI,kBAAkB;AAEtB,MAAI,SAAS;AACb,MAAI,YAAY;AAEf,aAAS,MAAM,iBAAiB,OAAO,QAAQ,SAAS,OAAO;AAAA,EAChE,OAAO;AAEN,aAAS,MAAM,OAAO,OAAO,QAAQ,SAAS,OAAO;AAAA,EACtD;AAEA,MAAI,CAAC,UAAU,CAACA,aAAW,MAAM,GAAG;AACnC,YAAQ,OAAO,gBAAgB;AAC/B,WAAO;AAAA,EACR;AAGA,QAAM,YAAY,MAAM,cAAc,MAAM;AAC5C,MAAI,WAAW;AACd,YAAQ,MAAM,aAAa,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,EAAE;AAAA,EAC1D,OAAO;AACN,YAAQ,MAAM,QAAQ;AAAA,EACvB;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,WAAW,MAAM,EAAE;AAC3B,SAAO;AACR;AAKA,eAAsBC,QAAO,UAAoC;AAChE,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACD,aAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAEA,QAAM,WAAW,YAAY,KAAK;AAElC,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUE,WAAS,KAAK;AAAA,MACxB,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd,aAAa;AAAA,IACd;AAAA,IACA,UAAU;AAAA,MACT,YAAY;AAAA,IACb;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,UAA0B;AAAA,QAC/B,OAAQ,KAAK,SAAoB,KAAK,MAAM,KAAK,CAAC,IAAI,CAAC;AAAA,QACvD,QAAS,KAAK,UAAqB,KAAK,MAAM,KAAK,CAAC,IAAI,CAAC;AAAA,QACzD,YAAa,KAAK,cAA0B;AAAA,MAC7C;AACA,aAAOC,iBAAgB,OAAO,OAAO;AAAA,IACtC;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,OAAiD,CAAC;AAExD,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,wBAAwB,CAAC;AAAA,QAC3D;AAAA,MACD;AAEA,YAAM,UAA0B;AAAA,QAC/B,OAAQ,KAAK,SAAoB,KAAK,MAAM,KAAK,CAAC,IAAI,CAAC;AAAA,QACvD,QAAS,KAAK,UAAqB,KAAK,MAAM,KAAK,CAAC,IAAI,CAAC;AAAA,QACzD,YAAa,KAAK,cAA0B;AAAA,MAC7C;AAEA,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,cAAc,QAAQ,KAAK,IAAI,QAAQ,MAAM,MAAM,CAAC;AAEvF,YAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,UAAU,SAAS,SAAS;AACnF,UAAI,SAAS;AAEb,UAAI,QAAQ,YAAY;AACvB,cAAM,SAAS,KAAK,IAAI,QAAQ,OAAO,QAAQ,MAAM;AACrD,iBAAS,MAAM,iBAAiB,OAAO,QAAQ,QAAQ,MAAM;AAAA,MAC9D,OAAO;AACN,iBAAS,MAAM,OAAO,OAAO,QAAQ,QAAQ,OAAO,QAAQ,MAAM;AAAA,MACnE;AAEA,UAAI,UAAUH,aAAW,MAAM,GAAG;AACjC,cAAM,YAAY,MAAM,cAAc,MAAM;AAC5C,cAAM,UAAU,YAAY,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,MAAM;AACnE,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,sBAAsB,CAAC;AAC7D,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,GAAGE,WAAS,MAAM,CAAC,GAAG,OAAO;AAAA,UACrC;AAAA,QACD;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,SAAS,SAAS,iBAAiB,CAAC;AACtD,aAAO,EAAE,SAAS,OAAO,OAAO,kBAAkB,KAAK;AAAA,IACxD;AAAA,EACD,CAAC;AACF;AAKA,eAAeC,iBACd,OACA,SACqG;AACrG,QAAM,UAAUC,QAAO;AACvB,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,aAAaC,OAAK,SAAS,kBAAkB,SAAS,UAAU;AACtE,QAAM,aAAaA,OAAK,SAAS,kBAAkB,SAAS,MAAM;AAElE,MAAI;AAEH,QAAI,eAAe;AACnB,QAAI,aAAa,KAAK,GAAG;AACxB,UAAI,CAAE,MAAM,kBAAkB,OAAO,UAAU,GAAI;AAClD,eAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,MAC3D;AACA,qBAAe;AAAA,IAChB;AAEA,QAAI,SAAS;AACb,QAAI,UAAU,QAAQ;AACtB,QAAI,UAAU,QAAQ;AAEtB,QAAI,QAAQ,YAAY;AACvB,YAAM,SAAS,KAAK,IAAI,SAAS,OAAO;AACxC,gBAAU;AACV,gBAAU;AACV,eAAS,MAAM,iBAAiB,cAAc,YAAY,SAAS,OAAO;AAAA,IAC3E,OAAO;AACN,eAAS,MAAM,OAAO,cAAc,YAAY,SAAS,OAAO;AAAA,IACjE;AAEA,QAAI,CAAC,UAAU,CAACL,aAAW,UAAU,GAAG;AACvC,cAAQ,UAAU;AAClB,aAAO,EAAE,SAAS,OAAO,OAAO,iBAAiB;AAAA,IAClD;AAEA,UAAM,SAASM,eAAa,UAAU;AACtC,UAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,UAAM,YAAY,yBAAyB,MAAM;AAEjD,UAAM,OAAO,MAAM,cAAc,UAAU;AAC3C,YAAQ,YAAY,UAAU;AAE9B,WAAO;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,OAAO,OAAO,CAAC;AAAA,MACf,QAAQ,OAAO,CAAC;AAAA,IACjB;AAAA,EACD,SAAS,KAAK;AACb,YAAQ,YAAY,UAAU;AAC9B,WAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,EACxD;AACD;AAEO,IAAMC,UAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,QAAQ,SAAS,QAAQ,MAAM;AACrD;;;ACpTA,SAAS,cAAAC,cAAY,aAAAC,kBAAiB;AACtC,SAAS,YAAAC,YAAU,QAAAC,cAAY;AAqB/B,eAAe,WACd,OACA,QACA,OACA,QACA,MACmB;AACnB,UAAQ,MAAM;AAAA,IACb,KAAK;AACJ,aAAO,cAAc,OAAO,QAAQ,OAAO,MAAM;AAAA,IAClD,KAAK;AACJ,aAAO,OAAO,OAAO,QAAQ,OAAO,MAAM;AAAA,IAC3C,KAAK;AAAA,IACL;AACC,aAAO,iBAAiB,OAAO,QAAQ,OAAO,MAAM;AAAA,EACtD;AACD;AAKA,eAAe,qBACd,WACA,WACA,QACA,YAAuB,OACvB,MACkB;AAClB,MAAI,SAAS;AACb,QAAM,QAAQ,OAAO,MAAM;AAE3B,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC/B,UAAM,OAAO,OAAO,MAAM,CAAC;AAC3B,UAAM,aAAaC,OAAK,WAAW,KAAK,QAAQ;AAEhD,QAAI,MAAM;AACT,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,KAAK,QAAQ,GAAG,CAAC;AAAA,IAC5E,OAAO;AACN,UAAI,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,KAAK,QAAQ,KAAK;AAAA,IACzD;AAEA,UAAM,SAAS,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,IACD;AAEA,QAAI,QAAQ;AACX,UAAI,CAAC,MAAM;AACV,gBAAQ,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,KAAK,IAAI,KAAK,MAAM,GAAG;AAAA,MACpF;AAAA,IACD,OAAO;AACN,UAAI,MAAM;AACT,aAAK,KAAK,EAAE,MAAM,SAAS,SAAS,WAAW,KAAK,QAAQ,GAAG,CAAC;AAAA,MACjE,OAAO;AACN,gBAAQ,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,KAAK,QAAQ,EAAE;AAAA,MAC9D;AACA;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;AAKA,eAAsBC,KAAI,UAAoC;AAC7D,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,UAAM,2CAA2C;AACjD,YAAQ,IAAI,mDAAmD;AAC/D,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACC,aAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,QAAM,WAAW,YAAY,KAAK;AAElC,SAAO,mBAAmB;AAG1B,MAAI,2BAA2B;AAC/B,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,YAAQ,OAAO,sBAAsB;AACrC,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,WAAW,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE;AAG7C,QAAM,UAAU,YAAY;AAC5B,QAAM,UAAU,QAAQ,IAAI,CAAC,OAAO;AAAA,IACnC,OAAO,EAAE;AAAA,IACT,OAAO,EAAE;AAAA,IACT,aAAa,EAAE;AAAA,EAChB,EAAE;AAGF,UAAQ,IAAI,EAAE;AACd,QAAM,aAAa,MAAM,OAAa,wBAAwB,SAAS,QAAQ,CAAC,EAAE,EAAE;AACpF,QAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU;AAEtD,MAAI,CAAC,QAAQ;AACZ,UAAM,kBAAkB;AACxB,WAAO;AAAA,EACR;AAGA,QAAM,YAAY,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,IAAI,OAAO,EAAE;AACvE,EAAAC,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AACxC,OAAK,WAAW,SAAS,EAAE;AAG3B,UAAQ,IAAI,EAAE;AACd,MAAI,qBAAqB;AACzB,QAAM,aAAaH,OAAK,WAAW,aAAa;AAEhD,MAAI,CAAE,MAAM,SAAS,OAAO,UAAU,GAAI;AACzC,YAAQ,OAAO,0BAA0B;AACzC,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,iBAAiB;AAG/B,UAAQ,IAAI,EAAE;AACd,SAAO,cAAc,OAAO,IAAI,SAAS;AAEzC,QAAM,SAAS,MAAM,qBAAqB,YAAY,WAAW,MAAM;AACvE,UAAQ,UAAU;AAElB,UAAQ,IAAI,EAAE;AACd,MAAI,WAAW,GAAG;AACjB,YAAQ,OAAO,OAAO,MAAM,MAAM,oBAAoB;AAAA,EACvD,OAAO;AACN,UAAM,GAAG,MAAM,IAAI,OAAO,MAAM,MAAM,gBAAgB;AAAA,EACvD;AAEA,OAAK,WAAW,SAAS,EAAE;AAC3B,SAAO,WAAW;AACnB;AAKA,eAAsBI,SAAO,UAAoC;AAChE,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACF,aAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAEA,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,UAAU,YAAY;AAE5B,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUG,WAAS,KAAK;AAAA,MACxB,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd,aAAa;AAAA,IACd;AAAA,IACA,UAAU;AAAA,MACT,SAAS,QAAQ,IAAI,CAAC,OAAO;AAAA,QAC5B,IAAI,EAAE;AAAA,QACN,MAAM,EAAE;AAAA,QACR,aAAa,EAAE;AAAA,QACf,OAAO,EAAE;AAAA,MACV,EAAE;AAAA,IACH;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,OAAiD,CAAC;AAExD,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,wBAAwB,CAAC;AAAA,QAC3D;AAAA,MACD;AAEA,YAAM,WAAW,KAAK;AACtB,YAAM,YAAa,KAAK,aAA2B;AACnD,YAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AAEpD,UAAI,CAAC,QAAQ;AACZ,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,qBAAqB,CAAC;AAAA,QACxD;AAAA,MACD;AAGA,YAAM,YAAY,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,IAAI,OAAO,EAAE;AACvE,MAAAF,WAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AACxC,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,WAAW,SAAS,GAAG,CAAC;AAC3D,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,eAAe,SAAS,GAAG,CAAC;AAG/D,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,cAAc,OAAO,MAAM,MAAM,aAAa,CAAC;AAClF,YAAM,SAAS,MAAM,qBAAqB,OAAO,WAAW,QAAQ,WAAW,IAAI;AAEnF,UAAI,WAAW,GAAG;AACjB,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,OAAO,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACrF,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,GAAG,OAAO,MAAM,MAAM,oBAAoB,SAAS,QAAQ,IAAI,OAAO,EAAE;AAAA,UAChF;AAAA,QACD;AAAA,MACD;AAEA,aAAO;AAAA,QACN,SAAS;AAAA,QACT,OAAO,GAAG,MAAM;AAAA,QAChB;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAEO,IAAMG,WAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,QAAQ,SAAS,MAAM;AAC7C;;;AC1QA,SAAS,cAAAC,cAAY,gBAAAC,sBAAgC;AACrD,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,YAAU,QAAAC,cAAY;AAqC/B,IAAM,mBAAkD;AAAA,EACvD,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,cAAc;AAAA,EACd,cAAc;AACf;AAKA,eAAeC,cACd,OACA,SACmB;AACnB,QAAM,WAAW,YAAY,KAAK;AAClC,QAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AACzE,QAAM,SAAS,QAAQ,UAAU,QAAQ,KAAK,EAAE;AAChD,QAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,IAAI,MAAM,GAAG,SAAS;AAE7E,MAAI,YAAY,iBAAiB,QAAQ,SAAS,CAAC,KAAK;AAExD,MAAIC,WAAU;AACd,UAAQ,QAAQ,WAAW;AAAA,IAC1B,KAAK;AACJ,MAAAA,WAAU,MAAM,eAAe,OAAO,MAAM;AAC5C;AAAA,IACD,KAAK;AACJ,MAAAA,WAAU,MAAM,aAAa,OAAO,MAAM;AAC1C;AAAA,IACD,KAAK;AACJ,MAAAA,WAAU,MAAM,OAAO,OAAO,QAAQ,EAAE;AACxC;AAAA,IACD,KAAK;AACJ,MAAAA,WAAU,MAAM,OAAO,OAAO,QAAQ,GAAG;AACzC;AAAA,IACD,KAAK;AACJ,MAAAA,WAAU,MAAM,OAAO,OAAO,QAAQ,GAAG;AACzC;AAAA,EACF;AAEA,MAAI,CAACA,UAAS;AACb,YAAQ,OAAO,kBAAkB;AACjC,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,iBAAiB,QAAQ,SAAS,CAAC;AAGjD,QAAM,YAAY,MAAM,cAAc,MAAM;AAE5C,UAAQ,IAAI,EAAE;AACd,MAAI,WAAW;AACd,YAAQ,IAAI,WAAW,MAAM,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,GAAG;AAAA,EAClE,OAAO;AACN,YAAQ,IAAI,WAAW,MAAM,EAAE;AAAA,EAChC;AACA,SAAO;AACR;AAKA,eAAeC,qBAA6C;AAC3D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,GAAG,IAAI,qBAAqB,KAAK,EAAE;AAC/C,UAAQ,IAAI,KAAK,GAAG,8BAA8B,KAAK,EAAE;AACzD,UAAQ,IAAI,KAAK,GAAG,mBAAmB,KAAK,EAAE;AAC9C,UAAQ,IAAI,KAAK,GAAG,6BAA0B,KAAK,EAAE;AACrD,UAAQ,IAAI,KAAK,GAAG,oBAAiB,KAAK,EAAE;AAC5C,UAAQ,IAAI,KAAK,GAAG,8BAA2B,KAAK,EAAE;AACtD,UAAQ,IAAI,EAAE;AAEd,QAAM,YAAY,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,MACC,EAAE,OAAO,UAAU,OAAO,kBAAkB;AAAA,MAC5C,EAAE,OAAO,UAAU,OAAO,gBAAgB;AAAA,MAC1C,EAAE,OAAO,aAAa,OAAO,gBAAa;AAAA,MAC1C,EAAE,OAAO,cAAc,OAAO,iBAAc;AAAA,MAC5C,EAAE,OAAO,cAAc,OAAO,iBAAc;AAAA,IAC7C;AAAA,IACA;AAAA,EACD;AAEA,SAAO,EAAE,WAAW,aAAa,SAAS;AAC3C;AAKA,eAAsBC,MAAI,UAAoC;AAE7D,MAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,UAAM,2CAA2C;AACjD,YAAQ,IAAI,mDAAmD;AAC/D,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAGA,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACC,aAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,UAAM,aAAa;AACnB,WAAO;AAAA,EACR;AAEA,SAAO,kBAAkB;AAGzB,MAAI,oBAAoB;AACxB,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,YAAQ,OAAO,sBAAsB;AACrC,WAAO;AAAA,EACR;AACA,UAAQ,MAAM,SAAS,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE;AAG3C,QAAM,UAAU,MAAMF,mBAAkB;AAExC,UAAQ,IAAI,EAAE;AACd,SAAOF,cAAa,OAAO,OAAO;AACnC;AAKA,eAAsBK,SAAO,UAAoC;AAChE,QAAM,QAAQ,cAAc,QAAQ;AAEpC,MAAI,CAACD,aAAW,KAAK,GAAG;AACvB,UAAM,mBAAmB,KAAK,EAAE;AAChC,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,cAAc,KAAK;AACtC,MAAI,CAAC,MAAM;AACV,UAAM,iCAAiC;AACvC,WAAO;AAAA,EACR;AAEA,SAAO,eAAe;AAAA,IACrB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,MACV,UAAU;AAAA,MACV,UAAUE,WAAS,KAAK;AAAA,MACxB,OAAO,KAAK,CAAC;AAAA,MACb,QAAQ,KAAK,CAAC;AAAA,MACd,aAAa;AAAA,IACd;AAAA,IACA,UAAU;AAAA,MACT,WAAW;AAAA,IACZ;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,YAAa,KAAK,aAA+B;AACvD,aAAOC,iBAAgB,OAAO,EAAE,UAAU,CAAC;AAAA,IAC5C;AAAA,IACA,WAAW,OAAO,SAAS;AAC1B,YAAM,OAAiD,CAAC;AAExD,UAAI,CAAE,MAAM,iBAAiB,GAAI;AAChC,eAAO;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,UACP,MAAM,CAAC,EAAE,MAAM,SAAS,SAAS,oEAAoE,CAAC;AAAA,QACvG;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,cAAcD,WAAS,KAAK,CAAC,MAAM,CAAC;AAEvE,YAAM,YAAa,KAAK,aAA+B;AACvD,YAAM,UAA0B,EAAE,UAAU;AAE5C,YAAM,WAAW,YAAY,KAAK;AAClC,YAAM,YAAY,SAAS,UAAU,YAAY,MAAM,SAAS,SAAS;AACzE,YAAM,SAAS,UAAU,QAAQ,KAAK,EAAE;AACxC,YAAM,SAAS,GAAG,SAAS,OAAO,IAAI,SAAS,QAAQ,IAAI,MAAM,GAAG,SAAS;AAE7E,WAAK,KAAK,EAAE,MAAM,QAAQ,SAAS,YAAY,iBAAiB,SAAS,CAAC,MAAM,CAAC;AAEjF,UAAIL,WAAU;AACd,cAAQ,WAAW;AAAA,QAClB,KAAK;AACJ,UAAAA,WAAU,MAAM,eAAe,OAAO,MAAM;AAC5C;AAAA,QACD,KAAK;AACJ,UAAAA,WAAU,MAAM,aAAa,OAAO,MAAM;AAC1C;AAAA,QACD,KAAK;AACJ,UAAAA,WAAU,MAAM,OAAO,OAAO,QAAQ,EAAE;AACxC;AAAA,QACD,KAAK;AACJ,UAAAA,WAAU,MAAM,OAAO,OAAO,QAAQ,GAAG;AACzC;AAAA,QACD,KAAK;AACJ,UAAAA,WAAU,MAAM,OAAO,OAAO,QAAQ,GAAG;AACzC;AAAA,MACF;AAEA,UAAIA,UAAS;AACZ,aAAK,KAAK,EAAE,MAAM,WAAW,SAAS,oBAAoB,CAAC;AAC3D,cAAM,YAAY,MAAM,cAAc,MAAM;AAC5C,cAAM,UAAU,YAAY,KAAK,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,MAAM;AACnE,eAAO;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,GAAGK,WAAS,MAAM,CAAC,GAAG,OAAO;AAAA,UACrC;AAAA,QACD;AAAA,MACD;AAEA,WAAK,KAAK,EAAE,MAAM,SAAS,SAAS,mBAAmB,CAAC;AACxD,aAAO;AAAA,QACN,SAAS;AAAA,QACT,OAAO;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAKA,eAAeC,iBACd,OACA,SACqG;AACrG,QAAM,UAAUC,QAAO;AACvB,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,aAAaC,OAAK,SAAS,kBAAkB,SAAS,UAAU;AACtE,QAAM,aAAaA,OAAK,SAAS,kBAAkB,SAAS,MAAM;AAElE,MAAI;AAEH,QAAI,eAAe;AACnB,QAAI,aAAa,KAAK,GAAG;AACxB,UAAI,CAAE,MAAM,kBAAkB,OAAO,UAAU,GAAI;AAClD,eAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,MAC3D;AACA,qBAAe;AAAA,IAChB;AAEA,QAAIR,WAAU;AACd,YAAQ,QAAQ,WAAW;AAAA,MAC1B,KAAK;AACJ,QAAAA,WAAU,MAAM,eAAe,cAAc,UAAU;AACvD;AAAA,MACD,KAAK;AACJ,QAAAA,WAAU,MAAM,aAAa,cAAc,UAAU;AACrD;AAAA,MACD,KAAK;AACJ,QAAAA,WAAU,MAAM,OAAO,cAAc,YAAY,EAAE;AACnD;AAAA,MACD,KAAK;AACJ,QAAAA,WAAU,MAAM,OAAO,cAAc,YAAY,GAAG;AACpD;AAAA,MACD,KAAK;AACJ,QAAAA,WAAU,MAAM,OAAO,cAAc,YAAY,GAAG;AACpD;AAAA,IACF;AAEA,QAAI,CAACA,UAAS;AACb,cAAQ,YAAY,UAAU;AAC9B,aAAO,EAAE,SAAS,OAAO,OAAO,mBAAmB;AAAA,IACpD;AAEA,UAAM,SAASS,eAAa,UAAU;AACtC,UAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,UAAM,YAAY,yBAAyB,MAAM;AAEjD,UAAM,OAAO,MAAM,cAAc,UAAU;AAE3C,YAAQ,YAAY,UAAU;AAE9B,WAAO;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,OAAO,OAAO,CAAC;AAAA,MACf,QAAQ,OAAO,CAAC;AAAA,IACjB;AAAA,EACD,SAAS,KAAK;AACb,YAAQ,YAAY,UAAU;AAC9B,WAAO,EAAE,SAAS,OAAO,OAAQ,IAAc,QAAQ;AAAA,EACxD;AACD;AAEO,IAAMC,WAAS;AAAA,EACrB,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,YAAY,CAAC,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,MAAM;AAC7D;;;AC3SO,IAAM,QAAgB;AAAA,EAC5B,EAAE,QAAiBC,SAAQ,KAAcC,MAAK,QAAiBC,QAAO;AAAA,EACtE,EAAE,QAAiBF,SAAQ,KAAcC,MAAK,QAAiBC,QAAO;AAAA,EACtE,EAAE,QAAgBF,SAAQ,KAAaC,MAAK,QAAgBC,QAAO;AAAA,EACnE,EAAE,QAAiBF,SAAQ,KAAcC,MAAK,QAAiBC,QAAO;AAAA,EACtE,EAAE,QAAkBF,UAAQ,KAAeC,MAAK,QAAkBC,SAAO;AAAA,EACzE,EAAE,QAAkBF,UAAQ,KAAeC,OAAK,QAAkBC,SAAO;AAAA,EACzE,EAAE,QAAeF,SAAQ,KAAYC,MAAK,QAAeC,QAAO;AAAA,EAChE,EAAE,QAAuB,KAAiB,OAAsB;AAAA,EAChE,EAAE,QAAgBF,SAAQ,KAAaC,MAAK,QAAgBC,QAAO;AAAA,EACnE,EAAE,QAAsBF,SAAQ,KAAmBC,MAAK,QAAsBC,QAAO;AACtF;AAGO,IAAM,aAA0B;AAAA,EACtC,QAAmBF;AAAA,EACnB,QAAmBE;AACpB;AAMO,SAAS,QAAQ,IAA8B;AACrD,SAAO,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,EAAE;AAC5C;AAGO,SAAS,mBAA6B;AAC5C,QAAM,aAAa,oBAAI,IAAY;AACnC,aAAW,EAAE,QAAAC,SAAO,KAAK,OAAO;AAC/B,eAAW,OAAOA,SAAO,YAAY;AACpC,iBAAW,IAAI,GAAG;AAAA,IACnB;AAAA,EACD;AACA,SAAO,MAAM,KAAK,UAAU;AAC7B;AAGO,SAAS,qBAAqB,WAA2B;AAC/D,SAAO,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,WAAW,SAAS,SAAS,CAAC;AACnE;;;AZnEO,SAAS,aAAqB;AACpC,QAAM,cAAcC,eAAc,YAAY,GAAG;AAEjD,SAAOC,SAAQ,WAAW;AAC3B;AAGO,SAAS,gBAAgB,WAA2B;AAC1D,SAAO,oDAAoD,SAAS;AACrE;AAGO,SAAS,mBACf,OACA,mBACyC;AACzC,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAoB,CAAC;AAE3B,aAAW,QAAQ,OAAO;AACzB,UAAM,MAAMC,SAAQ,IAAI,EAAE,YAAY;AACtC,QAAI,kBAAkB,SAAS,GAAG,GAAG;AACpC,YAAM,KAAK,IAAI;AAAA,IAChB,OAAO;AACN,cAAQ,KAAK,IAAI;AAAA,IAClB;AAAA,EACD;AAEA,SAAO,EAAE,OAAO,QAAQ;AACzB;AAGA,eAAsB,eACrB,QACA,OACA,QACmB;AACnB,QAAM,OAAO,QAAQ,MAAM;AAC3B,MAAI,CAAC,MAAM;AACV,YAAQ,MAAM,MAAM,IAAI,mBAAmB,MAAM,EAAE,CAAC;AACpD,WAAO;AAAA,EACR;AAGA,QAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAO,KAAK,OAAO,UAAU;AAE3E,MAAI,QAAQ,SAAS,GAAG;AACvB,YAAQ,MAAM,MAAM,IAAI,qBAAqB,CAAC;AAC9C,eAAW,QAAQ,SAAS;AAC3B,cAAQ,MAAM,MAAM,IAAI,YAAO,IAAI,EAAE,CAAC;AAAA,IACvC;AACA,YAAQ;AAAA,MACP,MAAM;AAAA,QACL;AAAA,wBAA2B,KAAK,OAAO,WAAW,KAAK,IAAI,CAAC;AAAA,MAC7D;AAAA,IACD;AACA,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,YAAQ,IAAI;AAAA,EACb;AAGA,MAAI,UAAU,MAAM,SAAS,GAAG;AAC/B,mBAAe,IAAI;AAAA,EACpB;AAGA,MAAI,aAAa;AACjB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACtC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,MAAM,SAAS,GAAG;AACrB,cAAQ,IAAI,MAAM,KAAK;AAAA,GAAM,IAAI,CAAC,IAAI,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC/D;AACA,UAAMC,WAAU,MAAM,KAAK,IAAI,IAAI;AACnC,QAAI,CAACA,SAAS,cAAa;AAAA,EAC5B;AAEA,SAAO;AACR;;;ARhFO,SAAS,sBAAsBC,UAAwB;AAC7D,EAAAA,SACE,QAAQ,mBAAmB,EAC3B,YAAY,kCAAkC,EAC9C,OAAO,aAAa,4BAA4B,EAChD,OAAO,aAAa,qBAAqB,EACzC,OAAO,OAAO,OAAiB,YAA8C;AAC7E,QAAI,QAAQ,KAAK;AAChB,YAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAc,OAAO,UAAU;AAC7E,UAAI,QAAQ,SAAS,GAAG;AACvB,gBAAQ,MAAMC,OAAM,IAAI,qBAAqB,CAAC;AAC9C,mBAAW,QAAQ,SAAS;AAC3B,kBAAQ,MAAMA,OAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,QACvC;AAAA,MACD;AACA,UAAI,MAAM,WAAW,GAAG;AACvB,gBAAQ,KAAK,CAAC;AAAA,MACf;AACA,YAAM,SAAS,MAAa,OAAO,MAAM,CAAC,CAAC;AAC3C,cAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,IAC5B;AAEA,UAAMC,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IAChB;AACA,YAAQ,KAAKA,WAAU,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH;;;AqBlCA,OAAOC,YAAW;AAIX,SAAS,sBAAsBC,UAAwB;AAC7D,QAAM,YAAYA,SAChB,QAAQ,QAAQ,EAChB,YAAY,0BAA0B,EACtC,OAAO,MAAM;AACb,UAAMC,WAAS,WAAW;AAC1B,YAAQ,IAAIC,OAAM,MAAM,KAAK,0BAA0B,CAAC;AACxD,YAAQ,IAAIA,OAAM,KAAK,KAAK,cAAc,CAAC;AAAA,CAAI,CAAC;AAChD,YAAQ,IAAI,KAAK,UAAUD,UAAQ,MAAM,CAAC,CAAC;AAC3C,YAAQ,IAAI;AAAA,EACb,CAAC;AAEF,YACE,QAAQ,OAAO,EACf,YAAY,kBAAkB,EAC9B,OAAO,MAAM;AACb,gBAAY;AACZ,YAAQ,IAAIC,OAAM,MAAM,kCAAkC,CAAC;AAAA,EAC5D,CAAC;AACH;;;ACvBA,OAAOC,YAAW;AAKX,SAAS,6BAA6BC,UAAwB;AACpE,EAAAA,SACE,QAAQ,2BAA2B,EACnC,MAAM,QAAQ,EACd,YAAY,kCAAkC,EAC9C,OAAO,aAAa,4BAA4B,EAChD,OAAO,aAAa,qBAAqB,EACzC,OAAO,OAAO,OAAiB,YAA8C;AAC7E,QAAI,QAAQ,KAAK;AAChB,YAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAqBC,QAAO,UAAU;AACpF,UAAI,QAAQ,SAAS,GAAG;AACvB,gBAAQ,MAAMC,OAAM,IAAI,qBAAqB,CAAC;AAC9C,mBAAW,QAAQ,SAAS;AAC3B,kBAAQ,MAAMA,OAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,QACvC;AAAA,MACD;AACA,UAAI,MAAM,WAAW,GAAG;AACvB,gBAAQ,KAAK,CAAC;AAAA,MACf;AACA,YAAM,SAAS,MAAoBC,QAAO,MAAM,CAAC,CAAC;AAClD,cAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,IAC5B;AAEA,UAAMC,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IAChB;AACA,YAAQ,KAAKA,WAAU,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH;;;ACnCA,OAAOC,YAAW;AAKX,SAAS,sBAAsBC,UAAwB;AAC7D,EAAAA,SACE,QAAQ,mBAAmB,EAC3B,YAAY,8CAA8C,EAC1D,OAAO,aAAa,4BAA4B,EAChD,OAAO,aAAa,qBAAqB,EACzC,OAAO,OAAO,OAAiB,YAA8C;AAC7E,QAAI,QAAQ,KAAK;AAChB,YAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAcC,QAAO,UAAU;AAC7E,UAAI,QAAQ,SAAS,GAAG;AACvB,gBAAQ,MAAMC,OAAM,IAAI,qBAAqB,CAAC;AAC9C,mBAAW,QAAQ,SAAS;AAC3B,kBAAQ,MAAMA,OAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,QACvC;AAAA,MACD;AACA,UAAI,MAAM,WAAW,GAAG;AACvB,gBAAQ,KAAK,CAAC;AAAA,MACf;AACA,YAAM,SAAS,MAAaC,QAAO,MAAM,CAAC,CAAC;AAC3C,cAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,IAC5B;AAEA,UAAMC,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IAChB;AACA,YAAQ,KAAKA,WAAU,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH;;;AC/BO,SAAS,oBAAoBC,UAAwB;AAC3D,EAAAA,SACE,QAAQ,MAAM,EACd,YAAY,WAAW,EACvB,OAAO,MAAM;AACb,aAAS;AAAA,EACV,CAAC;AACH;;;ACVA,OAAOC,YAAW;AAKX,SAAS,wBAAwBC,UAAwB;AAC/D,EAAAA,SACE,QAAQ,qBAAqB,EAC7B,YAAY,0CAA0C,EACtD,OAAO,aAAa,4BAA4B,EAChD,OAAO,aAAa,qBAAqB,EACzC,OAAO,OAAO,OAAiB,YAA8C;AAE7E,QAAI,QAAQ,KAAK;AAChB,YAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAgBC,QAAO,UAAU;AAC/E,UAAI,QAAQ,SAAS,GAAG;AACvB,gBAAQ,MAAMC,OAAM,IAAI,qBAAqB,CAAC;AAC9C,mBAAW,QAAQ,SAAS;AAC3B,kBAAQ,MAAMA,OAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,QACvC;AAAA,MACD;AACA,UAAI,MAAM,WAAW,GAAG;AACvB,gBAAQ,KAAK,CAAC;AAAA,MACf;AACA,YAAM,SAAS,MAAeC,QAAO,MAAM,CAAC,CAAC;AAC7C,cAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,IAC5B;AAEA,UAAMC,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IAChB;AACA,YAAQ,KAAKA,WAAU,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH;;;ACnCA,OAAOC,YAAW;;;ACAlB,SAAS,QAAAC,aAAY;AACrB,SAAS,cAAAC,oBAAkB;AAC3B,SAAS,WAAAC,iBAAe;AACxB,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,aAAAC,kBAAiB;AAE1B,IAAMC,aAAYD,WAAUJ,KAAI;AAKzB,SAAS,QAAiB;AAChC,SACC,QAAQ,aAAa,YACpB,QAAQ,IAAI,oBAAoB,UAChC,QAAQ,IAAI,WAAW;AAE1B;AAKO,SAAS,sBAA+B;AAC9C,SAAOC,aAAW,qCAAqC;AACxD;AAuCA,eAAsB,eACrB,SACA,WACA,OACA,OAAO,UACY;AACnB,QAAM,WAAW,YAAY,OAAO,SAAS,MAAM;AAEnD,QAAM,eAAe,MAAM,QAAQ,MAAM,KAAK;AAC9C,QAAM,MAAM,gBAAgB,OAAO,KAAK,QAAQ,OAAO,IAAI,QAAQ,YAAY;AAE/E,MAAI;AACH,UAAMK,WAAU,GAAG;AACnB,WAAO;AAAA,EACR,SAASC,QAAO;AACf,UAAM,UAAWA,OAAgB;AAEjC,UAAM,gBAAgB,CAAC,qBAAqB,WAAW;AACvD,UAAM,eAAe,cAAc;AAAA,MAAK,CAAC,MACxC,QAAQ,YAAY,EAAE,SAAS,EAAE,YAAY,CAAC;AAAA,IAC/C;AACA,QAAI,CAAC,cAAc;AAClB,cAAQ,MAAM,+BAA+B,OAAO,EAAE;AACtD,cAAQ,MAAM,OAAO;AAAA,IACtB;AACA,WAAO;AAAA,EACR;AACD;AAKA,eAAsB,kBAAkB,SAAmC;AAC1E,QAAM,MAAM,mBAAmB,OAAO;AAEtC,MAAI;AACH,UAAMD,WAAU,GAAG;AACnB,WAAO;AAAA,EACR,SAASC,QAAO;AACf,UAAM,UAAWA,OAAgB;AAKjC,UAAM,gBAAgB,CAAC,kBAAkB,qBAAqB,WAAW;AACzE,UAAM,eAAe,cAAc;AAAA,MAAK,CAAC,MACxC,QAAQ,YAAY,EAAE,SAAS,EAAE,YAAY,CAAC;AAAA,IAC/C;AACA,QAAI,CAAC,cAAc;AAClB,cAAQ,MAAM,kCAAkC,OAAO,EAAE;AAAA,IAC1D;AACA,WAAO;AAAA,EACR;AACD;;;ACpHA,SAAS,iBAAiB;AAC1B,SAAS,QAAAC,cAAY;AAcrB,eAAe,oBACd,WACA,UACA,cAC8B;AAC9B,QAAM,WAAW,oDAAoD,SAAS;AAC9E,QAAM,cAAc,aAAa,QAAQ;AACzC,QAAM,cAAc,aAAa,YAAY;AAG7C,QAAM,cAAc,MAAM,eAAe,UAAU,WAAW,QAAQ;AACtE,QAAM,cAAc,MAAM,eAAe,UAAU,QAAQ,GAAG,WAAW,cAAc;AAGvF,QAAM,eAAe,UAAU,oBAAoB,QAAQ;AAG3D,QAAM,eAAe,oBAAoB,WAAW;AACpD,QAAM,aAAa,MAAM,eAAe,GAAG,QAAQ,aAAa,IAAI,YAAY;AAEhF,SAAO;AAAA,IACN;AAAA,IACA,UAAU;AAAA,IACV,SAAS,eAAe,eAAe;AAAA,EACxC;AACD;AA2DA,eAAe,2BACd,WACgC;AAChC,QAAM,UAAgC,CAAC;AACvC,QAAM,WAAW,gBAAgB,SAAS;AAC1C,QAAM,iBAAiB,qBAAqB,SAAS;AAGrD,aAAW,EAAE,QAAAC,SAAO,KAAK,gBAAgB;AACxC,UAAM,WAAW,GAAG,QAAQ,YAAYA,SAAO,EAAE;AACjD,UAAM,kBAAkB,GAAG,QAAQ,WAAW;AAC9C,UAAMC,WAAU,MAAM,kBAAkB,QAAQ;AAEhD,YAAQ,KAAK;AAAA,MACZ;AAAA,MACA,UAAUD,SAAO;AAAA,MACjB,SAAAC;AAAA,IACD,CAAC;AAAA,EACF;AAGA,QAAM,kBAAkB,GAAG,QAAQ,SAAS;AAG5C,QAAM,kBAAkB,QAAQ;AAEhC,SAAO;AACR;AAGA,eAAsB,mBAAkD;AACvE,QAAM,UAAU,WAAW;AAC3B,QAAM,WAAWC,OAAK,SAAS,OAAO;AACtC,QAAM,eAAeA,OAAK,SAAS,cAAc;AACjD,QAAM,UAAgC,CAAC;AAGvC,aAAW,aAAa,WAAW,OAAO,YAAY;AACrD,UAAM,SAAS,MAAM,oBAAoB,WAAW,UAAU,YAAY;AAC1E,YAAQ,KAAK,MAAM;AAAA,EACpB;AAEA,SAAO;AACR;AAGA,IAAM,oBAAoB;AAAA;AAAA,EAEzB;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAGA,IAAM,uBAAuB,CAAC,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,QAAQ,SAAS,SAAS,MAAM;AAGvG,eAAsB,uBAAyE;AAC9F,QAAM,UAAoB,CAAC;AAC3B,QAAM,SAAmB,CAAC;AAE1B,aAAW,OAAO,sBAAsB;AACvC,UAAM,YAAY,oDAAoD,GAAG;AAEzE,eAAW,cAAc,mBAAmB;AAC3C,YAAM,UAAU,GAAG,SAAS,KAAK,UAAU;AAG3C,YAAM,kBAAkB,GAAG,OAAO,WAAW;AAG7C,YAAMD,WAAU,MAAM,kBAAkB,OAAO;AAC/C,UAAIA,UAAS;AACZ,gBAAQ,KAAK,GAAG,GAAG,WAAM,UAAU,EAAE;AAAA,MACtC;AAAA,IACD;AAAA,EACD;AAEA,SAAO,EAAE,SAAS,OAAO;AAC1B;AAGA,eAAsB,qBAAoD;AACzE,QAAM,UAAgC,CAAC;AAGvC,QAAM,UAAU,oBAAI,IAAI,CAAC,GAAG,iBAAiB,GAAG,GAAG,WAAW,OAAO,UAAU,CAAC;AAChF,aAAW,aAAa,SAAS;AAChC,UAAM,WAAW,gBAAgB,SAAS;AAG1C,UAAM,aAAa,MAAM,2BAA2B,SAAS;AAC7D,YAAQ,KAAK,GAAG,UAAU;AAG1B,UAAM,kBAAkB,GAAG,QAAQ,WAAW;AAC9C,UAAM,kBAAkB,QAAQ;AAAA,EACjC;AAEA,SAAO;AACR;AAKA,SAAS,eAAe,OAAuB;AAC9C,SAAO,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK;AACxD;AAKA,SAAS,qBAA6B;AACrC,QAAM,UAAU,WAAW;AAC3B,QAAM,WAAWC,OAAK,SAAS,OAAO;AACtC,QAAM,eAAeA,OAAK,SAAS,cAAc;AACjD,QAAM,cAAc,aAAa,QAAQ;AACzC,QAAM,cAAc,aAAa,YAAY;AAE7C,QAAM,QAAkB,CAAC,wCAAwC,EAAE;AAGnE,aAAW,aAAa,WAAW,OAAO,YAAY;AACrD,UAAM,WAAW,iEAAiE,SAAS;AAE3F,UAAM,KAAK,IAAI,QAAQ,GAAG;AAC1B,UAAM,KAAK,cAAc,eAAe,QAAQ,CAAC,GAAG;AACpD,UAAM,KAAK,WAAW,eAAe,GAAG,WAAW,cAAc,CAAC,GAAG;AACrE,UAAM,KAAK,6BAA6B;AACxC,UAAM,KAAK,EAAE;AAGb,UAAM,eAAe,oBAAoB,WAAW;AACpD,UAAM,KAAK,IAAI,QAAQ,YAAY;AACnC,UAAM,KAAK,MAAM,eAAe,YAAY,CAAC,GAAG;AAChD,UAAM,KAAK,EAAE;AAAA,EACd;AAEA,SAAO,MAAM,KAAK,MAAM;AACzB;AAKA,SAAS,8BAAsC;AAC9C,QAAM,QAAkB,CAAC,wCAAwC,EAAE;AAGnE,QAAM,UAAU,oBAAI,IAAI,CAAC,GAAG,iBAAiB,GAAG,GAAG,WAAW,OAAO,UAAU,CAAC;AAChF,aAAW,aAAa,SAAS;AAChC,UAAM,WAAW,iEAAiE,SAAS;AAG3F,UAAM,KAAK,KAAK,QAAQ,GAAG;AAC3B,UAAM,KAAK,EAAE;AAAA,EACd;AAGA,aAAW,OAAO,sBAAsB;AACvC,eAAW,cAAc,mBAAmB;AAC3C,YAAM,UAAU,iEAAiE,GAAG,YAAY,UAAU;AAC1G,YAAM,KAAK,KAAK,OAAO,GAAG;AAAA,IAC3B;AACA,UAAM,KAAK,EAAE;AAAA,EACd;AAEA,SAAO,MAAM,KAAK,MAAM;AACzB;AAMA,eAAsB,kBAAmC;AACxD,QAAM,UAAU,WAAW;AAC3B,QAAM,UAAUA,OAAK,SAAS,oBAAoB;AAClD,QAAM,UAAU,mBAAmB;AACnC,QAAM,UAAU,SAAS,SAAS,OAAO;AACzC,SAAO;AACR;AAMA,eAAsB,2BAA4C;AACjE,QAAM,UAAU,WAAW;AAC3B,QAAM,UAAUA,OAAK,SAAS,sBAAsB;AACpD,QAAM,UAAU,4BAA4B;AAC5C,QAAM,UAAU,SAAS,SAAS,OAAO;AACzC,SAAO;AACR;;;AFrTO,SAAS,uBAAuBC,UAAwB;AAC9D,EAAAA,SACE,QAAQ,SAAS,EACjB,YAAY,gDAAgD,EAC5D,OAAO,YAAY;AACnB,eAAW;AACX,YAAQ,IAAIC,OAAM,KAAK,iBAAiB,CAAC;AAEzC,QAAI,CAAC,MAAM,GAAG;AACb,cAAQ;AAAA,QACPA,OAAM,OAAO,qDAAqD;AAAA,MACnE;AACA,cAAQ;AAAA,QACPA,OAAM,OAAO,sDAAsD;AAAA,MACpE;AACA;AAAA,IACD;AAEA,QAAI,CAAC,oBAAoB,GAAG;AAC3B,cAAQ,IAAIA,OAAM,OAAO,0DAA0D,CAAC;AAEpF,YAAM,UAAU,MAAM,gBAAgB;AACtC,YAAM,UAAU,aAAa,OAAO;AAEpC,cAAQ,IAAIA,OAAM,MAAM,iCAA4B,CAAC;AACrD,cAAQ,IAAIA,OAAM,KAAK,KAAK,OAAO;AAAA,CAAI,CAAC;AACxC,cAAQ,IAAIA,OAAM,KAAK,qBAAqB,CAAC;AAC7C,cAAQ,IAAIA,OAAM,IAAI,qDAAqD,CAAC;AAC5E,cAAQ,IAAIA,OAAM,IAAI,gDAAgD,OAAO,GAAG,CAAC;AACjF,cAAQ,IAAI;AACZ;AAAA,IACD;AAGA,YAAQ,IAAIA,OAAM,IAAI,yBAAyB,CAAC;AAChD,UAAM,mBAAmB;AACzB,YAAQ,IAAI;AAEZ,UAAM,UAAU,MAAM,iBAAiB;AACvC,UAAM,aAAa,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO;AAGjD,eAAW,EAAE,QAAAC,SAAO,KAAK,OAAO;AAC/B,YAAM,UAAUA,SAAO,WAAW,KAAK,IAAI;AAC3C,cAAQ,IAAI,GAAGD,OAAM,MAAM,QAAG,CAAC,IAAIC,SAAO,IAAI,IAAID,OAAM,IAAI,IAAI,OAAO,GAAG,CAAC,EAAE;AAAA,IAC9E;AAEA,YAAQ,IAAI;AACZ,QAAI,YAAY;AACf,cAAQ;AAAA,QACPA,OAAM,MAAM,qBAAgB,MAAM,MAAM,0BAA0B;AAAA,MACnE;AAAA,IACD,OAAO;AACN,YAAM,eAAe,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AACtD,cAAQ;AAAA,QACPA,OAAM,OAAO,gBAAgB,YAAY,IAAI,QAAQ,MAAM,WAAW;AAAA,MACvE;AAAA,IACD;AAEA,YAAQ,IAAIA,OAAM,KAAK,uBAAuB,CAAC;AAC/C,YAAQ,IAAI,wDAAwD;AACpE,YAAQ,IAAI,gDAAgD;AAE5D,YAAQ,IAAIA,OAAM,KAAK,cAAc,CAAC;AACtC,YAAQ,IAAIA,OAAM,KAAK,kBAAkB,IAAIA,OAAM,IAAI,0BAA0B,CAAC;AAClF,YAAQ,IAAIA,OAAM,KAAK,yBAAyB,IAAIA,OAAM,IAAI,mBAAmB,CAAC;AAClF,YAAQ,IAAIA,OAAM,KAAK,0BAA0B,IAAIA,OAAM,IAAI,oBAAoB,CAAC;AACpF,YAAQ,IAAIA,OAAM,KAAK,sBAAsB,IAAIA,OAAM,IAAI,mBAAmB,CAAC;AAC/E,YAAQ,IAAIA,OAAM,KAAK,yBAAyB,IAAIA,OAAM,IAAI,sBAAsB,CAAC;AACrF,YAAQ,IAAIA,OAAM,KAAK,0BAA0B,IAAIA,OAAM,IAAI,wBAAwB,CAAC;AACxF,YAAQ,IAAIA,OAAM,KAAK,0BAA0B,IAAIA,OAAM,IAAI,oBAAoB,CAAC;AACpF,YAAQ,IAAIA,OAAM,KAAK,uBAAuB,IAAIA,OAAM,IAAI,mBAAmB,CAAC;AAChF,YAAQ,IAAIA,OAAM,KAAK,uBAAuB,IAAIA,OAAM,IAAI,gBAAgB,CAAC;AAC7E,YAAQ,IAAIA,OAAM,KAAK,wBAAwB,IAAIA,OAAM,IAAI,mBAAmB,CAAC;AACjF,YAAQ,IAAIA,OAAM,KAAK,+BAA+B,IAAIA,OAAM,IAAI,qBAAqB,CAAC;AAC1F,YAAQ,IAAIA,OAAM,IAAI,iDAAiD,CAAC;AACxE,YAAQ,IAAI;AAAA,EACb,CAAC;AACH;;;AGtFA,OAAOE,YAAW;AAKX,SAAS,wBAAwBC,UAAwB;AAC/D,EAAAA,SACE,QAAQ,qBAAqB,EAC7B,YAAY,0CAA0C,EACtD,OAAO,aAAa,4BAA4B,EAChD,OAAO,aAAa,0BAA0B,EAC9C,OAAO,OAAO,OAAiB,YAA8C;AAE7E,QAAI,QAAQ,KAAK;AAChB,YAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAgBC,QAAO,UAAU;AAC/E,UAAI,QAAQ,SAAS,GAAG;AACvB,gBAAQ,MAAMC,OAAM,IAAI,qBAAqB,CAAC;AAC9C,mBAAW,QAAQ,SAAS;AAC3B,kBAAQ,MAAMA,OAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,QACvC;AAAA,MACD;AACA,UAAI,MAAM,WAAW,GAAG;AACvB,gBAAQ,KAAK,CAAC;AAAA,MACf;AACA,YAAM,SAAS,MAAeC,QAAO,MAAM,CAAC,CAAC;AAC7C,cAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,IAC5B;AAEA,UAAMC,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IAChB;AACA,YAAQ,KAAKA,WAAU,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH;;;ACnCA,OAAOC,YAAW;AAKX,SAAS,sBAAsBC,UAAwB;AAC7D,EAAAA,SACE,QAAQ,eAAe,EACvB,YAAY,2CAA2C,EACvD,OAAO,aAAa,mBAAmB,EACvC,OAAO,OAAO,SAAiB;AAC/B,UAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,CAAC,IAAI,GAAG,WAAW,OAAO,UAAU;AAClF,QAAI,QAAQ,SAAS,GAAG;AACvB,cAAQ,MAAMC,OAAM,IAAI,sBAAsB,IAAI,EAAE,CAAC;AACrD,cAAQ,MAAMA,OAAM,OAAO,cAAc,WAAW,OAAO,WAAW,KAAK,IAAI,CAAC,EAAE,CAAC;AACnF,cAAQ,KAAK,CAAC;AAAA,IACf;AACA,UAAM,SAAS,MAAM,WAAW,OAAO,MAAM,CAAC,CAAC;AAC/C,YAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,EAC5B,CAAC;AACH;;;ACpBA,OAAOC,aAAW;AAKX,SAAS,uBAAuBC,UAAwB;AAC9D,EAAAA,SACE,QAAQ,oBAAoB,EAC5B,MAAM,eAAe,EACrB,YAAY,gCAAgC,EAC5C,OAAO,aAAa,4BAA4B,EAChD,OAAO,aAAa,qBAAqB,EACzC,OAAO,OAAO,OAAiB,YAA8C;AAC7E,QAAI,QAAQ,KAAK;AAChB,YAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAeC,QAAO,UAAU;AAC9E,UAAI,QAAQ,SAAS,GAAG;AACvB,gBAAQ,MAAMC,QAAM,IAAI,qBAAqB,CAAC;AAC9C,mBAAW,QAAQ,SAAS;AAC3B,kBAAQ,MAAMA,QAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,QACvC;AAAA,MACD;AACA,UAAI,MAAM,WAAW,GAAG;AACvB,gBAAQ,KAAK,CAAC;AAAA,MACf;AACA,YAAM,SAAS,MAAcC,QAAO,MAAM,CAAC,CAAC;AAC5C,cAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,IAC5B;AAEA,UAAMC,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IAChB;AACA,YAAQ,KAAKA,WAAU,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH;;;ACnCA,OAAOC,aAAW;AAMX,SAAS,wBAAwBC,UAAwB;AAC/D,EAAAA,SACE,QAAQ,sBAAsB,EAC9B,MAAM,UAAU,EAChB,YAAY,oCAAoC,EAChD,OAAO,aAAa,4BAA4B,EAChD,OAAO,aAAa,oCAAoC,EACxD,OAAO,wBAAwB,oCAAoC,EACnE,OAAO,cAAc,wCAAwC,EAC7D,OAAO,aAAa,+BAA+B,EACnD,OAAO,wBAAwB,oCAAoC,EACnE,OAAO,gBAAgB,iCAAiC,EACxD,OAAO,OAAO,OAAiB,YAAwH;AAEvJ,QAAI,QAAQ,KAAK;AAChB,YAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAgBC,QAAO,UAAU;AAC/E,UAAI,QAAQ,SAAS,GAAG;AACvB,gBAAQ,MAAMC,QAAM,IAAI,qBAAqB,CAAC;AAC9C,mBAAW,QAAQ,SAAS;AAC3B,kBAAQ,MAAMA,QAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,QACvC;AAAA,MACD;AACA,UAAI,MAAM,WAAW,GAAG;AACvB,gBAAQ,KAAK,CAAC;AAAA,MACf;AAEA,YAAM,SAAS,MAAeC,QAAO,MAAM,CAAC,CAAC;AAC7C,cAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,IAC5B;AAGA,QAAI,QAAQ,SAAS,QAAW;AAC/B,mBAAa,EAAE,QAAQ,OAAO,QAAQ,IAAI,EAAE,CAAC;AAAA,IAC9C;AACA,QAAI,QAAQ,SAAS,QAAW;AAC/B,mBAAa,EAAE,QAAQ,QAAQ,KAAK,CAAC;AAAA,IACtC;AACA,QAAI,QAAQ,eAAe;AAC1B,mBAAa,EAAE,kBAAkB,KAAK,CAAC;AAAA,IACxC;AACA,QAAI,QAAQ,QAAQ;AACnB,mBAAa,EAAE,UAAU,KAAK,CAAC;AAAA,IAChC;AAEA,UAAMC,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IAChB;AACA,mBAAe;AACf,YAAQ,KAAKA,WAAU,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH;;;AC1DA,OAAOC,aAAW;AAKX,SAAS,qBAAqBC,UAAwB;AAC5D,EAAAA,SACE,QAAQ,kBAAkB,EAC1B,MAAM,SAAS,EACf,YAAY,oCAAoC,EAChD,OAAO,aAAa,4BAA4B,EAChD,OAAO,aAAa,qBAAqB,EACzC,OAAO,OAAO,OAAiB,YAA8C;AAE7E,QAAI,QAAQ,KAAK;AAChB,YAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAeC,QAAO,UAAU;AAC9E,UAAI,QAAQ,SAAS,GAAG;AACvB,gBAAQ,MAAMC,QAAM,IAAI,qBAAqB,CAAC;AAC9C,mBAAW,QAAQ,SAAS;AAC3B,kBAAQ,MAAMA,QAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,QACvC;AAAA,MACD;AACA,UAAI,MAAM,WAAW,GAAG;AACvB,gBAAQ,KAAK,CAAC;AAAA,MACf;AACA,YAAM,SAAS,MAAcC,QAAO,MAAM,CAAC,CAAC;AAC5C,cAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,IAC5B;AAEA,UAAMC,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IAChB;AACA,YAAQ,KAAKA,WAAU,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH;;;ACpCA,OAAOC,aAAW;AAKX,SAAS,yBAAyBC,UAAwB;AAChE,EAAAA,SACE,QAAQ,sBAAsB,EAC9B,YAAY,8DAA8D,EAC1E,OAAO,aAAa,4BAA4B,EAChD,OAAO,aAAa,qBAAqB,EACzC,OAAO,OAAO,OAAiB,YAA8C;AAE7E,QAAI,QAAQ,KAAK;AAChB,YAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAiBC,SAAO,UAAU;AAChF,UAAI,QAAQ,SAAS,GAAG;AACvB,gBAAQ,MAAMC,QAAM,IAAI,qBAAqB,CAAC;AAC9C,mBAAW,QAAQ,SAAS;AAC3B,kBAAQ,MAAMA,QAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,QACvC;AAAA,MACD;AACA,UAAI,MAAM,WAAW,GAAG;AACvB,gBAAQ,KAAK,CAAC;AAAA,MACf;AACA,YAAM,SAAS,MAAgBC,SAAO,MAAM,CAAC,CAAC;AAC9C,cAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,IAC5B;AAEA,UAAMC,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IAChB;AACA,YAAQ,KAAKA,WAAU,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH;;;ACnCA,OAAOC,aAAW;AAKX,SAAS,yBAAyBC,UAAwB;AAChE,EAAAA,SACE,QAAQ,sBAAsB,EAC9B,MAAM,MAAM,EACZ,YAAY,uBAAuB,EACnC,OAAO,aAAa,4BAA4B,EAChD,OAAO,aAAa,qBAAqB,EACzC,OAAO,OAAO,OAAiB,YAA8C;AAC7E,QAAI,QAAQ,KAAK;AAChB,YAAM,EAAE,OAAO,QAAQ,IAAI,mBAAmB,OAAiBC,SAAO,UAAU;AAChF,UAAI,QAAQ,SAAS,GAAG;AACvB,gBAAQ,MAAMC,QAAM,IAAI,qBAAqB,CAAC;AAC9C,mBAAW,QAAQ,SAAS;AAC3B,kBAAQ,MAAMA,QAAM,IAAI,OAAO,IAAI,EAAE,CAAC;AAAA,QACvC;AAAA,MACD;AACA,UAAI,MAAM,WAAW,GAAG;AACvB,gBAAQ,KAAK,CAAC;AAAA,MACf;AACA,YAAM,SAAS,MAAgBC,SAAO,MAAM,CAAC,CAAC;AAC9C,cAAQ,KAAK,SAAS,IAAI,CAAC;AAAA,IAC5B;AAEA,UAAMC,WAAU,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,IAChB;AACA,YAAQ,KAAKA,WAAU,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH;;;ACnCA,OAAOC,aAAW;AAOX,SAAS,yBAAyBC,UAAwB;AAChE,EAAAA,SACE,QAAQ,WAAW,EACnB,YAAY,+CAA+C,EAC3D,OAAO,YAAY;AACnB,eAAW;AACX,YAAQ,IAAIC,QAAM,KAAK,mBAAmB,CAAC;AAE3C,QAAI,CAAC,MAAM,GAAG;AACb,cAAQ;AAAA,QACPA,QAAM,OAAO,iDAAiD;AAAA,MAC/D;AACA,cAAQ;AAAA,QACPA,QAAM;AAAA,UACL;AAAA,QACD;AAAA,MACD;AACA;AAAA,IACD;AAEA,QAAI,CAAC,oBAAoB,GAAG;AAC3B,cAAQ,IAAIA,QAAM,OAAO,0DAA0D,CAAC;AAEpF,YAAM,UAAU,MAAM,yBAAyB;AAC/C,YAAM,UAAU,aAAa,OAAO;AAEpC,cAAQ,IAAIA,QAAM,MAAM,2CAAsC,CAAC;AAC/D,cAAQ,IAAIA,QAAM,KAAK,KAAK,OAAO;AAAA,CAAI,CAAC;AACxC,cAAQ,IAAIA,QAAM,KAAK,uBAAuB,CAAC;AAC/C,cAAQ,IAAIA,QAAM,IAAI,qDAAqD,CAAC;AAC5E,cAAQ,IAAIA,QAAM,IAAI,gDAAgD,OAAO,GAAG,CAAC;AACjF,cAAQ,IAAI;AACZ;AAAA,IACD;AAGA,YAAQ,IAAIA,QAAM,IAAI,iCAAiC,CAAC;AACxD,UAAM,eAAe,MAAM,qBAAqB;AAEhD,QAAI,aAAa,QAAQ,SAAS,GAAG;AACpC,cAAQ,IAAIA,QAAM,OAAO,WAAW,aAAa,QAAQ,MAAM,kBAAkB,CAAC;AAClF,iBAAW,SAAS,aAAa,SAAS;AACzC,gBAAQ,IAAI,KAAKA,QAAM,MAAM,QAAG,CAAC,IAAI,KAAK,EAAE;AAAA,MAC7C;AACA,cAAQ,IAAI;AAAA,IACb;AAGA,UAAM,UAAU,MAAM,mBAAmB;AACzC,UAAM,eAAe,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAEtD,eAAW,UAAU,SAAS;AAC7B,UAAI,OAAO,SAAS;AACnB,gBAAQ;AAAA,UACP,GAAGA,QAAM,MAAM,QAAG,CAAC,aAAa,OAAO,SAAS,WAAM,OAAO,QAAQ;AAAA,QACtE;AAAA,MACD,OAAO;AACN,gBAAQ;AAAA,UACP,GAAGA,QAAM,KAAK,GAAG,CAAC,aAAa,OAAO,SAAS,WAAM,OAAO,QAAQ;AAAA,QACrE;AAAA,MACD;AAAA,IACD;AAEA,UAAM,eAAe,eAAe,aAAa,QAAQ;AACzD,YAAQ,IAAI;AACZ,YAAQ;AAAA,MACPA,QAAM;AAAA,QACL,oCAA+B,YAAY;AAAA,MAC5C;AAAA,IACD;AACA,YAAQ,IAAIA,QAAM,IAAI,8BAA8B,CAAC;AAAA,EACtD,CAAC;AACH;;;AtC5DO,SAAS,WAAiB;AAChC,aAAW;AAEX,QAAM,MAAMC,QAAM;AAClB,QAAM,MAAMA,QAAM;AAClB,QAAM,MAAMA,QAAM;AAClB,QAAM,MAAMA,QAAM;AAClB,QAAM,OAAOA,QAAM,MAAM;AAEzB,UAAQ;AAAA,IACP,KAAK,KAAK,QAAQ,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,IAAI,WAAW,CAAC;AAAA,EACpF;AACA,UAAQ,IAAI;AACZ,UAAQ,IAAI,KAAK,WAAW,CAAC;AAC7B,UAAQ;AAAA,IACP,OAAO,IAAI,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACtC;AACA,UAAQ,IAAI;AACZ,UAAQ,IAAI,KAAK,oBAAoB,CAAC;AACtC,UAAQ;AAAA,IACP,OAAO,IAAI,UAAU,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACxC;AACA,UAAQ;AAAA,IACP,OAAO,IAAI,WAAW,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACzC;AACA,UAAQ;AAAA,IACP,OAAO,IAAI,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACrC;AACA,UAAQ;AAAA,IACP,OAAO,IAAI,WAAW,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACzC;AACA,UAAQ;AAAA,IACP,OAAO,IAAI,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACtC;AACA,UAAQ;AAAA,IACP,OAAO,IAAI,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACtC;AACA,UAAQ;AAAA,IACP,OAAO,IAAI,SAAS,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACvC;AACA,UAAQ;AAAA,IACP,OAAO,IAAI,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACtC;AACA,UAAQ;AAAA,IACP,OAAO,IAAI,UAAU,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACxC;AACA,UAAQ;AAAA,IACP,OAAO,IAAI,WAAW,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,EACzC;AACA,UAAQ,IAAI;AACZ,UAAQ,IAAI,KAAK,SAAS,CAAC;AAC3B,UAAQ;AAAA,IACP,OAAO,IAAI,SAAS,CAAC;AAAA,EACtB;AACA,UAAQ,IAAI,OAAO,IAAI,WAAW,CAAC,qCAAqC;AACxE,UAAQ,IAAI;AACZ,UAAQ,IAAI,KAAK,UAAU,CAAC;AAC5B,UAAQ,IAAI,OAAO,IAAI,QAAQ,CAAC,yCAAyC;AACzE,UAAQ,IAAI,OAAO,IAAI,cAAc,CAAC,2BAA2B;AACjE,UAAQ,IAAI;AACZ,UAAQ,IAAI,KAAK,YAAY,CAAC;AAC9B,UAAQ,IAAI,OAAO,IAAI,GAAG,CAAC,WAAW,IAAI,QAAQ,CAAC,IAAI,IAAI,WAAW,CAAC,YAAY,IAAI,2BAA2B,CAAC,EAAE;AACrH,UAAQ,IAAI,OAAO,IAAI,GAAG,CAAC,WAAW,IAAI,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,WAAW,IAAI,eAAe,CAAC,EAAE;AACzG,UAAQ,IAAI,OAAO,IAAI,GAAG,CAAC,WAAW,IAAI,UAAU,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,IAAI,uBAAuB,CAAC,EAAE;AAC3H,UAAQ,IAAI,OAAO,IAAI,GAAG,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,IAAI,WAAW,CAAC,SAAS,IAAI,uBAAuB,CAAC,EAAE;AACjH,UAAQ,IAAI,OAAO,IAAI,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC,aAAa,IAAI,sBAAsB,CAAC,EAAE;AAChH,UAAQ,IAAI,OAAO,IAAI,GAAG,CAAC,WAAW,IAAI,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC,EAAE;AACrH,UAAQ,IAAI;AACZ,UAAQ,IAAI,KAAK,gBAAgB,CAAC;AAClC,UAAQ,IAAI,yCAAyC;AACrD,UAAQ,IAAI,iDAAiD;AAC7D,UAAQ,IAAI;AACb;AAEO,SAAS,gBAAyB;AACxC,QAAMC,WAAU,IAAI,QAAQ;AAG5B,EAAAA,SAAQ,kBAAkB,MAAM;AAChC,EAAAA,SAAQ,GAAG,UAAU,MAAM;AAAA,EAAC,CAAC;AAE7B,EAAAA,SACE,KAAK,QAAQ,EACb,YAAY,mEAAmE,EAC/E,QAAQ,OAAO,EACf,OAAO,MAAM;AACb,aAAS;AAAA,EACV,CAAC;AAGF,sBAAoBA,QAAO;AAC3B,yBAAuBA,QAAO;AAC9B,2BAAyBA,QAAO;AAChC,0BAAwBA,QAAO;AAC/B,0BAAwBA,QAAO;AAC/B,uBAAqBA,QAAO;AAC5B,2BAAyBA,QAAO;AAChC,wBAAsBA,QAAO;AAC7B,wBAAsBA,QAAO;AAC7B,yBAAuBA,QAAO;AAC9B,+BAA6BA,QAAO;AACpC,0BAAwBA,QAAO;AAC/B,2BAAyBA,QAAO;AAChC,wBAAsBA,QAAO;AAC7B,wBAAsBA,QAAO;AAE7B,SAAOA;AACR;;;ADzHA,IAAM,UAAU,cAAc;AAE9B,QAAQ,WAAW,QAAQ,IAAI,EAAE,MAAM,CAACC,WAAU;AACjD,UAAQ,MAAMC,QAAM,IAAI,UAAUD,OAAM,OAAO,EAAE,CAAC;AAClD,UAAQ,KAAK,CAAC;AACf,CAAC;","names":["chalk","chalk","chalk","existsSync","readFileSync","basename","join","dirname","join","config","config","config","__dirname","dirname","resolve","join","existsSync","mkdirSync","dirname","dirname","existsSync","mkdirSync","count","dirname","success","existsSync","basename","join","readFileSync","extname","dirname","fileURLToPath","existsSync","mkdirSync","readFileSync","tmpdir","basename","join","run","existsSync","mkdirSync","runGUI","basename","tmpdir","join","readFileSync","config","existsSync","readFileSync","tmpdir","basename","join","processImage","success","collectOptionsCLI","run","existsSync","runGUI","basename","generatePreview","tmpdir","join","readFileSync","config","existsSync","mkdirSync","basename","dirname","dirname","existsSync","mkdirSync","run","runGUI","basename","config","existsSync","readFileSync","tmpdir","basename","join","run","existsSync","generatePreview","tmpdir","join","readFileSync","runGUI","basename","success","config","existsSync","mkdirSync","readFileSync","writeFileSync","tmpdir","basename","dirname","extname","join","tmpdir","join","dims","previewPath","buffer","readFileSync","finalDims","success","basename","mkdirSync","dirname","runGUI","existsSync","generateFramePreview","extname","writeFileSync","config","existsSync","readFileSync","tmpdir","basename","join","processImage","success","collectOptionsCLI","run","existsSync","runGUI","basename","generatePreview","tmpdir","join","readFileSync","config","existsSync","readFileSync","renameSync","tmpdir","basename","join","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","homedir","dirname","existsSync","mkdirSync","writeFileSync","processImage","renameSync","collectOptionsCLI","run","existsSync","runGUI","config","basename","generatePreview","success","tmpdir","join","readFileSync","existsSync","readFileSync","tmpdir","basename","join","run","existsSync","runGUI","basename","generatePreview","tmpdir","join","readFileSync","config","existsSync","mkdirSync","basename","join","join","run","existsSync","mkdirSync","runGUI","basename","config","existsSync","readFileSync","tmpdir","basename","join","processImage","success","collectOptionsCLI","run","existsSync","runGUI","basename","generatePreview","tmpdir","join","readFileSync","config","config","run","runGUI","config","fileURLToPath","dirname","extname","success","program","chalk","success","chalk","program","config","chalk","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","program","chalk","program","config","chalk","runGUI","success","chalk","exec","existsSync","dirname","fileURLToPath","promisify","execAsync","execAsync","error","join","config","success","join","program","chalk","config","chalk","program","config","chalk","runGUI","success","chalk","program","chalk","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","chalk","program","config","chalk","runGUI","success","chalk","program","chalk","chalk","program","error","chalk"]}
|