nymbal 0.2.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1002 -75
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils/version.ts","../src/commands/dev.ts","../src/utils/project.ts","../src/utils/spawn.ts","../src/utils/port.ts","../src/utils/template-runner.ts","../src/commands/migrate.ts","../src/admin.ts","../src/commands/build.ts","../src/commands/seed.ts","../src/commands/import.ts","../src/commands/config-validate.ts","../src/commands/test.ts"],"sourcesContent":["import { defineCommand, runMain } from 'citty'\nimport { getCliVersion } from './utils/version.js'\nimport { devCommand } from './commands/dev.js'\nimport { buildCommand } from './commands/build.js'\nimport { migrateCommand } from './commands/migrate.js'\nimport { seedCommand } from './commands/seed.js'\nimport { importCommand } from './commands/import.js'\nimport { configValidateCommand } from './commands/config-validate.js'\nimport {\n testAllCommand,\n testCommand,\n testContractsCommand,\n testE2eCommand,\n testPerformanceCommand,\n testVisualCommand,\n} from './commands/test.js'\n\nexport { resolveAdminRoot } from './admin.js'\n\nconst main = defineCommand({\n meta: {\n name: 'nymbal',\n version: getCliVersion(),\n description: 'Nymbal developer CLI',\n },\n subCommands: {\n dev: devCommand,\n build: buildCommand,\n migrate: migrateCommand,\n seed: seedCommand,\n import: importCommand,\n 'config:validate': configValidateCommand,\n test: testCommand,\n 'test:e2e': testE2eCommand,\n 'test:visual': testVisualCommand,\n 'test:contracts': testContractsCommand,\n 'test:performance': testPerformanceCommand,\n 'test:all': testAllCommand,\n },\n})\n\n// citty prints --version through consola, which prefixes `[log]` when CI is set; scripts need the bare version.\nconst [flag, ...rest] = process.argv.slice(2)\nif (rest.length === 0 && (flag === '--version' || flag === '-v')) {\n process.stdout.write(`${getCliVersion()}\\n`)\n} else {\n runMain(main)\n}\n","import { readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst CLI_PACKAGE_NAME = 'nymbal'\n\nlet cached: string | null = null\n\n/**\n * Walks up from this module to the CLI's own package.json (found by name, so a nested or unrelated package.json\n * never answers). That is `dist/` in the workspace and in `node_modules/nymbal`, and `src/utils/` under Vitest.\n */\nfunction readOwnVersion(): string | undefined {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as {\n name?: string\n version?: string\n }\n if (pkg.name === CLI_PACKAGE_NAME) return pkg.version\n } catch {\n // No readable package.json in this directory: keep walking.\n }\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport function getCliVersion(): string {\n cached ??= readOwnVersion() ?? '0.0.0'\n return cached\n}\n","import { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport type { NymbalConfig } from '@nymbalhq/config'\nimport { loadProject } from '../utils/project.js'\nimport { createApp, runSeed } from '@nymbalhq/platform'\nimport { createHttpServer } from '@nymbalhq/http'\nimport { run } from '../utils/spawn.js'\nimport { getCliVersion } from '../utils/version.js'\nimport { findFreePort } from '../utils/port.js'\nimport { planTemplateLaunch } from '../utils/template-runner.js'\nimport { migrateProject } from './migrate.js'\nimport { resolveAdminRoot } from '../admin.js'\n\n/** Default storefront dev-server port per template (matches the scaffold scripts). */\nexport function defaultStorefrontPort(template: 'astro' | 'nextjs'): number {\n return template === 'astro' ? 4321 : 3000\n}\n\n/**\n * Resolve the *preferred* storefront port from (in priority order):\n * 1. --storefront-port flag\n * 2. NYMBAL_STOREFRONT_PORT env var\n * 3. the template default (Astro 4321 / Next.js 3000)\n * The value returned here is only the starting point; the dev command then\n * probes upward for a genuinely free port so a busy default never hard-fails.\n */\nexport function preferredStorefrontPort(\n template: 'astro' | 'nextjs',\n flagPort: number | undefined,\n env: NodeJS.ProcessEnv,\n): number {\n if (typeof flagPort === 'number' && Number.isFinite(flagPort)) return flagPort\n const fromEnv = env['NYMBAL_STOREFRONT_PORT']\n if (fromEnv && fromEnv.trim() !== '') {\n const parsed = Number(fromEnv)\n if (Number.isInteger(parsed) && parsed > 0) return parsed\n }\n return defaultStorefrontPort(template)\n}\n\n/**\n * The environment the storefront dev server starts with. The client-side variables must be set before it starts, and\n * both templates skip Stripe when the payments provider variable says `native-stub`, which is every provider but\n * `stripe`.\n */\nexport function storefrontEnv(\n config: NymbalConfig,\n apiUrl: string,\n storefrontPort: number,\n baseEnv: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n const stubPayments =\n config.commerce.payments.provider === 'stripe'\n ? {}\n : {\n PUBLIC_NYMBAL_PAYMENTS_PROVIDER: 'native-stub', // Astro\n NEXT_PUBLIC_NYMBAL_PAYMENTS_PROVIDER: 'native-stub', // Next.js\n }\n return {\n ...baseEnv,\n NYMBAL_API_URL: apiUrl,\n PUBLIC_NYMBAL_API_URL: apiUrl, // Astro\n NEXT_PUBLIC_NYMBAL_API_URL: apiUrl, // Next.js\n // The framework also reads the port flag; the env var keeps the scaffold\n // config (astro.config.mjs) in sync when it honours NYMBAL_STOREFRONT_PORT.\n NYMBAL_STOREFRONT_PORT: String(storefrontPort),\n ...stubPayments,\n }\n}\n\nexport const devCommand = defineCommand({\n meta: {\n name: 'dev',\n description: 'Start the API server and the configured storefront template with HMR',\n },\n args: {\n seed: {\n type: 'boolean',\n description: 'Run seed before starting (default: true if empty)',\n default: true,\n },\n apiOnly: {\n type: 'boolean',\n // `alias` is required: citty 0.1.6 registers the camelCase key `apiOnly`\n // with mri and applies `default: false`. Without this alias a kebab\n // `--api-only` flag lands on `args['api-only']`, but `args.apiOnly`\n // resolves to the `false` default first (`??` does not fall through on\n // `false`), so the flag is silently ignored. The alias makes mri map\n // `--api-only` straight to `apiOnly`. Both forms now work.\n alias: 'api-only',\n description: 'Start only the API server (skip template dev server)',\n default: false,\n },\n storefrontPort: {\n type: 'string',\n alias: 'storefront-port',\n description:\n 'Port for the storefront dev server (default: 4321 Astro / 3000 Next.js). ' +\n 'If busy, the next free port is used. Also settable via NYMBAL_STOREFRONT_PORT.',\n },\n },\n async run({ args }) {\n const { config, projectRoot } = await loadProject()\n const version = getCliVersion()\n\n // Auto-migrate on startup so a fresh clone works without running `nymbal migrate` first\n await migrateProject(config, projectRoot)\n\n const app = await createApp(config, { version })\n const { platform } = app\n\n if (args.seed) {\n const existing = await platform.documentStore.query('products', {\n partitionKey: { field: 'storeId', value: config.store.name },\n limit: 1,\n })\n if (existing.items.length === 0) {\n platform.logger.info({}, 'Seeding demo content (first run)')\n await runSeed({\n config,\n commandStore: platform.commandStore,\n documentStore: platform.documentStore,\n eventBus: platform.eventBus,\n logger: platform.logger,\n version,\n })\n }\n }\n\n const http = createHttpServer({\n config,\n logger: platform.logger,\n documentStore: platform.documentStore,\n version,\n })\n const adminRoot = resolveAdminRoot()\n if (adminRoot === null) {\n // eslint-disable-next-line no-console\n console.log(\n pc.yellow(\n '→ The admin is not built, so /admin/ answers 404: run `pnpm --filter @nymbalhq/admin build`.',\n ),\n )\n }\n await app.attachHttp(http.adapter, { adminRoot })\n await http.start()\n\n if (args.apiOnly) {\n const shutdown = async (signal: string) => {\n platform.logger.info({ signal }, 'Shutting down API')\n await http.stop().catch(() => {})\n await app.stop().catch(() => {})\n process.exit(0)\n }\n process.on('SIGINT', () => void shutdown('SIGINT'))\n process.on('SIGTERM', () => void shutdown('SIGTERM'))\n // Keep process alive — Playwright webServer will kill it when done\n return\n }\n\n // Resolve a free storefront port. The preferred port is configurable but may\n // be taken (a developer commonly has another project on 4321/3000), so we\n // probe upward for a free one instead of hard-failing.\n const flagPortRaw = args.storefrontPort\n const flagPort =\n typeof flagPortRaw === 'string' && flagPortRaw.trim() !== '' ? Number(flagPortRaw) : undefined\n const preferred = preferredStorefrontPort(config.template, flagPort, process.env)\n const storefrontPort = await findFreePort(preferred)\n if (storefrontPort !== preferred) {\n // eslint-disable-next-line no-console\n console.log(\n pc.yellow(\n `→ Storefront port ${preferred} is busy; using free port ${pc.bold(String(storefrontPort))} instead.`,\n ),\n )\n }\n\n // Plan how to launch the storefront. A flat scaffold (create-nymbal-app\n // output) runs the framework dev server directly in the project root; a\n // monorepo layout falls back to a pnpm --filter on the template package.\n const launch = planTemplateLaunch(projectRoot, config.template, storefrontPort)\n\n const apiUrl = `http://localhost:${config.http.port}`\n const storefrontUrl = `http://localhost:${storefrontPort}`\n // eslint-disable-next-line no-console\n console.log(\n pc.cyan(\n `→ Starting storefront (${pc.bold(config.template)}, ${launch.mode}) on ${pc.bold(storefrontUrl)}`,\n ),\n )\n // eslint-disable-next-line no-console\n console.log(pc.dim(` API: ${apiUrl}`))\n\n const templateProc = run(launch.command, launch.args, {\n cwd: launch.cwd,\n env: storefrontEnv(config, apiUrl, storefrontPort),\n })\n\n const shutdown = async (signal: string) => {\n platform.logger.info({ signal }, 'Shutting down')\n try {\n templateProc.child.kill('SIGINT')\n } catch {\n // ignore\n }\n await http.stop().catch(() => {})\n await app.stop().catch(() => {})\n process.exit(0)\n }\n process.on('SIGINT', () => void shutdown('SIGINT'))\n process.on('SIGTERM', () => void shutdown('SIGTERM'))\n\n const templateExit = await templateProc.done\n platform.logger.info({ code: templateExit }, 'Template process exited')\n await shutdown('template-exit')\n },\n})\n","import { existsSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { findConfigFile, loadConfig, type LoadedConfig } from '@nymbalhq/config'\n\n/**\n * Loads `<projectRoot>/.env` into the process environment, then the project's config, so `env()` calls in\n * `nymbal.config.ts` see it. A variable already set in the environment is kept: `process.loadEnvFile` never overrides.\n */\nexport async function loadProject(startDir: string = process.cwd()): Promise<LoadedConfig> {\n const configPath = findConfigFile(startDir)\n if (configPath) {\n const envFile = resolve(dirname(configPath), '.env')\n if (existsSync(envFile)) process.loadEnvFile(envFile)\n }\n return loadConfig(startDir)\n}\n","import { spawn, type ChildProcess, type SpawnOptions } from 'node:child_process'\n\nexport interface RunOptions extends SpawnOptions {\n name?: string\n}\n\nexport function run(\n command: string,\n args: string[],\n options: RunOptions = {},\n): { child: ChildProcess; done: Promise<number> } {\n const child = spawn(command, args, {\n stdio: 'inherit',\n shell: false,\n ...options,\n })\n const done = new Promise<number>((resolve, reject) => {\n child.on('error', reject)\n child.on('exit', (code) => resolve(code ?? 0))\n })\n return { child, done }\n}\n\nexport async function runOrFail(\n command: string,\n args: string[],\n options: RunOptions = {},\n): Promise<void> {\n const { done } = run(command, args, options)\n const code = await done\n if (code !== 0) {\n throw new Error(`${command} ${args.join(' ')} exited with code ${code}`)\n }\n}\n","import { createServer } from 'node:net'\n\n/**\n * Resolve a usable storefront port.\n *\n * The headline `nymbal dev` flow must not hard-fail when the preferred port is\n * already taken (a developer commonly has another project on 4321/3000). We\n * probe the preferred port first and, if it is busy, increment until we find a\n * free one — exactly how the underlying dev servers (Astro, Next.js) behave on\n * their own, but here we resolve the port *before* spawning so we can tell the\n * storefront which port to bind and tell the user where to open the browser.\n */\nexport async function isPortFree(port: number, host?: string): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const server = createServer()\n server.once('error', (err: NodeJS.ErrnoException) => {\n // EADDRINUSE / EACCES → not usable. Any other error → treat as not free\n // rather than silently swallowing it; the caller will skip this port.\n if (err.code !== 'EADDRINUSE' && err.code !== 'EACCES') {\n // eslint-disable-next-line no-console\n console.error(`[dev] unexpected error probing port ${port}:`, err.message)\n }\n resolve(false)\n })\n server.once('listening', () => {\n server.close(() => resolve(true))\n })\n // Bind across all interfaces (no explicit host) so a port already held on\n // IPv6 (e.g. another dev server on [::1]) is correctly seen as busy. A\n // 127.0.0.1-only probe would miss an IPv6 listener and wrongly report free,\n // then the framework — which binds dual-stack — would fail on that port.\n if (host) {\n server.listen(port, host)\n } else {\n server.listen(port)\n }\n })\n}\n\n/**\n * Find a free port starting at `preferred`, scanning upward up to `maxAttempts`\n * times. Throws an actionable error if no port in the range is free.\n */\nexport async function findFreePort(\n preferred: number,\n maxAttempts = 20,\n host?: string,\n): Promise<number> {\n if (!Number.isInteger(preferred) || preferred < 1 || preferred > 65535) {\n throw new Error(\n `Invalid storefront port \"${preferred}\". Set a valid port (1–65535) via --storefront-port or NYMBAL_STOREFRONT_PORT.`,\n )\n }\n for (let i = 0; i < maxAttempts; i++) {\n const candidate = preferred + i\n if (candidate > 65535) break\n if (await isPortFree(candidate, host)) {\n return candidate\n }\n }\n throw new Error(\n `No free storefront port found in range ${preferred}–${Math.min(preferred + maxAttempts - 1, 65535)}. ` +\n `Free a port in that range or pass an explicit free port via --storefront-port.`,\n )\n}\n","import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { NymbalConfig } from '@nymbalhq/config'\n\nexport type TemplateName = 'astro' | 'nextjs'\n\nexport interface TemplateLaunch {\n /** Working directory the storefront dev server runs in. */\n cwd: string\n /** Command + args to start the storefront dev server. */\n command: string\n args: string[]\n /**\n * How the storefront was located. `flat` = the project root IS the storefront\n * (create-nymbal-app output). `filter` = a sub-package in a monorepo layout.\n */\n mode: 'flat' | 'filter'\n}\n\nexport function templateFilterFor(template: NymbalConfig['template']): string {\n return template === 'astro' ? '@nymbalhq/template-astro' : '@nymbalhq/template-nextjs'\n}\n\n/**\n * A flat scaffold (create-nymbal-app output) places the storefront AT the\n * project root: the framework config and a `dev` script live in projectRoot.\n * In that layout we must run the dev server in projectRoot directly — NOT via\n * `pnpm --filter @nymbalhq/template-astro`, which would match the workspace\n * template package (the wrong directory) inside a monorepo, or match nothing at\n * all outside one.\n */\nexport function isFlatScaffold(projectRoot: string, template: TemplateName): boolean {\n const marker = template === 'astro' ? 'astro.config.mjs' : 'next.config.mjs'\n const altMarker = template === 'astro' ? 'astro.config.ts' : 'next.config.ts'\n return existsSync(resolve(projectRoot, marker)) || existsSync(resolve(projectRoot, altMarker))\n}\n\n/**\n * Resolve the framework's local CLI bin inside the project's node_modules.\n * We spawn the local bin directly (rather than the package-manager `run dev`\n * script) so we can inject the resolved free port via `--port`, overriding the\n * hardcoded port baked into the scaffold's `dev` script. Returns null when the\n * bin is not present (deps not installed) so the caller can produce an\n * actionable error.\n */\nexport function resolveLocalBin(projectRoot: string, bin: string): string | null {\n const binPath = resolve(projectRoot, 'node_modules', '.bin', bin)\n return existsSync(binPath) ? binPath : null\n}\n\n/**\n * Build the storefront dev launch plan.\n *\n * @param storefrontPort - the resolved (free) port the storefront must bind to.\n * Passed to the framework via flag so we control where it listens, instead of\n * relying on the framework's hardcoded default which may already be taken.\n */\nexport function planTemplateLaunch(\n projectRoot: string,\n template: TemplateName,\n storefrontPort: number,\n): TemplateLaunch {\n if (isFlatScaffold(projectRoot, template)) {\n // Run the framework dev server directly in the project root. We pass the\n // port explicitly so the framework binds where we resolved a free port,\n // overriding any hardcoded port in the scaffold's package.json script.\n const binName = template === 'astro' ? 'astro' : 'next'\n const localBin = resolveLocalBin(projectRoot, binName)\n if (!localBin) {\n throw new Error(\n `Cannot find the ${binName} dev server in ${projectRoot}/node_modules/.bin. ` +\n `Install dependencies first (e.g. \\`pnpm install\\`), then re-run \\`nymbal dev\\`.`,\n )\n }\n return {\n cwd: projectRoot,\n command: localBin,\n args: ['dev', '--port', String(storefrontPort), ...foregroundArgs(template)],\n mode: 'flat',\n }\n }\n\n // Monorepo layout fallback: the storefront lives in a workspace sub-package.\n const filter = templateFilterFor(template)\n return {\n cwd: projectRoot,\n command: 'pnpm',\n args: ['--filter', filter, 'dev', ...foregroundArgs(template)],\n mode: 'filter',\n }\n}\n\n/**\n * Astro 7 backgrounds `astro dev` when it detects an AI agent, so the launcher would see its child exit while the\n * server lives on detached; --ignore-lock keeps it in the foreground. `next dev` rejects unknown options.\n */\nfunction foregroundArgs(template: TemplateName): string[] {\n return template === 'astro' ? ['--ignore-lock'] : []\n}\n","import { defineCommand } from 'citty'\nimport type { NymbalConfig } from '@nymbalhq/config'\nimport { loadProject } from '../utils/project.js'\nimport { createCommandStore, runMigrations } from '@nymbalhq/platform'\nimport { dirname, resolve } from 'node:path'\nimport { existsSync } from 'node:fs'\n\nexport const migrateCommand = defineCommand({\n meta: { name: 'migrate', description: 'Run database migrations (Drizzle)' },\n async run() {\n const { config, projectRoot } = await loadProject()\n const kind = await migrateProject(config, projectRoot)\n // eslint-disable-next-line no-console\n console.log(`✓ migrations applied (${kind})`)\n },\n})\n\n/** Applies the project's migrations to its command store; the store is closed again before returning. */\nexport async function migrateProject(config: NymbalConfig, projectRoot: string): Promise<string> {\n const store = createCommandStore(config)\n try {\n await runMigrations(store, { migrationsRoot: resolveMigrations(projectRoot) })\n return store.kind\n } finally {\n await store.close()\n }\n}\n\nexport function resolveMigrations(projectRoot: string): string {\n // 1. Project-local override (scaffolded projects or custom migrations)\n const local = resolve(projectRoot, 'migrations')\n if (existsSync(local)) return local\n\n // 2. Monorepo workspace: packages/platform/migrations (for CI and fresh clones)\n const monorepoDev = resolve(projectRoot, 'packages/platform/migrations')\n if (existsSync(monorepoDev)) return monorepoDev\n\n // 3. Published package: node_modules/@nymbalhq/platform/migrations\n //\n // We must NOT use `require.resolve('@nymbalhq/platform/package.json')` nor\n // `require.resolve('@nymbalhq/platform')`: the package's `exports` map is\n // ESM-only and does not expose `./package.json`, so CJS resolution throws\n // (ERR_PACKAGE_PATH_NOT_EXPORTED / \"No exports main defined\"). Instead we\n // locate the installed package directory directly under node_modules, which\n // is independent of the exports map and works for symlinked (pnpm workspace)\n // and flat installs alike.\n const pkgDir = resolvePackageDir(projectRoot, '@nymbalhq/platform')\n if (pkgDir) {\n const pkgMigrations = resolve(pkgDir, 'migrations')\n if (existsSync(pkgMigrations)) return pkgMigrations\n }\n\n return local\n}\n\n/**\n * Resolve the on-disk root directory of an installed package from `fromRoot`,\n * by walking up the directory tree looking for `node_modules/<pkgName>`. This\n * does not depend on the package's `exports` map (which may be ESM-only and not\n * expose `./package.json`), and resolves correctly for pnpm symlinked workspace\n * installs as well as flat node_modules. Returns null when not found.\n */\nexport function resolvePackageDir(fromRoot: string, pkgName: string): string | null {\n let dir = resolve(fromRoot)\n for (let i = 0; i < 24; i++) {\n const candidate = resolve(dir, 'node_modules', pkgName)\n if (existsSync(resolve(candidate, 'package.json'))) {\n return candidate\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n","import { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { dirname, join } from 'node:path'\n\nfunction hasIndex(dir: string): boolean {\n return existsSync(join(dir, 'index.html'))\n}\n\n/**\n * The admin dist to serve: `NYMBAL_ADMIN_DIST` when it holds `index.html` (read per call), else the installed\n * `@nymbalhq/admin` dist when built, else null.\n */\nexport function resolveAdminRoot(): string | null {\n const override = process.env['NYMBAL_ADMIN_DIST']\n if (override && hasIndex(override)) return override\n try {\n const manifest = createRequire(import.meta.url).resolve('@nymbalhq/admin/package.json')\n const dist = join(dirname(manifest), 'dist')\n return hasIndex(dist) ? dist : null\n } catch {\n return null\n }\n}\n","import { defineCommand } from 'citty'\nimport { loadProject } from '../utils/project.js'\nimport { runOrFail } from '../utils/spawn.js'\nimport { isFlatScaffold, resolveLocalBin, templateFilterFor } from '../utils/template-runner.js'\n\nexport const buildCommand = defineCommand({\n meta: { name: 'build', description: 'Production build of the configured template' },\n async run() {\n const { config, projectRoot } = await loadProject()\n if (!isFlatScaffold(projectRoot, config.template)) {\n // Inside this monorepo the storefront is a workspace package.\n await runOrFail('pnpm', ['--filter', templateFilterFor(config.template), 'build'], {\n cwd: projectRoot,\n })\n return\n }\n const binName = config.template === 'astro' ? 'astro' : 'next'\n const bin = resolveLocalBin(projectRoot, binName)\n if (!bin) {\n throw new Error(\n `Cannot find the ${binName} binary in ${projectRoot}/node_modules/.bin. ` +\n 'Install dependencies first, then re-run `nymbal build`.',\n )\n }\n await runOrFail(bin, ['build'], { cwd: projectRoot })\n },\n})\n","import { defineCommand } from 'citty'\nimport { loadProject } from '../utils/project.js'\nimport { createPlatform, runSeed } from '@nymbalhq/platform'\nimport { getCliVersion } from '../utils/version.js'\nimport { migrateProject } from './migrate.js'\n\nexport const seedCommand = defineCommand({\n meta: { name: 'seed', description: 'Re-seed demo content (products, categories)' },\n async run() {\n const { config, projectRoot } = await loadProject()\n // A fresh project has no tables yet; `nymbal dev` migrates before it seeds, and so does this.\n await migrateProject(config, projectRoot)\n const platform = createPlatform(config)\n try {\n const result = await runSeed({\n config,\n commandStore: platform.commandStore,\n documentStore: platform.documentStore,\n eventBus: platform.eventBus,\n logger: platform.logger,\n version: getCliVersion(),\n })\n // eslint-disable-next-line no-console\n console.log(\n result.alreadySeeded\n ? '✓ demo content already present, nothing to seed'\n : `✓ seeded ${result.products} products across ${result.categories} categories`,\n )\n } finally {\n await platform.close()\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport { intro, outro, text, select, spinner, isCancel, cancel } from '@clack/prompts'\nimport * as p from 'picocolors'\nimport { loadProject } from '../utils/project.js'\nimport { createApp } from '@nymbalhq/platform'\nimport { runWooCommerceImport, writeReport, type ImportEntity, type ProgressEvent } from '@nymbalhq/importers'\nimport { join } from 'node:path'\nimport { getCliVersion } from '../utils/version.js'\n\nexport const importCommand = defineCommand({\n meta: {\n name: 'import',\n description: 'Migrate content from WooCommerce (or other sources) into Nymbal',\n },\n args: {\n source: {\n type: 'string',\n description: 'Import source (woocommerce)',\n },\n url: {\n type: 'string',\n description: 'Store URL (e.g. https://mystore.com)',\n },\n key: {\n type: 'string',\n description: 'WooCommerce Consumer Key (or set WOOCOMMERCE_KEY env var)',\n },\n secret: {\n type: 'string',\n description: 'WooCommerce Consumer Secret (or set WOOCOMMERCE_SECRET env var)',\n },\n entities: {\n type: 'string',\n description: 'Comma-separated list: products,customers,orders,reviews (default: products,customers,orders)',\n },\n ai: {\n type: 'boolean',\n description: 'Enable AI enrichment (default: true)',\n default: true,\n },\n gdpr: {\n type: 'boolean',\n description: 'Anonymise customer PII (default: true)',\n default: true,\n },\n fresh: {\n type: 'boolean',\n description: 'Ignore previous progress and re-import',\n default: false,\n },\n concurrency: {\n type: 'string',\n description: 'Parallel import workers (default: 4)',\n },\n },\n async run({ args }) {\n const { config } = await loadProject()\n const projectRoot = process.cwd()\n const statePath = join(projectRoot, '.nymbal-migration.json')\n const isTTY = process.stdin.isTTY ?? false\n\n intro(p.bold('Nymbal Import'))\n\n // ── Resolve source ────────────────────────────────────────────────────────\n let source = args.source\n if (!source) {\n if (!isTTY) {\n console.error('--source is required (woocommerce)')\n process.exit(1)\n }\n const picked = await select({\n message: 'Source platform?',\n options: [{ value: 'woocommerce', label: 'WooCommerce' }],\n })\n if (isCancel(picked)) { cancel('Import cancelled'); process.exit(0) }\n source = String(picked)\n }\n if (source !== 'woocommerce') {\n console.error(`Unsupported source: ${source}. Only 'woocommerce' is supported.`)\n process.exit(1)\n }\n\n // ── Resolve credentials ───────────────────────────────────────────────────\n let storeUrl = args.url\n if (!storeUrl) {\n if (!isTTY) { console.error('--url is required'); process.exit(1) }\n const val = await text({ message: 'Store URL?', placeholder: 'https://mystore.com', validate: (v) => v.startsWith('http') ? undefined : 'Must be a URL' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n storeUrl = String(val)\n }\n\n let consumerKey = args.key ?? process.env['WOOCOMMERCE_KEY'] ?? ''\n if (!consumerKey) {\n if (!isTTY) { console.error('--key or WOOCOMMERCE_KEY is required'); process.exit(1) }\n const val = await text({ message: 'Consumer Key?', placeholder: 'ck_...' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n consumerKey = String(val)\n }\n\n let consumerSecret = args.secret ?? process.env['WOOCOMMERCE_SECRET'] ?? ''\n if (!consumerSecret) {\n if (!isTTY) { console.error('--secret or WOOCOMMERCE_SECRET is required'); process.exit(1) }\n const val = await text({ message: 'Consumer Secret?', placeholder: 'cs_...' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n consumerSecret = String(val)\n }\n\n // ── Resolve entity list ───────────────────────────────────────────────────\n let entityList: ImportEntity[]\n if (args.entities) {\n entityList = args.entities.split(',').map((e) => e.trim()) as ImportEntity[]\n } else {\n entityList = ['categories', 'products', 'customers', 'orders']\n }\n\n const concurrency = parseInt(String(args.concurrency ?? '4'), 10)\n const aiEnabled = args.ai !== false\n const gdprEnabled = args.gdpr !== false\n\n // ── Bootstrap app ─────────────────────────────────────────────────────────\n const loadSpin = spinner()\n loadSpin.start('Starting platform…')\n const app = await createApp(config, { version: getCliVersion() })\n loadSpin.stop('Platform ready')\n\n try {\n const report = await runWooCommerceImport(\n {\n credentials: { url: storeUrl, consumerKey, consumerSecret },\n entities: entityList,\n ai: aiEnabled,\n gdpr: gdprEnabled,\n fresh: args.fresh,\n concurrency,\n projectRoot,\n currency: config.store.currency,\n statePath,\n },\n {\n services: app.services,\n repos: app.repos,\n adapters: { ai: app.adapters.ai, reviews: app.adapters.reviews },\n onProgress(event: ProgressEvent) {\n if (event.kind === 'phase') {\n console.log(p.cyan(` → ${event.phase}`))\n } else if (event.kind === 'progress') {\n const pct = Math.round((event.done / event.total) * 100)\n process.stdout.write(`\\r ${event.entity}: ${event.done}/${event.total} (${pct}%) `)\n if (event.done === event.total) process.stdout.write('\\n')\n } else if (event.kind === 'error') {\n console.log(p.red(` ✗ ${event.phase} [${event.id}]: ${event.message}`))\n }\n },\n },\n )\n\n const reportPath = await writeReport(report, projectRoot, config.store.name)\n\n outro(\n [\n p.green('✓ Import complete'),\n ` Products: ${report.imported.products}`,\n ` Customers: ${report.imported.customers}`,\n ` Orders: ${report.imported.orders}`,\n ` Categories: ${report.imported.categories}`,\n ...(aiEnabled ? [` AI enriched: ${report.enriched.enriched} products`] : []),\n ...(report.errors.length > 0 ? [p.yellow(` ⚠ ${report.errors.length} errors — see report`)] : []),\n ``,\n ` Report: ${reportPath}`,\n ` Next: ${p.bold('nymbal dev')}`,\n ].join('\\n'),\n )\n } finally {\n await app.stop()\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport { loadProject } from '../utils/project.js'\nimport { NymbalError } from '@nymbalhq/types'\n\nexport const configValidateCommand = defineCommand({\n meta: { name: 'config:validate', description: 'Validate nymbal.config.ts' },\n async run() {\n try {\n const { config, path } = await loadProject()\n // eslint-disable-next-line no-console\n console.log(pc.green(`✓ config valid`) + ` (${path})`)\n // eslint-disable-next-line no-console\n console.log(\n ` template: ${config.template}, cloud: ${config.infrastructure.cloud}, commandStore: ${config.infrastructure.commandStore}`,\n )\n process.exit(0)\n } catch (err) {\n if (err instanceof NymbalError) {\n // eslint-disable-next-line no-console\n console.error(pc.red('✗ config invalid'))\n // eslint-disable-next-line no-console\n console.error(err.message)\n } else {\n // eslint-disable-next-line no-console\n console.error(err)\n }\n process.exit(1)\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport { loadConfig } from '@nymbalhq/config'\nimport { run, runOrFail } from '../utils/spawn.js'\n\nexport const testCommand = defineCommand({\n meta: { name: 'test', description: 'Run unit + integration tests (vitest)' },\n async run() {\n await runOrFail('pnpm', ['vitest', 'run'])\n },\n})\n\nexport const testE2eCommand = defineCommand({\n meta: { name: 'test:e2e', description: 'Run Playwright E2E against the configured template' },\n async run() {\n const { config } = await loadConfig()\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep-invert', '@visual|@a11y',\n ])\n },\n})\n\nexport const testVisualCommand = defineCommand({\n meta: { name: 'test:visual', description: 'Run visual regression tests (Playwright toHaveScreenshot)' },\n args: {\n 'update-baselines': {\n type: 'boolean',\n description: 'Regenerate screenshot baselines',\n default: false,\n },\n },\n async run({ args }) {\n const { config } = await loadConfig()\n const isCI = !!process.env.CI\n const updateBaselines = args['update-baselines']\n\n if (updateBaselines && !isCI) {\n // Run in Docker for Linux-consistent baselines\n const dockerImage = 'mcr.microsoft.com/playwright:v1.50-jammy'\n const cwd = process.cwd()\n await runOrFail('docker', [\n 'run', '--rm', '-v', `${cwd}:${cwd}`, '-w', cwd,\n dockerImage, 'sh', '-c',\n `pnpm --filter @nymbalhq/e2e exec playwright test --project ${config.template} --grep \"@visual\" --update-snapshots`,\n ])\n } else {\n const pwArgs = [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep', '@visual',\n ]\n if (updateBaselines) pwArgs.push('--update-snapshots')\n await runOrFail('pnpm', pwArgs)\n }\n },\n})\n\nexport const testContractsCommand = defineCommand({\n meta: { name: 'test:contracts', description: 'Run adapter contract tests' },\n args: {\n adapter: { type: 'string', description: 'Run only contracts for a specific adapter (e.g. payments, email)' },\n },\n async run({ args }) {\n const vArgs = [\n 'vitest', 'run',\n '--project', 'contracts-native',\n ]\n if (args.adapter) {\n // Pass the specific file path as additional argument\n vArgs.push(`tests/contracts/${String(args.adapter)}.test.ts`)\n }\n await runOrFail('pnpm', vArgs)\n },\n})\n\nexport const testPerformanceCommand = defineCommand({\n meta: { name: 'test:performance', description: 'Run Lighthouse CI against the configured template' },\n async run() {\n const { config } = await loadConfig()\n const port = config.template === 'nextjs' ? 3000 : 4321\n await runOrFail('pnpm', ['lhci', 'autorun'], {\n env: {\n ...process.env,\n NYMBAL_TEMPLATE: config.template,\n NYMBAL_TEMPLATE_PORT: String(port),\n },\n })\n },\n})\n\nexport const testAllCommand = defineCommand({\n meta: { name: 'test:all', description: 'Run unit, contract, e2e, visual, and performance tests' },\n async run() {\n const steps: Array<{ name: string; args: string[] }> = [\n { name: 'unit', args: ['vitest', 'run'] },\n { name: 'contracts', args: ['vitest', 'run', '--project', 'contracts-native'] },\n ]\n\n for (const step of steps) {\n const { done } = run('pnpm', step.args)\n const code = await done\n if (code !== 0) {\n // eslint-disable-next-line no-console\n console.error(`✗ ${step.name} failed`)\n process.exit(code)\n }\n }\n\n const { config } = await loadConfig()\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep-invert', '@visual|@a11y',\n ])\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep', '@visual',\n ])\n await runOrFail('pnpm', ['lhci', 'autorun'], {\n env: { ...process.env, NYMBAL_TEMPLATE: config.template },\n })\n },\n})\n"],"mappings":";AAAA,SAAS,iBAAAA,gBAAe,eAAe;;;ACAvC,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AAC9B,SAAS,qBAAqB;AAE9B,IAAM,mBAAmB;AAEzB,IAAI,SAAwB;AAM5B,SAAS,iBAAqC;AAC5C,MAAI,MAAM,QAAQ,cAAc,YAAY,GAAG,CAAC;AAChD,aAAS;AACP,QAAI;AACF,YAAM,MAAM,KAAK,MAAM,aAAa,KAAK,KAAK,cAAc,GAAG,MAAM,CAAC;AAItE,UAAI,IAAI,SAAS,iBAAkB,QAAO,IAAI;AAAA,IAChD,QAAQ;AAAA,IAER;AACA,UAAM,SAAS,QAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK,QAAO;AAC3B,UAAM;AAAA,EACR;AACF;AAEO,SAAS,gBAAwB;AACtC,aAAW,eAAe,KAAK;AAC/B,SAAO;AACT;;;ACjCA,SAAS,iBAAAC,sBAAqB;AAC9B,OAAO,QAAQ;;;ACDf,SAAS,kBAAkB;AAC3B,SAAS,WAAAC,UAAS,eAAe;AACjC,SAAS,gBAAgB,kBAAqC;AAM9D,eAAsB,YAAY,WAAmB,QAAQ,IAAI,GAA0B;AACzF,QAAM,aAAa,eAAe,QAAQ;AAC1C,MAAI,YAAY;AACd,UAAM,UAAU,QAAQA,SAAQ,UAAU,GAAG,MAAM;AACnD,QAAI,WAAW,OAAO,EAAG,SAAQ,YAAY,OAAO;AAAA,EACtD;AACA,SAAO,WAAW,QAAQ;AAC5B;;;ADXA,SAAS,WAAW,eAAe;AACnC,SAAS,wBAAwB;;;AELjC,SAAS,aAAmD;AAMrD,SAAS,IACd,SACA,MACA,UAAsB,CAAC,GACyB;AAChD,QAAM,QAAQ,MAAM,SAAS,MAAM;AAAA,IACjC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,GAAG;AAAA,EACL,CAAC;AACD,QAAM,OAAO,IAAI,QAAgB,CAACC,UAAS,WAAW;AACpD,UAAM,GAAG,SAAS,MAAM;AACxB,UAAM,GAAG,QAAQ,CAAC,SAASA,SAAQ,QAAQ,CAAC,CAAC;AAAA,EAC/C,CAAC;AACD,SAAO,EAAE,OAAO,KAAK;AACvB;AAEA,eAAsB,UACpB,SACA,MACA,UAAsB,CAAC,GACR;AACf,QAAM,EAAE,KAAK,IAAI,IAAI,SAAS,MAAM,OAAO;AAC3C,QAAM,OAAO,MAAM;AACnB,MAAI,SAAS,GAAG;AACd,UAAM,IAAI,MAAM,GAAG,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC,qBAAqB,IAAI,EAAE;AAAA,EACzE;AACF;;;ACjCA,SAAS,oBAAoB;AAY7B,eAAsB,WAAW,MAAc,MAAiC;AAC9E,SAAO,IAAI,QAAiB,CAACC,aAAY;AACvC,UAAM,SAAS,aAAa;AAC5B,WAAO,KAAK,SAAS,CAAC,QAA+B;AAGnD,UAAI,IAAI,SAAS,gBAAgB,IAAI,SAAS,UAAU;AAEtD,gBAAQ,MAAM,uCAAuC,IAAI,KAAK,IAAI,OAAO;AAAA,MAC3E;AACA,MAAAA,SAAQ,KAAK;AAAA,IACf,CAAC;AACD,WAAO,KAAK,aAAa,MAAM;AAC7B,aAAO,MAAM,MAAMA,SAAQ,IAAI,CAAC;AAAA,IAClC,CAAC;AAKD,QAAI,MAAM;AACR,aAAO,OAAO,MAAM,IAAI;AAAA,IAC1B,OAAO;AACL,aAAO,OAAO,IAAI;AAAA,IACpB;AAAA,EACF,CAAC;AACH;AAMA,eAAsB,aACpB,WACA,cAAc,IACd,MACiB;AACjB,MAAI,CAAC,OAAO,UAAU,SAAS,KAAK,YAAY,KAAK,YAAY,OAAO;AACtE,UAAM,IAAI;AAAA,MACR,4BAA4B,SAAS;AAAA,IACvC;AAAA,EACF;AACA,WAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAM,YAAY,YAAY;AAC9B,QAAI,YAAY,MAAO;AACvB,QAAI,MAAM,WAAW,WAAW,IAAI,GAAG;AACrC,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,IAAI;AAAA,IACR,0CAA0C,SAAS,SAAI,KAAK,IAAI,YAAY,cAAc,GAAG,KAAK,CAAC;AAAA,EAErG;AACF;;;AChEA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,WAAAC,gBAAe;AAkBjB,SAAS,kBAAkB,UAA4C;AAC5E,SAAO,aAAa,UAAU,6BAA6B;AAC7D;AAUO,SAAS,eAAe,aAAqB,UAAiC;AACnF,QAAM,SAAS,aAAa,UAAU,qBAAqB;AAC3D,QAAM,YAAY,aAAa,UAAU,oBAAoB;AAC7D,SAAOD,YAAWC,SAAQ,aAAa,MAAM,CAAC,KAAKD,YAAWC,SAAQ,aAAa,SAAS,CAAC;AAC/F;AAUO,SAAS,gBAAgB,aAAqB,KAA4B;AAC/E,QAAM,UAAUA,SAAQ,aAAa,gBAAgB,QAAQ,GAAG;AAChE,SAAOD,YAAW,OAAO,IAAI,UAAU;AACzC;AASO,SAAS,mBACd,aACA,UACA,gBACgB;AAChB,MAAI,eAAe,aAAa,QAAQ,GAAG;AAIzC,UAAM,UAAU,aAAa,UAAU,UAAU;AACjD,UAAM,WAAW,gBAAgB,aAAa,OAAO;AACrD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR,mBAAmB,OAAO,kBAAkB,WAAW;AAAA,MAEzD;AAAA,IACF;AACA,WAAO;AAAA,MACL,KAAK;AAAA,MACL,SAAS;AAAA,MACT,MAAM,CAAC,OAAO,UAAU,OAAO,cAAc,GAAG,GAAG,eAAe,QAAQ,CAAC;AAAA,MAC3E,MAAM;AAAA,IACR;AAAA,EACF;AAGA,QAAM,SAAS,kBAAkB,QAAQ;AACzC,SAAO;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,IACT,MAAM,CAAC,YAAY,QAAQ,OAAO,GAAG,eAAe,QAAQ,CAAC;AAAA,IAC7D,MAAM;AAAA,EACR;AACF;AAMA,SAAS,eAAe,UAAkC;AACxD,SAAO,aAAa,UAAU,CAAC,eAAe,IAAI,CAAC;AACrD;;;AClGA,SAAS,qBAAqB;AAG9B,SAAS,oBAAoB,qBAAqB;AAClD,SAAS,WAAAE,UAAS,WAAAC,gBAAe;AACjC,SAAS,cAAAC,mBAAkB;AAEpB,IAAM,iBAAiB,cAAc;AAAA,EAC1C,MAAM,EAAE,MAAM,WAAW,aAAa,oCAAoC;AAAA,EAC1E,MAAM,MAAM;AACV,UAAM,EAAE,QAAQ,YAAY,IAAI,MAAM,YAAY;AAClD,UAAM,OAAO,MAAM,eAAe,QAAQ,WAAW;AAErD,YAAQ,IAAI,8BAAyB,IAAI,GAAG;AAAA,EAC9C;AACF,CAAC;AAGD,eAAsB,eAAe,QAAsB,aAAsC;AAC/F,QAAM,QAAQ,mBAAmB,MAAM;AACvC,MAAI;AACF,UAAM,cAAc,OAAO,EAAE,gBAAgB,kBAAkB,WAAW,EAAE,CAAC;AAC7E,WAAO,MAAM;AAAA,EACf,UAAE;AACA,UAAM,MAAM,MAAM;AAAA,EACpB;AACF;AAEO,SAAS,kBAAkB,aAA6B;AAE7D,QAAM,QAAQD,SAAQ,aAAa,YAAY;AAC/C,MAAIC,YAAW,KAAK,EAAG,QAAO;AAG9B,QAAM,cAAcD,SAAQ,aAAa,8BAA8B;AACvE,MAAIC,YAAW,WAAW,EAAG,QAAO;AAWpC,QAAM,SAAS,kBAAkB,aAAa,oBAAoB;AAClE,MAAI,QAAQ;AACV,UAAM,gBAAgBD,SAAQ,QAAQ,YAAY;AAClD,QAAIC,YAAW,aAAa,EAAG,QAAO;AAAA,EACxC;AAEA,SAAO;AACT;AASO,SAAS,kBAAkB,UAAkB,SAAgC;AAClF,MAAI,MAAMD,SAAQ,QAAQ;AAC1B,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,YAAYA,SAAQ,KAAK,gBAAgB,OAAO;AACtD,QAAIC,YAAWD,SAAQ,WAAW,cAAc,CAAC,GAAG;AAClD,aAAO;AAAA,IACT;AACA,UAAM,SAASD,SAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;;;AC1EA,SAAS,cAAAG,mBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAE9B,SAAS,SAAS,KAAsB;AACtC,SAAOF,YAAWE,MAAK,KAAK,YAAY,CAAC;AAC3C;AAMO,SAAS,mBAAkC;AAChD,QAAM,WAAW,QAAQ,IAAI,mBAAmB;AAChD,MAAI,YAAY,SAAS,QAAQ,EAAG,QAAO;AAC3C,MAAI;AACF,UAAM,WAAW,cAAc,YAAY,GAAG,EAAE,QAAQ,8BAA8B;AACtF,UAAM,OAAOA,MAAKD,SAAQ,QAAQ,GAAG,MAAM;AAC3C,WAAO,SAAS,IAAI,IAAI,OAAO;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ANRO,SAAS,sBAAsB,UAAsC;AAC1E,SAAO,aAAa,UAAU,OAAO;AACvC;AAUO,SAAS,wBACd,UACA,UACA,KACQ;AACR,MAAI,OAAO,aAAa,YAAY,OAAO,SAAS,QAAQ,EAAG,QAAO;AACtE,QAAM,UAAU,IAAI,wBAAwB;AAC5C,MAAI,WAAW,QAAQ,KAAK,MAAM,IAAI;AACpC,UAAM,SAAS,OAAO,OAAO;AAC7B,QAAI,OAAO,UAAU,MAAM,KAAK,SAAS,EAAG,QAAO;AAAA,EACrD;AACA,SAAO,sBAAsB,QAAQ;AACvC;AAOO,SAAS,cACd,QACA,QACA,gBACA,UAA6B,QAAQ,KAClB;AACnB,QAAM,eACJ,OAAO,SAAS,SAAS,aAAa,WAClC,CAAC,IACD;AAAA,IACE,iCAAiC;AAAA;AAAA,IACjC,sCAAsC;AAAA;AAAA,EACxC;AACN,SAAO;AAAA,IACL,GAAG;AAAA,IACH,gBAAgB;AAAA,IAChB,uBAAuB;AAAA;AAAA,IACvB,4BAA4B;AAAA;AAAA;AAAA;AAAA,IAG5B,wBAAwB,OAAO,cAAc;AAAA,IAC7C,GAAG;AAAA,EACL;AACF;AAEO,IAAM,aAAaE,eAAc;AAAA,EACtC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAON,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,gBAAgB;AAAA,MACd,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aACE;AAAA,IAEJ;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,EAAE,QAAQ,YAAY,IAAI,MAAM,YAAY;AAClD,UAAM,UAAU,cAAc;AAG9B,UAAM,eAAe,QAAQ,WAAW;AAExC,UAAM,MAAM,MAAM,UAAU,QAAQ,EAAE,QAAQ,CAAC;AAC/C,UAAM,EAAE,SAAS,IAAI;AAErB,QAAI,KAAK,MAAM;AACb,YAAM,WAAW,MAAM,SAAS,cAAc,MAAM,YAAY;AAAA,QAC9D,cAAc,EAAE,OAAO,WAAW,OAAO,OAAO,MAAM,KAAK;AAAA,QAC3D,OAAO;AAAA,MACT,CAAC;AACD,UAAI,SAAS,MAAM,WAAW,GAAG;AAC/B,iBAAS,OAAO,KAAK,CAAC,GAAG,kCAAkC;AAC3D,cAAM,QAAQ;AAAA,UACZ;AAAA,UACA,cAAc,SAAS;AAAA,UACvB,eAAe,SAAS;AAAA,UACxB,UAAU,SAAS;AAAA,UACnB,QAAQ,SAAS;AAAA,UACjB;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,OAAO,iBAAiB;AAAA,MAC5B;AAAA,MACA,QAAQ,SAAS;AAAA,MACjB,eAAe,SAAS;AAAA,MACxB;AAAA,IACF,CAAC;AACD,UAAM,YAAY,iBAAiB;AACnC,QAAI,cAAc,MAAM;AAEtB,cAAQ;AAAA,QACN,GAAG;AAAA,UACD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,IAAI,WAAW,KAAK,SAAS,EAAE,UAAU,CAAC;AAChD,UAAM,KAAK,MAAM;AAEjB,QAAI,KAAK,SAAS;AAChB,YAAMC,YAAW,OAAO,WAAmB;AACzC,iBAAS,OAAO,KAAK,EAAE,OAAO,GAAG,mBAAmB;AACpD,cAAM,KAAK,KAAK,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAChC,cAAM,IAAI,KAAK,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAC/B,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,cAAQ,GAAG,UAAU,MAAM,KAAKA,UAAS,QAAQ,CAAC;AAClD,cAAQ,GAAG,WAAW,MAAM,KAAKA,UAAS,SAAS,CAAC;AAEpD;AAAA,IACF;AAKA,UAAM,cAAc,KAAK;AACzB,UAAM,WACJ,OAAO,gBAAgB,YAAY,YAAY,KAAK,MAAM,KAAK,OAAO,WAAW,IAAI;AACvF,UAAM,YAAY,wBAAwB,OAAO,UAAU,UAAU,QAAQ,GAAG;AAChF,UAAM,iBAAiB,MAAM,aAAa,SAAS;AACnD,QAAI,mBAAmB,WAAW;AAEhC,cAAQ;AAAA,QACN,GAAG;AAAA,UACD,0BAAqB,SAAS,6BAA6B,GAAG,KAAK,OAAO,cAAc,CAAC,CAAC;AAAA,QAC5F;AAAA,MACF;AAAA,IACF;AAKA,UAAM,SAAS,mBAAmB,aAAa,OAAO,UAAU,cAAc;AAE9E,UAAM,SAAS,oBAAoB,OAAO,KAAK,IAAI;AACnD,UAAM,gBAAgB,oBAAoB,cAAc;AAExD,YAAQ;AAAA,MACN,GAAG;AAAA,QACD,+BAA0B,GAAG,KAAK,OAAO,QAAQ,CAAC,KAAK,OAAO,IAAI,QAAQ,GAAG,KAAK,aAAa,CAAC;AAAA,MAClG;AAAA,IACF;AAEA,YAAQ,IAAI,GAAG,IAAI,UAAU,MAAM,EAAE,CAAC;AAEtC,UAAM,eAAe,IAAI,OAAO,SAAS,OAAO,MAAM;AAAA,MACpD,KAAK,OAAO;AAAA,MACZ,KAAK,cAAc,QAAQ,QAAQ,cAAc;AAAA,IACnD,CAAC;AAED,UAAM,WAAW,OAAO,WAAmB;AACzC,eAAS,OAAO,KAAK,EAAE,OAAO,GAAG,eAAe;AAChD,UAAI;AACF,qBAAa,MAAM,KAAK,QAAQ;AAAA,MAClC,QAAQ;AAAA,MAER;AACA,YAAM,KAAK,KAAK,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAChC,YAAM,IAAI,KAAK,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAC/B,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,YAAQ,GAAG,UAAU,MAAM,KAAK,SAAS,QAAQ,CAAC;AAClD,YAAQ,GAAG,WAAW,MAAM,KAAK,SAAS,SAAS,CAAC;AAEpD,UAAM,eAAe,MAAM,aAAa;AACxC,aAAS,OAAO,KAAK,EAAE,MAAM,aAAa,GAAG,yBAAyB;AACtE,UAAM,SAAS,eAAe;AAAA,EAChC;AACF,CAAC;;;AOxND,SAAS,iBAAAC,sBAAqB;AAKvB,IAAM,eAAeC,eAAc;AAAA,EACxC,MAAM,EAAE,MAAM,SAAS,aAAa,8CAA8C;AAAA,EAClF,MAAM,MAAM;AACV,UAAM,EAAE,QAAQ,YAAY,IAAI,MAAM,YAAY;AAClD,QAAI,CAAC,eAAe,aAAa,OAAO,QAAQ,GAAG;AAEjD,YAAM,UAAU,QAAQ,CAAC,YAAY,kBAAkB,OAAO,QAAQ,GAAG,OAAO,GAAG;AAAA,QACjF,KAAK;AAAA,MACP,CAAC;AACD;AAAA,IACF;AACA,UAAM,UAAU,OAAO,aAAa,UAAU,UAAU;AACxD,UAAM,MAAM,gBAAgB,aAAa,OAAO;AAChD,QAAI,CAAC,KAAK;AACR,YAAM,IAAI;AAAA,QACR,mBAAmB,OAAO,cAAc,WAAW;AAAA,MAErD;AAAA,IACF;AACA,UAAM,UAAU,KAAK,CAAC,OAAO,GAAG,EAAE,KAAK,YAAY,CAAC;AAAA,EACtD;AACF,CAAC;;;AC1BD,SAAS,iBAAAC,sBAAqB;AAE9B,SAAS,gBAAgB,WAAAC,gBAAe;AAIjC,IAAM,cAAcC,eAAc;AAAA,EACvC,MAAM,EAAE,MAAM,QAAQ,aAAa,8CAA8C;AAAA,EACjF,MAAM,MAAM;AACV,UAAM,EAAE,QAAQ,YAAY,IAAI,MAAM,YAAY;AAElD,UAAM,eAAe,QAAQ,WAAW;AACxC,UAAM,WAAW,eAAe,MAAM;AACtC,QAAI;AACF,YAAM,SAAS,MAAMC,SAAQ;AAAA,QAC3B;AAAA,QACA,cAAc,SAAS;AAAA,QACvB,eAAe,SAAS;AAAA,QACxB,UAAU,SAAS;AAAA,QACnB,QAAQ,SAAS;AAAA,QACjB,SAAS,cAAc;AAAA,MACzB,CAAC;AAED,cAAQ;AAAA,QACN,OAAO,gBACH,yDACA,iBAAY,OAAO,QAAQ,oBAAoB,OAAO,UAAU;AAAA,MACtE;AAAA,IACF,UAAE;AACA,YAAM,SAAS,MAAM;AAAA,IACvB;AAAA,EACF;AACF,CAAC;;;AChCD,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,OAAO,OAAO,MAAM,QAAQ,SAAS,UAAU,cAAc;AACtE,YAAY,OAAO;AAEnB,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,sBAAsB,mBAA0D;AACzF,SAAS,QAAAC,aAAY;AAGd,IAAM,gBAAgBC,eAAc;AAAA,EACzC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,KAAK;AAAA,MACH,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,KAAK;AAAA,MACH,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,IAAI;AAAA,MACF,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,EAAE,OAAO,IAAI,MAAM,YAAY;AACrC,UAAM,cAAc,QAAQ,IAAI;AAChC,UAAM,YAAYC,MAAK,aAAa,wBAAwB;AAC5D,UAAM,QAAQ,QAAQ,MAAM,SAAS;AAErC,UAAQ,OAAK,eAAe,CAAC;AAG7B,QAAI,SAAS,KAAK;AAClB,QAAI,CAAC,QAAQ;AACX,UAAI,CAAC,OAAO;AACV,gBAAQ,MAAM,oCAAoC;AAClD,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,YAAM,SAAS,MAAM,OAAO;AAAA,QAC1B,SAAS;AAAA,QACT,SAAS,CAAC,EAAE,OAAO,eAAe,OAAO,cAAc,CAAC;AAAA,MAC1D,CAAC;AACD,UAAI,SAAS,MAAM,GAAG;AAAE,eAAO,kBAAkB;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AACpE,eAAS,OAAO,MAAM;AAAA,IACxB;AACA,QAAI,WAAW,eAAe;AAC5B,cAAQ,MAAM,uBAAuB,MAAM,oCAAoC;AAC/E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,QAAI,WAAW,KAAK;AACpB,QAAI,CAAC,UAAU;AACb,UAAI,CAAC,OAAO;AAAE,gBAAQ,MAAM,mBAAmB;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AAClE,YAAM,MAAM,MAAM,KAAK,EAAE,SAAS,cAAc,aAAa,uBAAuB,UAAU,CAAC,MAAM,EAAE,WAAW,MAAM,IAAI,SAAY,gBAAgB,CAAC;AACzJ,UAAI,SAAS,GAAG,GAAG;AAAE,eAAO,kBAAkB;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AACjE,iBAAW,OAAO,GAAG;AAAA,IACvB;AAEA,QAAI,cAAc,KAAK,OAAO,QAAQ,IAAI,iBAAiB,KAAK;AAChE,QAAI,CAAC,aAAa;AAChB,UAAI,CAAC,OAAO;AAAE,gBAAQ,MAAM,sCAAsC;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AACrF,YAAM,MAAM,MAAM,KAAK,EAAE,SAAS,iBAAiB,aAAa,SAAS,CAAC;AAC1E,UAAI,SAAS,GAAG,GAAG;AAAE,eAAO,kBAAkB;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AACjE,oBAAc,OAAO,GAAG;AAAA,IAC1B;AAEA,QAAI,iBAAiB,KAAK,UAAU,QAAQ,IAAI,oBAAoB,KAAK;AACzE,QAAI,CAAC,gBAAgB;AACnB,UAAI,CAAC,OAAO;AAAE,gBAAQ,MAAM,4CAA4C;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AAC3F,YAAM,MAAM,MAAM,KAAK,EAAE,SAAS,oBAAoB,aAAa,SAAS,CAAC;AAC7E,UAAI,SAAS,GAAG,GAAG;AAAE,eAAO,kBAAkB;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AACjE,uBAAiB,OAAO,GAAG;AAAA,IAC7B;AAGA,QAAI;AACJ,QAAI,KAAK,UAAU;AACjB,mBAAa,KAAK,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,IAC3D,OAAO;AACL,mBAAa,CAAC,cAAc,YAAY,aAAa,QAAQ;AAAA,IAC/D;AAEA,UAAM,cAAc,SAAS,OAAO,KAAK,eAAe,GAAG,GAAG,EAAE;AAChE,UAAM,YAAY,KAAK,OAAO;AAC9B,UAAM,cAAc,KAAK,SAAS;AAGlC,UAAM,WAAW,QAAQ;AACzB,aAAS,MAAM,yBAAoB;AACnC,UAAM,MAAM,MAAMC,WAAU,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;AAChE,aAAS,KAAK,gBAAgB;AAE9B,QAAI;AACF,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,UACE,aAAa,EAAE,KAAK,UAAU,aAAa,eAAe;AAAA,UAC1D,UAAU;AAAA,UACV,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,KAAK;AAAA,UACZ;AAAA,UACA;AAAA,UACA,UAAU,OAAO,MAAM;AAAA,UACvB;AAAA,QACF;AAAA,QACA;AAAA,UACE,UAAU,IAAI;AAAA,UACd,OAAO,IAAI;AAAA,UACX,UAAU,EAAE,IAAI,IAAI,SAAS,IAAI,SAAS,IAAI,SAAS,QAAQ;AAAA,UAC/D,WAAW,OAAsB;AAC/B,gBAAI,MAAM,SAAS,SAAS;AAC1B,sBAAQ,IAAM,OAAK,YAAO,MAAM,KAAK,EAAE,CAAC;AAAA,YAC1C,WAAW,MAAM,SAAS,YAAY;AACpC,oBAAM,MAAM,KAAK,MAAO,MAAM,OAAO,MAAM,QAAS,GAAG;AACvD,sBAAQ,OAAO,MAAM,OAAO,MAAM,MAAM,KAAK,MAAM,IAAI,IAAI,MAAM,KAAK,KAAK,GAAG,MAAM;AACpF,kBAAI,MAAM,SAAS,MAAM,MAAO,SAAQ,OAAO,MAAM,IAAI;AAAA,YAC3D,WAAW,MAAM,SAAS,SAAS;AACjC,sBAAQ,IAAM,MAAI,YAAO,MAAM,KAAK,KAAK,MAAM,EAAE,MAAM,MAAM,OAAO,EAAE,CAAC;AAAA,YACzE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,aAAa,MAAM,YAAY,QAAQ,aAAa,OAAO,MAAM,IAAI;AAE3E;AAAA,QACE;AAAA,UACI,QAAM,wBAAmB;AAAA,UAC3B,iBAAiB,OAAO,SAAS,QAAQ;AAAA,UACzC,iBAAiB,OAAO,SAAS,SAAS;AAAA,UAC1C,iBAAiB,OAAO,SAAS,MAAM;AAAA,UACvC,iBAAiB,OAAO,SAAS,UAAU;AAAA,UAC3C,GAAI,YAAY,CAAC,kBAAkB,OAAO,SAAS,QAAQ,WAAW,IAAI,CAAC;AAAA,UAC3E,GAAI,OAAO,OAAO,SAAS,IAAI,CAAG,SAAO,YAAO,OAAO,OAAO,MAAM,2BAAsB,CAAC,IAAI,CAAC;AAAA,UAChG;AAAA,UACA,aAAa,UAAU;AAAA,UACvB,aAAe,OAAK,YAAY,CAAC;AAAA,QACnC,EAAE,KAAK,IAAI;AAAA,MACb;AAAA,IACF,UAAE;AACA,YAAM,IAAI,KAAK;AAAA,IACjB;AAAA,EACF;AACF,CAAC;;;AChLD,SAAS,iBAAAC,sBAAqB;AAC9B,OAAOC,SAAQ;AAEf,SAAS,mBAAmB;AAErB,IAAM,wBAAwBC,eAAc;AAAA,EACjD,MAAM,EAAE,MAAM,mBAAmB,aAAa,4BAA4B;AAAA,EAC1E,MAAM,MAAM;AACV,QAAI;AACF,YAAM,EAAE,QAAQ,KAAK,IAAI,MAAM,YAAY;AAE3C,cAAQ,IAAIC,IAAG,MAAM,qBAAgB,IAAI,KAAK,IAAI,GAAG;AAErD,cAAQ;AAAA,QACN,eAAe,OAAO,QAAQ,YAAY,OAAO,eAAe,KAAK,mBAAmB,OAAO,eAAe,YAAY;AAAA,MAC5H;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB,SAAS,KAAK;AACZ,UAAI,eAAe,aAAa;AAE9B,gBAAQ,MAAMA,IAAG,IAAI,uBAAkB,CAAC;AAExC,gBAAQ,MAAM,IAAI,OAAO;AAAA,MAC3B,OAAO;AAEL,gBAAQ,MAAM,GAAG;AAAA,MACnB;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF,CAAC;;;AC9BD,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,cAAAC,mBAAkB;AAGpB,IAAM,cAAcC,eAAc;AAAA,EACvC,MAAM,EAAE,MAAM,QAAQ,aAAa,wCAAwC;AAAA,EAC3E,MAAM,MAAM;AACV,UAAM,UAAU,QAAQ,CAAC,UAAU,KAAK,CAAC;AAAA,EAC3C;AACF,CAAC;AAEM,IAAM,iBAAiBA,eAAc;AAAA,EAC1C,MAAM,EAAE,MAAM,YAAY,aAAa,qDAAqD;AAAA,EAC5F,MAAM,MAAM;AACV,UAAM,EAAE,OAAO,IAAI,MAAMC,YAAW;AACpC,UAAM,UAAU,QAAQ;AAAA,MACtB;AAAA,MAAY;AAAA,MAAiB;AAAA,MAC7B;AAAA,MAAc;AAAA,MAAQ;AAAA,MAAa,OAAO;AAAA,MAAU;AAAA,MAAiB;AAAA,IACvE,CAAC;AAAA,EACH;AACF,CAAC;AAEM,IAAM,oBAAoBD,eAAc;AAAA,EAC7C,MAAM,EAAE,MAAM,eAAe,aAAa,4DAA4D;AAAA,EACtG,MAAM;AAAA,IACJ,oBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,EAAE,OAAO,IAAI,MAAMC,YAAW;AACpC,UAAM,OAAO,CAAC,CAAC,QAAQ,IAAI;AAC3B,UAAM,kBAAkB,KAAK,kBAAkB;AAE/C,QAAI,mBAAmB,CAAC,MAAM;AAE5B,YAAM,cAAc;AACpB,YAAM,MAAM,QAAQ,IAAI;AACxB,YAAM,UAAU,UAAU;AAAA,QACxB;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAM,GAAG,GAAG,IAAI,GAAG;AAAA,QAAI;AAAA,QAAM;AAAA,QAC5C;AAAA,QAAa;AAAA,QAAM;AAAA,QACnB,8DAA8D,OAAO,QAAQ;AAAA,MAC/E,CAAC;AAAA,IACH,OAAO;AACL,YAAM,SAAS;AAAA,QACb;AAAA,QAAY;AAAA,QAAiB;AAAA,QAC7B;AAAA,QAAc;AAAA,QAAQ;AAAA,QAAa,OAAO;AAAA,QAAU;AAAA,QAAU;AAAA,MAChE;AACA,UAAI,gBAAiB,QAAO,KAAK,oBAAoB;AACrD,YAAM,UAAU,QAAQ,MAAM;AAAA,IAChC;AAAA,EACF;AACF,CAAC;AAEM,IAAM,uBAAuBD,eAAc;AAAA,EAChD,MAAM,EAAE,MAAM,kBAAkB,aAAa,6BAA6B;AAAA,EAC1E,MAAM;AAAA,IACJ,SAAS,EAAE,MAAM,UAAU,aAAa,mEAAmE;AAAA,EAC7G;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,QAAQ;AAAA,MACZ;AAAA,MAAU;AAAA,MACV;AAAA,MAAa;AAAA,IACf;AACA,QAAI,KAAK,SAAS;AAEhB,YAAM,KAAK,mBAAmB,OAAO,KAAK,OAAO,CAAC,UAAU;AAAA,IAC9D;AACA,UAAM,UAAU,QAAQ,KAAK;AAAA,EAC/B;AACF,CAAC;AAEM,IAAM,yBAAyBA,eAAc;AAAA,EAClD,MAAM,EAAE,MAAM,oBAAoB,aAAa,oDAAoD;AAAA,EACnG,MAAM,MAAM;AACV,UAAM,EAAE,OAAO,IAAI,MAAMC,YAAW;AACpC,UAAM,OAAO,OAAO,aAAa,WAAW,MAAO;AACnD,UAAM,UAAU,QAAQ,CAAC,QAAQ,SAAS,GAAG;AAAA,MAC3C,KAAK;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,iBAAiB,OAAO;AAAA,QACxB,sBAAsB,OAAO,IAAI;AAAA,MACnC;AAAA,IACF,CAAC;AAAA,EACH;AACF,CAAC;AAEM,IAAM,iBAAiBD,eAAc;AAAA,EAC1C,MAAM,EAAE,MAAM,YAAY,aAAa,yDAAyD;AAAA,EAChG,MAAM,MAAM;AACV,UAAM,QAAiD;AAAA,MACrD,EAAE,MAAM,QAAQ,MAAM,CAAC,UAAU,KAAK,EAAE;AAAA,MACxC,EAAE,MAAM,aAAa,MAAM,CAAC,UAAU,OAAO,aAAa,kBAAkB,EAAE;AAAA,IAChF;AAEA,eAAW,QAAQ,OAAO;AACxB,YAAM,EAAE,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI;AACtC,YAAM,OAAO,MAAM;AACnB,UAAI,SAAS,GAAG;AAEd,gBAAQ,MAAM,UAAK,KAAK,IAAI,SAAS;AACrC,gBAAQ,KAAK,IAAI;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,EAAE,OAAO,IAAI,MAAMC,YAAW;AACpC,UAAM,UAAU,QAAQ;AAAA,MACtB;AAAA,MAAY;AAAA,MAAiB;AAAA,MAC7B;AAAA,MAAc;AAAA,MAAQ;AAAA,MAAa,OAAO;AAAA,MAAU;AAAA,MAAiB;AAAA,IACvE,CAAC;AACD,UAAM,UAAU,QAAQ;AAAA,MACtB;AAAA,MAAY;AAAA,MAAiB;AAAA,MAC7B;AAAA,MAAc;AAAA,MAAQ;AAAA,MAAa,OAAO;AAAA,MAAU;AAAA,MAAU;AAAA,IAChE,CAAC;AACD,UAAM,UAAU,QAAQ,CAAC,QAAQ,SAAS,GAAG;AAAA,MAC3C,KAAK,EAAE,GAAG,QAAQ,KAAK,iBAAiB,OAAO,SAAS;AAAA,IAC1D,CAAC;AAAA,EACH;AACF,CAAC;;;AbrGD,IAAM,OAAOC,eAAc;AAAA,EACzB,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,cAAc;AAAA,IACvB,aAAa;AAAA,EACf;AAAA,EACA,aAAa;AAAA,IACX,KAAK;AAAA,IACL,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,YAAY;AAAA,EACd;AACF,CAAC;AAGD,IAAM,CAAC,MAAM,GAAG,IAAI,IAAI,QAAQ,KAAK,MAAM,CAAC;AAC5C,IAAI,KAAK,WAAW,MAAM,SAAS,eAAe,SAAS,OAAO;AAChE,UAAQ,OAAO,MAAM,GAAG,cAAc,CAAC;AAAA,CAAI;AAC7C,OAAO;AACL,UAAQ,IAAI;AACd;","names":["defineCommand","defineCommand","dirname","resolve","resolve","existsSync","resolve","dirname","resolve","existsSync","existsSync","dirname","join","defineCommand","shutdown","defineCommand","defineCommand","defineCommand","runSeed","defineCommand","runSeed","defineCommand","createApp","join","defineCommand","join","createApp","defineCommand","pc","defineCommand","pc","defineCommand","loadConfig","defineCommand","loadConfig","defineCommand"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils/version.ts","../src/commands/dev.ts","../src/utils/project.ts","../src/utils/spawn.ts","../src/utils/port.ts","../src/utils/template-runner.ts","../src/commands/migrate.ts","../src/admin.ts","../src/utils/shutdown.ts","../src/commands/dev-summary.ts","../src/commands/build.ts","../src/commands/seed.ts","../src/commands/import.ts","../src/commands/config-validate.ts","../src/commands/add.ts","../src/recipes/holders.ts","../src/recipes/config-edit.ts","../src/recipes/env-example.ts","../src/commands/doctor.ts","../src/commands/doctor-report.ts","../src/commands/test.ts"],"sourcesContent":["import { defineCommand, runMain } from 'citty'\nimport { getCliVersion } from './utils/version.js'\nimport { devCommand } from './commands/dev.js'\nimport { buildCommand } from './commands/build.js'\nimport { migrateCommand } from './commands/migrate.js'\nimport { seedCommand } from './commands/seed.js'\nimport { importCommand } from './commands/import.js'\nimport { configValidateCommand } from './commands/config-validate.js'\nimport { addCommand } from './commands/add.js'\nimport { doctorCommand } from './commands/doctor.js'\nimport {\n testAllCommand,\n testCommand,\n testContractsCommand,\n testE2eCommand,\n testPerformanceCommand,\n testVisualCommand,\n} from './commands/test.js'\n\nexport { resolveAdminRoot } from './admin.js'\n\nconst main = defineCommand({\n meta: {\n name: 'nymbal',\n version: getCliVersion(),\n description: 'Nymbal developer CLI',\n },\n subCommands: {\n dev: devCommand,\n build: buildCommand,\n migrate: migrateCommand,\n seed: seedCommand,\n import: importCommand,\n 'config:validate': configValidateCommand,\n add: addCommand,\n doctor: doctorCommand,\n test: testCommand,\n 'test:e2e': testE2eCommand,\n 'test:visual': testVisualCommand,\n 'test:contracts': testContractsCommand,\n 'test:performance': testPerformanceCommand,\n 'test:all': testAllCommand,\n },\n})\n\n// citty prints --version through consola, which prefixes `[log]` when CI is set; scripts need the bare version.\nconst [flag, ...rest] = process.argv.slice(2)\nif (rest.length === 0 && (flag === '--version' || flag === '-v')) {\n process.stdout.write(`${getCliVersion()}\\n`)\n} else {\n runMain(main)\n}\n","import { readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst CLI_PACKAGE_NAME = 'nymbal'\n\nlet cached: string | null = null\n\n/**\n * Walks up from this module to the CLI's own package.json (found by name, so a nested or unrelated package.json\n * never answers). That is `dist/` in the workspace and in `node_modules/nymbal`, and `src/utils/` under Vitest.\n */\nfunction readOwnVersion(): string | undefined {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as {\n name?: string\n version?: string\n }\n if (pkg.name === CLI_PACKAGE_NAME) return pkg.version\n } catch {\n // No readable package.json in this directory: keep walking.\n }\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport function getCliVersion(): string {\n cached ??= readOwnVersion() ?? '0.0.0'\n return cached\n}\n","import { resolve } from 'node:path'\nimport { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport { KNOWN_PROVIDERS, type NymbalConfig } from '@nymbalhq/config'\nimport type { CommerceSlot } from '@nymbalhq/types'\nimport { loadProject } from '../utils/project.js'\nimport { createApp, createLogger, runSeed, sqliteFile, type NymbalApp } from '@nymbalhq/platform'\nimport { createHttpServer } from '@nymbalhq/http'\nimport { run } from '../utils/spawn.js'\nimport { getCliVersion } from '../utils/version.js'\nimport { findFreePort } from '../utils/port.js'\nimport { planTemplateLaunch } from '../utils/template-runner.js'\nimport { migrateProject } from './migrate.js'\nimport { resolveAdminRoot } from '../admin.js'\nimport { runShutdown, SHUTDOWN_BOUND_MS, type ShutdownStep } from '../utils/shutdown.js'\nimport { renderDevSummary, type DevSummaryInfo } from './dev-summary.js'\n\n/** Default storefront dev-server port per template (matches the scaffold scripts). */\nexport function defaultStorefrontPort(template: 'astro' | 'nextjs'): number {\n return template === 'astro' ? 4321 : 3000\n}\n\n/**\n * Resolve the *preferred* storefront port from (in priority order):\n * 1. --storefront-port flag\n * 2. NYMBAL_STOREFRONT_PORT env var\n * 3. the template default (Astro 4321 / Next.js 3000)\n * The value returned here is only the starting point; the dev command then\n * probes upward for a genuinely free port so a busy default never hard-fails.\n */\nexport function preferredStorefrontPort(\n template: 'astro' | 'nextjs',\n flagPort: number | undefined,\n env: NodeJS.ProcessEnv,\n): number {\n if (typeof flagPort === 'number' && Number.isFinite(flagPort)) return flagPort\n const fromEnv = env['NYMBAL_STOREFRONT_PORT']\n if (fromEnv && fromEnv.trim() !== '') {\n const parsed = Number(fromEnv)\n if (Number.isInteger(parsed) && parsed > 0) return parsed\n }\n return defaultStorefrontPort(template)\n}\n\n/**\n * The environment the storefront dev server starts with. The client-side variables must be set before it starts. It\n * says nothing about the adapters: a storefront learns what the store can do from GET /api/capabilities.\n */\nexport function storefrontEnv(\n _config: NymbalConfig,\n apiUrl: string,\n storefrontPort: number,\n baseEnv: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n return {\n ...baseEnv,\n NYMBAL_API_URL: apiUrl,\n PUBLIC_NYMBAL_API_URL: apiUrl, // Astro\n NEXT_PUBLIC_NYMBAL_API_URL: apiUrl, // Next.js\n // The framework also reads the port flag; the env var keeps the scaffold\n // config (astro.config.mjs) in sync when it honours NYMBAL_STOREFRONT_PORT.\n NYMBAL_STOREFRONT_PORT: String(storefrontPort),\n }\n}\n\n/** dev logs at info, so it prints the summary and not every projection; `LOG_LEVEL` wins over `--verbose`. */\nexport function devLogLevel(verbose: boolean, env: NodeJS.ProcessEnv): string {\n const fromEnv = env['LOG_LEVEL']\n if (fromEnv !== undefined && fromEnv !== '') return fromEnv\n return verbose ? 'debug' : 'info'\n}\n\n/** The summary's facts, from the running app: no URL here carries anything but what the config gave. */\nfunction summaryInfo(\n config: NymbalConfig,\n app: NymbalApp,\n apiUrl: string,\n storefront: DevSummaryInfo['storefront'],\n adminBuilt: boolean,\n): DevSummaryInfo {\n const report = app.capabilities()\n return {\n store: config.store.name,\n apiUrl,\n storefront,\n admin: adminBuilt ? { url: `${apiUrl}/admin/` } : null,\n commandStore:\n config.infrastructure.commandStore === 'sqlite'\n ? { kind: 'sqlite', path: resolve(sqliteFile()) }\n : { kind: 'postgres', url: process.env['DATABASE_URL'] ?? '' },\n slots: (Object.keys(KNOWN_PROVIDERS) as CommerceSlot[]).map((slot) => ({\n slot,\n provider: report[slot].provider,\n capabilities: report[slot].capabilities,\n })),\n primitives: (['documentStore', 'eventBus', 'media'] as const).map((name) => ({\n name,\n provider: report[name].provider,\n })),\n }\n}\n\n/** The API port: `--port` when given, else the config's `http.port`. */\nfunction apiPort(config: NymbalConfig, flagPort: string | undefined): number {\n if (flagPort === undefined || flagPort.trim() === '') return config.http.port\n const port = Number(flagPort)\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(`--port must be an integer from 1 to 65535, got \"${flagPort}\"`)\n }\n return port\n}\n\nexport const devCommand = defineCommand({\n meta: {\n name: 'dev',\n description: 'Start the API server and the configured storefront template with HMR',\n },\n args: {\n seed: {\n type: 'boolean',\n description: 'Run seed before starting (default: true if empty)',\n default: true,\n },\n apiOnly: {\n type: 'boolean',\n // `alias` is required: citty 0.1.6 registers the camelCase key `apiOnly`\n // with mri and applies `default: false`. Without this alias a kebab\n // `--api-only` flag lands on `args['api-only']`, but `args.apiOnly`\n // resolves to the `false` default first (`??` does not fall through on\n // `false`), so the flag is silently ignored. The alias makes mri map\n // `--api-only` straight to `apiOnly`. Both forms now work.\n alias: 'api-only',\n description: 'Start only the API server (skip template dev server)',\n default: false,\n },\n port: {\n type: 'string',\n description: \"Port for the API server (default: the config's http.port)\",\n },\n storefrontPort: {\n type: 'string',\n alias: 'storefront-port',\n description:\n 'Port for the storefront dev server (default: 4321 Astro / 3000 Next.js). ' +\n 'If busy, the next free port is used. Also settable via NYMBAL_STOREFRONT_PORT.',\n },\n verbose: {\n type: 'boolean',\n description: 'Log at debug (LOG_LEVEL, when set, wins)',\n default: false,\n },\n },\n async run({ args }) {\n const loaded = await loadProject()\n const { projectRoot } = loaded\n const port = apiPort(loaded.config, args.port)\n const config: NymbalConfig = { ...loaded.config, http: { ...loaded.config.http, port } }\n const version = getCliVersion()\n\n // Auto-migrate on startup so a fresh clone works without running `nymbal migrate` first\n await migrateProject(config, projectRoot)\n\n const logger = createLogger({\n base: { store: config.store.name },\n level: devLogLevel(args.verbose, process.env),\n })\n const app = await createApp(config, {\n version,\n logger,\n ...(loaded.adapters !== undefined && { adapters: loaded.adapters }),\n })\n const { platform } = app\n\n if (args.seed) {\n const existing = await platform.documentStore.query('products', {\n partitionKey: { field: 'storeId', value: config.store.name },\n limit: 1,\n })\n if (existing.items.length === 0) {\n platform.logger.info({}, 'Seeding demo content (first run)')\n await runSeed({\n config,\n commandStore: platform.commandStore,\n documentStore: platform.documentStore,\n eventBus: platform.eventBus,\n logger: platform.logger,\n version,\n })\n }\n }\n\n const http = createHttpServer({\n config,\n logger: platform.logger,\n documentStore: platform.documentStore,\n version,\n })\n const adminRoot = resolveAdminRoot()\n await app.attachHttp(http.adapter, { adminRoot })\n await http.start()\n const apiUrl = `http://localhost:${config.http.port}`\n const printSummary = (storefront: DevSummaryInfo['storefront']) => {\n // eslint-disable-next-line no-console\n console.log(renderDevSummary(summaryInfo(config, app, apiUrl, storefront, adminRoot !== null)))\n }\n\n const stopApi: ShutdownStep[] = [\n { name: 'http.stop', run: () => http.stop() },\n { name: 'app.stop', run: () => app.stop() },\n ]\n const shutdownWith = (steps: ShutdownStep[]): Promise<never> =>\n runShutdown(steps, {\n boundMs: SHUTDOWN_BOUND_MS,\n logger: platform.logger,\n exit: (code) => process.exit(code),\n })\n\n if (args.apiOnly) {\n printSummary(null)\n const shutdown = (signal: string) => {\n platform.logger.info({ signal }, 'Shutting down API')\n return shutdownWith(stopApi)\n }\n process.on('SIGINT', () => void shutdown('SIGINT'))\n process.on('SIGTERM', () => void shutdown('SIGTERM'))\n // Keep process alive — Playwright webServer will kill it when done\n return\n }\n\n // Resolve a free storefront port. The preferred port is configurable but may\n // be taken (a developer commonly has another project on 4321/3000), so we\n // probe upward for a free one instead of hard-failing.\n const flagPortRaw = args.storefrontPort\n const flagPort =\n typeof flagPortRaw === 'string' && flagPortRaw.trim() !== '' ? Number(flagPortRaw) : undefined\n const preferred = preferredStorefrontPort(config.template, flagPort, process.env)\n const storefrontPort = await findFreePort(preferred)\n if (storefrontPort !== preferred) {\n // eslint-disable-next-line no-console\n console.log(\n pc.yellow(\n `→ Storefront port ${preferred} is busy; using free port ${pc.bold(String(storefrontPort))} instead.`,\n ),\n )\n }\n\n // Plan how to launch the storefront. A flat scaffold (create-nymbal-app\n // output) runs the framework dev server directly in the project root; a\n // monorepo layout falls back to a pnpm --filter on the template package.\n const launch = planTemplateLaunch(projectRoot, config.template, storefrontPort)\n\n const storefrontUrl = `http://localhost:${storefrontPort}`\n const templateProc = run(launch.command, launch.args, {\n cwd: launch.cwd,\n env: storefrontEnv(config, apiUrl, storefrontPort),\n })\n printSummary({ template: `${config.template}, ${launch.mode}`, url: storefrontUrl })\n\n let shuttingDown = false\n const shutdown = (signal: string) => {\n shuttingDown = true\n platform.logger.info({ signal }, 'Shutting down')\n return shutdownWith([\n {\n name: 'storefront.kill',\n run: async () => {\n templateProc.child.kill('SIGINT')\n },\n },\n ...stopApi,\n ])\n }\n process.on('SIGINT', () => void shutdown('SIGINT'))\n process.on('SIGTERM', () => void shutdown('SIGTERM'))\n\n const templateExit = await templateProc.done\n platform.logger.info({ code: templateExit }, 'Template process exited')\n // A Ctrl-C reaches the storefront too, so it exits during the signal's own shutdown, which ends the process.\n // Calling `runShutdown` again would count as a repeat signal and exit 1 at once.\n if (shuttingDown) return\n await shutdown('template-exit')\n },\n})\n","import { existsSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { findConfigFile, loadConfig, type LoadedConfig } from '@nymbalhq/config'\n\n/**\n * Loads `<projectRoot>/.env` into the process environment, then the project's config, so `env()` calls in\n * `nymbal.config.ts` see it. A variable already set in the environment is kept: `process.loadEnvFile` never overrides.\n */\nexport async function loadProject(startDir: string = process.cwd()): Promise<LoadedConfig> {\n const configPath = findConfigFile(startDir)\n if (configPath) {\n const envFile = resolve(dirname(configPath), '.env')\n if (existsSync(envFile)) process.loadEnvFile(envFile)\n }\n return loadConfig(startDir)\n}\n","import { spawn, type ChildProcess, type SpawnOptions } from 'node:child_process'\n\nexport interface RunOptions extends SpawnOptions {\n name?: string\n}\n\nexport function run(\n command: string,\n args: string[],\n options: RunOptions = {},\n): { child: ChildProcess; done: Promise<number> } {\n const child = spawn(command, args, {\n stdio: 'inherit',\n shell: false,\n ...options,\n })\n const done = new Promise<number>((resolve, reject) => {\n child.on('error', reject)\n child.on('exit', (code) => resolve(code ?? 0))\n })\n return { child, done }\n}\n\nexport async function runOrFail(\n command: string,\n args: string[],\n options: RunOptions = {},\n): Promise<void> {\n const { done } = run(command, args, options)\n const code = await done\n if (code !== 0) {\n throw new Error(`${command} ${args.join(' ')} exited with code ${code}`)\n }\n}\n","import { createServer } from 'node:net'\n\n/**\n * Resolve a usable storefront port.\n *\n * The headline `nymbal dev` flow must not hard-fail when the preferred port is\n * already taken (a developer commonly has another project on 4321/3000). We\n * probe the preferred port first and, if it is busy, increment until we find a\n * free one — exactly how the underlying dev servers (Astro, Next.js) behave on\n * their own, but here we resolve the port *before* spawning so we can tell the\n * storefront which port to bind and tell the user where to open the browser.\n */\nexport async function isPortFree(port: number, host?: string): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const server = createServer()\n server.once('error', (err: NodeJS.ErrnoException) => {\n // EADDRINUSE / EACCES → not usable. Any other error → treat as not free\n // rather than silently swallowing it; the caller will skip this port.\n if (err.code !== 'EADDRINUSE' && err.code !== 'EACCES') {\n // eslint-disable-next-line no-console\n console.error(`[dev] unexpected error probing port ${port}:`, err.message)\n }\n resolve(false)\n })\n server.once('listening', () => {\n server.close(() => resolve(true))\n })\n // Bind across all interfaces (no explicit host) so a port already held on\n // IPv6 (e.g. another dev server on [::1]) is correctly seen as busy. A\n // 127.0.0.1-only probe would miss an IPv6 listener and wrongly report free,\n // then the framework — which binds dual-stack — would fail on that port.\n if (host) {\n server.listen(port, host)\n } else {\n server.listen(port)\n }\n })\n}\n\n/**\n * Find a free port starting at `preferred`, scanning upward up to `maxAttempts`\n * times. Throws an actionable error if no port in the range is free.\n */\nexport async function findFreePort(\n preferred: number,\n maxAttempts = 20,\n host?: string,\n): Promise<number> {\n if (!Number.isInteger(preferred) || preferred < 1 || preferred > 65535) {\n throw new Error(\n `Invalid storefront port \"${preferred}\". Set a valid port (1–65535) via --storefront-port or NYMBAL_STOREFRONT_PORT.`,\n )\n }\n for (let i = 0; i < maxAttempts; i++) {\n const candidate = preferred + i\n if (candidate > 65535) break\n if (await isPortFree(candidate, host)) {\n return candidate\n }\n }\n throw new Error(\n `No free storefront port found in range ${preferred}–${Math.min(preferred + maxAttempts - 1, 65535)}. ` +\n `Free a port in that range or pass an explicit free port via --storefront-port.`,\n )\n}\n","import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { NymbalConfig } from '@nymbalhq/config'\n\nexport type TemplateName = 'astro' | 'nextjs'\n\nexport interface TemplateLaunch {\n /** Working directory the storefront dev server runs in. */\n cwd: string\n /** Command + args to start the storefront dev server. */\n command: string\n args: string[]\n /**\n * How the storefront was located. `flat` = the project root IS the storefront\n * (create-nymbal-app output). `filter` = a sub-package in a monorepo layout.\n */\n mode: 'flat' | 'filter'\n}\n\nexport function templateFilterFor(template: NymbalConfig['template']): string {\n return template === 'astro' ? '@nymbalhq/template-astro' : '@nymbalhq/template-nextjs'\n}\n\n/**\n * A flat scaffold (create-nymbal-app output) places the storefront AT the\n * project root: the framework config and a `dev` script live in projectRoot.\n * In that layout we must run the dev server in projectRoot directly — NOT via\n * `pnpm --filter @nymbalhq/template-astro`, which would match the workspace\n * template package (the wrong directory) inside a monorepo, or match nothing at\n * all outside one.\n */\nexport function isFlatScaffold(projectRoot: string, template: TemplateName): boolean {\n const marker = template === 'astro' ? 'astro.config.mjs' : 'next.config.mjs'\n const altMarker = template === 'astro' ? 'astro.config.ts' : 'next.config.ts'\n return existsSync(resolve(projectRoot, marker)) || existsSync(resolve(projectRoot, altMarker))\n}\n\n/**\n * Resolve the framework's local CLI bin inside the project's node_modules.\n * We spawn the local bin directly (rather than the package-manager `run dev`\n * script) so we can inject the resolved free port via `--port`, overriding the\n * hardcoded port baked into the scaffold's `dev` script. Returns null when the\n * bin is not present (deps not installed) so the caller can produce an\n * actionable error.\n */\nexport function resolveLocalBin(projectRoot: string, bin: string): string | null {\n const binPath = resolve(projectRoot, 'node_modules', '.bin', bin)\n return existsSync(binPath) ? binPath : null\n}\n\n/**\n * Build the storefront dev launch plan.\n *\n * @param storefrontPort - the resolved (free) port the storefront must bind to.\n * Passed to the framework via flag so we control where it listens, instead of\n * relying on the framework's hardcoded default which may already be taken.\n */\nexport function planTemplateLaunch(\n projectRoot: string,\n template: TemplateName,\n storefrontPort: number,\n): TemplateLaunch {\n if (isFlatScaffold(projectRoot, template)) {\n // Run the framework dev server directly in the project root. We pass the\n // port explicitly so the framework binds where we resolved a free port,\n // overriding any hardcoded port in the scaffold's package.json script.\n const binName = template === 'astro' ? 'astro' : 'next'\n const localBin = resolveLocalBin(projectRoot, binName)\n if (!localBin) {\n throw new Error(\n `Cannot find the ${binName} dev server in ${projectRoot}/node_modules/.bin. ` +\n `Install dependencies first (e.g. \\`pnpm install\\`), then re-run \\`nymbal dev\\`.`,\n )\n }\n return {\n cwd: projectRoot,\n command: localBin,\n args: ['dev', '--port', String(storefrontPort), ...foregroundArgs(template)],\n mode: 'flat',\n }\n }\n\n // Monorepo layout fallback: the storefront lives in a workspace sub-package.\n const filter = templateFilterFor(template)\n return {\n cwd: projectRoot,\n command: 'pnpm',\n args: ['--filter', filter, 'dev', ...foregroundArgs(template)],\n mode: 'filter',\n }\n}\n\n/**\n * Astro 7 backgrounds `astro dev` when it detects an AI agent, so the launcher would see its child exit while the\n * server lives on detached; --ignore-lock keeps it in the foreground. `next dev` rejects unknown options.\n */\nfunction foregroundArgs(template: TemplateName): string[] {\n return template === 'astro' ? ['--ignore-lock'] : []\n}\n","import { defineCommand } from 'citty'\nimport type { NymbalConfig } from '@nymbalhq/config'\nimport { loadProject } from '../utils/project.js'\nimport { createCommandStore, runMigrations } from '@nymbalhq/platform'\nimport { dirname, resolve } from 'node:path'\nimport { existsSync } from 'node:fs'\n\nexport const migrateCommand = defineCommand({\n meta: { name: 'migrate', description: 'Run database migrations (Drizzle)' },\n async run() {\n const { config, projectRoot } = await loadProject()\n const kind = await migrateProject(config, projectRoot)\n // eslint-disable-next-line no-console\n console.log(`✓ migrations applied (${kind})`)\n },\n})\n\n/** Applies the project's migrations to its command store; the store is closed again before returning. */\nexport async function migrateProject(config: NymbalConfig, projectRoot: string): Promise<string> {\n const store = createCommandStore(config)\n try {\n await runMigrations(store, { migrationsRoot: resolveMigrations(projectRoot) })\n return store.kind\n } finally {\n await store.close()\n }\n}\n\nexport function resolveMigrations(projectRoot: string): string {\n // 1. Project-local override (scaffolded projects or custom migrations)\n const local = resolve(projectRoot, 'migrations')\n if (existsSync(local)) return local\n\n // 2. Monorepo workspace: packages/platform/migrations (for CI and fresh clones)\n const monorepoDev = resolve(projectRoot, 'packages/platform/migrations')\n if (existsSync(monorepoDev)) return monorepoDev\n\n // 3. Published package: node_modules/@nymbalhq/platform/migrations\n //\n // We must NOT use `require.resolve('@nymbalhq/platform/package.json')` nor\n // `require.resolve('@nymbalhq/platform')`: the package's `exports` map is\n // ESM-only and does not expose `./package.json`, so CJS resolution throws\n // (ERR_PACKAGE_PATH_NOT_EXPORTED / \"No exports main defined\"). Instead we\n // locate the installed package directory directly under node_modules, which\n // is independent of the exports map and works for symlinked (pnpm workspace)\n // and flat installs alike.\n const pkgDir = resolvePackageDir(projectRoot, '@nymbalhq/platform')\n if (pkgDir) {\n const pkgMigrations = resolve(pkgDir, 'migrations')\n if (existsSync(pkgMigrations)) return pkgMigrations\n }\n\n return local\n}\n\n/**\n * Resolve the on-disk root directory of an installed package from `fromRoot`,\n * by walking up the directory tree looking for `node_modules/<pkgName>`. This\n * does not depend on the package's `exports` map (which may be ESM-only and not\n * expose `./package.json`), and resolves correctly for pnpm symlinked workspace\n * installs as well as flat node_modules. Returns null when not found.\n */\nexport function resolvePackageDir(fromRoot: string, pkgName: string): string | null {\n let dir = resolve(fromRoot)\n for (let i = 0; i < 24; i++) {\n const candidate = resolve(dir, 'node_modules', pkgName)\n if (existsSync(resolve(candidate, 'package.json'))) {\n return candidate\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n","import { existsSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { dirname, join } from 'node:path'\n\nfunction hasIndex(dir: string): boolean {\n return existsSync(join(dir, 'index.html'))\n}\n\n/**\n * The admin dist to serve: `NYMBAL_ADMIN_DIST` when it holds `index.html` (read per call), else the installed\n * `@nymbalhq/admin` dist when built, else null.\n */\nexport function resolveAdminRoot(): string | null {\n const override = process.env['NYMBAL_ADMIN_DIST']\n if (override && hasIndex(override)) return override\n try {\n const manifest = createRequire(import.meta.url).resolve('@nymbalhq/admin/package.json')\n const dist = join(dirname(manifest), 'dist')\n return hasIndex(dist) ? dist : null\n } catch {\n return null\n }\n}\n","/**\n * The CLI's own bound on a signal shutdown. Below the E2E wrapper's `DEFAULT_SHUTDOWN_MS` (`scripts/e2e-server.mjs`),\n * so the pending step is logged before the wrapper's SIGKILL lands.\n */\nexport const SHUTDOWN_BOUND_MS = 3000\n\nexport interface ShutdownStep {\n name: string\n run: () => Promise<void>\n}\n\nexport interface ShutdownOptions {\n boundMs: number\n logger: { info: (obj: unknown, msg?: string) => void; error: (obj: unknown, msg?: string) => void }\n exit: (code: number) => never\n}\n\nlet running = false\n\n/**\n * Runs the steps in order, then exits 0. A step that throws is logged and the rest still run, then it exits 1. A step\n * still pending at `boundMs` is named in the log and it exits 1, so no client can hold the process open. A second call\n * while one runs (a repeat signal) exits 1 at once.\n */\nexport async function runShutdown(steps: ShutdownStep[], opts: ShutdownOptions): Promise<never> {\n if (running) {\n opts.logger.error({}, 'Shutdown already running; exiting now')\n return opts.exit(1)\n }\n running = true\n\n let pending: string | undefined\n let failed = false\n const work = (async () => {\n for (const step of steps) {\n pending = step.name\n try {\n await step.run()\n } catch (err) {\n failed = true\n opts.logger.error({ err, step: step.name }, `Shutdown step \"${step.name}\" failed`)\n }\n }\n pending = undefined\n })()\n\n let timer: ReturnType<typeof setTimeout> | undefined\n const bound = new Promise<'bound'>((resolve) => {\n timer = setTimeout(() => resolve('bound'), opts.boundMs)\n })\n const outcome = await Promise.race([work.then(() => 'done' as const), bound])\n clearTimeout(timer)\n\n if (outcome === 'bound') {\n opts.logger.error(\n { step: pending, boundMs: opts.boundMs },\n `Shutdown step \"${pending}\" did not finish within ${opts.boundMs} ms; exiting`,\n )\n return opts.exit(1)\n }\n return opts.exit(failed ? 1 : 0)\n}\n","import { displayUrl } from '@nymbalhq/types'\n\n/** What `nymbal dev` reports once it is up. */\nexport type DevSummaryInfo = {\n store: string\n apiUrl: string\n /** null under `--api-only`. */\n storefront: { template: string; url: string } | null\n /** null when the admin is not built. */\n admin: { url: string } | null\n commandStore: { kind: 'sqlite'; path: string } | { kind: 'postgres'; url: string }\n slots: Array<{ slot: string; provider: string; capabilities: readonly string[] }>\n primitives: Array<{ name: 'documentStore' | 'eventBus' | 'media'; provider: string }>\n}\n\n/** A terminal this narrow still shows every line whole. */\nconst WIDTH = 100\nconst LABEL = 14\n/** Slot and provider names longer than this push the capability column no further. */\nconst NAME_COLUMN = 20\n\n/** Columns as a terminal counts them: one per code point. */\nconst columns = (text: string) => [...text].length\n\nfunction fit(text: string, width = WIDTH): string {\n return columns(text) <= width ? text : `${[...text].slice(0, width - 1).join('')}…`\n}\n\nfunction row(label: string, value: string): string {\n return fit(` ${label.padEnd(LABEL)} ${value}`)\n}\n\n/** The capabilities that fit in `width`, whole and in order; the rest are counted, as `… (+n)`. */\nfunction capabilityList(capabilities: readonly string[], width: number): string {\n if (capabilities.length === 0) return '—'\n const all = capabilities.join(', ')\n if (columns(all) <= width) return all\n for (let shown = capabilities.length - 1; shown > 0; shown--) {\n const text = `${capabilities.slice(0, shown).join(', ')}, … (+${capabilities.length - shown})`\n if (columns(text) <= width) return text\n }\n return `… (+${capabilities.length})`\n}\n\n/**\n * The screen `nymbal dev` prints once the store is up: the store, its URLs, the command store, each commerce slot's\n * provider and capabilities, and each primitive's provider. At most 30 lines of at most 100 columns, and never a\n * credential: a Postgres URL is shown as `scheme://host:port/db`.\n */\nexport function renderDevSummary(info: DevSummaryInfo): string {\n const slotWidth = Math.min(NAME_COLUMN, Math.max(...info.slots.map((s) => columns(s.slot)), 0))\n const providerWidth = Math.min(\n NAME_COLUMN,\n Math.max(...info.slots.map((s) => columns(s.provider)), 0),\n )\n const slotLines = info.slots.map(({ slot, provider, capabilities }) => {\n const lead = ` ${slot.padEnd(slotWidth)} ${provider.padEnd(providerWidth)} `\n return fit(`${lead}${capabilityList(capabilities, WIDTH - columns(lead))}`)\n })\n const commandStore =\n info.commandStore.kind === 'sqlite'\n ? `sqlite ${info.commandStore.path}`\n : `postgres ${displayUrl(info.commandStore.url)}`\n const lines = [\n fit(` ${info.store}`),\n '',\n row('API', info.apiUrl),\n row(\n 'storefront',\n info.storefront === null\n ? 'not started (--api-only)'\n : `${info.storefront.url} (${info.storefront.template})`,\n ),\n row(\n 'admin',\n info.admin === null ? 'not built — run pnpm --filter @nymbalhq/admin build' : info.admin.url,\n ),\n row('command store', commandStore),\n '',\n ...slotLines,\n '',\n ...info.primitives.map(({ name, provider }) => row(name, provider)),\n '',\n ' Debug logs: run with --verbose (or LOG_LEVEL=debug).',\n ]\n return `${lines.join('\\n')}\\n`\n}\n","import { defineCommand } from 'citty'\nimport { loadProject } from '../utils/project.js'\nimport { runOrFail } from '../utils/spawn.js'\nimport { isFlatScaffold, resolveLocalBin, templateFilterFor } from '../utils/template-runner.js'\n\nexport const buildCommand = defineCommand({\n meta: { name: 'build', description: 'Production build of the configured template' },\n async run() {\n const { config, projectRoot } = await loadProject()\n if (!isFlatScaffold(projectRoot, config.template)) {\n // Inside this monorepo the storefront is a workspace package.\n await runOrFail('pnpm', ['--filter', templateFilterFor(config.template), 'build'], {\n cwd: projectRoot,\n })\n return\n }\n const binName = config.template === 'astro' ? 'astro' : 'next'\n const bin = resolveLocalBin(projectRoot, binName)\n if (!bin) {\n throw new Error(\n `Cannot find the ${binName} binary in ${projectRoot}/node_modules/.bin. ` +\n 'Install dependencies first, then re-run `nymbal build`.',\n )\n }\n await runOrFail(bin, ['build'], { cwd: projectRoot })\n },\n})\n","import { defineCommand } from 'citty'\nimport { loadProject } from '../utils/project.js'\nimport { createPlatform, resolvePrimitives, runSeed } from '@nymbalhq/platform'\nimport { getCliVersion } from '../utils/version.js'\nimport { migrateProject } from './migrate.js'\n\nexport const seedCommand = defineCommand({\n meta: { name: 'seed', description: 'Re-seed demo content (products, categories)' },\n async run() {\n const { config, projectRoot } = await loadProject()\n // A fresh project has no tables yet; `nymbal dev` migrates before it seeds, and so does this.\n await migrateProject(config, projectRoot)\n const platform = createPlatform(config, await resolvePrimitives(config))\n try {\n const result = await runSeed({\n config,\n commandStore: platform.commandStore,\n documentStore: platform.documentStore,\n eventBus: platform.eventBus,\n logger: platform.logger,\n version: getCliVersion(),\n })\n // eslint-disable-next-line no-console\n console.log(\n result.alreadySeeded\n ? '✓ demo content already present, nothing to seed'\n : `✓ seeded ${result.products} products across ${result.categories} categories`,\n )\n } finally {\n await platform.close()\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport { intro, outro, text, select, spinner, isCancel, cancel } from '@clack/prompts'\nimport p from 'picocolors'\nimport { loadProject } from '../utils/project.js'\nimport { createApp } from '@nymbalhq/platform'\nimport { runWooCommerceImport, writeReport, type ImportEntity, type ProgressEvent } from '@nymbalhq/importers'\nimport { join } from 'node:path'\nimport { getCliVersion } from '../utils/version.js'\n\nexport const importCommand = defineCommand({\n meta: {\n name: 'import',\n description: 'Migrate content from WooCommerce (or other sources) into Nymbal',\n },\n args: {\n source: {\n type: 'string',\n description: 'Import source (woocommerce)',\n },\n url: {\n type: 'string',\n description: 'Store URL (e.g. https://mystore.com)',\n },\n key: {\n type: 'string',\n description: 'WooCommerce Consumer Key (or set WOOCOMMERCE_KEY env var)',\n },\n secret: {\n type: 'string',\n description: 'WooCommerce Consumer Secret (or set WOOCOMMERCE_SECRET env var)',\n },\n entities: {\n type: 'string',\n description: 'Comma-separated list: products,customers,orders,reviews (default: products,customers,orders)',\n },\n ai: {\n type: 'boolean',\n description: 'Enable AI enrichment (default: true)',\n default: true,\n },\n gdpr: {\n type: 'boolean',\n description: 'Anonymise customer PII (default: true)',\n default: true,\n },\n fresh: {\n type: 'boolean',\n description: 'Ignore previous progress and re-import',\n default: false,\n },\n concurrency: {\n type: 'string',\n description: 'Parallel import workers (default: 4)',\n },\n },\n async run({ args }) {\n const { config } = await loadProject()\n const projectRoot = process.cwd()\n const statePath = join(projectRoot, '.nymbal-migration.json')\n const isTTY = process.stdin.isTTY ?? false\n\n intro(p.bold('Nymbal Import'))\n\n // ── Resolve source ────────────────────────────────────────────────────────\n let source = args.source\n if (!source) {\n if (!isTTY) {\n console.error('--source is required (woocommerce)')\n process.exit(1)\n }\n const picked = await select({\n message: 'Source platform?',\n options: [{ value: 'woocommerce', label: 'WooCommerce' }],\n })\n if (isCancel(picked)) { cancel('Import cancelled'); process.exit(0) }\n source = String(picked)\n }\n if (source !== 'woocommerce') {\n console.error(`Unsupported source: ${source}. Only 'woocommerce' is supported.`)\n process.exit(1)\n }\n\n // ── Resolve credentials ───────────────────────────────────────────────────\n let storeUrl = args.url\n if (!storeUrl) {\n if (!isTTY) { console.error('--url is required'); process.exit(1) }\n const val = await text({ message: 'Store URL?', placeholder: 'https://mystore.com', validate: (v) => v.startsWith('http') ? undefined : 'Must be a URL' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n storeUrl = String(val)\n }\n\n let consumerKey = args.key ?? process.env['WOOCOMMERCE_KEY'] ?? ''\n if (!consumerKey) {\n if (!isTTY) { console.error('--key or WOOCOMMERCE_KEY is required'); process.exit(1) }\n const val = await text({ message: 'Consumer Key?', placeholder: 'ck_...' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n consumerKey = String(val)\n }\n\n let consumerSecret = args.secret ?? process.env['WOOCOMMERCE_SECRET'] ?? ''\n if (!consumerSecret) {\n if (!isTTY) { console.error('--secret or WOOCOMMERCE_SECRET is required'); process.exit(1) }\n const val = await text({ message: 'Consumer Secret?', placeholder: 'cs_...' })\n if (isCancel(val)) { cancel('Import cancelled'); process.exit(0) }\n consumerSecret = String(val)\n }\n\n // ── Resolve entity list ───────────────────────────────────────────────────\n let entityList: ImportEntity[]\n if (args.entities) {\n entityList = args.entities.split(',').map((e) => e.trim()) as ImportEntity[]\n } else {\n entityList = ['categories', 'products', 'customers', 'orders']\n }\n\n const concurrency = parseInt(String(args.concurrency ?? '4'), 10)\n const aiEnabled = args.ai !== false\n const gdprEnabled = args.gdpr !== false\n\n // ── Bootstrap app ─────────────────────────────────────────────────────────\n const loadSpin = spinner()\n loadSpin.start('Starting platform…')\n const app = await createApp(config, { version: getCliVersion() })\n loadSpin.stop('Platform ready')\n\n try {\n const report = await runWooCommerceImport(\n {\n credentials: { url: storeUrl, consumerKey, consumerSecret },\n entities: entityList,\n ai: aiEnabled,\n gdpr: gdprEnabled,\n fresh: args.fresh,\n concurrency,\n projectRoot,\n currency: config.store.currency,\n statePath,\n },\n {\n services: app.services,\n repos: app.repos,\n adapters: { ai: app.adapters.ai, reviews: app.adapters.reviews },\n media: app.platform.media,\n onProgress(event: ProgressEvent) {\n if (event.kind === 'phase') {\n console.log(p.cyan(` → ${event.phase}`))\n } else if (event.kind === 'progress') {\n const pct = Math.round((event.done / event.total) * 100)\n process.stdout.write(`\\r ${event.entity}: ${event.done}/${event.total} (${pct}%) `)\n if (event.done === event.total) process.stdout.write('\\n')\n } else if (event.kind === 'error') {\n console.log(p.red(` ✗ ${event.phase} [${event.id}]: ${event.message}`))\n }\n },\n },\n )\n\n const reportPath = await writeReport(report, projectRoot, config.store.name)\n\n outro(\n [\n p.green('✓ Import complete'),\n ` Products: ${report.imported.products}`,\n ` Customers: ${report.imported.customers}`,\n ` Orders: ${report.imported.orders}`,\n ` Categories: ${report.imported.categories}`,\n ...(aiEnabled ? [` AI enriched: ${report.enriched.enriched} products`] : []),\n ...(report.errors.length > 0 ? [p.yellow(` ⚠ ${report.errors.length} errors — see report`)] : []),\n ``,\n ` Report: ${reportPath}`,\n ` Next: ${p.bold('nymbal dev')}`,\n ].join('\\n'),\n )\n } finally {\n await app.stop()\n }\n },\n})\n","import { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport { loadProject } from '../utils/project.js'\nimport { NymbalError } from '@nymbalhq/types'\n\nexport const configValidateCommand = defineCommand({\n meta: { name: 'config:validate', description: 'Validate nymbal.config.ts' },\n async run() {\n try {\n const { config, path } = await loadProject()\n // eslint-disable-next-line no-console\n console.log(pc.green(`✓ config valid`) + ` (${path})`)\n // eslint-disable-next-line no-console\n console.log(\n ` template: ${config.template}, commandStore: ${config.infrastructure.commandStore}, documentStore: ${config.infrastructure.documentStore}, eventBus: ${config.infrastructure.eventBus}`,\n )\n process.exit(0)\n } catch (err) {\n if (err instanceof NymbalError) {\n // eslint-disable-next-line no-console\n console.error(pc.red('✗ config invalid'))\n // eslint-disable-next-line no-console\n console.error(err.message)\n } else {\n // eslint-disable-next-line no-console\n console.error(err)\n }\n process.exit(1)\n }\n },\n})\n","import { spawnSync } from 'node:child_process'\nimport { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { parseEnv } from 'node:util'\nimport { defineCommand } from 'citty'\nimport pc from 'picocolors'\nimport { findConfigFile, loadConfig } from '@nymbalhq/config'\nimport { installLine } from '@nymbalhq/platform'\nimport type { Recipe } from '@nymbalhq/types'\nimport {\n RECIPE_HOLDERS,\n appendRecipeEnv,\n applyRecipeToConfig,\n envCalls,\n isInstalled,\n isKnownRecipe,\n knownRecipes,\n missingEnv,\n readRecipe,\n recipeFile,\n} from '../recipes/index.js'\n\nexport interface AddOptions {\n recipe: string\n install: boolean\n force: boolean\n dryRun: boolean\n}\n\nconst out = (line = ''): void => void process.stdout.write(`${line}\\n`)\nconst err = (line: string): void => void process.stderr.write(`${line}\\n`)\n\nfunction fail(message: string): number {\n err(pc.red(`✗ ${message}`))\n return 1\n}\n\n/** Runs an install line in the project, its output passed through; whether it succeeded. */\nfunction runInstall(line: string, root: string): boolean {\n out(pc.dim(`$ ${line}`))\n const [command, ...args] = line.split(' ')\n const result = spawnSync(command!, args, {\n cwd: root,\n stdio: 'inherit',\n shell: process.platform === 'win32',\n })\n return result.status === 0\n}\n\n/** The variables `.env` sets to something, which `nymbal dev` loads before the config. */\nfunction dotEnv(root: string): Record<string, string> {\n const file = join(root, '.env')\n return existsSync(file) ? (parseEnv(readFileSync(file, 'utf8')) as Record<string, string>) : {}\n}\n\nconst isSet = (name: string, fromFile: Record<string, string>): boolean =>\n (process.env[name] ?? '') !== '' || (fromFile[name] ?? '') !== ''\n\n/**\n * Why the candidate config would not run, without connecting to anything: a recipe package the project does not\n * resolve, or a config `loadConfig` refuses (the schema and its cross-slot rules). The candidate is loaded as\n * `nymbal.config.ts` from a temp directory under the project, so `@nymbalhq/config` resolves as the real one does. For\n * that load only, every variable an `env()` call names takes its `.env` value as `nymbal dev` would, and one still\n * unset gets a placeholder unless its calls have a default, which is what runs.\n */\nasync function problemsWith(\n candidate: string,\n recipe: Recipe,\n root: string,\n fromFile: Record<string, string>,\n): Promise<string[]> {\n const problems: string[] = []\n const missing = recipe.install.filter((pkg) => !isInstalled(pkg, root))\n if (missing.length > 0) {\n problems.push(\n `${missing.join(', ')} ${missing.length === 1 ? 'is' : 'are'} not installed: ${installLine(missing, process.env, root)}`,\n )\n }\n const saved = new Map<string, string | undefined>()\n for (const { name, defaulted } of envCalls(candidate)) {\n if ((process.env[name] ?? '') !== '') continue\n const value = fromFile[name] || (defaulted ? undefined : `nymbal-add-placeholder-${name}`)\n if (value === undefined) continue\n saved.set(name, process.env[name])\n process.env[name] = value\n }\n const dir = mkdtempSync(join(root, '.nymbal-add-'))\n try {\n writeFileSync(join(dir, 'nymbal.config.ts'), candidate)\n await loadConfig(dir)\n } catch (error) {\n problems.push((error as Error).message)\n } finally {\n rmSync(dir, { recursive: true, force: true })\n for (const [name, value] of saved) {\n if (value === undefined) delete process.env[name]\n else process.env[name] = value\n }\n }\n return problems\n}\n\n/** The lines of `after` that `before` lacks (`+`) and the reverse (`-`), by a longest common subsequence. */\nfunction lineDiff(before: string, after: string): string[] {\n const a = before.split('\\n')\n const b = after.split('\\n')\n const t = Array.from({ length: a.length + 1 }, () => new Array<number>(b.length + 1).fill(0))\n for (let i = a.length - 1; i >= 0; i--)\n for (let j = b.length - 1; j >= 0; j--)\n t[i]![j] = a[i] === b[j] ? t[i + 1]![j + 1]! + 1 : Math.max(t[i + 1]![j]!, t[i]![j + 1]!)\n const lines: string[] = []\n let i = 0\n let j = 0\n while (i < a.length || j < b.length) {\n if (i < a.length && j < b.length && a[i] === b[j]) {\n i++\n j++\n } else if (j < b.length && (i === a.length || t[i]![j + 1]! >= t[i + 1]![j]!)) {\n lines.push(pc.green(`+ ${b[j++]}`))\n } else {\n lines.push(pc.red(`- ${a[i++]}`))\n }\n }\n return lines\n}\n\nconst show = (value: unknown): string =>\n typeof value === 'string' ? `'${value}'` : JSON.stringify(value)\n\nexport async function add(opts: AddOptions, cwd: string = process.cwd()): Promise<number> {\n const name = opts.recipe\n if (!isKnownRecipe(name)) {\n return fail(`unknown recipe '${name}'. The recipes are: ${knownRecipes().join(', ')}`)\n }\n const configPath = findConfigFile(cwd)\n if (configPath === null) return fail(`no nymbal.config.ts in ${cwd} or any parent directory`)\n const root = dirname(configPath)\n const holder = RECIPE_HOLDERS[name]!\n\n const installed: string[] = []\n if (recipeFile(name, root) === null) {\n const line = installLine([holder], process.env, root)\n if (!opts.install || opts.dryRun) {\n return fail(\n `the ${name} recipe ships in ${holder}, which is not installed. Install it: ${line}`,\n )\n }\n if (!runInstall(line, root)) return fail(`${line} failed`)\n installed.push(holder)\n }\n const recipe = await readRecipe(name, root)\n\n const source = readFileSync(configPath, 'utf8')\n let edited: { source: string; changed: string[] }\n try {\n const applied = applyRecipeToConfig(source, recipe, { force: opts.force })\n if ('conflict' in applied) {\n const { path, current, wanted } = applied.conflict\n return fail(\n `${path} is ${show(current)} in nymbal.config.ts, and the ${name} recipe sets it to ${show(wanted)}. ` +\n 'nymbal.config.ts is unchanged: edit it by hand, or re-run with --force to overwrite it.',\n )\n }\n edited = applied\n } catch (error) {\n return fail((error as Error).message)\n }\n const examplePath = join(root, '.env.example')\n const example = existsSync(examplePath) ? readFileSync(examplePath, 'utf8') : ''\n const nextExample = appendRecipeEnv(example, recipe)\n\n if (opts.dryRun) {\n out(pc.bold(`nymbal add ${name} --dry-run: nothing is written`))\n out()\n out(\n recipe.install.length > 0\n ? `install: ${installLine(recipe.install, process.env, root)}`\n : 'install: nothing',\n )\n out()\n out('nymbal.config.ts:')\n const diff = lineDiff(source, edited.source)\n for (const line of diff.length > 0 ? diff : ['(already set)']) out(` ${line}`)\n out()\n out('.env.example:')\n const added = nextExample\n .slice(example.length)\n .split(/\\r?\\n/)\n .filter((l) => l !== '')\n for (const line of added.length > 0 ? added : ['(every variable already listed)'])\n out(` ${line}`)\n return 0\n }\n\n const pending = recipe.install.filter((pkg) => !isInstalled(pkg, root))\n if (pending.length > 0 && opts.install) {\n const line = installLine(pending, process.env, root)\n if (!runInstall(line, root)) return fail(`${line} failed`)\n installed.push(...pending)\n }\n\n const fromFile = dotEnv(root)\n const problems = await problemsWith(edited.source, recipe, root, fromFile)\n if (problems.length > 0) {\n return fail(\n `the ${name} recipe would leave a config that does not load, so nymbal.config.ts is unchanged:\\n ${problems.join('\\n ')}`,\n )\n }\n\n const written: string[] = []\n if (installed.length > 0) written.push(`package.json and its lockfile (${installed.join(', ')})`)\n if (edited.source !== source) {\n writeFileSync(configPath, edited.source)\n written.push(`nymbal.config.ts (${edited.changed.join(', ')})`)\n }\n if (nextExample !== example) {\n writeFileSync(examplePath, nextExample)\n written.push(\n `.env.example (${missingEnv(example, recipe)\n .map((v) => v.name)\n .join(', ')})`,\n )\n }\n\n out(pc.green(`✓ ${name}: ${recipe.summary}`))\n out(written.length > 0 ? ` changed ${written.join(', ')}` : ' already added: nothing changed')\n const unset = recipe.env.filter((v) => v.required && !isSet(v.name, fromFile))\n if (unset.length > 0 || recipe.next.length > 0) {\n out()\n out('Next:')\n for (const v of unset) out(` - set ${v.name} in .env`)\n for (const line of recipe.next) out(` - ${line}`)\n }\n return 0\n}\n\nexport const addCommand = defineCommand({\n meta: {\n name: 'add',\n description: `Put the store on a service: ${knownRecipes().join(', ')}`,\n },\n args: {\n recipe: { type: 'positional', required: true, description: knownRecipes().join(', ') },\n install: {\n type: 'boolean',\n default: true,\n description: 'Install the packages (--no-install: they must already be installed)',\n },\n force: {\n type: 'boolean',\n default: false,\n description: 'Overwrite a config value the recipe conflicts with',\n },\n 'dry-run': {\n type: 'boolean',\n default: false,\n description:\n 'Print the config change, the .env.example lines and the install line, and write nothing',\n },\n },\n async run({ args }) {\n process.exitCode = await add({\n recipe: args.recipe,\n install: args.install,\n force: args.force,\n dryRun: args['dry-run'],\n })\n },\n})\n","import { existsSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { dirname, join, resolve } from 'node:path'\nimport type { Recipe } from '@nymbalhq/types'\n\n/**\n * Each recipe `nymbal add` knows, and the package that ships it as `recipes/<name>.json`. The recipe itself is data in\n * that package, so a package brings its own recipe; this table only says where to look.\n */\nexport const RECIPE_HOLDERS: Readonly<Record<string, string>> = {\n postgres: '@nymbalhq/platform',\n redis: '@nymbalhq/doc-store-redis',\n s3: '@nymbalhq/media-s3',\n stripe: '@nymbalhq/adapter-stripe',\n}\n\nexport function knownRecipes(): string[] {\n return Object.keys(RECIPE_HOLDERS).sort()\n}\n\nexport function isKnownRecipe(name: string): boolean {\n return Object.hasOwn(RECIPE_HOLDERS, name)\n}\n\nfunction unknownRecipe(name: string): Error {\n return new Error(`unknown recipe '${name}': the recipes are ${knownRecipes().join(', ')}`)\n}\n\n/**\n * The directory of `pkg` in the `node_modules` of the project or a directory above it, as Node looks for it, or null.\n * Node's global fallbacks are left out: pnpm's shims put its whole store on NODE_PATH, which is no install.\n */\nfunction packageDir(pkg: string, projectRoot: string): string | null {\n let dir = resolve(projectRoot)\n while (true) {\n const candidate = join(dir, 'node_modules', pkg)\n if (existsSync(join(candidate, 'package.json'))) return candidate\n const parent = dirname(dir)\n if (parent === dir) return null\n dir = parent\n }\n}\n\n/** Where the project resolves `<holder>/recipes/<name>.json`, or null when the holder is not installed there. */\nexport function recipeFile(name: string, projectRoot: string): string | null {\n const holder = RECIPE_HOLDERS[name]\n if (holder === undefined || !isKnownRecipe(name)) throw unknownRecipe(name)\n const dir = packageDir(holder, projectRoot)\n if (dir === null) return null\n try {\n // From the holder's own manifest the specifier resolves through its `exports`, as from the project.\n return createRequire(join(dir, 'package.json')).resolve(`${holder}/recipes/${name}.json`)\n } catch (error) {\n const code = (error as { code?: unknown }).code\n if (code === 'MODULE_NOT_FOUND' || code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') return null\n throw error\n }\n}\n\nexport function isInstalled(pkg: string, projectRoot: string): boolean {\n return packageDir(pkg, projectRoot) !== null\n}\n\n/** The recipe the holder installed in the project ships, read through Node resolution from the project root. */\nexport async function readRecipe(name: string, projectRoot: string): Promise<Recipe> {\n const file = recipeFile(name, projectRoot)\n if (file === null) {\n throw new Error(\n `${RECIPE_HOLDERS[name]} is not installed in ${projectRoot}, so its ${name} recipe cannot be read`,\n )\n }\n const recipe = JSON.parse(await readFile(file, 'utf8')) as Recipe\n const malformed =\n recipe === null ||\n typeof recipe !== 'object' ||\n recipe.name !== name ||\n !Array.isArray(recipe.install) ||\n !Array.isArray(recipe.set) ||\n !Array.isArray(recipe.env) ||\n !Array.isArray(recipe.next)\n if (malformed) throw new Error(`${file} is not a ${name} recipe`)\n return recipe\n}\n","import { parseModule } from 'magicast'\nimport type { Recipe, RecipeValue } from '@nymbalhq/types'\n\n/** What the scaffold writes into the slots a recipe sets: replacing one of these is no conflict. */\nexport const SCAFFOLD_DEFAULTS: readonly string[] = [\n 'sqlite',\n 'in-memory',\n 'in-process',\n 'local-fs',\n 'native',\n]\n\nconst CONFIG_MODULE = '@nymbalhq/config'\n\nexport type Conflict = { path: string; current: unknown; wanted: unknown }\nexport type AppliedRecipe = { source: string; changed: string[] } | { conflict: Conflict }\n\n/** The parts of a Babel node this module reads. */\ninterface Node {\n type: string\n start: number\n end: number\n [key: string]: unknown\n}\n\nconst child = (node: Node, key: string): Node => node[key] as Node\nconst children = (node: Node, key: string): Node[] => node[key] as Node[]\n\n/** Parses LF text only: recast's offsets count a line break as one character, so CRLF text goes through `lfCopy`. */\nfunction parse(lf: string): Node {\n // Recast expands tabs to `tabWidth` columns before Babel parses: at 1 every offset still points into `lf`.\n return parseModule(lf, { tabWidth: 1 }).$ast as unknown as Node\n}\n\nconst lfCopy = (source: string): string => source.replace(/\\r\\n/g, '\\n')\n\nfunction unwrap(node: Node | undefined): Node | undefined {\n let at = node\n while (\n at !== undefined &&\n (at.type === 'TSAsExpression' ||\n at.type === 'TSSatisfiesExpression' ||\n at.type === 'TSNonNullExpression' ||\n at.type === 'ParenthesizedExpression')\n ) {\n at = child(at, 'expression')\n }\n return at\n}\n\nfunction nameOf(node: Node): string | undefined {\n if (node.type === 'Identifier') return node['name'] as string\n if (node.type === 'StringLiteral') return node['value'] as string\n if (node.type === 'NumericLiteral') return String(node['value'])\n return undefined\n}\n\ninterface ConfigModule {\n program: Node\n /** The object literal `defineConfig` is called with, or the default export itself. */\n config: Node\n /** The local name `env` is imported under from @nymbalhq/config, if it is. */\n envName: string | undefined\n /** Whether a top-level import or declaration binds the name `env`. */\n envBound: boolean\n /** The first value import from @nymbalhq/config that names its imports. */\n namedImport: Node | undefined\n}\n\nfunction configImports(program: Node): Node[] {\n return children(program, 'body').filter(\n (n) =>\n n.type === 'ImportDeclaration' &&\n child(n, 'source')['value'] === CONFIG_MODULE &&\n n['importKind'] !== 'type',\n )\n}\n\nfunction importedAs(program: Node, imported: string): string | undefined {\n for (const decl of configImports(program)) {\n for (const spec of children(decl, 'specifiers')) {\n if (spec.type !== 'ImportSpecifier' || spec['importKind'] === 'type') continue\n if (nameOf(child(spec, 'imported')) === imported)\n return child(spec, 'local')['name'] as string\n }\n }\n return undefined\n}\n\nfunction bindsEnv(program: Node): boolean {\n const bound = (id: Node | undefined): boolean => id?.type === 'Identifier' && id['name'] === 'env'\n return children(program, 'body').some((n) => {\n const decl = n.type === 'ExportNamedDeclaration' ? child(n, 'declaration') : n\n if (decl === null || decl === undefined) return false\n if (decl.type === 'ImportDeclaration')\n return children(decl, 'specifiers').some((s) => bound(child(s, 'local')))\n if (decl.type === 'VariableDeclaration')\n return children(decl, 'declarations').some((d) => bound(child(d, 'id')))\n return bound(child(decl, 'id'))\n })\n}\n\n/** The config literal of `source`, the LF copy of a nymbal.config.ts. */\nfunction locate(source: string): ConfigModule | undefined {\n const program = parse(source)\n const exported = children(program, 'body').find((n) => n.type === 'ExportDefaultDeclaration')\n if (exported === undefined) return undefined\n let config = unwrap(child(exported, 'declaration'))\n if (config?.type === 'CallExpression') {\n const callee = child(config, 'callee')\n const define = importedAs(program, 'defineConfig') ?? 'defineConfig'\n if (callee.type !== 'Identifier' || callee['name'] !== define) return undefined\n config = unwrap(children(config, 'arguments')[0])\n }\n if (config?.type !== 'ObjectExpression') return undefined\n // A guard on the offsets: they must frame the literal in `source` itself.\n if (source[config.start] !== '{' || source[config.end - 1] !== '}') return undefined\n return {\n program,\n config,\n envName: importedAs(program, 'env'),\n envBound: bindsEnv(program),\n namedImport: configImports(program).find((d) =>\n children(d, 'specifiers').some((s) => s.type === 'ImportSpecifier'),\n ),\n }\n}\n\nfunction isEnvRef(value: unknown): value is { env: string; default?: string } {\n if (typeof value !== 'object' || value === null) return false\n const keys = Object.keys(value)\n return (\n typeof (value as { env?: unknown }).env === 'string' &&\n keys.every((k) => k === 'env' || k === 'default')\n )\n}\n\n/** The value a literal node holds, `env('X')` as `{ env: 'X' }`; undefined for anything that is not a literal. */\nfunction evaluate(node: Node, envName: string | undefined): unknown {\n const at = unwrap(node)!\n switch (at.type) {\n case 'StringLiteral':\n case 'NumericLiteral':\n case 'BooleanLiteral':\n return at['value']\n case 'TemplateLiteral': {\n const quasis = children(at, 'quasis')\n return children(at, 'expressions').length === 0\n ? (quasis[0]?.['value'] as { cooked: string }).cooked\n : undefined\n }\n case 'ObjectExpression': {\n const out: Record<string, unknown> = {}\n for (const prop of children(at, 'properties')) {\n const key =\n prop.type === 'ObjectProperty' && !prop['computed']\n ? nameOf(child(prop, 'key'))\n : undefined\n const value = key === undefined ? undefined : evaluate(child(prop, 'value'), envName)\n if (key === undefined || value === undefined) return undefined\n out[key] = value\n }\n return out\n }\n case 'CallExpression': {\n const callee = child(at, 'callee')\n const args = children(at, 'arguments')\n if (callee.type !== 'Identifier' || callee['name'] !== (envName ?? 'env')) return undefined\n if (args.length < 1 || args.length > 2 || args.some((a) => a.type !== 'StringLiteral'))\n return undefined\n return {\n env: args[0]!['value'],\n ...(args[1] !== undefined && { default: args[1]['value'] }),\n }\n }\n default:\n return undefined\n }\n}\n\nfunction sameValue(a: unknown, b: unknown): boolean {\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return a === b\n const ka = Object.keys(a).sort()\n const kb = Object.keys(b).sort()\n return (\n ka.length === kb.length &&\n ka.every(\n (k, i) =>\n k === kb[i] &&\n sameValue((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]),\n )\n )\n}\n\nfunction isScaffoldDefault(value: unknown): boolean {\n if (typeof value === 'string') return SCAFFOLD_DEFAULTS.includes(value)\n const provider = (value as { provider?: unknown } | null)?.provider\n return typeof provider === 'string' && SCAFFOLD_DEFAULTS.includes(provider)\n}\n\ninterface Style {\n quote: string\n unit: string\n envName: string\n}\n\nfunction styleOf(source: string, mod: ConfigModule): Style {\n const firstString = /(['\"])(?:(?!\\1)[^\\\\\\r\\n]|\\\\.)*\\1/.exec(source.slice(mod.config.start))\n const indented = /\\n([ \\t]+)\\S/.exec(source.slice(mod.config.start))\n return {\n quote: firstString?.[1] ?? \"'\",\n unit: indented?.[1] ?? ' ',\n envName: mod.envName ?? 'env',\n }\n}\n\nfunction quoted(text: string, style: Style): string {\n const q = style.quote\n const body = text\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(new RegExp(q, 'g'), `\\\\${q}`)\n .replace(/\\r/g, '\\\\r')\n .replace(/\\n/g, '\\\\n')\n return `${q}${body}${q}`\n}\n\nfunction renderKey(key: string, style: Style): string {\n return /^[A-Za-z_$][\\w$]*$/.test(key) ? key : quoted(key, style)\n}\n\n/** `value` as source text, an object over several lines starting at `indent`. */\nfunction render(value: RecipeValue, indent: string, style: Style): string {\n if (typeof value === 'string') return quoted(value, style)\n if (typeof value === 'number' || typeof value === 'boolean') return String(value)\n if (isEnvRef(value)) {\n const fallback = value.default === undefined ? '' : `, ${quoted(value.default, style)}`\n return `${style.envName}(${quoted(value.env, style)}${fallback})`\n }\n const entries = Object.entries(value)\n if (entries.length === 0) return '{}'\n const inner = indent + style.unit\n const lines = entries.map(\n ([k, v]) => `${inner}${renderKey(k, style)}: ${render(v, inner, style)},`,\n )\n return `{\\n${lines.join('\\n')}\\n${indent}}`\n}\n\nfunction writesEnv(value: RecipeValue): boolean {\n if (isEnvRef(value)) return true\n return typeof value === 'object' && Object.values(value).some(writesEnv)\n}\n\n/** The whitespace that starts the line `offset` is on. */\nfunction indentAt(source: string, offset: number): string {\n const lineStart = source.lastIndexOf('\\n', offset - 1) + 1\n return /^[ \\t]*/.exec(source.slice(lineStart))![0]\n}\n\n/** An edit at offsets of the LF copy, its text LF too. */\ntype Splice = { at: number; remove: number; text: string }\n\n/**\n * `source` with `edits` made. Their offsets are mapped from the LF copy back to `source`, and a line an edit adds ends\n * as the line it lands in does, so a CRLF or mixed file keeps its own endings and every byte outside the edits.\n */\nfunction spliced(source: string, edits: Splice[]): string {\n // The LF copy's offset of every `\\n` that a `\\r` stands before in `source`.\n const crlf: number[] = []\n for (const m of source.matchAll(/\\r\\n/g)) crlf.push(m.index - crlf.length)\n const at = (lf: number): number => lf + crlf.filter((p) => p < lf).length\n const lastBreak = /\\r?\\n(?![\\s\\S]*\\n)/.exec(source)?.[0] ?? '\\n'\n return edits\n .map((e) => {\n const start = at(e.at)\n const end = at(e.at + e.remove)\n const eol = /\\r?\\n/.exec(source.slice(end))?.[0] ?? lastBreak\n return { start, end, text: e.text.replace(/\\n/g, eol) }\n })\n .sort((a, b) => b.start - a.start)\n .reduce((s, e) => s.slice(0, e.start) + e.text + s.slice(e.end), source)\n}\n\n/** The edits that add `key: value` as the last property of `object`, in the layout the object already has. */\nfunction addProperty(\n source: string,\n object: Node,\n key: string,\n value: RecipeValue,\n style: Style,\n): Splice[] {\n const props = children(object, 'properties')\n const close = object.end - 1\n const last = props.at(-1)\n if (last === undefined) {\n const indent = indentAt(source, object.start)\n const inside = source.slice(object.start + 1, close)\n const text = `${indent}${style.unit}${renderKey(key, style)}: ${render(value, indent + style.unit, style)},`\n // An empty `{}` (or one holding only whitespace) is rewritten; anything else in it, a comment, stays above.\n return inside.trim() === ''\n ? [\n {\n at: object.start + 1,\n remove: inside.length,\n text: `\\n${text}\\n${indent}`,\n },\n ]\n : [{ at: close, remove: 0, text: `\\n${text}\\n${indent}` }]\n }\n const after = /^[ \\t]*,/.exec(source.slice(last.end, close))\n const comma = after === null ? undefined : last.end + after[0].length\n const lineEnd = source.slice(last.end, close).indexOf('\\n')\n const property = (indent: string): string =>\n `${renderKey(key, style)}: ${render(value, indent, style)}`\n if (lineEnd === -1) {\n // `{ a: 1 }` on one line: the property joins it there.\n return comma === undefined\n ? [{ at: last.end, remove: 0, text: `, ${property(indentAt(source, last.start))}` }]\n : [{ at: comma, remove: 0, text: ` ${property(indentAt(source, last.start))},` }]\n }\n const indent = indentAt(source, last.start)\n const edits: Splice[] = [\n {\n at: last.end + lineEnd,\n remove: 0,\n text: `\\n${indent}${property(indent)}${comma === undefined ? '' : ','}`,\n },\n ]\n if (comma === undefined) edits.push({ at: last.end, remove: 0, text: ',' })\n return edits\n}\n\nfunction findProperty(object: Node, key: string): Node | undefined {\n return children(object, 'properties').findLast(\n (p) => p.type === 'ObjectProperty' && !p['computed'] && nameOf(child(p, 'key')) === key,\n )\n}\n\nfunction editByHand(recipe: Recipe, why: string): Error {\n const wanted = recipe.set.map(({ path, value }) => `${path} = ${JSON.stringify(value)}`)\n return new Error(\n `nymbal.config.ts ${why}, so the ${recipe.name} recipe cannot edit it: edit by hand and set ${wanted.join('; ')}`,\n )\n}\n\ntype Step = { source: string; wrote: boolean } | { conflict: Conflict }\n\n/** One `set` entry applied to `source`. */\nfunction setPath(\n source: string,\n recipe: Recipe,\n path: string,\n value: RecipeValue,\n force: boolean,\n): Step {\n const lf = lfCopy(source)\n const mod = locate(lf)\n if (mod === undefined)\n throw editByHand(recipe, 'does not export a defineConfig({...}) object literal')\n const style = styleOf(lf, mod)\n const keys = path.split('.')\n let object = mod.config\n for (const [i, key] of keys.entries()) {\n const prop = findProperty(object, key)\n if (prop === undefined) {\n const nested = keys.slice(i + 1).reduceRight<RecipeValue>((v, k) => ({ [k]: v }), value)\n return {\n source: spliced(source, addProperty(lf, object, key, nested, style)),\n wrote: true,\n }\n }\n const held = child(prop, 'value')\n if (i === keys.length - 1) {\n const current = evaluate(held, mod.envName)\n if (current !== undefined && sameValue(current, value)) return { source, wrote: false }\n if (!force && !isScaffoldDefault(current)) {\n return {\n conflict: { path, current: current ?? lf.slice(held.start, held.end), wanted: value },\n }\n }\n const text = render(value, indentAt(lf, prop.start), style)\n return {\n source: spliced(source, [{ at: held.start, remove: held.end - held.start, text }]),\n wrote: true,\n }\n }\n const inner = unwrap(held)\n if (inner?.type !== 'ObjectExpression') {\n throw editByHand(\n recipe,\n `holds ${keys.slice(0, i + 1).join('.')} as something other than an object literal`,\n )\n }\n object = inner\n }\n return { source, wrote: false }\n}\n\n/** `source` importing `env` from @nymbalhq/config, by adding it to an import that names its imports, or a new one. */\nfunction importEnv(source: string, recipe: Recipe): string {\n const lf = lfCopy(source)\n const mod = locate(lf)!\n if (mod.envName !== undefined) return source\n if (mod.envBound)\n throw editByHand(recipe, 'binds `env` to something other than the env of @nymbalhq/config')\n const style = styleOf(lf, mod)\n if (mod.namedImport !== undefined) {\n const last = children(mod.namedImport, 'specifiers')\n .filter((s) => s.type === 'ImportSpecifier')\n .at(-1)!\n return spliced(source, [{ at: last.end, remove: 0, text: ', env' }])\n }\n const imports = children(mod.program, 'body').filter((n) => n.type === 'ImportDeclaration')\n const line = `import { env } from ${quoted(CONFIG_MODULE, style)}\\n`\n const lastImport = imports.at(-1)\n const lineEnd = lastImport === undefined ? -1 : lf.indexOf('\\n', lastImport.end)\n const edit: Splice =\n lastImport === undefined\n ? { at: 0, remove: 0, text: line }\n : lineEnd === -1\n ? { at: lf.length, remove: 0, text: `\\n${line}` }\n : { at: lineEnd + 1, remove: 0, text: line }\n return spliced(source, [edit])\n}\n\n/**\n * `source` (a `nymbal.config.ts`) with every `set` path of the recipe holding the recipe's value, through the AST of\n * the `defineConfig({...})` literal (or a plain object default export). Everything outside the edited properties is\n * kept byte for byte, and a path already holding the value is left alone, so applying it twice equals applying it\n * once. A path holding another value that is not the scaffold's default is a conflict unless `force`. A config that\n * is not such a literal throws \"edit by hand\".\n */\nexport function applyRecipeToConfig(\n source: string,\n recipe: Recipe,\n opts: { force: boolean },\n): AppliedRecipe {\n if (locate(lfCopy(source)) === undefined) {\n throw editByHand(recipe, 'does not export a defineConfig({...}) object literal')\n }\n let current = source\n const changed: string[] = []\n let envWritten = false\n for (const { path, value } of recipe.set) {\n const step = setPath(current, recipe, path, value, opts.force)\n if ('conflict' in step) return step\n if (!step.wrote) continue\n current = step.source\n changed.push(path)\n envWritten ||= writesEnv(value)\n }\n if (envWritten) current = importEnv(current, recipe)\n return { source: current, changed }\n}\n\nexport type EnvCall = { name: string; defaulted: boolean }\n\n/**\n * Every variable an `env('NAME')` call names in the config, `env` imported from @nymbalhq/config, and whether every\n * call naming it has a default. A load needs the others set; a defaulted one runs on its default unless `.env` sets it.\n */\nexport function envCalls(source: string): EnvCall[] {\n const lf = lfCopy(source)\n const mod = locate(lf)\n const envName = mod === undefined ? importedAs(parse(lf), 'env') : mod.envName\n if (envName === undefined) return []\n const defaulted = new Map<string, boolean>()\n const visit = (node: unknown): void => {\n if (Array.isArray(node)) return node.forEach(visit)\n if (typeof node !== 'object' || node === null || typeof (node as Node).type !== 'string') return\n const n = node as Node\n if (n.type === 'CallExpression') {\n const callee = child(n, 'callee')\n const args = children(n, 'arguments')\n const first = args[0]\n if (\n callee.type === 'Identifier' &&\n callee['name'] === envName &&\n first?.type === 'StringLiteral'\n ) {\n const name = first['value'] as string\n defaulted.set(name, (defaulted.get(name) ?? true) && args.length > 1)\n }\n }\n for (const [key, value] of Object.entries(n)) {\n if (key !== 'loc' && key !== 'comments' && key !== 'extra' && key !== 'original') visit(value)\n }\n }\n visit(mod?.program ?? parse(lf))\n return [...defaulted].map(([name, all]) => ({ name, defaulted: all }))\n}\n","import type { Recipe } from '@nymbalhq/types'\n\nconst escapeRegExp = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\/]/g, '\\\\$&')\n\n/** `NAME=` or `# NAME=`: a variable the file already lists, set or commented out. */\nfunction declares(lines: string[], name: string): boolean {\n const re = new RegExp(`^(#\\\\s*)?${escapeRegExp(name)}=`)\n return lines.some((line) => re.test(line.trim()))\n}\n\n/** The recipe's variables `example` does not list, each once. */\nexport function missingEnv(example: string, recipe: Recipe): Recipe['env'] {\n const lines = example.split(/\\r?\\n/)\n return recipe.env.filter(\n (v, i) => !declares(lines, v.name) && recipe.env.findIndex((w) => w.name === v.name) === i,\n )\n}\n\n/**\n * `example` (a `.env.example`) with every variable of the recipe it does not list yet appended under a\n * `# <recipe> (nymbal add <recipe>)` header, each with its comment above it; an optional one is commented out.\n * No line is removed or moved, and a file that lists them all is returned as it is.\n */\nexport function appendRecipeEnv(example: string, recipe: Recipe): string {\n const eol = example.includes('\\r\\n') ? '\\r\\n' : '\\n'\n const missing = missingEnv(example, recipe)\n if (missing.length === 0) return example\n\n const block = [`# ${recipe.name} (nymbal add ${recipe.name})`]\n for (const v of missing) {\n if (v.comment !== '') block.push(`# ${v.comment}`)\n block.push(`${v.required ? '' : '# '}${v.name}=${v.example}`)\n }\n let head = example\n if (head !== '' && !head.endsWith('\\n')) head += eol\n const last = head.split(/\\r?\\n/).at(-2)\n const gap = last === undefined || last.trim() === '' ? '' : eol\n return `${head}${gap}${block.join(eol)}${eol}`\n}\n","import { existsSync } from 'node:fs'\nimport { defineCommand } from 'citty'\nimport type { LoadedConfig } from '@nymbalhq/config'\nimport { createLogger, diagnose, type DiagnosisReport } from '@nymbalhq/platform'\nimport { errorText, HEALTH_CHECK_TIMEOUT_MS } from '@nymbalhq/types'\nimport { loadProject } from '../utils/project.js'\nimport { resolveMigrations } from './migrate.js'\nimport { formatDoctorReport } from './doctor-report.js'\n\nfunction timeoutOf(flag: string | undefined): number {\n if (flag === undefined || flag.trim() === '') return HEALTH_CHECK_TIMEOUT_MS\n const ms = Number(flag)\n if (!Number.isInteger(ms) || ms < 1) {\n throw new Error(`--timeout must be a whole number of milliseconds, got \"${flag}\"`)\n }\n return ms\n}\n\n/**\n * The migrations `nymbal migrate` applies here, when it can find them; else diagnose reads those of the platform this\n * CLI runs, which are the ones its kernel expects.\n */\nfunction migrationsOf(projectRoot: string): { migrationsRoot?: string } {\n const root = resolveMigrations(projectRoot)\n return existsSync(root) ? { migrationsRoot: root } : {}\n}\n\nexport const doctorCommand = defineCommand({\n meta: {\n name: 'doctor',\n description:\n 'Check the project without changing it: config, packages, command store, migrations, slots and primitives',\n },\n args: {\n json: { type: 'boolean', description: 'Print the checks as one JSON document', default: false },\n timeout: {\n type: 'string',\n description: `How long each check may take, in ms (default ${HEALTH_CHECK_TIMEOUT_MS})`,\n },\n },\n async run({ args }) {\n const timeoutMs = timeoutOf(args.timeout)\n let loaded: LoadedConfig | { error: unknown }\n try {\n loaded = await loadProject()\n } catch (error) {\n loaded = { error }\n }\n const report: DiagnosisReport =\n 'error' in loaded\n ? // Nothing else can be checked without a config, so it is the only line.\n { checks: [{ name: 'config', status: 'down', detail: errorText(loaded.error) }] }\n : await diagnose(loaded.config, {\n ...(loaded.adapters !== undefined && { adapters: loaded.adapters }),\n // The report carries every failure; a log line would only repeat one, and break `--json`.\n logger: createLogger({ level: 'silent', pretty: false }),\n timeoutMs,\n ...migrationsOf(loaded.projectRoot),\n })\n const text = formatDoctorReport(report, {\n json: args.json,\n config: 'error' in loaded ? undefined : loaded.config,\n env: process.env,\n })\n const down = report.checks.some((check) => check.status === 'down')\n // A pipe on macOS is written asynchronously: exiting before the write lands would cut the report short.\n process.stdout.write(`${text}\\n`, () => process.exit(down ? 1 : 0))\n },\n})\n","import pc from 'picocolors'\nimport type { NymbalConfig } from '@nymbalhq/config'\nimport type { DiagnosisReport } from '@nymbalhq/platform'\nimport { connectionSecrets, displayUrl, SECRET_MIN_LENGTH } from '@nymbalhq/types'\n\nexport interface FormatDoctorOptions {\n json: boolean\n /** The config the report was made from: its secret values are removed from every detail. */\n config?: NymbalConfig | undefined\n /** The environment it was made from, `.env` included: likewise. */\n env?: NodeJS.ProcessEnv\n}\n\ntype Status = DiagnosisReport['checks'][number]['status']\n\nconst TEXT_STATUS: Record<Status, 'ok' | 'warn' | 'down'> = {\n ok: 'ok',\n healthy: 'ok',\n degraded: 'warn',\n down: 'down',\n}\n\nconst JSON_STATUS: Record<Status, 'ok' | 'degraded' | 'down'> = {\n ok: 'ok',\n healthy: 'ok',\n degraded: 'degraded',\n down: 'down',\n}\n\nconst COLOUR = { ok: pc.green, warn: pc.yellow, down: pc.red }\n\n/** Config keys whose values are secrets: `secretKey`, `webhookSecret`, `jwtSecret`, SMTP's `pass`, an `apiKey`. */\nconst SECRET_KEY = /secret|passw(?:or)?d|^pass$|token|api[-_]?key|private[-_]?key|credential|access[-_]?key/i\n/** Environment variables whose values are secrets: `STRIPE_SECRET_KEY`, `SMTP_PASS`, `AWS_SECRET_ACCESS_KEY`. */\nconst SECRET_ENV =\n /SECRET|PASSWORD|PASSWD|(?:^|_)PASS(?:$|_)|TOKEN|API_KEY|PRIVATE_KEY|CREDENTIAL|ACCESS_KEY/i\nconst URL_IN_TEXT = /\\b[a-z][a-z0-9+.-]*:\\/\\/[^\\s'\"`<>]+/gi\nconst TRAILING_PUNCTUATION = /[.,;:)\\]}]+$/\n\nfunction addSecret(into: Set<string>, value: string): void {\n if (value.length >= SECRET_MIN_LENGTH) into.add(value)\n}\n\nfunction collectFromConfig(value: unknown, key: string, into: Set<string>, seen: WeakSet<object>) {\n if (typeof value === 'string') {\n if (SECRET_KEY.test(key)) addSecret(into, value)\n if (value.includes('://')) for (const s of connectionSecrets(value, { user: false })) addSecret(into, s)\n return\n }\n if (value === null || typeof value !== 'object' || seen.has(value)) return\n seen.add(value)\n for (const [k, v] of Object.entries(value)) collectFromConfig(v, k, into, seen)\n}\n\n/** Every value of `config` and `env` that must not be printed, longest first. */\nfunction secretsOf(config: NymbalConfig | undefined, env: NodeJS.ProcessEnv): string[] {\n const found = new Set<string>()\n collectFromConfig(config, '', found, new WeakSet())\n for (const [name, value] of Object.entries(env)) {\n if (value === undefined) continue\n if (SECRET_ENV.test(name)) addSecret(found, value)\n if (value.includes('://')) for (const s of connectionSecrets(value, { user: false })) addSecret(found, s)\n }\n return [...found].sort((a, b) => b.length - a.length)\n}\n\n/** A detail as it may be printed: on one line, every URL as `scheme://host:port/db`, and no secret value. */\nfunction scrub(detail: string, secrets: readonly string[]): string {\n let text = detail.replace(URL_IN_TEXT, (match) => {\n const trailing = TRAILING_PUNCTUATION.exec(match)?.[0] ?? ''\n return displayUrl(match.slice(0, match.length - trailing.length)) + trailing\n })\n for (const secret of secrets) text = text.split(secret).join('***')\n return text.replace(/\\s*\\n\\s*(?:•\\s*)?/g, ' ').trim()\n}\n\n/**\n * Doctor's output: one line per check (`<ok|warn|down> <name> <detail>`) and a count, or with `json` one document,\n * `{ checks: [{ name, status, detail }] }`, whose status is `ok`, `degraded` or `down`. Neither prints a secret.\n */\nexport function formatDoctorReport(report: DiagnosisReport, options: FormatDoctorOptions): string {\n const secrets = secretsOf(options.config, options.env ?? {})\n const checks = report.checks.map((check) => ({\n name: check.name,\n status: check.status,\n detail: scrub(check.detail, secrets),\n }))\n if (options.json) {\n return JSON.stringify(\n {\n checks: checks.map((c) => ({ name: c.name, status: JSON_STATUS[c.status], detail: c.detail })),\n },\n null,\n 2,\n )\n }\n const width = Math.max(...checks.map((c) => c.name.length), 0)\n const lines = checks.map((c) => {\n const status = TEXT_STATUS[c.status]\n return `${COLOUR[status](status.padEnd(4))} ${c.name.padEnd(width)} ${c.detail}`.trimEnd()\n })\n const count = (s: 'ok' | 'warn' | 'down') =>\n checks.filter((c) => TEXT_STATUS[c.status] === s).length\n return [...lines, '', `${count('down')} down, ${count('warn')} warn, ${count('ok')} ok`].join('\\n')\n}\n","import { defineCommand } from 'citty'\nimport { loadConfig } from '@nymbalhq/config'\nimport { run, runOrFail } from '../utils/spawn.js'\n\nexport const testCommand = defineCommand({\n meta: { name: 'test', description: 'Run unit + integration tests (vitest)' },\n async run() {\n await runOrFail('pnpm', ['vitest', 'run'])\n },\n})\n\nexport const testE2eCommand = defineCommand({\n meta: { name: 'test:e2e', description: 'Run Playwright E2E against the configured template' },\n async run() {\n const { config } = await loadConfig()\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep-invert', '@visual|@a11y',\n ])\n },\n})\n\nexport const testVisualCommand = defineCommand({\n meta: { name: 'test:visual', description: 'Run visual regression tests (Playwright toHaveScreenshot)' },\n args: {\n 'update-baselines': {\n type: 'boolean',\n description: 'Regenerate screenshot baselines',\n default: false,\n },\n },\n async run({ args }) {\n const { config } = await loadConfig()\n const isCI = !!process.env.CI\n const updateBaselines = args['update-baselines']\n\n if (updateBaselines && !isCI) {\n // Run in Docker for Linux-consistent baselines\n const dockerImage = 'mcr.microsoft.com/playwright:v1.50-jammy'\n const cwd = process.cwd()\n await runOrFail('docker', [\n 'run', '--rm', '-v', `${cwd}:${cwd}`, '-w', cwd,\n dockerImage, 'sh', '-c',\n `pnpm --filter @nymbalhq/e2e exec playwright test --project ${config.template} --grep \"@visual\" --update-snapshots`,\n ])\n } else {\n const pwArgs = [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep', '@visual',\n ]\n if (updateBaselines) pwArgs.push('--update-snapshots')\n await runOrFail('pnpm', pwArgs)\n }\n },\n})\n\nexport const testContractsCommand = defineCommand({\n meta: { name: 'test:contracts', description: 'Run adapter contract tests' },\n args: {\n adapter: { type: 'string', description: 'Run only contracts for a specific adapter (e.g. payments, email)' },\n },\n async run({ args }) {\n const vArgs = [\n 'vitest', 'run',\n '--project', 'contracts-native',\n ]\n if (args.adapter) {\n // Pass the specific file path as additional argument\n vArgs.push(`tests/contracts/${String(args.adapter)}.test.ts`)\n }\n await runOrFail('pnpm', vArgs)\n },\n})\n\nexport const testPerformanceCommand = defineCommand({\n meta: { name: 'test:performance', description: 'Run Lighthouse CI against the configured template' },\n async run() {\n const { config } = await loadConfig()\n const port = config.template === 'nextjs' ? 3000 : 4321\n await runOrFail('pnpm', ['lhci', 'autorun'], {\n env: {\n ...process.env,\n NYMBAL_TEMPLATE: config.template,\n NYMBAL_TEMPLATE_PORT: String(port),\n },\n })\n },\n})\n\nexport const testAllCommand = defineCommand({\n meta: { name: 'test:all', description: 'Run unit, contract, e2e, visual, and performance tests' },\n async run() {\n const steps: Array<{ name: string; args: string[] }> = [\n { name: 'unit', args: ['vitest', 'run'] },\n { name: 'contracts', args: ['vitest', 'run', '--project', 'contracts-native'] },\n ]\n\n for (const step of steps) {\n const { done } = run('pnpm', step.args)\n const code = await done\n if (code !== 0) {\n // eslint-disable-next-line no-console\n console.error(`✗ ${step.name} failed`)\n process.exit(code)\n }\n }\n\n const { config } = await loadConfig()\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep-invert', '@visual|@a11y',\n ])\n await runOrFail('pnpm', [\n '--filter', '@nymbalhq/e2e', 'exec',\n 'playwright', 'test', '--project', config.template, '--grep', '@visual',\n ])\n await runOrFail('pnpm', ['lhci', 'autorun'], {\n env: { ...process.env, NYMBAL_TEMPLATE: config.template },\n })\n },\n})\n"],"mappings":";AAAA,SAAS,iBAAAA,iBAAe,eAAe;;;ACAvC,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AAC9B,SAAS,qBAAqB;AAE9B,IAAM,mBAAmB;AAEzB,IAAI,SAAwB;AAM5B,SAAS,iBAAqC;AAC5C,MAAI,MAAM,QAAQ,cAAc,YAAY,GAAG,CAAC;AAChD,aAAS;AACP,QAAI;AACF,YAAM,MAAM,KAAK,MAAM,aAAa,KAAK,KAAK,cAAc,GAAG,MAAM,CAAC;AAItE,UAAI,IAAI,SAAS,iBAAkB,QAAO,IAAI;AAAA,IAChD,QAAQ;AAAA,IAER;AACA,UAAM,SAAS,QAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK,QAAO;AAC3B,UAAM;AAAA,EACR;AACF;AAEO,SAAS,gBAAwB;AACtC,aAAW,eAAe,KAAK;AAC/B,SAAO;AACT;;;ACjCA,SAAS,WAAAC,gBAAe;AACxB,SAAS,iBAAAC,sBAAqB;AAC9B,OAAO,QAAQ;AACf,SAAS,uBAA0C;;;ACHnD,SAAS,kBAAkB;AAC3B,SAAS,WAAAC,UAAS,eAAe;AACjC,SAAS,gBAAgB,kBAAqC;AAM9D,eAAsB,YAAY,WAAmB,QAAQ,IAAI,GAA0B;AACzF,QAAM,aAAa,eAAe,QAAQ;AAC1C,MAAI,YAAY;AACd,UAAM,UAAU,QAAQA,SAAQ,UAAU,GAAG,MAAM;AACnD,QAAI,WAAW,OAAO,EAAG,SAAQ,YAAY,OAAO;AAAA,EACtD;AACA,SAAO,WAAW,QAAQ;AAC5B;;;ADTA,SAAS,WAAW,cAAc,SAAS,kBAAkC;AAC7E,SAAS,wBAAwB;;;AEPjC,SAAS,aAAmD;AAMrD,SAAS,IACd,SACA,MACA,UAAsB,CAAC,GACyB;AAChD,QAAMC,SAAQ,MAAM,SAAS,MAAM;AAAA,IACjC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,GAAG;AAAA,EACL,CAAC;AACD,QAAM,OAAO,IAAI,QAAgB,CAACC,UAAS,WAAW;AACpD,IAAAD,OAAM,GAAG,SAAS,MAAM;AACxB,IAAAA,OAAM,GAAG,QAAQ,CAAC,SAASC,SAAQ,QAAQ,CAAC,CAAC;AAAA,EAC/C,CAAC;AACD,SAAO,EAAE,OAAAD,QAAO,KAAK;AACvB;AAEA,eAAsB,UACpB,SACA,MACA,UAAsB,CAAC,GACR;AACf,QAAM,EAAE,KAAK,IAAI,IAAI,SAAS,MAAM,OAAO;AAC3C,QAAM,OAAO,MAAM;AACnB,MAAI,SAAS,GAAG;AACd,UAAM,IAAI,MAAM,GAAG,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC,qBAAqB,IAAI,EAAE;AAAA,EACzE;AACF;;;ACjCA,SAAS,oBAAoB;AAY7B,eAAsB,WAAW,MAAc,MAAiC;AAC9E,SAAO,IAAI,QAAiB,CAACE,aAAY;AACvC,UAAM,SAAS,aAAa;AAC5B,WAAO,KAAK,SAAS,CAACC,SAA+B;AAGnD,UAAIA,KAAI,SAAS,gBAAgBA,KAAI,SAAS,UAAU;AAEtD,gBAAQ,MAAM,uCAAuC,IAAI,KAAKA,KAAI,OAAO;AAAA,MAC3E;AACA,MAAAD,SAAQ,KAAK;AAAA,IACf,CAAC;AACD,WAAO,KAAK,aAAa,MAAM;AAC7B,aAAO,MAAM,MAAMA,SAAQ,IAAI,CAAC;AAAA,IAClC,CAAC;AAKD,QAAI,MAAM;AACR,aAAO,OAAO,MAAM,IAAI;AAAA,IAC1B,OAAO;AACL,aAAO,OAAO,IAAI;AAAA,IACpB;AAAA,EACF,CAAC;AACH;AAMA,eAAsB,aACpB,WACA,cAAc,IACd,MACiB;AACjB,MAAI,CAAC,OAAO,UAAU,SAAS,KAAK,YAAY,KAAK,YAAY,OAAO;AACtE,UAAM,IAAI;AAAA,MACR,4BAA4B,SAAS;AAAA,IACvC;AAAA,EACF;AACA,WAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAM,YAAY,YAAY;AAC9B,QAAI,YAAY,MAAO;AACvB,QAAI,MAAM,WAAW,WAAW,IAAI,GAAG;AACrC,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,IAAI;AAAA,IACR,0CAA0C,SAAS,SAAI,KAAK,IAAI,YAAY,cAAc,GAAG,KAAK,CAAC;AAAA,EAErG;AACF;;;AChEA,SAAS,cAAAE,mBAAkB;AAC3B,SAAS,WAAAC,gBAAe;AAkBjB,SAAS,kBAAkB,UAA4C;AAC5E,SAAO,aAAa,UAAU,6BAA6B;AAC7D;AAUO,SAAS,eAAe,aAAqB,UAAiC;AACnF,QAAM,SAAS,aAAa,UAAU,qBAAqB;AAC3D,QAAM,YAAY,aAAa,UAAU,oBAAoB;AAC7D,SAAOD,YAAWC,SAAQ,aAAa,MAAM,CAAC,KAAKD,YAAWC,SAAQ,aAAa,SAAS,CAAC;AAC/F;AAUO,SAAS,gBAAgB,aAAqB,KAA4B;AAC/E,QAAM,UAAUA,SAAQ,aAAa,gBAAgB,QAAQ,GAAG;AAChE,SAAOD,YAAW,OAAO,IAAI,UAAU;AACzC;AASO,SAAS,mBACd,aACA,UACA,gBACgB;AAChB,MAAI,eAAe,aAAa,QAAQ,GAAG;AAIzC,UAAM,UAAU,aAAa,UAAU,UAAU;AACjD,UAAM,WAAW,gBAAgB,aAAa,OAAO;AACrD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR,mBAAmB,OAAO,kBAAkB,WAAW;AAAA,MAEzD;AAAA,IACF;AACA,WAAO;AAAA,MACL,KAAK;AAAA,MACL,SAAS;AAAA,MACT,MAAM,CAAC,OAAO,UAAU,OAAO,cAAc,GAAG,GAAG,eAAe,QAAQ,CAAC;AAAA,MAC3E,MAAM;AAAA,IACR;AAAA,EACF;AAGA,QAAM,SAAS,kBAAkB,QAAQ;AACzC,SAAO;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,IACT,MAAM,CAAC,YAAY,QAAQ,OAAO,GAAG,eAAe,QAAQ,CAAC;AAAA,IAC7D,MAAM;AAAA,EACR;AACF;AAMA,SAAS,eAAe,UAAkC;AACxD,SAAO,aAAa,UAAU,CAAC,eAAe,IAAI,CAAC;AACrD;;;AClGA,SAAS,qBAAqB;AAG9B,SAAS,oBAAoB,qBAAqB;AAClD,SAAS,WAAAE,UAAS,WAAAC,gBAAe;AACjC,SAAS,cAAAC,mBAAkB;AAEpB,IAAM,iBAAiB,cAAc;AAAA,EAC1C,MAAM,EAAE,MAAM,WAAW,aAAa,oCAAoC;AAAA,EAC1E,MAAM,MAAM;AACV,UAAM,EAAE,QAAQ,YAAY,IAAI,MAAM,YAAY;AAClD,UAAM,OAAO,MAAM,eAAe,QAAQ,WAAW;AAErD,YAAQ,IAAI,8BAAyB,IAAI,GAAG;AAAA,EAC9C;AACF,CAAC;AAGD,eAAsB,eAAe,QAAsB,aAAsC;AAC/F,QAAM,QAAQ,mBAAmB,MAAM;AACvC,MAAI;AACF,UAAM,cAAc,OAAO,EAAE,gBAAgB,kBAAkB,WAAW,EAAE,CAAC;AAC7E,WAAO,MAAM;AAAA,EACf,UAAE;AACA,UAAM,MAAM,MAAM;AAAA,EACpB;AACF;AAEO,SAAS,kBAAkB,aAA6B;AAE7D,QAAM,QAAQD,SAAQ,aAAa,YAAY;AAC/C,MAAIC,YAAW,KAAK,EAAG,QAAO;AAG9B,QAAM,cAAcD,SAAQ,aAAa,8BAA8B;AACvE,MAAIC,YAAW,WAAW,EAAG,QAAO;AAWpC,QAAM,SAAS,kBAAkB,aAAa,oBAAoB;AAClE,MAAI,QAAQ;AACV,UAAM,gBAAgBD,SAAQ,QAAQ,YAAY;AAClD,QAAIC,YAAW,aAAa,EAAG,QAAO;AAAA,EACxC;AAEA,SAAO;AACT;AASO,SAAS,kBAAkB,UAAkB,SAAgC;AAClF,MAAI,MAAMD,SAAQ,QAAQ;AAC1B,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,YAAYA,SAAQ,KAAK,gBAAgB,OAAO;AACtD,QAAIC,YAAWD,SAAQ,WAAW,cAAc,CAAC,GAAG;AAClD,aAAO;AAAA,IACT;AACA,UAAM,SAASD,SAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;;;AC1EA,SAAS,cAAAG,mBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAE9B,SAAS,SAAS,KAAsB;AACtC,SAAOF,YAAWE,MAAK,KAAK,YAAY,CAAC;AAC3C;AAMO,SAAS,mBAAkC;AAChD,QAAM,WAAW,QAAQ,IAAI,mBAAmB;AAChD,MAAI,YAAY,SAAS,QAAQ,EAAG,QAAO;AAC3C,MAAI;AACF,UAAM,WAAW,cAAc,YAAY,GAAG,EAAE,QAAQ,8BAA8B;AACtF,UAAM,OAAOA,MAAKD,SAAQ,QAAQ,GAAG,MAAM;AAC3C,WAAO,SAAS,IAAI,IAAI,OAAO;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AClBO,IAAM,oBAAoB;AAajC,IAAI,UAAU;AAOd,eAAsB,YAAY,OAAuB,MAAuC;AAC9F,MAAI,SAAS;AACX,SAAK,OAAO,MAAM,CAAC,GAAG,uCAAuC;AAC7D,WAAO,KAAK,KAAK,CAAC;AAAA,EACpB;AACA,YAAU;AAEV,MAAI;AACJ,MAAI,SAAS;AACb,QAAM,QAAQ,YAAY;AACxB,eAAW,QAAQ,OAAO;AACxB,gBAAU,KAAK;AACf,UAAI;AACF,cAAM,KAAK,IAAI;AAAA,MACjB,SAASE,MAAK;AACZ,iBAAS;AACT,aAAK,OAAO,MAAM,EAAE,KAAAA,MAAK,MAAM,KAAK,KAAK,GAAG,kBAAkB,KAAK,IAAI,UAAU;AAAA,MACnF;AAAA,IACF;AACA,cAAU;AAAA,EACZ,GAAG;AAEH,MAAI;AACJ,QAAM,QAAQ,IAAI,QAAiB,CAACC,aAAY;AAC9C,YAAQ,WAAW,MAAMA,SAAQ,OAAO,GAAG,KAAK,OAAO;AAAA,EACzD,CAAC;AACD,QAAM,UAAU,MAAM,QAAQ,KAAK,CAAC,KAAK,KAAK,MAAM,MAAe,GAAG,KAAK,CAAC;AAC5E,eAAa,KAAK;AAElB,MAAI,YAAY,SAAS;AACvB,SAAK,OAAO;AAAA,MACV,EAAE,MAAM,SAAS,SAAS,KAAK,QAAQ;AAAA,MACvC,kBAAkB,OAAO,2BAA2B,KAAK,OAAO;AAAA,IAClE;AACA,WAAO,KAAK,KAAK,CAAC;AAAA,EACpB;AACA,SAAO,KAAK,KAAK,SAAS,IAAI,CAAC;AACjC;;;AC7DA,SAAS,kBAAkB;AAgB3B,IAAM,QAAQ;AACd,IAAM,QAAQ;AAEd,IAAM,cAAc;AAGpB,IAAM,UAAU,CAACC,UAAiB,CAAC,GAAGA,KAAI,EAAE;AAE5C,SAAS,IAAIA,OAAc,QAAQ,OAAe;AAChD,SAAO,QAAQA,KAAI,KAAK,QAAQA,QAAO,GAAG,CAAC,GAAGA,KAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;AAClF;AAEA,SAAS,IAAI,OAAe,OAAuB;AACjD,SAAO,IAAI,KAAK,MAAM,OAAO,KAAK,CAAC,IAAI,KAAK,EAAE;AAChD;AAGA,SAAS,eAAe,cAAiC,OAAuB;AAC9E,MAAI,aAAa,WAAW,EAAG,QAAO;AACtC,QAAM,MAAM,aAAa,KAAK,IAAI;AAClC,MAAI,QAAQ,GAAG,KAAK,MAAO,QAAO;AAClC,WAAS,QAAQ,aAAa,SAAS,GAAG,QAAQ,GAAG,SAAS;AAC5D,UAAMA,QAAO,GAAG,aAAa,MAAM,GAAG,KAAK,EAAE,KAAK,IAAI,CAAC,cAAS,aAAa,SAAS,KAAK;AAC3F,QAAI,QAAQA,KAAI,KAAK,MAAO,QAAOA;AAAA,EACrC;AACA,SAAO,YAAO,aAAa,MAAM;AACnC;AAOO,SAAS,iBAAiB,MAA8B;AAC7D,QAAM,YAAY,KAAK,IAAI,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,MAAM,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9F,QAAM,gBAAgB,KAAK;AAAA,IACzB;AAAA,IACA,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,MAAM,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC;AAAA,EAC3D;AACA,QAAM,YAAY,KAAK,MAAM,IAAI,CAAC,EAAE,MAAM,UAAU,aAAa,MAAM;AACrE,UAAM,OAAO,KAAK,KAAK,OAAO,SAAS,CAAC,KAAK,SAAS,OAAO,aAAa,CAAC;AAC3E,WAAO,IAAI,GAAG,IAAI,GAAG,eAAe,cAAc,QAAQ,QAAQ,IAAI,CAAC,CAAC,EAAE;AAAA,EAC5E,CAAC;AACD,QAAM,eACJ,KAAK,aAAa,SAAS,WACvB,WAAW,KAAK,aAAa,IAAI,KACjC,aAAa,WAAW,KAAK,aAAa,GAAG,CAAC;AACpD,QAAM,QAAQ;AAAA,IACZ,IAAI,KAAK,KAAK,KAAK,EAAE;AAAA,IACrB;AAAA,IACA,IAAI,OAAO,KAAK,MAAM;AAAA,IACtB;AAAA,MACE;AAAA,MACA,KAAK,eAAe,OAChB,6BACA,GAAG,KAAK,WAAW,GAAG,MAAM,KAAK,WAAW,QAAQ;AAAA,IAC1D;AAAA,IACA;AAAA,MACE;AAAA,MACA,KAAK,UAAU,OAAO,6DAAwD,KAAK,MAAM;AAAA,IAC3F;AAAA,IACA,IAAI,iBAAiB,YAAY;AAAA,IACjC;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA,GAAG,KAAK,WAAW,IAAI,CAAC,EAAE,MAAM,SAAS,MAAM,IAAI,MAAM,QAAQ,CAAC;AAAA,IAClE;AAAA,IACA;AAAA,EACF;AACA,SAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA;AAC5B;;;ARpEO,SAAS,sBAAsB,UAAsC;AAC1E,SAAO,aAAa,UAAU,OAAO;AACvC;AAUO,SAAS,wBACd,UACA,UACA,KACQ;AACR,MAAI,OAAO,aAAa,YAAY,OAAO,SAAS,QAAQ,EAAG,QAAO;AACtE,QAAM,UAAU,IAAI,wBAAwB;AAC5C,MAAI,WAAW,QAAQ,KAAK,MAAM,IAAI;AACpC,UAAM,SAAS,OAAO,OAAO;AAC7B,QAAI,OAAO,UAAU,MAAM,KAAK,SAAS,EAAG,QAAO;AAAA,EACrD;AACA,SAAO,sBAAsB,QAAQ;AACvC;AAMO,SAAS,cACd,SACA,QACA,gBACA,UAA6B,QAAQ,KAClB;AACnB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,gBAAgB;AAAA,IAChB,uBAAuB;AAAA;AAAA,IACvB,4BAA4B;AAAA;AAAA;AAAA;AAAA,IAG5B,wBAAwB,OAAO,cAAc;AAAA,EAC/C;AACF;AAGO,SAAS,YAAY,SAAkB,KAAgC;AAC5E,QAAM,UAAU,IAAI,WAAW;AAC/B,MAAI,YAAY,UAAa,YAAY,GAAI,QAAO;AACpD,SAAO,UAAU,UAAU;AAC7B;AAGA,SAAS,YACP,QACA,KACA,QACA,YACA,YACgB;AAChB,QAAM,SAAS,IAAI,aAAa;AAChC,SAAO;AAAA,IACL,OAAO,OAAO,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,OAAO,aAAa,EAAE,KAAK,GAAG,MAAM,UAAU,IAAI;AAAA,IAClD,cACE,OAAO,eAAe,iBAAiB,WACnC,EAAE,MAAM,UAAU,MAAMC,SAAQ,WAAW,CAAC,EAAE,IAC9C,EAAE,MAAM,YAAY,KAAK,QAAQ,IAAI,cAAc,KAAK,GAAG;AAAA,IACjE,OAAQ,OAAO,KAAK,eAAe,EAAqB,IAAI,CAAC,UAAU;AAAA,MACrE;AAAA,MACA,UAAU,OAAO,IAAI,EAAE;AAAA,MACvB,cAAc,OAAO,IAAI,EAAE;AAAA,IAC7B,EAAE;AAAA,IACF,YAAa,CAAC,iBAAiB,YAAY,OAAO,EAAY,IAAI,CAAC,UAAU;AAAA,MAC3E;AAAA,MACA,UAAU,OAAO,IAAI,EAAE;AAAA,IACzB,EAAE;AAAA,EACJ;AACF;AAGA,SAAS,QAAQ,QAAsB,UAAsC;AAC3E,MAAI,aAAa,UAAa,SAAS,KAAK,MAAM,GAAI,QAAO,OAAO,KAAK;AACzE,QAAM,OAAO,OAAO,QAAQ;AAC5B,MAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO,OAAO;AACvD,UAAM,IAAI,MAAM,mDAAmD,QAAQ,GAAG;AAAA,EAChF;AACA,SAAO;AACT;AAEO,IAAM,aAAaC,eAAc;AAAA,EACtC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAON,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,gBAAgB;AAAA,MACd,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aACE;AAAA,IAEJ;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,SAAS,MAAM,YAAY;AACjC,UAAM,EAAE,YAAY,IAAI;AACxB,UAAM,OAAO,QAAQ,OAAO,QAAQ,KAAK,IAAI;AAC7C,UAAM,SAAuB,EAAE,GAAG,OAAO,QAAQ,MAAM,EAAE,GAAG,OAAO,OAAO,MAAM,KAAK,EAAE;AACvF,UAAM,UAAU,cAAc;AAG9B,UAAM,eAAe,QAAQ,WAAW;AAExC,UAAM,SAAS,aAAa;AAAA,MAC1B,MAAM,EAAE,OAAO,OAAO,MAAM,KAAK;AAAA,MACjC,OAAO,YAAY,KAAK,SAAS,QAAQ,GAAG;AAAA,IAC9C,CAAC;AACD,UAAM,MAAM,MAAM,UAAU,QAAQ;AAAA,MAClC;AAAA,MACA;AAAA,MACA,GAAI,OAAO,aAAa,UAAa,EAAE,UAAU,OAAO,SAAS;AAAA,IACnE,CAAC;AACD,UAAM,EAAE,SAAS,IAAI;AAErB,QAAI,KAAK,MAAM;AACb,YAAM,WAAW,MAAM,SAAS,cAAc,MAAM,YAAY;AAAA,QAC9D,cAAc,EAAE,OAAO,WAAW,OAAO,OAAO,MAAM,KAAK;AAAA,QAC3D,OAAO;AAAA,MACT,CAAC;AACD,UAAI,SAAS,MAAM,WAAW,GAAG;AAC/B,iBAAS,OAAO,KAAK,CAAC,GAAG,kCAAkC;AAC3D,cAAM,QAAQ;AAAA,UACZ;AAAA,UACA,cAAc,SAAS;AAAA,UACvB,eAAe,SAAS;AAAA,UACxB,UAAU,SAAS;AAAA,UACnB,QAAQ,SAAS;AAAA,UACjB;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,OAAO,iBAAiB;AAAA,MAC5B;AAAA,MACA,QAAQ,SAAS;AAAA,MACjB,eAAe,SAAS;AAAA,MACxB;AAAA,IACF,CAAC;AACD,UAAM,YAAY,iBAAiB;AACnC,UAAM,IAAI,WAAW,KAAK,SAAS,EAAE,UAAU,CAAC;AAChD,UAAM,KAAK,MAAM;AACjB,UAAM,SAAS,oBAAoB,OAAO,KAAK,IAAI;AACnD,UAAM,eAAe,CAAC,eAA6C;AAEjE,cAAQ,IAAI,iBAAiB,YAAY,QAAQ,KAAK,QAAQ,YAAY,cAAc,IAAI,CAAC,CAAC;AAAA,IAChG;AAEA,UAAM,UAA0B;AAAA,MAC9B,EAAE,MAAM,aAAa,KAAK,MAAM,KAAK,KAAK,EAAE;AAAA,MAC5C,EAAE,MAAM,YAAY,KAAK,MAAM,IAAI,KAAK,EAAE;AAAA,IAC5C;AACA,UAAM,eAAe,CAAC,UACpB,YAAY,OAAO;AAAA,MACjB,SAAS;AAAA,MACT,QAAQ,SAAS;AAAA,MACjB,MAAM,CAAC,SAAS,QAAQ,KAAK,IAAI;AAAA,IACnC,CAAC;AAEH,QAAI,KAAK,SAAS;AAChB,mBAAa,IAAI;AACjB,YAAMC,YAAW,CAAC,WAAmB;AACnC,iBAAS,OAAO,KAAK,EAAE,OAAO,GAAG,mBAAmB;AACpD,eAAO,aAAa,OAAO;AAAA,MAC7B;AACA,cAAQ,GAAG,UAAU,MAAM,KAAKA,UAAS,QAAQ,CAAC;AAClD,cAAQ,GAAG,WAAW,MAAM,KAAKA,UAAS,SAAS,CAAC;AAEpD;AAAA,IACF;AAKA,UAAM,cAAc,KAAK;AACzB,UAAM,WACJ,OAAO,gBAAgB,YAAY,YAAY,KAAK,MAAM,KAAK,OAAO,WAAW,IAAI;AACvF,UAAM,YAAY,wBAAwB,OAAO,UAAU,UAAU,QAAQ,GAAG;AAChF,UAAM,iBAAiB,MAAM,aAAa,SAAS;AACnD,QAAI,mBAAmB,WAAW;AAEhC,cAAQ;AAAA,QACN,GAAG;AAAA,UACD,0BAAqB,SAAS,6BAA6B,GAAG,KAAK,OAAO,cAAc,CAAC,CAAC;AAAA,QAC5F;AAAA,MACF;AAAA,IACF;AAKA,UAAM,SAAS,mBAAmB,aAAa,OAAO,UAAU,cAAc;AAE9E,UAAM,gBAAgB,oBAAoB,cAAc;AACxD,UAAM,eAAe,IAAI,OAAO,SAAS,OAAO,MAAM;AAAA,MACpD,KAAK,OAAO;AAAA,MACZ,KAAK,cAAc,QAAQ,QAAQ,cAAc;AAAA,IACnD,CAAC;AACD,iBAAa,EAAE,UAAU,GAAG,OAAO,QAAQ,KAAK,OAAO,IAAI,IAAI,KAAK,cAAc,CAAC;AAEnF,QAAI,eAAe;AACnB,UAAM,WAAW,CAAC,WAAmB;AACnC,qBAAe;AACf,eAAS,OAAO,KAAK,EAAE,OAAO,GAAG,eAAe;AAChD,aAAO,aAAa;AAAA,QAClB;AAAA,UACE,MAAM;AAAA,UACN,KAAK,YAAY;AACf,yBAAa,MAAM,KAAK,QAAQ;AAAA,UAClC;AAAA,QACF;AAAA,QACA,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AACA,YAAQ,GAAG,UAAU,MAAM,KAAK,SAAS,QAAQ,CAAC;AAClD,YAAQ,GAAG,WAAW,MAAM,KAAK,SAAS,SAAS,CAAC;AAEpD,UAAM,eAAe,MAAM,aAAa;AACxC,aAAS,OAAO,KAAK,EAAE,MAAM,aAAa,GAAG,yBAAyB;AAGtE,QAAI,aAAc;AAClB,UAAM,SAAS,eAAe;AAAA,EAChC;AACF,CAAC;;;AS1RD,SAAS,iBAAAC,sBAAqB;AAKvB,IAAM,eAAeC,eAAc;AAAA,EACxC,MAAM,EAAE,MAAM,SAAS,aAAa,8CAA8C;AAAA,EAClF,MAAM,MAAM;AACV,UAAM,EAAE,QAAQ,YAAY,IAAI,MAAM,YAAY;AAClD,QAAI,CAAC,eAAe,aAAa,OAAO,QAAQ,GAAG;AAEjD,YAAM,UAAU,QAAQ,CAAC,YAAY,kBAAkB,OAAO,QAAQ,GAAG,OAAO,GAAG;AAAA,QACjF,KAAK;AAAA,MACP,CAAC;AACD;AAAA,IACF;AACA,UAAM,UAAU,OAAO,aAAa,UAAU,UAAU;AACxD,UAAM,MAAM,gBAAgB,aAAa,OAAO;AAChD,QAAI,CAAC,KAAK;AACR,YAAM,IAAI;AAAA,QACR,mBAAmB,OAAO,cAAc,WAAW;AAAA,MAErD;AAAA,IACF;AACA,UAAM,UAAU,KAAK,CAAC,OAAO,GAAG,EAAE,KAAK,YAAY,CAAC;AAAA,EACtD;AACF,CAAC;;;AC1BD,SAAS,iBAAAC,sBAAqB;AAE9B,SAAS,gBAAgB,mBAAmB,WAAAC,gBAAe;AAIpD,IAAM,cAAcC,eAAc;AAAA,EACvC,MAAM,EAAE,MAAM,QAAQ,aAAa,8CAA8C;AAAA,EACjF,MAAM,MAAM;AACV,UAAM,EAAE,QAAQ,YAAY,IAAI,MAAM,YAAY;AAElD,UAAM,eAAe,QAAQ,WAAW;AACxC,UAAM,WAAW,eAAe,QAAQ,MAAM,kBAAkB,MAAM,CAAC;AACvE,QAAI;AACF,YAAM,SAAS,MAAMC,SAAQ;AAAA,QAC3B;AAAA,QACA,cAAc,SAAS;AAAA,QACvB,eAAe,SAAS;AAAA,QACxB,UAAU,SAAS;AAAA,QACnB,QAAQ,SAAS;AAAA,QACjB,SAAS,cAAc;AAAA,MACzB,CAAC;AAED,cAAQ;AAAA,QACN,OAAO,gBACH,yDACA,iBAAY,OAAO,QAAQ,oBAAoB,OAAO,UAAU;AAAA,MACtE;AAAA,IACF,UAAE;AACA,YAAM,SAAS,MAAM;AAAA,IACvB;AAAA,EACF;AACF,CAAC;;;AChCD,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,OAAO,OAAO,MAAM,QAAQ,SAAS,UAAU,cAAc;AACtE,OAAO,OAAO;AAEd,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,sBAAsB,mBAA0D;AACzF,SAAS,QAAAC,aAAY;AAGd,IAAM,gBAAgBC,eAAc;AAAA,EACzC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,KAAK;AAAA,MACH,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,KAAK;AAAA,MACH,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,IAAI;AAAA,MACF,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,EAAE,OAAO,IAAI,MAAM,YAAY;AACrC,UAAM,cAAc,QAAQ,IAAI;AAChC,UAAM,YAAYC,MAAK,aAAa,wBAAwB;AAC5D,UAAM,QAAQ,QAAQ,MAAM,SAAS;AAErC,UAAM,EAAE,KAAK,eAAe,CAAC;AAG7B,QAAI,SAAS,KAAK;AAClB,QAAI,CAAC,QAAQ;AACX,UAAI,CAAC,OAAO;AACV,gBAAQ,MAAM,oCAAoC;AAClD,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,YAAM,SAAS,MAAM,OAAO;AAAA,QAC1B,SAAS;AAAA,QACT,SAAS,CAAC,EAAE,OAAO,eAAe,OAAO,cAAc,CAAC;AAAA,MAC1D,CAAC;AACD,UAAI,SAAS,MAAM,GAAG;AAAE,eAAO,kBAAkB;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AACpE,eAAS,OAAO,MAAM;AAAA,IACxB;AACA,QAAI,WAAW,eAAe;AAC5B,cAAQ,MAAM,uBAAuB,MAAM,oCAAoC;AAC/E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,QAAI,WAAW,KAAK;AACpB,QAAI,CAAC,UAAU;AACb,UAAI,CAAC,OAAO;AAAE,gBAAQ,MAAM,mBAAmB;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AAClE,YAAM,MAAM,MAAM,KAAK,EAAE,SAAS,cAAc,aAAa,uBAAuB,UAAU,CAAC,MAAM,EAAE,WAAW,MAAM,IAAI,SAAY,gBAAgB,CAAC;AACzJ,UAAI,SAAS,GAAG,GAAG;AAAE,eAAO,kBAAkB;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AACjE,iBAAW,OAAO,GAAG;AAAA,IACvB;AAEA,QAAI,cAAc,KAAK,OAAO,QAAQ,IAAI,iBAAiB,KAAK;AAChE,QAAI,CAAC,aAAa;AAChB,UAAI,CAAC,OAAO;AAAE,gBAAQ,MAAM,sCAAsC;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AACrF,YAAM,MAAM,MAAM,KAAK,EAAE,SAAS,iBAAiB,aAAa,SAAS,CAAC;AAC1E,UAAI,SAAS,GAAG,GAAG;AAAE,eAAO,kBAAkB;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AACjE,oBAAc,OAAO,GAAG;AAAA,IAC1B;AAEA,QAAI,iBAAiB,KAAK,UAAU,QAAQ,IAAI,oBAAoB,KAAK;AACzE,QAAI,CAAC,gBAAgB;AACnB,UAAI,CAAC,OAAO;AAAE,gBAAQ,MAAM,4CAA4C;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AAC3F,YAAM,MAAM,MAAM,KAAK,EAAE,SAAS,oBAAoB,aAAa,SAAS,CAAC;AAC7E,UAAI,SAAS,GAAG,GAAG;AAAE,eAAO,kBAAkB;AAAG,gBAAQ,KAAK,CAAC;AAAA,MAAE;AACjE,uBAAiB,OAAO,GAAG;AAAA,IAC7B;AAGA,QAAI;AACJ,QAAI,KAAK,UAAU;AACjB,mBAAa,KAAK,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,IAC3D,OAAO;AACL,mBAAa,CAAC,cAAc,YAAY,aAAa,QAAQ;AAAA,IAC/D;AAEA,UAAM,cAAc,SAAS,OAAO,KAAK,eAAe,GAAG,GAAG,EAAE;AAChE,UAAM,YAAY,KAAK,OAAO;AAC9B,UAAM,cAAc,KAAK,SAAS;AAGlC,UAAM,WAAW,QAAQ;AACzB,aAAS,MAAM,yBAAoB;AACnC,UAAM,MAAM,MAAMC,WAAU,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;AAChE,aAAS,KAAK,gBAAgB;AAE9B,QAAI;AACF,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,UACE,aAAa,EAAE,KAAK,UAAU,aAAa,eAAe;AAAA,UAC1D,UAAU;AAAA,UACV,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,KAAK;AAAA,UACZ;AAAA,UACA;AAAA,UACA,UAAU,OAAO,MAAM;AAAA,UACvB;AAAA,QACF;AAAA,QACA;AAAA,UACE,UAAU,IAAI;AAAA,UACd,OAAO,IAAI;AAAA,UACX,UAAU,EAAE,IAAI,IAAI,SAAS,IAAI,SAAS,IAAI,SAAS,QAAQ;AAAA,UAC/D,OAAO,IAAI,SAAS;AAAA,UACpB,WAAW,OAAsB;AAC/B,gBAAI,MAAM,SAAS,SAAS;AAC1B,sBAAQ,IAAI,EAAE,KAAK,YAAO,MAAM,KAAK,EAAE,CAAC;AAAA,YAC1C,WAAW,MAAM,SAAS,YAAY;AACpC,oBAAM,MAAM,KAAK,MAAO,MAAM,OAAO,MAAM,QAAS,GAAG;AACvD,sBAAQ,OAAO,MAAM,OAAO,MAAM,MAAM,KAAK,MAAM,IAAI,IAAI,MAAM,KAAK,KAAK,GAAG,MAAM;AACpF,kBAAI,MAAM,SAAS,MAAM,MAAO,SAAQ,OAAO,MAAM,IAAI;AAAA,YAC3D,WAAW,MAAM,SAAS,SAAS;AACjC,sBAAQ,IAAI,EAAE,IAAI,YAAO,MAAM,KAAK,KAAK,MAAM,EAAE,MAAM,MAAM,OAAO,EAAE,CAAC;AAAA,YACzE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,aAAa,MAAM,YAAY,QAAQ,aAAa,OAAO,MAAM,IAAI;AAE3E;AAAA,QACE;AAAA,UACE,EAAE,MAAM,wBAAmB;AAAA,UAC3B,iBAAiB,OAAO,SAAS,QAAQ;AAAA,UACzC,iBAAiB,OAAO,SAAS,SAAS;AAAA,UAC1C,iBAAiB,OAAO,SAAS,MAAM;AAAA,UACvC,iBAAiB,OAAO,SAAS,UAAU;AAAA,UAC3C,GAAI,YAAY,CAAC,kBAAkB,OAAO,SAAS,QAAQ,WAAW,IAAI,CAAC;AAAA,UAC3E,GAAI,OAAO,OAAO,SAAS,IAAI,CAAC,EAAE,OAAO,YAAO,OAAO,OAAO,MAAM,2BAAsB,CAAC,IAAI,CAAC;AAAA,UAChG;AAAA,UACA,aAAa,UAAU;AAAA,UACvB,aAAa,EAAE,KAAK,YAAY,CAAC;AAAA,QACnC,EAAE,KAAK,IAAI;AAAA,MACb;AAAA,IACF,UAAE;AACA,YAAM,IAAI,KAAK;AAAA,IACjB;AAAA,EACF;AACF,CAAC;;;ACjLD,SAAS,iBAAAC,sBAAqB;AAC9B,OAAOC,SAAQ;AAEf,SAAS,mBAAmB;AAErB,IAAM,wBAAwBC,eAAc;AAAA,EACjD,MAAM,EAAE,MAAM,mBAAmB,aAAa,4BAA4B;AAAA,EAC1E,MAAM,MAAM;AACV,QAAI;AACF,YAAM,EAAE,QAAQ,KAAK,IAAI,MAAM,YAAY;AAE3C,cAAQ,IAAIC,IAAG,MAAM,qBAAgB,IAAI,KAAK,IAAI,GAAG;AAErD,cAAQ;AAAA,QACN,eAAe,OAAO,QAAQ,mBAAmB,OAAO,eAAe,YAAY,oBAAoB,OAAO,eAAe,aAAa,eAAe,OAAO,eAAe,QAAQ;AAAA,MACzL;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB,SAASC,MAAK;AACZ,UAAIA,gBAAe,aAAa;AAE9B,gBAAQ,MAAMD,IAAG,IAAI,uBAAkB,CAAC;AAExC,gBAAQ,MAAMC,KAAI,OAAO;AAAA,MAC3B,OAAO;AAEL,gBAAQ,MAAMA,IAAG;AAAA,MACnB;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF,CAAC;;;AC9BD,SAAS,iBAAiB;AAC1B,SAAS,cAAAC,aAAY,aAAa,gBAAAC,eAAc,QAAQ,qBAAqB;AAC7E,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,SAAS,gBAAgB;AACzB,SAAS,iBAAAC,sBAAqB;AAC9B,OAAOC,SAAQ;AACf,SAAS,kBAAAC,iBAAgB,cAAAC,mBAAkB;AAC3C,SAAS,mBAAmB;;;ACP5B,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,WAAAC,UAAS,QAAAC,OAAM,WAAAC,gBAAe;AAOhC,IAAM,iBAAmD;AAAA,EAC9D,UAAU;AAAA,EACV,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,QAAQ;AACV;AAEO,SAAS,eAAyB;AACvC,SAAO,OAAO,KAAK,cAAc,EAAE,KAAK;AAC1C;AAEO,SAAS,cAAc,MAAuB;AACnD,SAAO,OAAO,OAAO,gBAAgB,IAAI;AAC3C;AAEA,SAAS,cAAc,MAAqB;AAC1C,SAAO,IAAI,MAAM,mBAAmB,IAAI,sBAAsB,aAAa,EAAE,KAAK,IAAI,CAAC,EAAE;AAC3F;AAMA,SAAS,WAAW,KAAa,aAAoC;AACnE,MAAI,MAAMA,SAAQ,WAAW;AAC7B,SAAO,MAAM;AACX,UAAM,YAAYD,MAAK,KAAK,gBAAgB,GAAG;AAC/C,QAAIH,YAAWG,MAAK,WAAW,cAAc,CAAC,EAAG,QAAO;AACxD,UAAM,SAASD,SAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK,QAAO;AAC3B,UAAM;AAAA,EACR;AACF;AAGO,SAAS,WAAW,MAAc,aAAoC;AAC3E,QAAM,SAAS,eAAe,IAAI;AAClC,MAAI,WAAW,UAAa,CAAC,cAAc,IAAI,EAAG,OAAM,cAAc,IAAI;AAC1E,QAAM,MAAM,WAAW,QAAQ,WAAW;AAC1C,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAI;AAEF,WAAOD,eAAcE,MAAK,KAAK,cAAc,CAAC,EAAE,QAAQ,GAAG,MAAM,YAAY,IAAI,OAAO;AAAA,EAC1F,SAAS,OAAO;AACd,UAAM,OAAQ,MAA6B;AAC3C,QAAI,SAAS,sBAAsB,SAAS,gCAAiC,QAAO;AACpF,UAAM;AAAA,EACR;AACF;AAEO,SAAS,YAAY,KAAa,aAA8B;AACrE,SAAO,WAAW,KAAK,WAAW,MAAM;AAC1C;AAGA,eAAsB,WAAW,MAAc,aAAsC;AACnF,QAAM,OAAO,WAAW,MAAM,WAAW;AACzC,MAAI,SAAS,MAAM;AACjB,UAAM,IAAI;AAAA,MACR,GAAG,eAAe,IAAI,CAAC,wBAAwB,WAAW,YAAY,IAAI;AAAA,IAC5E;AAAA,EACF;AACA,QAAM,SAAS,KAAK,MAAM,MAAM,SAAS,MAAM,MAAM,CAAC;AACtD,QAAM,YACJ,WAAW,QACX,OAAO,WAAW,YAClB,OAAO,SAAS,QAChB,CAAC,MAAM,QAAQ,OAAO,OAAO,KAC7B,CAAC,MAAM,QAAQ,OAAO,GAAG,KACzB,CAAC,MAAM,QAAQ,OAAO,GAAG,KACzB,CAAC,MAAM,QAAQ,OAAO,IAAI;AAC5B,MAAI,UAAW,OAAM,IAAI,MAAM,GAAG,IAAI,aAAa,IAAI,SAAS;AAChE,SAAO;AACT;;;ACnFA,SAAS,mBAAmB;AAIrB,IAAM,oBAAuC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,gBAAgB;AAatB,IAAM,QAAQ,CAAC,MAAY,QAAsB,KAAK,GAAG;AACzD,IAAM,WAAW,CAAC,MAAY,QAAwB,KAAK,GAAG;AAG9D,SAAS,MAAM,IAAkB;AAE/B,SAAO,YAAY,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE;AAC1C;AAEA,IAAM,SAAS,CAAC,WAA2B,OAAO,QAAQ,SAAS,IAAI;AAEvE,SAAS,OAAO,MAA0C;AACxD,MAAI,KAAK;AACT,SACE,OAAO,WACN,GAAG,SAAS,oBACX,GAAG,SAAS,2BACZ,GAAG,SAAS,yBACZ,GAAG,SAAS,4BACd;AACA,SAAK,MAAM,IAAI,YAAY;AAAA,EAC7B;AACA,SAAO;AACT;AAEA,SAAS,OAAO,MAAgC;AAC9C,MAAI,KAAK,SAAS,aAAc,QAAO,KAAK,MAAM;AAClD,MAAI,KAAK,SAAS,gBAAiB,QAAO,KAAK,OAAO;AACtD,MAAI,KAAK,SAAS,iBAAkB,QAAO,OAAO,KAAK,OAAO,CAAC;AAC/D,SAAO;AACT;AAcA,SAAS,cAAc,SAAuB;AAC5C,SAAO,SAAS,SAAS,MAAM,EAAE;AAAA,IAC/B,CAAC,MACC,EAAE,SAAS,uBACX,MAAM,GAAG,QAAQ,EAAE,OAAO,MAAM,iBAChC,EAAE,YAAY,MAAM;AAAA,EACxB;AACF;AAEA,SAAS,WAAW,SAAe,UAAsC;AACvE,aAAW,QAAQ,cAAc,OAAO,GAAG;AACzC,eAAW,QAAQ,SAAS,MAAM,YAAY,GAAG;AAC/C,UAAI,KAAK,SAAS,qBAAqB,KAAK,YAAY,MAAM,OAAQ;AACtE,UAAI,OAAO,MAAM,MAAM,UAAU,CAAC,MAAM;AACtC,eAAO,MAAM,MAAM,OAAO,EAAE,MAAM;AAAA,IACtC;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,SAAS,SAAwB;AACxC,QAAM,QAAQ,CAAC,OAAkC,IAAI,SAAS,gBAAgB,GAAG,MAAM,MAAM;AAC7F,SAAO,SAAS,SAAS,MAAM,EAAE,KAAK,CAAC,MAAM;AAC3C,UAAM,OAAO,EAAE,SAAS,2BAA2B,MAAM,GAAG,aAAa,IAAI;AAC7E,QAAI,SAAS,QAAQ,SAAS,OAAW,QAAO;AAChD,QAAI,KAAK,SAAS;AAChB,aAAO,SAAS,MAAM,YAAY,EAAE,KAAK,CAAC,MAAM,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC;AAC1E,QAAI,KAAK,SAAS;AAChB,aAAO,SAAS,MAAM,cAAc,EAAE,KAAK,CAAC,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC;AACzE,WAAO,MAAM,MAAM,MAAM,IAAI,CAAC;AAAA,EAChC,CAAC;AACH;AAGA,SAAS,OAAO,QAA0C;AACxD,QAAM,UAAU,MAAM,MAAM;AAC5B,QAAM,WAAW,SAAS,SAAS,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,0BAA0B;AAC5F,MAAI,aAAa,OAAW,QAAO;AACnC,MAAI,SAAS,OAAO,MAAM,UAAU,aAAa,CAAC;AAClD,MAAI,QAAQ,SAAS,kBAAkB;AACrC,UAAM,SAAS,MAAM,QAAQ,QAAQ;AACrC,UAAM,SAAS,WAAW,SAAS,cAAc,KAAK;AACtD,QAAI,OAAO,SAAS,gBAAgB,OAAO,MAAM,MAAM,OAAQ,QAAO;AACtE,aAAS,OAAO,SAAS,QAAQ,WAAW,EAAE,CAAC,CAAC;AAAA,EAClD;AACA,MAAI,QAAQ,SAAS,mBAAoB,QAAO;AAEhD,MAAI,OAAO,OAAO,KAAK,MAAM,OAAO,OAAO,OAAO,MAAM,CAAC,MAAM,IAAK,QAAO;AAC3E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,SAAS,WAAW,SAAS,KAAK;AAAA,IAClC,UAAU,SAAS,OAAO;AAAA,IAC1B,aAAa,cAAc,OAAO,EAAE;AAAA,MAAK,CAAC,MACxC,SAAS,GAAG,YAAY,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,iBAAiB;AAAA,IACpE;AAAA,EACF;AACF;AAEA,SAAS,SAAS,OAA4D;AAC5E,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,OAAO,OAAO,KAAK,KAAK;AAC9B,SACE,OAAQ,MAA4B,QAAQ,YAC5C,KAAK,MAAM,CAAC,MAAM,MAAM,SAAS,MAAM,SAAS;AAEpD;AAGA,SAAS,SAAS,MAAY,SAAsC;AAClE,QAAM,KAAK,OAAO,IAAI;AACtB,UAAQ,GAAG,MAAM;AAAA,IACf,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,GAAG,OAAO;AAAA,IACnB,KAAK,mBAAmB;AACtB,YAAM,SAAS,SAAS,IAAI,QAAQ;AACpC,aAAO,SAAS,IAAI,aAAa,EAAE,WAAW,KACzC,OAAO,CAAC,IAAI,OAAO,GAAyB,SAC7C;AAAA,IACN;AAAA,IACA,KAAK,oBAAoB;AACvB,YAAME,OAA+B,CAAC;AACtC,iBAAW,QAAQ,SAAS,IAAI,YAAY,GAAG;AAC7C,cAAM,MACJ,KAAK,SAAS,oBAAoB,CAAC,KAAK,UAAU,IAC9C,OAAO,MAAM,MAAM,KAAK,CAAC,IACzB;AACN,cAAM,QAAQ,QAAQ,SAAY,SAAY,SAAS,MAAM,MAAM,OAAO,GAAG,OAAO;AACpF,YAAI,QAAQ,UAAa,UAAU,OAAW,QAAO;AACrD,QAAAA,KAAI,GAAG,IAAI;AAAA,MACb;AACA,aAAOA;AAAA,IACT;AAAA,IACA,KAAK,kBAAkB;AACrB,YAAM,SAAS,MAAM,IAAI,QAAQ;AACjC,YAAM,OAAO,SAAS,IAAI,WAAW;AACrC,UAAI,OAAO,SAAS,gBAAgB,OAAO,MAAM,OAAO,WAAW,OAAQ,QAAO;AAClF,UAAI,KAAK,SAAS,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,eAAe;AACnF,eAAO;AACT,aAAO;AAAA,QACL,KAAK,KAAK,CAAC,EAAG,OAAO;AAAA,QACrB,GAAI,KAAK,CAAC,MAAM,UAAa,EAAE,SAAS,KAAK,CAAC,EAAE,OAAO,EAAE;AAAA,MAC3D;AAAA,IACF;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,UAAU,GAAY,GAAqB;AAClD,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,MAAM,QAAQ,MAAM,KAAM,QAAO,MAAM;AAC7F,QAAM,KAAK,OAAO,KAAK,CAAC,EAAE,KAAK;AAC/B,QAAM,KAAK,OAAO,KAAK,CAAC,EAAE,KAAK;AAC/B,SACE,GAAG,WAAW,GAAG,UACjB,GAAG;AAAA,IACD,CAAC,GAAG,MACF,MAAM,GAAG,CAAC,KACV,UAAW,EAA8B,CAAC,GAAI,EAA8B,CAAC,CAAC;AAAA,EAClF;AAEJ;AAEA,SAAS,kBAAkB,OAAyB;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO,kBAAkB,SAAS,KAAK;AACtE,QAAM,WAAY,OAAyC;AAC3D,SAAO,OAAO,aAAa,YAAY,kBAAkB,SAAS,QAAQ;AAC5E;AAQA,SAAS,QAAQ,QAAgB,KAA0B;AACzD,QAAM,cAAc,mCAAmC,KAAK,OAAO,MAAM,IAAI,OAAO,KAAK,CAAC;AAC1F,QAAM,WAAW,eAAe,KAAK,OAAO,MAAM,IAAI,OAAO,KAAK,CAAC;AACnE,SAAO;AAAA,IACL,OAAO,cAAc,CAAC,KAAK;AAAA,IAC3B,MAAM,WAAW,CAAC,KAAK;AAAA,IACvB,SAAS,IAAI,WAAW;AAAA,EAC1B;AACF;AAEA,SAAS,OAAOC,OAAc,OAAsB;AAClD,QAAM,IAAI,MAAM;AAChB,QAAM,OAAOA,MACV,QAAQ,OAAO,MAAM,EACrB,QAAQ,IAAI,OAAO,GAAG,GAAG,GAAG,KAAK,CAAC,EAAE,EACpC,QAAQ,OAAO,KAAK,EACpB,QAAQ,OAAO,KAAK;AACvB,SAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;AACxB;AAEA,SAAS,UAAU,KAAa,OAAsB;AACpD,SAAO,qBAAqB,KAAK,GAAG,IAAI,MAAM,OAAO,KAAK,KAAK;AACjE;AAGA,SAAS,OAAO,OAAoB,QAAgB,OAAsB;AACxE,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,OAAO,KAAK;AACzD,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAW,QAAO,OAAO,KAAK;AAChF,MAAI,SAAS,KAAK,GAAG;AACnB,UAAM,WAAW,MAAM,YAAY,SAAY,KAAK,KAAK,OAAO,MAAM,SAAS,KAAK,CAAC;AACrF,WAAO,GAAG,MAAM,OAAO,IAAI,OAAO,MAAM,KAAK,KAAK,CAAC,GAAG,QAAQ;AAAA,EAChE;AACA,QAAM,UAAU,OAAO,QAAQ,KAAK;AACpC,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,QAAQ,SAAS,MAAM;AAC7B,QAAM,QAAQ,QAAQ;AAAA,IACpB,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,KAAK,CAAC,KAAK,OAAO,GAAG,OAAO,KAAK,CAAC;AAAA,EACxE;AACA,SAAO;AAAA,EAAM,MAAM,KAAK,IAAI,CAAC;AAAA,EAAK,MAAM;AAC1C;AAEA,SAAS,UAAU,OAA6B;AAC9C,MAAI,SAAS,KAAK,EAAG,QAAO;AAC5B,SAAO,OAAO,UAAU,YAAY,OAAO,OAAO,KAAK,EAAE,KAAK,SAAS;AACzE;AAGA,SAAS,SAAS,QAAgB,QAAwB;AACxD,QAAM,YAAY,OAAO,YAAY,MAAM,SAAS,CAAC,IAAI;AACzD,SAAO,UAAU,KAAK,OAAO,MAAM,SAAS,CAAC,EAAG,CAAC;AACnD;AASA,SAAS,QAAQ,QAAgB,OAAyB;AAExD,QAAM,OAAiB,CAAC;AACxB,aAAW,KAAK,OAAO,SAAS,OAAO,EAAG,MAAK,KAAK,EAAE,QAAQ,KAAK,MAAM;AACzE,QAAM,KAAK,CAAC,OAAuB,KAAK,KAAK,OAAO,CAACC,OAAMA,KAAI,EAAE,EAAE;AACnE,QAAM,YAAY,qBAAqB,KAAK,MAAM,IAAI,CAAC,KAAK;AAC5D,SAAO,MACJ,IAAI,CAAC,MAAM;AACV,UAAM,QAAQ,GAAG,EAAE,EAAE;AACrB,UAAM,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM;AAC9B,UAAM,MAAM,QAAQ,KAAK,OAAO,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK;AACpD,WAAO,EAAE,OAAO,KAAK,MAAM,EAAE,KAAK,QAAQ,OAAO,GAAG,EAAE;AAAA,EACxD,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,OAAO,CAAC,GAAG,MAAM,EAAE,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,MAAM;AAC3E;AAGA,SAAS,YACP,QACA,QACA,KACA,OACA,OACU;AACV,QAAM,QAAQ,SAAS,QAAQ,YAAY;AAC3C,QAAM,QAAQ,OAAO,MAAM;AAC3B,QAAM,OAAO,MAAM,GAAG,EAAE;AACxB,MAAI,SAAS,QAAW;AACtB,UAAMC,UAAS,SAAS,QAAQ,OAAO,KAAK;AAC5C,UAAM,SAAS,OAAO,MAAM,OAAO,QAAQ,GAAG,KAAK;AACnD,UAAMF,QAAO,GAAGE,OAAM,GAAG,MAAM,IAAI,GAAG,UAAU,KAAK,KAAK,CAAC,KAAK,OAAO,OAAOA,UAAS,MAAM,MAAM,KAAK,CAAC;AAEzG,WAAO,OAAO,KAAK,MAAM,KACrB;AAAA,MACE;AAAA,QACE,IAAI,OAAO,QAAQ;AAAA,QACnB,QAAQ,OAAO;AAAA,QACf,MAAM;AAAA,EAAKF,KAAI;AAAA,EAAKE,OAAM;AAAA,MAC5B;AAAA,IACF,IACA,CAAC,EAAE,IAAI,OAAO,QAAQ,GAAG,MAAM;AAAA,EAAKF,KAAI;AAAA,EAAKE,OAAM,GAAG,CAAC;AAAA,EAC7D;AACA,QAAM,QAAQ,WAAW,KAAK,OAAO,MAAM,KAAK,KAAK,KAAK,CAAC;AAC3D,QAAM,QAAQ,UAAU,OAAO,SAAY,KAAK,MAAM,MAAM,CAAC,EAAE;AAC/D,QAAM,UAAU,OAAO,MAAM,KAAK,KAAK,KAAK,EAAE,QAAQ,IAAI;AAC1D,QAAM,WAAW,CAACA,YAChB,GAAG,UAAU,KAAK,KAAK,CAAC,KAAK,OAAO,OAAOA,SAAQ,KAAK,CAAC;AAC3D,MAAI,YAAY,IAAI;AAElB,WAAO,UAAU,SACb,CAAC,EAAE,IAAI,KAAK,KAAK,QAAQ,GAAG,MAAM,KAAK,SAAS,SAAS,QAAQ,KAAK,KAAK,CAAC,CAAC,GAAG,CAAC,IACjF,CAAC,EAAE,IAAI,OAAO,QAAQ,GAAG,MAAM,IAAI,SAAS,SAAS,QAAQ,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC;AAAA,EACpF;AACA,QAAM,SAAS,SAAS,QAAQ,KAAK,KAAK;AAC1C,QAAM,QAAkB;AAAA,IACtB;AAAA,MACE,IAAI,KAAK,MAAM;AAAA,MACf,QAAQ;AAAA,MACR,MAAM;AAAA,EAAK,MAAM,GAAG,SAAS,MAAM,CAAC,GAAG,UAAU,SAAY,KAAK,GAAG;AAAA,IACvE;AAAA,EACF;AACA,MAAI,UAAU,OAAW,OAAM,KAAK,EAAE,IAAI,KAAK,KAAK,QAAQ,GAAG,MAAM,IAAI,CAAC;AAC1E,SAAO;AACT;AAEA,SAAS,aAAa,QAAc,KAA+B;AACjE,SAAO,SAAS,QAAQ,YAAY,EAAE;AAAA,IACpC,CAACD,OAAMA,GAAE,SAAS,oBAAoB,CAACA,GAAE,UAAU,KAAK,OAAO,MAAMA,IAAG,KAAK,CAAC,MAAM;AAAA,EACtF;AACF;AAEA,SAAS,WAAW,QAAgB,KAAoB;AACtD,QAAM,SAAS,OAAO,IAAI,IAAI,CAAC,EAAE,MAAM,MAAM,MAAM,GAAG,IAAI,MAAM,KAAK,UAAU,KAAK,CAAC,EAAE;AACvF,SAAO,IAAI;AAAA,IACT,oBAAoB,GAAG,YAAY,OAAO,IAAI,gDAAgD,OAAO,KAAK,IAAI,CAAC;AAAA,EACjH;AACF;AAKA,SAAS,QACP,QACA,QACA,MACA,OACA,OACM;AACN,QAAM,KAAK,OAAO,MAAM;AACxB,QAAM,MAAM,OAAO,EAAE;AACrB,MAAI,QAAQ;AACV,UAAM,WAAW,QAAQ,sDAAsD;AACjF,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,QAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,MAAI,SAAS,IAAI;AACjB,aAAW,CAAC,GAAG,GAAG,KAAK,KAAK,QAAQ,GAAG;AACrC,UAAM,OAAO,aAAa,QAAQ,GAAG;AACrC,QAAI,SAAS,QAAW;AACtB,YAAM,SAAS,KAAK,MAAM,IAAI,CAAC,EAAE,YAAyB,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK;AACvF,aAAO;AAAA,QACL,QAAQ,QAAQ,QAAQ,YAAY,IAAI,QAAQ,KAAK,QAAQ,KAAK,CAAC;AAAA,QACnE,OAAO;AAAA,MACT;AAAA,IACF;AACA,UAAM,OAAO,MAAM,MAAM,OAAO;AAChC,QAAI,MAAM,KAAK,SAAS,GAAG;AACzB,YAAM,UAAU,SAAS,MAAM,IAAI,OAAO;AAC1C,UAAI,YAAY,UAAa,UAAU,SAAS,KAAK,EAAG,QAAO,EAAE,QAAQ,OAAO,MAAM;AACtF,UAAI,CAAC,SAAS,CAAC,kBAAkB,OAAO,GAAG;AACzC,eAAO;AAAA,UACL,UAAU,EAAE,MAAM,SAAS,WAAW,GAAG,MAAM,KAAK,OAAO,KAAK,GAAG,GAAG,QAAQ,MAAM;AAAA,QACtF;AAAA,MACF;AACA,YAAMD,QAAO,OAAO,OAAO,SAAS,IAAI,KAAK,KAAK,GAAG,KAAK;AAC1D,aAAO;AAAA,QACL,QAAQ,QAAQ,QAAQ,CAAC,EAAE,IAAI,KAAK,OAAO,QAAQ,KAAK,MAAM,KAAK,OAAO,MAAAA,MAAK,CAAC,CAAC;AAAA,QACjF,OAAO;AAAA,MACT;AAAA,IACF;AACA,UAAM,QAAQ,OAAO,IAAI;AACzB,QAAI,OAAO,SAAS,oBAAoB;AACtC,YAAM;AAAA,QACJ;AAAA,QACA,SAAS,KAAK,MAAM,GAAG,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA,MACzC;AAAA,IACF;AACA,aAAS;AAAA,EACX;AACA,SAAO,EAAE,QAAQ,OAAO,MAAM;AAChC;AAGA,SAAS,UAAU,QAAgB,QAAwB;AACzD,QAAM,KAAK,OAAO,MAAM;AACxB,QAAM,MAAM,OAAO,EAAE;AACrB,MAAI,IAAI,YAAY,OAAW,QAAO;AACtC,MAAI,IAAI;AACN,UAAM,WAAW,QAAQ,iEAAiE;AAC5F,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,IAAI,gBAAgB,QAAW;AACjC,UAAM,OAAO,SAAS,IAAI,aAAa,YAAY,EAChD,OAAO,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAC1C,GAAG,EAAE;AACR,WAAO,QAAQ,QAAQ,CAAC,EAAE,IAAI,KAAK,KAAK,QAAQ,GAAG,MAAM,QAAQ,CAAC,CAAC;AAAA,EACrE;AACA,QAAM,UAAU,SAAS,IAAI,SAAS,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,mBAAmB;AAC1F,QAAM,OAAO,uBAAuB,OAAO,eAAe,KAAK,CAAC;AAAA;AAChE,QAAM,aAAa,QAAQ,GAAG,EAAE;AAChC,QAAM,UAAU,eAAe,SAAY,KAAK,GAAG,QAAQ,MAAM,WAAW,GAAG;AAC/E,QAAM,OACJ,eAAe,SACX,EAAE,IAAI,GAAG,QAAQ,GAAG,MAAM,KAAK,IAC/B,YAAY,KACV,EAAE,IAAI,GAAG,QAAQ,QAAQ,GAAG,MAAM;AAAA,EAAK,IAAI,GAAG,IAC9C,EAAE,IAAI,UAAU,GAAG,QAAQ,GAAG,MAAM,KAAK;AACjD,SAAO,QAAQ,QAAQ,CAAC,IAAI,CAAC;AAC/B;AASO,SAAS,oBACd,QACA,QACA,MACe;AACf,MAAI,OAAO,OAAO,MAAM,CAAC,MAAM,QAAW;AACxC,UAAM,WAAW,QAAQ,sDAAsD;AAAA,EACjF;AACA,MAAI,UAAU;AACd,QAAM,UAAoB,CAAC;AAC3B,MAAI,aAAa;AACjB,aAAW,EAAE,MAAM,MAAM,KAAK,OAAO,KAAK;AACxC,UAAM,OAAO,QAAQ,SAAS,QAAQ,MAAM,OAAO,KAAK,KAAK;AAC7D,QAAI,cAAc,KAAM,QAAO;AAC/B,QAAI,CAAC,KAAK,MAAO;AACjB,cAAU,KAAK;AACf,YAAQ,KAAK,IAAI;AACjB,mBAAe,UAAU,KAAK;AAAA,EAChC;AACA,MAAI,WAAY,WAAU,UAAU,SAAS,MAAM;AACnD,SAAO,EAAE,QAAQ,SAAS,QAAQ;AACpC;AAQO,SAAS,SAAS,QAA2B;AAClD,QAAM,KAAK,OAAO,MAAM;AACxB,QAAM,MAAM,OAAO,EAAE;AACrB,QAAM,UAAU,QAAQ,SAAY,WAAW,MAAM,EAAE,GAAG,KAAK,IAAI,IAAI;AACvE,MAAI,YAAY,OAAW,QAAO,CAAC;AACnC,QAAM,YAAY,oBAAI,IAAqB;AAC3C,QAAM,QAAQ,CAAC,SAAwB;AACrC,QAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,QAAQ,KAAK;AAClD,QAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,OAAQ,KAAc,SAAS,SAAU;AAC1F,UAAM,IAAI;AACV,QAAI,EAAE,SAAS,kBAAkB;AAC/B,YAAM,SAAS,MAAM,GAAG,QAAQ;AAChC,YAAM,OAAO,SAAS,GAAG,WAAW;AACpC,YAAM,QAAQ,KAAK,CAAC;AACpB,UACE,OAAO,SAAS,gBAChB,OAAO,MAAM,MAAM,WACnB,OAAO,SAAS,iBAChB;AACA,cAAM,OAAO,MAAM,OAAO;AAC1B,kBAAU,IAAI,OAAO,UAAU,IAAI,IAAI,KAAK,SAAS,KAAK,SAAS,CAAC;AAAA,MACtE;AAAA,IACF;AACA,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,CAAC,GAAG;AAC5C,UAAI,QAAQ,SAAS,QAAQ,cAAc,QAAQ,WAAW,QAAQ,WAAY,OAAM,KAAK;AAAA,IAC/F;AAAA,EACF;AACA,QAAM,KAAK,WAAW,MAAM,EAAE,CAAC;AAC/B,SAAO,CAAC,GAAG,SAAS,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,WAAW,IAAI,EAAE;AACvE;;;ACveA,IAAM,eAAe,CAAC,MAAsB,EAAE,QAAQ,wBAAwB,MAAM;AAGpF,SAAS,SAAS,OAAiB,MAAuB;AACxD,QAAM,KAAK,IAAI,OAAO,YAAY,aAAa,IAAI,CAAC,GAAG;AACvD,SAAO,MAAM,KAAK,CAAC,SAAS,GAAG,KAAK,KAAK,KAAK,CAAC,CAAC;AAClD;AAGO,SAAS,WAAW,SAAiB,QAA+B;AACzE,QAAM,QAAQ,QAAQ,MAAM,OAAO;AACnC,SAAO,OAAO,IAAI;AAAA,IAChB,CAAC,GAAG,MAAM,CAAC,SAAS,OAAO,EAAE,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,MAAM;AAAA,EAC3F;AACF;AAOO,SAAS,gBAAgB,SAAiB,QAAwB;AACvE,QAAM,MAAM,QAAQ,SAAS,MAAM,IAAI,SAAS;AAChD,QAAM,UAAU,WAAW,SAAS,MAAM;AAC1C,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,QAAM,QAAQ,CAAC,KAAK,OAAO,IAAI,gBAAgB,OAAO,IAAI,GAAG;AAC7D,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,YAAY,GAAI,OAAM,KAAK,KAAK,EAAE,OAAO,EAAE;AACjD,UAAM,KAAK,GAAG,EAAE,WAAW,KAAK,IAAI,GAAG,EAAE,IAAI,IAAI,EAAE,OAAO,EAAE;AAAA,EAC9D;AACA,MAAI,OAAO;AACX,MAAI,SAAS,MAAM,CAAC,KAAK,SAAS,IAAI,EAAG,SAAQ;AACjD,QAAM,OAAO,KAAK,MAAM,OAAO,EAAE,GAAG,EAAE;AACtC,QAAM,MAAM,SAAS,UAAa,KAAK,KAAK,MAAM,KAAK,KAAK;AAC5D,SAAO,GAAG,IAAI,GAAG,GAAG,GAAG,MAAM,KAAK,GAAG,CAAC,GAAG,GAAG;AAC9C;;;AHTA,IAAM,MAAM,CAAC,OAAO,OAAa,KAAK,QAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AACtE,IAAM,MAAM,CAAC,SAAuB,KAAK,QAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAEzE,SAAS,KAAK,SAAyB;AACrC,MAAIG,IAAG,IAAI,UAAK,OAAO,EAAE,CAAC;AAC1B,SAAO;AACT;AAGA,SAAS,WAAW,MAAc,MAAuB;AACvD,MAAIA,IAAG,IAAI,KAAK,IAAI,EAAE,CAAC;AACvB,QAAM,CAAC,SAAS,GAAG,IAAI,IAAI,KAAK,MAAM,GAAG;AACzC,QAAM,SAAS,UAAU,SAAU,MAAM;AAAA,IACvC,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO,QAAQ,aAAa;AAAA,EAC9B,CAAC;AACD,SAAO,OAAO,WAAW;AAC3B;AAGA,SAAS,OAAO,MAAsC;AACpD,QAAM,OAAOC,MAAK,MAAM,MAAM;AAC9B,SAAOC,YAAW,IAAI,IAAK,SAASC,cAAa,MAAM,MAAM,CAAC,IAA+B,CAAC;AAChG;AAEA,IAAM,QAAQ,CAAC,MAAc,cAC1B,QAAQ,IAAI,IAAI,KAAK,QAAQ,OAAO,SAAS,IAAI,KAAK,QAAQ;AASjE,eAAe,aACb,WACA,QACA,MACA,UACmB;AACnB,QAAM,WAAqB,CAAC;AAC5B,QAAM,UAAU,OAAO,QAAQ,OAAO,CAAC,QAAQ,CAAC,YAAY,KAAK,IAAI,CAAC;AACtE,MAAI,QAAQ,SAAS,GAAG;AACtB,aAAS;AAAA,MACP,GAAG,QAAQ,KAAK,IAAI,CAAC,IAAI,QAAQ,WAAW,IAAI,OAAO,KAAK,mBAAmB,YAAY,SAAS,QAAQ,KAAK,IAAI,CAAC;AAAA,IACxH;AAAA,EACF;AACA,QAAM,QAAQ,oBAAI,IAAgC;AAClD,aAAW,EAAE,MAAM,UAAU,KAAK,SAAS,SAAS,GAAG;AACrD,SAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,GAAI;AACtC,UAAM,QAAQ,SAAS,IAAI,MAAM,YAAY,SAAY,0BAA0B,IAAI;AACvF,QAAI,UAAU,OAAW;AACzB,UAAM,IAAI,MAAM,QAAQ,IAAI,IAAI,CAAC;AACjC,YAAQ,IAAI,IAAI,IAAI;AAAA,EACtB;AACA,QAAM,MAAM,YAAYF,MAAK,MAAM,cAAc,CAAC;AAClD,MAAI;AACF,kBAAcA,MAAK,KAAK,kBAAkB,GAAG,SAAS;AACtD,UAAMG,YAAW,GAAG;AAAA,EACtB,SAAS,OAAO;AACd,aAAS,KAAM,MAAgB,OAAO;AAAA,EACxC,UAAE;AACA,WAAO,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC5C,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO;AACjC,UAAI,UAAU,OAAW,QAAO,QAAQ,IAAI,IAAI;AAAA,UAC3C,SAAQ,IAAI,IAAI,IAAI;AAAA,IAC3B;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,SAAS,QAAgB,OAAyB;AACzD,QAAM,IAAI,OAAO,MAAM,IAAI;AAC3B,QAAM,IAAI,MAAM,MAAM,IAAI;AAC1B,QAAM,IAAI,MAAM,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,MAAc,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;AAC5F,WAASC,KAAI,EAAE,SAAS,GAAGA,MAAK,GAAGA;AACjC,aAASC,KAAI,EAAE,SAAS,GAAGA,MAAK,GAAGA;AACjC,QAAED,EAAC,EAAGC,EAAC,IAAI,EAAED,EAAC,MAAM,EAAEC,EAAC,IAAI,EAAED,KAAI,CAAC,EAAGC,KAAI,CAAC,IAAK,IAAI,KAAK,IAAI,EAAED,KAAI,CAAC,EAAGC,EAAC,GAAI,EAAED,EAAC,EAAGC,KAAI,CAAC,CAAE;AAC5F,QAAM,QAAkB,CAAC;AACzB,MAAI,IAAI;AACR,MAAI,IAAI;AACR,SAAO,IAAI,EAAE,UAAU,IAAI,EAAE,QAAQ;AACnC,QAAI,IAAI,EAAE,UAAU,IAAI,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG;AACjD;AACA;AAAA,IACF,WAAW,IAAI,EAAE,WAAW,MAAM,EAAE,UAAU,EAAE,CAAC,EAAG,IAAI,CAAC,KAAM,EAAE,IAAI,CAAC,EAAG,CAAC,IAAK;AAC7E,YAAM,KAAKN,IAAG,MAAM,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;AAAA,IACpC,OAAO;AACL,YAAM,KAAKA,IAAG,IAAI,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;AAAA,IAClC;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,OAAO,CAAC,UACZ,OAAO,UAAU,WAAW,IAAI,KAAK,MAAM,KAAK,UAAU,KAAK;AAEjE,eAAsB,IAAI,MAAkB,MAAc,QAAQ,IAAI,GAAoB;AACxF,QAAM,OAAO,KAAK;AAClB,MAAI,CAAC,cAAc,IAAI,GAAG;AACxB,WAAO,KAAK,mBAAmB,IAAI,uBAAuB,aAAa,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACvF;AACA,QAAM,aAAaO,gBAAe,GAAG;AACrC,MAAI,eAAe,KAAM,QAAO,KAAK,0BAA0B,GAAG,0BAA0B;AAC5F,QAAM,OAAOC,SAAQ,UAAU;AAC/B,QAAM,SAAS,eAAe,IAAI;AAElC,QAAM,YAAsB,CAAC;AAC7B,MAAI,WAAW,MAAM,IAAI,MAAM,MAAM;AACnC,UAAM,OAAO,YAAY,CAAC,MAAM,GAAG,QAAQ,KAAK,IAAI;AACpD,QAAI,CAAC,KAAK,WAAW,KAAK,QAAQ;AAChC,aAAO;AAAA,QACL,OAAO,IAAI,oBAAoB,MAAM,yCAAyC,IAAI;AAAA,MACpF;AAAA,IACF;AACA,QAAI,CAAC,WAAW,MAAM,IAAI,EAAG,QAAO,KAAK,GAAG,IAAI,SAAS;AACzD,cAAU,KAAK,MAAM;AAAA,EACvB;AACA,QAAM,SAAS,MAAM,WAAW,MAAM,IAAI;AAE1C,QAAM,SAASL,cAAa,YAAY,MAAM;AAC9C,MAAI;AACJ,MAAI;AACF,UAAM,UAAU,oBAAoB,QAAQ,QAAQ,EAAE,OAAO,KAAK,MAAM,CAAC;AACzE,QAAI,cAAc,SAAS;AACzB,YAAM,EAAE,MAAM,SAAS,OAAO,IAAI,QAAQ;AAC1C,aAAO;AAAA,QACL,GAAG,IAAI,OAAO,KAAK,OAAO,CAAC,iCAAiC,IAAI,sBAAsB,KAAK,MAAM,CAAC;AAAA,MAEpG;AAAA,IACF;AACA,aAAS;AAAA,EACX,SAAS,OAAO;AACd,WAAO,KAAM,MAAgB,OAAO;AAAA,EACtC;AACA,QAAM,cAAcF,MAAK,MAAM,cAAc;AAC7C,QAAM,UAAUC,YAAW,WAAW,IAAIC,cAAa,aAAa,MAAM,IAAI;AAC9E,QAAM,cAAc,gBAAgB,SAAS,MAAM;AAEnD,MAAI,KAAK,QAAQ;AACf,QAAIH,IAAG,KAAK,cAAc,IAAI,gCAAgC,CAAC;AAC/D,QAAI;AACJ;AAAA,MACE,OAAO,QAAQ,SAAS,IACpB,YAAY,YAAY,OAAO,SAAS,QAAQ,KAAK,IAAI,CAAC,KAC1D;AAAA,IACN;AACA,QAAI;AACJ,QAAI,mBAAmB;AACvB,UAAM,OAAO,SAAS,QAAQ,OAAO,MAAM;AAC3C,eAAW,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,eAAe,EAAG,KAAI,KAAK,IAAI,EAAE;AAC9E,QAAI;AACJ,QAAI,eAAe;AACnB,UAAM,QAAQ,YACX,MAAM,QAAQ,MAAM,EACpB,MAAM,OAAO,EACb,OAAO,CAAC,MAAM,MAAM,EAAE;AACzB,eAAW,QAAQ,MAAM,SAAS,IAAI,QAAQ,CAAC,iCAAiC;AAC9E,UAAI,KAAK,IAAI,EAAE;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,OAAO,QAAQ,OAAO,CAAC,QAAQ,CAAC,YAAY,KAAK,IAAI,CAAC;AACtE,MAAI,QAAQ,SAAS,KAAK,KAAK,SAAS;AACtC,UAAM,OAAO,YAAY,SAAS,QAAQ,KAAK,IAAI;AACnD,QAAI,CAAC,WAAW,MAAM,IAAI,EAAG,QAAO,KAAK,GAAG,IAAI,SAAS;AACzD,cAAU,KAAK,GAAG,OAAO;AAAA,EAC3B;AAEA,QAAM,WAAW,OAAO,IAAI;AAC5B,QAAM,WAAW,MAAM,aAAa,OAAO,QAAQ,QAAQ,MAAM,QAAQ;AACzE,MAAI,SAAS,SAAS,GAAG;AACvB,WAAO;AAAA,MACL,OAAO,IAAI;AAAA,IAAyF,SAAS,KAAK,MAAM,CAAC;AAAA,IAC3H;AAAA,EACF;AAEA,QAAM,UAAoB,CAAC;AAC3B,MAAI,UAAU,SAAS,EAAG,SAAQ,KAAK,kCAAkC,UAAU,KAAK,IAAI,CAAC,GAAG;AAChG,MAAI,OAAO,WAAW,QAAQ;AAC5B,kBAAc,YAAY,OAAO,MAAM;AACvC,YAAQ,KAAK,qBAAqB,OAAO,QAAQ,KAAK,IAAI,CAAC,GAAG;AAAA,EAChE;AACA,MAAI,gBAAgB,SAAS;AAC3B,kBAAc,aAAa,WAAW;AACtC,YAAQ;AAAA,MACN,iBAAiB,WAAW,SAAS,MAAM,EACxC,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI,CAAC;AAAA,IACf;AAAA,EACF;AAEA,MAAIA,IAAG,MAAM,UAAK,IAAI,KAAK,OAAO,OAAO,EAAE,CAAC;AAC5C,MAAI,QAAQ,SAAS,IAAI,aAAa,QAAQ,KAAK,IAAI,CAAC,KAAK,kCAAkC;AAC/F,QAAM,QAAQ,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC7E,MAAI,MAAM,SAAS,KAAK,OAAO,KAAK,SAAS,GAAG;AAC9C,QAAI;AACJ,QAAI,OAAO;AACX,eAAW,KAAK,MAAO,KAAI,WAAW,EAAE,IAAI,UAAU;AACtD,eAAW,QAAQ,OAAO,KAAM,KAAI,OAAO,IAAI,EAAE;AAAA,EACnD;AACA,SAAO;AACT;AAEO,IAAM,aAAaS,eAAc;AAAA,EACtC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa,+BAA+B,aAAa,EAAE,KAAK,IAAI,CAAC;AAAA,EACvE;AAAA,EACA,MAAM;AAAA,IACJ,QAAQ,EAAE,MAAM,cAAc,UAAU,MAAM,aAAa,aAAa,EAAE,KAAK,IAAI,EAAE;AAAA,IACrF,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA,WAAW;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,YAAQ,WAAW,MAAM,IAAI;AAAA,MAC3B,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK,SAAS;AAAA,IACxB,CAAC;AAAA,EACH;AACF,CAAC;;;AI5QD,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,iBAAAC,sBAAqB;AAE9B,SAAS,gBAAAC,eAAc,gBAAsC;AAC7D,SAAS,WAAW,+BAA+B;;;ACJnD,OAAOC,SAAQ;AAGf,SAAS,mBAAmB,cAAAC,aAAY,yBAAyB;AAYjE,IAAM,cAAsD;AAAA,EAC1D,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,UAAU;AAAA,EACV,MAAM;AACR;AAEA,IAAM,cAA0D;AAAA,EAC9D,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,UAAU;AAAA,EACV,MAAM;AACR;AAEA,IAAM,SAAS,EAAE,IAAID,IAAG,OAAO,MAAMA,IAAG,QAAQ,MAAMA,IAAG,IAAI;AAG7D,IAAM,aAAa;AAEnB,IAAM,aACJ;AACF,IAAM,cAAc;AACpB,IAAM,uBAAuB;AAE7B,SAAS,UAAU,MAAmB,OAAqB;AACzD,MAAI,MAAM,UAAU,kBAAmB,MAAK,IAAI,KAAK;AACvD;AAEA,SAAS,kBAAkB,OAAgB,KAAa,MAAmB,MAAuB;AAChG,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,WAAW,KAAK,GAAG,EAAG,WAAU,MAAM,KAAK;AAC/C,QAAI,MAAM,SAAS,KAAK,EAAG,YAAW,KAAK,kBAAkB,OAAO,EAAE,MAAM,MAAM,CAAC,EAAG,WAAU,MAAM,CAAC;AACvG;AAAA,EACF;AACA,MAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,KAAK,IAAI,KAAK,EAAG;AACpE,OAAK,IAAI,KAAK;AACd,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,EAAG,mBAAkB,GAAG,GAAG,MAAM,IAAI;AAChF;AAGA,SAAS,UAAU,QAAkC,KAAkC;AACrF,QAAM,QAAQ,oBAAI,IAAY;AAC9B,oBAAkB,QAAQ,IAAI,OAAO,oBAAI,QAAQ,CAAC;AAClD,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC/C,QAAI,UAAU,OAAW;AACzB,QAAI,WAAW,KAAK,IAAI,EAAG,WAAU,OAAO,KAAK;AACjD,QAAI,MAAM,SAAS,KAAK,EAAG,YAAW,KAAK,kBAAkB,OAAO,EAAE,MAAM,MAAM,CAAC,EAAG,WAAU,OAAO,CAAC;AAAA,EAC1G;AACA,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACtD;AAGA,SAAS,MAAM,QAAgB,SAAoC;AACjE,MAAIE,QAAO,OAAO,QAAQ,aAAa,CAAC,UAAU;AAChD,UAAM,WAAW,qBAAqB,KAAK,KAAK,IAAI,CAAC,KAAK;AAC1D,WAAOD,YAAW,MAAM,MAAM,GAAG,MAAM,SAAS,SAAS,MAAM,CAAC,IAAI;AAAA,EACtE,CAAC;AACD,aAAW,UAAU,QAAS,CAAAC,QAAOA,MAAK,MAAM,MAAM,EAAE,KAAK,KAAK;AAClE,SAAOA,MAAK,QAAQ,sBAAsB,GAAG,EAAE,KAAK;AACtD;AAMO,SAAS,mBAAmB,QAAyB,SAAsC;AAChG,QAAM,UAAU,UAAU,QAAQ,QAAQ,QAAQ,OAAO,CAAC,CAAC;AAC3D,QAAM,SAAS,OAAO,OAAO,IAAI,CAAC,WAAW;AAAA,IAC3C,MAAM,MAAM;AAAA,IACZ,QAAQ,MAAM;AAAA,IACd,QAAQ,MAAM,MAAM,QAAQ,OAAO;AAAA,EACrC,EAAE;AACF,MAAI,QAAQ,MAAM;AAChB,WAAO,KAAK;AAAA,MACV;AAAA,QACE,QAAQ,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,YAAY,EAAE,MAAM,GAAG,QAAQ,EAAE,OAAO,EAAE;AAAA,MAC/F;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,GAAG,CAAC;AAC7D,QAAM,QAAQ,OAAO,IAAI,CAAC,MAAM;AAC9B,UAAM,SAAS,YAAY,EAAE,MAAM;AACnC,WAAO,GAAG,OAAO,MAAM,EAAE,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,OAAO,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ;AAAA,EAC7F,CAAC;AACD,QAAM,QAAQ,CAAC,MACb,OAAO,OAAO,CAAC,MAAM,YAAY,EAAE,MAAM,MAAM,CAAC,EAAE;AACpD,SAAO,CAAC,GAAG,OAAO,IAAI,GAAG,MAAM,MAAM,CAAC,UAAU,MAAM,MAAM,CAAC,UAAU,MAAM,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI;AACpG;;;AD/FA,SAAS,UAAUC,OAAkC;AACnD,MAAIA,UAAS,UAAaA,MAAK,KAAK,MAAM,GAAI,QAAO;AACrD,QAAM,KAAK,OAAOA,KAAI;AACtB,MAAI,CAAC,OAAO,UAAU,EAAE,KAAK,KAAK,GAAG;AACnC,UAAM,IAAI,MAAM,0DAA0DA,KAAI,GAAG;AAAA,EACnF;AACA,SAAO;AACT;AAMA,SAAS,aAAa,aAAkD;AACtE,QAAM,OAAO,kBAAkB,WAAW;AAC1C,SAAOC,YAAW,IAAI,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;AACxD;AAEO,IAAM,gBAAgBC,eAAc;AAAA,EACzC,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aACE;AAAA,EACJ;AAAA,EACA,MAAM;AAAA,IACJ,MAAM,EAAE,MAAM,WAAW,aAAa,yCAAyC,SAAS,MAAM;AAAA,IAC9F,SAAS;AAAA,MACP,MAAM;AAAA,MACN,aAAa,gDAAgD,uBAAuB;AAAA,IACtF;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,YAAY,UAAU,KAAK,OAAO;AACxC,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,YAAY;AAAA,IAC7B,SAAS,OAAO;AACd,eAAS,EAAE,MAAM;AAAA,IACnB;AACA,UAAM,SACJ,WAAW;AAAA;AAAA,MAEP,EAAE,QAAQ,CAAC,EAAE,MAAM,UAAU,QAAQ,QAAQ,QAAQ,UAAU,OAAO,KAAK,EAAE,CAAC,EAAE;AAAA,QAChF,MAAM,SAAS,OAAO,QAAQ;AAAA,MAC5B,GAAI,OAAO,aAAa,UAAa,EAAE,UAAU,OAAO,SAAS;AAAA;AAAA,MAEjE,QAAQC,cAAa,EAAE,OAAO,UAAU,QAAQ,MAAM,CAAC;AAAA,MACvD;AAAA,MACA,GAAG,aAAa,OAAO,WAAW;AAAA,IACpC,CAAC;AACP,UAAMC,QAAO,mBAAmB,QAAQ;AAAA,MACtC,MAAM,KAAK;AAAA,MACX,QAAQ,WAAW,SAAS,SAAY,OAAO;AAAA,MAC/C,KAAK,QAAQ;AAAA,IACf,CAAC;AACD,UAAM,OAAO,OAAO,OAAO,KAAK,CAAC,UAAU,MAAM,WAAW,MAAM;AAElE,YAAQ,OAAO,MAAM,GAAGA,KAAI;AAAA,GAAM,MAAM,QAAQ,KAAK,OAAO,IAAI,CAAC,CAAC;AAAA,EACpE;AACF,CAAC;;;AEpED,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,cAAAC,mBAAkB;AAGpB,IAAM,cAAcC,eAAc;AAAA,EACvC,MAAM,EAAE,MAAM,QAAQ,aAAa,wCAAwC;AAAA,EAC3E,MAAM,MAAM;AACV,UAAM,UAAU,QAAQ,CAAC,UAAU,KAAK,CAAC;AAAA,EAC3C;AACF,CAAC;AAEM,IAAM,iBAAiBA,eAAc;AAAA,EAC1C,MAAM,EAAE,MAAM,YAAY,aAAa,qDAAqD;AAAA,EAC5F,MAAM,MAAM;AACV,UAAM,EAAE,OAAO,IAAI,MAAMC,YAAW;AACpC,UAAM,UAAU,QAAQ;AAAA,MACtB;AAAA,MAAY;AAAA,MAAiB;AAAA,MAC7B;AAAA,MAAc;AAAA,MAAQ;AAAA,MAAa,OAAO;AAAA,MAAU;AAAA,MAAiB;AAAA,IACvE,CAAC;AAAA,EACH;AACF,CAAC;AAEM,IAAM,oBAAoBD,eAAc;AAAA,EAC7C,MAAM,EAAE,MAAM,eAAe,aAAa,4DAA4D;AAAA,EACtG,MAAM;AAAA,IACJ,oBAAoB;AAAA,MAClB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,EAAE,OAAO,IAAI,MAAMC,YAAW;AACpC,UAAM,OAAO,CAAC,CAAC,QAAQ,IAAI;AAC3B,UAAM,kBAAkB,KAAK,kBAAkB;AAE/C,QAAI,mBAAmB,CAAC,MAAM;AAE5B,YAAM,cAAc;AACpB,YAAM,MAAM,QAAQ,IAAI;AACxB,YAAM,UAAU,UAAU;AAAA,QACxB;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAM,GAAG,GAAG,IAAI,GAAG;AAAA,QAAI;AAAA,QAAM;AAAA,QAC5C;AAAA,QAAa;AAAA,QAAM;AAAA,QACnB,8DAA8D,OAAO,QAAQ;AAAA,MAC/E,CAAC;AAAA,IACH,OAAO;AACL,YAAM,SAAS;AAAA,QACb;AAAA,QAAY;AAAA,QAAiB;AAAA,QAC7B;AAAA,QAAc;AAAA,QAAQ;AAAA,QAAa,OAAO;AAAA,QAAU;AAAA,QAAU;AAAA,MAChE;AACA,UAAI,gBAAiB,QAAO,KAAK,oBAAoB;AACrD,YAAM,UAAU,QAAQ,MAAM;AAAA,IAChC;AAAA,EACF;AACF,CAAC;AAEM,IAAM,uBAAuBD,eAAc;AAAA,EAChD,MAAM,EAAE,MAAM,kBAAkB,aAAa,6BAA6B;AAAA,EAC1E,MAAM;AAAA,IACJ,SAAS,EAAE,MAAM,UAAU,aAAa,mEAAmE;AAAA,EAC7G;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,QAAQ;AAAA,MACZ;AAAA,MAAU;AAAA,MACV;AAAA,MAAa;AAAA,IACf;AACA,QAAI,KAAK,SAAS;AAEhB,YAAM,KAAK,mBAAmB,OAAO,KAAK,OAAO,CAAC,UAAU;AAAA,IAC9D;AACA,UAAM,UAAU,QAAQ,KAAK;AAAA,EAC/B;AACF,CAAC;AAEM,IAAM,yBAAyBA,eAAc;AAAA,EAClD,MAAM,EAAE,MAAM,oBAAoB,aAAa,oDAAoD;AAAA,EACnG,MAAM,MAAM;AACV,UAAM,EAAE,OAAO,IAAI,MAAMC,YAAW;AACpC,UAAM,OAAO,OAAO,aAAa,WAAW,MAAO;AACnD,UAAM,UAAU,QAAQ,CAAC,QAAQ,SAAS,GAAG;AAAA,MAC3C,KAAK;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,iBAAiB,OAAO;AAAA,QACxB,sBAAsB,OAAO,IAAI;AAAA,MACnC;AAAA,IACF,CAAC;AAAA,EACH;AACF,CAAC;AAEM,IAAM,iBAAiBD,eAAc;AAAA,EAC1C,MAAM,EAAE,MAAM,YAAY,aAAa,yDAAyD;AAAA,EAChG,MAAM,MAAM;AACV,UAAM,QAAiD;AAAA,MACrD,EAAE,MAAM,QAAQ,MAAM,CAAC,UAAU,KAAK,EAAE;AAAA,MACxC,EAAE,MAAM,aAAa,MAAM,CAAC,UAAU,OAAO,aAAa,kBAAkB,EAAE;AAAA,IAChF;AAEA,eAAW,QAAQ,OAAO;AACxB,YAAM,EAAE,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI;AACtC,YAAM,OAAO,MAAM;AACnB,UAAI,SAAS,GAAG;AAEd,gBAAQ,MAAM,UAAK,KAAK,IAAI,SAAS;AACrC,gBAAQ,KAAK,IAAI;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,EAAE,OAAO,IAAI,MAAMC,YAAW;AACpC,UAAM,UAAU,QAAQ;AAAA,MACtB;AAAA,MAAY;AAAA,MAAiB;AAAA,MAC7B;AAAA,MAAc;AAAA,MAAQ;AAAA,MAAa,OAAO;AAAA,MAAU;AAAA,MAAiB;AAAA,IACvE,CAAC;AACD,UAAM,UAAU,QAAQ;AAAA,MACtB;AAAA,MAAY;AAAA,MAAiB;AAAA,MAC7B;AAAA,MAAc;AAAA,MAAQ;AAAA,MAAa,OAAO;AAAA,MAAU;AAAA,MAAU;AAAA,IAChE,CAAC;AACD,UAAM,UAAU,QAAQ,CAAC,QAAQ,SAAS,GAAG;AAAA,MAC3C,KAAK,EAAE,GAAG,QAAQ,KAAK,iBAAiB,OAAO,SAAS;AAAA,IAC1D,CAAC;AAAA,EACH;AACF,CAAC;;;ArBnGD,IAAM,OAAOC,gBAAc;AAAA,EACzB,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,SAAS,cAAc;AAAA,IACvB,aAAa;AAAA,EACf;AAAA,EACA,aAAa;AAAA,IACX,KAAK;AAAA,IACL,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,YAAY;AAAA,EACd;AACF,CAAC;AAGD,IAAM,CAAC,MAAM,GAAG,IAAI,IAAI,QAAQ,KAAK,MAAM,CAAC;AAC5C,IAAI,KAAK,WAAW,MAAM,SAAS,eAAe,SAAS,OAAO;AAChE,UAAQ,OAAO,MAAM,GAAG,cAAc,CAAC;AAAA,CAAI;AAC7C,OAAO;AACL,UAAQ,IAAI;AACd;","names":["defineCommand","resolve","defineCommand","dirname","child","resolve","resolve","err","existsSync","resolve","dirname","resolve","existsSync","existsSync","dirname","join","err","resolve","text","resolve","defineCommand","shutdown","defineCommand","defineCommand","defineCommand","runSeed","defineCommand","runSeed","defineCommand","createApp","join","defineCommand","join","createApp","defineCommand","pc","defineCommand","pc","err","existsSync","readFileSync","dirname","join","defineCommand","pc","findConfigFile","loadConfig","existsSync","createRequire","dirname","join","resolve","out","text","p","indent","pc","join","existsSync","readFileSync","loadConfig","i","j","findConfigFile","dirname","defineCommand","existsSync","defineCommand","createLogger","pc","displayUrl","text","flag","existsSync","defineCommand","createLogger","text","defineCommand","loadConfig","defineCommand","loadConfig","defineCommand"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nymbal",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "nymbal — developer CLI for the Nymbal platform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,13 +33,14 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@clack/prompts": "^0.7.0",
|
|
35
35
|
"citty": "^0.1.6",
|
|
36
|
+
"magicast": "^0.5.5",
|
|
36
37
|
"picocolors": "^1.1.1",
|
|
37
|
-
"@nymbalhq/admin": "
|
|
38
|
-
"@nymbalhq/config": "
|
|
39
|
-
"@nymbalhq/http": "
|
|
40
|
-
"@nymbalhq/importers": "0.
|
|
41
|
-
"@nymbalhq/platform": "
|
|
42
|
-
"@nymbalhq/types": "
|
|
38
|
+
"@nymbalhq/admin": "1.1.0",
|
|
39
|
+
"@nymbalhq/config": "1.1.0",
|
|
40
|
+
"@nymbalhq/http": "1.1.0",
|
|
41
|
+
"@nymbalhq/importers": "0.3.0",
|
|
42
|
+
"@nymbalhq/platform": "1.1.0",
|
|
43
|
+
"@nymbalhq/types": "1.1.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"tsup": "^8.3.5",
|