grok-image-cli 0.3.0 → 0.3.1
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/main.mjs +5 -1
- package/dist/main.mjs.map +1 -1
- package/package.json +1 -1
package/dist/main.mjs
CHANGED
|
@@ -314,6 +314,10 @@ var KeyStoreChain = class {
|
|
|
314
314
|
}
|
|
315
315
|
};
|
|
316
316
|
|
|
317
|
+
//#endregion
|
|
318
|
+
//#region package.json
|
|
319
|
+
var version = "0.3.1";
|
|
320
|
+
|
|
317
321
|
//#endregion
|
|
318
322
|
//#region src/presentation/commands/auth.command.ts
|
|
319
323
|
function readInput(prompt) {
|
|
@@ -490,7 +494,7 @@ function createGenerateCommand(generateUseCase) {
|
|
|
490
494
|
//#endregion
|
|
491
495
|
//#region src/presentation/cli.ts
|
|
492
496
|
function createCli(useCases) {
|
|
493
|
-
const program = new Command().name("grok-img").description("CLI for generating and editing images with Grok API").version(
|
|
497
|
+
const program = new Command().name("grok-img").description("CLI for generating and editing images with Grok API").version(version);
|
|
494
498
|
program.addCommand(createAuthCommand({
|
|
495
499
|
login: useCases.login,
|
|
496
500
|
logout: useCases.logout,
|
package/dist/main.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.mjs","names":["VALID_MODELS","VALID_RATIOS"],"sources":["../src/domain/errors.ts","../src/application/usecases/edit-image.usecase.ts","../src/application/usecases/generate-image.usecase.ts","../src/application/usecases/get-auth-status.usecase.ts","../src/application/usecases/login.usecase.ts","../src/application/usecases/logout.usecase.ts","../src/infrastructure/adapters/env-key-store.adapter.ts","../src/infrastructure/adapters/file-storage.adapter.ts","../src/infrastructure/adapters/grok-api.adapter.ts","../src/infrastructure/adapters/keychain.adapter.ts","../src/infrastructure/adapters/pass.adapter.ts","../src/infrastructure/key-store-chain.ts","../src/presentation/commands/auth.command.ts","../src/presentation/commands/edit.command.ts","../src/presentation/commands/generate.command.ts","../src/presentation/cli.ts","../src/main.ts"],"sourcesContent":["export class ApiKeyMissingError extends Error {\n constructor() {\n super(\n \"API key not found. Run `grok-img auth login` or set XAI_API_KEY environment variable.\",\n )\n this.name = \"ApiKeyMissingError\"\n }\n}\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public readonly cause?: unknown,\n ) {\n super(message)\n this.name = \"ApiError\"\n }\n}\n\nexport class ImageNotFoundError extends Error {\n constructor(path: string) {\n super(`Image not found: ${path}`)\n this.name = \"ImageNotFoundError\"\n }\n}\n","import type { EditParams } from \"../../domain/entities/edit-params.js\"\nimport { ApiKeyMissingError } from \"../../domain/errors.js\"\nimport type { FileStoragePort } from \"../../domain/ports/file-storage.port.js\"\nimport type { ImageGeneratorPort } from \"../../domain/ports/image-generator.port.js\"\nimport type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport class EditImageUseCase {\n constructor(\n private readonly imageGenerator: ImageGeneratorPort,\n private readonly keyStore: KeyStorePort,\n private readonly fileStorage: FileStoragePort,\n ) {}\n\n async execute(params: EditParams, outputDir: string): Promise<string> {\n const apiKey = await this.keyStore.get()\n if (!apiKey) throw new ApiKeyMissingError()\n\n let imageSource = params.imageSource\n if (typeof imageSource === \"string\" && !imageSource.startsWith(\"http\")) {\n imageSource = await this.fileStorage.readImage(imageSource)\n }\n\n this.fileStorage.ensureDir(outputDir)\n\n const result = await this.imageGenerator.edit({ ...params, imageSource }, apiKey)\n\n const outputPath = this.fileStorage.generateOutputPath(outputDir, 0, result.mediaType)\n return this.fileStorage.saveImage(result.uint8Array, outputPath)\n }\n}\n","import type { GenerateParams } from \"../../domain/entities/generate-params.js\"\nimport { ApiKeyMissingError } from \"../../domain/errors.js\"\nimport type { FileStoragePort } from \"../../domain/ports/file-storage.port.js\"\nimport type { ImageGeneratorPort } from \"../../domain/ports/image-generator.port.js\"\nimport type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport class GenerateImageUseCase {\n constructor(\n private readonly imageGenerator: ImageGeneratorPort,\n private readonly keyStore: KeyStorePort,\n private readonly fileStorage: FileStoragePort,\n ) {}\n\n async execute(params: GenerateParams, outputDir: string): Promise<string[]> {\n const apiKey = await this.keyStore.get()\n if (!apiKey) throw new ApiKeyMissingError()\n\n this.fileStorage.ensureDir(outputDir)\n\n const results = await this.imageGenerator.generate(params, apiKey)\n\n const savedPaths: string[] = []\n for (let i = 0; i < results.length; i++) {\n const result = results[i]\n const outputPath = this.fileStorage.generateOutputPath(\n outputDir,\n i,\n result.mediaType,\n )\n const saved = await this.fileStorage.saveImage(result.uint8Array, outputPath)\n savedPaths.push(saved)\n }\n\n return savedPaths\n }\n}\n","import type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport type AuthStatus = {\n authenticated: boolean\n maskedKey: string | null\n source: \"credential-store\" | \"env\" | null\n}\n\nexport class GetAuthStatusUseCase {\n constructor(private readonly keyStore: KeyStorePort) {}\n\n async execute(): Promise<AuthStatus> {\n const key = await this.keyStore.get()\n\n if (!key) {\n return { authenticated: false, maskedKey: null, source: null }\n }\n\n const masked =\n key.length > 8\n ? `${key.slice(0, 4)}${\"*\".repeat(key.length - 8)}${key.slice(-4)}`\n : \"****\"\n\n const source = process.env.XAI_API_KEY === key ? \"env\" : \"credential-store\"\n\n return { authenticated: true, maskedKey: masked, source }\n }\n}\n","import type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport class LoginUseCase {\n constructor(private readonly keyStore: KeyStorePort) {}\n\n async execute(apiKey: string): Promise<void> {\n await this.keyStore.save(apiKey)\n }\n}\n","import type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport class LogoutUseCase {\n constructor(private readonly keyStore: KeyStorePort) {}\n\n async execute(): Promise<void> {\n await this.keyStore.remove()\n }\n}\n","import type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport class EnvKeyStoreAdapter implements KeyStorePort {\n async get(): Promise<string | null> {\n return process.env.XAI_API_KEY ?? null\n }\n\n async save(_key: string): Promise<void> {\n throw new Error(\"XAI_API_KEY is a read-only environment variable\")\n }\n\n async remove(): Promise<void> {\n // no-op: environment variables cannot be deleted programmatically\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\nimport { ImageNotFoundError } from \"../../domain/errors.js\"\nimport type { FileStoragePort } from \"../../domain/ports/file-storage.port.js\"\n\nconst MEDIA_TYPE_EXT: Record<string, string> = {\n \"image/png\": \"png\",\n \"image/jpeg\": \"jpg\",\n \"image/webp\": \"webp\",\n \"image/gif\": \"gif\",\n}\n\nexport class FileStorageAdapter implements FileStoragePort {\n async saveImage(data: Uint8Array, outputPath: string): Promise<string> {\n writeFileSync(outputPath, data)\n return outputPath\n }\n\n async readImage(filePath: string): Promise<Uint8Array> {\n if (!existsSync(filePath)) {\n throw new ImageNotFoundError(filePath)\n }\n return new Uint8Array(readFileSync(filePath))\n }\n\n ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n }\n\n generateOutputPath(dir: string, index: number, mediaType: string): string {\n const ext = MEDIA_TYPE_EXT[mediaType] ?? \"png\"\n const timestamp = Date.now()\n return join(dir, `grok-img-${timestamp}-${index}.${ext}`)\n }\n}\n","import { createXai } from \"@ai-sdk/xai\"\nimport { generateImage, NoImageGeneratedError } from \"ai\"\nimport type { EditParams } from \"../../domain/entities/edit-params.js\"\nimport type { GenerateParams } from \"../../domain/entities/generate-params.js\"\nimport type { ImageResult } from \"../../domain/entities/image-result.js\"\nimport { ApiError } from \"../../domain/errors.js\"\nimport type { ImageGeneratorPort } from \"../../domain/ports/image-generator.port.js\"\n\nconst DEFAULT_MODEL = \"grok-imagine-image\"\n\nexport class GrokApiAdapter implements ImageGeneratorPort {\n async generate(params: GenerateParams, apiKey: string): Promise<ImageResult[]> {\n const xai = createXai({ apiKey })\n\n try {\n const { images } = await generateImage({\n model: xai.image(params.model ?? DEFAULT_MODEL),\n prompt: params.prompt,\n aspectRatio: params.aspectRatio as `${number}:${number}`,\n n: params.count,\n })\n\n return images.map((img) => ({\n base64: img.base64,\n uint8Array: img.uint8Array,\n mediaType: img.mediaType,\n }))\n } catch (error) {\n if (NoImageGeneratedError.isInstance(error)) {\n throw new ApiError(\n \"Image generation failed: the model could not produce an image.\",\n error,\n )\n }\n if (error instanceof Error) {\n throw new ApiError(`API request failed: ${error.message}`, error)\n }\n throw new ApiError(\"An unexpected error occurred during image generation.\", error)\n }\n }\n\n async edit(params: EditParams, apiKey: string): Promise<ImageResult> {\n const xai = createXai({ apiKey })\n\n try {\n const { image } = await generateImage({\n model: xai.image(params.model ?? DEFAULT_MODEL),\n prompt: {\n text: params.prompt,\n images: [params.imageSource],\n },\n aspectRatio: params.aspectRatio as `${number}:${number}`,\n })\n\n return {\n base64: image.base64,\n uint8Array: image.uint8Array,\n mediaType: image.mediaType,\n }\n } catch (error) {\n if (NoImageGeneratedError.isInstance(error)) {\n throw new ApiError(\n \"Image editing failed: the model could not produce an image.\",\n error,\n )\n }\n if (error instanceof Error) {\n throw new ApiError(`API request failed: ${error.message}`, error)\n }\n throw new ApiError(\"An unexpected error occurred during image editing.\", error)\n }\n }\n}\n","import { deletePassword, getPassword, setPassword } from \"cross-keychain\"\nimport type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nconst SERVICE = \"grok-image-cli\"\nconst ACCOUNT = \"api-key\"\n\nexport class KeychainAdapter implements KeyStorePort {\n async save(key: string): Promise<void> {\n await setPassword(SERVICE, ACCOUNT, key)\n }\n\n async get(): Promise<string | null> {\n const key = await getPassword(SERVICE, ACCOUNT)\n return key ?? null\n }\n\n async remove(): Promise<void> {\n await deletePassword(SERVICE, ACCOUNT)\n }\n}\n","import { execFileSync } from \"node:child_process\"\nimport type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nconst SECRET_PATH = \"grok-image-cli/api-key\"\n\nfunction detectTool(): string | null {\n for (const tool of [\"gopass\", \"pass\"]) {\n try {\n execFileSync(\"which\", [tool], { stdio: \"ignore\" })\n return tool\n } catch {}\n }\n return null\n}\n\nconst tool = detectTool()\n\nexport class PassAdapter implements KeyStorePort {\n async save(key: string): Promise<void> {\n if (!tool) throw new Error(\"Neither gopass nor pass is installed\")\n\n const args =\n tool === \"gopass\"\n ? [\"insert\", \"-f\", SECRET_PATH]\n : [\"insert\", \"-m\", \"--force\", SECRET_PATH]\n\n execFileSync(tool, args, { input: `${key}\\n`, stdio: [\"pipe\", \"ignore\", \"ignore\"] })\n }\n\n async get(): Promise<string | null> {\n if (!tool) throw new Error(\"Neither gopass nor pass is installed\")\n\n try {\n const output = execFileSync(tool, [\"show\", SECRET_PATH], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n return output.trim().split(\"\\n\")[0] ?? null\n } catch {\n return null\n }\n }\n\n async remove(): Promise<void> {\n if (!tool) throw new Error(\"Neither gopass nor pass is installed\")\n\n try {\n execFileSync(tool, [\"rm\", \"--force\", SECRET_PATH], { stdio: \"ignore\" })\n } catch {}\n }\n}\n","import type { KeyStorePort } from \"../domain/ports/key-store.port.js\"\n\ntype NamedStore = { store: KeyStorePort; name: string }\n\nexport class KeyStoreChain implements KeyStorePort {\n constructor(\n private readonly stores: ReadonlyArray<NamedStore>,\n private readonly onSave?: (storeName: string) => void,\n ) {}\n\n async save(key: string): Promise<void> {\n let lastError: unknown\n for (const { store, name } of this.stores) {\n try {\n await store.save(key)\n this.onSave?.(name)\n return\n } catch (e) {\n lastError = e\n }\n }\n throw lastError\n }\n\n async get(): Promise<string | null> {\n for (const { store } of this.stores) {\n try {\n const key = await store.get()\n if (key) return key\n } catch {}\n }\n return null\n }\n\n async remove(): Promise<void> {\n for (const { store } of this.stores) {\n try {\n await store.remove()\n } catch {}\n }\n }\n}\n","import { createInterface } from \"node:readline\"\nimport chalk from \"chalk\"\nimport { Command } from \"commander\"\nimport type { GetAuthStatusUseCase } from \"../../application/usecases/get-auth-status.usecase.js\"\nimport type { LoginUseCase } from \"../../application/usecases/login.usecase.js\"\nimport type { LogoutUseCase } from \"../../application/usecases/logout.usecase.js\"\n\nfunction readInput(prompt: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n })\n\n return new Promise((resolve) => {\n rl.question(prompt, (answer) => {\n rl.close()\n resolve(answer.trim())\n })\n })\n}\n\nexport function createAuthCommand(useCases: {\n login: LoginUseCase\n logout: LogoutUseCase\n getStatus: GetAuthStatusUseCase\n}): Command {\n const auth = new Command(\"auth\").description(\"Manage API key authentication\")\n\n auth\n .command(\"login\")\n .description(\"Store your xAI API key in the system credential store\")\n .action(async () => {\n try {\n const apiKey = await readInput(chalk.cyan(\"Enter your xAI API key: \"))\n\n if (!apiKey) {\n console.log(chalk.red(\"No API key provided.\"))\n process.exit(1)\n }\n\n await useCases.login.execute(apiKey)\n console.log(chalk.green(\"API key saved successfully.\"))\n } catch (error) {\n console.error(\n chalk.red(\n `Failed to save API key: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n )\n process.exit(1)\n }\n })\n\n auth\n .command(\"logout\")\n .description(\"Remove your xAI API key from the system credential store\")\n .action(async () => {\n try {\n await useCases.logout.execute()\n console.log(chalk.green(\"API key removed successfully.\"))\n } catch (error) {\n console.error(\n chalk.red(\n `Failed to remove API key: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n )\n process.exit(1)\n }\n })\n\n auth\n .command(\"status\")\n .description(\"Check current authentication status\")\n .action(async () => {\n try {\n const status = await useCases.getStatus.execute()\n\n if (status.authenticated) {\n console.log(chalk.green(\"Authenticated\"))\n console.log(chalk.dim(` Key: ${status.maskedKey}`))\n console.log(chalk.dim(` Source: ${status.source}`))\n } else {\n console.log(chalk.yellow(\"Not authenticated\"))\n console.log(\n chalk.dim(\n \" Run `grok-img auth login` or set XAI_API_KEY environment variable.\",\n ),\n )\n }\n } catch (error) {\n console.error(\n chalk.red(\n `Failed to check status: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n )\n process.exit(1)\n }\n })\n\n return auth\n}\n","import { resolve } from \"node:path\"\nimport chalk from \"chalk\"\nimport { Command } from \"commander\"\nimport ora from \"ora\"\nimport type { EditImageUseCase } from \"../../application/usecases/edit-image.usecase.js\"\nimport type { Model } from \"../../domain/entities/generate-params.js\"\nimport { ApiError, ApiKeyMissingError, ImageNotFoundError } from \"../../domain/errors.js\"\n\nconst VALID_MODELS: Model[] = [\n \"grok-2-image-1212\",\n \"grok-imagine-image-pro\",\n \"grok-imagine-image\",\n]\n\nconst VALID_RATIOS = [\n \"1:1\",\n \"16:9\",\n \"9:16\",\n \"4:3\",\n \"3:4\",\n \"3:2\",\n \"2:3\",\n \"2:1\",\n \"1:2\",\n \"19.5:9\",\n \"9:19.5\",\n \"20:9\",\n \"9:20\",\n \"auto\",\n]\n\nexport function createEditCommand(editUseCase: EditImageUseCase): Command {\n return new Command(\"edit\")\n .description(\"Edit an existing image with a text prompt\")\n .argument(\"<prompt>\", \"Text prompt describing the edit to apply\")\n .requiredOption(\"-i, --image <path>\", \"Source image (local file path or URL)\")\n .option(\"-m, --model <model>\", \"Model to use\", \"grok-imagine-image\")\n .option(\"-a, --aspect-ratio <ratio>\", \"Aspect ratio\", \"auto\")\n .option(\"-o, --output <dir>\", \"Output directory\", \"./grok-images\")\n .action(async (prompt: string, options) => {\n if (!VALID_MODELS.includes(options.model)) {\n console.error(\n chalk.red(`Invalid model. Valid options: ${VALID_MODELS.join(\", \")}`),\n )\n process.exit(1)\n }\n\n if (!VALID_RATIOS.includes(options.aspectRatio)) {\n console.error(\n chalk.red(`Invalid aspect ratio. Valid options: ${VALID_RATIOS.join(\", \")}`),\n )\n process.exit(1)\n }\n\n const imageSource = options.image.startsWith(\"http\")\n ? options.image\n : resolve(options.image)\n\n const outputDir = resolve(options.output)\n const spinner = ora(\"Editing image...\").start()\n\n try {\n const savedPath = await editUseCase.execute(\n { prompt, imageSource, aspectRatio: options.aspectRatio, model: options.model },\n outputDir,\n )\n\n spinner.succeed(chalk.green(\"Image edited successfully:\"))\n console.log(chalk.dim(` ${savedPath}`))\n } catch (error) {\n spinner.fail()\n if (error instanceof ApiKeyMissingError) {\n console.error(chalk.red(error.message))\n } else if (error instanceof ImageNotFoundError) {\n console.error(chalk.red(error.message))\n } else if (error instanceof ApiError) {\n console.error(chalk.red(`API Error: ${error.message}`))\n } else {\n console.error(\n chalk.red(\n `Unexpected error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n )\n }\n process.exit(1)\n }\n })\n}\n","import { resolve } from \"node:path\"\nimport chalk from \"chalk\"\nimport { Command } from \"commander\"\nimport ora from \"ora\"\nimport type { GenerateImageUseCase } from \"../../application/usecases/generate-image.usecase.js\"\nimport type { Model } from \"../../domain/entities/generate-params.js\"\nimport { ApiError, ApiKeyMissingError } from \"../../domain/errors.js\"\n\nconst VALID_MODELS: Model[] = [\n \"grok-2-image-1212\",\n \"grok-imagine-image-pro\",\n \"grok-imagine-image\",\n]\n\nconst VALID_RATIOS = [\n \"1:1\",\n \"16:9\",\n \"9:16\",\n \"4:3\",\n \"3:4\",\n \"3:2\",\n \"2:3\",\n \"2:1\",\n \"1:2\",\n \"19.5:9\",\n \"9:19.5\",\n \"20:9\",\n \"9:20\",\n \"auto\",\n]\n\nexport function createGenerateCommand(generateUseCase: GenerateImageUseCase): Command {\n return new Command(\"generate\")\n .description(\"Generate images from a text prompt\")\n .argument(\"<prompt>\", \"Text prompt describing the image to generate\")\n .option(\"-m, --model <model>\", \"Model to use\", \"grok-imagine-image\")\n .option(\"-a, --aspect-ratio <ratio>\", \"Aspect ratio\", \"auto\")\n .option(\"-n, --count <number>\", \"Number of images (1-10)\", \"1\")\n .option(\"-o, --output <dir>\", \"Output directory\", \"./grok-images\")\n .action(async (prompt: string, options) => {\n const count = parseInt(options.count, 10)\n if (Number.isNaN(count) || count < 1 || count > 10) {\n console.error(chalk.red(\"Count must be a number between 1 and 10.\"))\n process.exit(1)\n }\n\n if (!VALID_MODELS.includes(options.model)) {\n console.error(\n chalk.red(`Invalid model. Valid options: ${VALID_MODELS.join(\", \")}`),\n )\n process.exit(1)\n }\n\n if (!VALID_RATIOS.includes(options.aspectRatio)) {\n console.error(\n chalk.red(`Invalid aspect ratio. Valid options: ${VALID_RATIOS.join(\", \")}`),\n )\n process.exit(1)\n }\n\n const outputDir = resolve(options.output)\n const spinner = ora(`Generating ${count} image${count > 1 ? \"s\" : \"\"}...`).start()\n\n try {\n const paths = await generateUseCase.execute(\n { prompt, count, aspectRatio: options.aspectRatio, model: options.model },\n outputDir,\n )\n\n spinner.succeed(\n chalk.green(`Generated ${paths.length} image${paths.length > 1 ? \"s\" : \"\"}:`),\n )\n for (const p of paths) {\n console.log(chalk.dim(` ${p}`))\n }\n } catch (error) {\n spinner.fail()\n if (error instanceof ApiKeyMissingError) {\n console.error(chalk.red(error.message))\n } else if (error instanceof ApiError) {\n console.error(chalk.red(`API Error: ${error.message}`))\n } else {\n console.error(\n chalk.red(\n `Unexpected error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n )\n }\n process.exit(1)\n }\n })\n}\n","import { Command } from \"commander\"\nimport type { EditImageUseCase } from \"../application/usecases/edit-image.usecase.js\"\nimport type { GenerateImageUseCase } from \"../application/usecases/generate-image.usecase.js\"\nimport type { GetAuthStatusUseCase } from \"../application/usecases/get-auth-status.usecase.js\"\nimport type { LoginUseCase } from \"../application/usecases/login.usecase.js\"\nimport type { LogoutUseCase } from \"../application/usecases/logout.usecase.js\"\nimport { createAuthCommand } from \"./commands/auth.command.js\"\nimport { createEditCommand } from \"./commands/edit.command.js\"\nimport { createGenerateCommand } from \"./commands/generate.command.js\"\n\nexport type UseCases = {\n generateImage: GenerateImageUseCase\n editImage: EditImageUseCase\n login: LoginUseCase\n logout: LogoutUseCase\n getAuthStatus: GetAuthStatusUseCase\n}\n\nexport function createCli(useCases: UseCases): Command {\n const program = new Command()\n .name(\"grok-img\")\n .description(\"CLI for generating and editing images with Grok API\")\n .version(\"1.0.0\")\n\n program.addCommand(\n createAuthCommand({\n login: useCases.login,\n logout: useCases.logout,\n getStatus: useCases.getAuthStatus,\n }),\n )\n\n program.addCommand(createGenerateCommand(useCases.generateImage))\n program.addCommand(createEditCommand(useCases.editImage))\n\n return program\n}\n","import chalk from \"chalk\"\nimport { EditImageUseCase } from \"./application/usecases/edit-image.usecase.js\"\nimport { GenerateImageUseCase } from \"./application/usecases/generate-image.usecase.js\"\nimport { GetAuthStatusUseCase } from \"./application/usecases/get-auth-status.usecase.js\"\nimport { LoginUseCase } from \"./application/usecases/login.usecase.js\"\nimport { LogoutUseCase } from \"./application/usecases/logout.usecase.js\"\nimport { EnvKeyStoreAdapter } from \"./infrastructure/adapters/env-key-store.adapter.js\"\nimport { FileStorageAdapter } from \"./infrastructure/adapters/file-storage.adapter.js\"\nimport { GrokApiAdapter } from \"./infrastructure/adapters/grok-api.adapter.js\"\nimport { KeychainAdapter } from \"./infrastructure/adapters/keychain.adapter.js\"\nimport { PassAdapter } from \"./infrastructure/adapters/pass.adapter.js\"\nimport { KeyStoreChain } from \"./infrastructure/key-store-chain.js\"\nimport { createCli } from \"./presentation/cli.js\"\n\nconst keyStore = new KeyStoreChain(\n [\n { store: new KeychainAdapter(), name: \"Keychain\" },\n { store: new PassAdapter(), name: \"pass\" },\n { store: new EnvKeyStoreAdapter(), name: \"XAI_API_KEY\" },\n ],\n (name) => console.log(chalk.dim(`Key stored in: ${name}`)),\n)\nconst imageGenerator = new GrokApiAdapter()\nconst fileStorage = new FileStorageAdapter()\n\nconst generateImageUseCase = new GenerateImageUseCase(\n imageGenerator,\n keyStore,\n fileStorage,\n)\nconst editImageUseCase = new EditImageUseCase(imageGenerator, keyStore, fileStorage)\nconst loginUseCase = new LoginUseCase(keyStore)\nconst logoutUseCase = new LogoutUseCase(keyStore)\nconst getAuthStatusUseCase = new GetAuthStatusUseCase(keyStore)\n\nconst program = createCli({\n generateImage: generateImageUseCase,\n editImage: editImageUseCase,\n login: loginUseCase,\n logout: logoutUseCase,\n getAuthStatus: getAuthStatusUseCase,\n})\n\nprogram.parse()\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"main.mjs","names":["VALID_MODELS","VALID_RATIOS","pkg.version"],"sources":["../src/domain/errors.ts","../src/application/usecases/edit-image.usecase.ts","../src/application/usecases/generate-image.usecase.ts","../src/application/usecases/get-auth-status.usecase.ts","../src/application/usecases/login.usecase.ts","../src/application/usecases/logout.usecase.ts","../src/infrastructure/adapters/env-key-store.adapter.ts","../src/infrastructure/adapters/file-storage.adapter.ts","../src/infrastructure/adapters/grok-api.adapter.ts","../src/infrastructure/adapters/keychain.adapter.ts","../src/infrastructure/adapters/pass.adapter.ts","../src/infrastructure/key-store-chain.ts","../package.json","../src/presentation/commands/auth.command.ts","../src/presentation/commands/edit.command.ts","../src/presentation/commands/generate.command.ts","../src/presentation/cli.ts","../src/main.ts"],"sourcesContent":["export class ApiKeyMissingError extends Error {\n constructor() {\n super(\n \"API key not found. Run `grok-img auth login` or set XAI_API_KEY environment variable.\",\n )\n this.name = \"ApiKeyMissingError\"\n }\n}\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public readonly cause?: unknown,\n ) {\n super(message)\n this.name = \"ApiError\"\n }\n}\n\nexport class ImageNotFoundError extends Error {\n constructor(path: string) {\n super(`Image not found: ${path}`)\n this.name = \"ImageNotFoundError\"\n }\n}\n","import type { EditParams } from \"../../domain/entities/edit-params.js\"\nimport { ApiKeyMissingError } from \"../../domain/errors.js\"\nimport type { FileStoragePort } from \"../../domain/ports/file-storage.port.js\"\nimport type { ImageGeneratorPort } from \"../../domain/ports/image-generator.port.js\"\nimport type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport class EditImageUseCase {\n constructor(\n private readonly imageGenerator: ImageGeneratorPort,\n private readonly keyStore: KeyStorePort,\n private readonly fileStorage: FileStoragePort,\n ) {}\n\n async execute(params: EditParams, outputDir: string): Promise<string> {\n const apiKey = await this.keyStore.get()\n if (!apiKey) throw new ApiKeyMissingError()\n\n let imageSource = params.imageSource\n if (typeof imageSource === \"string\" && !imageSource.startsWith(\"http\")) {\n imageSource = await this.fileStorage.readImage(imageSource)\n }\n\n this.fileStorage.ensureDir(outputDir)\n\n const result = await this.imageGenerator.edit({ ...params, imageSource }, apiKey)\n\n const outputPath = this.fileStorage.generateOutputPath(outputDir, 0, result.mediaType)\n return this.fileStorage.saveImage(result.uint8Array, outputPath)\n }\n}\n","import type { GenerateParams } from \"../../domain/entities/generate-params.js\"\nimport { ApiKeyMissingError } from \"../../domain/errors.js\"\nimport type { FileStoragePort } from \"../../domain/ports/file-storage.port.js\"\nimport type { ImageGeneratorPort } from \"../../domain/ports/image-generator.port.js\"\nimport type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport class GenerateImageUseCase {\n constructor(\n private readonly imageGenerator: ImageGeneratorPort,\n private readonly keyStore: KeyStorePort,\n private readonly fileStorage: FileStoragePort,\n ) {}\n\n async execute(params: GenerateParams, outputDir: string): Promise<string[]> {\n const apiKey = await this.keyStore.get()\n if (!apiKey) throw new ApiKeyMissingError()\n\n this.fileStorage.ensureDir(outputDir)\n\n const results = await this.imageGenerator.generate(params, apiKey)\n\n const savedPaths: string[] = []\n for (let i = 0; i < results.length; i++) {\n const result = results[i]\n const outputPath = this.fileStorage.generateOutputPath(\n outputDir,\n i,\n result.mediaType,\n )\n const saved = await this.fileStorage.saveImage(result.uint8Array, outputPath)\n savedPaths.push(saved)\n }\n\n return savedPaths\n }\n}\n","import type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport type AuthStatus = {\n authenticated: boolean\n maskedKey: string | null\n source: \"credential-store\" | \"env\" | null\n}\n\nexport class GetAuthStatusUseCase {\n constructor(private readonly keyStore: KeyStorePort) {}\n\n async execute(): Promise<AuthStatus> {\n const key = await this.keyStore.get()\n\n if (!key) {\n return { authenticated: false, maskedKey: null, source: null }\n }\n\n const masked =\n key.length > 8\n ? `${key.slice(0, 4)}${\"*\".repeat(key.length - 8)}${key.slice(-4)}`\n : \"****\"\n\n const source = process.env.XAI_API_KEY === key ? \"env\" : \"credential-store\"\n\n return { authenticated: true, maskedKey: masked, source }\n }\n}\n","import type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport class LoginUseCase {\n constructor(private readonly keyStore: KeyStorePort) {}\n\n async execute(apiKey: string): Promise<void> {\n await this.keyStore.save(apiKey)\n }\n}\n","import type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport class LogoutUseCase {\n constructor(private readonly keyStore: KeyStorePort) {}\n\n async execute(): Promise<void> {\n await this.keyStore.remove()\n }\n}\n","import type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nexport class EnvKeyStoreAdapter implements KeyStorePort {\n async get(): Promise<string | null> {\n return process.env.XAI_API_KEY ?? null\n }\n\n async save(_key: string): Promise<void> {\n throw new Error(\"XAI_API_KEY is a read-only environment variable\")\n }\n\n async remove(): Promise<void> {\n // no-op: environment variables cannot be deleted programmatically\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\nimport { ImageNotFoundError } from \"../../domain/errors.js\"\nimport type { FileStoragePort } from \"../../domain/ports/file-storage.port.js\"\n\nconst MEDIA_TYPE_EXT: Record<string, string> = {\n \"image/png\": \"png\",\n \"image/jpeg\": \"jpg\",\n \"image/webp\": \"webp\",\n \"image/gif\": \"gif\",\n}\n\nexport class FileStorageAdapter implements FileStoragePort {\n async saveImage(data: Uint8Array, outputPath: string): Promise<string> {\n writeFileSync(outputPath, data)\n return outputPath\n }\n\n async readImage(filePath: string): Promise<Uint8Array> {\n if (!existsSync(filePath)) {\n throw new ImageNotFoundError(filePath)\n }\n return new Uint8Array(readFileSync(filePath))\n }\n\n ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n }\n\n generateOutputPath(dir: string, index: number, mediaType: string): string {\n const ext = MEDIA_TYPE_EXT[mediaType] ?? \"png\"\n const timestamp = Date.now()\n return join(dir, `grok-img-${timestamp}-${index}.${ext}`)\n }\n}\n","import { createXai } from \"@ai-sdk/xai\"\nimport { generateImage, NoImageGeneratedError } from \"ai\"\nimport type { EditParams } from \"../../domain/entities/edit-params.js\"\nimport type { GenerateParams } from \"../../domain/entities/generate-params.js\"\nimport type { ImageResult } from \"../../domain/entities/image-result.js\"\nimport { ApiError } from \"../../domain/errors.js\"\nimport type { ImageGeneratorPort } from \"../../domain/ports/image-generator.port.js\"\n\nconst DEFAULT_MODEL = \"grok-imagine-image\"\n\nexport class GrokApiAdapter implements ImageGeneratorPort {\n async generate(params: GenerateParams, apiKey: string): Promise<ImageResult[]> {\n const xai = createXai({ apiKey })\n\n try {\n const { images } = await generateImage({\n model: xai.image(params.model ?? DEFAULT_MODEL),\n prompt: params.prompt,\n aspectRatio: params.aspectRatio as `${number}:${number}`,\n n: params.count,\n })\n\n return images.map((img) => ({\n base64: img.base64,\n uint8Array: img.uint8Array,\n mediaType: img.mediaType,\n }))\n } catch (error) {\n if (NoImageGeneratedError.isInstance(error)) {\n throw new ApiError(\n \"Image generation failed: the model could not produce an image.\",\n error,\n )\n }\n if (error instanceof Error) {\n throw new ApiError(`API request failed: ${error.message}`, error)\n }\n throw new ApiError(\"An unexpected error occurred during image generation.\", error)\n }\n }\n\n async edit(params: EditParams, apiKey: string): Promise<ImageResult> {\n const xai = createXai({ apiKey })\n\n try {\n const { image } = await generateImage({\n model: xai.image(params.model ?? DEFAULT_MODEL),\n prompt: {\n text: params.prompt,\n images: [params.imageSource],\n },\n aspectRatio: params.aspectRatio as `${number}:${number}`,\n })\n\n return {\n base64: image.base64,\n uint8Array: image.uint8Array,\n mediaType: image.mediaType,\n }\n } catch (error) {\n if (NoImageGeneratedError.isInstance(error)) {\n throw new ApiError(\n \"Image editing failed: the model could not produce an image.\",\n error,\n )\n }\n if (error instanceof Error) {\n throw new ApiError(`API request failed: ${error.message}`, error)\n }\n throw new ApiError(\"An unexpected error occurred during image editing.\", error)\n }\n }\n}\n","import { deletePassword, getPassword, setPassword } from \"cross-keychain\"\nimport type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nconst SERVICE = \"grok-image-cli\"\nconst ACCOUNT = \"api-key\"\n\nexport class KeychainAdapter implements KeyStorePort {\n async save(key: string): Promise<void> {\n await setPassword(SERVICE, ACCOUNT, key)\n }\n\n async get(): Promise<string | null> {\n const key = await getPassword(SERVICE, ACCOUNT)\n return key ?? null\n }\n\n async remove(): Promise<void> {\n await deletePassword(SERVICE, ACCOUNT)\n }\n}\n","import { execFileSync } from \"node:child_process\"\nimport type { KeyStorePort } from \"../../domain/ports/key-store.port.js\"\n\nconst SECRET_PATH = \"grok-image-cli/api-key\"\n\nfunction detectTool(): string | null {\n for (const tool of [\"gopass\", \"pass\"]) {\n try {\n execFileSync(\"which\", [tool], { stdio: \"ignore\" })\n return tool\n } catch {}\n }\n return null\n}\n\nconst tool = detectTool()\n\nexport class PassAdapter implements KeyStorePort {\n async save(key: string): Promise<void> {\n if (!tool) throw new Error(\"Neither gopass nor pass is installed\")\n\n const args =\n tool === \"gopass\"\n ? [\"insert\", \"-f\", SECRET_PATH]\n : [\"insert\", \"-m\", \"--force\", SECRET_PATH]\n\n execFileSync(tool, args, { input: `${key}\\n`, stdio: [\"pipe\", \"ignore\", \"ignore\"] })\n }\n\n async get(): Promise<string | null> {\n if (!tool) throw new Error(\"Neither gopass nor pass is installed\")\n\n try {\n const output = execFileSync(tool, [\"show\", SECRET_PATH], {\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n return output.trim().split(\"\\n\")[0] ?? null\n } catch {\n return null\n }\n }\n\n async remove(): Promise<void> {\n if (!tool) throw new Error(\"Neither gopass nor pass is installed\")\n\n try {\n execFileSync(tool, [\"rm\", \"--force\", SECRET_PATH], { stdio: \"ignore\" })\n } catch {}\n }\n}\n","import type { KeyStorePort } from \"../domain/ports/key-store.port.js\"\n\ntype NamedStore = { store: KeyStorePort; name: string }\n\nexport class KeyStoreChain implements KeyStorePort {\n constructor(\n private readonly stores: ReadonlyArray<NamedStore>,\n private readonly onSave?: (storeName: string) => void,\n ) {}\n\n async save(key: string): Promise<void> {\n let lastError: unknown\n for (const { store, name } of this.stores) {\n try {\n await store.save(key)\n this.onSave?.(name)\n return\n } catch (e) {\n lastError = e\n }\n }\n throw lastError\n }\n\n async get(): Promise<string | null> {\n for (const { store } of this.stores) {\n try {\n const key = await store.get()\n if (key) return key\n } catch {}\n }\n return null\n }\n\n async remove(): Promise<void> {\n for (const { store } of this.stores) {\n try {\n await store.remove()\n } catch {}\n }\n }\n}\n","","import { createInterface } from \"node:readline\"\nimport chalk from \"chalk\"\nimport { Command } from \"commander\"\nimport type { GetAuthStatusUseCase } from \"../../application/usecases/get-auth-status.usecase.js\"\nimport type { LoginUseCase } from \"../../application/usecases/login.usecase.js\"\nimport type { LogoutUseCase } from \"../../application/usecases/logout.usecase.js\"\n\nfunction readInput(prompt: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n })\n\n return new Promise((resolve) => {\n rl.question(prompt, (answer) => {\n rl.close()\n resolve(answer.trim())\n })\n })\n}\n\nexport function createAuthCommand(useCases: {\n login: LoginUseCase\n logout: LogoutUseCase\n getStatus: GetAuthStatusUseCase\n}): Command {\n const auth = new Command(\"auth\").description(\"Manage API key authentication\")\n\n auth\n .command(\"login\")\n .description(\"Store your xAI API key in the system credential store\")\n .action(async () => {\n try {\n const apiKey = await readInput(chalk.cyan(\"Enter your xAI API key: \"))\n\n if (!apiKey) {\n console.log(chalk.red(\"No API key provided.\"))\n process.exit(1)\n }\n\n await useCases.login.execute(apiKey)\n console.log(chalk.green(\"API key saved successfully.\"))\n } catch (error) {\n console.error(\n chalk.red(\n `Failed to save API key: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n )\n process.exit(1)\n }\n })\n\n auth\n .command(\"logout\")\n .description(\"Remove your xAI API key from the system credential store\")\n .action(async () => {\n try {\n await useCases.logout.execute()\n console.log(chalk.green(\"API key removed successfully.\"))\n } catch (error) {\n console.error(\n chalk.red(\n `Failed to remove API key: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n )\n process.exit(1)\n }\n })\n\n auth\n .command(\"status\")\n .description(\"Check current authentication status\")\n .action(async () => {\n try {\n const status = await useCases.getStatus.execute()\n\n if (status.authenticated) {\n console.log(chalk.green(\"Authenticated\"))\n console.log(chalk.dim(` Key: ${status.maskedKey}`))\n console.log(chalk.dim(` Source: ${status.source}`))\n } else {\n console.log(chalk.yellow(\"Not authenticated\"))\n console.log(\n chalk.dim(\n \" Run `grok-img auth login` or set XAI_API_KEY environment variable.\",\n ),\n )\n }\n } catch (error) {\n console.error(\n chalk.red(\n `Failed to check status: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n )\n process.exit(1)\n }\n })\n\n return auth\n}\n","import { resolve } from \"node:path\"\nimport chalk from \"chalk\"\nimport { Command } from \"commander\"\nimport ora from \"ora\"\nimport type { EditImageUseCase } from \"../../application/usecases/edit-image.usecase.js\"\nimport type { Model } from \"../../domain/entities/generate-params.js\"\nimport { ApiError, ApiKeyMissingError, ImageNotFoundError } from \"../../domain/errors.js\"\n\nconst VALID_MODELS: Model[] = [\n \"grok-2-image-1212\",\n \"grok-imagine-image-pro\",\n \"grok-imagine-image\",\n]\n\nconst VALID_RATIOS = [\n \"1:1\",\n \"16:9\",\n \"9:16\",\n \"4:3\",\n \"3:4\",\n \"3:2\",\n \"2:3\",\n \"2:1\",\n \"1:2\",\n \"19.5:9\",\n \"9:19.5\",\n \"20:9\",\n \"9:20\",\n \"auto\",\n]\n\nexport function createEditCommand(editUseCase: EditImageUseCase): Command {\n return new Command(\"edit\")\n .description(\"Edit an existing image with a text prompt\")\n .argument(\"<prompt>\", \"Text prompt describing the edit to apply\")\n .requiredOption(\"-i, --image <path>\", \"Source image (local file path or URL)\")\n .option(\"-m, --model <model>\", \"Model to use\", \"grok-imagine-image\")\n .option(\"-a, --aspect-ratio <ratio>\", \"Aspect ratio\", \"auto\")\n .option(\"-o, --output <dir>\", \"Output directory\", \"./grok-images\")\n .action(async (prompt: string, options) => {\n if (!VALID_MODELS.includes(options.model)) {\n console.error(\n chalk.red(`Invalid model. Valid options: ${VALID_MODELS.join(\", \")}`),\n )\n process.exit(1)\n }\n\n if (!VALID_RATIOS.includes(options.aspectRatio)) {\n console.error(\n chalk.red(`Invalid aspect ratio. Valid options: ${VALID_RATIOS.join(\", \")}`),\n )\n process.exit(1)\n }\n\n const imageSource = options.image.startsWith(\"http\")\n ? options.image\n : resolve(options.image)\n\n const outputDir = resolve(options.output)\n const spinner = ora(\"Editing image...\").start()\n\n try {\n const savedPath = await editUseCase.execute(\n { prompt, imageSource, aspectRatio: options.aspectRatio, model: options.model },\n outputDir,\n )\n\n spinner.succeed(chalk.green(\"Image edited successfully:\"))\n console.log(chalk.dim(` ${savedPath}`))\n } catch (error) {\n spinner.fail()\n if (error instanceof ApiKeyMissingError) {\n console.error(chalk.red(error.message))\n } else if (error instanceof ImageNotFoundError) {\n console.error(chalk.red(error.message))\n } else if (error instanceof ApiError) {\n console.error(chalk.red(`API Error: ${error.message}`))\n } else {\n console.error(\n chalk.red(\n `Unexpected error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n )\n }\n process.exit(1)\n }\n })\n}\n","import { resolve } from \"node:path\"\nimport chalk from \"chalk\"\nimport { Command } from \"commander\"\nimport ora from \"ora\"\nimport type { GenerateImageUseCase } from \"../../application/usecases/generate-image.usecase.js\"\nimport type { Model } from \"../../domain/entities/generate-params.js\"\nimport { ApiError, ApiKeyMissingError } from \"../../domain/errors.js\"\n\nconst VALID_MODELS: Model[] = [\n \"grok-2-image-1212\",\n \"grok-imagine-image-pro\",\n \"grok-imagine-image\",\n]\n\nconst VALID_RATIOS = [\n \"1:1\",\n \"16:9\",\n \"9:16\",\n \"4:3\",\n \"3:4\",\n \"3:2\",\n \"2:3\",\n \"2:1\",\n \"1:2\",\n \"19.5:9\",\n \"9:19.5\",\n \"20:9\",\n \"9:20\",\n \"auto\",\n]\n\nexport function createGenerateCommand(generateUseCase: GenerateImageUseCase): Command {\n return new Command(\"generate\")\n .description(\"Generate images from a text prompt\")\n .argument(\"<prompt>\", \"Text prompt describing the image to generate\")\n .option(\"-m, --model <model>\", \"Model to use\", \"grok-imagine-image\")\n .option(\"-a, --aspect-ratio <ratio>\", \"Aspect ratio\", \"auto\")\n .option(\"-n, --count <number>\", \"Number of images (1-10)\", \"1\")\n .option(\"-o, --output <dir>\", \"Output directory\", \"./grok-images\")\n .action(async (prompt: string, options) => {\n const count = parseInt(options.count, 10)\n if (Number.isNaN(count) || count < 1 || count > 10) {\n console.error(chalk.red(\"Count must be a number between 1 and 10.\"))\n process.exit(1)\n }\n\n if (!VALID_MODELS.includes(options.model)) {\n console.error(\n chalk.red(`Invalid model. Valid options: ${VALID_MODELS.join(\", \")}`),\n )\n process.exit(1)\n }\n\n if (!VALID_RATIOS.includes(options.aspectRatio)) {\n console.error(\n chalk.red(`Invalid aspect ratio. Valid options: ${VALID_RATIOS.join(\", \")}`),\n )\n process.exit(1)\n }\n\n const outputDir = resolve(options.output)\n const spinner = ora(`Generating ${count} image${count > 1 ? \"s\" : \"\"}...`).start()\n\n try {\n const paths = await generateUseCase.execute(\n { prompt, count, aspectRatio: options.aspectRatio, model: options.model },\n outputDir,\n )\n\n spinner.succeed(\n chalk.green(`Generated ${paths.length} image${paths.length > 1 ? \"s\" : \"\"}:`),\n )\n for (const p of paths) {\n console.log(chalk.dim(` ${p}`))\n }\n } catch (error) {\n spinner.fail()\n if (error instanceof ApiKeyMissingError) {\n console.error(chalk.red(error.message))\n } else if (error instanceof ApiError) {\n console.error(chalk.red(`API Error: ${error.message}`))\n } else {\n console.error(\n chalk.red(\n `Unexpected error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n ),\n )\n }\n process.exit(1)\n }\n })\n}\n","import { Command } from \"commander\"\nimport pkg from \"../../package.json\" with { type: \"json\" }\nimport type { EditImageUseCase } from \"../application/usecases/edit-image.usecase.js\"\nimport type { GenerateImageUseCase } from \"../application/usecases/generate-image.usecase.js\"\nimport type { GetAuthStatusUseCase } from \"../application/usecases/get-auth-status.usecase.js\"\nimport type { LoginUseCase } from \"../application/usecases/login.usecase.js\"\nimport type { LogoutUseCase } from \"../application/usecases/logout.usecase.js\"\nimport { createAuthCommand } from \"./commands/auth.command.js\"\nimport { createEditCommand } from \"./commands/edit.command.js\"\nimport { createGenerateCommand } from \"./commands/generate.command.js\"\n\nexport type UseCases = {\n generateImage: GenerateImageUseCase\n editImage: EditImageUseCase\n login: LoginUseCase\n logout: LogoutUseCase\n getAuthStatus: GetAuthStatusUseCase\n}\n\nexport function createCli(useCases: UseCases): Command {\n const program = new Command()\n .name(\"grok-img\")\n .description(\"CLI for generating and editing images with Grok API\")\n .version(pkg.version)\n\n program.addCommand(\n createAuthCommand({\n login: useCases.login,\n logout: useCases.logout,\n getStatus: useCases.getAuthStatus,\n }),\n )\n\n program.addCommand(createGenerateCommand(useCases.generateImage))\n program.addCommand(createEditCommand(useCases.editImage))\n\n return program\n}\n","import chalk from \"chalk\"\nimport { EditImageUseCase } from \"./application/usecases/edit-image.usecase.js\"\nimport { GenerateImageUseCase } from \"./application/usecases/generate-image.usecase.js\"\nimport { GetAuthStatusUseCase } from \"./application/usecases/get-auth-status.usecase.js\"\nimport { LoginUseCase } from \"./application/usecases/login.usecase.js\"\nimport { LogoutUseCase } from \"./application/usecases/logout.usecase.js\"\nimport { EnvKeyStoreAdapter } from \"./infrastructure/adapters/env-key-store.adapter.js\"\nimport { FileStorageAdapter } from \"./infrastructure/adapters/file-storage.adapter.js\"\nimport { GrokApiAdapter } from \"./infrastructure/adapters/grok-api.adapter.js\"\nimport { KeychainAdapter } from \"./infrastructure/adapters/keychain.adapter.js\"\nimport { PassAdapter } from \"./infrastructure/adapters/pass.adapter.js\"\nimport { KeyStoreChain } from \"./infrastructure/key-store-chain.js\"\nimport { createCli } from \"./presentation/cli.js\"\n\nconst keyStore = new KeyStoreChain(\n [\n { store: new KeychainAdapter(), name: \"Keychain\" },\n { store: new PassAdapter(), name: \"pass\" },\n { store: new EnvKeyStoreAdapter(), name: \"XAI_API_KEY\" },\n ],\n (name) => console.log(chalk.dim(`Key stored in: ${name}`)),\n)\nconst imageGenerator = new GrokApiAdapter()\nconst fileStorage = new FileStorageAdapter()\n\nconst generateImageUseCase = new GenerateImageUseCase(\n imageGenerator,\n keyStore,\n fileStorage,\n)\nconst editImageUseCase = new EditImageUseCase(imageGenerator, keyStore, fileStorage)\nconst loginUseCase = new LoginUseCase(keyStore)\nconst logoutUseCase = new LogoutUseCase(keyStore)\nconst getAuthStatusUseCase = new GetAuthStatusUseCase(keyStore)\n\nconst program = createCli({\n generateImage: generateImageUseCase,\n editImage: editImageUseCase,\n login: loginUseCase,\n logout: logoutUseCase,\n getAuthStatus: getAuthStatusUseCase,\n})\n\nprogram.parse()\n"],"mappings":";;;;;;;;;;;;;AAAA,IAAa,qBAAb,cAAwC,MAAM;CAC5C,cAAc;AACZ,QACE,wFACD;AACD,OAAK,OAAO;;;AAIhB,IAAa,WAAb,cAA8B,MAAM;CAClC,YACE,SACA,AAAgB,OAChB;AACA,QAAM,QAAQ;EAFE;AAGhB,OAAK,OAAO;;;AAIhB,IAAa,qBAAb,cAAwC,MAAM;CAC5C,YAAY,MAAc;AACxB,QAAM,oBAAoB,OAAO;AACjC,OAAK,OAAO;;;;;;AChBhB,IAAa,mBAAb,MAA8B;CAC5B,YACE,AAAiB,gBACjB,AAAiB,UACjB,AAAiB,aACjB;EAHiB;EACA;EACA;;CAGnB,MAAM,QAAQ,QAAoB,WAAoC;EACpE,MAAM,SAAS,MAAM,KAAK,SAAS,KAAK;AACxC,MAAI,CAAC,OAAQ,OAAM,IAAI,oBAAoB;EAE3C,IAAI,cAAc,OAAO;AACzB,MAAI,OAAO,gBAAgB,YAAY,CAAC,YAAY,WAAW,OAAO,CACpE,eAAc,MAAM,KAAK,YAAY,UAAU,YAAY;AAG7D,OAAK,YAAY,UAAU,UAAU;EAErC,MAAM,SAAS,MAAM,KAAK,eAAe,KAAK;GAAE,GAAG;GAAQ;GAAa,EAAE,OAAO;EAEjF,MAAM,aAAa,KAAK,YAAY,mBAAmB,WAAW,GAAG,OAAO,UAAU;AACtF,SAAO,KAAK,YAAY,UAAU,OAAO,YAAY,WAAW;;;;;;ACrBpE,IAAa,uBAAb,MAAkC;CAChC,YACE,AAAiB,gBACjB,AAAiB,UACjB,AAAiB,aACjB;EAHiB;EACA;EACA;;CAGnB,MAAM,QAAQ,QAAwB,WAAsC;EAC1E,MAAM,SAAS,MAAM,KAAK,SAAS,KAAK;AACxC,MAAI,CAAC,OAAQ,OAAM,IAAI,oBAAoB;AAE3C,OAAK,YAAY,UAAU,UAAU;EAErC,MAAM,UAAU,MAAM,KAAK,eAAe,SAAS,QAAQ,OAAO;EAElE,MAAM,aAAuB,EAAE;AAC/B,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,SAAS,QAAQ;GACvB,MAAM,aAAa,KAAK,YAAY,mBAClC,WACA,GACA,OAAO,UACR;GACD,MAAM,QAAQ,MAAM,KAAK,YAAY,UAAU,OAAO,YAAY,WAAW;AAC7E,cAAW,KAAK,MAAM;;AAGxB,SAAO;;;;;;ACzBX,IAAa,uBAAb,MAAkC;CAChC,YAAY,AAAiB,UAAwB;EAAxB;;CAE7B,MAAM,UAA+B;EACnC,MAAM,MAAM,MAAM,KAAK,SAAS,KAAK;AAErC,MAAI,CAAC,IACH,QAAO;GAAE,eAAe;GAAO,WAAW;GAAM,QAAQ;GAAM;AAUhE,SAAO;GAAE,eAAe;GAAM,WAN5B,IAAI,SAAS,IACT,GAAG,IAAI,MAAM,GAAG,EAAE,GAAG,IAAI,OAAO,IAAI,SAAS,EAAE,GAAG,IAAI,MAAM,GAAG,KAC/D;GAI2C,QAFlC,QAAQ,IAAI,gBAAgB,MAAM,QAAQ;GAEA;;;;;;ACvB7D,IAAa,eAAb,MAA0B;CACxB,YAAY,AAAiB,UAAwB;EAAxB;;CAE7B,MAAM,QAAQ,QAA+B;AAC3C,QAAM,KAAK,SAAS,KAAK,OAAO;;;;;;ACJpC,IAAa,gBAAb,MAA2B;CACzB,YAAY,AAAiB,UAAwB;EAAxB;;CAE7B,MAAM,UAAyB;AAC7B,QAAM,KAAK,SAAS,QAAQ;;;;;;ACJhC,IAAa,qBAAb,MAAwD;CACtD,MAAM,MAA8B;AAClC,SAAO,QAAQ,IAAI,eAAe;;CAGpC,MAAM,KAAK,MAA6B;AACtC,QAAM,IAAI,MAAM,kDAAkD;;CAGpE,MAAM,SAAwB;;;;;ACNhC,MAAM,iBAAyC;CAC7C,aAAa;CACb,cAAc;CACd,cAAc;CACd,aAAa;CACd;AAED,IAAa,qBAAb,MAA2D;CACzD,MAAM,UAAU,MAAkB,YAAqC;AACrE,gBAAc,YAAY,KAAK;AAC/B,SAAO;;CAGT,MAAM,UAAU,UAAuC;AACrD,MAAI,CAAC,WAAW,SAAS,CACvB,OAAM,IAAI,mBAAmB,SAAS;AAExC,SAAO,IAAI,WAAW,aAAa,SAAS,CAAC;;CAG/C,UAAU,KAAmB;AAC3B,MAAI,CAAC,WAAW,IAAI,CAClB,WAAU,KAAK,EAAE,WAAW,MAAM,CAAC;;CAIvC,mBAAmB,KAAa,OAAe,WAA2B;EACxE,MAAM,MAAM,eAAe,cAAc;AAEzC,SAAO,KAAK,KAAK,YADC,KAAK,KAAK,CACW,GAAG,MAAM,GAAG,MAAM;;;;;;AC1B7D,MAAM,gBAAgB;AAEtB,IAAa,iBAAb,MAA0D;CACxD,MAAM,SAAS,QAAwB,QAAwC;EAC7E,MAAM,MAAM,UAAU,EAAE,QAAQ,CAAC;AAEjC,MAAI;GACF,MAAM,EAAE,WAAW,MAAM,cAAc;IACrC,OAAO,IAAI,MAAM,OAAO,SAAS,cAAc;IAC/C,QAAQ,OAAO;IACf,aAAa,OAAO;IACpB,GAAG,OAAO;IACX,CAAC;AAEF,UAAO,OAAO,KAAK,SAAS;IAC1B,QAAQ,IAAI;IACZ,YAAY,IAAI;IAChB,WAAW,IAAI;IAChB,EAAE;WACI,OAAO;AACd,OAAI,sBAAsB,WAAW,MAAM,CACzC,OAAM,IAAI,SACR,kEACA,MACD;AAEH,OAAI,iBAAiB,MACnB,OAAM,IAAI,SAAS,uBAAuB,MAAM,WAAW,MAAM;AAEnE,SAAM,IAAI,SAAS,yDAAyD,MAAM;;;CAItF,MAAM,KAAK,QAAoB,QAAsC;EACnE,MAAM,MAAM,UAAU,EAAE,QAAQ,CAAC;AAEjC,MAAI;GACF,MAAM,EAAE,UAAU,MAAM,cAAc;IACpC,OAAO,IAAI,MAAM,OAAO,SAAS,cAAc;IAC/C,QAAQ;KACN,MAAM,OAAO;KACb,QAAQ,CAAC,OAAO,YAAY;KAC7B;IACD,aAAa,OAAO;IACrB,CAAC;AAEF,UAAO;IACL,QAAQ,MAAM;IACd,YAAY,MAAM;IAClB,WAAW,MAAM;IAClB;WACM,OAAO;AACd,OAAI,sBAAsB,WAAW,MAAM,CACzC,OAAM,IAAI,SACR,+DACA,MACD;AAEH,OAAI,iBAAiB,MACnB,OAAM,IAAI,SAAS,uBAAuB,MAAM,WAAW,MAAM;AAEnE,SAAM,IAAI,SAAS,sDAAsD,MAAM;;;;;;;AClErF,MAAM,UAAU;AAChB,MAAM,UAAU;AAEhB,IAAa,kBAAb,MAAqD;CACnD,MAAM,KAAK,KAA4B;AACrC,QAAM,YAAY,SAAS,SAAS,IAAI;;CAG1C,MAAM,MAA8B;AAElC,SADY,MAAM,YAAY,SAAS,QAAQ,IACjC;;CAGhB,MAAM,SAAwB;AAC5B,QAAM,eAAe,SAAS,QAAQ;;;;;;ACd1C,MAAM,cAAc;AAEpB,SAAS,aAA4B;AACnC,MAAK,MAAM,QAAQ,CAAC,UAAU,OAAO,CACnC,KAAI;AACF,eAAa,SAAS,CAAC,KAAK,EAAE,EAAE,OAAO,UAAU,CAAC;AAClD,SAAO;SACD;AAEV,QAAO;;AAGT,MAAM,OAAO,YAAY;AAEzB,IAAa,cAAb,MAAiD;CAC/C,MAAM,KAAK,KAA4B;AACrC,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,uCAAuC;AAOlE,eAAa,MAJX,SAAS,WACL;GAAC;GAAU;GAAM;GAAY,GAC7B;GAAC;GAAU;GAAM;GAAW;GAAY,EAErB;GAAE,OAAO,GAAG,IAAI;GAAK,OAAO;IAAC;IAAQ;IAAU;IAAS;GAAE,CAAC;;CAGtF,MAAM,MAA8B;AAClC,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,uCAAuC;AAElE,MAAI;AAKF,UAJe,aAAa,MAAM,CAAC,QAAQ,YAAY,EAAE;IACvD,UAAU;IACV,OAAO;KAAC;KAAU;KAAQ;KAAS;IACpC,CAAC,CACY,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM;UACjC;AACN,UAAO;;;CAIX,MAAM,SAAwB;AAC5B,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,uCAAuC;AAElE,MAAI;AACF,gBAAa,MAAM;IAAC;IAAM;IAAW;IAAY,EAAE,EAAE,OAAO,UAAU,CAAC;UACjE;;;;;;AC5CZ,IAAa,gBAAb,MAAmD;CACjD,YACE,AAAiB,QACjB,AAAiB,QACjB;EAFiB;EACA;;CAGnB,MAAM,KAAK,KAA4B;EACrC,IAAI;AACJ,OAAK,MAAM,EAAE,OAAO,UAAU,KAAK,OACjC,KAAI;AACF,SAAM,MAAM,KAAK,IAAI;AACrB,QAAK,SAAS,KAAK;AACnB;WACO,GAAG;AACV,eAAY;;AAGhB,QAAM;;CAGR,MAAM,MAA8B;AAClC,OAAK,MAAM,EAAE,WAAW,KAAK,OAC3B,KAAI;GACF,MAAM,MAAM,MAAM,MAAM,KAAK;AAC7B,OAAI,IAAK,QAAO;UACV;AAEV,SAAO;;CAGT,MAAM,SAAwB;AAC5B,OAAK,MAAM,EAAE,WAAW,KAAK,OAC3B,KAAI;AACF,SAAM,MAAM,QAAQ;UACd;;;;;;;;;;AE/Bd,SAAS,UAAU,QAAiC;CAClD,MAAM,KAAK,gBAAgB;EACzB,OAAO,QAAQ;EACf,QAAQ,QAAQ;EACjB,CAAC;AAEF,QAAO,IAAI,SAAS,YAAY;AAC9B,KAAG,SAAS,SAAS,WAAW;AAC9B,MAAG,OAAO;AACV,WAAQ,OAAO,MAAM,CAAC;IACtB;GACF;;AAGJ,SAAgB,kBAAkB,UAItB;CACV,MAAM,OAAO,IAAI,QAAQ,OAAO,CAAC,YAAY,gCAAgC;AAE7E,MACG,QAAQ,QAAQ,CAChB,YAAY,wDAAwD,CACpE,OAAO,YAAY;AAClB,MAAI;GACF,MAAM,SAAS,MAAM,UAAU,MAAM,KAAK,2BAA2B,CAAC;AAEtE,OAAI,CAAC,QAAQ;AACX,YAAQ,IAAI,MAAM,IAAI,uBAAuB,CAAC;AAC9C,YAAQ,KAAK,EAAE;;AAGjB,SAAM,SAAS,MAAM,QAAQ,OAAO;AACpC,WAAQ,IAAI,MAAM,MAAM,8BAA8B,CAAC;WAChD,OAAO;AACd,WAAQ,MACN,MAAM,IACJ,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,kBACrE,CACF;AACD,WAAQ,KAAK,EAAE;;GAEjB;AAEJ,MACG,QAAQ,SAAS,CACjB,YAAY,2DAA2D,CACvE,OAAO,YAAY;AAClB,MAAI;AACF,SAAM,SAAS,OAAO,SAAS;AAC/B,WAAQ,IAAI,MAAM,MAAM,gCAAgC,CAAC;WAClD,OAAO;AACd,WAAQ,MACN,MAAM,IACJ,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,kBACvE,CACF;AACD,WAAQ,KAAK,EAAE;;GAEjB;AAEJ,MACG,QAAQ,SAAS,CACjB,YAAY,sCAAsC,CAClD,OAAO,YAAY;AAClB,MAAI;GACF,MAAM,SAAS,MAAM,SAAS,UAAU,SAAS;AAEjD,OAAI,OAAO,eAAe;AACxB,YAAQ,IAAI,MAAM,MAAM,gBAAgB,CAAC;AACzC,YAAQ,IAAI,MAAM,IAAI,UAAU,OAAO,YAAY,CAAC;AACpD,YAAQ,IAAI,MAAM,IAAI,aAAa,OAAO,SAAS,CAAC;UAC/C;AACL,YAAQ,IAAI,MAAM,OAAO,oBAAoB,CAAC;AAC9C,YAAQ,IACN,MAAM,IACJ,uEACD,CACF;;WAEI,OAAO;AACd,WAAQ,MACN,MAAM,IACJ,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,kBACrE,CACF;AACD,WAAQ,KAAK,EAAE;;GAEjB;AAEJ,QAAO;;;;;AC1FT,MAAMA,iBAAwB;CAC5B;CACA;CACA;CACD;AAED,MAAMC,iBAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,kBAAkB,aAAwC;AACxE,QAAO,IAAI,QAAQ,OAAO,CACvB,YAAY,4CAA4C,CACxD,SAAS,YAAY,2CAA2C,CAChE,eAAe,sBAAsB,wCAAwC,CAC7E,OAAO,uBAAuB,gBAAgB,qBAAqB,CACnE,OAAO,8BAA8B,gBAAgB,OAAO,CAC5D,OAAO,sBAAsB,oBAAoB,gBAAgB,CACjE,OAAO,OAAO,QAAgB,YAAY;AACzC,MAAI,CAACD,eAAa,SAAS,QAAQ,MAAM,EAAE;AACzC,WAAQ,MACN,MAAM,IAAI,iCAAiCA,eAAa,KAAK,KAAK,GAAG,CACtE;AACD,WAAQ,KAAK,EAAE;;AAGjB,MAAI,CAACC,eAAa,SAAS,QAAQ,YAAY,EAAE;AAC/C,WAAQ,MACN,MAAM,IAAI,wCAAwCA,eAAa,KAAK,KAAK,GAAG,CAC7E;AACD,WAAQ,KAAK,EAAE;;EAGjB,MAAM,cAAc,QAAQ,MAAM,WAAW,OAAO,GAChD,QAAQ,QACR,QAAQ,QAAQ,MAAM;EAE1B,MAAM,YAAY,QAAQ,QAAQ,OAAO;EACzC,MAAM,UAAU,IAAI,mBAAmB,CAAC,OAAO;AAE/C,MAAI;GACF,MAAM,YAAY,MAAM,YAAY,QAClC;IAAE;IAAQ;IAAa,aAAa,QAAQ;IAAa,OAAO,QAAQ;IAAO,EAC/E,UACD;AAED,WAAQ,QAAQ,MAAM,MAAM,6BAA6B,CAAC;AAC1D,WAAQ,IAAI,MAAM,IAAI,KAAK,YAAY,CAAC;WACjC,OAAO;AACd,WAAQ,MAAM;AACd,OAAI,iBAAiB,mBACnB,SAAQ,MAAM,MAAM,IAAI,MAAM,QAAQ,CAAC;YAC9B,iBAAiB,mBAC1B,SAAQ,MAAM,MAAM,IAAI,MAAM,QAAQ,CAAC;YAC9B,iBAAiB,SAC1B,SAAQ,MAAM,MAAM,IAAI,cAAc,MAAM,UAAU,CAAC;OAEvD,SAAQ,MACN,MAAM,IACJ,qBAAqB,iBAAiB,QAAQ,MAAM,UAAU,kBAC/D,CACF;AAEH,WAAQ,KAAK,EAAE;;GAEjB;;;;;AC9EN,MAAM,eAAwB;CAC5B;CACA;CACA;CACD;AAED,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,sBAAsB,iBAAgD;AACpF,QAAO,IAAI,QAAQ,WAAW,CAC3B,YAAY,qCAAqC,CACjD,SAAS,YAAY,+CAA+C,CACpE,OAAO,uBAAuB,gBAAgB,qBAAqB,CACnE,OAAO,8BAA8B,gBAAgB,OAAO,CAC5D,OAAO,wBAAwB,2BAA2B,IAAI,CAC9D,OAAO,sBAAsB,oBAAoB,gBAAgB,CACjE,OAAO,OAAO,QAAgB,YAAY;EACzC,MAAM,QAAQ,SAAS,QAAQ,OAAO,GAAG;AACzC,MAAI,OAAO,MAAM,MAAM,IAAI,QAAQ,KAAK,QAAQ,IAAI;AAClD,WAAQ,MAAM,MAAM,IAAI,2CAA2C,CAAC;AACpE,WAAQ,KAAK,EAAE;;AAGjB,MAAI,CAAC,aAAa,SAAS,QAAQ,MAAM,EAAE;AACzC,WAAQ,MACN,MAAM,IAAI,iCAAiC,aAAa,KAAK,KAAK,GAAG,CACtE;AACD,WAAQ,KAAK,EAAE;;AAGjB,MAAI,CAAC,aAAa,SAAS,QAAQ,YAAY,EAAE;AAC/C,WAAQ,MACN,MAAM,IAAI,wCAAwC,aAAa,KAAK,KAAK,GAAG,CAC7E;AACD,WAAQ,KAAK,EAAE;;EAGjB,MAAM,YAAY,QAAQ,QAAQ,OAAO;EACzC,MAAM,UAAU,IAAI,cAAc,MAAM,QAAQ,QAAQ,IAAI,MAAM,GAAG,KAAK,CAAC,OAAO;AAElF,MAAI;GACF,MAAM,QAAQ,MAAM,gBAAgB,QAClC;IAAE;IAAQ;IAAO,aAAa,QAAQ;IAAa,OAAO,QAAQ;IAAO,EACzE,UACD;AAED,WAAQ,QACN,MAAM,MAAM,aAAa,MAAM,OAAO,QAAQ,MAAM,SAAS,IAAI,MAAM,GAAG,GAAG,CAC9E;AACD,QAAK,MAAM,KAAK,MACd,SAAQ,IAAI,MAAM,IAAI,KAAK,IAAI,CAAC;WAE3B,OAAO;AACd,WAAQ,MAAM;AACd,OAAI,iBAAiB,mBACnB,SAAQ,MAAM,MAAM,IAAI,MAAM,QAAQ,CAAC;YAC9B,iBAAiB,SAC1B,SAAQ,MAAM,MAAM,IAAI,cAAc,MAAM,UAAU,CAAC;OAEvD,SAAQ,MACN,MAAM,IACJ,qBAAqB,iBAAiB,QAAQ,MAAM,UAAU,kBAC/D,CACF;AAEH,WAAQ,KAAK,EAAE;;GAEjB;;;;;ACvEN,SAAgB,UAAU,UAA6B;CACrD,MAAM,UAAU,IAAI,SAAS,CAC1B,KAAK,WAAW,CAChB,YAAY,sDAAsD,CAClE,QAAQC,QAAY;AAEvB,SAAQ,WACN,kBAAkB;EAChB,OAAO,SAAS;EAChB,QAAQ,SAAS;EACjB,WAAW,SAAS;EACrB,CAAC,CACH;AAED,SAAQ,WAAW,sBAAsB,SAAS,cAAc,CAAC;AACjE,SAAQ,WAAW,kBAAkB,SAAS,UAAU,CAAC;AAEzD,QAAO;;;;;ACtBT,MAAM,WAAW,IAAI,cACnB;CACE;EAAE,OAAO,IAAI,iBAAiB;EAAE,MAAM;EAAY;CAClD;EAAE,OAAO,IAAI,aAAa;EAAE,MAAM;EAAQ;CAC1C;EAAE,OAAO,IAAI,oBAAoB;EAAE,MAAM;EAAe;CACzD,GACA,SAAS,QAAQ,IAAI,MAAM,IAAI,kBAAkB,OAAO,CAAC,CAC3D;AACD,MAAM,iBAAiB,IAAI,gBAAgB;AAC3C,MAAM,cAAc,IAAI,oBAAoB;AAY5B,UAAU;CACxB,eAX2B,IAAI,qBAC/B,gBACA,UACA,YACD;CAQC,WAPuB,IAAI,iBAAiB,gBAAgB,UAAU,YAAY;CAQlF,OAPmB,IAAI,aAAa,SAAS;CAQ7C,QAPoB,IAAI,cAAc,SAAS;CAQ/C,eAP2B,IAAI,qBAAqB,SAAS;CAQ9D,CAAC,CAEM,OAAO"}
|