seedcord 0.18.2 → 0.19.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/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["createNodeRequire","select","clackSelect","confirm","clackConfirm","confirm","select","Chip","MS_PER_SECOND","process","viteConfig","POLL_INTERVAL_MS","createServer"],"sources":["../src/core/BaseCommand.ts","../src/utils/resolveDefaultExport.ts","../src/core/config/ConfigLoader.ts","../src/core/config/ConfigLocator.ts","../src/core/modules/RuntimeModuleLoader.ts","../src/commands/build/builder/BootstrapWriter.ts","../src/commands/build/builder/TypeScriptProjectBuilder.ts","../src/commands/build/BuildRunner.ts","../src/commands/build/BuildCommand.ts","../src/commands/codegen/AugmentationBuilder.ts","../src/commands/codegen/renderAugmentation.ts","../src/commands/codegen/CodegenRunner.ts","../src/commands/codegen/CodegenCommand.ts","../src/core/interactive.ts","../src/commands/commands/classify.ts","../src/commands/commands/CleanRunner.ts","../src/core/format.ts","../src/core/prompts/requireValue.ts","../src/core/prompts/pickFromList.ts","../src/core/prompts/index.ts","../src/commands/commands/confirm.ts","../src/commands/commands/cleanPresenters.ts","../src/commands/commands/executeClean.ts","../src/commands/commands/flagClean.ts","../src/commands/commands/wizard.ts","../src/commands/commands/CommandsCommand.ts","../src/ui/components/primitives/Rule.tsx","../src/ui/filterCursor.ts","../src/ui/hooks/useDevState.ts","../src/ui/stores/LogStore.ts","../src/ui/hooks/useLogs.ts","../src/ui/hooks/useMeasuredBox.ts","../src/ui/hooks/useRailWidth.ts","../src/ui/hooks/useScroll.ts","../src/ui/palette.ts","../src/ui/stores/devPhase.ts","../src/ui/hooks/useUptime.ts","../src/ui/channelColor.ts","../src/ui/components/primitives/FilterChips.tsx","../src/ui/hotkeys.ts","../src/ui/components/primitives/LogHeader.tsx","../src/ui/components/primitives/NotificationStack.tsx","../src/ui/format.ts","../src/ui/logRows.ts","../src/ui/components/primitives/ScrollableLogView.tsx","../src/ui/components/Banner.tsx","../src/ui/components/primitives/BlinkDot.tsx","../src/ui/components/StatusBadge.tsx","../src/ui/components/primitives/Hotkeys.tsx","../src/ui/components/primitives/Sidebar.tsx","../src/ui/components/primitives/StatusLine.tsx","../src/ui/layout/DevLayout.tsx","../src/ui/components/CommandRefreshPrompt.tsx","../src/ui/components/ErrorDisplay.tsx","../src/ui/components/QuitConfirmCard.tsx","../src/ui/components/RestartRequiredCard.tsx","../src/ui/components/TunnelOpeningCard.tsx","../src/ui/notices.tsx","../src/ui/profile.ts","../src/ui/tier.ts","../src/ui/DevApp.tsx","../src/ui/stores/DevStore.ts","../src/commands/dev/TscRunner.ts","../src/commands/dev/DevSession.ts","../src/commands/dev/runtime/HmrPlugin.ts","../src/commands/dev/runtime/vite.config.ts","../src/commands/dev/runtime/ViteDevRuntime.ts","../src/commands/dev/tunnel/cloudflared.ts","../src/commands/dev/tunnel/probe.ts","../src/commands/dev/tunnel/CloudflaredTunnel.ts","../src/commands/dev/tunnel/InteractionsEndpoint.ts","../src/commands/dev/tunnel/TunnelCoordinator.ts","../src/commands/dev/tunnel/createTunnelCoordinator.ts","../src/commands/dev/tunnel/TunnelRouter.ts","../src/commands/dev/DevRunner.ts","../src/commands/dev/DevCommand.ts","../src/cli.ts"],"sourcesContent":["import { Logger } from '@seedcord/logger';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport abstract class BaseCommand {\n protected readonly logger: Logger;\n\n constructor(\n public readonly name: string,\n public readonly description: string,\n label: string\n ) {\n this.logger = new Logger(label, { channel: 'cli' });\n }\n\n public abstract register(program: Command): void;\n}\n","export function resolveDefaultExport<TValue>(moduleExport: TValue): unknown {\n let current: unknown = moduleExport;\n const visited = new Set<unknown>();\n\n while (isObjectWithDefault(current) && !visited.has(current)) {\n visited.add(current);\n current = current.default;\n }\n\n return current;\n}\n\nfunction isObjectWithDefault(value: unknown): value is { default: unknown } {\n return Boolean(value && typeof value === 'object' && 'default' in value);\n}\n","import { dirname, isAbsolute, relative, resolve } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { resolveDefaultExport } from '#utils/resolveDefaultExport';\n\nimport type { ModuleLoader } from '#core/modules/ModuleLoader';\nimport type {\n ResolvedSeedcordBuildConfig,\n ResolvedSeedcordDevConfig,\n ResolvedTunnel,\n ResolvedTypecheck,\n SeedcordBuildConfig,\n SeedcordDevConfig,\n SeedcordHmrConfig\n} from './schema';\nimport type { ILogger } from '@seedcord/types';\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n return value === undefined || typeof value === 'string';\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\nfunction invalidField(field: string, expected: string): SeedcordError {\n return new SeedcordError(SeedcordErrorCode.CliConfigInvalidField, [field, expected]);\n}\n\nfunction validateBuild(value: unknown): void {\n if (value === undefined) return;\n if (!isPlainObject(value)) throw invalidField('build', 'an object');\n if (!isOptionalString(value.outDir)) throw invalidField('build.outDir', 'a string');\n if (!isOptionalString(value.tsconfig)) throw invalidField('build.tsconfig', 'a string');\n if (!isOptionalString(value.bootstrap)) throw invalidField('build.bootstrap', 'a string');\n}\n\nfunction validateTypecheck(value: unknown): void {\n if (value === undefined || typeof value === 'boolean') return;\n if (!isPlainObject(value)) throw invalidField('hmr.typecheck', 'a boolean or an object');\n if (!isOptionalString(value.tsconfig)) throw invalidField('hmr.typecheck.tsconfig', 'a string');\n}\n\nfunction validateHmr(value: unknown): void {\n if (value === undefined) return;\n if (!isPlainObject(value)) throw invalidField('hmr', 'an object');\n if (value.restart !== undefined && !isStringArray(value.restart)) {\n throw invalidField('hmr.restart', 'an array of strings');\n }\n if (value.rollback !== undefined && typeof value.rollback !== 'boolean') {\n throw invalidField('hmr.rollback', 'a boolean');\n }\n validateTypecheck(value.typecheck);\n}\n\nfunction validateTunnel(value: unknown): void {\n if (value === undefined || typeof value === 'boolean') return;\n // discord only accepts an https interactions endpoint\n if (typeof value !== 'string' || URL.parse(value)?.protocol !== 'https:') {\n throw invalidField('tunnel', 'a boolean or an https URL');\n }\n}\n\nfunction resolveTunnel(value: boolean | string | undefined): ResolvedTunnel {\n if (value === false) return { mode: 'off' };\n if (typeof value === 'string') return { mode: 'url', url: value };\n return { mode: 'quick' };\n}\n\nfunction resolveTypecheck(value: SeedcordHmrConfig['typecheck'], root: string): ResolvedTypecheck {\n if (value === undefined || value === false) return { enabled: false };\n if (value === true || value.tsconfig === undefined) return { enabled: true };\n\n return { enabled: true, tsconfig: resolve(root, value.tsconfig) };\n}\n\nfunction validateConfig(raw: unknown): asserts raw is SeedcordDevConfig {\n if (!isPlainObject(raw)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidExport);\n if (typeof raw.instance !== 'string' || raw.instance.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigMissingInstance);\n }\n if (typeof raw.entry !== 'string' || raw.entry.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigMissingEntry);\n }\n if (!isOptionalString(raw.root)) throw invalidField('root', 'a string');\n if (raw.idleAnimation !== undefined && typeof raw.idleAnimation !== 'boolean') {\n throw invalidField('idleAnimation', 'a boolean');\n }\n validateTunnel(raw.tunnel);\n validateBuild(raw.build);\n validateHmr(raw.hmr);\n}\n\nexport class ConfigLoader {\n constructor(\n private readonly modules: ModuleLoader,\n private readonly logger: ILogger\n ) {}\n\n public async load(configPath: string): Promise<ResolvedSeedcordDevConfig> {\n const loadedModule = await this.modules.importModule(configPath);\n const config: unknown = await Promise.resolve(resolveDefaultExport(loadedModule));\n validateConfig(config);\n\n const configDir = dirname(configPath);\n const root = resolve(configDir, config.root ?? '.');\n const instance = this.resolveWithinRoot(root, config.instance);\n const entry = this.resolveWithinRoot(root, config.entry);\n this.assertEntryWithinRoot(root, entry);\n const build = this.resolveBuildOptions(configDir, config.build);\n const typecheck = resolveTypecheck(config.hmr?.typecheck, root);\n\n this.logger.debug(`Loaded configuration from ${configPath}`);\n this.logger.trace(`Resolved root: ${root}`);\n this.logger.trace(`Resolved instance: ${instance}`);\n this.logger.trace(`Resolved entry: ${entry}`);\n this.logger.trace(`Resolved build outDir: ${build.outDir}`);\n if (build.tsconfig) this.logger.trace(`Resolved build tsconfig: ${build.tsconfig}`);\n if (typecheck.enabled) this.logger.trace(`Typecheck tsconfig: ${typecheck.tsconfig ?? 'nearest'}`);\n this.logger.trace(`Resolved bootstrap: ${build.bootstrap}`);\n\n return {\n instance,\n root,\n configFile: configPath,\n entry,\n build,\n typecheck,\n idleAnimation: config.idleAnimation ?? true,\n tunnel: resolveTunnel(config.tunnel),\n hmr: config.hmr\n } satisfies ResolvedSeedcordDevConfig;\n }\n\n private resolveWithinRoot(root: string, target: string): string {\n if (isAbsolute(target)) return target;\n return resolve(root, target);\n }\n\n private assertEntryWithinRoot(root: string, entry: string): void {\n const relativePath = relative(root, entry);\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigEntryOutsideRoot, [entry, root]);\n }\n }\n\n private resolveBuildOptions(\n configDir: string,\n build: SeedcordBuildConfig | undefined\n ): ResolvedSeedcordBuildConfig {\n const outDir = resolve(configDir, build?.outDir ?? 'dist');\n const bootstrapValue = build?.bootstrap;\n const bootstrap = bootstrapValue ? this.resolveBootstrap(outDir, bootstrapValue) : resolve(outDir, 'index.mjs');\n const tsconfig = build?.tsconfig ? resolve(configDir, build.tsconfig) : undefined;\n\n const resolvedBuild: ResolvedSeedcordBuildConfig = tsconfig\n ? { outDir, bootstrap, tsconfig }\n : { outDir, bootstrap };\n\n return resolvedBuild;\n }\n\n private resolveBootstrap(outDir: string, bootstrap: string): string {\n if (isAbsolute(bootstrap)) return bootstrap;\n return resolve(outDir, bootstrap);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { SEEDCORD_CONFIG_FILENAMES } from './schema';\n\nimport type { ILogger } from '@seedcord/types';\n\nexport class ConfigLocator {\n constructor(private readonly logger: ILogger) {}\n\n public locate(baseDir = process.cwd()): string {\n const normalizedBase = resolve(baseDir);\n for (const candidate of SEEDCORD_CONFIG_FILENAMES) {\n const fullPath = join(normalizedBase, candidate);\n if (existsSync(fullPath)) {\n this.logger.trace(`Found config at ${fullPath}`);\n return fullPath;\n }\n }\n\n throw new SeedcordError(SeedcordErrorCode.CliConfigNotFound, [normalizedBase, SEEDCORD_CONFIG_FILENAMES]);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, extname, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { createJiti } from 'jiti';\nimport { tsImport } from 'tsx/esm/api';\n\nimport type { ModuleLoader } from './ModuleLoader';\n\ntype TsconfigOption = string | false;\n\ninterface RuntimeModuleLoaderOptions {\n tsconfig?: TsconfigOption;\n forceTsx?: boolean;\n}\n\nconst TS_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);\n\nexport class RuntimeModuleLoader implements ModuleLoader {\n private readonly jiti = createJiti(import.meta.url, {\n cache: false,\n interopDefault: true,\n extensions: ['.ts', '.tsx', '.mts', '.cts', '.js', '.mjs', '.cjs']\n });\n\n constructor(private readonly options: RuntimeModuleLoaderOptions = {}) {}\n\n public async importModule<TModule = unknown>(entryPath: string): Promise<TModule> {\n const normalized = resolve(entryPath);\n if (!existsSync(normalized)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [normalized]);\n }\n\n if (this.shouldUseTsx(normalized)) {\n return this.importWithTsx<TModule>(normalized);\n }\n\n return this.importWithNode<TModule>(normalized);\n }\n\n private shouldUseTsx(filePath: string): boolean {\n if (this.options.forceTsx) return true;\n return TS_EXTENSIONS.has(extname(filePath).toLowerCase());\n }\n\n private async importWithTsx<TModule = unknown>(entryPath: string): Promise<TModule> {\n const specifier = pathToFileURL(entryPath).href;\n const tsconfig = this.resolveTsconfig(entryPath);\n\n try {\n return (await tsImport(specifier, { parentURL: import.meta.url, tsconfig })) as TModule;\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown tsx error';\n throw new SeedcordError(SeedcordErrorCode.CliTsxImportFailed, [entryPath, reason]);\n }\n }\n\n private async importWithNode<TModule = unknown>(entryPath: string): Promise<TModule> {\n const specifier = pathToFileURL(entryPath).href;\n\n try {\n return (await import(specifier)) as TModule;\n } catch (nativeError: unknown) {\n try {\n return await this.jiti.import(entryPath);\n } catch (fallbackError: unknown) {\n const nativeReason = Error.isError(nativeError) ? nativeError.message : 'Unknown ESM import error';\n const fallbackReason = Error.isError(fallbackError) ? fallbackError.message : 'Unknown jiti error';\n throw new SeedcordError(SeedcordErrorCode.CliImportFailed, [entryPath, nativeReason, fallbackReason]);\n }\n }\n }\n\n private resolveTsconfig(entryPath: string): TsconfigOption {\n if (this.options.tsconfig !== undefined) {\n return this.options.tsconfig;\n }\n\n return this.findNearestTsconfig(dirname(entryPath)) ?? false;\n }\n\n private findNearestTsconfig(startDir: string): string | undefined {\n const candidate = resolve(startDir, 'tsconfig.json');\n if (existsSync(candidate)) return candidate;\n\n const parent = dirname(startDir);\n if (parent === startDir) return undefined;\n\n return this.findNearestTsconfig(parent);\n }\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, relative } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport class BootstrapWriter {\n constructor(private readonly logger: ILogger) {}\n\n public async write(config: ResolvedSeedcordDevConfig, emittedEntry: string): Promise<void> {\n const target = config.build.bootstrap;\n const relativeImport = this.formatImportPath(relative(dirname(target), emittedEntry));\n const contents = `import '${relativeImport}';\\n`;\n\n try {\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, contents, 'utf8');\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown error';\n throw new SeedcordError(SeedcordErrorCode.CliBootstrapWriteFailed, [target, reason]);\n }\n\n this.logger.info(`Bootstrap file created at ${target}`);\n }\n\n private formatImportPath(fragment: string): string {\n const normalized = fragment.replaceAll('\\\\', '/');\n return normalized.startsWith('.') ? normalized : `./${normalized}`;\n }\n}\n","import { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { createRequire as createNodeRequire } from 'node:module';\nimport { dirname, extname, relative, resolve } from 'node:path';\n\nimport { isSeedcordError, SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport interface BuildResult {\n emittedEntry: string;\n}\n\ninterface ProcessResult {\n exitCode: number;\n output: string;\n}\n\nexport class TypeScriptProjectBuilder {\n constructor(private readonly logger: ILogger) {}\n\n public async build(config: ResolvedSeedcordDevConfig): Promise<BuildResult> {\n const tsconfigPath = this.resolveTsconfig(config);\n const projectDir = dirname(config.configFile);\n\n await mkdir(config.build.outDir, { recursive: true });\n\n this.logger.info(`Building Seedcord project via tsc using ${tsconfigPath}`);\n\n try {\n await this.runTsc(projectDir, tsconfigPath);\n await this.rewriteSpecifiers(projectDir, tsconfigPath);\n } catch (error: unknown) {\n if (isSeedcordError(error)) throw error;\n\n const reason = Error.isError(error) ? error.message : 'Unknown build error';\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [reason]);\n }\n\n const emittedEntry = this.resolveEmittedEntry(config);\n if (!existsSync(emittedEntry)) {\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Expected output file ${emittedEntry} missing after build`\n ]);\n }\n\n this.logger.info(`Emitted entry: ${emittedEntry}`);\n return { emittedEntry } satisfies BuildResult;\n }\n\n private async runTsc(projectDir: string, tsconfigPath: string): Promise<void> {\n const tscPath = this.resolveProjectTsc(projectDir);\n\n const args = ['-p', tsconfigPath, '--pretty', 'false', '--inlineSources'];\n // tsc rejects --sourceMap alongside a project's inlineSourceMap; only force it otherwise.\n if (!(await this.usesInlineSourceMap(projectDir, tsconfigPath))) args.push('--sourceMap');\n\n const result = await this.runNodeScript(projectDir, tscPath, args);\n if (result.exitCode === 0) return;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `TypeScript compilation failed:\\n${this.truncateOutput(result.output)}`\n ]);\n }\n\n private async usesInlineSourceMap(projectDir: string, tsconfigPath: string): Promise<boolean> {\n const tscPath = this.resolveProjectTsc(projectDir);\n const result = await this.runNodeScript(projectDir, tscPath, ['--showConfig', '-p', tsconfigPath]);\n if (result.exitCode !== 0) return false;\n\n try {\n const config = JSON.parse(result.output) as { compilerOptions?: { inlineSourceMap?: boolean } };\n return config.compilerOptions?.inlineSourceMap === true;\n } catch {\n return false;\n }\n }\n\n // tsc emits every specifier as written\n private async rewriteSpecifiers(projectDir: string, tsconfigPath: string): Promise<void> {\n const binPath = this.resolveTscAlias();\n\n const result = await this.runNodeScript(projectDir, binPath, [\n '-p',\n tsconfigPath,\n '--resolve-full-paths',\n '--resolve-full-extension',\n '.js'\n ]);\n if (result.exitCode === 0) return;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Failed to rewrite import specifiers:\\n${this.truncateOutput(result.output)}`\n ]);\n }\n\n private resolveProjectTsc(projectDir: string): string {\n const projectRequire = this.createProjectRequire(projectDir);\n\n try {\n return projectRequire.resolve('typescript/bin/tsc');\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown resolution error';\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Unable to resolve typescript. Ensure it is installed in this project.\\n${reason}`\n ]);\n }\n }\n\n private resolveTscAlias(): string {\n const selfRequire = createNodeRequire(import.meta.url);\n\n return selfRequire.resolve('tsc-alias/dist/bin/index.js');\n }\n\n private createProjectRequire(projectDir: string): NodeJS.Require {\n const candidate = resolve(projectDir, 'package.json');\n if (existsSync(candidate)) return createNodeRequire(candidate);\n\n return createNodeRequire(import.meta.url);\n }\n\n private async runNodeScript(cwd: string, scriptPath: string, args: string[]): Promise<ProcessResult> {\n return await this.runProcess(process.execPath, [scriptPath, ...args], cwd);\n }\n\n private runProcess(cmd: string, args: string[], cwd: string): Promise<ProcessResult> {\n return new Promise((resolvePromise, rejectPromise) => {\n const child = spawn(cmd, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });\n\n let output = '';\n\n child.stdout.on('data', (chunk) => {\n output += String(chunk);\n });\n\n child.stderr.on('data', (chunk) => {\n output += String(chunk);\n });\n\n child.on('error', rejectPromise);\n\n child.on('close', (code) => {\n resolvePromise({ exitCode: code ?? 1, output });\n });\n });\n }\n\n private truncateOutput(text: string, maxChars = 24_000): string {\n const trimmed = text.trim();\n if (trimmed.length <= maxChars) return trimmed;\n return `${trimmed.slice(0, maxChars)}\\n...output truncated...`;\n }\n\n private resolveTsconfig(config: ResolvedSeedcordDevConfig): string {\n if (config.build.tsconfig) {\n if (!existsSync(config.build.tsconfig)) {\n throw new SeedcordError(SeedcordErrorCode.CliBuildTsconfigNotFound, [config.build.tsconfig]);\n }\n\n return config.build.tsconfig;\n }\n\n const configDir = dirname(config.configFile);\n const candidate = ['tsconfig.build.json', 'tsconfig.json']\n .map((file) => resolve(configDir, file))\n .find((candidatePath) => existsSync(candidatePath));\n\n if (candidate) return candidate;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildTsconfigNotFound, [configDir]);\n }\n\n private resolveEmittedEntry(config: ResolvedSeedcordDevConfig): string {\n const relFromRoot = relative(config.root, config.entry);\n const relNoExt = relFromRoot.slice(0, relFromRoot.length - extname(relFromRoot).length);\n\n const basePath = resolve(config.build.outDir, relNoExt);\n const candidateExts = ['.js', '.mjs', '.cjs'];\n\n for (const ext of candidateExts) {\n const candidate = `${basePath}${ext}`;\n if (existsSync(candidate)) return candidate;\n }\n\n // Fallback if no emitted file was found\n return `${basePath}.js`;\n }\n}\n","import { existsSync } from 'node:fs';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { ConfigLoader } from '#core/config/ConfigLoader';\nimport { ConfigLocator } from '#core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '#core/modules/RuntimeModuleLoader';\n\nimport { BootstrapWriter } from './builder/BootstrapWriter';\nimport { TypeScriptProjectBuilder } from './builder/TypeScriptProjectBuilder';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport class BuildRunner {\n constructor(\n private readonly locator: ConfigLocator,\n private readonly configLoader: ConfigLoader,\n private readonly builder: TypeScriptProjectBuilder,\n private readonly bootstrapWriter: BootstrapWriter,\n private readonly logger: ILogger\n ) {}\n\n public static create(logger: ILogger): BuildRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const locator = new ConfigLocator(logger);\n const configLoader = new ConfigLoader(moduleLoader, logger);\n const builder = new TypeScriptProjectBuilder(logger);\n const bootstrapWriter = new BootstrapWriter(logger);\n\n return new BuildRunner(locator, configLoader, builder, bootstrapWriter, logger);\n }\n\n public async run(): Promise<void> {\n const config = await this.loadConfig();\n this.assertEntryExists(config.entry);\n const { emittedEntry } = await this.builder.build(config);\n await this.bootstrapWriter.write(config, emittedEntry);\n this.logger.info('Seedcord build finished successfully.');\n }\n\n private async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n const configPath = this.locator.locate();\n return this.configLoader.load(configPath);\n }\n\n private assertEntryExists(entryPath: string): void {\n if (!existsSync(entryPath)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [entryPath]);\n }\n }\n}\n","import { isSeedcordError } from '@seedcord/errors';\n\nimport { BaseCommand } from '#core/BaseCommand';\n\nimport { BuildRunner } from './BuildRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class BuildCommand extends BaseCommand {\n private readonly runner: BuildRunner;\n\n constructor() {\n super('build', 'Compile a Seedcord project from the config file', 'Build');\n this.runner = BuildRunner.create(this.logger);\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .action(async () => {\n try {\n await this.runner.run();\n } catch (error: unknown) {\n this.logger.error('Seedcord build failed', error);\n if (isSeedcordError(error)) process.exitCode = 1;\n else process.exit(1);\n }\n });\n }\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { routeLeavesOf, type SlashRouteLeaf } from '@seedcord/utils/internal';\nimport { ApplicationCommandOptionType, ApplicationCommandType } from 'discord-api-types/v10';\n\nimport type { OptionKind, SlashOption } from '@seedcord/core';\nimport type { EmojiConfig, ILogger } from '@seedcord/types';\nimport type {\n APIApplicationCommandBasicOption,\n RESTPostAPIApplicationCommandsJSONBody,\n RESTPostAPIChatInputApplicationCommandsJSONBody,\n RESTPostAPIContextMenuApplicationCommandsJSONBody\n} from 'discord-api-types/v10';\n\nexport type RouteOptions = Record<string, SlashOption>;\n\n// keyed by route string (`cmd`, `cmd/sub`, or `cmd/group/sub`)\nexport type SlashTables = Record<string, RouteOptions>;\n\nexport type EmojiKinds = Record<string, 'string' | 'tuple'>;\n\nexport interface Augmentation {\n slash: SlashTables;\n userContextMenus: string[];\n messageContextMenus: string[];\n emojis: EmojiKinds;\n}\n\nexport interface ScannedCommand {\n sourceFile: string;\n json: RESTPostAPIApplicationCommandsJSONBody;\n}\n\ntype CommandOption = SlashRouteLeaf['options'][number];\ntype BasicOption = Exclude<\n CommandOption,\n { type: ApplicationCommandOptionType.Subcommand | ApplicationCommandOptionType.SubcommandGroup }\n>;\n\n// discord-api-types renaming or adding a basic option type breaks this object\nconst KIND_BY_TYPE = {\n [ApplicationCommandOptionType.String]: 'string',\n [ApplicationCommandOptionType.Integer]: 'integer',\n [ApplicationCommandOptionType.Number]: 'number',\n [ApplicationCommandOptionType.Boolean]: 'boolean',\n [ApplicationCommandOptionType.User]: 'user',\n [ApplicationCommandOptionType.Channel]: 'channel',\n [ApplicationCommandOptionType.Role]: 'role',\n [ApplicationCommandOptionType.Mentionable]: 'mentionable',\n [ApplicationCommandOptionType.Attachment]: 'attachment'\n} as const satisfies Record<APIApplicationCommandBasicOption['type'], OptionKind>;\n\nfunction mapEmojis(emojiConfig: EmojiConfig): EmojiKinds {\n const emojis: EmojiKinds = {};\n for (const [key, value] of Object.entries(emojiConfig)) {\n emojis[key] = Array.isArray(value) ? 'tuple' : 'string';\n }\n return emojis;\n}\n\n// reads each builder back through toJSON() because djs erases option names at the type level\nexport class AugmentationBuilder {\n constructor(private readonly logger: ILogger) {}\n\n public generate(commands: readonly ScannedCommand[], emojiConfig: EmojiConfig): Augmentation {\n const slash: SlashTables = {};\n const sourceByRoute = new Map<string, string>();\n const sourceByUserName = new Map<string, string>();\n const sourceByMessageName = new Map<string, string>();\n\n for (const command of commands) {\n const { json } = command;\n switch (json.type) {\n case ApplicationCommandType.User: {\n this.collectContextMenu('user', json, command.sourceFile, sourceByUserName);\n break;\n }\n case ApplicationCommandType.Message: {\n this.collectContextMenu('message', json, command.sourceFile, sourceByMessageName);\n break;\n }\n case undefined:\n case ApplicationCommandType.ChatInput: {\n this.collectSlash(json, command.sourceFile, slash, sourceByRoute);\n break;\n }\n // No default\n }\n }\n\n const userContextMenus = [...sourceByUserName.keys()];\n const messageContextMenus = [...sourceByMessageName.keys()];\n const emojis = mapEmojis(emojiConfig);\n this.logger.debug(\n `Generated ${Object.keys(slash).length} slash route(s), ${userContextMenus.length} user and ${messageContextMenus.length} message context-menu command(s), ${Object.keys(emojis).length} emoji(s)`\n );\n return { slash, userContextMenus, messageContextMenus, emojis };\n }\n\n private collectSlash(\n json: RESTPostAPIChatInputApplicationCommandsJSONBody,\n sourceFile: string,\n slash: SlashTables,\n sourceByRoute: Map<string, string>\n ): void {\n this.warnEmptyGroups(json);\n for (const leaf of routeLeavesOf(json)) {\n // declaration merging folds a duplicate route in silently\n const firstFile = sourceByRoute.get(leaf.route);\n if (firstFile !== undefined) {\n throw new SeedcordError(SeedcordErrorCode.CliCodegenDuplicateRoute, [\n leaf.route,\n firstFile,\n sourceFile\n ]);\n }\n sourceByRoute.set(leaf.route, sourceFile);\n slash[leaf.route] = this.mapOptions(leaf.options);\n }\n }\n\n private collectContextMenu(\n kind: 'user' | 'message',\n json: RESTPostAPIContextMenuApplicationCommandsJSONBody,\n sourceFile: string,\n sourceByName: Map<string, string>\n ): void {\n const firstFile = sourceByName.get(json.name);\n if (firstFile !== undefined) {\n throw new SeedcordError(SeedcordErrorCode.CliCodegenDuplicateContextMenu, [\n kind,\n json.name,\n firstFile,\n sourceFile\n ]);\n }\n sourceByName.set(json.name, sourceFile);\n }\n\n // toJSON() allows an empty subcommand group though discord rejects it at deploy. routeLeavesOf gives it\n // no route, so it never reaches the tables\n private warnEmptyGroups(json: RESTPostAPIChatInputApplicationCommandsJSONBody): void {\n for (const option of json.options ?? []) {\n if (option.type === ApplicationCommandOptionType.SubcommandGroup && (option.options ?? []).length === 0) {\n this.logger.warn(`Slash group \\`${json.name}/${option.name}\\` has no subcommands and will not deploy.`);\n }\n }\n }\n\n private mapOptions(options: readonly CommandOption[]): RouteOptions {\n const table: RouteOptions = {};\n for (const option of options) {\n if (\n option.type === ApplicationCommandOptionType.Subcommand ||\n option.type === ApplicationCommandOptionType.SubcommandGroup\n ) {\n continue;\n }\n table[option.name] = this.toSlashOption(option);\n }\n return table;\n }\n\n private toSlashOption(option: BasicOption): SlashOption {\n // empty choices would narrow the value to never\n const choices =\n 'choices' in option && option.choices && option.choices.length > 0\n ? option.choices.map((choice) => choice.value)\n : undefined;\n const autocomplete = 'autocomplete' in option && option.autocomplete === true ? true : undefined;\n // sorted so a reordered declaration still matches under `--check`\n const channelTypes =\n 'channel_types' in option && option.channel_types && option.channel_types.length > 0\n ? [...option.channel_types].sort((first, second) => first - second)\n : undefined;\n return {\n kind: KIND_BY_TYPE[option.type],\n required: option.required ?? false,\n ...(choices && { choices }),\n ...(autocomplete && { autocomplete }),\n ...(channelTypes && { channelTypes })\n };\n }\n}\n","import type { EmojiKinds, Augmentation, RouteOptions, SlashTables } from './AugmentationBuilder';\nimport type { SlashOption } from '@seedcord/core';\n\nconst BANNER = `// Generated by \\`seedcord codegen\\`. Do not edit by hand.\n// Run \\`seedcord codegen\\` after changing your commands, plugins, or emoji config.`;\n\nconst BOT_BINDING = 'Bot';\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst CONTROL_CHAR = 0x20;\nconst HEX_RADIX = 16;\n\ninterface AttachedPlugins {\n readonly specifier: string; // relative to the generated file at config.root\n readonly keys: readonly string[];\n}\n\nexport function renderAugmentation(registry: Augmentation, target: string, plugins?: AttachedPlugins): string {\n const keys = [...(plugins?.keys ?? [])].sort(compare);\n const attached = plugins !== undefined && keys.length > 0;\n const botImport = attached ? `import type ${BOT_BINDING} from '${escapeLiteral(plugins.specifier)}';\\n\\n` : '';\n const coreRows = attached ? ` interface Core {\\n${renderPluginRows(keys)}\\n }\\n` : '';\n\n // prettier-ignore binds to the next statement, and the declare module is the whole file\n const header = `${BANNER}\\n\\n${botImport}// prettier-ignore\\ndeclare module '${target}' {\\n`;\n\n return (\n `${header + coreRows} interface SlashOptionRegistry {\\n${renderSlashRows(registry.slash)}\\n }\\n` +\n ` interface UserContextMenuRegistry {\\n${renderContextMenuRows(registry.userContextMenus)}\\n }\\n` +\n ` interface MessageContextMenuRegistry {\\n${renderContextMenuRows(registry.messageContextMenus)}\\n }\\n` +\n ` interface EmojiMap {\\n${renderEmojiRows(registry.emojis)}\\n }\\n` +\n `}\\n\\nexport {};\\n`\n );\n}\n\n// the indexed access defers resolution. an `extends Pick<typeof Bot, ...>` clause resolves while the bot\n// constant is still being inferred, and a plugin ctor naming Core closes that loop (TS7022).\nfunction renderPluginRows(keys: readonly string[]): string {\n return keys.map((key) => ` ${renderKey(key)}: (typeof ${BOT_BINDING})['${escapeLiteral(key)}'];`).join('\\n');\n}\n\nfunction renderSlashRows(tables: SlashTables): string {\n return Object.entries(tables)\n .sort(([first], [second]) => compare(first, second))\n .map(([route, options]) => ` ${renderKey(route)}: ${renderRow(options)};`)\n .join('\\n');\n}\n\nfunction renderContextMenuRows(names: readonly string[]): string {\n return [...names]\n .sort(compare)\n .map((name) => ` ${renderKey(name)}: true;`)\n .join('\\n');\n}\n\n// InjectedEmojiMap reads this tag to type Emojis.X as GuildEmoji or ApplicationEmoji\nfunction renderEmojiRows(emojis: EmojiKinds): string {\n return Object.entries(emojis)\n .sort(([first], [second]) => compare(first, second))\n .map(([key, kind]) => ` ${renderKey(key)}: '${kind === 'tuple' ? 'guild' : 'application'}';`)\n .join('\\n');\n}\n\nfunction renderRow(options: RouteOptions): string {\n const entries = Object.entries(options);\n if (entries.length === 0) return '{}';\n return `{ ${entries.map(([name, opt]) => `${renderKey(name)}: ${renderOption(opt)}`).join('; ')} }`;\n}\n\nfunction renderOption(opt: SlashOption): string {\n const parts = [`kind: '${opt.kind}'`, `required: ${opt.required}`];\n if (opt.choices && opt.choices.length > 0) parts.push(`choices: [${opt.choices.map(renderChoice).join(', ')}]`);\n if (opt.autocomplete) parts.push('autocomplete: true');\n // wire numbers, mapped to channel subtypes by the typed view\n if (opt.channelTypes && opt.channelTypes.length > 0) parts.push(`channelTypes: [${opt.channelTypes.join(', ')}]`);\n return `{ ${parts.join('; ')} }`;\n}\n\nfunction renderChoice(value: string | number): string {\n if (typeof value !== 'string') return String(value);\n return `'${escapeLiteral(value)}'`;\n}\n\n// discord allows spaces and apostrophes in a context-menu name\nfunction renderKey(name: string): string {\n return IDENTIFIER.test(name) ? name : `'${escapeLiteral(name)}'`;\n}\n\nfunction escapeLiteral(value: string): string {\n let escaped = '';\n for (const char of value) {\n const code = char.charCodeAt(0);\n switch (char) {\n case '\\\\': {\n escaped += '\\\\\\\\';\n break;\n }\n case \"'\": {\n escaped += String.raw`\\'`;\n break;\n }\n case '\\n': {\n escaped += String.raw`\\n`;\n break;\n }\n case '\\r': {\n escaped += String.raw`\\r`;\n break;\n }\n case '\\t': {\n escaped += String.raw`\\t`;\n break;\n }\n default: {\n if (code < CONTROL_CHAR) escaped += String.raw`\\x${code.toString(HEX_RADIX).padStart(2, '0')}`;\n else escaped += char;\n }\n }\n }\n return escaped;\n}\n\nfunction compare(first: string, second: string): number {\n if (first < second) return -1;\n return first > second ? 1 : 0;\n}\n","import { existsSync } from 'node:fs';\nimport { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { SeedcordBrand, type Brandable, type SeedcordInstance } from '@seedcord/types/internal';\nimport { isTsOrJsFile } from '@seedcord/utils/node';\nimport { ApplicationCommandType } from 'discord-api-types/v10';\n\nimport { ConfigLoader } from '#core/config/ConfigLoader';\nimport { ConfigLocator } from '#core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '#core/modules/RuntimeModuleLoader';\nimport { resolveDefaultExport } from '#utils/resolveDefaultExport';\n\nimport { AugmentationBuilder } from './AugmentationBuilder';\nimport { renderAugmentation } from './renderAugmentation';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { ModuleLoader } from '#core/modules/ModuleLoader';\nimport type { ScannedCommand } from './AugmentationBuilder';\nimport type { EmojiConfig, ILogger, TypedOmit } from '@seedcord/types';\nimport type { RESTPostAPIApplicationCommandsJSONBody } from 'discord-api-types/v10';\n\nconst OUTPUT_FILENAME = 'seedcord-gen.d.ts';\n\nconst ENTRY_EXTENSION = /\\.[mc]?[jt]sx?$/;\n\ninterface BuilderLike {\n component: { toJSON: () => unknown };\n}\n\ninterface ScanResult {\n commands: ScannedCommand[];\n emojis: EmojiConfig;\n augmentTarget: string;\n pluginKeys: readonly string[];\n}\n\n// extensionless resolves under moduleResolution bundler, which a seedcord project sets\nfunction botSpecifier(root: string, instance: string): string {\n const posix = relative(root, instance).split(sep).join('/').replace(ENTRY_EXTENSION, '');\n return posix.startsWith('.') ? posix : `./${posix}`;\n}\n\nexport class CodegenRunner {\n constructor(\n private readonly locator: ConfigLocator,\n private readonly configLoader: ConfigLoader,\n private readonly moduleLoader: ModuleLoader,\n private readonly generator: AugmentationBuilder,\n private readonly logger: ILogger\n ) {}\n\n public static create(logger: ILogger): CodegenRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const locator = new ConfigLocator(logger);\n const configLoader = new ConfigLoader(moduleLoader, logger);\n const generator = new AugmentationBuilder(logger);\n\n return new CodegenRunner(locator, configLoader, moduleLoader, generator, logger);\n }\n\n public async run(check: boolean): Promise<void> {\n const config = await this.loadConfig();\n const { commands, emojis, augmentTarget, pluginKeys } = await this.scan(config);\n const rendered = renderAugmentation(this.generator.generate(commands, emojis), augmentTarget, {\n specifier: botSpecifier(config.root, config.instance),\n keys: pluginKeys\n });\n const outputPath = resolve(config.root, OUTPUT_FILENAME);\n\n if (check) {\n await this.check(rendered, outputPath);\n return;\n }\n\n await this.write(rendered, outputPath);\n }\n\n private async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n return this.configLoader.load(this.locator.locate());\n }\n\n private async scan(config: ResolvedSeedcordDevConfig): Promise<ScanResult> {\n const { commandsDir, emojis, augmentTarget, pluginKeys } = await this.resolveInstance(config);\n\n const commands: ScannedCommand[] = [];\n if (commandsDir) {\n for await (const command of this.walk(commandsDir, new Set(), true)) {\n commands.push(command);\n }\n }\n return { commands, emojis, augmentTarget, pluginKeys };\n }\n\n // the bot scans under tsx/vite where import() takes a .ts path. codegen runs under plain node, hence the\n // tsx-backed module loader below.\n private async *walk(dir: string, seen: Set<unknown>, isRoot: boolean): AsyncGenerator<ScannedCommand> {\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown error';\n // an unreadable commands dir would pass --check against a stale registry\n if (isRoot) throw new SeedcordError(SeedcordErrorCode.CliCodegenCommandsDirUnreadable, [dir, reason]);\n this.logger.warn(`Skipping unreadable directory ${dir}. ${reason}.`);\n return;\n }\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n yield* this.walk(fullPath, seen, false);\n } else if (isTsOrJsFile(entry)) {\n const imported = await this.moduleLoader.importModule<Record<string, unknown>>(fullPath);\n for (const exported of Object.values(imported)) {\n // a barrel re-exports the same class object\n if (seen.has(exported)) continue;\n seen.add(exported);\n const json = this.commandJsonOf(exported);\n if (json) yield { sourceFile: fullPath, json };\n }\n }\n }\n }\n\n private async resolveInstance(\n config: ResolvedSeedcordDevConfig\n ): Promise<TypedOmit<ScanResult, 'commands'> & { commandsDir: string | undefined }> {\n // reading commands.path and emojis constructs the bot, so its lifecycle and plugin setup logs\n // appear here. codegen never starts it, nothing logs in or connects\n this.logger.debug('Loading instance to resolve the commands directory');\n const module = await this.moduleLoader.importModule(config.instance);\n const instance = resolveDefaultExport(module);\n if (!this.isSeedcordInstance(instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliInstanceInvalid);\n }\n\n // the bot resolves commands.path against cwd\n const commandsPath = instance.config.bot.commands.path;\n return {\n commandsDir: commandsPath ? resolve(process.cwd(), commandsPath) : undefined,\n emojis: instance.config.bot.emojis ?? {},\n augmentTarget: instance.augmentTarget,\n pluginKeys: instance.pluginKeys\n };\n }\n\n private commandJsonOf(exported: unknown): RESTPostAPIApplicationCommandsJSONBody | undefined {\n if (typeof exported !== 'function') return undefined;\n\n let instance: unknown;\n try {\n instance = new (exported as new () => unknown)();\n } catch {\n return undefined;\n }\n\n if (!this.isBuilderLike(instance)) return undefined;\n const json = instance.component.toJSON();\n if (!this.isApplicationCommand(json)) return undefined;\n return json;\n }\n\n private isBuilderLike(value: unknown): value is BuilderLike {\n if (typeof value !== 'object' || value === null) return false;\n const component = (value as { component?: unknown }).component;\n return (\n typeof component === 'object' &&\n component !== null &&\n typeof (component as BuilderLike['component']).toJSON === 'function'\n );\n }\n\n private isApplicationCommand(json: unknown): json is RESTPostAPIApplicationCommandsJSONBody {\n if (typeof json !== 'object' || json === null) return false;\n const { name, type } = json as { name?: unknown; type?: unknown };\n if (typeof name !== 'string') return false;\n // chat-input omits type or sets ChatInput, context menus set User or Message\n return (\n type === undefined ||\n type === ApplicationCommandType.ChatInput ||\n type === ApplicationCommandType.User ||\n type === ApplicationCommandType.Message\n );\n }\n\n private isSeedcordInstance(candidate: unknown): candidate is SeedcordInstance {\n return typeof candidate === 'object' && candidate !== null && (candidate as Brandable)[SeedcordBrand] === true;\n }\n\n private async write(rendered: string, outputPath: string): Promise<void> {\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, rendered, 'utf8');\n this.logger.info(`Augmentations written to ${outputPath}`);\n }\n\n private async check(rendered: string, outputPath: string): Promise<void> {\n const onDisk = existsSync(outputPath) ? await readFile(outputPath, 'utf8') : '';\n if (onDisk === rendered) return;\n\n this.logger.error(`Augmentations are out of date. Run \\`seedcord codegen\\` and commit ${outputPath}.`);\n process.exitCode = 1;\n }\n}\n","import { isSeedcordError } from '@seedcord/errors';\n\nimport { BaseCommand } from '#core/BaseCommand';\n\nimport { CodegenRunner } from './CodegenRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class CodegenCommand extends BaseCommand {\n private readonly runner: CodegenRunner;\n\n constructor() {\n super('codegen', 'Generate typed augmentations from your commands and config', 'Codegen');\n this.runner = CodegenRunner.create(this.logger);\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .option('--check', 'Verify the committed augmentations are up to date instead of writing them')\n .action(async (options) => {\n try {\n await this.runner.run(options.check ?? false);\n } catch (error: unknown) {\n this.logger.error('Seedcord codegen failed', error);\n if (isSeedcordError(error)) process.exitCode = 1;\n else process.exit(1);\n }\n });\n }\n}\n","export function isInteractive(opts: { yes?: boolean }, hasActionFlags: boolean): boolean {\n return (\n !hasActionFlags &&\n process.stdin.isTTY === true &&\n process.stdout.isTTY === true &&\n // some CI fakes a TTY\n !process.env.CI &&\n !opts.yes\n );\n}\n","type CleanReason = 'overlap' | 'purge';\n\ninterface DeployedCommand {\n id: string;\n name: string;\n}\n\nexport interface GuildCommands {\n guildId: string;\n guildName: string;\n commands: DeployedCommand[];\n}\n\nexport interface Flagged extends DeployedCommand {\n guildId: string;\n guildName: string;\n reason: CleanReason;\n}\n\n/**\n * Selects which deployed guild commands `commands --clean` would delete. An overlap is a guild command\n * whose name also exists globally, so it renders twice in the picker.\n */\nexport function classifyGuildCommands(\n globalNames: ReadonlySet<string>,\n guilds: readonly GuildCommands[],\n purge: boolean\n): Flagged[] {\n const flagged: Flagged[] = [];\n\n for (const { guildId, guildName, commands } of guilds) {\n for (const command of commands) {\n if (purge) {\n flagged.push({ guildId, guildName, id: command.id, name: command.name, reason: 'purge' });\n } else if (globalNames.has(command.name)) {\n flagged.push({ guildId, guildName, id: command.id, name: command.name, reason: 'overlap' });\n }\n }\n }\n\n return flagged;\n}\n","import { REST } from '@discordjs/rest';\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Routes } from 'discord-api-types/v10';\n\nimport { classifyGuildCommands } from './classify';\n\nimport type { Flagged, GuildCommands } from './classify';\nimport type {\n RESTGetAPIApplicationCommandsResult,\n RESTGetAPIApplicationGuildCommandsResult,\n RESTGetAPICurrentUserGuildsResult,\n RESTGetCurrentApplicationResult,\n Snowflake\n} from 'discord-api-types/v10';\n\ntype RestClient = Pick<REST, 'get' | 'delete'>;\n\nexport interface CleanScope {\n guildIds: string[];\n allGuilds: boolean;\n purge: boolean;\n}\n\nexport interface GuildSummary {\n id: string;\n name: string;\n}\n\nexport interface ResolvedTargets {\n appId: Snowflake;\n guilds: GuildSummary[];\n}\n\nexport interface SkippedGuild {\n guildId: string;\n guildName: string;\n reason: string;\n}\n\nexport interface ScanResult {\n flagged: Flagged[];\n skipped: SkippedGuild[];\n scannedGuildCount: number;\n scannedCommandCount: number;\n globalCommandCount: number;\n}\n\ninterface DeleteFailure {\n command: Flagged;\n reason: string;\n}\n\nexport interface DeleteResult {\n deleted: number;\n failed: DeleteFailure[];\n}\n\nexport interface CleanOps {\n resolveTargets(scope: CleanScope, token: string): Promise<ResolvedTargets>;\n scanGuilds(token: string, appId: Snowflake, guilds: GuildSummary[], purge: boolean): Promise<ScanResult>;\n applyDeletions(token: string, appId: Snowflake, flagged: Flagged[]): Promise<DeleteResult>;\n}\n\nconst GUILD_PAGE = 200;\n\nexport class CleanRunner implements CleanOps {\n constructor(private readonly makeRest: (token: string) => RestClient) {}\n\n public static create(): CleanRunner {\n return new CleanRunner((token) => new REST({ version: '10' }).setToken(token));\n }\n\n public async resolveTargets(scope: CleanScope, token: string): Promise<ResolvedTargets> {\n // purge across all guilds would wipe every command\n if (scope.purge && scope.allGuilds) throw new SeedcordError(SeedcordErrorCode.CliCleanPurgeAllGuilds);\n\n if (!scope.allGuilds && scope.guildIds.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.CliCleanNoGuilds);\n }\n\n const rest = this.makeRest(token);\n const appId = await this.resolveAppId(rest);\n const guilds = scope.allGuilds\n ? await this.fetchBotGuilds(rest)\n : scope.guildIds.map((id) => ({ id, name: id }));\n\n return { appId, guilds };\n }\n\n public async listBotGuilds(token: string): Promise<GuildSummary[]> {\n return this.fetchBotGuilds(this.makeRest(token));\n }\n\n public async scanGuilds(\n token: string,\n appId: Snowflake,\n guilds: GuildSummary[],\n purge: boolean\n ): Promise<ScanResult> {\n const rest = this.makeRest(token);\n const globalNames = await this.fetchGlobalNames(rest, appId);\n\n const buckets: GuildCommands[] = [];\n const skipped: SkippedGuild[] = [];\n let scannedCommandCount = 0;\n for (const guild of guilds) {\n try {\n const deployed = (await rest.get(\n Routes.applicationGuildCommands(appId, guild.id)\n )) as RESTGetAPIApplicationGuildCommandsResult;\n const commands = deployed.map((command) => ({ id: command.id, name: command.name }));\n scannedCommandCount += commands.length;\n buckets.push({ guildId: guild.id, guildName: guild.name, commands });\n } catch (error: unknown) {\n skipped.push({\n guildId: guild.id,\n guildName: guild.name,\n reason: Error.isError(error) ? error.message : 'Unknown error'\n });\n }\n }\n\n return {\n flagged: classifyGuildCommands(globalNames, buckets, purge),\n skipped,\n scannedGuildCount: buckets.length,\n scannedCommandCount,\n globalCommandCount: globalNames.size\n };\n }\n\n public async applyDeletions(token: string, appId: Snowflake, flagged: Flagged[]): Promise<DeleteResult> {\n const rest = this.makeRest(token);\n let deleted = 0;\n const failed: DeleteFailure[] = [];\n\n for (const command of flagged) {\n try {\n await rest.delete(Routes.applicationGuildCommand(appId, command.guildId, command.id));\n deleted++;\n } catch (error: unknown) {\n failed.push({ command, reason: Error.isError(error) ? error.message : 'Unknown error' });\n }\n }\n\n return { deleted, failed };\n }\n\n private async resolveAppId(rest: RestClient): Promise<Snowflake> {\n try {\n const app = (await rest.get(Routes.currentApplication())) as RESTGetCurrentApplicationResult;\n return app.id;\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown error';\n throw new SeedcordError(SeedcordErrorCode.CliCleanAppFetchFailed, [reason]);\n }\n }\n\n private async fetchBotGuilds(rest: RestClient): Promise<GuildSummary[]> {\n const guilds: GuildSummary[] = [];\n let after: string | undefined;\n\n for (;;) {\n const query = new URLSearchParams({ limit: String(GUILD_PAGE) });\n if (after) query.set('after', after);\n\n const page = (await rest.get(Routes.userGuilds(), { query })) as RESTGetAPICurrentUserGuildsResult;\n for (const guild of page) guilds.push({ id: guild.id, name: guild.name });\n\n after = page.at(-1)?.id;\n if (page.length < GUILD_PAGE || !after) break;\n }\n\n return guilds;\n }\n\n private async fetchGlobalNames(rest: RestClient, appId: Snowflake): Promise<Set<string>> {\n const global = (await rest.get(Routes.applicationCommands(appId))) as RESTGetAPIApplicationCommandsResult;\n return new Set(global.map((command) => command.name));\n }\n}\n","export function plural(count: number, singular: string, pluralForm = `${singular}s`): string {\n return `${count} ${count === 1 ? singular : pluralForm}`;\n}\n\nexport function includesIgnoreCase(text: string, search: string): boolean {\n return text.toLowerCase().includes(search.trim().toLowerCase());\n}\n","import { cancel, isCancel } from '@clack/prompts';\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\n// clack signals cancel with a symbol\nexport function requireValue<Value>(value: Value | symbol): Value {\n if (isCancel(value)) {\n cancel('Cancelled.');\n throw new SeedcordError(SeedcordErrorCode.CliCancelled);\n }\n return value;\n}\n","import { autocompleteMultiselect, multiselect } from '@clack/prompts';\n\nimport { includesIgnoreCase } from '#core/format';\n\nimport { requireValue } from './requireValue';\n\ninterface PickItem {\n id: string;\n name: string;\n}\n\nexport interface PickFromListOptions {\n message: string;\n items: PickItem[];\n maxItems?: number;\n}\n\nconst DEFAULT_MAX_ITEMS = 10;\n// above this a checkbox list is hard to scan, so switch to search-as-you-type\nconst SEARCH_THRESHOLD = 12;\n\nexport async function pickFromList(opts: PickFromListOptions): Promise<string[]> {\n const options = opts.items.map((item) => ({ value: item.id, label: item.name }));\n const maxItems = opts.maxItems ?? DEFAULT_MAX_ITEMS;\n\n if (opts.items.length <= SEARCH_THRESHOLD) {\n return requireValue(await multiselect<string>({ message: opts.message, options, maxItems, required: false }));\n }\n\n return requireValue(\n await autocompleteMultiselect<string>({\n message: opts.message,\n options,\n maxItems,\n placeholder: 'Type to search…',\n filter: (search, option) =>\n includesIgnoreCase(option.label ?? '', search) || includesIgnoreCase(String(option.value), search)\n })\n );\n}\n","import { confirm as clackConfirm, select as clackSelect } from '@clack/prompts';\n\nimport { requireValue } from './requireValue';\n\nimport type { ConfirmOptions, SelectOptions } from '@clack/prompts';\n\nexport { intro, outro, log, note, spinner } from '@clack/prompts';\nexport { pickFromList } from './pickFromList';\n\nexport async function select<Value>(opts: SelectOptions<Value>): Promise<Value> {\n return requireValue(await clackSelect(opts));\n}\n\nexport async function confirm(opts: ConfirmOptions): Promise<boolean> {\n return requireValue(await clackConfirm(opts));\n}\n","import { createInterface } from 'node:readline';\n\nimport type { ILogger } from '@seedcord/types';\n\ntype Ask = (question: string) => Promise<string>;\n\nasync function readlineAsk(question: string): Promise<string> {\n using rl = createInterface({ input: process.stdin, output: process.stdout });\n return await new Promise<string>((resolve) => rl.question(question, resolve));\n}\n\nexport async function confirmCount(count: number, logger: ILogger, ask: Ask = readlineAsk): Promise<boolean> {\n logger.warn(`About to delete ${count} guild command(s). This cannot be undone.`);\n const answer = await ask(`Type ${count} to confirm (anything else aborts) `);\n return answer.trim() === String(count);\n}\n","import { SeedcordErrorCode, paint } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { plural } from '#core/format';\nimport { confirm, log, note, outro, spinner } from '#core/prompts';\n\nimport { confirmCount } from './confirm';\n\nimport type { Flagged } from './classify';\nimport type { DeleteResult, ScanResult, SkippedGuild } from './CleanRunner';\nimport type { CleanPresenter, EmptyOutcome } from './executeClean';\nimport type { ILogger } from '@seedcord/types';\n\ninterface GuildGroup {\n guildName: string;\n commands: Flagged[];\n}\n\nfunction groupByGuild(flagged: Flagged[]): GuildGroup[] {\n const groups = new Map<string, GuildGroup>();\n for (const command of flagged) {\n const group = groups.get(command.guildId) ?? { guildName: command.guildName, commands: [] };\n group.commands.push(command);\n groups.set(command.guildId, group);\n }\n return [...groups.values()];\n}\n\nfunction skippedSummary(skipped: SkippedGuild[]): string {\n return `Could not read ${plural(skipped.length, 'guild')} (${skipped.map((s) => s.guildName).join(', ')}).`;\n}\n\nfunction emptyLines(scan: ScanResult, outcome: EmptyOutcome): { info: string[]; outro: string } {\n const variants: Record<EmptyOutcome, { info: string[]; outro: string }> = {\n 'all-skipped': {\n info: [],\n outro: `Could not read any of the ${plural(scan.skipped.length, 'guild')}, nothing was scanned.`\n },\n 'no-commands': {\n info: [],\n outro: `Scanned ${plural(scan.scannedGuildCount, 'guild')} with no guild commands deployed. Nothing to clean.`\n },\n 'no-globals': {\n info: [\n 'This app has no global commands, so nothing can duplicate one.',\n 'Re-run and choose a full reset to remove guild commands.'\n ],\n outro: 'Nothing to clean.'\n },\n 'no-overlaps': {\n info: [\n `Scanned ${plural(scan.scannedCommandCount, 'guild command')} across ${plural(scan.scannedGuildCount, 'guild')}. None duplicate a global command.`,\n 'Re-run and choose a full reset to remove all of them.'\n ],\n outro: 'Nothing to clean.'\n }\n };\n return variants[outcome];\n}\n\n/** Renders the clean flow as clack framed output for an interactive terminal. */\nexport class InteractivePresenter implements CleanPresenter {\n public async status<Value>(message: string, task: () => Promise<Value>, done?: string): Promise<Value> {\n const status = spinner();\n status.start(message);\n try {\n return await task();\n } finally {\n status.stop(done ?? message);\n }\n }\n\n public preview(scan: ScanResult): void {\n const body = groupByGuild(scan.flagged)\n .map((group) => `${paint.bold(group.guildName)}\\n${group.commands.map((c) => ` ${c.name}`).join('\\n')}`)\n .join('\\n\\n');\n note(body, `Will delete ${plural(scan.flagged.length, 'guild command')} (nothing deleted yet)`);\n if (scan.skipped.length > 0) log.warn(skippedSummary(scan.skipped));\n }\n\n public largeBotGuard(guildCount: number): Promise<boolean> {\n return confirm({\n message: `The bot is in ${guildCount} guilds. Scan all of them? This makes ${guildCount} requests.`,\n initialValue: false\n });\n }\n\n public confirmDelete(count: number, skippedCount: number): Promise<boolean> {\n const skips = skippedCount > 0 ? ` ${plural(skippedCount, 'guild')} could not be read.` : '';\n return confirm({\n message: `Delete ${plural(count, 'guild command')}? This cannot be undone.${skips}`,\n initialValue: false\n });\n }\n\n public result(deletion: DeleteResult, skipped: SkippedGuild[]): void {\n for (const failure of deletion.failed) {\n log.warn(`Could not delete ${failure.command.name} in ${failure.command.guildName} (${failure.reason}).`);\n }\n if (skipped.length > 0) log.warn(skippedSummary(skipped));\n outro(`Deleted ${plural(deletion.deleted, 'guild command')}. Global commands untouched.`);\n }\n\n public nothingToClean(scan: ScanResult, outcome: EmptyOutcome): void {\n const lines = emptyLines(scan, outcome);\n for (const line of lines.info) log.info(line);\n outro(lines.outro);\n }\n\n public dryRunHint(): void {\n outro('Dry run, nothing was deleted.');\n }\n}\n\n/** Renders the clean flow as plain logger lines for the flag, CI, and non-TTY path. */\nexport class FlagPresenter implements CleanPresenter {\n constructor(\n private readonly logger: ILogger,\n private readonly yes: boolean\n ) {}\n\n public status<Value>(message: string, task: () => Promise<Value>): Promise<Value> {\n this.logger.info(message);\n return task();\n }\n\n public preview(scan: ScanResult): void {\n this.logger.info(paint.bold(`${plural(scan.flagged.length, 'guild command')} selected for deletion`));\n for (const group of groupByGuild(scan.flagged)) {\n this.logger.info(paint.sky(group.guildName));\n for (const command of group.commands) this.logger.info(` ${command.name}`);\n }\n for (const skip of scan.skipped) this.logger.warn(`Skipped ${skip.guildName} (${skip.reason}).`);\n }\n\n public largeBotGuard(guildCount: number): Promise<boolean> {\n if (this.yes) return Promise.resolve(true);\n return Promise.reject(new SeedcordError(SeedcordErrorCode.CliCleanLargeBotUnconfirmed, [guildCount]));\n }\n\n // clack confirm needs a tty, so this prompts for a typed count instead\n public confirmDelete(count: number, skippedCount: number): Promise<boolean> {\n if (this.yes) return Promise.resolve(true);\n // readline cannot prompt without a terminal\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n return Promise.reject(new SeedcordError(SeedcordErrorCode.CliCleanApplyNeedsYes));\n }\n if (skippedCount > 0)\n this.logger.warn(`${plural(skippedCount, 'guild')} could not be read and were not scanned.`);\n return confirmCount(count, this.logger);\n }\n\n public result(deletion: DeleteResult, skipped: SkippedGuild[]): void {\n for (const failure of deletion.failed) {\n this.logger.warn(\n `Could not delete ${failure.command.name} in ${failure.command.guildName} (${failure.reason}).`\n );\n }\n if (skipped.length > 0) this.logger.warn(skippedSummary(skipped));\n this.logger.info(\n paint.mint(`Deleted ${plural(deletion.deleted, 'guild command')}. Global commands untouched.`)\n );\n }\n\n public nothingToClean(scan: ScanResult, outcome: EmptyOutcome): void {\n const lines = emptyLines(scan, outcome);\n for (const line of lines.info) this.logger.info(line);\n this.logger.info(paint.mint(lines.outro));\n }\n\n public dryRunHint(): void {\n this.logger.info(paint.italic('Dry run. Re-run with --apply to delete the above.'));\n }\n}\n","import { plural } from '#core/format';\n\nimport type { CleanOps, CleanScope, DeleteResult, GuildSummary, ScanResult, SkippedGuild } from './CleanRunner';\n\nexport interface CleanPresenter {\n status<Value>(message: string, task: () => Promise<Value>, done?: string): Promise<Value>;\n preview(scan: ScanResult): void;\n largeBotGuard(guildCount: number): Promise<boolean>;\n confirmDelete(count: number, skippedCount: number): Promise<boolean>;\n result(deletion: DeleteResult, skipped: SkippedGuild[]): void;\n nothingToClean(scan: ScanResult, outcome: EmptyOutcome): void;\n dryRunHint(): void;\n}\n\nexport interface CleanRequest {\n runner: CleanOps;\n scope: CleanScope;\n apply: boolean;\n token: string;\n presenter: CleanPresenter;\n /** Names the caller already fetched (the wizard picker), used to label guilds the scan only knows by id. */\n knownGuilds?: GuildSummary[] | undefined;\n}\n\n// one guild page, above this --all-guilds means a fetch per guild\nexport const LARGE_BOT_THRESHOLD = 200;\n\nexport type EmptyOutcome = 'all-skipped' | 'no-commands' | 'no-globals' | 'no-overlaps';\n\nexport function emptyOutcome(scan: ScanResult, purge: boolean): EmptyOutcome {\n if (scan.scannedGuildCount === 0 && scan.skipped.length > 0) return 'all-skipped';\n if (scan.scannedCommandCount === 0) return 'no-commands';\n if (!purge && scan.globalCommandCount === 0) return 'no-globals';\n return 'no-overlaps';\n}\n\n/** The wizard and the flag path share this flow through different presenters, which own all output and both confirmations. */\nexport async function executeClean(request: CleanRequest): Promise<void> {\n const { runner, scope, apply, token, presenter, knownGuilds } = request;\n\n const { appId, guilds } = await presenter.status(\n 'Connecting to Discord…',\n () => runner.resolveTargets(scope, token),\n 'Connected to Discord.'\n );\n\n if (scope.allGuilds && guilds.length > LARGE_BOT_THRESHOLD && !(await presenter.largeBotGuard(guilds.length)))\n return;\n\n const scan = await presenter.status(\n `Scanning ${plural(guilds.length, 'guild')} for commands…`,\n () => runner.scanGuilds(token, appId, overlayNames(guilds, knownGuilds), scope.purge),\n `Scanned ${plural(guilds.length, 'guild')}.`\n );\n\n if (scan.flagged.length === 0) {\n presenter.nothingToClean(scan, emptyOutcome(scan, scope.purge));\n return;\n }\n\n presenter.preview(scan);\n\n if (!apply) {\n presenter.dryRunHint();\n return;\n }\n\n if (!(await presenter.confirmDelete(scan.flagged.length, scan.skipped.length))) return;\n\n const deletion = await presenter.status(\n `Deleting ${plural(scan.flagged.length, 'guild command')}…`,\n () => runner.applyDeletions(token, appId, scan.flagged),\n 'Deletion complete.'\n );\n presenter.result(deletion, scan.skipped);\n}\n\nfunction overlayNames(guilds: GuildSummary[], knownGuilds?: GuildSummary[]): GuildSummary[] {\n if (!knownGuilds?.length) return guilds;\n const known = new Map(knownGuilds.map((guild) => [guild.id, guild.name]));\n return guilds.map((guild) => ({ id: guild.id, name: known.get(guild.id) ?? guild.name }));\n}\n","import { FlagPresenter } from './cleanPresenters';\nimport { executeClean } from './executeClean';\n\nimport type { CleanRunner } from './CleanRunner';\nimport type { ILogger } from '@seedcord/types';\n\nexport interface CleanFlags {\n guildIds: string[];\n allGuilds: boolean;\n apply: boolean;\n purge: boolean;\n yes: boolean;\n}\n\nexport async function runCleanFromFlags(\n runner: CleanRunner,\n flags: CleanFlags,\n token: string,\n logger: ILogger\n): Promise<void> {\n await executeClean({\n runner,\n scope: { guildIds: flags.guildIds, allGuilds: flags.allGuilds, purge: flags.purge },\n apply: flags.apply,\n token,\n presenter: new FlagPresenter(logger, flags.yes)\n });\n}\n","import { plural } from '#core/format';\nimport { intro, log, outro, pickFromList, select, spinner } from '#core/prompts';\n\nimport { InteractivePresenter } from './cleanPresenters';\nimport { executeClean } from './executeClean';\n\nimport type { CleanRunner, CleanScope, GuildSummary } from './CleanRunner';\n\ninterface ScopePlan {\n scope: CleanScope;\n knownGuilds?: GuildSummary[];\n}\n\nexport async function runCleanWizard(runner: CleanRunner, token: string): Promise<void> {\n intro('seedcord commands');\n\n const plan = await buildScope(runner, token);\n if (!plan) return;\n\n await executeClean({\n runner,\n scope: plan.scope,\n apply: true,\n token,\n presenter: new InteractivePresenter(),\n knownGuilds: plan.knownGuilds\n });\n}\n\nasync function buildScope(runner: CleanRunner, token: string): Promise<ScopePlan | undefined> {\n const target = await select({\n message: 'Remove guild commands that duplicate a global command. Which guilds?',\n options: [\n { value: 'pick', label: 'Pick specific guilds' },\n {\n value: 'all',\n label: 'All guilds the bot is in',\n hint: 'duplicates only, pick specific guilds for a full reset'\n }\n ]\n });\n\n // a full purge needs named guilds\n if (target === 'all') return { scope: { guildIds: [], allGuilds: true, purge: false } };\n\n const status = spinner();\n status.start('Fetching the guilds the bot is in…');\n let guilds: GuildSummary[];\n try {\n guilds = await runner.listBotGuilds(token);\n } catch (error) {\n status.stop('Could not fetch the guild list.');\n throw error;\n }\n status.stop(`Found ${plural(guilds.length, 'guild')}.`);\n\n if (guilds.length === 0) {\n outro('The bot is in no guilds.');\n return undefined;\n }\n\n let guildIds: string[];\n if (guilds.length > 1) {\n guildIds = await pickFromList({ message: 'Select guilds to clean', items: guilds });\n if (guildIds.length === 0) {\n outro('No guilds selected.');\n return undefined;\n }\n } else {\n const only = guilds[0];\n if (!only) return undefined;\n guildIds = [only.id];\n log.info(`Only one guild, using ${only.name}.`);\n }\n\n const mode = await select({\n message: 'What should I remove?',\n options: [\n { value: 'overlap', label: 'Only duplicates of a global command (recommended)' },\n { value: 'purge', label: 'Every command in these guilds (full reset)' }\n ]\n });\n\n return { scope: { guildIds, allGuilds: false, purge: mode === 'purge' }, knownGuilds: guilds };\n}\n","import { isSeedcordError, SeedcordErrorCode } from '@seedcord/errors';\nimport { validateDiscordToken } from '@seedcord/errors/internal';\nimport { Envapter } from 'envapt';\n\nimport { BaseCommand } from '#core/BaseCommand';\nimport { isInteractive } from '#core/interactive';\n\nimport { CleanRunner } from './CleanRunner';\nimport { runCleanFromFlags } from './flagClean';\nimport { runCleanWizard } from './wizard';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport interface CleanInvocation {\n clean: boolean;\n guild: string[];\n allGuilds: boolean;\n apply: boolean;\n purge: boolean;\n yes: boolean;\n}\n\nexport function hasCleanFlags(options: CleanInvocation): boolean {\n return [options.clean, options.allGuilds, options.apply, options.purge].some(Boolean) || options.guild.length > 0;\n}\n\nexport class CommandsCommand extends BaseCommand {\n private readonly cleanRunner: CleanRunner;\n\n constructor() {\n super('commands', 'Inspect and clean deployed guild commands', 'Commands');\n this.cleanRunner = CleanRunner.create();\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .option('--clean', 'Report guild commands that duplicate a global command (deletes only with --apply)')\n .option('--guild <ids...>', 'Guild ids to inspect')\n .option('--all-guilds', 'Scan every guild the bot is in (overlaps only, cannot combine with --purge)')\n .option('--apply', 'Delete the reported commands instead of running a dry run')\n .option('--purge', 'Select every command in the named guilds, not only global overlaps')\n .option('--yes', 'Skip prompts and the typed-count confirm (for scripts and CI)')\n .action(async (options) =>\n this.run({\n clean: options.clean ?? false,\n guild: options.guild ?? [],\n allGuilds: options.allGuilds ?? false,\n apply: options.apply ?? false,\n purge: options.purge ?? false,\n yes: options.yes ?? false\n })\n );\n }\n\n private async run(options: CleanInvocation): Promise<void> {\n try {\n await this.dispatch(options);\n } catch (error: unknown) {\n // a cancelled prompt exits quietly here because it's an intentional abort\n if (isSeedcordError(error, 'SeedcordError', SeedcordErrorCode.CliCancelled)) return;\n\n this.logger.error('seedcord commands failed', error);\n if (isSeedcordError(error)) process.exitCode = 1;\n else process.exit(1);\n }\n }\n\n private async dispatch(options: CleanInvocation): Promise<void> {\n const flags = hasCleanFlags(options);\n const interactive = isInteractive(options, flags);\n\n if (!interactive && !flags) {\n this.logger.info('Nothing to do. Pass --clean to inspect deployed commands.');\n return;\n }\n\n const token = validateDiscordToken(Envapter.get('DISCORD_BOT_TOKEN'));\n\n if (interactive) {\n await runCleanWizard(this.cleanRunner, token);\n return;\n }\n\n await runCleanFromFlags(\n this.cleanRunner,\n {\n guildIds: options.guild,\n allGuilds: options.allGuilds,\n apply: options.apply,\n purge: options.purge,\n yes: options.yes\n },\n token,\n this.logger\n );\n }\n}\n","import { Box } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\n// full-width flex line bracketing a block. flexShrink={0} keeps the border-only box from compressing to\n// zero height under overflow, which would land the rule on the neighbouring text line.\nexport function Rule(): ReactElement {\n return (\n <Box\n flexShrink={0}\n borderStyle=\"single\"\n borderTop\n borderBottom={false}\n borderLeft={false}\n borderRight={false}\n borderDimColor\n />\n );\n}\n","export type FilterGroup = 'channels' | 'levels';\nexport type CursorMove = 'left' | 'right' | 'switch';\n\nexport interface FilterCursor {\n readonly group: FilterGroup;\n readonly channels: number;\n readonly levels: number;\n}\n\nexport const INITIAL_CURSOR: FilterCursor = { group: 'channels', channels: 0, levels: 0 };\n\nexport function moveCursor(\n cursor: FilterCursor,\n move: CursorMove,\n channelCount: number,\n levelCount: number\n): FilterCursor {\n if (move === 'switch') {\n return { ...cursor, group: cursor.group === 'channels' ? 'levels' : 'channels' };\n }\n\n const count = cursor.group === 'channels' ? channelCount : levelCount;\n if (count === 0) return cursor;\n\n const index = cursor.group === 'channels' ? cursor.channels : cursor.levels;\n const next = move === 'right' ? (index + 1) % count : (index + count - 1) % count;\n return cursor.group === 'channels' ? { ...cursor, channels: next } : { ...cursor, levels: next };\n}\n\n// modulo, a remembered index can exceed the count after the channel list shrinks\nexport function focusedIn(cursor: FilterCursor | null, group: FilterGroup, count: number): number | null {\n if (cursor?.group !== group || count === 0) return null;\n return (group === 'channels' ? cursor.channels : cursor.levels) % count;\n}\n","import { useCallback, useSyncExternalStore } from 'react';\n\nimport type { DevState, DevStore } from '#ui/stores/DevStore';\n\nexport function useDevState(store: DevStore): DevState {\n const subscribe = useCallback(\n (onChange: () => void) => {\n store.on('change', onChange);\n return () => {\n store.off('change', onChange);\n };\n },\n [store]\n );\n const getSnapshot = useCallback(() => store.getState(), [store]);\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n","import { TypedEventEmitter } from '@seedcord/event-emitter';\nimport { LoggerChannelRegistry } from '@seedcord/logger';\nimport { formatBody } from '@seedcord/logger/node';\n\nimport type { ILogSink, LogLevel, LogRecord, LogSinkHandle } from '@seedcord/types';\n\nexport interface LogEntry {\n id: number;\n channel: string;\n level: LogLevel;\n label: string;\n text: string;\n timestamp: number;\n head: boolean;\n frame: boolean;\n}\n\nconst STACK_FRAME = /^\\s+at\\s/;\n\ninterface LogStoreEvents {\n change: [];\n}\n\n// 30ms keeps a noisy bot from re-rendering the log view once per line\nconst UPDATE_DEBOUNCE_MS = 30;\n\n// eslint-disable-next-line no-magic-numbers -- 27 is the ESC control code\nconst ESC = String.fromCharCode(27);\n\nexport class LogStore extends TypedEventEmitter<LogStoreEvents> implements ILogSink {\n private static _instance: LogStore | null = null;\n\n public readonly kind = 'capture';\n\n private entries: LogEntry[] = [];\n private buffer: LogEntry[] = [];\n private nextId = 1;\n private sinkHandle: LogSinkHandle | null = null;\n private pendingUpdate = false;\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private readonly MAX_LOGS = 1000;\n private readonly MAX_LABEL_WIDTH = 12;\n\n private constructor() {\n super();\n }\n\n public static get instance(): LogStore {\n LogStore._instance ??= new LogStore();\n return LogStore._instance;\n }\n\n public mount(): void {\n if (this.sinkHandle) return;\n this.sinkHandle = LoggerChannelRegistry.instance.installSink(this, {\n muteConsole: true\n });\n }\n\n public unmount(): void {\n if (!this.sinkHandle) return;\n this.sinkHandle.dispose();\n this.sinkHandle = null;\n }\n\n public onLog(record: LogRecord): void {\n // a lone \\r left in a row sends the terminal cursor to column 0 and overwrites what it printed, and\n // every other control char corrupts the row the same way. ESC survives because SGR colors need it.\n const lines = formatBody(record).split(/\\r\\n|\\r|\\n/);\n\n for (const [index, line] of lines.entries()) {\n const text = line.replaceAll(/\\p{Cc}/gu, (char) => (char === ESC ? char : ''));\n this.buffer.push({\n id: this.nextId++,\n channel: record.channel,\n level: record.level,\n label: record.label,\n head: index === 0,\n frame: index > 0 && STACK_FRAME.test(text),\n text,\n timestamp: record.timestamp\n });\n }\n\n this.scheduleUpdate();\n }\n\n // useSyncExternalStore needs a stable reference, so channel filtering stays in useLogs\n public getLogs(): readonly LogEntry[] {\n return this.entries;\n }\n\n // read off live entries, else the toggle list carries an empty \"default\" row\n public getChannels(): readonly string[] {\n const seen = new Set<string>();\n for (const entry of this.entries) seen.add(entry.channel);\n return [...seen].sort();\n }\n\n public getLabelWidth(): number {\n let width = 0;\n for (const entry of this.entries) if (entry.label.length > width) width = entry.label.length;\n return Math.min(width, this.MAX_LABEL_WIDTH);\n }\n\n public clear(): void {\n this.entries = [];\n this.buffer = [];\n this.emit('change');\n }\n\n // the yield gives ink one paint of the last lines before quit unmounts the ui\n public async flush(): Promise<void> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n this.applyBuffer();\n await new Promise<void>((resolve) => setImmediate(resolve));\n }\n\n private scheduleUpdate(): void {\n if (this.pendingUpdate) return;\n this.pendingUpdate = true;\n this.flushTimer = setTimeout(() => this.applyBuffer(), UPDATE_DEBOUNCE_MS);\n }\n\n private applyBuffer(): void {\n this.flushTimer = null;\n this.pendingUpdate = false;\n if (this.buffer.length === 0) return;\n\n const newEntries = [...this.entries, ...this.buffer];\n this.buffer = [];\n this.entries = newEntries.length > this.MAX_LOGS ? newEntries.slice(-this.MAX_LOGS) : newEntries;\n\n this.emit('change');\n }\n}\n","import { useCallback, useMemo, useSyncExternalStore } from 'react';\n\nimport { LogStore } from '#ui/stores/LogStore';\n\nimport type { LogEntry } from '#ui/stores/LogStore';\nimport type { LogLevel } from '@seedcord/types';\n\nconst EMPTY_CHANNELS: ReadonlySet<string> = new Set();\nconst EMPTY_LEVELS: ReadonlySet<LogLevel> = new Set();\n\n// empty set means all, so a channel or level that appears later stays visible by default\nexport function filterLogs(\n logs: readonly LogEntry[],\n channels: ReadonlySet<string>,\n levels: ReadonlySet<LogLevel>\n): readonly LogEntry[] {\n const allChannels = channels.size === 0;\n const allLevels = levels.size === 0;\n if (allChannels && allLevels) return logs;\n return logs.filter((log) => (allChannels || channels.has(log.channel)) && (allLevels || levels.has(log.level)));\n}\n\n// `channels`/`levels` must be stable references between unchanged renders (the shell holds them in state), or\n// the memo recomputes every render.\nexport function useLogs(channels?: ReadonlySet<string>, levels?: ReadonlySet<LogLevel>): readonly LogEntry[] {\n const store = LogStore.instance;\n\n const subscribe = useCallback(\n (cb: () => void) => {\n store.on('change', cb);\n return () => {\n store.off('change', cb);\n };\n },\n [store]\n );\n\n const getSnapshot = useCallback(() => store.getLogs(), [store]);\n\n const allLogs = useSyncExternalStore(subscribe, getSnapshot);\n\n return useMemo(\n () => filterLogs(allLogs, channels ?? EMPTY_CHANNELS, levels ?? EMPTY_LEVELS),\n [allLogs, channels, levels]\n );\n}\n","import { measureElement } from 'ink';\nimport { useLayoutEffect, useState } from 'react';\n\nimport type { DOMElement } from 'ink';\nimport type { RefObject } from 'react';\n\nexport interface MeasuredBox {\n readonly width: number;\n readonly height: number;\n}\n\nconst UNMEASURED: MeasuredBox = { width: 0, height: 0 };\n\nexport function useMeasuredBox(ref: RefObject<DOMElement | null>): MeasuredBox {\n const [box, setBox] = useState<MeasuredBox>(UNMEASURED);\n\n // eslint-disable-next-line @eslint-react/exhaustive-deps, react-hooks/exhaustive-deps -- the measured size can change on any render, so no dep list covers it\n useLayoutEffect(() => {\n if (!ref.current) return;\n const { width, height } = measureElement(ref.current);\n // eslint-disable-next-line @eslint-react/set-state-in-effect -- Ink measures only after render, and the equality bail stops the update chain\n setBox((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));\n });\n\n return box;\n}\n","import { measureElement } from 'ink';\nimport { useLayoutEffect, useRef, useState } from 'react';\n\nimport type { DevPhase } from '#ui/stores/devPhase';\nimport type { DOMElement } from 'ink';\nimport type { RefObject } from 'react';\n\n// held until the next restart so the rail doesn't resize mid-stream\nexport function useRailWidth(\n railRef: RefObject<DOMElement | null>,\n phase: DevPhase,\n rows: number,\n columns: number\n): number | null {\n const [railWidth, setRailWidth] = useState<number | null>(null);\n const needsMeasureRef = useRef(true);\n\n useLayoutEffect(() => {\n if (phase !== 'running') {\n needsMeasureRef.current = true;\n // drop the lock too, because a rail still constrained by it would measure back the old width\n // eslint-disable-next-line @eslint-react/set-state-in-effect, react-hooks/set-state-in-effect -- see the measurement set below\n setRailWidth(null);\n return;\n }\n if (!needsMeasureRef.current || !railRef.current) return;\n const measured = measureElement(railRef.current).width;\n if (measured > 0) {\n needsMeasureRef.current = false;\n // eslint-disable-next-line @eslint-react/set-state-in-effect -- rail width comes from measuring the rendered element, set once per run\n setRailWidth(measured);\n }\n }, [rows, columns, phase, railRef]);\n\n return railWidth;\n}\n","import { useState } from 'react';\n\nexport interface ScrollApi<Item> {\n // oldest first, consumers render in array order\n readonly visible: readonly Item[];\n readonly following: boolean;\n readonly atTop: boolean;\n readonly above: number;\n readonly below: number;\n readonly up: (lines?: number) => void;\n readonly down: (lines?: number) => void;\n readonly pageUp: () => void;\n readonly pageDown: () => void;\n readonly toTop: () => void;\n readonly toBottom: () => void;\n}\n\ntype ScrollKey = number | string;\n\ninterface ScrollView<Item> {\n readonly visible: readonly Item[];\n readonly topIndex: number;\n readonly following: boolean;\n readonly atTop: boolean;\n readonly above: number;\n readonly below: number;\n}\n\n// a null anchor follows the newest line. a key anchor pins the top row to that entry's current index, so\n// the visible lines stay put while LogStore trims its head or appends. a trimmed-away anchor falls back to\n// the oldest line.\nexport function computeScrollView<Item>(\n items: readonly Item[],\n viewportHeight: number,\n anchor: ScrollKey | null,\n getKey: (item: Item) => ScrollKey\n): ScrollView<Item> {\n const height = Math.max(1, viewportHeight);\n const len = items.length;\n const maxTop = Math.max(0, len - height);\n\n let topIndex: number;\n if (anchor === null) {\n topIndex = maxTop;\n } else {\n const found = items.findIndex((item) => getKey(item) === anchor);\n topIndex = found === -1 ? 0 : found;\n }\n topIndex = Math.min(Math.max(0, topIndex), maxTop);\n\n const visible = items.slice(topIndex, topIndex + height);\n return {\n visible,\n topIndex,\n following: anchor === null || topIndex >= maxTop,\n atTop: topIndex === 0,\n above: topIndex,\n below: len - (topIndex + visible.length)\n };\n}\n\nexport function useScroll<Item>(\n items: readonly Item[],\n viewportHeight: number,\n getKey: (item: Item) => ScrollKey\n): ScrollApi<Item> {\n const [anchor, setAnchor] = useState<ScrollKey | null>(null);\n\n const height = Math.max(1, viewportHeight);\n const maxTop = Math.max(0, items.length - height);\n const view = computeScrollView(items, viewportHeight, anchor, getKey);\n\n const anchorAt = (nextTop: number): void => {\n const clamped = Math.min(Math.max(0, nextTop), maxTop);\n if (clamped >= maxTop) {\n setAnchor(null);\n return;\n }\n const entry = items[clamped];\n setAnchor(entry === undefined ? null : getKey(entry));\n };\n\n const up = (lines = 1): void => anchorAt(view.topIndex - lines);\n const down = (lines = 1): void => anchorAt(view.topIndex + lines);\n\n return {\n visible: view.visible,\n following: view.following,\n atTop: view.atTop,\n above: view.above,\n below: view.below,\n up,\n down,\n pageUp: () => up(height - 1),\n pageDown: () => down(height - 1),\n toTop: () => {\n const oldest = items[0];\n setAnchor(oldest === undefined ? null : getKey(oldest));\n },\n toBottom: () => setAnchor(null)\n };\n}\n","// truecolor palette for the dev-TUI's own chrome (headings, hotkeys, status), so it renders the same\n// across terminals. the bot's log lines carry their own colors\nexport const ui = {\n accent: '#7dcfff',\n muted: '#9aa0b3',\n faint: '#565c6b',\n good: '#9ece6a',\n warn: '#e0af68',\n bad: '#f7768e'\n} as const;\n","import { ui } from '#ui/palette';\n\nimport type { TextProps } from 'ink';\n\nexport type DevPhase = 'starting' | 'running' | 'restart-required' | 'disconnected' | 'error' | 'quitting';\n\n// disconnect only applies while a session is running. the other phases have nothing to stop.\nexport function isSessionLive(phase: DevPhase): boolean {\n return phase === 'running' || phase === 'restart-required';\n}\n\n// up and emitting logs (restart-required is up but stale), which is what the live dot blinks for\nexport function isStreaming(phase: DevPhase): boolean {\n return phase === 'starting' || phase === 'running' || phase === 'restart-required';\n}\n\n// spinner runs once, arc loops\ntype PhaseGlyph = 'spinner' | 'arc' | 'static';\n\nexport interface PhaseMeta {\n readonly label: string;\n readonly icon: string;\n readonly color: TextProps['color'];\n readonly kind: PhaseGlyph;\n}\n\nexport const PHASE_META = {\n starting: { label: 'starting', icon: '◐', color: ui.accent, kind: 'spinner' },\n running: { label: 'running', icon: '●', color: ui.good, kind: 'arc' },\n 'restart-required': { label: 'restart required', icon: '◆', color: ui.warn, kind: 'static' },\n disconnected: { label: 'offline', icon: '○', color: ui.muted, kind: 'static' },\n error: { label: 'error', icon: '✘', color: ui.bad, kind: 'static' },\n quitting: { label: 'quitting', icon: '◐', color: ui.muted, kind: 'spinner' }\n} as const satisfies Record<DevPhase, PhaseMeta>;\n","import { useAnimation } from 'ink';\n\nimport { isSessionLive } from '#ui/stores/devPhase';\n\nimport type { DevState } from '#ui/stores/DevStore';\n\nconst TICK_MS = 1000;\n\n// ink's useAnimation resets time to 0 on reactivation, so it restarts each run and keeps counting across restart-required\nexport function useUptime(state: DevState, shown: boolean): number | null {\n const active = isSessionLive(state.phase) && shown;\n const { time } = useAnimation({ interval: TICK_MS, isActive: active });\n return active ? time : null;\n}\n","// stable first-seen assignment keeps a channel's tag matched to its filter chip. red is reserved for errors and the live dot, so it stays out of the palette.\nconst PALETTE = [\n '#ff8a3d',\n '#ff6a4d',\n '#f5b52a',\n '#d9d641',\n '#a3d93a',\n '#5fc95a',\n '#35c98a',\n '#2fbfa0',\n '#23b5c9',\n '#3d9ff0',\n '#3d8ef0',\n '#5a7bff',\n '#6d6ff0',\n '#9a6cf0',\n '#b85cf0',\n '#c96cf0',\n '#e05cd0',\n '#f062c0',\n '#ff5f9e',\n '#ff6b6b'\n] as const;\n\nconst assigned = new Map<string, string>();\n\nexport function channelColor(channel: string): string {\n const existing = assigned.get(channel);\n if (existing !== undefined) return existing;\n\n const color = PALETTE[assigned.size % PALETTE.length] ?? PALETTE[0];\n assigned.set(channel, color);\n return color;\n}\n\n// clearing here keeps stale channels from skewing the next session's colors\nexport function resetChannelColors(): void {\n assigned.clear();\n}\n","import { LEVEL_COLOR } from '@seedcord/logger';\nimport { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { channelColor } from '#ui/channelColor';\nimport { focusedIn } from '#ui/filterCursor';\nimport { ui } from '#ui/palette';\n\nimport type { FilterCursor } from '#ui/filterCursor';\nimport type { LogLevel } from '@seedcord/types';\nimport type { ReactElement } from 'react';\n\nexport const FILTER_LEVELS: readonly LogLevel[] = ['error', 'warn', 'info', 'debug', 'trace'];\n\ninterface FilterChipsProps {\n readonly channels: readonly string[];\n readonly enabledChannels: ReadonlySet<string>;\n readonly enabledLevels: ReadonlySet<LogLevel>;\n readonly cursor: FilterCursor | null;\n readonly open: boolean;\n}\n\nfunction Heading({ label, open }: { label: string; open: boolean }): ReactElement {\n return (\n <Text>\n <Text color={ui.accent} bold>\n {open ? '▾' : '▸'}\n </Text>\n <Text color={ui.muted}> {label}</Text>\n </Text>\n );\n}\n\nfunction Chip({\n label,\n on,\n color,\n focused\n}: {\n label: string;\n on: boolean;\n color: string;\n focused: boolean;\n}): ReactElement {\n return (\n <Box marginRight={1}>\n {on ? (\n <Text color={color} bold={focused} underline={focused}>\n {label}\n </Text>\n ) : (\n <Text dimColor bold={focused} underline={focused}>\n {label}\n </Text>\n )}\n </Box>\n );\n}\n\nexport function FilterChips({\n channels,\n enabledChannels,\n enabledLevels,\n cursor,\n open\n}: FilterChipsProps): ReactElement {\n const allChannels = enabledChannels.size === 0;\n const allLevels = enabledLevels.size === 0;\n const channelFocus = focusedIn(cursor, 'channels', channels.length);\n const levelFocus = focusedIn(cursor, 'levels', FILTER_LEVELS.length);\n\n return (\n <Box flexDirection=\"column\">\n {open ? null : (\n <Text dimColor wrap=\"truncate\">\n resize to see filters\n </Text>\n )}\n <Heading label=\"channels\" open={open} />\n {open ? (\n <Box marginLeft={2} flexWrap=\"wrap\">\n {channels.map((channel, index) => (\n <Chip\n key={channel}\n label={channel}\n on={allChannels || enabledChannels.has(channel)}\n color={channelColor(channel)}\n focused={channelFocus === index}\n />\n ))}\n </Box>\n ) : null}\n\n <Heading label=\"levels\" open={open} />\n {open ? (\n <Box marginLeft={2} flexWrap=\"wrap\">\n {FILTER_LEVELS.map((level, index) => (\n <Chip\n key={level}\n label={level}\n on={allLevels || enabledLevels.has(level)}\n color={LEVEL_COLOR[level]}\n focused={levelFocus === index}\n />\n ))}\n </Box>\n ) : null}\n </Box>\n );\n}\n","import { FILTER_LEVELS } from '#ui/components/primitives/FilterChips';\nimport { focusedIn, moveCursor } from '#ui/filterCursor';\nimport { isSessionLive } from '#ui/stores/devPhase';\nimport { LogStore } from '#ui/stores/LogStore';\n\nimport type { CursorMove, FilterCursor } from '#ui/filterCursor';\nimport type { ScrollApi } from '#ui/hooks/useScroll';\nimport type { LogRow } from '#ui/logRows';\nimport type { DevState, DevStore } from '#ui/stores/DevStore';\nimport type { LogLevel } from '@seedcord/types';\nimport type { Key } from 'ink';\n\n// empty set means all. toggling every channel on collapses back to empty, keeping later channels visible by default\nfunction toggleChannel(prev: ReadonlySet<string>, channel: string, all: readonly string[]): ReadonlySet<string> {\n const base = prev.size === 0 ? new Set(all) : new Set(prev);\n if (base.has(channel)) base.delete(channel);\n else base.add(channel);\n return base.size === all.length ? new Set<string>() : base;\n}\n\nfunction toggleLevel(prev: ReadonlySet<LogLevel>, level: LogLevel): ReadonlySet<LogLevel> {\n const base = prev.size === 0 ? new Set(FILTER_LEVELS) : new Set(prev);\n if (base.has(level)) base.delete(level);\n else base.add(level);\n return base.size === FILTER_LEVELS.length ? new Set<LogLevel>() : base;\n}\n\n// re-soloing the soloed item restores all (empty set = all)\nfunction soloChannel(prev: ReadonlySet<string>, channel: string): ReadonlySet<string> {\n return prev.size === 1 && prev.has(channel) ? new Set<string>() : new Set([channel]);\n}\n\nfunction soloLevel(prev: ReadonlySet<LogLevel>, level: LogLevel): ReadonlySet<LogLevel> {\n return prev.size === 1 && prev.has(level) ? new Set<LogLevel>() : new Set([level]);\n}\n\ninterface HotkeyContext {\n readonly input: string;\n readonly key: Key;\n readonly state: DevState;\n readonly interactive: boolean;\n readonly scroll: ScrollApi<LogRow>;\n readonly store: DevStore;\n readonly enabled: ReadonlySet<string>;\n readonly setEnabled: (next: ReadonlySet<string>) => void;\n readonly enabledLevels: ReadonlySet<LogLevel>;\n readonly setEnabledLevels: (next: ReadonlySet<LogLevel>) => void;\n readonly cursor: FilterCursor;\n readonly setCursor: (next: FilterCursor) => void;\n readonly filtersOpen: boolean;\n readonly onQuit?: (() => Promise<void> | void) | undefined;\n readonly onDisconnect?: (() => Promise<void> | void) | undefined;\n readonly onRestart?: (() => Promise<void> | void) | undefined;\n readonly onRefreshCommands?: ((shouldRefresh: boolean) => Promise<void> | void) | undefined;\n}\n\nfunction quit(ctx: HotkeyContext): void {\n ctx.store.beginQuit();\n void ctx.onQuit?.();\n}\n\n// ink puts stdin in raw mode, so ctrl-c arrives as a plain keypress with no sigint\nfunction handleQuitSignal(ctx: HotkeyContext): boolean {\n if (!ctx.key.ctrl || ctx.input !== 'c') return false;\n\n if (ctx.state.quitArmed) quit(ctx);\n else ctx.store.setQuitArmed(true);\n return true;\n}\n\nfunction handlePrompt(ctx: HotkeyContext): boolean {\n if (!ctx.state.commandUpdatePrompt) return false;\n if (ctx.input === 'y') {\n void ctx.onRefreshCommands?.(true);\n ctx.store.clearPrompt();\n } else if (ctx.input === 'n') {\n void ctx.onRefreshCommands?.(false);\n ctx.store.clearPrompt();\n }\n return true;\n}\n\nfunction applyAtCursor(\n ctx: HotkeyContext,\n channels: readonly string[],\n onChannel: (prev: ReadonlySet<string>, channel: string, all: readonly string[]) => ReadonlySet<string>,\n onLevel: (prev: ReadonlySet<LogLevel>, level: LogLevel) => ReadonlySet<LogLevel>\n): void {\n if (ctx.cursor.group === 'channels') {\n const index = focusedIn(ctx.cursor, 'channels', channels.length);\n const channel = index === null ? undefined : channels[index];\n if (channel !== undefined) ctx.setEnabled(onChannel(ctx.enabled, channel, channels));\n return;\n }\n const index = focusedIn(ctx.cursor, 'levels', FILTER_LEVELS.length);\n const level = index === null ? undefined : FILTER_LEVELS[index];\n if (level !== undefined) ctx.setEnabledLevels(onLevel(ctx.enabledLevels, level));\n}\n\nfunction handleFilters(ctx: HotkeyContext): boolean {\n if (!ctx.filtersOpen) return false;\n\n const channels = LogStore.instance.getChannels();\n const move = (dir: CursorMove): void =>\n ctx.setCursor(moveCursor(ctx.cursor, dir, channels.length, FILTER_LEVELS.length));\n\n if (ctx.key.leftArrow) move('left');\n else if (ctx.key.rightArrow) move('right');\n else if (ctx.key.tab) move('switch');\n else if (ctx.input === ' ') applyAtCursor(ctx, channels, soloChannel, soloLevel);\n else if (ctx.input === 'o') applyAtCursor(ctx, channels, toggleChannel, toggleLevel);\n else return false;\n return true;\n}\n\nfunction handleScroll(ctx: HotkeyContext): boolean {\n // runs before session actions so scroll works even when non-interactive\n const { key, input, scroll } = ctx;\n if (key.upArrow) scroll.up();\n else if (key.downArrow) scroll.down();\n else if (key.pageUp) scroll.pageUp();\n else if (key.pageDown) scroll.pageDown();\n else if (key.home || input === 't') scroll.toTop();\n else if (key.end || input === 'b') scroll.toBottom();\n else return false;\n return true;\n}\n\nfunction handleActions(ctx: HotkeyContext): void {\n const { input, state, store } = ctx;\n\n if (input === 'q') {\n quit(ctx);\n return;\n }\n if (!ctx.interactive) return;\n\n switch (input) {\n case 'd': {\n if (!isSessionLive(state.phase)) return;\n store.beginDisconnect();\n void ctx.onDisconnect?.();\n\n break;\n }\n case 'r': {\n store.beginRestart();\n void ctx.onRestart?.();\n\n break;\n }\n case 'c': {\n LogStore.instance.clear();\n ctx.scroll.toBottom();\n\n break;\n }\n // No default\n }\n}\n\n// dispatch checks the prompt before filters. an open y/n prompt would otherwise lose keys to filter hotkeys\nexport function dispatchHotkey(ctx: HotkeyContext): void {\n if (handleQuitSignal(ctx)) return;\n if (ctx.state.quitArmed) ctx.store.setQuitArmed(false);\n if (handlePrompt(ctx)) return;\n if (handleFilters(ctx)) return;\n if (handleScroll(ctx)) return;\n handleActions(ctx);\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\ninterface LogHeaderProps {\n readonly following: boolean;\n readonly below: number;\n}\n\nexport function LogHeader({ following, below }: LogHeaderProps): ReactElement | null {\n if (following) return null;\n return (\n <Box flexShrink={0}>\n <Text color={ui.warn} wrap=\"truncate\">{`▲ scrolled · ${below} newer below · b to follow`}</Text>\n </Box>\n );\n}\n","import { Box } from 'ink';\nimport React, { Fragment } from 'react';\n\nimport type { Notice } from '#ui/notices';\nimport type { ReactElement } from 'react';\n\ninterface NotificationStackProps {\n readonly notices: readonly Notice[];\n}\n\nexport function NotificationStack({ notices }: NotificationStackProps): ReactElement | null {\n if (notices.length === 0) return null;\n\n return (\n <Box flexShrink={0} flexDirection=\"column\">\n {notices.map((notice) => (\n <Fragment key={notice.key}>{notice.card}</Fragment>\n ))}\n </Box>\n );\n}\n","const MS_PER_SECOND = 1000;\nconst SECONDS_PER_MINUTE = 60;\nconst MINUTES_PER_HOUR = 60;\n\nfunction pad(value: number): string {\n return value.toString().padStart(2, '0');\n}\n\nexport function formatUptime(ms: number): string {\n const totalSeconds = Math.max(0, Math.floor(ms / MS_PER_SECOND));\n const seconds = totalSeconds % SECONDS_PER_MINUTE;\n const totalMinutes = Math.floor(totalSeconds / SECONDS_PER_MINUTE);\n const minutes = totalMinutes % MINUTES_PER_HOUR;\n const hours = Math.floor(totalMinutes / MINUTES_PER_HOUR);\n\n if (hours > 0) return `${hours}h ${pad(minutes)}m ${pad(seconds)}s`;\n if (minutes > 0) return `${minutes}m ${pad(seconds)}s`;\n return `${seconds}s`;\n}\n\n// local time\nexport function formatClock(ts: number): string {\n const d = new Date(ts);\n return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;\n}\n","import wrapAnsi from 'wrap-ansi';\n\nimport type { LogEntry } from '#ui/stores/LogStore';\n\nconst CHIP_WIDTH = 3;\nconst TIME_WIDTH = 8;\nconst DOT_WIDTH = 1;\nconst BAR_WIDTH = 1;\nconst MIN_TEXT_WIDTH = 8;\n\nexport const messageColumn = (labelWidth: number): number =>\n CHIP_WIDTH + 1 + TIME_WIDTH + 1 + labelWidth + 1 + DOT_WIDTH + 1;\n\n// one row per rendered line, which the viewport math uses\nexport type LogRow =\n { kind: 'entry'; key: string; entry: LogEntry; text: string; first: boolean } | { kind: 'rule'; key: string };\n\nfunction isBlockLine(entry: LogEntry | undefined): boolean {\n return entry !== undefined && entry.level !== 'error';\n}\n\nfunction opensBlock(logs: readonly LogEntry[], index: number): boolean {\n const log = logs[index];\n const next = logs[index + 1];\n return log?.head === true && isBlockLine(log) && next !== undefined && !next.head && isBlockLine(next);\n}\n\nfunction closesBlock(logs: readonly LogEntry[], index: number): boolean {\n const log = logs[index];\n const next = logs[index + 1];\n return log !== undefined && !log.head && isBlockLine(log) && (next === undefined || next.head);\n}\n\n// adjacent blocks share one rule, because the block above already drew its bottom\nfunction prevClosedBlock(logs: readonly LogEntry[], index: number): boolean {\n const prev = logs[index - 1];\n return prev !== undefined && !prev.head && isBlockLine(prev);\n}\n\nexport function expandRows(logs: readonly LogEntry[]): LogRow[] {\n const rows: LogRow[] = [];\n for (const [index, entry] of logs.entries()) {\n if (opensBlock(logs, index) && !prevClosedBlock(logs, index)) {\n rows.push({ kind: 'rule', key: `top-${entry.id}` });\n }\n rows.push({ kind: 'entry', key: String(entry.id), entry, text: entry.text, first: true });\n if (closesBlock(logs, index)) rows.push({ kind: 'rule', key: `bottom-${entry.id}` });\n }\n return rows;\n}\n\n// the gutters mirror what ScrollableLogView draws in front of each line\nfunction textWidth(entry: LogEntry, width: number, labelWidth: number): number {\n const gutter = !entry.head && entry.level === 'error' ? BAR_WIDTH : messageColumn(labelWidth);\n return width - gutter;\n}\n\nexport function wrapRows(rows: readonly LogRow[], width: number, labelWidth: number): LogRow[] {\n return rows.flatMap((row) => {\n if (row.kind === 'rule') return row;\n\n const available = textWidth(row.entry, width, labelWidth);\n // nothing left to wrap into at this width, and the render truncates\n if (available < MIN_TEXT_WIDTH) return row;\n\n // trim would strip a stack frame's leading indentation\n const lines = wrapAnsi(row.text, available, { hard: true, trim: false }).split('\\n');\n return lines.map((text, index) => ({\n kind: 'entry' as const,\n key: `${row.key}:${String(index)}`,\n entry: row.entry,\n // the wrap break leaves a leading space that would misalign the tail\n text: index === 0 ? text : text.replace(/^ +/, ''),\n first: index === 0\n }));\n });\n}\n\nexport function rowKey(row: LogRow): number | string {\n return row.key;\n}\n","import { LEVEL_COLOR } from '@seedcord/logger';\nimport { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { channelColor } from '#ui/channelColor';\nimport { Rule } from '#ui/components/primitives/Rule';\nimport { formatClock } from '#ui/format';\nimport { messageColumn } from '#ui/logRows';\nimport { ui } from '#ui/palette';\nimport { LogStore } from '#ui/stores/LogStore';\n\nimport type { LogRow } from '#ui/logRows';\nimport type { LogEntry } from '#ui/stores/LogStore';\nimport type { LogLevel } from '@seedcord/types';\nimport type { ReactElement } from 'react';\n\nconst MIN_LOG_LINES = 5; // fits an error head plus a few stack frames\n\nexport const NO_ROOM = 'Need more room for logs.';\nconst DOT = '●';\nconst BAR = '▌';\nconst GUIDE = '│';\nconst ELLIPSIS = '…';\nconst CHIP_TEXT = '#1a1a1a';\n\nconst LEVEL_LETTER: Record<LogLevel, string> = { error: 'E', warn: 'W', info: 'I', debug: 'D', trace: 'T' };\n\nconst WASH: Partial<Record<LogLevel, string>> = { warn: '#3a2f14', error: '#3d1a20' };\n\nfunction truncate(label: string, width: number): string {\n return label.length > width ? `${label.slice(0, width - 1)}${ELLIPSIS}` : label;\n}\n\nfunction Chip({ level }: { level: LogLevel }): ReactElement {\n return (\n <Text backgroundColor={LEVEL_COLOR[level]} color={CHIP_TEXT} bold>\n {` ${LEVEL_LETTER[level]} `}\n </Text>\n );\n}\n\nfunction Prefix({ log, labelWidth }: { log: LogEntry; labelWidth: number }): ReactElement {\n const label = truncate(log.label, labelWidth).padStart(labelWidth);\n return (\n <>\n <Chip level={log.level} /> <Text dimColor>{formatClock(log.timestamp)}</Text> <Text>{label}</Text>{' '}\n <Text color={channelColor(log.channel)}>{DOT}</Text>\n </>\n );\n}\n\ninterface LineProps {\n readonly log: LogEntry;\n readonly text: string;\n readonly labelWidth: number;\n}\n\nfunction HeadLine({ log, text, labelWidth }: LineProps): ReactElement {\n const wash = WASH[log.level];\n\n if (wash) {\n return (\n <Text wrap=\"truncate\">\n <Text backgroundColor={wash}>\n <Prefix log={log} labelWidth={labelWidth} />\n </Text>{' '}\n {text}\n </Text>\n );\n }\n\n return (\n <Text wrap=\"truncate\">\n <Prefix log={log} labelWidth={labelWidth} /> {text}\n </Text>\n );\n}\n\nfunction HeadTail({ text, labelWidth }: Omit<LineProps, 'log'>): ReactElement {\n return (\n <Text wrap=\"truncate\">\n {' '.repeat(messageColumn(labelWidth) - 2)}\n <Text dimColor>{GUIDE}</Text> {text}\n </Text>\n );\n}\n\nfunction ContinuationLine({ log, text, labelWidth }: LineProps): ReactElement {\n if (log.level === 'error') {\n return (\n <Text wrap=\"truncate\">\n <Text color={LEVEL_COLOR.error} bold>\n {BAR}\n </Text>\n <Text dimColor={log.frame}>{text}</Text>\n </Text>\n );\n }\n\n return (\n <Text wrap=\"truncate\">\n {' '.repeat(messageColumn(labelWidth) - 2)}\n <Text dimColor>{GUIDE}</Text> {text}\n </Text>\n );\n}\n\ninterface ScrollableLogViewProps {\n readonly visible: readonly LogRow[];\n readonly viewportHeight: number;\n // an unmeasured height would flash \"too small\" on the first frame\n readonly measured: boolean;\n}\n\nexport function ScrollableLogView({ visible, viewportHeight, measured }: ScrollableLogViewProps): ReactElement | null {\n if (!measured) return null;\n\n if (viewportHeight < MIN_LOG_LINES) {\n return (\n <Box flexGrow={1} alignItems=\"center\" justifyContent=\"center\" overflow=\"hidden\">\n <Text color={ui.warn} bold wrap=\"truncate\">\n {NO_ROOM}\n </Text>\n </Box>\n );\n }\n\n const labelWidth = Math.max(1, LogStore.instance.getLabelWidth());\n\n return (\n // flex-end keeps the newest line on the bottom edge even when the buffer is nearly empty\n <Box flexDirection=\"column\" flexGrow={1} justifyContent=\"flex-end\" overflow=\"hidden\">\n {visible.length === 0 ? (\n <Text dimColor>Waiting for logs…</Text>\n ) : (\n visible.map((row) => {\n if (row.kind === 'rule') return <Rule key={row.key} />;\n const props = { log: row.entry, text: row.text, labelWidth };\n // a continuation draws its gutter on every row\n if (!row.entry.head) return <ContinuationLine key={row.key} {...props} />;\n return row.first ? <HeadLine key={row.key} {...props} /> : <HeadTail key={row.key} {...props} />;\n })\n )}\n </Box>\n );\n}\n","import { BRAND } from '@seedcord/errors/internal';\nimport { Text } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\ninterface BannerProps {\n readonly version: string | null;\n}\n\nexport function Banner({ version }: BannerProps): ReactElement {\n return (\n <Text>\n <Text bold color={BRAND.flesh}>\n seed\n </Text>\n <Text bold color={BRAND.rind}>\n cord\n </Text>\n {version === null ? null : <Text color={BRAND.pith}> • v{version}</Text>}\n </Text>\n );\n}\n","import { Text, useAnimation } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\nconst BLINK_MS = 530;\n\nexport function BlinkDot({ animate = true }: { readonly animate?: boolean }): ReactElement {\n const { frame } = useAnimation({ interval: BLINK_MS, isActive: animate });\n const lit = !animate || frame % 2 === 0;\n\n return <Text color={ui.bad}>{lit ? '●' : ' '}</Text>;\n}\n","import { Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport React from 'react';\n\nimport { isStreaming, PHASE_META } from '#ui/stores/devPhase';\n\nimport { BlinkDot } from './primitives/BlinkDot';\n\nimport type { DevPhase } from '#ui/stores/devPhase';\nimport type { ReactElement } from 'react';\n\ninterface StatusBadgeProps {\n readonly phase: DevPhase;\n readonly glyph?: 'phase' | 'live';\n readonly animate?: boolean;\n}\n\nfunction Glyph({ phase, glyph, animate }: Required<StatusBadgeProps>): ReactElement {\n const meta = PHASE_META[phase];\n if (glyph === 'live') return isStreaming(phase) ? <BlinkDot animate={animate} /> : <Text>{meta.icon}</Text>;\n // ink-spinner keeps its frame index across a type swap and wraps on equality, so a 7-frame\n // index carried into a 4-frame set renders nothing forever. The key forces a fresh mount.\n if (meta.kind === 'spinner') return <Spinner key=\"balloon2\" type=\"balloon2\" />;\n // the arc runs for as long as the bot does\n if (meta.kind === 'arc' && animate) return <Spinner key=\"toggle4\" type=\"toggle4\" />;\n return <Text>{meta.icon}</Text>;\n}\n\nexport function StatusBadge({ phase, glyph = 'phase', animate = true }: StatusBadgeProps): ReactElement {\n const meta = PHASE_META[phase];\n return (\n <Text color={meta.color} bold>\n <Glyph phase={phase} glyph={glyph} animate={animate} /> {meta.label}\n </Text>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\nimport { isSessionLive } from '#ui/stores/devPhase';\n\nimport type { DevPhase } from '#ui/stores/devPhase';\nimport type { ReactElement } from 'react';\n\ninterface HotkeyProps {\n readonly keyLabel: string;\n readonly action: string;\n readonly enabled?: boolean;\n readonly highlight?: boolean;\n}\n\nfunction Hotkey({ keyLabel, action, enabled = true, highlight = false }: HotkeyProps): ReactElement {\n const keyColor = !enabled ? ui.faint : highlight ? ui.warn : ui.accent;\n const actionColor = enabled ? ui.muted : ui.faint;\n return (\n <Box marginRight={2}>\n <Text color={keyColor} bold>\n {keyLabel}\n </Text>\n <Text color={actionColor}> {action}</Text>\n </Box>\n );\n}\n\nconst RESTART_HINT_PHASES = new Set<DevPhase>(['restart-required', 'disconnected', 'error']);\n\ninterface SessionKeysProps {\n readonly phase: DevPhase;\n readonly interactive: boolean;\n readonly following: boolean;\n}\n\nexport function SessionKeys({ phase, interactive, following }: SessionKeysProps): ReactElement {\n return (\n <Box flexDirection=\"column\">\n <Hotkey keyLabel=\"q\" action=\"quit\" />\n <Hotkey keyLabel=\"r\" action=\"restart\" enabled={interactive} highlight={RESTART_HINT_PHASES.has(phase)} />\n <Hotkey keyLabel=\"d\" action=\"disconnect\" enabled={interactive && isSessionLive(phase)} />\n <Hotkey keyLabel=\"c\" action=\"clear\" enabled={interactive} />\n <Hotkey keyLabel=\"↑↓\" action=\"scroll\" />\n <Hotkey keyLabel=\"t/b\" action=\"top/bottom\" highlight={!following} />\n </Box>\n );\n}\n\nexport function FilterKeys(): ReactElement {\n return (\n <Box flexDirection=\"column\">\n <Hotkey keyLabel=\"←→\" action=\"select\" />\n <Hotkey keyLabel=\"tab\" action=\"group\" />\n <Hotkey keyLabel=\"space\" action=\"filter\" />\n <Hotkey keyLabel=\"o\" action=\"toggle\" />\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { version } from '#core/version';\nimport { formatUptime } from '#ui/format';\nimport { isStreaming } from '#ui/stores/devPhase';\nimport { LogStore } from '#ui/stores/LogStore';\n\nimport { Banner } from '../Banner';\nimport { StatusBadge } from '../StatusBadge';\nimport { BlinkDot } from './BlinkDot';\nimport { FilterChips } from './FilterChips';\nimport { FilterKeys, SessionKeys } from './Hotkeys';\nimport { Rule } from './Rule';\n\nimport type { TunnelStatus } from '#commands/dev/tunnel/TunnelCoordinator';\nimport type { FilterCursor } from '#ui/filterCursor';\nimport type { DevState, DevTransport } from '#ui/stores/DevStore';\nimport type { LogLevel } from '@seedcord/types';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement, Ref } from 'react';\n\nexport const MAX_RAIL = 40;\n\n// the widest label is 'gateway' at 7\nconst META_LABEL_WIDTH = 8;\n\nconst LOG_DIR = 'logs/'; // the dev default writes one combined file into this folder\n\ninterface SidebarProps {\n readonly state: DevState;\n readonly enabled: ReadonlySet<string>;\n readonly enabledLevels: ReadonlySet<LogLevel>;\n readonly uptimeMs: number | null;\n readonly following: boolean;\n readonly interactive: boolean;\n readonly cursor: FilterCursor;\n readonly width: number | null;\n readonly filtersOpen: boolean;\n readonly ref?: Ref<DOMElement>;\n}\n\nfunction Meta({ label, value }: { label: string; value: string }): ReactElement {\n return (\n <Text>\n <Text dimColor>{label.padEnd(META_LABEL_WIDTH)}</Text>\n {value}\n </Text>\n );\n}\n\nfunction tunnelValue(status: TunnelStatus): string {\n return status === 'live' || status === 'lost' ? status : `${status}…`;\n}\n\nfunction transportLabel({ name }: DevTransport): string {\n return name.replace('@seedcord/', '');\n}\n\nfunction StatusBlock({ state, uptimeMs }: { state: DevState; uptimeMs: number | null }): ReactElement {\n return (\n <Box flexDirection=\"column\">\n <StatusBadge phase={state.phase} animate={state.idleAnimation} />\n {state.status ? <Text>{state.status}</Text> : null}\n {state.transport === null ? null : (\n <Meta label={transportLabel(state.transport)} value={`v${state.transport.version}`} />\n )}\n {uptimeMs === null ? null : <Meta label=\"up\" value={formatUptime(uptimeMs)} />}\n {/* only the http host reports a port */}\n {state.port === null ? null : <Meta label=\"port\" value={String(state.port)} />}\n {state.tunnel === null ? null : <Meta label=\"tunnel\" value={tunnelValue(state.tunnel)} />}\n <Meta label=\"logs\" value={LOG_DIR} />\n </Box>\n );\n}\n\n// flexShrink={0} on every section holds its natural height, a short terminal overlaps rows without it\nexport function Sidebar({\n state,\n enabled,\n enabledLevels,\n uptimeMs,\n following,\n interactive,\n cursor,\n width,\n filtersOpen,\n ref\n}: SidebarProps): ReactElement {\n return (\n <Box\n ref={ref}\n flexDirection=\"column\"\n width={width ?? undefined}\n maxWidth={MAX_RAIL}\n flexShrink={0}\n paddingX={1}\n overflow=\"hidden\"\n >\n <Box flexShrink={0}>\n <Banner version={version} />\n </Box>\n <Box flexShrink={0} marginTop={1}>\n <StatusBlock state={state} uptimeMs={uptimeMs} />\n </Box>\n <Box flexShrink={0} marginTop={1} flexDirection=\"column\">\n <FilterChips\n channels={LogStore.instance.getChannels()}\n enabledChannels={enabled}\n enabledLevels={enabledLevels}\n cursor={cursor}\n open={filtersOpen}\n />\n </Box>\n {filtersOpen ? (\n <Box flexShrink={0} marginTop={1} flexDirection=\"column\">\n <FilterKeys />\n <Rule />\n </Box>\n ) : null}\n {/* the rule already separates the two key groups, so the blank row is only for the collapsed form */}\n <Box flexShrink={0} marginTop={filtersOpen ? 0 : 1}>\n <SessionKeys phase={state.phase} interactive={interactive} following={following} />\n </Box>\n <Box flexGrow={1} />\n <Box flexShrink={0} justifyContent=\"flex-end\">\n {isStreaming(state.phase) ? (\n <Text>\n <BlinkDot animate={state.idleAnimation} />\n <Text dimColor> live</Text>\n </Text>\n ) : (\n <Text dimColor>○ idle</Text>\n )}\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport { Banner } from '../Banner';\nimport { StatusBadge } from '../StatusBadge';\n\nimport type { Notice } from '#ui/notices';\nimport type { DevState } from '#ui/stores/DevStore';\nimport type { ReactElement } from 'react';\n\nconst HINT = 'resize for full ui';\n\n// below this the hint would crowd out the summary, and it stays optional either way\nconst HINT_COLUMNS = 64;\n\ninterface StatusLineProps {\n readonly state: DevState;\n readonly notices: readonly Notice[];\n readonly columns: number;\n}\n\n/** The single row standing in for the rail once the terminal is too small to hold it. */\nexport function StatusLine({ state, notices, columns }: StatusLineProps): ReactElement {\n const [top, ...rest] = notices;\n\n return (\n <Box flexShrink={0} justifyContent=\"space-between\" paddingX={1}>\n <Box flexShrink={1} overflow=\"hidden\">\n <Text wrap=\"truncate\">\n <Banner version={null} />{' '}\n <StatusBadge phase={state.phase} glyph=\"live\" animate={state.idleAnimation} />\n {top?.summary ? <Text dimColor> · </Text> : null}\n {top?.summary ? <Text color={ui.warn}>{top.summary}</Text> : null}\n {rest.length > 0 ? <Text dimColor> · +{rest.length}</Text> : null}\n </Text>\n </Box>\n {/* flexShrink 0 and the margin keep the key readable against a summary that fills the row */}\n <Box flexShrink={0} marginLeft={2}>\n {top ? (\n <Text bold color={ui.accent}>\n {top.action}\n </Text>\n ) : null}\n {/* the action always renders, since a prompt swallows every key and this row is its only affordance */}\n {!top && columns >= HINT_COLUMNS ? <Text dimColor>{HINT}</Text> : null}\n </Box>\n </Box>\n );\n}\n","import { Box } from 'ink';\nimport React from 'react';\n\nimport { LogHeader } from '#ui/components/primitives/LogHeader';\nimport { NotificationStack } from '#ui/components/primitives/NotificationStack';\nimport { Rule } from '#ui/components/primitives/Rule';\nimport { ScrollableLogView } from '#ui/components/primitives/ScrollableLogView';\nimport { Sidebar } from '#ui/components/primitives/Sidebar';\nimport { StatusLine } from '#ui/components/primitives/StatusLine';\n\nimport type { FilterCursor } from '#ui/filterCursor';\nimport type { ScrollApi } from '#ui/hooks/useScroll';\nimport type { LogRow } from '#ui/logRows';\nimport type { Notice } from '#ui/notices';\nimport type { DevState } from '#ui/stores/DevStore';\nimport type { Tier } from '#ui/tier';\nimport type { LogLevel } from '@seedcord/types';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement, Ref } from 'react';\n\nexport interface DevLayoutProps {\n readonly state: DevState;\n readonly tier: Tier;\n readonly notices: readonly Notice[];\n readonly railRef: Ref<DOMElement>;\n // measured once per run and held until the next restart, null before the measurement completes\n readonly railWidth: number | null;\n // the shell measures this box to size the scroll window. it must be attached or the viewport is empty\n readonly logBoxRef: Ref<DOMElement>;\n readonly scroll: ScrollApi<LogRow>;\n readonly viewportHeight: number;\n readonly measured: boolean;\n readonly columns: number;\n readonly enabled: ReadonlySet<string>;\n readonly enabledLevels: ReadonlySet<LogLevel>;\n readonly cursor: FilterCursor;\n readonly interactive: boolean;\n readonly uptimeMs: number | null;\n}\n\n// notification cards render below the logs so stack traces have room\nexport function DevLayout(props: DevLayoutProps): ReactElement {\n const { state, tier, notices, railRef, railWidth, logBoxRef, scroll, viewportHeight, measured } = props;\n const { columns, enabled, enabledLevels, cursor, interactive, uptimeMs } = props;\n const railed = tier === 'full' || tier === 'compact';\n\n return (\n <Box flexGrow={1}>\n {railed ? (\n <Sidebar\n ref={railRef}\n state={state}\n enabled={enabled}\n enabledLevels={enabledLevels}\n uptimeMs={uptimeMs}\n following={scroll.following}\n interactive={interactive}\n cursor={cursor}\n width={railWidth}\n filtersOpen={tier === 'full'}\n />\n ) : null}\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n minWidth={0}\n borderStyle=\"single\"\n borderColor=\"gray\"\n borderTop={false}\n borderRight={false}\n borderBottom={false}\n borderLeft={railed}\n paddingLeft={railed ? 1 : 0}\n overflow=\"hidden\"\n >\n {railed ? null : <StatusLine state={state} notices={notices} columns={columns} />}\n {railed ? null : <Rule />}\n <LogHeader following={scroll.following} below={scroll.below} />\n {/* the notification stack is unbounded, so the pane keeps a row back for its own message */}\n <Box ref={logBoxRef} flexGrow={1} minHeight={1} overflow=\"hidden\">\n <ScrollableLogView visible={scroll.visible} viewportHeight={viewportHeight} measured={measured} />\n </Box>\n {railed ? <NotificationStack notices={notices} /> : null}\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\ninterface CommandRefreshPromptProps {\n files: string[];\n}\n\nexport function CommandRefreshPrompt({ files }: CommandRefreshPromptProps): ReactElement {\n return (\n <Box borderStyle=\"round\" borderColor={ui.warn} flexDirection=\"column\" paddingX={1}>\n <Text>\n <Text color={ui.warn} bold>\n Commands updated:\n </Text>\n </Text>\n {files.map((file) => (\n <Text key={file} color={ui.accent}>\n - {file}\n </Text>\n ))}\n <Text>Refresh commands? (y/n)</Text>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\nconst STACK_PREVIEW_LINES = 6;\n\ninterface ErrorDisplayProps {\n readonly error: Error;\n}\n\nexport function ErrorDisplay({ error }: ErrorDisplayProps): ReactElement {\n // stack[0] repeats the \"Error: message\" line already rendered above\n const frames = (error.stack?.split('\\n') ?? []).slice(1);\n const preview = frames.slice(0, STACK_PREVIEW_LINES);\n const hidden = frames.length - preview.length;\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={ui.bad} paddingX={1}>\n <Text color={ui.bad} bold>\n Error: {error.name}\n </Text>\n <Text>{error.message}</Text>\n {preview.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n {preview.map((line) => (\n <Text key={line} dimColor wrap=\"truncate\">\n {line}\n </Text>\n ))}\n {hidden > 0 && <Text dimColor>{`… ${hidden} more line${hidden === 1 ? '' : 's'}`}</Text>}\n </Box>\n )}\n <Box marginTop={1}>\n <Text>\n press{' '}\n <Text color={ui.warn} bold>\n r\n </Text>{' '}\n to restart\n </Text>\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\nexport function QuitConfirmCard(): ReactElement {\n return (\n <Box borderStyle=\"round\" borderColor={ui.warn} flexDirection=\"column\" paddingX={1}>\n <Text color={ui.warn} bold>\n Quit?\n </Text>\n <Text>\n press{' '}\n <Text color={ui.warn} bold>\n Ctrl-C\n </Text>{' '}\n again to quit, or any other key to stay\n </Text>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\nexport function RestartRequiredCard(): ReactElement {\n return (\n <Box borderStyle=\"round\" borderColor={ui.warn} flexDirection=\"column\" paddingX={1}>\n <Text color={ui.warn} bold>\n Restart required\n </Text>\n <Text>\n A change needs a full restart. press{' '}\n <Text color={ui.warn} bold>\n r\n </Text>{' '}\n to restart\n </Text>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { TunnelPhase } from '#commands/dev/tunnel/TunnelCoordinator';\nimport type { ReactElement } from 'react';\n\nconst STEPS: readonly (readonly [TunnelPhase, string])[] = [\n ['opening', 'Opening the tunnel'],\n ['resolving', 'Waiting for it to answer'],\n ['registering', 'Telling Discord where to reach you']\n];\n\nfunction Marker({ done, active }: { done: boolean; active: boolean }): ReactElement {\n if (done) return <Text color={ui.good}>✔︎</Text>;\n if (active) return <Spinner type=\"dots\" />;\n return <Text color={ui.faint}>·</Text>;\n}\n\nexport function TunnelOpeningCard({ phase }: { phase: TunnelPhase }): ReactElement {\n const at = STEPS.findIndex(([step]) => step === phase);\n\n return (\n <Box borderStyle=\"round\" borderColor={ui.accent} flexDirection=\"column\" paddingX={1}>\n <Text color={ui.accent} bold>\n Setting up your interactions endpoint\n </Text>\n {STEPS.map(([step, label], index) => (\n <Text key={step} dimColor={index > at}>\n <Marker done={index < at} active={index === at} /> {label}\n </Text>\n ))}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { CommandRefreshPrompt } from '#ui/components/CommandRefreshPrompt';\nimport { ErrorDisplay } from '#ui/components/ErrorDisplay';\nimport { QuitConfirmCard } from '#ui/components/QuitConfirmCard';\nimport { RestartRequiredCard } from '#ui/components/RestartRequiredCard';\nimport { TunnelOpeningCard } from '#ui/components/TunnelOpeningCard';\n\nimport type { TunnelPhase, TunnelStatus } from '#commands/dev/tunnel/TunnelCoordinator';\nimport type { DevState } from '#ui/stores/DevStore';\nimport type { ReactElement } from 'react';\n\ntype NoticeKey = 'quit' | 'commands' | 'error' | 'restart' | 'tunnel';\n\nexport interface Notice {\n readonly key: NoticeKey;\n /** Description shown on the status line's left side. */\n readonly summary: string;\n /** What to press. */\n readonly action: string;\n readonly card: ReactElement;\n}\n\nconst RESTART = 'press r to restart';\n\nfunction openingPhase(status: TunnelStatus | null): TunnelPhase | null {\n return status === null || status === 'live' || status === 'lost' ? null : status;\n}\n\n/** Every pending notice, ranked with the one that blocks a decision first. */\nexport function noticesOf(state: DevState): readonly Notice[] {\n const notices: Notice[] = [];\n\n if (state.quitArmed) {\n notices.push({ key: 'quit', summary: 'Quit?', action: 'press Ctrl-C again', card: <QuitConfirmCard /> });\n }\n\n if (state.commandUpdatePrompt) {\n const count = state.commandUpdatePrompt.length;\n notices.push({\n key: 'commands',\n summary: `${count} command${count === 1 ? '' : 's'} updated`,\n action: 'refresh? y/n',\n card: <CommandRefreshPrompt files={[...state.commandUpdatePrompt]} />\n });\n }\n\n if (state.error) {\n notices.push({\n key: 'error',\n summary: state.error.message, // status line only has room for one line\n action: RESTART,\n card: <ErrorDisplay error={state.error} />\n });\n }\n\n if (state.restartRequired) {\n notices.push({ key: 'restart', summary: '', action: RESTART, card: <RestartRequiredCard /> });\n }\n\n const phase = openingPhase(state.tunnel);\n if (phase) {\n notices.push({\n key: 'tunnel',\n summary: 'Setting up your interactions endpoint',\n action: 'hold on',\n card: <TunnelOpeningCard phase={phase} />\n });\n }\n\n return notices;\n}\n","import { cpus, totalmem } from 'node:os';\nimport process from 'node:process';\n\nimport { Envapter } from 'envapt';\n\nconst enabled = Envapter.getBoolean('SEEDCORD_DEV_PROFILE', false);\n\nconst MEDIAN = 0.5;\nconst NEAR_WORST = 0.99;\nconst BYTES_PER_MB = 1024 * 1024;\nconst PERCENT = 100;\nconst MS_PER_SECOND = 1000;\n\n// each one is the elapsed time when that startup step finished\nconst PHASES = ['config', 'vite', 'entry', 'ready'] as const;\ntype Phase = (typeof PHASES)[number];\n\nconst marks = new Map<Phase, number>();\nconst renderTimes: number[] = [];\nlet wrapCalls = 0;\nlet wrapTotal = 0;\nlet writes = 0;\nlet written = 0;\nlet writeTotal = 0;\nlet framesAtReady = 0;\n\nexport function profileMark(phase: Phase): void {\n if (!enabled) return;\n\n // performance.now() counts from process start\n marks.set(phase, performance.now());\n\n // everything after the bot is up is the idle cost\n if (phase === 'ready') framesAtReady = renderTimes.length;\n}\n\nexport function profileFrame(renderTime: number): void {\n if (enabled) renderTimes.push(renderTime);\n}\n\n// ink's renderTime brackets its own layout only\nexport function profileWrap<Rows>(build: () => Rows): Rows {\n if (!enabled) return build();\n\n const started = performance.now();\n const rows = build();\n wrapTotal += performance.now() - started;\n wrapCalls++;\n\n return rows;\n}\n\n// conhost is far slower at bulk writes than a mac terminal\nexport function profileStdout(): void {\n if (!enabled) return;\n\n const original = process.stdout.write.bind(process.stdout);\n\n process.stdout.write = (chunk: string | Uint8Array, ...rest: never[]) => {\n writes++;\n written += typeof chunk === 'string' ? Buffer.byteLength(chunk) : chunk.byteLength;\n\n const started = performance.now();\n const flushed = original(chunk, ...rest);\n writeTotal += performance.now() - started;\n\n return flushed;\n };\n}\n\nfunction at(sorted: readonly number[], fraction: number): number {\n return sorted[Math.min(sorted.length - 1, Math.floor(sorted.length * fraction))] ?? 0;\n}\n\nfunction ms(value: number): string {\n return `${value.toFixed(1)} ms`;\n}\n\nfunction machine(): string[] {\n const cores = cpus();\n const gb = (totalmem() / BYTES_PER_MB / 1024).toFixed(1);\n const terminal = process.env.WT_SESSION ? 'windows terminal' : (process.env.TERM_PROGRAM ?? 'unknown');\n\n return [\n ` node ${process.version} on ${process.platform} ${process.arch}`,\n ` cpu ${cores[0]?.model ?? 'unknown'} x${String(cores.length)}, ${gb} GB`,\n ` terminal ${terminal}, TERM=${process.env.TERM ?? 'unset'}, ${String(process.stdout.columns)}x${String(process.stdout.rows)}`\n ];\n}\n\nfunction startup(): string[] {\n const ready = marks.get('ready');\n if (ready === undefined) return [' startup never reached ready'];\n\n const lines = [` startup ${ms(ready)}`];\n let previous = 0;\n\n for (const phase of PHASES) {\n const at = marks.get(phase);\n if (at === undefined) continue;\n\n lines.push(` ${phase.padEnd(10)} ${ms(at - previous)}`);\n previous = at;\n }\n\n return lines;\n}\n\nexport function profileReport(): string | null {\n if (!enabled) return null;\n\n const session = performance.now();\n const sorted = [...renderTimes].sort((a, b) => a - b);\n const layoutTotal = renderTimes.reduce((sum, time) => sum + time, 0);\n const mb = (written / BYTES_PER_MB).toFixed(2);\n const share = (part: number): string => `${((part / session) * PERCENT).toFixed(1)}% of session`;\n\n const ready = marks.get('ready') ?? session;\n const idleFrames = renderTimes.length - framesAtReady;\n const idleSeconds = (session - ready) / MS_PER_SECOND;\n const idleRate = idleSeconds > 0 ? (idleFrames / idleSeconds).toFixed(1) : '0.0';\n\n return [\n 'seedcord dev profile',\n ...machine(),\n ` session ${ms(session)}`,\n ...startup(),\n ` frames ${String(renderTimes.length)}`,\n ` idle ${String(idleFrames)} frames over ${idleSeconds.toFixed(1)}s = ${idleRate} fps`,\n ` layout p50 ${ms(at(sorted, MEDIAN))}, p99 ${ms(at(sorted, NEAR_WORST))}, total ${ms(layoutTotal)}, ${share(layoutTotal)}`,\n ` stdout ${mb} MB over ${String(writes)} writes, ${ms(writeTotal)}, ${share(writeTotal)}`,\n ` log wrap ${ms(wrapTotal)} over ${String(wrapCalls)} builds, ${share(wrapTotal)}`\n ].join('\\n');\n}\n","/** How much of the dev UI the terminal has room for. */\nexport type Tier = 'full' | 'compact' | 'logs';\n\n// measured against the real rail with every framework channel plus headroom. Sidebar.test re-measures, so a\n// new rail section fails there before it clips at runtime.\nexport const FULL_ROWS = 30;\nexport const COMPACT_ROWS = 21;\n\n// the rail at its widest, plus the columns a log line uses for its prefix and a readable message\nexport const RAIL_COLUMNS = 80;\n\nexport function tierFor(rows: number, columns: number): Tier {\n if (columns < RAIL_COLUMNS) return 'logs';\n if (rows >= FULL_ROWS) return 'full';\n if (rows >= COMPACT_ROWS) return 'compact';\n return 'logs';\n}\n","import { Box, useInput, useWindowSize } from 'ink';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { Rule } from '#ui/components/primitives/Rule';\nimport { INITIAL_CURSOR } from '#ui/filterCursor';\nimport { useDevState } from '#ui/hooks/useDevState';\nimport { useLogs } from '#ui/hooks/useLogs';\nimport { useMeasuredBox } from '#ui/hooks/useMeasuredBox';\nimport { useRailWidth } from '#ui/hooks/useRailWidth';\nimport { useScroll } from '#ui/hooks/useScroll';\nimport { useUptime } from '#ui/hooks/useUptime';\nimport { dispatchHotkey } from '#ui/hotkeys';\nimport { DevLayout } from '#ui/layout/DevLayout';\nimport { expandRows, rowKey, wrapRows } from '#ui/logRows';\nimport { noticesOf } from '#ui/notices';\nimport { profileWrap } from '#ui/profile';\nimport { LogStore } from '#ui/stores/LogStore';\nimport { tierFor } from '#ui/tier';\n\nimport type { DevStore } from '#ui/stores/DevStore';\nimport type { LogLevel } from '@seedcord/types';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement } from 'react';\n\ninterface DevAppProps {\n readonly store: DevStore;\n readonly onReady: () => void;\n readonly onQuit?: () => Promise<void> | void;\n readonly onDisconnect?: () => Promise<void> | void;\n readonly onRestart?: () => Promise<void> | void;\n readonly onRefreshCommands?: (shouldRefresh: boolean) => Promise<void> | void;\n}\n\nexport function DevApp(props: DevAppProps): ReactElement {\n const { store, onReady } = props;\n const state = useDevState(store);\n const { rows, columns } = useWindowSize();\n\n const [enabled, setEnabled] = useState<ReadonlySet<string>>(() => new Set());\n const [enabledLevels, setEnabledLevels] = useState<ReadonlySet<LogLevel>>(() => new Set());\n const [cursor, setCursor] = useState(INITIAL_CURSOR);\n\n const logBoxRef = useRef<DOMElement | null>(null);\n const logBox = useMeasuredBox(logBoxRef);\n\n const railRef = useRef<DOMElement | null>(null);\n const railWidth = useRailWidth(railRef, state.phase, rows, columns);\n\n const tier = tierFor(rows, columns);\n const notices = noticesOf(state);\n\n const logs = useLogs(enabled, enabledLevels);\n // the label width only grows with a new entry, so the logs dep already covers it\n const logRows = useMemo(\n () =>\n profileWrap(() => wrapRows(expandRows(logs), logBox.width, Math.max(1, LogStore.instance.getLabelWidth()))),\n [logs, logBox.width]\n );\n const viewportHeight = Math.max(1, logBox.height);\n const scroll = useScroll(logRows, viewportHeight, rowKey);\n const uptimeMs = useUptime(state, tier !== 'logs');\n\n const interactive = !state.isBusy || state.restartRequired;\n\n useInput((input, key) => {\n dispatchHotkey({\n input,\n key,\n state,\n interactive,\n scroll,\n store,\n enabled,\n setEnabled,\n enabledLevels,\n setEnabledLevels,\n cursor,\n setCursor,\n filtersOpen: tier === 'full',\n onQuit: props.onQuit,\n onDisconnect: props.onDisconnect,\n onRestart: props.onRestart,\n onRefreshCommands: props.onRefreshCommands\n });\n });\n\n const isInitializedRef = useRef(false);\n useEffect(() => {\n if (isInitializedRef.current) return;\n isInitializedRef.current = true;\n\n LogStore.instance.clear();\n LogStore.instance.mount();\n onReady();\n\n return () => {\n LogStore.instance.unmount();\n };\n }, [onReady]);\n\n return (\n <Box flexDirection=\"column\" width={columns} height={rows} overflow=\"hidden\">\n {/* need the rule for some padding at the top */}\n <Rule />\n <DevLayout\n state={state}\n tier={tier}\n notices={notices}\n railRef={railRef}\n railWidth={railWidth}\n logBoxRef={logBoxRef}\n scroll={scroll}\n viewportHeight={viewportHeight}\n measured={logBox.height > 0}\n columns={columns}\n enabled={enabled}\n enabledLevels={enabledLevels}\n cursor={cursor}\n interactive={interactive}\n uptimeMs={uptimeMs}\n />\n </Box>\n );\n}\n","import { TypedEventEmitter } from '@seedcord/event-emitter';\nimport { assertNever } from '@seedcord/utils';\n\nimport type { DevEvent } from '#commands/dev/runtime/events';\nimport type { TunnelStatus } from '#commands/dev/tunnel/TunnelCoordinator';\nimport type { DevPhase } from './devPhase';\n\nexport interface DevTransport {\n // the transport package, '@seedcord/gateway' or '@seedcord/http'\n readonly name: string;\n readonly version: string;\n}\n\nexport interface DevState {\n readonly phase: DevPhase;\n readonly status: string;\n readonly error: Error | null;\n readonly isBusy: boolean;\n readonly transport: DevTransport | null;\n readonly restartRequired: boolean;\n readonly commandUpdatePrompt: string[] | null;\n readonly port: number | null;\n readonly tunnel: TunnelStatus | null;\n readonly quitArmed: boolean;\n readonly idleAnimation: boolean;\n}\n\nconst INITIAL: DevState = {\n phase: 'starting',\n status: 'Initializing…',\n error: null,\n isBusy: true,\n transport: null,\n restartRequired: false,\n commandUpdatePrompt: null,\n port: null,\n tunnel: null,\n quitArmed: false,\n idleAnimation: true\n};\n\nexport class DevStore extends TypedEventEmitter<{ change: [] }> {\n private state: DevState = INITIAL;\n\n // a stable reference between mutations, which useSyncExternalStore needs to avoid render loops\n public getState(): DevState {\n return this.state;\n }\n\n public setStatus(status: string): void {\n this.patch({ status });\n }\n\n public setBusy(isBusy: boolean): void {\n this.patch({ isBusy });\n }\n\n public setPhase(phase: DevPhase): void {\n this.patch({ phase });\n }\n\n public setError(error: Error | null): void {\n this.patch({ error });\n }\n\n public setTransport(transport: DevTransport | null): void {\n this.patch({ transport });\n }\n\n public setTunnel(tunnel: TunnelStatus | null): void {\n this.patch({ tunnel });\n }\n\n public setQuitArmed(quitArmed: boolean): void {\n this.patch({ quitArmed });\n }\n\n public setIdleAnimation(idleAnimation: boolean): void {\n this.patch({ idleAnimation });\n }\n\n public clearPrompt(): void {\n this.patch({ commandUpdatePrompt: null });\n }\n\n // keeps the r/d press to a single render before the runner swaps sessions\n public beginRestart(): void {\n this.patch({\n phase: 'starting',\n isBusy: true,\n restartRequired: false,\n error: null,\n status: 'Restarting…',\n port: null\n });\n }\n\n public beginDisconnect(): void {\n this.patch({\n phase: 'disconnected',\n isBusy: true,\n restartRequired: false,\n error: null,\n status: 'Disconnecting…',\n port: null\n });\n }\n\n public beginQuit(): void {\n this.patch({ phase: 'quitting', isBusy: true, status: 'Shutting down…' });\n }\n\n public apply(event: DevEvent): void {\n switch (event.type) {\n case 'restart-required': {\n this.patch({\n phase: 'restart-required',\n status: 'Restart required. Press r to restart.',\n restartRequired: true\n });\n break;\n }\n case 'command-update-prompt': {\n this.patch({ commandUpdatePrompt: event.files });\n break;\n }\n case 'server-listening': {\n this.patch({ port: event.port });\n break;\n }\n case 'module-loading':\n case 'module-loaded':\n case 'module-error':\n case 'file-change':\n case 'ready': {\n break;\n }\n default: {\n assertNever(event);\n }\n }\n }\n\n private patch(next: Partial<DevState>): void {\n this.state = { ...this.state, ...next };\n this.emit('change');\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\n\nimport { Logger } from '@seedcord/logger';\n\nconst TSC_GRACEFUL_EXIT_MS = 2000;\n\nexport class TscRunner {\n private process: ChildProcess | null = null;\n private readonly logger: Logger;\n\n constructor(\n private readonly tsconfigPath?: string,\n private readonly cwd?: string\n ) {\n this.logger = new Logger('Typecheck', { channel: 'tsc' });\n }\n\n public start(): void {\n if (this.process) return;\n\n const tscPath = this.resolveProjectTsc();\n if (!tscPath) {\n this.logger.error('Unable to resolve \"typescript\". Install it in the project to enable tsc --watch.');\n return;\n }\n\n const args = [tscPath, '--noEmit', '--watch', '--preserveWatchOutput', '--pretty'];\n if (this.tsconfigPath) {\n args.push('--project', this.tsconfigPath);\n }\n\n this.logger.debug('Starting tsc --watch...');\n\n this.process = spawn(process.execPath, args, {\n cwd: this.cwd ?? process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe']\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n const lines = data.toString().split('\\n');\n for (const line of lines) {\n if (line.trim()) {\n this.logger.debug(line.trimEnd());\n }\n }\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n const lines = data.toString().split('\\n');\n for (const line of lines) {\n if (line.trim()) {\n this.logger.error(line.trimEnd());\n }\n }\n });\n\n this.process.on('error', (err) => {\n this.logger.error(`Failed to start tsc: ${err.message}`);\n });\n\n this.process.on('exit', (code) => {\n if (code !== 0 && code !== null) {\n this.logger.error(`tsc exited with code ${code}`);\n } else {\n this.logger.debug('tsc exited.');\n }\n this.process = null;\n });\n }\n\n public stop(): void {\n const child = this.process;\n if (!child) return;\n\n this.logger.debug('Stopping tsc...');\n child.kill('SIGTERM');\n\n // justified: tsc --watch can ignore SIGTERM when stdin is detached (Windows/some Node builds), so escalate to SIGKILL after a grace window. unref so the timer never holds the event loop open.\n const killTimer = setTimeout(() => child.kill('SIGKILL'), TSC_GRACEFUL_EXIT_MS);\n killTimer.unref();\n child.once('exit', () => {\n clearTimeout(killTimer);\n });\n // start()'s 'exit' listener is what nulls the handle, so it stays set until then and blocks a second tsc spawning over the dying one\n }\n\n private resolveProjectTsc(): string | null {\n const projectDir = this.cwd ?? process.cwd();\n const manifest = resolve(projectDir, 'package.json');\n const projectRequire = existsSync(manifest) ? createRequire(manifest) : createRequire(import.meta.url);\n\n try {\n return projectRequire.resolve('typescript/bin/tsc');\n } catch {\n return null;\n }\n }\n}\n","import { existsSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { paint, SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { SeedcordBrand, type Brandable, type SeedcordInstance } from '@seedcord/types/internal';\n\nimport { profileMark } from '#ui/profile';\nimport { resolveDefaultExport } from '#utils/resolveDefaultExport';\n\nimport { TscRunner } from './TscRunner';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { DevStore } from '#ui/stores/DevStore';\nimport type { DevRuntime } from './runtime/DevRuntime';\nimport type { DevEventHandler } from './runtime/events';\n\nfunction isSeedcordInstance(candidate: unknown): candidate is SeedcordInstance {\n return typeof candidate === 'object' && candidate !== null && (candidate as Brandable)[SeedcordBrand] === true;\n}\n\nexport class DevSession {\n private stopResolve?: () => void;\n private instance?: SeedcordInstance;\n private isStopped = false;\n private startupPromise?: Promise<unknown>;\n private tscRunner?: TscRunner;\n private stopPromise?: Promise<void>;\n\n constructor(\n private readonly config: ResolvedSeedcordDevConfig,\n private readonly runtime: DevRuntime,\n private readonly store: DevStore,\n private readonly onEvent: DevEventHandler\n ) {}\n\n private async loadInstanceModule(): Promise<unknown> {\n await this.runtime.start({\n config: this.config,\n onEvent: (event) => {\n this.store.apply(event);\n this.onEvent(event);\n }\n });\n profileMark('vite');\n\n // vite's missing-entry message changed across a minor and broke detection\n if (!existsSync(this.config.instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [this.config.instance]);\n }\n\n try {\n const { module } = await this.runtime.loadEntry();\n profileMark('entry');\n return module;\n } catch (error: unknown) {\n const message = Error.isError(error) ? error.message : String(error);\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [this.config.instance, message]);\n }\n }\n\n private startTypecheck(): void {\n const { typecheck } = this.config;\n if (!typecheck.enabled) return;\n\n this.tscRunner = new TscRunner(typecheck.tsconfig, dirname(this.config.configFile));\n this.tscRunner.start();\n }\n\n public async start(onReady?: () => void): Promise<void> {\n const module = await this.loadInstanceModule();\n const exported = resolveDefaultExport(module);\n const instance = await Promise.resolve(exported);\n\n if (!isSeedcordInstance(instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliInstanceInvalid);\n }\n\n this.instance = instance;\n this.store.setTransport({ name: instance.augmentTarget, version: instance.version });\n\n try {\n this.store.setPhase('starting');\n this.store.setStatus('Starting Seedcord instance…');\n this.startupPromise = Promise.resolve(instance.start());\n await this.startupPromise;\n\n if (this.isStopped) {\n return;\n }\n\n this.store.setPhase('running');\n this.store.setStatus(`${paint.bold(instance.username ?? 'Bot')} is ready!`);\n profileMark('ready');\n onReady?.();\n // tsc competes with vite's cold transform when it starts any earlier\n this.startTypecheck();\n\n // resolved by stop(), and no signal handlers here so restarts never accumulate listeners\n await new Promise<void>((resolve) => {\n this.stopResolve = resolve;\n });\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown error';\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [this.config.instance, reason]);\n }\n }\n\n // quit, restart, disconnect, and dispose all call this\n public async stop(): Promise<void> {\n this.stopPromise ??= this.runStop();\n return this.stopPromise;\n }\n\n private async runStop(): Promise<void> {\n this.isStopped = true;\n this.tscRunner?.stop();\n this.instance?.startup.abort();\n\n if (this.startupPromise) {\n // so the shutdown below still runs\n try {\n await this.startupPromise;\n } catch {}\n }\n\n await this.instance?.shutdown.run(0, false);\n this.stopResolve?.();\n }\n\n public async dispose(): Promise<void> {\n await this.stop();\n await this.runtime.dispose();\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n this.runtime.refreshCommands?.(shouldRefresh);\n }\n}\n","import { relative, resolve } from 'node:path';\n\nimport { wrapHot } from '@seedcord/core/internal';\nimport { paint } from '@seedcord/errors';\nimport { TypedEventEmitter } from '@seedcord/event-emitter';\nimport { Logger } from '@seedcord/logger';\nimport { minimatch } from 'minimatch';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { DevEvent } from './events';\nimport type { HmrEventType, HmrUpdateEvent } from '@seedcord/types';\nimport type { DevChannel, SeedcordCliEvents, SeedcordFrameworkEvents } from '@seedcord/types/internal';\nimport type {\n EnvironmentModuleNode,\n HotUpdateOptions,\n ModuleNode,\n NormalizedHotChannel,\n Plugin,\n ViteDevServer\n} from 'vite';\n\nconst DEBOUNCE_MS = 250;\n\nexport class HmrPlugin extends TypedEventEmitter<{ event: [DevEvent] }> {\n private readonly logger: Logger;\n private readonly lastUpdate = new Map<string, number>();\n private readonly awaitingCreateEcho = new Set<string>();\n private server: ViteDevServer | null = null;\n private readonly dynamicRestartPatterns = new Set<string>();\n\n private get hot(): NormalizedHotChannel | undefined {\n return this.server?.environments.ssr.hot;\n }\n\n private get dev(): DevChannel<SeedcordCliEvents, SeedcordFrameworkEvents> | undefined {\n return this.hot ? wrapHot<SeedcordCliEvents, SeedcordFrameworkEvents>(this.hot) : undefined;\n }\n\n constructor(private readonly config: ResolvedSeedcordDevConfig) {\n super();\n this.logger = new Logger('HMR', { channel: 'hmr' });\n }\n\n public get plugin(): Plugin {\n return {\n name: 'seedcord:hmr',\n configureServer: this.configureServer.bind(this),\n hotUpdate: this.hotUpdate.bind(this)\n };\n }\n\n public sendRefreshCommands(shouldRefresh: boolean): void {\n this.dev?.send('seedcord:refresh-commands', { shouldRefresh });\n }\n\n private configureServer(server: ViteDevServer): void {\n this.server = server;\n server.watcher.on('add', (file) => this.handleFileEvent(file, 'create'));\n server.watcher.on('unlink', (file) => this.handleFileEvent(file, 'delete'));\n server.watcher.on('addDir', (file) => this.handleFileEvent(file, 'createDir'));\n server.watcher.on('unlinkDir', (file) => this.handleFileEvent(file, 'deleteDir'));\n\n // vite's watcher covers config.root only, which excludes the config file\n server.watcher.add(this.config.configFile);\n server.watcher.on('change', (file) => this.handleChange(file));\n\n this.dev?.on('seedcord:commands-update-prompt', (data) => {\n this.emit('event', { type: 'command-update-prompt', files: data.files });\n });\n\n this.dev?.on('seedcord:server-listening', (data) => {\n this.emit('event', { type: 'server-listening', port: data.port });\n });\n\n this.dev?.on('seedcord:register-critical-files', (data) => {\n for (const pattern of data.patterns) {\n this.dynamicRestartPatterns.add(pattern);\n }\n\n this.logger.debug(`Registered ${String(data.patterns.length)} critical file patterns`);\n });\n }\n\n // keyed per type, else an atomic-save rename (unlink then add) loses the add and the handler stays unloaded\n private isDebounced(file: string, type: HmrEventType): boolean {\n if (this.justSaw(file, type)) return true;\n this.lastUpdate.set(`${file}::${type}`, Date.now());\n return false;\n }\n\n private justSaw(file: string, type: HmrEventType): boolean {\n const last = this.lastUpdate.get(`${file}::${type}`);\n return last !== undefined && Date.now() - last < DEBOUNCE_MS;\n }\n\n // hotUpdate covers a critical file inside the root\n private handleChange(file: string): void {\n if (!this.isCriticalFile(file) || this.isDebounced(file, 'update')) return;\n this.reportRestartRequired(file);\n }\n\n private reportRestartRequired(file: string): void {\n const relPath = relative(process.cwd(), file);\n this.logger.warn(`${paint.coral('Critical file changed:')} ${paint.sky.bold(relPath)}. Restart required.`);\n this.emit('event', { type: 'restart-required' });\n }\n\n private handleFileEvent(file: string, type: HmrEventType): void {\n if (this.isDebounced(file, type)) return;\n if (type === 'create') this.awaitingCreateEcho.add(file);\n\n const relPath = relative(process.cwd(), file);\n const typeColor =\n type === 'create' || type === 'createDir'\n ? paint.mint\n : type === 'delete' || type === 'deleteDir'\n ? paint.coral\n : paint.sky;\n\n this.logger.trace(`${typeColor(type.toUpperCase())} ${paint.mute(relPath)}`);\n\n const payload: HmrUpdateEvent = { file, type, rollback: this.config.hmr?.rollback ?? true };\n\n this.dev?.send('seedcord:hmr', payload);\n }\n\n private hotUpdate(ctx: HotUpdateOptions): EnvironmentModuleNode[] {\n const { file, modules, server } = ctx;\n const type = 'update';\n\n // vite fires one update straight after the watcher's add, and the create already reloaded the file\n const isCreateEcho = this.awaitingCreateEcho.delete(file) && this.justSaw(file, 'create');\n if (isCreateEcho || this.isDebounced(file, type)) return [];\n\n const relPath = relative(process.cwd(), file);\n\n this.logger.trace(`${paint.sky(type.toUpperCase())} ${paint.mute(relPath)}`);\n\n if (this.isCriticalFile(file)) {\n this.reportRestartRequired(file);\n return [];\n }\n\n const moduleGraph = server.moduleGraph;\n const fileModules = moduleGraph.getModulesByFile(file);\n const allModules = fileModules ? [...fileModules] : [];\n\n const combinedModules = new Set([...modules, ...allModules]);\n const affectedModules = this.getAffectedModules([...combinedModules]);\n\n const filesToInvalidate = new Set([file, ...affectedModules]);\n\n for (const fileToInvalidate of filesToInvalidate) {\n const mods = moduleGraph.getModulesByFile(fileToInvalidate);\n if (mods) {\n for (const mod of mods) {\n moduleGraph.invalidateModule(mod);\n }\n }\n }\n\n // the runtime invalidates this module in its evaluated-modules graph on a file-change event.\n this.emit('event', { type: 'file-change', path: file });\n\n const payload: HmrUpdateEvent = { file, type, affectedModules, rollback: this.config.hmr?.rollback ?? true };\n\n this.dev?.send('seedcord:hmr', payload);\n\n // returning [] suppresses vite's default client HMR so invalidation runs through the runtime.\n return [];\n }\n\n private isCriticalFile(file: string): boolean {\n const root = this.config.root;\n const relPath = relative(root, file);\n\n if (this.config.hmr?.restart) {\n for (const pattern of this.config.hmr.restart) {\n if (minimatch(relPath, pattern)) {\n return true;\n }\n }\n }\n\n for (const pattern of this.dynamicRestartPatterns) {\n if (minimatch(relPath, pattern)) {\n return true;\n }\n }\n\n if (\n file === this.config.configFile ||\n file.endsWith('package.json') ||\n file.endsWith('tsconfig.json') ||\n file.endsWith('.env')\n ) {\n return true;\n }\n\n const entryPath = resolve(root, this.config.entry);\n const instancePath = resolve(root, this.config.instance);\n\n if (file === entryPath || file === instancePath) {\n return true;\n }\n\n return false;\n }\n\n private getAffectedModules(modules: (EnvironmentModuleNode | ModuleNode)[]): string[] {\n const affected = new Set<string>();\n const seen = new Set<string>();\n\n const traverse = (mod: EnvironmentModuleNode | ModuleNode): void => {\n if (!mod.file || seen.has(mod.file)) return;\n\n seen.add(mod.file);\n affected.add(mod.file);\n mod.importers.forEach(traverse);\n };\n\n modules.forEach(traverse);\n return [...affected];\n }\n}\n","import { realpathSync } from 'node:fs';\nimport { resolve, sep } from 'node:path';\n\nimport { defineConfig } from 'vite';\n\n// a **/logs/** glob would also swallow a source directory named logs\nexport function logsIgnore(root: string): (path: string) => boolean {\n // chokidar reports the resolved path, and a mac temp dir arrives through a symlink\n const logs = resolve(realpathSync(root), 'logs');\n\n return (path) => path === logs || path.startsWith(logs + sep);\n}\n\nexport default defineConfig({\n server: {\n middlewareMode: true,\n hmr: true,\n watch: {\n usePolling: false,\n ignored: ['**/node_modules/**', '**/dist/**', '**/.git/**']\n }\n },\n build: {\n ssr: true,\n outDir: 'dist',\n sourcemap: true,\n minify: false,\n rollupOptions: {\n output: {\n format: 'esm',\n preserveModules: true\n }\n }\n },\n ssr: {\n target: 'node',\n // logger stays external so the bot shares the CLI's LoggerChannelRegistry singleton the dev TUI reads through\n external: ['@seedcord/logger', '@seedcord/logger/node'],\n // an externalized package's import() of a project .ts file goes to node's loader, which cannot parse decorators\n // vite injects import.meta.hot only into modules it transforms, and HmrManager.init reads it\n noExternal: [/^@seedcord\\//],\n resolve: {\n conditions: ['node', 'import'],\n externalConditions: ['node']\n }\n },\n environments: {\n ssr: {\n resolve: {\n conditions: ['node', 'import'],\n externalConditions: ['node']\n }\n }\n },\n future: {\n removeSsrLoadModule: 'warn',\n removePluginHookHandleHotUpdate: 'warn',\n removePluginHookSsrArgument: 'warn',\n removeServerModuleGraph: 'warn',\n removeServerReloadModule: 'warn',\n removeServerPluginContainer: 'warn',\n removeServerHot: 'warn',\n removeServerTransformRequest: 'warn',\n removeServerWarmupRequest: 'warn'\n },\n clearScreen: false,\n logLevel: 'error',\n appType: 'custom'\n});\n","import { dirname, relative } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { createServer, createServerModuleRunner, mergeConfig } from 'vite';\nimport { EvaluatedModules } from 'vite/module-runner';\n// eslint-disable-next-line import-x/no-rename-default -- the package declares its default as `_default`\nimport tsconfigPaths from 'vite-tsconfig-paths';\n\nimport { HmrPlugin } from './HmrPlugin';\nimport viteConfig, { logsIgnore } from './vite.config';\n\nimport type { DevRuntime, DevRuntimeContext, DevRuntimeLoadResult } from './DevRuntime';\nimport type { DevEvent, DevEventHandler } from './events';\nimport type { ViteDevServer } from 'vite';\nimport type { ModuleRunner } from 'vite/module-runner';\n\nexport class ViteDevRuntime implements DevRuntime {\n private context: DevRuntimeContext | null = null;\n private viteServer: ViteDevServer | null = null;\n private moduleRunner: ModuleRunner | null = null;\n private eventHandler: DevEventHandler | null = null;\n private evaluatedModules: EvaluatedModules | null = null;\n private hmrPlugin: HmrPlugin | null = null;\n\n public async start(context: DevRuntimeContext): Promise<void> {\n this.context = context;\n this.eventHandler = context.onEvent ?? null;\n\n const projectRoot = this.context.config.root;\n\n this.emit({ type: 'module-loading', path: projectRoot });\n\n const hmrPlugin = new HmrPlugin(this.context.config);\n this.hmrPlugin = hmrPlugin;\n\n // vite searches its own root for a config file\n const config = mergeConfig(viteConfig, {\n root: projectRoot,\n configFile: false,\n server: { watch: { ignored: [logsIgnore(projectRoot)] } },\n plugins: [tsconfigPaths({ root: dirname(this.context.config.configFile) }), hmrPlugin.plugin]\n });\n\n this.viteServer = await createServer(config);\n\n this.evaluatedModules = new EvaluatedModules();\n this.moduleRunner = createServerModuleRunner(this.viteServer.environments.ssr, {\n evaluatedModules: this.evaluatedModules\n });\n\n hmrPlugin.on('event', this.handleHmrEvent.bind(this));\n\n this.emit({ type: 'module-loaded', path: projectRoot });\n this.emit({ type: 'ready' });\n }\n\n private handleHmrEvent(event: DevEvent): void {\n if (event.type === 'file-change') {\n this.invalidateModule(event.path);\n }\n this.emit(event);\n }\n\n private invalidateModule(file: string): void {\n const projectRoot = this.context?.config.root;\n if (!projectRoot || !this.evaluatedModules) return;\n\n const moduleId = toModuleId(projectRoot, file);\n const moduleNode = this.evaluatedModules.getModuleById(moduleId);\n if (moduleNode) {\n this.evaluatedModules.invalidateModule(moduleNode);\n }\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n this.hmrPlugin?.sendRefreshCommands(shouldRefresh);\n }\n\n public async loadEntry(): Promise<DevRuntimeLoadResult> {\n if (!this.context || !this.viteServer || !this.moduleRunner) {\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [\n this.context?.config.instance ?? 'runtime',\n 'ViteDevRuntime.start() must complete before loadEntry()'\n ]);\n }\n\n const { instance: entryPath } = this.context.config;\n const projectRoot = this.context.config.root;\n\n this.emit({ type: 'module-loading', path: entryPath });\n\n try {\n const moduleId = toModuleId(projectRoot, entryPath);\n\n const module = await this.moduleRunner.import<unknown>(moduleId);\n\n this.emit({ type: 'module-loaded', path: entryPath });\n\n return { module };\n } catch (error: unknown) {\n this.emit({ type: 'module-error', path: entryPath, error });\n throw error;\n }\n }\n\n public async dispose(): Promise<void> {\n // restart and disconnect dispose the runtime without exiting the process, so drop the event\n // wiring here, else each new session leaks the last one's listeners\n this.hmrPlugin?.removeAllListeners('event');\n\n if (this.viteServer) {\n await this.viteServer.close();\n this.viteServer = null;\n }\n\n this.moduleRunner = null;\n this.evaluatedModules = null;\n this.hmrPlugin = null;\n this.context = null;\n this.eventHandler = null;\n }\n\n private emit(event: DevEvent): void {\n this.eventHandler?.(event);\n }\n}\n\n// vite normalizes module ids to forward slashes. relative() yields backslashes on windows\nfunction toModuleId(projectRoot: string, file: string): string {\n return `/${relative(projectRoot, file).replaceAll('\\\\', '/')}`;\n}\n","import { existsSync } from 'node:fs';\nimport { delimiter, join } from 'node:path';\n\nimport { Envapter } from 'envapt';\n\nconst BINARY = 'cloudflared';\nconst DOWNLOADS = 'https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/';\n\nexport interface PathLookup {\n readonly pathVar: string | undefined;\n readonly pathExt: string | undefined;\n readonly platform: NodeJS.Platform;\n readonly delimiter: string;\n readonly exists: (candidate: string) => boolean;\n}\n\nexport function systemLookup(): PathLookup {\n return {\n pathVar: Envapter.get('PATH'),\n pathExt: Envapter.get('PATHEXT'),\n platform: process.platform,\n delimiter,\n exists: existsSync\n };\n}\n\nexport function findCloudflared(lookup: PathLookup): string | undefined {\n const suffixes = lookup.platform === 'win32' ? (lookup.pathExt?.split(';') ?? ['.EXE']) : [''];\n\n for (const dir of lookup.pathVar?.split(lookup.delimiter) ?? []) {\n for (const suffix of suffixes) {\n const candidate = join(dir, `${BINARY}${suffix}`);\n if (lookup.exists(candidate)) return candidate;\n }\n }\n\n return undefined;\n}\n\nexport function installHint(platform: NodeJS.Platform): string {\n if (platform === 'darwin') return 'brew install cloudflared';\n if (platform === 'win32') return 'winget install -e --id Cloudflare.cloudflared';\n return DOWNLOADS;\n}\n","const UNAUTHORIZED = 401;\nconst POLL_INTERVAL_MS = 250;\nconst BUDGET_MS = 60_000;\n\nexport const PROBE_SECONDS = BUDGET_MS / 1000;\n\nexport interface ProbeDeps {\n fetch: (url: string, init?: RequestInit) => Promise<Response>;\n wait: (ms: number) => Promise<void>;\n}\n\n// an unsigned POST reaches the engine on any path, and only a seedcord bot answers it with a 401\nexport async function awaitReachable(url: string, deps: ProbeDeps, signal: AbortSignal): Promise<boolean> {\n // one budget shared by every request, so a slow answer still gets the time left in it\n const budget = AbortSignal.any([signal, AbortSignal.timeout(BUDGET_MS)]);\n\n for (let attempt = 0; attempt < BUDGET_MS / POLL_INTERVAL_MS; attempt++) {\n try {\n const response = await deps.fetch(url, { method: 'POST', signal: budget });\n if (response.status === UNAUTHORIZED) return true;\n } catch {\n signal.throwIfAborted();\n }\n await deps.wait(POLL_INTERVAL_MS);\n }\n\n return false;\n}\n","import { spawn } from 'node:child_process';\nimport { createServer } from 'node:net';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { awaitReachable } from './probe';\n\nimport type { ProbeDeps } from './probe';\nimport type { ChildProcess } from 'node:child_process';\n\nconst POLL_INTERVAL_MS = 250;\nconst HOSTNAME_ATTEMPTS = 240;\nconst SETTLE_MS = 4000;\nconst GRACEFUL_EXIT_MS = 2000;\n\nexport interface TunnelDeps extends ProbeDeps {\n spawn: (command: string, args: string[]) => ChildProcess;\n freePort: () => Promise<number>;\n}\n\nfunction freePort(): Promise<number> {\n return new Promise((resolve, reject) => {\n const probe = createServer();\n probe.once('error', reject);\n probe.listen(0, '127.0.0.1', () => {\n // justified: address() is AddressInfo once a TCP server is listening\n const { port } = probe.address() as { port: number };\n probe.close(() => resolve(port));\n });\n });\n}\n\nexport function systemTunnelDeps(): TunnelDeps {\n return {\n spawn: (command, args) => spawn(command, args, { stdio: 'ignore' }),\n fetch: (url, init) => fetch(url, init),\n freePort,\n wait: (ms) => new Promise((resolve) => setTimeout(resolve, ms))\n };\n}\n\nexport class CloudflaredTunnel {\n private child: ChildProcess | undefined;\n private failure: Error | undefined;\n\n constructor(\n private readonly deps: TunnelDeps,\n private readonly binary: string,\n private readonly onLost: () => void\n ) {}\n\n public async open(signal: AbortSignal, targetPort: number, onResolving?: () => void): Promise<string> {\n const metricsPort = await this.deps.freePort();\n\n const child = this.deps.spawn(this.binary, [\n 'tunnel',\n '--url',\n `http://localhost:${String(targetPort)}`,\n '--metrics',\n `127.0.0.1:${String(metricsPort)}`\n ]);\n // without a listener node throws a spawn failure process-wide\n child.on('error', (error) => {\n this.failure = error;\n });\n // stop() clears this.child first, so a deliberate kill skips this\n child.on('exit', (code) => {\n if (this.child !== child) return;\n this.failure = new Error(`cloudflared exited early with code ${String(code)}`);\n });\n this.child = child;\n\n const url = `https://${await this.readHostname(metricsPort, signal)}`;\n onResolving?.();\n // the record lands ~2.5s later and an early lookup caches NXDOMAIN for a 30 minute negative TTL\n await this.deps.wait(SETTLE_MS);\n // local dns resolving doesn't mean discord's resolver has too, so this only shortens the wait\n await awaitReachable(url, this.deps, signal);\n child.once('exit', () => {\n if (this.child === child) this.onLost();\n });\n return url;\n }\n\n public stop(): void {\n const child = this.child;\n if (!child) return;\n\n this.child = undefined;\n this.failure = undefined;\n child.kill('SIGTERM');\n\n const escalate = setTimeout(() => child.kill('SIGKILL'), GRACEFUL_EXIT_MS);\n escalate.unref();\n child.once('exit', () => {\n clearTimeout(escalate);\n });\n }\n\n private async readHostname(metricsPort: number, signal: AbortSignal): Promise<string> {\n const budget = AbortSignal.any([signal, AbortSignal.timeout(HOSTNAME_ATTEMPTS * POLL_INTERVAL_MS)]);\n\n for (let attempt = 0; attempt < HOSTNAME_ATTEMPTS && !this.failure; attempt++) {\n signal.throwIfAborted();\n if (budget.aborted) break;\n const hostname = await this.pollOnce(metricsPort, budget);\n if (hostname) return hostname;\n await this.deps.wait(POLL_INTERVAL_MS);\n }\n\n const cause = this.failure;\n this.stop();\n throw new SeedcordError(\n SeedcordErrorCode.CliTunnelUrlUnavailable,\n [(HOSTNAME_ATTEMPTS * POLL_INTERVAL_MS) / 1000],\n { cause }\n );\n }\n\n private async pollOnce(metricsPort: number, signal: AbortSignal): Promise<string | undefined> {\n try {\n const response = await this.deps.fetch(`http://127.0.0.1:${String(metricsPort)}/quicktunnel`, { signal });\n // justified: the cloudflared metrics route returns this shape\n const { hostname } = (await response.json()) as { hostname?: string };\n return hostname === '' ? undefined : hostname; // empty until the edge assigns one\n } catch {\n return undefined;\n }\n }\n}\n","import { DiscordAPIError, REST } from '@discordjs/rest';\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { RESTJSONErrorCodes, Routes } from 'discord-api-types/v10';\n\nimport type { RESTGetCurrentApplicationResult, RESTPatchCurrentApplicationJSONBody } from 'discord-api-types/v10';\n\nconst FIELD = 'interactions_endpoint_url';\n\nexport type EndpointRest = Pick<REST, 'get' | 'patch'>;\n\n// discord verifies by posting a signed ping to the url, which fails until the hostname resolves on its side\nfunction unverified(error: unknown): boolean {\n if (!(error instanceof DiscordAPIError) || error.code !== RESTJSONErrorCodes.InvalidFormBodyOrContentType) {\n return false;\n }\n\n const { rawError } = error;\n return 'errors' in rawError && containsField(rawError.errors);\n}\n\nfunction containsField(errors: unknown): boolean {\n return typeof errors === 'object' && errors !== null && FIELD in errors;\n}\n\nexport class InteractionsEndpoint {\n private client: EndpointRest | undefined;\n\n constructor(private readonly makeRest: () => EndpointRest) {}\n\n // the token is read on the first request, since the bot module can repoint envapt while it loads\n public static create(token: () => string): InteractionsEndpoint {\n // without this the client silently waits out an exhausted bucket and the cli looks frozen\n const rest = new REST({ version: '10', rejectOnRateLimit: ['/applications'] });\n return new InteractionsEndpoint(() => rest.setToken(token()));\n }\n\n public async set(url: string, signal: AbortSignal): Promise<void> {\n signal.throwIfAborted();\n // justified: the discord api contract for this route\n const application = (await this.rest().get(Routes.currentApplication())) as RESTGetCurrentApplicationResult;\n if (application.interactions_endpoint_url === url) return;\n\n signal.throwIfAborted();\n try {\n await this.write(url);\n } catch (error: unknown) {\n if (!unverified(error)) throw error;\n throw new SeedcordError(SeedcordErrorCode.CliTunnelNotVerified, [url]);\n }\n }\n\n private rest(): EndpointRest {\n this.client ??= this.makeRest();\n return this.client;\n }\n\n public async clear(): Promise<void> {\n await this.write(null);\n }\n\n private async write(endpoint: string | null): Promise<void> {\n await this.rest().patch(Routes.currentApplication(), {\n body: { interactions_endpoint_url: endpoint } satisfies RESTPatchCurrentApplicationJSONBody\n });\n }\n}\n","import { paint } from '@seedcord/errors';\n\nimport { formatUptime } from '#ui/format';\n\nimport type { CloudflaredTunnel } from './CloudflaredTunnel';\nimport type { InteractionsEndpoint } from './InteractionsEndpoint';\nimport type { ILogger } from '@seedcord/types';\n\nconst PASTE_HINT = 'The tunnel is still up, so try pasting that URL into the dashboard.';\nconst RESTART_HINT = 'Restart for a fresh hostname, or set `tunnel` to an https URL you already serve.';\n\nexport type CoordinatorTunnel = Pick<CloudflaredTunnel, 'open' | 'stop'>;\n\nexport type TunnelPhase = 'opening' | 'resolving' | 'registering';\nexport type TunnelStatus = TunnelPhase | 'live' | 'lost';\n\nexport interface CoordinatorDeps {\n readonly makeTunnel: (onLost: () => void) => CoordinatorTunnel;\n // a quick hostname lasts only as long as this process, so quit clears the endpoint\n readonly kind: 'quick' | 'configured';\n readonly endpoint: Pick<InteractionsEndpoint, 'set' | 'clear'>;\n readonly onStatus: (status: TunnelStatus | null) => void;\n readonly logger: ILogger;\n}\n\n// a call, because a direct read of signal.aborted narrows to false past the first check\nfunction superseded(attempt: AbortController): boolean {\n return attempt.signal.aborted;\n}\n\nfunction opening(kind: CoordinatorDeps['kind']): string {\n return kind === 'quick' ? 'Requesting a cloudflared tunnel to port' : 'Checking if your tunnel reaches port';\n}\n\nexport class TunnelCoordinator {\n private target: number | undefined;\n private current: AbortController | undefined;\n\n constructor(private readonly deps: CoordinatorDeps) {}\n\n public async onPort(port: number): Promise<void> {\n if (this.target === port) return;\n\n this.target = port;\n const attempt = this.begin();\n const startedAt = Date.now();\n const since = (): string => paint.mute(`+${formatUptime(Date.now() - startedAt)}`);\n const tunnel = this.deps.makeTunnel(() => this.reportLost(attempt));\n // a later onPort has no handle on this tunnel. the abort is the only way back to stop it.\n attempt.signal.addEventListener('abort', () => tunnel.stop(), { once: true });\n let patched = false;\n\n try {\n this.deps.onStatus('opening');\n this.deps.logger.info(`${opening(this.deps.kind)} ${paint.sky.bold(String(port))}`);\n const url = await tunnel.open(attempt.signal, port, () => this.deps.onStatus('resolving'));\n if (superseded(attempt)) return;\n this.deps.logger.info(`Reachable at ${paint.sky.bold(url)} ${since()}`);\n\n this.deps.onStatus('registering');\n patched = true;\n await this.deps.endpoint.set(url, attempt.signal);\n if (superseded(attempt)) return;\n\n this.deps.onStatus('live');\n this.deps.logger.info(`Interactions endpoint set on the dev dashboard ${since()}`);\n } catch (error: unknown) {\n if (superseded(attempt)) return;\n // discord will refuse the same hostname again\n if (patched) attempt.abort();\n this.reportFailure(error, patched);\n }\n }\n\n private reportLost(attempt: AbortController): void {\n if (superseded(attempt)) return;\n\n this.target = undefined;\n this.deps.onStatus('lost');\n this.deps.logger.error('cloudflared exited, so the bot has no public endpoint');\n }\n\n private reportFailure(error: unknown, patched: boolean): void {\n // so a retry on this port is not skipped\n this.target = undefined;\n this.deps.onStatus(null);\n this.deps.logger.error('Tunnel setup failed, the bot runs without a public endpoint', error);\n // patched means the abort above stopped the tunnel. the paste hint only holds while it is up.\n if (this.deps.kind === 'quick') this.deps.logger.info(patched ? RESTART_HINT : PASTE_HINT);\n }\n\n public async stop(): Promise<void> {\n if (!this.current) return;\n\n this.target = undefined;\n this.current.abort();\n this.current = undefined;\n this.deps.onStatus(null);\n if (this.deps.kind === 'configured') return;\n\n try {\n await this.deps.endpoint.clear();\n } catch (error: unknown) {\n // a failed clear must not reject the quit path\n this.deps.logger.warn('Could not clear the interactions endpoint', error);\n }\n }\n\n private begin(): AbortController {\n this.current?.abort();\n this.current = new AbortController();\n return this.current;\n }\n}\n","import { SeedcordErrorCode, paint } from '@seedcord/errors';\nimport { SeedcordError, validateDiscordToken } from '@seedcord/errors/internal';\nimport { Envapter } from 'envapt';\n\nimport { findCloudflared, installHint, systemLookup } from './cloudflared';\nimport { CloudflaredTunnel, systemTunnelDeps } from './CloudflaredTunnel';\nimport { InteractionsEndpoint } from './InteractionsEndpoint';\nimport { awaitReachable, PROBE_SECONDS } from './probe';\nimport { TunnelCoordinator } from './TunnelCoordinator';\n\nimport type { ResolvedTunnel } from '#core/config/schema';\nimport type { TunnelStatus } from './TunnelCoordinator';\nimport type { ILogger } from '@seedcord/types';\n\nexport function missingCloudflaredHint(platform: NodeJS.Platform): string {\n const arrow = paint.mute('→');\n return [\n `${paint.sky.bold('cloudflared')} is missing, so a tunnel can't be set up for you. Discord won't have any url to reach this bot`,\n `${arrow} install it with ${paint.mint.bold(installHint(platform))}`,\n `${arrow} or set ${paint.amber('tunnel')} to an https url you already serve, like ${paint.sky.italic('https://bot.example.com')}`\n ].join('\\n');\n}\n\nexport function createTunnelCoordinator(\n logger: ILogger,\n onStatus: (status: TunnelStatus | null) => void,\n tunnel: ResolvedTunnel,\n findBinary: () => string | undefined = () => findCloudflared(systemLookup())\n): TunnelCoordinator | undefined {\n if (tunnel.mode === 'off') return undefined;\n\n const deps = systemTunnelDeps();\n const endpoint = InteractionsEndpoint.create(() => validateDiscordToken(Envapter.get('DISCORD_BOT_TOKEN')));\n\n if (tunnel.mode === 'url') {\n return new TunnelCoordinator({\n makeTunnel: () => ({\n // no answer here means your server is down or the url is wrong\n open: async (signal, _port, onResolving) => {\n onResolving?.();\n if (await awaitReachable(tunnel.url, deps, signal)) return tunnel.url;\n throw new SeedcordError(SeedcordErrorCode.CliTunnelUnreachable, [tunnel.url, PROBE_SECONDS]);\n },\n // the forwarder is the user's process\n stop: () => undefined\n }),\n kind: 'configured',\n endpoint,\n onStatus,\n logger\n });\n }\n\n const binary = findBinary();\n if (!binary) return undefined;\n\n return new TunnelCoordinator({\n makeTunnel: (onLost) => new CloudflaredTunnel(deps, binary, onLost),\n kind: 'quick',\n endpoint,\n onStatus,\n logger\n });\n}\n","import { missingCloudflaredHint } from './createTunnelCoordinator';\n\nimport type { ResolvedTunnel } from '#core/config/schema';\nimport type { TunnelCoordinator } from './TunnelCoordinator';\nimport type { DevEvent } from '../runtime/events';\nimport type { ILogger } from '@seedcord/types';\n\nfunction same(a: ResolvedTunnel | undefined, b: ResolvedTunnel): boolean {\n if (a?.mode !== b.mode) return false;\n return a.mode === 'url' && b.mode === 'url' ? a.url === b.url : true;\n}\n\nexport class TunnelRouter {\n private coordinator: TunnelCoordinator | undefined;\n private built: ResolvedTunnel | undefined;\n\n constructor(\n private readonly make: (tunnel: ResolvedTunnel) => TunnelCoordinator | undefined,\n private readonly logger: ILogger\n ) {}\n\n // the dev session calls this from a sync callback where a rejection would end up unhandled\n public route(tunnel: ResolvedTunnel, event: DevEvent): Promise<void> {\n if (event.type !== 'server-listening') return Promise.resolve();\n return this.routeTo(tunnel, event.port).catch((error: unknown) => {\n this.logger.error('Tunnel setup failed, the bot runs without a public endpoint', error);\n });\n }\n\n private async routeTo(tunnel: ResolvedTunnel, port: number): Promise<void> {\n // each restart reloads the config\n if (!same(this.built, tunnel)) {\n // clearing the old endpoint must finish before the replacement sets its own\n await this.stop();\n this.built = tunnel;\n this.coordinator = tunnel.mode === 'off' ? undefined : this.make(tunnel);\n if (tunnel.mode !== 'off' && !this.coordinator) {\n this.logger.warn(missingCloudflaredHint(process.platform));\n }\n }\n\n await this.coordinator?.onPort(port);\n }\n\n public stop(): Promise<void> {\n const running = this.coordinator;\n this.coordinator = undefined;\n return running?.stop() ?? Promise.resolve();\n }\n}\n","import { settleWithin } from '@seedcord/core/node/internal';\nimport { Logger } from '@seedcord/logger';\n\nimport { CodegenRunner } from '#commands/codegen/CodegenRunner';\nimport { ConfigLoader } from '#core/config/ConfigLoader';\nimport { ConfigLocator } from '#core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '#core/modules/RuntimeModuleLoader';\nimport { resetChannelColors } from '#ui/channelColor';\nimport { profileMark } from '#ui/profile';\n\nimport { DevSession } from './DevSession';\nimport { ViteDevRuntime } from './runtime/ViteDevRuntime';\nimport { createTunnelCoordinator } from './tunnel/createTunnelCoordinator';\nimport { TunnelRouter } from './tunnel/TunnelRouter';\n\nimport type { ResolvedSeedcordDevConfig, ResolvedTunnel } from '#core/config/schema';\nimport type { DevStore } from '#ui/stores/DevStore';\nimport type { TunnelCoordinator } from './tunnel/TunnelCoordinator';\nimport type { ILogger } from '@seedcord/types';\n\nconst TUNNEL_TEARDOWN_MS = 3000;\n\nexport interface DevRunnerDeps {\n readonly locator: ConfigLocator;\n readonly configLoader: ConfigLoader;\n readonly store: DevStore;\n readonly codegen: CodegenRunner;\n readonly codegenLogger: ILogger;\n readonly tunnel: TunnelRouter;\n}\n\nexport class DevRunner {\n private currentSession: DevSession | null = null;\n private signalResolve?: () => void;\n private shouldQuit = false;\n private quitting?: Promise<void>;\n private isDisconnected = false;\n private isRunning = false;\n private isRegenerating = false;\n\n constructor(private readonly deps: DevRunnerDeps) {}\n\n public static create(logger: Logger, store: DevStore): DevRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const codegenLogger = new Logger('Codegen', { channel: 'cli' });\n const tunnelLogger = new Logger('Tunnel', { channel: 'cli' });\n const makeCoordinator = (tunnel: ResolvedTunnel): TunnelCoordinator | undefined =>\n createTunnelCoordinator(tunnelLogger, (status) => store.setTunnel(status), tunnel);\n\n return new DevRunner({\n locator: new ConfigLocator(logger),\n configLoader: new ConfigLoader(moduleLoader, logger),\n store,\n codegen: CodegenRunner.create(codegenLogger),\n codegenLogger,\n tunnel: new TunnelRouter(makeCoordinator, tunnelLogger)\n });\n }\n\n public async run(): Promise<void> {\n if (this.isRunning) return;\n this.isRunning = true;\n\n try {\n while (!this.shouldQuit) {\n try {\n if (this.isDisconnected) {\n await this.handleDisconnected();\n continue;\n }\n\n await this.runSession();\n } catch (error: unknown) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- quit() flips shouldQuit during the awaited session, which TS cannot see from the loop guard\n if (this.shouldQuit) break;\n await this.handleError(error);\n }\n }\n } finally {\n this.isRunning = false;\n await this.quitting; // process.exit follows run() resolving\n }\n }\n\n private async handleDisconnected(): Promise<void> {\n this.deps.store.setPhase('disconnected');\n this.deps.store.setStatus('Disconnected. Press r to restart.');\n this.deps.store.setBusy(false);\n await this.waitForSignal();\n this.deps.store.setBusy(true);\n if (!this.shouldQuit) {\n this.isDisconnected = false;\n }\n }\n\n private async runSession(): Promise<void> {\n resetChannelColors();\n this.deps.store.setPhase('starting');\n this.deps.store.setBusy(true);\n const config = await this.loadConfig();\n profileMark('config');\n this.deps.store.setIdleAnimation(config.idleAnimation);\n const runtime = new ViteDevRuntime();\n this.currentSession = new DevSession(config, runtime, this.deps.store, (event) => {\n void this.deps.tunnel.route(config.tunnel, event);\n });\n\n try {\n await this.currentSession.start(() => {\n this.deps.store.setBusy(false);\n });\n } finally {\n this.deps.store.setBusy(true);\n await this.currentSession.dispose();\n this.currentSession = null;\n }\n }\n\n private async handleError(error: unknown): Promise<void> {\n this.deps.store.setPhase('error');\n this.deps.store.setError(Error.isError(error) ? error : new Error(String(error)));\n this.deps.store.setStatus('Press r to restart.');\n this.deps.store.setBusy(false);\n await this.waitForSignal();\n this.deps.store.setBusy(true);\n }\n\n // every caller drops this promise, so run() awaits it\n public async quit(): Promise<void> {\n this.quitting ??= this.runQuit();\n return this.quitting;\n }\n\n private async runQuit(): Promise<void> {\n this.shouldQuit = true;\n this.deps.store.setPhase('quitting');\n await this.currentSession?.stop();\n // the endpoint clear is a discord round trip\n await settleWithin(this.deps.tunnel.stop(), TUNNEL_TEARDOWN_MS);\n this.signalResolve?.();\n }\n\n public async restart(): Promise<void> {\n this.isDisconnected = false;\n await this.currentSession?.stop();\n this.signalResolve?.();\n }\n\n // the tunnel stays up because a disconnect is a short parked state the user leaves by pressing r\n public async disconnect(): Promise<void> {\n // waking the signal while already parked would fall through and start a fresh session\n if (this.isDisconnected) return;\n this.isDisconnected = true;\n await this.currentSession?.stop();\n this.signalResolve?.();\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n if (shouldRefresh) void this.regenerateRegistry();\n this.currentSession?.refreshCommands(shouldRefresh);\n }\n\n // regenerates so tsc picks up the new command option types\n private async regenerateRegistry(): Promise<void> {\n if (this.isRegenerating) return;\n this.isRegenerating = true;\n try {\n await this.deps.codegen.run(false);\n } catch (error: unknown) {\n // a codegen throw must not take the dev session down\n this.deps.codegenLogger.error('Command registry regeneration failed', error);\n } finally {\n this.isRegenerating = false;\n }\n }\n\n private async waitForSignal(): Promise<void> {\n return new Promise<void>((resolve) => {\n this.signalResolve = resolve;\n });\n }\n\n private async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n const configPath = this.deps.locator.locate();\n return this.deps.configLoader.load(configPath);\n }\n}\n","import { render } from 'ink';\nimport React from 'react';\n\nimport { BaseCommand } from '#core/BaseCommand';\nimport { DevApp } from '#ui/DevApp';\nimport { profileFrame, profileReport, profileStdout } from '#ui/profile';\nimport { DevStore } from '#ui/stores/DevStore';\nimport { LogStore } from '#ui/stores/LogStore';\n\nimport { DevRunner } from './DevRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class DevCommand extends BaseCommand {\n constructor() {\n super('dev', 'Run a Seedcord instance from the config file', 'Dev');\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .action(async () => {\n profileStdout();\n const store = new DevStore();\n const runner = DevRunner.create(this.logger, store);\n\n // ink intercepts Ctrl-C under raw mode. this fires only when stdin is not raw.\n const onSignal = (): void => {\n void runner.quit();\n };\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n\n try {\n await this.runDevApp(store, runner);\n } catch (error: unknown) {\n this.logger.error('Seedcord dev failed', error);\n process.exitCode = 1;\n } finally {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n }\n\n // the in-ui logs went with the unmount\n await this.printLogLocation();\n\n // ink's raw stdin and vite's dev server keep the event loop alive after teardown\n process.exit();\n });\n }\n\n // process.exit() drops whatever a piped stdout has not flushed\n private async write(text: string): Promise<void> {\n return new Promise((resolve) => {\n process.stdout.write(text, () => {\n resolve();\n });\n });\n }\n\n private async printLogLocation(): Promise<void> {\n await this.write('seedcord dev stopped. logs: logs/\\n');\n\n const report = profileReport();\n if (report !== null) await this.write(`${report}\\n`);\n }\n\n private async runDevApp(store: DevStore, runner: DevRunner): Promise<void> {\n let failure: { error: unknown } | undefined;\n let runResult: Promise<void> = Promise.resolve();\n\n const { unmount, waitUntilExit } = render(\n React.createElement(DevApp, {\n store,\n onQuit: () => runner.quit(),\n onDisconnect: () => runner.disconnect(),\n onRestart: () => runner.restart(),\n onRefreshCommands: (shouldRefresh: boolean) => runner.refreshCommands(shouldRefresh),\n onReady: () => {\n runResult = runner\n .run()\n .finally(async () => {\n // unmounting first drops the buffered lines\n await LogStore.instance.flush();\n unmount();\n })\n // node kills the process over an unwatched rejection\n .catch((error: unknown) => {\n failure = { error };\n });\n }\n }),\n // the alternate screen restores the terminal and scrollback on quit, and ink's ESC[3J purge never fires\n {\n exitOnCtrlC: false,\n alternateScreen: true,\n onRender: ({ renderTime }) => {\n profileFrame(renderTime);\n }\n }\n );\n\n await waitUntilExit();\n // a run-loop failure has to reach the action's catch before process.exit()\n await runResult;\n if (failure) throw failure.error;\n }\n}\n","import { Command } from '@commander-js/extra-typings';\nimport { Logger } from '@seedcord/logger';\nimport { installNodeDefaults } from '@seedcord/logger/node';\nimport { Envapter, Environment } from 'envapt';\n\nimport { BuildCommand } from '#commands/build/BuildCommand';\nimport { CodegenCommand } from '#commands/codegen/CodegenCommand';\nimport { CommandsCommand } from '#commands/commands/CommandsCommand';\nimport { DevCommand } from '#commands/dev/DevCommand';\n\nimport { version } from '.';\n\nasync function main(): Promise<void> {\n if (!process.env.ENV && !process.env.ENVIRONMENT && !process.env.NODE_ENV) {\n Envapter.environment = Environment.Development;\n }\n\n installNodeDefaults();\n\n const program = new Command().name('seedcord').description('seedcord CLI').version(version);\n\n new DevCommand().register(program);\n new BuildCommand().register(program);\n new CodegenCommand().register(program);\n new CommandsCommand().register(program);\n\n await program.parseAsync(process.argv);\n}\n\nvoid main().catch((error) => {\n const logger = new Logger('CLI', { channel: 'cli' });\n logger.error('Unexpected CLI error', error);\n process.exit(1);\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["createNodeRequire","select","clackSelect","confirm","clackConfirm","confirm","select","Chip","MS_PER_SECOND","process","viteConfig","POLL_INTERVAL_MS","createServer"],"sources":["../src/core/BaseCommand.ts","../src/utils/resolveDefaultExport.ts","../src/core/config/ConfigLoader.ts","../src/core/config/ConfigLocator.ts","../src/core/modules/RuntimeModuleLoader.ts","../src/commands/build/builder/BootstrapWriter.ts","../src/commands/build/builder/TypeScriptProjectBuilder.ts","../src/commands/build/BuildRunner.ts","../src/commands/build/BuildCommand.ts","../src/commands/codegen/AugmentationBuilder.ts","../src/commands/codegen/renderAugmentation.ts","../src/commands/codegen/CodegenRunner.ts","../src/commands/codegen/CodegenCommand.ts","../src/core/interactive.ts","../src/commands/commands/classify.ts","../src/commands/commands/CleanRunner.ts","../src/core/format.ts","../src/core/prompts/requireValue.ts","../src/core/prompts/pickFromList.ts","../src/core/prompts/index.ts","../src/commands/commands/confirm.ts","../src/commands/commands/cleanPresenters.ts","../src/commands/commands/executeClean.ts","../src/commands/commands/flagClean.ts","../src/commands/commands/wizard.ts","../src/commands/commands/CommandsCommand.ts","../src/ui/components/primitives/Rule.tsx","../src/ui/filterCursor.ts","../src/ui/hooks/useDevState.ts","../src/ui/stores/LogStore.ts","../src/ui/hooks/useLogs.ts","../src/ui/hooks/useMeasuredBox.ts","../src/ui/hooks/useRailWidth.ts","../src/ui/hooks/useScroll.ts","../src/ui/palette.ts","../src/ui/stores/devPhase.ts","../src/ui/hooks/useUptime.ts","../src/ui/channelColor.ts","../src/ui/components/primitives/FilterChips.tsx","../src/ui/hotkeys.ts","../src/ui/components/primitives/LogHeader.tsx","../src/ui/components/primitives/NotificationStack.tsx","../src/ui/format.ts","../src/ui/logRows.ts","../src/ui/components/primitives/ScrollableLogView.tsx","../src/ui/components/Banner.tsx","../src/ui/components/primitives/BlinkDot.tsx","../src/ui/components/StatusBadge.tsx","../src/ui/components/primitives/Hotkeys.tsx","../src/ui/components/primitives/Sidebar.tsx","../src/ui/components/primitives/StatusLine.tsx","../src/ui/layout/DevLayout.tsx","../src/ui/components/CommandRefreshPrompt.tsx","../src/ui/components/ErrorDisplay.tsx","../src/ui/components/QuitConfirmCard.tsx","../src/ui/components/RestartRequiredCard.tsx","../src/ui/components/TunnelOpeningCard.tsx","../src/ui/notices.tsx","../src/ui/profile.ts","../src/ui/tier.ts","../src/ui/DevApp.tsx","../src/ui/stores/DevStore.ts","../src/commands/dev/TscRunner.ts","../src/commands/dev/DevSession.ts","../src/commands/dev/runtime/HmrPlugin.ts","../src/commands/dev/runtime/vite.config.ts","../src/commands/dev/runtime/ViteDevRuntime.ts","../src/commands/dev/tunnel/cloudflared.ts","../src/commands/dev/tunnel/probe.ts","../src/commands/dev/tunnel/CloudflaredTunnel.ts","../src/commands/dev/tunnel/InteractionsEndpoint.ts","../src/commands/dev/tunnel/TunnelCoordinator.ts","../src/commands/dev/tunnel/createTunnelCoordinator.ts","../src/commands/dev/tunnel/TunnelRouter.ts","../src/commands/dev/DevRunner.ts","../src/commands/dev/DevCommand.ts","../src/cli.ts"],"sourcesContent":["import { Logger } from '@seedcord/logger';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport abstract class BaseCommand {\n protected readonly logger: Logger;\n\n constructor(\n public readonly name: string,\n public readonly description: string,\n label: string\n ) {\n this.logger = new Logger(label, { channel: 'cli' });\n }\n\n public abstract register(program: Command): void;\n}\n","export function resolveDefaultExport<TValue>(moduleExport: TValue): unknown {\n let current: unknown = moduleExport;\n const visited = new Set<unknown>();\n\n while (isObjectWithDefault(current) && !visited.has(current)) {\n visited.add(current);\n current = current.default;\n }\n\n return current;\n}\n\nfunction isObjectWithDefault(value: unknown): value is { default: unknown } {\n return Boolean(value && typeof value === 'object' && 'default' in value);\n}\n","import { dirname, isAbsolute, relative, resolve } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { resolveDefaultExport } from '#utils/resolveDefaultExport';\n\nimport type { ModuleLoader } from '#core/modules/ModuleLoader';\nimport type {\n ResolvedSeedcordBuildConfig,\n ResolvedSeedcordDevConfig,\n ResolvedTunnel,\n ResolvedTypecheck,\n SeedcordBuildConfig,\n SeedcordDevConfig,\n SeedcordHmrConfig\n} from './schema';\nimport type { ILogger } from '@seedcord/types';\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n return value === undefined || typeof value === 'string';\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\nfunction invalidField(field: string, expected: string): SeedcordError {\n return new SeedcordError(SeedcordErrorCode.CliConfigInvalidField, [field, expected]);\n}\n\nfunction validateBuild(value: unknown): void {\n if (value === undefined) return;\n if (!isPlainObject(value)) throw invalidField('build', 'an object');\n if (!isOptionalString(value.outDir)) throw invalidField('build.outDir', 'a string');\n if (!isOptionalString(value.tsconfig)) throw invalidField('build.tsconfig', 'a string');\n if (!isOptionalString(value.bootstrap)) throw invalidField('build.bootstrap', 'a string');\n}\n\nfunction validateTypecheck(value: unknown): void {\n if (value === undefined || typeof value === 'boolean') return;\n if (!isPlainObject(value)) throw invalidField('hmr.typecheck', 'a boolean or an object');\n if (!isOptionalString(value.tsconfig)) throw invalidField('hmr.typecheck.tsconfig', 'a string');\n}\n\nfunction validateHmr(value: unknown): void {\n if (value === undefined) return;\n if (!isPlainObject(value)) throw invalidField('hmr', 'an object');\n if (value.restart !== undefined && !isStringArray(value.restart)) {\n throw invalidField('hmr.restart', 'an array of strings');\n }\n if (value.rollback !== undefined && typeof value.rollback !== 'boolean') {\n throw invalidField('hmr.rollback', 'a boolean');\n }\n validateTypecheck(value.typecheck);\n}\n\nfunction validateTunnel(value: unknown): void {\n if (value === undefined || typeof value === 'boolean') return;\n // discord only accepts an https interactions endpoint\n if (typeof value !== 'string' || URL.parse(value)?.protocol !== 'https:') {\n throw invalidField('tunnel', 'a boolean or an https URL');\n }\n}\n\nfunction resolveTunnel(value: boolean | string | undefined): ResolvedTunnel {\n if (value === false) return { mode: 'off' };\n if (typeof value === 'string') return { mode: 'url', url: value };\n return { mode: 'quick' };\n}\n\nfunction resolveTypecheck(value: SeedcordHmrConfig['typecheck'], root: string): ResolvedTypecheck {\n if (value === undefined || value === false) return { enabled: false };\n if (value === true || value.tsconfig === undefined) return { enabled: true };\n\n return { enabled: true, tsconfig: resolve(root, value.tsconfig) };\n}\n\nfunction validateConfig(raw: unknown): asserts raw is SeedcordDevConfig {\n if (!isPlainObject(raw)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidExport);\n if (typeof raw.instance !== 'string' || raw.instance.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigMissingInstance);\n }\n if (typeof raw.entry !== 'string' || raw.entry.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigMissingEntry);\n }\n if (!isOptionalString(raw.root)) throw invalidField('root', 'a string');\n if (raw.idleAnimation !== undefined && typeof raw.idleAnimation !== 'boolean') {\n throw invalidField('idleAnimation', 'a boolean');\n }\n validateTunnel(raw.tunnel);\n validateBuild(raw.build);\n validateHmr(raw.hmr);\n}\n\nexport class ConfigLoader {\n constructor(\n private readonly modules: ModuleLoader,\n private readonly logger: ILogger\n ) {}\n\n public async load(configPath: string): Promise<ResolvedSeedcordDevConfig> {\n const loadedModule = await this.modules.importModule(configPath);\n const config: unknown = await Promise.resolve(resolveDefaultExport(loadedModule));\n validateConfig(config);\n\n const configDir = dirname(configPath);\n const root = resolve(configDir, config.root ?? '.');\n const instance = this.resolveWithinRoot(root, config.instance);\n const entry = this.resolveWithinRoot(root, config.entry);\n this.assertEntryWithinRoot(root, entry);\n const build = this.resolveBuildOptions(configDir, config.build);\n const typecheck = resolveTypecheck(config.hmr?.typecheck, root);\n\n this.logger.debug(`Loaded configuration from ${configPath}`);\n this.logger.trace(`Resolved root: ${root}`);\n this.logger.trace(`Resolved instance: ${instance}`);\n this.logger.trace(`Resolved entry: ${entry}`);\n this.logger.trace(`Resolved build outDir: ${build.outDir}`);\n if (build.tsconfig) this.logger.trace(`Resolved build tsconfig: ${build.tsconfig}`);\n if (typecheck.enabled) this.logger.trace(`Typecheck tsconfig: ${typecheck.tsconfig ?? 'nearest'}`);\n this.logger.trace(`Resolved bootstrap: ${build.bootstrap}`);\n\n return {\n instance,\n root,\n configFile: configPath,\n entry,\n build,\n typecheck,\n idleAnimation: config.idleAnimation ?? true,\n tunnel: resolveTunnel(config.tunnel),\n hmr: config.hmr\n } satisfies ResolvedSeedcordDevConfig;\n }\n\n private resolveWithinRoot(root: string, target: string): string {\n if (isAbsolute(target)) return target;\n return resolve(root, target);\n }\n\n private assertEntryWithinRoot(root: string, entry: string): void {\n const relativePath = relative(root, entry);\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigEntryOutsideRoot, [entry, root]);\n }\n }\n\n private resolveBuildOptions(\n configDir: string,\n build: SeedcordBuildConfig | undefined\n ): ResolvedSeedcordBuildConfig {\n const outDir = resolve(configDir, build?.outDir ?? 'dist');\n const bootstrapValue = build?.bootstrap;\n const bootstrap = bootstrapValue ? this.resolveBootstrap(outDir, bootstrapValue) : resolve(outDir, 'index.mjs');\n const tsconfig = build?.tsconfig ? resolve(configDir, build.tsconfig) : undefined;\n\n const resolvedBuild: ResolvedSeedcordBuildConfig = tsconfig\n ? { outDir, bootstrap, tsconfig }\n : { outDir, bootstrap };\n\n return resolvedBuild;\n }\n\n private resolveBootstrap(outDir: string, bootstrap: string): string {\n if (isAbsolute(bootstrap)) return bootstrap;\n return resolve(outDir, bootstrap);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { SEEDCORD_CONFIG_FILENAMES } from './schema';\n\nimport type { ILogger } from '@seedcord/types';\n\nexport class ConfigLocator {\n constructor(private readonly logger: ILogger) {}\n\n public locate(baseDir = process.cwd()): string {\n const normalizedBase = resolve(baseDir);\n for (const candidate of SEEDCORD_CONFIG_FILENAMES) {\n const fullPath = join(normalizedBase, candidate);\n if (existsSync(fullPath)) {\n this.logger.trace(`Found config at ${fullPath}`);\n return fullPath;\n }\n }\n\n throw new SeedcordError(SeedcordErrorCode.CliConfigNotFound, [normalizedBase, SEEDCORD_CONFIG_FILENAMES]);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, extname, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { createJiti } from 'jiti';\nimport { tsImport } from 'tsx/esm/api';\n\nimport type { ModuleLoader } from './ModuleLoader';\n\ntype TsconfigOption = string | false;\n\ninterface RuntimeModuleLoaderOptions {\n tsconfig?: TsconfigOption;\n forceTsx?: boolean;\n}\n\nconst TS_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);\n\nexport class RuntimeModuleLoader implements ModuleLoader {\n private readonly jiti = createJiti(import.meta.url, {\n cache: false,\n interopDefault: true,\n extensions: ['.ts', '.tsx', '.mts', '.cts', '.js', '.mjs', '.cjs']\n });\n\n constructor(private readonly options: RuntimeModuleLoaderOptions = {}) {}\n\n public async importModule<TModule = unknown>(entryPath: string): Promise<TModule> {\n const normalized = resolve(entryPath);\n if (!existsSync(normalized)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [normalized]);\n }\n\n if (this.shouldUseTsx(normalized)) {\n return this.importWithTsx<TModule>(normalized);\n }\n\n return this.importWithNode<TModule>(normalized);\n }\n\n private shouldUseTsx(filePath: string): boolean {\n if (this.options.forceTsx) return true;\n return TS_EXTENSIONS.has(extname(filePath).toLowerCase());\n }\n\n private async importWithTsx<TModule = unknown>(entryPath: string): Promise<TModule> {\n const specifier = pathToFileURL(entryPath).href;\n const tsconfig = this.resolveTsconfig(entryPath);\n\n try {\n return (await tsImport(specifier, { parentURL: import.meta.url, tsconfig })) as TModule;\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown tsx error';\n throw new SeedcordError(SeedcordErrorCode.CliTsxImportFailed, [entryPath, reason]);\n }\n }\n\n private async importWithNode<TModule = unknown>(entryPath: string): Promise<TModule> {\n const specifier = pathToFileURL(entryPath).href;\n\n try {\n return (await import(specifier)) as TModule;\n } catch (nativeError: unknown) {\n try {\n return await this.jiti.import(entryPath);\n } catch (fallbackError: unknown) {\n const nativeReason = Error.isError(nativeError) ? nativeError.message : 'Unknown ESM import error';\n const fallbackReason = Error.isError(fallbackError) ? fallbackError.message : 'Unknown jiti error';\n throw new SeedcordError(SeedcordErrorCode.CliImportFailed, [entryPath, nativeReason, fallbackReason]);\n }\n }\n }\n\n private resolveTsconfig(entryPath: string): TsconfigOption {\n if (this.options.tsconfig !== undefined) {\n return this.options.tsconfig;\n }\n\n return this.findNearestTsconfig(dirname(entryPath)) ?? false;\n }\n\n private findNearestTsconfig(startDir: string): string | undefined {\n const candidate = resolve(startDir, 'tsconfig.json');\n if (existsSync(candidate)) return candidate;\n\n const parent = dirname(startDir);\n if (parent === startDir) return undefined;\n\n return this.findNearestTsconfig(parent);\n }\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, relative } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport class BootstrapWriter {\n constructor(private readonly logger: ILogger) {}\n\n public async write(config: ResolvedSeedcordDevConfig, emittedEntry: string): Promise<void> {\n const target = config.build.bootstrap;\n const relativeImport = this.formatImportPath(relative(dirname(target), emittedEntry));\n const contents = `import '${relativeImport}';\\n`;\n\n try {\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, contents, 'utf8');\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown error';\n throw new SeedcordError(SeedcordErrorCode.CliBootstrapWriteFailed, [target, reason]);\n }\n\n this.logger.info(`Bootstrap file created at ${target}`);\n }\n\n private formatImportPath(fragment: string): string {\n const normalized = fragment.replaceAll('\\\\', '/');\n return normalized.startsWith('.') ? normalized : `./${normalized}`;\n }\n}\n","import { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { createRequire as createNodeRequire } from 'node:module';\nimport { dirname, extname, relative, resolve } from 'node:path';\n\nimport { isSeedcordError, SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport interface BuildResult {\n emittedEntry: string;\n}\n\ninterface ProcessResult {\n exitCode: number;\n output: string;\n}\n\nexport class TypeScriptProjectBuilder {\n constructor(private readonly logger: ILogger) {}\n\n public async build(config: ResolvedSeedcordDevConfig): Promise<BuildResult> {\n const tsconfigPath = this.resolveTsconfig(config);\n const projectDir = dirname(config.configFile);\n\n await mkdir(config.build.outDir, { recursive: true });\n\n this.logger.info(`Building Seedcord project via tsc using ${tsconfigPath}`);\n\n try {\n await this.runTsc(projectDir, tsconfigPath);\n await this.rewriteSpecifiers(projectDir, tsconfigPath);\n } catch (error: unknown) {\n if (isSeedcordError(error)) throw error;\n\n const reason = Error.isError(error) ? error.message : 'Unknown build error';\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [reason]);\n }\n\n const emittedEntry = this.resolveEmittedEntry(config);\n if (!existsSync(emittedEntry)) {\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Expected output file ${emittedEntry} missing after build`\n ]);\n }\n\n this.logger.info(`Emitted entry: ${emittedEntry}`);\n return { emittedEntry } satisfies BuildResult;\n }\n\n private async runTsc(projectDir: string, tsconfigPath: string): Promise<void> {\n const tscPath = this.resolveProjectTsc(projectDir);\n\n const args = ['-p', tsconfigPath, '--pretty', 'false', '--inlineSources'];\n // tsc rejects --sourceMap alongside a project's inlineSourceMap; only force it otherwise.\n if (!(await this.usesInlineSourceMap(projectDir, tsconfigPath))) args.push('--sourceMap');\n\n const result = await this.runNodeScript(projectDir, tscPath, args);\n if (result.exitCode === 0) return;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `TypeScript compilation failed:\\n${this.truncateOutput(result.output)}`\n ]);\n }\n\n private async usesInlineSourceMap(projectDir: string, tsconfigPath: string): Promise<boolean> {\n const tscPath = this.resolveProjectTsc(projectDir);\n const result = await this.runNodeScript(projectDir, tscPath, ['--showConfig', '-p', tsconfigPath]);\n if (result.exitCode !== 0) return false;\n\n try {\n const config = JSON.parse(result.output) as { compilerOptions?: { inlineSourceMap?: boolean } };\n return config.compilerOptions?.inlineSourceMap === true;\n } catch {\n return false;\n }\n }\n\n // tsc emits every specifier as written\n private async rewriteSpecifiers(projectDir: string, tsconfigPath: string): Promise<void> {\n const binPath = this.resolveTscAlias();\n\n const result = await this.runNodeScript(projectDir, binPath, [\n '-p',\n tsconfigPath,\n '--resolve-full-paths',\n '--resolve-full-extension',\n '.js'\n ]);\n if (result.exitCode === 0) return;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Failed to rewrite import specifiers:\\n${this.truncateOutput(result.output)}`\n ]);\n }\n\n private resolveProjectTsc(projectDir: string): string {\n const projectRequire = this.createProjectRequire(projectDir);\n\n try {\n return projectRequire.resolve('typescript/bin/tsc');\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown resolution error';\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Unable to resolve typescript. Ensure it is installed in this project.\\n${reason}`\n ]);\n }\n }\n\n private resolveTscAlias(): string {\n const selfRequire = createNodeRequire(import.meta.url);\n\n return selfRequire.resolve('tsc-alias/dist/bin/index.js');\n }\n\n private createProjectRequire(projectDir: string): NodeJS.Require {\n const candidate = resolve(projectDir, 'package.json');\n if (existsSync(candidate)) return createNodeRequire(candidate);\n\n return createNodeRequire(import.meta.url);\n }\n\n private async runNodeScript(cwd: string, scriptPath: string, args: string[]): Promise<ProcessResult> {\n return await this.runProcess(process.execPath, [scriptPath, ...args], cwd);\n }\n\n private runProcess(cmd: string, args: string[], cwd: string): Promise<ProcessResult> {\n return new Promise((resolvePromise, rejectPromise) => {\n const child = spawn(cmd, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });\n\n let output = '';\n\n child.stdout.on('data', (chunk) => {\n output += String(chunk);\n });\n\n child.stderr.on('data', (chunk) => {\n output += String(chunk);\n });\n\n child.on('error', rejectPromise);\n\n child.on('close', (code) => {\n resolvePromise({ exitCode: code ?? 1, output });\n });\n });\n }\n\n private truncateOutput(text: string, maxChars = 24_000): string {\n const trimmed = text.trim();\n if (trimmed.length <= maxChars) return trimmed;\n return `${trimmed.slice(0, maxChars)}\\n...output truncated...`;\n }\n\n private resolveTsconfig(config: ResolvedSeedcordDevConfig): string {\n if (config.build.tsconfig) {\n if (!existsSync(config.build.tsconfig)) {\n throw new SeedcordError(SeedcordErrorCode.CliBuildTsconfigNotFound, [config.build.tsconfig]);\n }\n\n return config.build.tsconfig;\n }\n\n const configDir = dirname(config.configFile);\n const candidate = ['tsconfig.build.json', 'tsconfig.json']\n .map((file) => resolve(configDir, file))\n .find((candidatePath) => existsSync(candidatePath));\n\n if (candidate) return candidate;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildTsconfigNotFound, [configDir]);\n }\n\n private resolveEmittedEntry(config: ResolvedSeedcordDevConfig): string {\n const relFromRoot = relative(config.root, config.entry);\n const relNoExt = relFromRoot.slice(0, relFromRoot.length - extname(relFromRoot).length);\n\n const basePath = resolve(config.build.outDir, relNoExt);\n const candidateExts = ['.js', '.mjs', '.cjs'];\n\n for (const ext of candidateExts) {\n const candidate = `${basePath}${ext}`;\n if (existsSync(candidate)) return candidate;\n }\n\n // Fallback if no emitted file was found\n return `${basePath}.js`;\n }\n}\n","import { existsSync } from 'node:fs';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { ConfigLoader } from '#core/config/ConfigLoader';\nimport { ConfigLocator } from '#core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '#core/modules/RuntimeModuleLoader';\n\nimport { BootstrapWriter } from './builder/BootstrapWriter';\nimport { TypeScriptProjectBuilder } from './builder/TypeScriptProjectBuilder';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport class BuildRunner {\n constructor(\n private readonly locator: ConfigLocator,\n private readonly configLoader: ConfigLoader,\n private readonly builder: TypeScriptProjectBuilder,\n private readonly bootstrapWriter: BootstrapWriter,\n private readonly logger: ILogger\n ) {}\n\n public static create(logger: ILogger): BuildRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const locator = new ConfigLocator(logger);\n const configLoader = new ConfigLoader(moduleLoader, logger);\n const builder = new TypeScriptProjectBuilder(logger);\n const bootstrapWriter = new BootstrapWriter(logger);\n\n return new BuildRunner(locator, configLoader, builder, bootstrapWriter, logger);\n }\n\n public async run(): Promise<void> {\n const config = await this.loadConfig();\n this.assertEntryExists(config.entry);\n const { emittedEntry } = await this.builder.build(config);\n await this.bootstrapWriter.write(config, emittedEntry);\n this.logger.info('Seedcord build finished successfully.');\n }\n\n private async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n const configPath = this.locator.locate();\n return this.configLoader.load(configPath);\n }\n\n private assertEntryExists(entryPath: string): void {\n if (!existsSync(entryPath)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [entryPath]);\n }\n }\n}\n","import { isSeedcordError } from '@seedcord/errors';\n\nimport { BaseCommand } from '#core/BaseCommand';\n\nimport { BuildRunner } from './BuildRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class BuildCommand extends BaseCommand {\n private readonly runner: BuildRunner;\n\n constructor() {\n super('build', 'Compile a Seedcord project from the config file', 'Build');\n this.runner = BuildRunner.create(this.logger);\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .action(async () => {\n try {\n await this.runner.run();\n } catch (error: unknown) {\n this.logger.error('Seedcord build failed', error);\n if (isSeedcordError(error)) process.exitCode = 1;\n else process.exit(1);\n }\n });\n }\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { routeLeavesOf, type SlashRouteLeaf } from '@seedcord/utils/internal';\nimport { ApplicationCommandOptionType, ApplicationCommandType, InteractionContextType } from 'discord-api-types/v10';\n\nimport type { OptionKind, RouteCache, SlashOption, SlashRouteEntry } from '@seedcord/core/internal';\nimport type { EmojiConfig, ILogger } from '@seedcord/types';\nimport type {\n APIApplicationCommandBasicOption,\n RESTPostAPIApplicationCommandsJSONBody,\n RESTPostAPIChatInputApplicationCommandsJSONBody,\n RESTPostAPIContextMenuApplicationCommandsJSONBody\n} from 'discord-api-types/v10';\n\nexport type RouteOptions = Record<string, SlashOption>;\n\n// keyed by route string (`cmd`, `cmd/sub`, or `cmd/group/sub`)\nexport type SlashTables = Record<string, SlashRouteEntry>;\n\n// keyed by the command name discord shows in the menu\nexport type ContextMenuTables = Record<string, { cache: RouteCache }>;\n\nexport type EmojiKinds = Record<string, 'string' | 'tuple'>;\n\nexport interface Augmentation {\n slash: SlashTables;\n userContextMenus: ContextMenuTables;\n messageContextMenus: ContextMenuTables;\n emojis: EmojiKinds;\n}\n\nexport interface ScannedCommand {\n sourceFile: string;\n json: RESTPostAPIApplicationCommandsJSONBody;\n}\n\ntype CommandOption = SlashRouteLeaf['options'][number];\ntype BasicOption = Exclude<\n CommandOption,\n { type: ApplicationCommandOptionType.Subcommand | ApplicationCommandOptionType.SubcommandGroup }\n>;\n\n// discord-api-types renaming or adding a basic option type breaks this object\nconst KIND_BY_TYPE = {\n [ApplicationCommandOptionType.String]: 'string',\n [ApplicationCommandOptionType.Integer]: 'integer',\n [ApplicationCommandOptionType.Number]: 'number',\n [ApplicationCommandOptionType.Boolean]: 'boolean',\n [ApplicationCommandOptionType.User]: 'user',\n [ApplicationCommandOptionType.Channel]: 'channel',\n [ApplicationCommandOptionType.Role]: 'role',\n [ApplicationCommandOptionType.Mentionable]: 'mentionable',\n [ApplicationCommandOptionType.Attachment]: 'attachment'\n} as const satisfies Record<APIApplicationCommandBasicOption['type'], OptionKind>;\n\n// discord reads a command with no contexts as reachable from all three\nfunction cacheStateOf(contexts: RESTPostAPIApplicationCommandsJSONBody['contexts']): 'cached' | undefined {\n if (!contexts || contexts.length === 0) return undefined;\n return contexts.every((context) => context === InteractionContextType.Guild) ? 'cached' : undefined;\n}\n\nfunction mapEmojis(emojiConfig: EmojiConfig): EmojiKinds {\n const emojis: EmojiKinds = {};\n for (const [key, value] of Object.entries(emojiConfig)) {\n emojis[key] = Array.isArray(value) ? 'tuple' : 'string';\n }\n return emojis;\n}\n\n// reads each builder back through toJSON() because djs erases option names at the type level\nexport class AugmentationBuilder {\n constructor(private readonly logger: ILogger) {}\n\n public generate(commands: readonly ScannedCommand[], emojiConfig: EmojiConfig): Augmentation {\n const slash: SlashTables = {};\n const sourceByRoute = new Map<string, string>();\n const sourceByUserName = new Map<string, string>();\n const sourceByMessageName = new Map<string, string>();\n const userMenus = new Map<string, { cache: 'cached' | undefined }>();\n const messageMenus = new Map<string, { cache: 'cached' | undefined }>();\n\n for (const command of commands) {\n const { json } = command;\n switch (json.type) {\n case ApplicationCommandType.User: {\n this.collectContextMenu('user', json, command.sourceFile, sourceByUserName, userMenus);\n break;\n }\n case ApplicationCommandType.Message: {\n this.collectContextMenu('message', json, command.sourceFile, sourceByMessageName, messageMenus);\n break;\n }\n case undefined:\n case ApplicationCommandType.ChatInput: {\n this.collectSlash(json, command.sourceFile, slash, sourceByRoute);\n break;\n }\n // No default\n }\n }\n\n const userContextMenus = Object.fromEntries(userMenus);\n const messageContextMenus = Object.fromEntries(messageMenus);\n const emojis = mapEmojis(emojiConfig);\n this.logger.debug(\n `Generated ${Object.keys(slash).length} slash route(s), ${Object.keys(userContextMenus).length} user and ${Object.keys(messageContextMenus).length} message context-menu command(s), ${Object.keys(emojis).length} emoji(s)`\n );\n return { slash, userContextMenus, messageContextMenus, emojis };\n }\n\n private collectSlash(\n json: RESTPostAPIChatInputApplicationCommandsJSONBody,\n sourceFile: string,\n slash: SlashTables,\n sourceByRoute: Map<string, string>\n ): void {\n this.warnEmptyGroups(json);\n const cacheState = cacheStateOf(json.contexts);\n for (const leaf of routeLeavesOf(json)) {\n // declaration merging folds a duplicate route in silently\n const firstFile = sourceByRoute.get(leaf.route);\n if (firstFile !== undefined) {\n throw new SeedcordError(SeedcordErrorCode.CliCodegenDuplicateRoute, [\n leaf.route,\n firstFile,\n sourceFile\n ]);\n }\n sourceByRoute.set(leaf.route, sourceFile);\n slash[leaf.route] = { options: this.mapOptions(leaf.options), cache: cacheState };\n }\n }\n\n private collectContextMenu(\n kind: 'user' | 'message',\n json: RESTPostAPIContextMenuApplicationCommandsJSONBody,\n sourceFile: string,\n sourceByName: Map<string, string>,\n menus: Map<string, { cache: 'cached' | undefined }>\n ): void {\n const firstFile = sourceByName.get(json.name);\n if (firstFile !== undefined) {\n throw new SeedcordError(SeedcordErrorCode.CliCodegenDuplicateContextMenu, [\n kind,\n json.name,\n firstFile,\n sourceFile\n ]);\n }\n sourceByName.set(json.name, sourceFile);\n menus.set(json.name, { cache: cacheStateOf(json.contexts) });\n }\n\n // toJSON() allows an empty subcommand group though discord rejects it at deploy. routeLeavesOf gives it\n // no route, so it never reaches the tables\n private warnEmptyGroups(json: RESTPostAPIChatInputApplicationCommandsJSONBody): void {\n for (const option of json.options ?? []) {\n if (option.type === ApplicationCommandOptionType.SubcommandGroup && (option.options ?? []).length === 0) {\n this.logger.warn(`Slash group \\`${json.name}/${option.name}\\` has no subcommands and will not deploy.`);\n }\n }\n }\n\n private mapOptions(options: readonly CommandOption[]): RouteOptions {\n const table: RouteOptions = {};\n for (const option of options) {\n if (\n option.type === ApplicationCommandOptionType.Subcommand ||\n option.type === ApplicationCommandOptionType.SubcommandGroup\n ) {\n continue;\n }\n table[option.name] = this.toSlashOption(option);\n }\n return table;\n }\n\n private toSlashOption(option: BasicOption): SlashOption {\n // empty choices would narrow the value to never\n const choices =\n 'choices' in option && option.choices && option.choices.length > 0\n ? option.choices.map((choice) => choice.value)\n : undefined;\n const autocomplete = 'autocomplete' in option && option.autocomplete === true ? true : undefined;\n // sorted so a reordered declaration still matches under `--check`\n const channelTypes =\n 'channel_types' in option && option.channel_types && option.channel_types.length > 0\n ? [...option.channel_types].sort((first, second) => first - second)\n : undefined;\n return {\n kind: KIND_BY_TYPE[option.type],\n required: option.required ?? false,\n ...(choices && { choices }),\n ...(autocomplete && { autocomplete }),\n ...(channelTypes && { channelTypes })\n };\n }\n}\n","import type { EmojiKinds, Augmentation, ContextMenuTables, RouteOptions, SlashTables } from './AugmentationBuilder';\nimport type { SlashOption, SlashRouteEntry } from '@seedcord/core/internal';\n\nconst BANNER = `// Generated by \\`seedcord codegen\\`. Do not edit by hand.\n// Run \\`seedcord codegen\\` after changing your commands, plugins, or emoji config.`;\n\nconst BOT_BINDING = 'Bot';\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst CONTROL_CHAR = 0x20;\nconst HEX_RADIX = 16;\n\ninterface AttachedPlugins {\n readonly specifier: string; // relative to the generated file at config.root\n readonly keys: readonly string[];\n}\n\nexport function renderAugmentation(registry: Augmentation, target: string, plugins?: AttachedPlugins): string {\n const keys = [...(plugins?.keys ?? [])].sort(compare);\n const attached = plugins !== undefined && keys.length > 0;\n const botImport = attached ? `import type ${BOT_BINDING} from '${escapeLiteral(plugins.specifier)}';\\n\\n` : '';\n const coreRows = attached ? ` interface Core {\\n${renderPluginRows(keys)}\\n }\\n` : '';\n\n // prettier-ignore binds to the next statement, and the declare module is the whole file\n const header = `${BANNER}\\n\\n${botImport}// prettier-ignore\\ndeclare module '${target}' {\\n`;\n\n return (\n `${header + coreRows} interface SlashRegistry {\\n${renderSlashRows(registry.slash)}\\n }\\n` +\n ` interface UserContextMenuRegistry {\\n${renderContextMenuRows(registry.userContextMenus)}\\n }\\n` +\n ` interface MessageContextMenuRegistry {\\n${renderContextMenuRows(registry.messageContextMenus)}\\n }\\n` +\n ` interface EmojiMap {\\n${renderEmojiRows(registry.emojis)}\\n }\\n` +\n `}\\n\\nexport {};\\n`\n );\n}\n\n// the indexed access defers resolution. an `extends Pick<typeof Bot, ...>` clause resolves while the bot\n// constant is still being inferred, and a plugin ctor naming Core closes that loop (TS7022).\nfunction renderPluginRows(keys: readonly string[]): string {\n return keys.map((key) => ` ${renderKey(key)}: (typeof ${BOT_BINDING})['${escapeLiteral(key)}'];`).join('\\n');\n}\n\nfunction renderSlashRows(tables: SlashTables): string {\n return Object.entries(tables)\n .sort(([first], [second]) => compare(first, second))\n .map(([route, row]) => ` ${renderKey(route)}: ${renderRow(row)};`)\n .join('\\n');\n}\n\nfunction renderContextMenuRows(menus: ContextMenuTables): string {\n return Object.entries(menus)\n .sort(([first], [second]) => compare(first, second))\n .map(([name, { cache }]) => ` ${renderKey(name)}: ${renderCacheRow(cache)};`)\n .join('\\n');\n}\n\nfunction renderCacheRow(cache: 'cached' | undefined): string {\n return `{ cache: ${cache === undefined ? 'undefined' : `'${cache}'`} }`;\n}\n\n// InjectedEmojiMap reads this tag to type Emojis.X as GuildEmoji or ApplicationEmoji\nfunction renderEmojiRows(emojis: EmojiKinds): string {\n return Object.entries(emojis)\n .sort(([first], [second]) => compare(first, second))\n .map(([key, kind]) => ` ${renderKey(key)}: '${kind === 'tuple' ? 'guild' : 'application'}';`)\n .join('\\n');\n}\n\nfunction renderRow(row: SlashRouteEntry): string {\n const cache = row.cache === undefined ? 'undefined' : `'${row.cache}'`;\n return `{ options: ${renderOptions(row.options)}; cache: ${cache} }`;\n}\n\nfunction renderOptions(options: RouteOptions): string {\n const entries = Object.entries(options);\n if (entries.length === 0) return '{}';\n return `{ ${entries.map(([name, opt]) => `${renderKey(name)}: ${renderOption(opt)}`).join('; ')} }`;\n}\n\nfunction renderOption(opt: SlashOption): string {\n const parts = [`kind: '${opt.kind}'`, `required: ${opt.required}`];\n if (opt.choices && opt.choices.length > 0) parts.push(`choices: [${opt.choices.map(renderChoice).join(', ')}]`);\n if (opt.autocomplete) parts.push('autocomplete: true');\n // wire numbers, mapped to channel subtypes by the typed view\n if (opt.channelTypes && opt.channelTypes.length > 0) parts.push(`channelTypes: [${opt.channelTypes.join(', ')}]`);\n return `{ ${parts.join('; ')} }`;\n}\n\nfunction renderChoice(value: string | number): string {\n if (typeof value !== 'string') return String(value);\n return `'${escapeLiteral(value)}'`;\n}\n\n// discord allows spaces and apostrophes in a context-menu name\nfunction renderKey(name: string): string {\n return IDENTIFIER.test(name) ? name : `'${escapeLiteral(name)}'`;\n}\n\nfunction escapeLiteral(value: string): string {\n let escaped = '';\n for (const char of value) {\n const code = char.charCodeAt(0);\n switch (char) {\n case '\\\\': {\n escaped += '\\\\\\\\';\n break;\n }\n case \"'\": {\n escaped += String.raw`\\'`;\n break;\n }\n case '\\n': {\n escaped += String.raw`\\n`;\n break;\n }\n case '\\r': {\n escaped += String.raw`\\r`;\n break;\n }\n case '\\t': {\n escaped += String.raw`\\t`;\n break;\n }\n default: {\n if (code < CONTROL_CHAR) escaped += String.raw`\\x${code.toString(HEX_RADIX).padStart(2, '0')}`;\n else escaped += char;\n }\n }\n }\n return escaped;\n}\n\nfunction compare(first: string, second: string): number {\n if (first < second) return -1;\n return first > second ? 1 : 0;\n}\n","import { existsSync } from 'node:fs';\nimport { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { SeedcordBrand, type Brandable, type SeedcordInstance } from '@seedcord/types/internal';\nimport { isTsOrJsFile } from '@seedcord/utils/node';\nimport { ApplicationCommandType } from 'discord-api-types/v10';\n\nimport { ConfigLoader } from '#core/config/ConfigLoader';\nimport { ConfigLocator } from '#core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '#core/modules/RuntimeModuleLoader';\nimport { resolveDefaultExport } from '#utils/resolveDefaultExport';\n\nimport { AugmentationBuilder } from './AugmentationBuilder';\nimport { renderAugmentation } from './renderAugmentation';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { ModuleLoader } from '#core/modules/ModuleLoader';\nimport type { ScannedCommand } from './AugmentationBuilder';\nimport type { EmojiConfig, ILogger, TypedOmit } from '@seedcord/types';\nimport type { RESTPostAPIApplicationCommandsJSONBody } from 'discord-api-types/v10';\n\nconst OUTPUT_FILENAME = 'seedcord-gen.d.ts';\n\nconst ENTRY_EXTENSION = /\\.[mc]?[jt]sx?$/;\n\ninterface BuilderLike {\n component: { toJSON: () => unknown };\n}\n\ninterface ScanResult {\n commands: ScannedCommand[];\n emojis: EmojiConfig;\n augmentTarget: string;\n pluginKeys: readonly string[];\n}\n\n// extensionless resolves under moduleResolution bundler, which a seedcord project sets\nfunction botSpecifier(root: string, instance: string): string {\n const posix = relative(root, instance).split(sep).join('/').replace(ENTRY_EXTENSION, '');\n return posix.startsWith('.') ? posix : `./${posix}`;\n}\n\nexport class CodegenRunner {\n constructor(\n private readonly locator: ConfigLocator,\n private readonly configLoader: ConfigLoader,\n private readonly moduleLoader: ModuleLoader,\n private readonly generator: AugmentationBuilder,\n private readonly logger: ILogger\n ) {}\n\n public static create(logger: ILogger): CodegenRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const locator = new ConfigLocator(logger);\n const configLoader = new ConfigLoader(moduleLoader, logger);\n const generator = new AugmentationBuilder(logger);\n\n return new CodegenRunner(locator, configLoader, moduleLoader, generator, logger);\n }\n\n public async run(check: boolean): Promise<void> {\n const config = await this.loadConfig();\n const { commands, emojis, augmentTarget, pluginKeys } = await this.scan(config);\n const rendered = renderAugmentation(this.generator.generate(commands, emojis), augmentTarget, {\n specifier: botSpecifier(config.root, config.instance),\n keys: pluginKeys\n });\n const outputPath = resolve(config.root, OUTPUT_FILENAME);\n\n if (check) {\n await this.check(rendered, outputPath);\n return;\n }\n\n await this.write(rendered, outputPath);\n }\n\n private async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n return this.configLoader.load(this.locator.locate());\n }\n\n private async scan(config: ResolvedSeedcordDevConfig): Promise<ScanResult> {\n const { commandsDir, emojis, augmentTarget, pluginKeys } = await this.resolveInstance(config);\n\n const commands: ScannedCommand[] = [];\n if (commandsDir) {\n for await (const command of this.walk(commandsDir, new Set(), true)) {\n commands.push(command);\n }\n }\n return { commands, emojis, augmentTarget, pluginKeys };\n }\n\n // the bot scans under tsx/vite where import() takes a .ts path. codegen runs under plain node, hence the\n // tsx-backed module loader below.\n private async *walk(dir: string, seen: Set<unknown>, isRoot: boolean): AsyncGenerator<ScannedCommand> {\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown error';\n // an unreadable commands dir would pass --check against a stale registry\n if (isRoot) throw new SeedcordError(SeedcordErrorCode.CliCodegenCommandsDirUnreadable, [dir, reason]);\n this.logger.warn(`Skipping unreadable directory ${dir}. ${reason}.`);\n return;\n }\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n yield* this.walk(fullPath, seen, false);\n } else if (isTsOrJsFile(entry)) {\n const imported = await this.moduleLoader.importModule<Record<string, unknown>>(fullPath);\n for (const exported of Object.values(imported)) {\n // a barrel re-exports the same class object\n if (seen.has(exported)) continue;\n seen.add(exported);\n const json = this.commandJsonOf(exported);\n if (json) yield { sourceFile: fullPath, json };\n }\n }\n }\n }\n\n private async resolveInstance(\n config: ResolvedSeedcordDevConfig\n ): Promise<TypedOmit<ScanResult, 'commands'> & { commandsDir: string | undefined }> {\n // reading commands.path and emojis constructs the bot, so its lifecycle and plugin setup logs\n // appear here. codegen never starts it, nothing logs in or connects\n this.logger.debug('Loading instance to resolve the commands directory');\n const module = await this.moduleLoader.importModule(config.instance);\n const instance = resolveDefaultExport(module);\n if (!this.isSeedcordInstance(instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliInstanceInvalid);\n }\n\n // the bot resolves commands.path against cwd\n const commandsPath = instance.config.bot.commands.path;\n return {\n commandsDir: commandsPath ? resolve(process.cwd(), commandsPath) : undefined,\n emojis: instance.config.bot.emojis ?? {},\n augmentTarget: instance.augmentTarget,\n pluginKeys: instance.pluginKeys\n };\n }\n\n private commandJsonOf(exported: unknown): RESTPostAPIApplicationCommandsJSONBody | undefined {\n if (typeof exported !== 'function') return undefined;\n\n let instance: unknown;\n try {\n instance = new (exported as new () => unknown)();\n } catch {\n return undefined;\n }\n\n if (!this.isBuilderLike(instance)) return undefined;\n const json = instance.component.toJSON();\n if (!this.isApplicationCommand(json)) return undefined;\n return json;\n }\n\n private isBuilderLike(value: unknown): value is BuilderLike {\n if (typeof value !== 'object' || value === null) return false;\n const component = (value as { component?: unknown }).component;\n return (\n typeof component === 'object' &&\n component !== null &&\n typeof (component as BuilderLike['component']).toJSON === 'function'\n );\n }\n\n private isApplicationCommand(json: unknown): json is RESTPostAPIApplicationCommandsJSONBody {\n if (typeof json !== 'object' || json === null) return false;\n const { name, type } = json as { name?: unknown; type?: unknown };\n if (typeof name !== 'string') return false;\n // chat-input omits type or sets ChatInput, context menus set User or Message\n return (\n type === undefined ||\n type === ApplicationCommandType.ChatInput ||\n type === ApplicationCommandType.User ||\n type === ApplicationCommandType.Message\n );\n }\n\n private isSeedcordInstance(candidate: unknown): candidate is SeedcordInstance {\n return typeof candidate === 'object' && candidate !== null && (candidate as Brandable)[SeedcordBrand] === true;\n }\n\n private async write(rendered: string, outputPath: string): Promise<void> {\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, rendered, 'utf8');\n this.logger.info(`Augmentations written to ${outputPath}`);\n }\n\n private async check(rendered: string, outputPath: string): Promise<void> {\n const onDisk = existsSync(outputPath) ? await readFile(outputPath, 'utf8') : '';\n if (onDisk === rendered) return;\n\n this.logger.error(`Augmentations are out of date. Run \\`seedcord codegen\\` and commit ${outputPath}.`);\n process.exitCode = 1;\n }\n}\n","import { isSeedcordError } from '@seedcord/errors';\n\nimport { BaseCommand } from '#core/BaseCommand';\n\nimport { CodegenRunner } from './CodegenRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class CodegenCommand extends BaseCommand {\n private readonly runner: CodegenRunner;\n\n constructor() {\n super('codegen', 'Generate typed augmentations from your commands and config', 'Codegen');\n this.runner = CodegenRunner.create(this.logger);\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .option('--check', 'Verify the committed augmentations are up to date instead of writing them')\n .action(async (options) => {\n try {\n await this.runner.run(options.check ?? false);\n } catch (error: unknown) {\n this.logger.error('Seedcord codegen failed', error);\n if (isSeedcordError(error)) process.exitCode = 1;\n else process.exit(1);\n }\n });\n }\n}\n","export function isInteractive(opts: { yes?: boolean }, hasActionFlags: boolean): boolean {\n return (\n !hasActionFlags &&\n process.stdin.isTTY === true &&\n process.stdout.isTTY === true &&\n // some CI fakes a TTY\n !process.env.CI &&\n !opts.yes\n );\n}\n","type CleanReason = 'overlap' | 'purge';\n\ninterface DeployedCommand {\n id: string;\n name: string;\n}\n\nexport interface GuildCommands {\n guildId: string;\n guildName: string;\n commands: DeployedCommand[];\n}\n\nexport interface Flagged extends DeployedCommand {\n guildId: string;\n guildName: string;\n reason: CleanReason;\n}\n\n/**\n * Selects which deployed guild commands `commands --clean` would delete. An overlap is a guild command\n * whose name also exists globally, so it renders twice in the picker.\n */\nexport function classifyGuildCommands(\n globalNames: ReadonlySet<string>,\n guilds: readonly GuildCommands[],\n purge: boolean\n): Flagged[] {\n const flagged: Flagged[] = [];\n\n for (const { guildId, guildName, commands } of guilds) {\n for (const command of commands) {\n if (purge) {\n flagged.push({ guildId, guildName, id: command.id, name: command.name, reason: 'purge' });\n } else if (globalNames.has(command.name)) {\n flagged.push({ guildId, guildName, id: command.id, name: command.name, reason: 'overlap' });\n }\n }\n }\n\n return flagged;\n}\n","import { REST } from '@discordjs/rest';\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Routes } from 'discord-api-types/v10';\n\nimport { classifyGuildCommands } from './classify';\n\nimport type { Flagged, GuildCommands } from './classify';\nimport type {\n RESTGetAPIApplicationCommandsResult,\n RESTGetAPIApplicationGuildCommandsResult,\n RESTGetAPICurrentUserGuildsResult,\n RESTGetCurrentApplicationResult,\n Snowflake\n} from 'discord-api-types/v10';\n\ntype RestClient = Pick<REST, 'get' | 'delete'>;\n\nexport interface CleanScope {\n guildIds: string[];\n allGuilds: boolean;\n purge: boolean;\n}\n\nexport interface GuildSummary {\n id: string;\n name: string;\n}\n\nexport interface ResolvedTargets {\n appId: Snowflake;\n guilds: GuildSummary[];\n}\n\nexport interface SkippedGuild {\n guildId: string;\n guildName: string;\n reason: string;\n}\n\nexport interface ScanResult {\n flagged: Flagged[];\n skipped: SkippedGuild[];\n scannedGuildCount: number;\n scannedCommandCount: number;\n globalCommandCount: number;\n}\n\ninterface DeleteFailure {\n command: Flagged;\n reason: string;\n}\n\nexport interface DeleteResult {\n deleted: number;\n failed: DeleteFailure[];\n}\n\nexport interface CleanOps {\n resolveTargets(scope: CleanScope, token: string): Promise<ResolvedTargets>;\n scanGuilds(token: string, appId: Snowflake, guilds: GuildSummary[], purge: boolean): Promise<ScanResult>;\n applyDeletions(token: string, appId: Snowflake, flagged: Flagged[]): Promise<DeleteResult>;\n}\n\nconst GUILD_PAGE = 200;\n\nexport class CleanRunner implements CleanOps {\n constructor(private readonly makeRest: (token: string) => RestClient) {}\n\n public static create(): CleanRunner {\n return new CleanRunner((token) => new REST({ version: '10' }).setToken(token));\n }\n\n public async resolveTargets(scope: CleanScope, token: string): Promise<ResolvedTargets> {\n // purge across all guilds would wipe every command\n if (scope.purge && scope.allGuilds) throw new SeedcordError(SeedcordErrorCode.CliCleanPurgeAllGuilds);\n\n if (!scope.allGuilds && scope.guildIds.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.CliCleanNoGuilds);\n }\n\n const rest = this.makeRest(token);\n const appId = await this.resolveAppId(rest);\n const guilds = scope.allGuilds\n ? await this.fetchBotGuilds(rest)\n : scope.guildIds.map((id) => ({ id, name: id }));\n\n return { appId, guilds };\n }\n\n public async listBotGuilds(token: string): Promise<GuildSummary[]> {\n return this.fetchBotGuilds(this.makeRest(token));\n }\n\n public async scanGuilds(\n token: string,\n appId: Snowflake,\n guilds: GuildSummary[],\n purge: boolean\n ): Promise<ScanResult> {\n const rest = this.makeRest(token);\n const globalNames = await this.fetchGlobalNames(rest, appId);\n\n const buckets: GuildCommands[] = [];\n const skipped: SkippedGuild[] = [];\n let scannedCommandCount = 0;\n for (const guild of guilds) {\n try {\n const deployed = (await rest.get(\n Routes.applicationGuildCommands(appId, guild.id)\n )) as RESTGetAPIApplicationGuildCommandsResult;\n const commands = deployed.map((command) => ({ id: command.id, name: command.name }));\n scannedCommandCount += commands.length;\n buckets.push({ guildId: guild.id, guildName: guild.name, commands });\n } catch (error: unknown) {\n skipped.push({\n guildId: guild.id,\n guildName: guild.name,\n reason: Error.isError(error) ? error.message : 'Unknown error'\n });\n }\n }\n\n return {\n flagged: classifyGuildCommands(globalNames, buckets, purge),\n skipped,\n scannedGuildCount: buckets.length,\n scannedCommandCount,\n globalCommandCount: globalNames.size\n };\n }\n\n public async applyDeletions(token: string, appId: Snowflake, flagged: Flagged[]): Promise<DeleteResult> {\n const rest = this.makeRest(token);\n let deleted = 0;\n const failed: DeleteFailure[] = [];\n\n for (const command of flagged) {\n try {\n await rest.delete(Routes.applicationGuildCommand(appId, command.guildId, command.id));\n deleted++;\n } catch (error: unknown) {\n failed.push({ command, reason: Error.isError(error) ? error.message : 'Unknown error' });\n }\n }\n\n return { deleted, failed };\n }\n\n private async resolveAppId(rest: RestClient): Promise<Snowflake> {\n try {\n const app = (await rest.get(Routes.currentApplication())) as RESTGetCurrentApplicationResult;\n return app.id;\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown error';\n throw new SeedcordError(SeedcordErrorCode.CliCleanAppFetchFailed, [reason]);\n }\n }\n\n private async fetchBotGuilds(rest: RestClient): Promise<GuildSummary[]> {\n const guilds: GuildSummary[] = [];\n let after: string | undefined;\n\n for (;;) {\n const query = new URLSearchParams({ limit: String(GUILD_PAGE) });\n if (after) query.set('after', after);\n\n const page = (await rest.get(Routes.userGuilds(), { query })) as RESTGetAPICurrentUserGuildsResult;\n for (const guild of page) guilds.push({ id: guild.id, name: guild.name });\n\n after = page.at(-1)?.id;\n if (page.length < GUILD_PAGE || !after) break;\n }\n\n return guilds;\n }\n\n private async fetchGlobalNames(rest: RestClient, appId: Snowflake): Promise<Set<string>> {\n const global = (await rest.get(Routes.applicationCommands(appId))) as RESTGetAPIApplicationCommandsResult;\n return new Set(global.map((command) => command.name));\n }\n}\n","export function plural(count: number, singular: string, pluralForm = `${singular}s`): string {\n return `${count} ${count === 1 ? singular : pluralForm}`;\n}\n\nexport function includesIgnoreCase(text: string, search: string): boolean {\n return text.toLowerCase().includes(search.trim().toLowerCase());\n}\n","import { cancel, isCancel } from '@clack/prompts';\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\n// clack signals cancel with a symbol\nexport function requireValue<Value>(value: Value | symbol): Value {\n if (isCancel(value)) {\n cancel('Cancelled.');\n throw new SeedcordError(SeedcordErrorCode.CliCancelled);\n }\n return value;\n}\n","import { autocompleteMultiselect, multiselect } from '@clack/prompts';\n\nimport { includesIgnoreCase } from '#core/format';\n\nimport { requireValue } from './requireValue';\n\ninterface PickItem {\n id: string;\n name: string;\n}\n\nexport interface PickFromListOptions {\n message: string;\n items: PickItem[];\n maxItems?: number;\n}\n\nconst DEFAULT_MAX_ITEMS = 10;\n// above this a checkbox list is hard to scan, so switch to search-as-you-type\nconst SEARCH_THRESHOLD = 12;\n\nexport async function pickFromList(opts: PickFromListOptions): Promise<string[]> {\n const options = opts.items.map((item) => ({ value: item.id, label: item.name }));\n const maxItems = opts.maxItems ?? DEFAULT_MAX_ITEMS;\n\n if (opts.items.length <= SEARCH_THRESHOLD) {\n return requireValue(await multiselect<string>({ message: opts.message, options, maxItems, required: false }));\n }\n\n return requireValue(\n await autocompleteMultiselect<string>({\n message: opts.message,\n options,\n maxItems,\n placeholder: 'Type to search…',\n filter: (search, option) =>\n includesIgnoreCase(option.label ?? '', search) || includesIgnoreCase(String(option.value), search)\n })\n );\n}\n","import { confirm as clackConfirm, select as clackSelect } from '@clack/prompts';\n\nimport { requireValue } from './requireValue';\n\nimport type { ConfirmOptions, SelectOptions } from '@clack/prompts';\n\nexport { intro, outro, log, note, spinner } from '@clack/prompts';\nexport { pickFromList } from './pickFromList';\n\nexport async function select<Value>(opts: SelectOptions<Value>): Promise<Value> {\n return requireValue(await clackSelect(opts));\n}\n\nexport async function confirm(opts: ConfirmOptions): Promise<boolean> {\n return requireValue(await clackConfirm(opts));\n}\n","import { createInterface } from 'node:readline';\n\nimport type { ILogger } from '@seedcord/types';\n\ntype Ask = (question: string) => Promise<string>;\n\nasync function readlineAsk(question: string): Promise<string> {\n using rl = createInterface({ input: process.stdin, output: process.stdout });\n return await new Promise<string>((resolve) => rl.question(question, resolve));\n}\n\nexport async function confirmCount(count: number, logger: ILogger, ask: Ask = readlineAsk): Promise<boolean> {\n logger.warn(`About to delete ${count} guild command(s). This cannot be undone.`);\n const answer = await ask(`Type ${count} to confirm (anything else aborts) `);\n return answer.trim() === String(count);\n}\n","import { SeedcordErrorCode, paint } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { plural } from '#core/format';\nimport { confirm, log, note, outro, spinner } from '#core/prompts';\n\nimport { confirmCount } from './confirm';\n\nimport type { Flagged } from './classify';\nimport type { DeleteResult, ScanResult, SkippedGuild } from './CleanRunner';\nimport type { CleanPresenter, EmptyOutcome } from './executeClean';\nimport type { ILogger } from '@seedcord/types';\n\ninterface GuildGroup {\n guildName: string;\n commands: Flagged[];\n}\n\nfunction groupByGuild(flagged: Flagged[]): GuildGroup[] {\n const groups = new Map<string, GuildGroup>();\n for (const command of flagged) {\n const group = groups.get(command.guildId) ?? { guildName: command.guildName, commands: [] };\n group.commands.push(command);\n groups.set(command.guildId, group);\n }\n return [...groups.values()];\n}\n\nfunction skippedSummary(skipped: SkippedGuild[]): string {\n return `Could not read ${plural(skipped.length, 'guild')} (${skipped.map((s) => s.guildName).join(', ')}).`;\n}\n\nfunction emptyLines(scan: ScanResult, outcome: EmptyOutcome): { info: string[]; outro: string } {\n const variants: Record<EmptyOutcome, { info: string[]; outro: string }> = {\n 'all-skipped': {\n info: [],\n outro: `Could not read any of the ${plural(scan.skipped.length, 'guild')}, nothing was scanned.`\n },\n 'no-commands': {\n info: [],\n outro: `Scanned ${plural(scan.scannedGuildCount, 'guild')} with no guild commands deployed. Nothing to clean.`\n },\n 'no-globals': {\n info: [\n 'This app has no global commands, so nothing can duplicate one.',\n 'Re-run and choose a full reset to remove guild commands.'\n ],\n outro: 'Nothing to clean.'\n },\n 'no-overlaps': {\n info: [\n `Scanned ${plural(scan.scannedCommandCount, 'guild command')} across ${plural(scan.scannedGuildCount, 'guild')}. None duplicate a global command.`,\n 'Re-run and choose a full reset to remove all of them.'\n ],\n outro: 'Nothing to clean.'\n }\n };\n return variants[outcome];\n}\n\n/** Renders the clean flow as clack framed output for an interactive terminal. */\nexport class InteractivePresenter implements CleanPresenter {\n public async status<Value>(message: string, task: () => Promise<Value>, done?: string): Promise<Value> {\n const status = spinner();\n status.start(message);\n try {\n return await task();\n } finally {\n status.stop(done ?? message);\n }\n }\n\n public preview(scan: ScanResult): void {\n const body = groupByGuild(scan.flagged)\n .map((group) => `${paint.bold(group.guildName)}\\n${group.commands.map((c) => ` ${c.name}`).join('\\n')}`)\n .join('\\n\\n');\n note(body, `Will delete ${plural(scan.flagged.length, 'guild command')} (nothing deleted yet)`);\n if (scan.skipped.length > 0) log.warn(skippedSummary(scan.skipped));\n }\n\n public largeBotGuard(guildCount: number): Promise<boolean> {\n return confirm({\n message: `The bot is in ${guildCount} guilds. Scan all of them? This makes ${guildCount} requests.`,\n initialValue: false\n });\n }\n\n public confirmDelete(count: number, skippedCount: number): Promise<boolean> {\n const skips = skippedCount > 0 ? ` ${plural(skippedCount, 'guild')} could not be read.` : '';\n return confirm({\n message: `Delete ${plural(count, 'guild command')}? This cannot be undone.${skips}`,\n initialValue: false\n });\n }\n\n public result(deletion: DeleteResult, skipped: SkippedGuild[]): void {\n for (const failure of deletion.failed) {\n log.warn(`Could not delete ${failure.command.name} in ${failure.command.guildName} (${failure.reason}).`);\n }\n if (skipped.length > 0) log.warn(skippedSummary(skipped));\n outro(`Deleted ${plural(deletion.deleted, 'guild command')}. Global commands untouched.`);\n }\n\n public nothingToClean(scan: ScanResult, outcome: EmptyOutcome): void {\n const lines = emptyLines(scan, outcome);\n for (const line of lines.info) log.info(line);\n outro(lines.outro);\n }\n\n public dryRunHint(): void {\n outro('Dry run, nothing was deleted.');\n }\n}\n\n/** Renders the clean flow as plain logger lines for the flag, CI, and non-TTY path. */\nexport class FlagPresenter implements CleanPresenter {\n constructor(\n private readonly logger: ILogger,\n private readonly yes: boolean\n ) {}\n\n public status<Value>(message: string, task: () => Promise<Value>): Promise<Value> {\n this.logger.info(message);\n return task();\n }\n\n public preview(scan: ScanResult): void {\n this.logger.info(paint.bold(`${plural(scan.flagged.length, 'guild command')} selected for deletion`));\n for (const group of groupByGuild(scan.flagged)) {\n this.logger.info(paint.sky(group.guildName));\n for (const command of group.commands) this.logger.info(` ${command.name}`);\n }\n for (const skip of scan.skipped) this.logger.warn(`Skipped ${skip.guildName} (${skip.reason}).`);\n }\n\n public largeBotGuard(guildCount: number): Promise<boolean> {\n if (this.yes) return Promise.resolve(true);\n return Promise.reject(new SeedcordError(SeedcordErrorCode.CliCleanLargeBotUnconfirmed, [guildCount]));\n }\n\n // clack confirm needs a tty, so this prompts for a typed count instead\n public confirmDelete(count: number, skippedCount: number): Promise<boolean> {\n if (this.yes) return Promise.resolve(true);\n // readline cannot prompt without a terminal\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n return Promise.reject(new SeedcordError(SeedcordErrorCode.CliCleanApplyNeedsYes));\n }\n if (skippedCount > 0)\n this.logger.warn(`${plural(skippedCount, 'guild')} could not be read and were not scanned.`);\n return confirmCount(count, this.logger);\n }\n\n public result(deletion: DeleteResult, skipped: SkippedGuild[]): void {\n for (const failure of deletion.failed) {\n this.logger.warn(\n `Could not delete ${failure.command.name} in ${failure.command.guildName} (${failure.reason}).`\n );\n }\n if (skipped.length > 0) this.logger.warn(skippedSummary(skipped));\n this.logger.info(\n paint.mint(`Deleted ${plural(deletion.deleted, 'guild command')}. Global commands untouched.`)\n );\n }\n\n public nothingToClean(scan: ScanResult, outcome: EmptyOutcome): void {\n const lines = emptyLines(scan, outcome);\n for (const line of lines.info) this.logger.info(line);\n this.logger.info(paint.mint(lines.outro));\n }\n\n public dryRunHint(): void {\n this.logger.info(paint.italic('Dry run. Re-run with --apply to delete the above.'));\n }\n}\n","import { plural } from '#core/format';\n\nimport type { CleanOps, CleanScope, DeleteResult, GuildSummary, ScanResult, SkippedGuild } from './CleanRunner';\n\nexport interface CleanPresenter {\n status<Value>(message: string, task: () => Promise<Value>, done?: string): Promise<Value>;\n preview(scan: ScanResult): void;\n largeBotGuard(guildCount: number): Promise<boolean>;\n confirmDelete(count: number, skippedCount: number): Promise<boolean>;\n result(deletion: DeleteResult, skipped: SkippedGuild[]): void;\n nothingToClean(scan: ScanResult, outcome: EmptyOutcome): void;\n dryRunHint(): void;\n}\n\nexport interface CleanRequest {\n runner: CleanOps;\n scope: CleanScope;\n apply: boolean;\n token: string;\n presenter: CleanPresenter;\n /** Names the caller already fetched (the wizard picker), used to label guilds the scan only knows by id. */\n knownGuilds?: GuildSummary[] | undefined;\n}\n\n// one guild page, above this --all-guilds means a fetch per guild\nexport const LARGE_BOT_THRESHOLD = 200;\n\nexport type EmptyOutcome = 'all-skipped' | 'no-commands' | 'no-globals' | 'no-overlaps';\n\nexport function emptyOutcome(scan: ScanResult, purge: boolean): EmptyOutcome {\n if (scan.scannedGuildCount === 0 && scan.skipped.length > 0) return 'all-skipped';\n if (scan.scannedCommandCount === 0) return 'no-commands';\n if (!purge && scan.globalCommandCount === 0) return 'no-globals';\n return 'no-overlaps';\n}\n\n/** The wizard and the flag path share this flow through different presenters, which own all output and both confirmations. */\nexport async function executeClean(request: CleanRequest): Promise<void> {\n const { runner, scope, apply, token, presenter, knownGuilds } = request;\n\n const { appId, guilds } = await presenter.status(\n 'Connecting to Discord…',\n () => runner.resolveTargets(scope, token),\n 'Connected to Discord.'\n );\n\n if (scope.allGuilds && guilds.length > LARGE_BOT_THRESHOLD && !(await presenter.largeBotGuard(guilds.length)))\n return;\n\n const scan = await presenter.status(\n `Scanning ${plural(guilds.length, 'guild')} for commands…`,\n () => runner.scanGuilds(token, appId, overlayNames(guilds, knownGuilds), scope.purge),\n `Scanned ${plural(guilds.length, 'guild')}.`\n );\n\n if (scan.flagged.length === 0) {\n presenter.nothingToClean(scan, emptyOutcome(scan, scope.purge));\n return;\n }\n\n presenter.preview(scan);\n\n if (!apply) {\n presenter.dryRunHint();\n return;\n }\n\n if (!(await presenter.confirmDelete(scan.flagged.length, scan.skipped.length))) return;\n\n const deletion = await presenter.status(\n `Deleting ${plural(scan.flagged.length, 'guild command')}…`,\n () => runner.applyDeletions(token, appId, scan.flagged),\n 'Deletion complete.'\n );\n presenter.result(deletion, scan.skipped);\n}\n\nfunction overlayNames(guilds: GuildSummary[], knownGuilds?: GuildSummary[]): GuildSummary[] {\n if (!knownGuilds?.length) return guilds;\n const known = new Map(knownGuilds.map((guild) => [guild.id, guild.name]));\n return guilds.map((guild) => ({ id: guild.id, name: known.get(guild.id) ?? guild.name }));\n}\n","import { FlagPresenter } from './cleanPresenters';\nimport { executeClean } from './executeClean';\n\nimport type { CleanRunner } from './CleanRunner';\nimport type { ILogger } from '@seedcord/types';\n\nexport interface CleanFlags {\n guildIds: string[];\n allGuilds: boolean;\n apply: boolean;\n purge: boolean;\n yes: boolean;\n}\n\nexport async function runCleanFromFlags(\n runner: CleanRunner,\n flags: CleanFlags,\n token: string,\n logger: ILogger\n): Promise<void> {\n await executeClean({\n runner,\n scope: { guildIds: flags.guildIds, allGuilds: flags.allGuilds, purge: flags.purge },\n apply: flags.apply,\n token,\n presenter: new FlagPresenter(logger, flags.yes)\n });\n}\n","import { plural } from '#core/format';\nimport { intro, log, outro, pickFromList, select, spinner } from '#core/prompts';\n\nimport { InteractivePresenter } from './cleanPresenters';\nimport { executeClean } from './executeClean';\n\nimport type { CleanRunner, CleanScope, GuildSummary } from './CleanRunner';\n\ninterface ScopePlan {\n scope: CleanScope;\n knownGuilds?: GuildSummary[];\n}\n\nexport async function runCleanWizard(runner: CleanRunner, token: string): Promise<void> {\n intro('seedcord commands');\n\n const plan = await buildScope(runner, token);\n if (!plan) return;\n\n await executeClean({\n runner,\n scope: plan.scope,\n apply: true,\n token,\n presenter: new InteractivePresenter(),\n knownGuilds: plan.knownGuilds\n });\n}\n\nasync function buildScope(runner: CleanRunner, token: string): Promise<ScopePlan | undefined> {\n const target = await select({\n message: 'Remove guild commands that duplicate a global command. Which guilds?',\n options: [\n { value: 'pick', label: 'Pick specific guilds' },\n {\n value: 'all',\n label: 'All guilds the bot is in',\n hint: 'duplicates only, pick specific guilds for a full reset'\n }\n ]\n });\n\n // a full purge needs named guilds\n if (target === 'all') return { scope: { guildIds: [], allGuilds: true, purge: false } };\n\n const status = spinner();\n status.start('Fetching the guilds the bot is in…');\n let guilds: GuildSummary[];\n try {\n guilds = await runner.listBotGuilds(token);\n } catch (error) {\n status.stop('Could not fetch the guild list.');\n throw error;\n }\n status.stop(`Found ${plural(guilds.length, 'guild')}.`);\n\n if (guilds.length === 0) {\n outro('The bot is in no guilds.');\n return undefined;\n }\n\n let guildIds: string[];\n if (guilds.length > 1) {\n guildIds = await pickFromList({ message: 'Select guilds to clean', items: guilds });\n if (guildIds.length === 0) {\n outro('No guilds selected.');\n return undefined;\n }\n } else {\n const only = guilds[0];\n if (!only) return undefined;\n guildIds = [only.id];\n log.info(`Only one guild, using ${only.name}.`);\n }\n\n const mode = await select({\n message: 'What should I remove?',\n options: [\n { value: 'overlap', label: 'Only duplicates of a global command (recommended)' },\n { value: 'purge', label: 'Every command in these guilds (full reset)' }\n ]\n });\n\n return { scope: { guildIds, allGuilds: false, purge: mode === 'purge' }, knownGuilds: guilds };\n}\n","import { isSeedcordError, SeedcordErrorCode } from '@seedcord/errors';\nimport { validateDiscordToken } from '@seedcord/errors/internal';\nimport { Envapter } from 'envapt';\n\nimport { BaseCommand } from '#core/BaseCommand';\nimport { isInteractive } from '#core/interactive';\n\nimport { CleanRunner } from './CleanRunner';\nimport { runCleanFromFlags } from './flagClean';\nimport { runCleanWizard } from './wizard';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport interface CleanInvocation {\n clean: boolean;\n guild: string[];\n allGuilds: boolean;\n apply: boolean;\n purge: boolean;\n yes: boolean;\n}\n\nexport function hasCleanFlags(options: CleanInvocation): boolean {\n return [options.clean, options.allGuilds, options.apply, options.purge].some(Boolean) || options.guild.length > 0;\n}\n\nexport class CommandsCommand extends BaseCommand {\n private readonly cleanRunner: CleanRunner;\n\n constructor() {\n super('commands', 'Inspect and clean deployed guild commands', 'Commands');\n this.cleanRunner = CleanRunner.create();\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .option('--clean', 'Report guild commands that duplicate a global command (deletes only with --apply)')\n .option('--guild <ids...>', 'Guild ids to inspect')\n .option('--all-guilds', 'Scan every guild the bot is in (overlaps only, cannot combine with --purge)')\n .option('--apply', 'Delete the reported commands instead of running a dry run')\n .option('--purge', 'Select every command in the named guilds, not only global overlaps')\n .option('--yes', 'Skip prompts and the typed-count confirm (for scripts and CI)')\n .action(async (options) =>\n this.run({\n clean: options.clean ?? false,\n guild: options.guild ?? [],\n allGuilds: options.allGuilds ?? false,\n apply: options.apply ?? false,\n purge: options.purge ?? false,\n yes: options.yes ?? false\n })\n );\n }\n\n private async run(options: CleanInvocation): Promise<void> {\n try {\n await this.dispatch(options);\n } catch (error: unknown) {\n // a cancelled prompt exits quietly here because it's an intentional abort\n if (isSeedcordError(error, 'SeedcordError', SeedcordErrorCode.CliCancelled)) return;\n\n this.logger.error('seedcord commands failed', error);\n if (isSeedcordError(error)) process.exitCode = 1;\n else process.exit(1);\n }\n }\n\n private async dispatch(options: CleanInvocation): Promise<void> {\n const flags = hasCleanFlags(options);\n const interactive = isInteractive(options, flags);\n\n if (!interactive && !flags) {\n this.logger.info('Nothing to do. Pass --clean to inspect deployed commands.');\n return;\n }\n\n const token = validateDiscordToken(Envapter.get('DISCORD_BOT_TOKEN'));\n\n if (interactive) {\n await runCleanWizard(this.cleanRunner, token);\n return;\n }\n\n await runCleanFromFlags(\n this.cleanRunner,\n {\n guildIds: options.guild,\n allGuilds: options.allGuilds,\n apply: options.apply,\n purge: options.purge,\n yes: options.yes\n },\n token,\n this.logger\n );\n }\n}\n","import { Box } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\n// full-width flex line bracketing a block. flexShrink={0} keeps the border-only box from compressing to\n// zero height under overflow, which would land the rule on the neighbouring text line.\nexport function Rule(): ReactElement {\n return (\n <Box\n flexShrink={0}\n borderStyle=\"single\"\n borderTop\n borderBottom={false}\n borderLeft={false}\n borderRight={false}\n borderDimColor\n />\n );\n}\n","export type FilterGroup = 'channels' | 'levels';\nexport type CursorMove = 'left' | 'right' | 'switch';\n\nexport interface FilterCursor {\n readonly group: FilterGroup;\n readonly channels: number;\n readonly levels: number;\n}\n\nexport const INITIAL_CURSOR: FilterCursor = { group: 'channels', channels: 0, levels: 0 };\n\nexport function moveCursor(\n cursor: FilterCursor,\n move: CursorMove,\n channelCount: number,\n levelCount: number\n): FilterCursor {\n if (move === 'switch') {\n return { ...cursor, group: cursor.group === 'channels' ? 'levels' : 'channels' };\n }\n\n const count = cursor.group === 'channels' ? channelCount : levelCount;\n if (count === 0) return cursor;\n\n const index = cursor.group === 'channels' ? cursor.channels : cursor.levels;\n const next = move === 'right' ? (index + 1) % count : (index + count - 1) % count;\n return cursor.group === 'channels' ? { ...cursor, channels: next } : { ...cursor, levels: next };\n}\n\n// modulo, a remembered index can exceed the count after the channel list shrinks\nexport function focusedIn(cursor: FilterCursor | null, group: FilterGroup, count: number): number | null {\n if (cursor?.group !== group || count === 0) return null;\n return (group === 'channels' ? cursor.channels : cursor.levels) % count;\n}\n","import { useCallback, useSyncExternalStore } from 'react';\n\nimport type { DevState, DevStore } from '#ui/stores/DevStore';\n\nexport function useDevState(store: DevStore): DevState {\n const subscribe = useCallback(\n (onChange: () => void) => {\n store.on('change', onChange);\n return () => {\n store.off('change', onChange);\n };\n },\n [store]\n );\n const getSnapshot = useCallback(() => store.getState(), [store]);\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n","import { TypedEventEmitter } from '@seedcord/event-emitter';\nimport { LoggerChannelRegistry } from '@seedcord/logger';\nimport { formatBody } from '@seedcord/logger/node';\n\nimport type { ILogSink, LogLevel, LogRecord, LogSinkHandle } from '@seedcord/types';\n\nexport interface LogEntry {\n id: number;\n channel: string;\n level: LogLevel;\n label: string;\n text: string;\n timestamp: number;\n head: boolean;\n frame: boolean;\n}\n\nconst STACK_FRAME = /^\\s+at\\s/;\n\ninterface LogStoreEvents {\n change: [];\n}\n\n// 30ms keeps a noisy bot from re-rendering the log view once per line\nconst UPDATE_DEBOUNCE_MS = 30;\n\n// eslint-disable-next-line no-magic-numbers -- 27 is the ESC control code\nconst ESC = String.fromCharCode(27);\n\nexport class LogStore extends TypedEventEmitter<LogStoreEvents> implements ILogSink {\n private static _instance: LogStore | null = null;\n\n public readonly kind = 'capture';\n\n private entries: LogEntry[] = [];\n private buffer: LogEntry[] = [];\n private nextId = 1;\n private sinkHandle: LogSinkHandle | null = null;\n private pendingUpdate = false;\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private readonly MAX_LOGS = 1000;\n private readonly MAX_LABEL_WIDTH = 12;\n\n private constructor() {\n super();\n }\n\n public static get instance(): LogStore {\n LogStore._instance ??= new LogStore();\n return LogStore._instance;\n }\n\n public mount(): void {\n if (this.sinkHandle) return;\n this.sinkHandle = LoggerChannelRegistry.instance.installSink(this, {\n muteConsole: true\n });\n }\n\n public unmount(): void {\n if (!this.sinkHandle) return;\n this.sinkHandle.dispose();\n this.sinkHandle = null;\n }\n\n public onLog(record: LogRecord): void {\n // a lone \\r left in a row sends the terminal cursor to column 0 and overwrites what it printed, and\n // every other control char corrupts the row the same way. ESC survives because SGR colors need it.\n const lines = formatBody(record).split(/\\r\\n|\\r|\\n/);\n\n for (const [index, line] of lines.entries()) {\n const text = line.replaceAll(/\\p{Cc}/gu, (char) => (char === ESC ? char : ''));\n this.buffer.push({\n id: this.nextId++,\n channel: record.channel,\n level: record.level,\n label: record.label,\n head: index === 0,\n frame: index > 0 && STACK_FRAME.test(text),\n text,\n timestamp: record.timestamp\n });\n }\n\n this.scheduleUpdate();\n }\n\n // useSyncExternalStore needs a stable reference, so channel filtering stays in useLogs\n public getLogs(): readonly LogEntry[] {\n return this.entries;\n }\n\n // read off live entries, else the toggle list carries an empty \"default\" row\n public getChannels(): readonly string[] {\n const seen = new Set<string>();\n for (const entry of this.entries) seen.add(entry.channel);\n return [...seen].sort();\n }\n\n public getLabelWidth(): number {\n let width = 0;\n for (const entry of this.entries) if (entry.label.length > width) width = entry.label.length;\n return Math.min(width, this.MAX_LABEL_WIDTH);\n }\n\n public clear(): void {\n this.entries = [];\n this.buffer = [];\n this.emit('change');\n }\n\n // the yield gives ink one paint of the last lines before quit unmounts the ui\n public async flush(): Promise<void> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n this.applyBuffer();\n await new Promise<void>((resolve) => setImmediate(resolve));\n }\n\n private scheduleUpdate(): void {\n if (this.pendingUpdate) return;\n this.pendingUpdate = true;\n this.flushTimer = setTimeout(() => this.applyBuffer(), UPDATE_DEBOUNCE_MS);\n }\n\n private applyBuffer(): void {\n this.flushTimer = null;\n this.pendingUpdate = false;\n if (this.buffer.length === 0) return;\n\n const newEntries = [...this.entries, ...this.buffer];\n this.buffer = [];\n this.entries = newEntries.length > this.MAX_LOGS ? newEntries.slice(-this.MAX_LOGS) : newEntries;\n\n this.emit('change');\n }\n}\n","import { useCallback, useMemo, useSyncExternalStore } from 'react';\n\nimport { LogStore } from '#ui/stores/LogStore';\n\nimport type { LogEntry } from '#ui/stores/LogStore';\nimport type { LogLevel } from '@seedcord/types';\n\nconst EMPTY_CHANNELS: ReadonlySet<string> = new Set();\nconst EMPTY_LEVELS: ReadonlySet<LogLevel> = new Set();\n\n// empty set means all, so a channel or level that appears later stays visible by default\nexport function filterLogs(\n logs: readonly LogEntry[],\n channels: ReadonlySet<string>,\n levels: ReadonlySet<LogLevel>\n): readonly LogEntry[] {\n const allChannels = channels.size === 0;\n const allLevels = levels.size === 0;\n if (allChannels && allLevels) return logs;\n return logs.filter((log) => (allChannels || channels.has(log.channel)) && (allLevels || levels.has(log.level)));\n}\n\n// `channels`/`levels` must be stable references between unchanged renders (the shell holds them in state), or\n// the memo recomputes every render.\nexport function useLogs(channels?: ReadonlySet<string>, levels?: ReadonlySet<LogLevel>): readonly LogEntry[] {\n const store = LogStore.instance;\n\n const subscribe = useCallback(\n (cb: () => void) => {\n store.on('change', cb);\n return () => {\n store.off('change', cb);\n };\n },\n [store]\n );\n\n const getSnapshot = useCallback(() => store.getLogs(), [store]);\n\n const allLogs = useSyncExternalStore(subscribe, getSnapshot);\n\n return useMemo(\n () => filterLogs(allLogs, channels ?? EMPTY_CHANNELS, levels ?? EMPTY_LEVELS),\n [allLogs, channels, levels]\n );\n}\n","import { measureElement } from 'ink';\nimport { useLayoutEffect, useState } from 'react';\n\nimport type { DOMElement } from 'ink';\nimport type { RefObject } from 'react';\n\nexport interface MeasuredBox {\n readonly width: number;\n readonly height: number;\n}\n\nconst UNMEASURED: MeasuredBox = { width: 0, height: 0 };\n\nexport function useMeasuredBox(ref: RefObject<DOMElement | null>): MeasuredBox {\n const [box, setBox] = useState<MeasuredBox>(UNMEASURED);\n\n // eslint-disable-next-line @eslint-react/exhaustive-deps, react-hooks/exhaustive-deps -- the measured size can change on any render, so no dep list covers it\n useLayoutEffect(() => {\n if (!ref.current) return;\n const { width, height } = measureElement(ref.current);\n // eslint-disable-next-line @eslint-react/set-state-in-effect -- Ink measures only after render, and the equality bail stops the update chain\n setBox((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));\n });\n\n return box;\n}\n","import { measureElement } from 'ink';\nimport { useLayoutEffect, useRef, useState } from 'react';\n\nimport type { DevPhase } from '#ui/stores/devPhase';\nimport type { DOMElement } from 'ink';\nimport type { RefObject } from 'react';\n\n// held until the next restart so the rail doesn't resize mid-stream\nexport function useRailWidth(\n railRef: RefObject<DOMElement | null>,\n phase: DevPhase,\n rows: number,\n columns: number\n): number | null {\n const [railWidth, setRailWidth] = useState<number | null>(null);\n const needsMeasureRef = useRef(true);\n\n useLayoutEffect(() => {\n if (phase !== 'running') {\n needsMeasureRef.current = true;\n // drop the lock too, because a rail still constrained by it would measure back the old width\n // eslint-disable-next-line @eslint-react/set-state-in-effect, react-hooks/set-state-in-effect -- see the measurement set below\n setRailWidth(null);\n return;\n }\n if (!needsMeasureRef.current || !railRef.current) return;\n const measured = measureElement(railRef.current).width;\n if (measured > 0) {\n needsMeasureRef.current = false;\n // eslint-disable-next-line @eslint-react/set-state-in-effect -- rail width comes from measuring the rendered element, set once per run\n setRailWidth(measured);\n }\n }, [rows, columns, phase, railRef]);\n\n return railWidth;\n}\n","import { useState } from 'react';\n\nexport interface ScrollApi<Item> {\n // oldest first, consumers render in array order\n readonly visible: readonly Item[];\n readonly following: boolean;\n readonly atTop: boolean;\n readonly above: number;\n readonly below: number;\n readonly up: (lines?: number) => void;\n readonly down: (lines?: number) => void;\n readonly pageUp: () => void;\n readonly pageDown: () => void;\n readonly toTop: () => void;\n readonly toBottom: () => void;\n}\n\ntype ScrollKey = number | string;\n\ninterface ScrollView<Item> {\n readonly visible: readonly Item[];\n readonly topIndex: number;\n readonly following: boolean;\n readonly atTop: boolean;\n readonly above: number;\n readonly below: number;\n}\n\n// a null anchor follows the newest line. a key anchor pins the top row to that entry's current index, so\n// the visible lines stay put while LogStore trims its head or appends. a trimmed-away anchor falls back to\n// the oldest line.\nexport function computeScrollView<Item>(\n items: readonly Item[],\n viewportHeight: number,\n anchor: ScrollKey | null,\n getKey: (item: Item) => ScrollKey\n): ScrollView<Item> {\n const height = Math.max(1, viewportHeight);\n const len = items.length;\n const maxTop = Math.max(0, len - height);\n\n let topIndex: number;\n if (anchor === null) {\n topIndex = maxTop;\n } else {\n const found = items.findIndex((item) => getKey(item) === anchor);\n topIndex = found === -1 ? 0 : found;\n }\n topIndex = Math.min(Math.max(0, topIndex), maxTop);\n\n const visible = items.slice(topIndex, topIndex + height);\n return {\n visible,\n topIndex,\n following: anchor === null || topIndex >= maxTop,\n atTop: topIndex === 0,\n above: topIndex,\n below: len - (topIndex + visible.length)\n };\n}\n\nexport function useScroll<Item>(\n items: readonly Item[],\n viewportHeight: number,\n getKey: (item: Item) => ScrollKey\n): ScrollApi<Item> {\n const [anchor, setAnchor] = useState<ScrollKey | null>(null);\n\n const height = Math.max(1, viewportHeight);\n const maxTop = Math.max(0, items.length - height);\n const view = computeScrollView(items, viewportHeight, anchor, getKey);\n\n const anchorAt = (nextTop: number): void => {\n const clamped = Math.min(Math.max(0, nextTop), maxTop);\n if (clamped >= maxTop) {\n setAnchor(null);\n return;\n }\n const entry = items[clamped];\n setAnchor(entry === undefined ? null : getKey(entry));\n };\n\n const up = (lines = 1): void => anchorAt(view.topIndex - lines);\n const down = (lines = 1): void => anchorAt(view.topIndex + lines);\n\n return {\n visible: view.visible,\n following: view.following,\n atTop: view.atTop,\n above: view.above,\n below: view.below,\n up,\n down,\n pageUp: () => up(height - 1),\n pageDown: () => down(height - 1),\n toTop: () => {\n const oldest = items[0];\n setAnchor(oldest === undefined ? null : getKey(oldest));\n },\n toBottom: () => setAnchor(null)\n };\n}\n","// truecolor palette for the dev-TUI's own chrome (headings, hotkeys, status), so it renders the same\n// across terminals. the bot's log lines carry their own colors\nexport const ui = {\n accent: '#7dcfff',\n muted: '#9aa0b3',\n faint: '#565c6b',\n good: '#9ece6a',\n warn: '#e0af68',\n bad: '#f7768e'\n} as const;\n","import { ui } from '#ui/palette';\n\nimport type { TextProps } from 'ink';\n\nexport type DevPhase = 'starting' | 'running' | 'restart-required' | 'disconnected' | 'error' | 'quitting';\n\n// disconnect only applies while a session is running. the other phases have nothing to stop.\nexport function isSessionLive(phase: DevPhase): boolean {\n return phase === 'running' || phase === 'restart-required';\n}\n\n// up and emitting logs (restart-required is up but stale), which is what the live dot blinks for\nexport function isStreaming(phase: DevPhase): boolean {\n return phase === 'starting' || phase === 'running' || phase === 'restart-required';\n}\n\n// spinner runs once, arc loops\ntype PhaseGlyph = 'spinner' | 'arc' | 'static';\n\nexport interface PhaseMeta {\n readonly label: string;\n readonly icon: string;\n readonly color: TextProps['color'];\n readonly kind: PhaseGlyph;\n}\n\nexport const PHASE_META = {\n starting: { label: 'starting', icon: '◐', color: ui.accent, kind: 'spinner' },\n running: { label: 'running', icon: '●', color: ui.good, kind: 'arc' },\n 'restart-required': { label: 'restart required', icon: '◆', color: ui.warn, kind: 'static' },\n disconnected: { label: 'offline', icon: '○', color: ui.muted, kind: 'static' },\n error: { label: 'error', icon: '✘', color: ui.bad, kind: 'static' },\n quitting: { label: 'quitting', icon: '◐', color: ui.muted, kind: 'spinner' }\n} as const satisfies Record<DevPhase, PhaseMeta>;\n","import { useAnimation } from 'ink';\n\nimport { isSessionLive } from '#ui/stores/devPhase';\n\nimport type { DevState } from '#ui/stores/DevStore';\n\nconst TICK_MS = 1000;\n\n// ink's useAnimation resets time to 0 on reactivation, so it restarts each run and keeps counting across restart-required\nexport function useUptime(state: DevState, shown: boolean): number | null {\n const active = isSessionLive(state.phase) && shown;\n const { time } = useAnimation({ interval: TICK_MS, isActive: active });\n return active ? time : null;\n}\n","// stable first-seen assignment keeps a channel's tag matched to its filter chip. red is reserved for errors and the live dot, so it stays out of the palette.\nconst PALETTE = [\n '#ff8a3d',\n '#ff6a4d',\n '#f5b52a',\n '#d9d641',\n '#a3d93a',\n '#5fc95a',\n '#35c98a',\n '#2fbfa0',\n '#23b5c9',\n '#3d9ff0',\n '#3d8ef0',\n '#5a7bff',\n '#6d6ff0',\n '#9a6cf0',\n '#b85cf0',\n '#c96cf0',\n '#e05cd0',\n '#f062c0',\n '#ff5f9e',\n '#ff6b6b'\n] as const;\n\nconst assigned = new Map<string, string>();\n\nexport function channelColor(channel: string): string {\n const existing = assigned.get(channel);\n if (existing !== undefined) return existing;\n\n const color = PALETTE[assigned.size % PALETTE.length] ?? PALETTE[0];\n assigned.set(channel, color);\n return color;\n}\n\n// clearing here keeps stale channels from skewing the next session's colors\nexport function resetChannelColors(): void {\n assigned.clear();\n}\n","import { LEVEL_COLOR } from '@seedcord/logger';\nimport { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { channelColor } from '#ui/channelColor';\nimport { focusedIn } from '#ui/filterCursor';\nimport { ui } from '#ui/palette';\n\nimport type { FilterCursor } from '#ui/filterCursor';\nimport type { LogLevel } from '@seedcord/types';\nimport type { ReactElement } from 'react';\n\nexport const FILTER_LEVELS: readonly LogLevel[] = ['error', 'warn', 'info', 'debug', 'trace'];\n\ninterface FilterChipsProps {\n readonly channels: readonly string[];\n readonly enabledChannels: ReadonlySet<string>;\n readonly enabledLevels: ReadonlySet<LogLevel>;\n readonly cursor: FilterCursor | null;\n readonly open: boolean;\n}\n\nfunction Heading({ label, open }: { label: string; open: boolean }): ReactElement {\n return (\n <Text>\n <Text color={ui.accent} bold>\n {open ? '▾' : '▸'}\n </Text>\n <Text color={ui.muted}> {label}</Text>\n </Text>\n );\n}\n\nfunction Chip({\n label,\n on,\n color,\n focused\n}: {\n label: string;\n on: boolean;\n color: string;\n focused: boolean;\n}): ReactElement {\n return (\n <Box marginRight={1}>\n {on ? (\n <Text color={color} bold={focused} underline={focused}>\n {label}\n </Text>\n ) : (\n <Text dimColor bold={focused} underline={focused}>\n {label}\n </Text>\n )}\n </Box>\n );\n}\n\nexport function FilterChips({\n channels,\n enabledChannels,\n enabledLevels,\n cursor,\n open\n}: FilterChipsProps): ReactElement {\n const allChannels = enabledChannels.size === 0;\n const allLevels = enabledLevels.size === 0;\n const channelFocus = focusedIn(cursor, 'channels', channels.length);\n const levelFocus = focusedIn(cursor, 'levels', FILTER_LEVELS.length);\n\n return (\n <Box flexDirection=\"column\">\n {open ? null : (\n <Text dimColor wrap=\"truncate\">\n resize to see filters\n </Text>\n )}\n <Heading label=\"channels\" open={open} />\n {open ? (\n <Box marginLeft={2} flexWrap=\"wrap\">\n {channels.map((channel, index) => (\n <Chip\n key={channel}\n label={channel}\n on={allChannels || enabledChannels.has(channel)}\n color={channelColor(channel)}\n focused={channelFocus === index}\n />\n ))}\n </Box>\n ) : null}\n\n <Heading label=\"levels\" open={open} />\n {open ? (\n <Box marginLeft={2} flexWrap=\"wrap\">\n {FILTER_LEVELS.map((level, index) => (\n <Chip\n key={level}\n label={level}\n on={allLevels || enabledLevels.has(level)}\n color={LEVEL_COLOR[level]}\n focused={levelFocus === index}\n />\n ))}\n </Box>\n ) : null}\n </Box>\n );\n}\n","import { FILTER_LEVELS } from '#ui/components/primitives/FilterChips';\nimport { focusedIn, moveCursor } from '#ui/filterCursor';\nimport { isSessionLive } from '#ui/stores/devPhase';\nimport { LogStore } from '#ui/stores/LogStore';\n\nimport type { CursorMove, FilterCursor } from '#ui/filterCursor';\nimport type { ScrollApi } from '#ui/hooks/useScroll';\nimport type { LogRow } from '#ui/logRows';\nimport type { DevState, DevStore } from '#ui/stores/DevStore';\nimport type { LogLevel } from '@seedcord/types';\nimport type { Key } from 'ink';\n\n// empty set means all. toggling every channel on collapses back to empty, keeping later channels visible by default\nfunction toggleChannel(prev: ReadonlySet<string>, channel: string, all: readonly string[]): ReadonlySet<string> {\n const base = prev.size === 0 ? new Set(all) : new Set(prev);\n if (base.has(channel)) base.delete(channel);\n else base.add(channel);\n return base.size === all.length ? new Set<string>() : base;\n}\n\nfunction toggleLevel(prev: ReadonlySet<LogLevel>, level: LogLevel): ReadonlySet<LogLevel> {\n const base = prev.size === 0 ? new Set(FILTER_LEVELS) : new Set(prev);\n if (base.has(level)) base.delete(level);\n else base.add(level);\n return base.size === FILTER_LEVELS.length ? new Set<LogLevel>() : base;\n}\n\n// re-soloing the soloed item restores all (empty set = all)\nfunction soloChannel(prev: ReadonlySet<string>, channel: string): ReadonlySet<string> {\n return prev.size === 1 && prev.has(channel) ? new Set<string>() : new Set([channel]);\n}\n\nfunction soloLevel(prev: ReadonlySet<LogLevel>, level: LogLevel): ReadonlySet<LogLevel> {\n return prev.size === 1 && prev.has(level) ? new Set<LogLevel>() : new Set([level]);\n}\n\ninterface HotkeyContext {\n readonly input: string;\n readonly key: Key;\n readonly state: DevState;\n readonly interactive: boolean;\n readonly scroll: ScrollApi<LogRow>;\n readonly store: DevStore;\n readonly enabled: ReadonlySet<string>;\n readonly setEnabled: (next: ReadonlySet<string>) => void;\n readonly enabledLevels: ReadonlySet<LogLevel>;\n readonly setEnabledLevels: (next: ReadonlySet<LogLevel>) => void;\n readonly cursor: FilterCursor;\n readonly setCursor: (next: FilterCursor) => void;\n readonly filtersOpen: boolean;\n readonly onQuit?: (() => Promise<void> | void) | undefined;\n readonly onDisconnect?: (() => Promise<void> | void) | undefined;\n readonly onRestart?: (() => Promise<void> | void) | undefined;\n readonly onRefreshCommands?: ((shouldRefresh: boolean) => Promise<void> | void) | undefined;\n}\n\nfunction quit(ctx: HotkeyContext): void {\n ctx.store.beginQuit();\n void ctx.onQuit?.();\n}\n\n// ink puts stdin in raw mode, so ctrl-c arrives as a plain keypress with no sigint\nfunction handleQuitSignal(ctx: HotkeyContext): boolean {\n if (!ctx.key.ctrl || ctx.input !== 'c') return false;\n\n if (ctx.state.quitArmed) quit(ctx);\n else ctx.store.setQuitArmed(true);\n return true;\n}\n\nfunction handlePrompt(ctx: HotkeyContext): boolean {\n if (!ctx.state.commandUpdatePrompt) return false;\n if (ctx.input === 'y') {\n void ctx.onRefreshCommands?.(true);\n ctx.store.clearPrompt();\n } else if (ctx.input === 'n') {\n void ctx.onRefreshCommands?.(false);\n ctx.store.clearPrompt();\n }\n return true;\n}\n\nfunction applyAtCursor(\n ctx: HotkeyContext,\n channels: readonly string[],\n onChannel: (prev: ReadonlySet<string>, channel: string, all: readonly string[]) => ReadonlySet<string>,\n onLevel: (prev: ReadonlySet<LogLevel>, level: LogLevel) => ReadonlySet<LogLevel>\n): void {\n if (ctx.cursor.group === 'channels') {\n const index = focusedIn(ctx.cursor, 'channels', channels.length);\n const channel = index === null ? undefined : channels[index];\n if (channel !== undefined) ctx.setEnabled(onChannel(ctx.enabled, channel, channels));\n return;\n }\n const index = focusedIn(ctx.cursor, 'levels', FILTER_LEVELS.length);\n const level = index === null ? undefined : FILTER_LEVELS[index];\n if (level !== undefined) ctx.setEnabledLevels(onLevel(ctx.enabledLevels, level));\n}\n\nfunction handleFilters(ctx: HotkeyContext): boolean {\n if (!ctx.filtersOpen) return false;\n\n const channels = LogStore.instance.getChannels();\n const move = (dir: CursorMove): void =>\n ctx.setCursor(moveCursor(ctx.cursor, dir, channels.length, FILTER_LEVELS.length));\n\n if (ctx.key.leftArrow) move('left');\n else if (ctx.key.rightArrow) move('right');\n else if (ctx.key.tab) move('switch');\n else if (ctx.input === ' ') applyAtCursor(ctx, channels, soloChannel, soloLevel);\n else if (ctx.input === 'o') applyAtCursor(ctx, channels, toggleChannel, toggleLevel);\n else return false;\n return true;\n}\n\nfunction handleScroll(ctx: HotkeyContext): boolean {\n // runs before session actions so scroll works even when non-interactive\n const { key, input, scroll } = ctx;\n if (key.upArrow) scroll.up();\n else if (key.downArrow) scroll.down();\n else if (key.pageUp) scroll.pageUp();\n else if (key.pageDown) scroll.pageDown();\n else if (key.home || input === 't') scroll.toTop();\n else if (key.end || input === 'b') scroll.toBottom();\n else return false;\n return true;\n}\n\nfunction handleActions(ctx: HotkeyContext): void {\n const { input, state, store } = ctx;\n\n if (input === 'q') {\n quit(ctx);\n return;\n }\n if (!ctx.interactive) return;\n\n switch (input) {\n case 'd': {\n if (!isSessionLive(state.phase)) return;\n store.beginDisconnect();\n void ctx.onDisconnect?.();\n\n break;\n }\n case 'r': {\n store.beginRestart();\n void ctx.onRestart?.();\n\n break;\n }\n case 'c': {\n LogStore.instance.clear();\n ctx.scroll.toBottom();\n\n break;\n }\n // No default\n }\n}\n\n// dispatch checks the prompt before filters. an open y/n prompt would otherwise lose keys to filter hotkeys\nexport function dispatchHotkey(ctx: HotkeyContext): void {\n if (handleQuitSignal(ctx)) return;\n if (ctx.state.quitArmed) ctx.store.setQuitArmed(false);\n if (handlePrompt(ctx)) return;\n if (handleFilters(ctx)) return;\n if (handleScroll(ctx)) return;\n handleActions(ctx);\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\ninterface LogHeaderProps {\n readonly following: boolean;\n readonly below: number;\n}\n\nexport function LogHeader({ following, below }: LogHeaderProps): ReactElement | null {\n if (following) return null;\n return (\n <Box flexShrink={0}>\n <Text color={ui.warn} wrap=\"truncate\">{`▲ scrolled · ${below} newer below · b to follow`}</Text>\n </Box>\n );\n}\n","import { Box } from 'ink';\nimport React, { Fragment } from 'react';\n\nimport type { Notice } from '#ui/notices';\nimport type { ReactElement } from 'react';\n\ninterface NotificationStackProps {\n readonly notices: readonly Notice[];\n}\n\nexport function NotificationStack({ notices }: NotificationStackProps): ReactElement | null {\n if (notices.length === 0) return null;\n\n return (\n <Box flexShrink={0} flexDirection=\"column\">\n {notices.map((notice) => (\n <Fragment key={notice.key}>{notice.card}</Fragment>\n ))}\n </Box>\n );\n}\n","const MS_PER_SECOND = 1000;\nconst SECONDS_PER_MINUTE = 60;\nconst MINUTES_PER_HOUR = 60;\n\nfunction pad(value: number): string {\n return value.toString().padStart(2, '0');\n}\n\nexport function formatUptime(ms: number): string {\n const totalSeconds = Math.max(0, Math.floor(ms / MS_PER_SECOND));\n const seconds = totalSeconds % SECONDS_PER_MINUTE;\n const totalMinutes = Math.floor(totalSeconds / SECONDS_PER_MINUTE);\n const minutes = totalMinutes % MINUTES_PER_HOUR;\n const hours = Math.floor(totalMinutes / MINUTES_PER_HOUR);\n\n if (hours > 0) return `${hours}h ${pad(minutes)}m ${pad(seconds)}s`;\n if (minutes > 0) return `${minutes}m ${pad(seconds)}s`;\n return `${seconds}s`;\n}\n\n// local time\nexport function formatClock(ts: number): string {\n const d = new Date(ts);\n return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;\n}\n","import wrapAnsi from 'wrap-ansi';\n\nimport type { LogEntry } from '#ui/stores/LogStore';\n\nconst CHIP_WIDTH = 3;\nconst TIME_WIDTH = 8;\nconst DOT_WIDTH = 1;\nconst BAR_WIDTH = 1;\nconst MIN_TEXT_WIDTH = 8;\n\nexport const messageColumn = (labelWidth: number): number =>\n CHIP_WIDTH + 1 + TIME_WIDTH + 1 + labelWidth + 1 + DOT_WIDTH + 1;\n\n// one row per rendered line, which the viewport math uses\nexport type LogRow =\n { kind: 'entry'; key: string; entry: LogEntry; text: string; first: boolean } | { kind: 'rule'; key: string };\n\nfunction isBlockLine(entry: LogEntry | undefined): boolean {\n return entry !== undefined && entry.level !== 'error';\n}\n\nfunction opensBlock(logs: readonly LogEntry[], index: number): boolean {\n const log = logs[index];\n const next = logs[index + 1];\n return log?.head === true && isBlockLine(log) && next !== undefined && !next.head && isBlockLine(next);\n}\n\nfunction closesBlock(logs: readonly LogEntry[], index: number): boolean {\n const log = logs[index];\n const next = logs[index + 1];\n return log !== undefined && !log.head && isBlockLine(log) && (next === undefined || next.head);\n}\n\n// adjacent blocks share one rule, because the block above already drew its bottom\nfunction prevClosedBlock(logs: readonly LogEntry[], index: number): boolean {\n const prev = logs[index - 1];\n return prev !== undefined && !prev.head && isBlockLine(prev);\n}\n\nexport function expandRows(logs: readonly LogEntry[]): LogRow[] {\n const rows: LogRow[] = [];\n for (const [index, entry] of logs.entries()) {\n if (opensBlock(logs, index) && !prevClosedBlock(logs, index)) {\n rows.push({ kind: 'rule', key: `top-${entry.id}` });\n }\n rows.push({ kind: 'entry', key: String(entry.id), entry, text: entry.text, first: true });\n if (closesBlock(logs, index)) rows.push({ kind: 'rule', key: `bottom-${entry.id}` });\n }\n return rows;\n}\n\n// the gutters mirror what ScrollableLogView draws in front of each line\nfunction textWidth(entry: LogEntry, width: number, labelWidth: number): number {\n const gutter = !entry.head && entry.level === 'error' ? BAR_WIDTH : messageColumn(labelWidth);\n return width - gutter;\n}\n\nexport function wrapRows(rows: readonly LogRow[], width: number, labelWidth: number): LogRow[] {\n return rows.flatMap((row) => {\n if (row.kind === 'rule') return row;\n\n const available = textWidth(row.entry, width, labelWidth);\n // nothing left to wrap into at this width, and the render truncates\n if (available < MIN_TEXT_WIDTH) return row;\n\n // trim would strip a stack frame's leading indentation\n const lines = wrapAnsi(row.text, available, { hard: true, trim: false }).split('\\n');\n return lines.map((text, index) => ({\n kind: 'entry' as const,\n key: `${row.key}:${String(index)}`,\n entry: row.entry,\n // the wrap break leaves a leading space that would misalign the tail\n text: index === 0 ? text : text.replace(/^ +/, ''),\n first: index === 0\n }));\n });\n}\n\nexport function rowKey(row: LogRow): number | string {\n return row.key;\n}\n","import { LEVEL_COLOR } from '@seedcord/logger';\nimport { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { channelColor } from '#ui/channelColor';\nimport { Rule } from '#ui/components/primitives/Rule';\nimport { formatClock } from '#ui/format';\nimport { messageColumn } from '#ui/logRows';\nimport { ui } from '#ui/palette';\nimport { LogStore } from '#ui/stores/LogStore';\n\nimport type { LogRow } from '#ui/logRows';\nimport type { LogEntry } from '#ui/stores/LogStore';\nimport type { LogLevel } from '@seedcord/types';\nimport type { ReactElement } from 'react';\n\nconst MIN_LOG_LINES = 5; // fits an error head plus a few stack frames\n\nexport const NO_ROOM = 'Need more room for logs.';\nconst DOT = '●';\nconst BAR = '▌';\nconst GUIDE = '│';\nconst ELLIPSIS = '…';\nconst CHIP_TEXT = '#1a1a1a';\n\nconst LEVEL_LETTER: Record<LogLevel, string> = { error: 'E', warn: 'W', info: 'I', debug: 'D', trace: 'T' };\n\nconst WASH: Partial<Record<LogLevel, string>> = { warn: '#3a2f14', error: '#3d1a20' };\n\nfunction truncate(label: string, width: number): string {\n return label.length > width ? `${label.slice(0, width - 1)}${ELLIPSIS}` : label;\n}\n\nfunction Chip({ level }: { level: LogLevel }): ReactElement {\n return (\n <Text backgroundColor={LEVEL_COLOR[level]} color={CHIP_TEXT} bold>\n {` ${LEVEL_LETTER[level]} `}\n </Text>\n );\n}\n\nfunction Prefix({ log, labelWidth }: { log: LogEntry; labelWidth: number }): ReactElement {\n const label = truncate(log.label, labelWidth).padStart(labelWidth);\n return (\n <>\n <Chip level={log.level} /> <Text dimColor>{formatClock(log.timestamp)}</Text> <Text>{label}</Text>{' '}\n <Text color={channelColor(log.channel)}>{DOT}</Text>\n </>\n );\n}\n\ninterface LineProps {\n readonly log: LogEntry;\n readonly text: string;\n readonly labelWidth: number;\n}\n\nfunction HeadLine({ log, text, labelWidth }: LineProps): ReactElement {\n const wash = WASH[log.level];\n\n if (wash) {\n return (\n <Text wrap=\"truncate\">\n <Text backgroundColor={wash}>\n <Prefix log={log} labelWidth={labelWidth} />\n </Text>{' '}\n {text}\n </Text>\n );\n }\n\n return (\n <Text wrap=\"truncate\">\n <Prefix log={log} labelWidth={labelWidth} /> {text}\n </Text>\n );\n}\n\nfunction HeadTail({ text, labelWidth }: Omit<LineProps, 'log'>): ReactElement {\n return (\n <Text wrap=\"truncate\">\n {' '.repeat(messageColumn(labelWidth) - 2)}\n <Text dimColor>{GUIDE}</Text> {text}\n </Text>\n );\n}\n\nfunction ContinuationLine({ log, text, labelWidth }: LineProps): ReactElement {\n if (log.level === 'error') {\n return (\n <Text wrap=\"truncate\">\n <Text color={LEVEL_COLOR.error} bold>\n {BAR}\n </Text>\n <Text dimColor={log.frame}>{text}</Text>\n </Text>\n );\n }\n\n return (\n <Text wrap=\"truncate\">\n {' '.repeat(messageColumn(labelWidth) - 2)}\n <Text dimColor>{GUIDE}</Text> {text}\n </Text>\n );\n}\n\ninterface ScrollableLogViewProps {\n readonly visible: readonly LogRow[];\n readonly viewportHeight: number;\n // an unmeasured height would flash \"too small\" on the first frame\n readonly measured: boolean;\n}\n\nexport function ScrollableLogView({ visible, viewportHeight, measured }: ScrollableLogViewProps): ReactElement | null {\n if (!measured) return null;\n\n if (viewportHeight < MIN_LOG_LINES) {\n return (\n <Box flexGrow={1} alignItems=\"center\" justifyContent=\"center\" overflow=\"hidden\">\n <Text color={ui.warn} bold wrap=\"truncate\">\n {NO_ROOM}\n </Text>\n </Box>\n );\n }\n\n const labelWidth = Math.max(1, LogStore.instance.getLabelWidth());\n\n return (\n // flex-end keeps the newest line on the bottom edge even when the buffer is nearly empty\n <Box flexDirection=\"column\" flexGrow={1} justifyContent=\"flex-end\" overflow=\"hidden\">\n {visible.length === 0 ? (\n <Text dimColor>Waiting for logs…</Text>\n ) : (\n visible.map((row) => {\n if (row.kind === 'rule') return <Rule key={row.key} />;\n const props = { log: row.entry, text: row.text, labelWidth };\n // a continuation draws its gutter on every row\n if (!row.entry.head) return <ContinuationLine key={row.key} {...props} />;\n return row.first ? <HeadLine key={row.key} {...props} /> : <HeadTail key={row.key} {...props} />;\n })\n )}\n </Box>\n );\n}\n","import { BRAND } from '@seedcord/errors/internal';\nimport { Text } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\ninterface BannerProps {\n readonly version: string | null;\n}\n\nexport function Banner({ version }: BannerProps): ReactElement {\n return (\n <Text>\n <Text bold color={BRAND.flesh}>\n seed\n </Text>\n <Text bold color={BRAND.rind}>\n cord\n </Text>\n {version === null ? null : <Text color={BRAND.pith}> • v{version}</Text>}\n </Text>\n );\n}\n","import { Text, useAnimation } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\nconst BLINK_MS = 530;\n\nexport function BlinkDot({ animate = true }: { readonly animate?: boolean }): ReactElement {\n const { frame } = useAnimation({ interval: BLINK_MS, isActive: animate });\n const lit = !animate || frame % 2 === 0;\n\n return <Text color={ui.bad}>{lit ? '●' : ' '}</Text>;\n}\n","import { Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport React from 'react';\n\nimport { isStreaming, PHASE_META } from '#ui/stores/devPhase';\n\nimport { BlinkDot } from './primitives/BlinkDot';\n\nimport type { DevPhase } from '#ui/stores/devPhase';\nimport type { ReactElement } from 'react';\n\ninterface StatusBadgeProps {\n readonly phase: DevPhase;\n readonly glyph?: 'phase' | 'live';\n readonly animate?: boolean;\n}\n\nfunction Glyph({ phase, glyph, animate }: Required<StatusBadgeProps>): ReactElement {\n const meta = PHASE_META[phase];\n if (glyph === 'live') return isStreaming(phase) ? <BlinkDot animate={animate} /> : <Text>{meta.icon}</Text>;\n // ink-spinner keeps its frame index across a type swap and wraps on equality, so a 7-frame\n // index carried into a 4-frame set renders nothing forever. The key forces a fresh mount.\n if (meta.kind === 'spinner') return <Spinner key=\"balloon2\" type=\"balloon2\" />;\n // the arc runs for as long as the bot does\n if (meta.kind === 'arc' && animate) return <Spinner key=\"toggle4\" type=\"toggle4\" />;\n return <Text>{meta.icon}</Text>;\n}\n\nexport function StatusBadge({ phase, glyph = 'phase', animate = true }: StatusBadgeProps): ReactElement {\n const meta = PHASE_META[phase];\n return (\n <Text color={meta.color} bold>\n <Glyph phase={phase} glyph={glyph} animate={animate} /> {meta.label}\n </Text>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\nimport { isSessionLive } from '#ui/stores/devPhase';\n\nimport type { DevPhase } from '#ui/stores/devPhase';\nimport type { ReactElement } from 'react';\n\ninterface HotkeyProps {\n readonly keyLabel: string;\n readonly action: string;\n readonly enabled?: boolean;\n readonly highlight?: boolean;\n}\n\nfunction Hotkey({ keyLabel, action, enabled = true, highlight = false }: HotkeyProps): ReactElement {\n const keyColor = !enabled ? ui.faint : highlight ? ui.warn : ui.accent;\n const actionColor = enabled ? ui.muted : ui.faint;\n return (\n <Box marginRight={2}>\n <Text color={keyColor} bold>\n {keyLabel}\n </Text>\n <Text color={actionColor}> {action}</Text>\n </Box>\n );\n}\n\nconst RESTART_HINT_PHASES = new Set<DevPhase>(['restart-required', 'disconnected', 'error']);\n\ninterface SessionKeysProps {\n readonly phase: DevPhase;\n readonly interactive: boolean;\n readonly following: boolean;\n}\n\nexport function SessionKeys({ phase, interactive, following }: SessionKeysProps): ReactElement {\n return (\n <Box flexDirection=\"column\">\n <Hotkey keyLabel=\"q\" action=\"quit\" />\n <Hotkey keyLabel=\"r\" action=\"restart\" enabled={interactive} highlight={RESTART_HINT_PHASES.has(phase)} />\n <Hotkey keyLabel=\"d\" action=\"disconnect\" enabled={interactive && isSessionLive(phase)} />\n <Hotkey keyLabel=\"c\" action=\"clear\" enabled={interactive} />\n <Hotkey keyLabel=\"↑↓\" action=\"scroll\" />\n <Hotkey keyLabel=\"t/b\" action=\"top/bottom\" highlight={!following} />\n </Box>\n );\n}\n\nexport function FilterKeys(): ReactElement {\n return (\n <Box flexDirection=\"column\">\n <Hotkey keyLabel=\"←→\" action=\"select\" />\n <Hotkey keyLabel=\"tab\" action=\"group\" />\n <Hotkey keyLabel=\"space\" action=\"filter\" />\n <Hotkey keyLabel=\"o\" action=\"toggle\" />\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { version } from '#core/version';\nimport { formatUptime } from '#ui/format';\nimport { isStreaming } from '#ui/stores/devPhase';\nimport { LogStore } from '#ui/stores/LogStore';\n\nimport { Banner } from '../Banner';\nimport { StatusBadge } from '../StatusBadge';\nimport { BlinkDot } from './BlinkDot';\nimport { FilterChips } from './FilterChips';\nimport { FilterKeys, SessionKeys } from './Hotkeys';\nimport { Rule } from './Rule';\n\nimport type { TunnelStatus } from '#commands/dev/tunnel/TunnelCoordinator';\nimport type { FilterCursor } from '#ui/filterCursor';\nimport type { DevState, DevTransport } from '#ui/stores/DevStore';\nimport type { LogLevel } from '@seedcord/types';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement, Ref } from 'react';\n\nexport const MAX_RAIL = 40;\n\n// the widest label is 'gateway' at 7\nconst META_LABEL_WIDTH = 8;\n\nconst LOG_DIR = 'logs/'; // the dev default writes one combined file into this folder\n\ninterface SidebarProps {\n readonly state: DevState;\n readonly enabled: ReadonlySet<string>;\n readonly enabledLevels: ReadonlySet<LogLevel>;\n readonly uptimeMs: number | null;\n readonly following: boolean;\n readonly interactive: boolean;\n readonly cursor: FilterCursor;\n readonly width: number | null;\n readonly filtersOpen: boolean;\n readonly ref?: Ref<DOMElement>;\n}\n\nfunction Meta({ label, value }: { label: string; value: string }): ReactElement {\n return (\n <Text>\n <Text dimColor>{label.padEnd(META_LABEL_WIDTH)}</Text>\n {value}\n </Text>\n );\n}\n\nfunction tunnelValue(status: TunnelStatus): string {\n return status === 'live' || status === 'lost' ? status : `${status}…`;\n}\n\nfunction transportLabel({ name }: DevTransport): string {\n return name.replace('@seedcord/', '');\n}\n\nfunction StatusBlock({ state, uptimeMs }: { state: DevState; uptimeMs: number | null }): ReactElement {\n return (\n <Box flexDirection=\"column\">\n <StatusBadge phase={state.phase} animate={state.idleAnimation} />\n {state.status ? <Text>{state.status}</Text> : null}\n {state.transport === null ? null : (\n <Meta label={transportLabel(state.transport)} value={`v${state.transport.version}`} />\n )}\n {uptimeMs === null ? null : <Meta label=\"up\" value={formatUptime(uptimeMs)} />}\n {/* only the http host reports a port */}\n {state.port === null ? null : <Meta label=\"port\" value={String(state.port)} />}\n {state.tunnel === null ? null : <Meta label=\"tunnel\" value={tunnelValue(state.tunnel)} />}\n <Meta label=\"logs\" value={LOG_DIR} />\n </Box>\n );\n}\n\n// flexShrink={0} on every section holds its natural height, a short terminal overlaps rows without it\nexport function Sidebar({\n state,\n enabled,\n enabledLevels,\n uptimeMs,\n following,\n interactive,\n cursor,\n width,\n filtersOpen,\n ref\n}: SidebarProps): ReactElement {\n return (\n <Box\n ref={ref}\n flexDirection=\"column\"\n width={width ?? undefined}\n maxWidth={MAX_RAIL}\n flexShrink={0}\n paddingX={1}\n overflow=\"hidden\"\n >\n <Box flexShrink={0}>\n <Banner version={version} />\n </Box>\n <Box flexShrink={0} marginTop={1}>\n <StatusBlock state={state} uptimeMs={uptimeMs} />\n </Box>\n <Box flexShrink={0} marginTop={1} flexDirection=\"column\">\n <FilterChips\n channels={LogStore.instance.getChannels()}\n enabledChannels={enabled}\n enabledLevels={enabledLevels}\n cursor={cursor}\n open={filtersOpen}\n />\n </Box>\n {filtersOpen ? (\n <Box flexShrink={0} marginTop={1} flexDirection=\"column\">\n <FilterKeys />\n <Rule />\n </Box>\n ) : null}\n {/* the rule already separates the two key groups, so the blank row is only for the collapsed form */}\n <Box flexShrink={0} marginTop={filtersOpen ? 0 : 1}>\n <SessionKeys phase={state.phase} interactive={interactive} following={following} />\n </Box>\n <Box flexGrow={1} />\n <Box flexShrink={0} justifyContent=\"flex-end\">\n {isStreaming(state.phase) ? (\n <Text>\n <BlinkDot animate={state.idleAnimation} />\n <Text dimColor> live</Text>\n </Text>\n ) : (\n <Text dimColor>○ idle</Text>\n )}\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport { Banner } from '../Banner';\nimport { StatusBadge } from '../StatusBadge';\n\nimport type { Notice } from '#ui/notices';\nimport type { DevState } from '#ui/stores/DevStore';\nimport type { ReactElement } from 'react';\n\nconst HINT = 'resize for full ui';\n\n// below this the hint would crowd out the summary, and it stays optional either way\nconst HINT_COLUMNS = 64;\n\ninterface StatusLineProps {\n readonly state: DevState;\n readonly notices: readonly Notice[];\n readonly columns: number;\n}\n\n/** The single row standing in for the rail once the terminal is too small to hold it. */\nexport function StatusLine({ state, notices, columns }: StatusLineProps): ReactElement {\n const [top, ...rest] = notices;\n\n return (\n <Box flexShrink={0} justifyContent=\"space-between\" paddingX={1}>\n <Box flexShrink={1} overflow=\"hidden\">\n <Text wrap=\"truncate\">\n <Banner version={null} />{' '}\n <StatusBadge phase={state.phase} glyph=\"live\" animate={state.idleAnimation} />\n {top?.summary ? <Text dimColor> · </Text> : null}\n {top?.summary ? <Text color={ui.warn}>{top.summary}</Text> : null}\n {rest.length > 0 ? <Text dimColor> · +{rest.length}</Text> : null}\n </Text>\n </Box>\n {/* flexShrink 0 and the margin keep the key readable against a summary that fills the row */}\n <Box flexShrink={0} marginLeft={2}>\n {top ? (\n <Text bold color={ui.accent}>\n {top.action}\n </Text>\n ) : null}\n {/* the action always renders, since a prompt swallows every key and this row is its only affordance */}\n {!top && columns >= HINT_COLUMNS ? <Text dimColor>{HINT}</Text> : null}\n </Box>\n </Box>\n );\n}\n","import { Box } from 'ink';\nimport React from 'react';\n\nimport { LogHeader } from '#ui/components/primitives/LogHeader';\nimport { NotificationStack } from '#ui/components/primitives/NotificationStack';\nimport { Rule } from '#ui/components/primitives/Rule';\nimport { ScrollableLogView } from '#ui/components/primitives/ScrollableLogView';\nimport { Sidebar } from '#ui/components/primitives/Sidebar';\nimport { StatusLine } from '#ui/components/primitives/StatusLine';\n\nimport type { FilterCursor } from '#ui/filterCursor';\nimport type { ScrollApi } from '#ui/hooks/useScroll';\nimport type { LogRow } from '#ui/logRows';\nimport type { Notice } from '#ui/notices';\nimport type { DevState } from '#ui/stores/DevStore';\nimport type { Tier } from '#ui/tier';\nimport type { LogLevel } from '@seedcord/types';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement, Ref } from 'react';\n\nexport interface DevLayoutProps {\n readonly state: DevState;\n readonly tier: Tier;\n readonly notices: readonly Notice[];\n readonly railRef: Ref<DOMElement>;\n // measured once per run and held until the next restart, null before the measurement completes\n readonly railWidth: number | null;\n // the shell measures this box to size the scroll window. it must be attached or the viewport is empty\n readonly logBoxRef: Ref<DOMElement>;\n readonly scroll: ScrollApi<LogRow>;\n readonly viewportHeight: number;\n readonly measured: boolean;\n readonly columns: number;\n readonly enabled: ReadonlySet<string>;\n readonly enabledLevels: ReadonlySet<LogLevel>;\n readonly cursor: FilterCursor;\n readonly interactive: boolean;\n readonly uptimeMs: number | null;\n}\n\n// notification cards render below the logs so stack traces have room\nexport function DevLayout(props: DevLayoutProps): ReactElement {\n const { state, tier, notices, railRef, railWidth, logBoxRef, scroll, viewportHeight, measured } = props;\n const { columns, enabled, enabledLevels, cursor, interactive, uptimeMs } = props;\n const railed = tier === 'full' || tier === 'compact';\n\n return (\n <Box flexGrow={1}>\n {railed ? (\n <Sidebar\n ref={railRef}\n state={state}\n enabled={enabled}\n enabledLevels={enabledLevels}\n uptimeMs={uptimeMs}\n following={scroll.following}\n interactive={interactive}\n cursor={cursor}\n width={railWidth}\n filtersOpen={tier === 'full'}\n />\n ) : null}\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n minWidth={0}\n borderStyle=\"single\"\n borderColor=\"gray\"\n borderTop={false}\n borderRight={false}\n borderBottom={false}\n borderLeft={railed}\n paddingLeft={railed ? 1 : 0}\n overflow=\"hidden\"\n >\n {railed ? null : <StatusLine state={state} notices={notices} columns={columns} />}\n {railed ? null : <Rule />}\n <LogHeader following={scroll.following} below={scroll.below} />\n {/* the notification stack is unbounded, so the pane keeps a row back for its own message */}\n <Box ref={logBoxRef} flexGrow={1} minHeight={1} overflow=\"hidden\">\n <ScrollableLogView visible={scroll.visible} viewportHeight={viewportHeight} measured={measured} />\n </Box>\n {railed ? <NotificationStack notices={notices} /> : null}\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\ninterface CommandRefreshPromptProps {\n files: string[];\n}\n\nexport function CommandRefreshPrompt({ files }: CommandRefreshPromptProps): ReactElement {\n return (\n <Box borderStyle=\"round\" borderColor={ui.warn} flexDirection=\"column\" paddingX={1}>\n <Text>\n <Text color={ui.warn} bold>\n Commands updated:\n </Text>\n </Text>\n {files.map((file) => (\n <Text key={file} color={ui.accent}>\n - {file}\n </Text>\n ))}\n <Text>Refresh commands? (y/n)</Text>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\nconst STACK_PREVIEW_LINES = 6;\n\ninterface ErrorDisplayProps {\n readonly error: Error;\n}\n\nexport function ErrorDisplay({ error }: ErrorDisplayProps): ReactElement {\n // stack[0] repeats the \"Error: message\" line already rendered above\n const frames = (error.stack?.split('\\n') ?? []).slice(1);\n const preview = frames.slice(0, STACK_PREVIEW_LINES);\n const hidden = frames.length - preview.length;\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={ui.bad} paddingX={1}>\n <Text color={ui.bad} bold>\n Error: {error.name}\n </Text>\n <Text>{error.message}</Text>\n {preview.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n {preview.map((line) => (\n <Text key={line} dimColor wrap=\"truncate\">\n {line}\n </Text>\n ))}\n {hidden > 0 && <Text dimColor>{`… ${hidden} more line${hidden === 1 ? '' : 's'}`}</Text>}\n </Box>\n )}\n <Box marginTop={1}>\n <Text>\n press{' '}\n <Text color={ui.warn} bold>\n r\n </Text>{' '}\n to restart\n </Text>\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\nexport function QuitConfirmCard(): ReactElement {\n return (\n <Box borderStyle=\"round\" borderColor={ui.warn} flexDirection=\"column\" paddingX={1}>\n <Text color={ui.warn} bold>\n Quit?\n </Text>\n <Text>\n press{' '}\n <Text color={ui.warn} bold>\n Ctrl-C\n </Text>{' '}\n again to quit, or any other key to stay\n </Text>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { ReactElement } from 'react';\n\nexport function RestartRequiredCard(): ReactElement {\n return (\n <Box borderStyle=\"round\" borderColor={ui.warn} flexDirection=\"column\" paddingX={1}>\n <Text color={ui.warn} bold>\n Restart required\n </Text>\n <Text>\n A change needs a full restart. press{' '}\n <Text color={ui.warn} bold>\n r\n </Text>{' '}\n to restart\n </Text>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport React from 'react';\n\nimport { ui } from '#ui/palette';\n\nimport type { TunnelPhase } from '#commands/dev/tunnel/TunnelCoordinator';\nimport type { ReactElement } from 'react';\n\nconst STEPS: readonly (readonly [TunnelPhase, string])[] = [\n ['opening', 'Opening the tunnel'],\n ['resolving', 'Waiting for it to answer'],\n ['registering', 'Telling Discord where to reach you']\n];\n\nfunction Marker({ done, active }: { done: boolean; active: boolean }): ReactElement {\n if (done) return <Text color={ui.good}>✔︎</Text>;\n if (active) return <Spinner type=\"dots\" />;\n return <Text color={ui.faint}>·</Text>;\n}\n\nexport function TunnelOpeningCard({ phase }: { phase: TunnelPhase }): ReactElement {\n const at = STEPS.findIndex(([step]) => step === phase);\n\n return (\n <Box borderStyle=\"round\" borderColor={ui.accent} flexDirection=\"column\" paddingX={1}>\n <Text color={ui.accent} bold>\n Setting up your interactions endpoint\n </Text>\n {STEPS.map(([step, label], index) => (\n <Text key={step} dimColor={index > at}>\n <Marker done={index < at} active={index === at} /> {label}\n </Text>\n ))}\n </Box>\n );\n}\n","import React from 'react';\n\nimport { CommandRefreshPrompt } from '#ui/components/CommandRefreshPrompt';\nimport { ErrorDisplay } from '#ui/components/ErrorDisplay';\nimport { QuitConfirmCard } from '#ui/components/QuitConfirmCard';\nimport { RestartRequiredCard } from '#ui/components/RestartRequiredCard';\nimport { TunnelOpeningCard } from '#ui/components/TunnelOpeningCard';\n\nimport type { TunnelPhase, TunnelStatus } from '#commands/dev/tunnel/TunnelCoordinator';\nimport type { DevState } from '#ui/stores/DevStore';\nimport type { ReactElement } from 'react';\n\ntype NoticeKey = 'quit' | 'commands' | 'error' | 'restart' | 'tunnel';\n\nexport interface Notice {\n readonly key: NoticeKey;\n /** Description shown on the status line's left side. */\n readonly summary: string;\n /** What to press. */\n readonly action: string;\n readonly card: ReactElement;\n}\n\nconst RESTART = 'press r to restart';\n\nfunction openingPhase(status: TunnelStatus | null): TunnelPhase | null {\n return status === null || status === 'live' || status === 'lost' ? null : status;\n}\n\n/** Every pending notice, ranked with the one that blocks a decision first. */\nexport function noticesOf(state: DevState): readonly Notice[] {\n const notices: Notice[] = [];\n\n if (state.quitArmed) {\n notices.push({ key: 'quit', summary: 'Quit?', action: 'press Ctrl-C again', card: <QuitConfirmCard /> });\n }\n\n if (state.commandUpdatePrompt) {\n const count = state.commandUpdatePrompt.length;\n notices.push({\n key: 'commands',\n summary: `${count} command${count === 1 ? '' : 's'} updated`,\n action: 'refresh? y/n',\n card: <CommandRefreshPrompt files={[...state.commandUpdatePrompt]} />\n });\n }\n\n if (state.error) {\n notices.push({\n key: 'error',\n summary: state.error.message, // status line only has room for one line\n action: RESTART,\n card: <ErrorDisplay error={state.error} />\n });\n }\n\n if (state.restartRequired) {\n notices.push({ key: 'restart', summary: '', action: RESTART, card: <RestartRequiredCard /> });\n }\n\n const phase = openingPhase(state.tunnel);\n if (phase) {\n notices.push({\n key: 'tunnel',\n summary: 'Setting up your interactions endpoint',\n action: 'hold on',\n card: <TunnelOpeningCard phase={phase} />\n });\n }\n\n return notices;\n}\n","import { cpus, totalmem } from 'node:os';\nimport process from 'node:process';\n\nimport { Envapter } from 'envapt';\n\nconst enabled = Envapter.getBoolean('SEEDCORD_DEV_PROFILE', false);\n\nconst MEDIAN = 0.5;\nconst NEAR_WORST = 0.99;\nconst BYTES_PER_MB = 1024 * 1024;\nconst PERCENT = 100;\nconst MS_PER_SECOND = 1000;\n\n// each one is the elapsed time when that startup step finished\nconst PHASES = ['config', 'vite', 'entry', 'ready'] as const;\ntype Phase = (typeof PHASES)[number];\n\nconst marks = new Map<Phase, number>();\nconst renderTimes: number[] = [];\nlet wrapCalls = 0;\nlet wrapTotal = 0;\nlet writes = 0;\nlet written = 0;\nlet writeTotal = 0;\nlet framesAtReady = 0;\n\nexport function profileMark(phase: Phase): void {\n if (!enabled) return;\n\n // performance.now() counts from process start\n marks.set(phase, performance.now());\n\n // everything after the bot is up is the idle cost\n if (phase === 'ready') framesAtReady = renderTimes.length;\n}\n\nexport function profileFrame(renderTime: number): void {\n if (enabled) renderTimes.push(renderTime);\n}\n\n// ink's renderTime brackets its own layout only\nexport function profileWrap<Rows>(build: () => Rows): Rows {\n if (!enabled) return build();\n\n const started = performance.now();\n const rows = build();\n wrapTotal += performance.now() - started;\n wrapCalls++;\n\n return rows;\n}\n\n// conhost is far slower at bulk writes than a mac terminal\nexport function profileStdout(): void {\n if (!enabled) return;\n\n const original = process.stdout.write.bind(process.stdout);\n\n process.stdout.write = (chunk: string | Uint8Array, ...rest: never[]) => {\n writes++;\n written += typeof chunk === 'string' ? Buffer.byteLength(chunk) : chunk.byteLength;\n\n const started = performance.now();\n const flushed = original(chunk, ...rest);\n writeTotal += performance.now() - started;\n\n return flushed;\n };\n}\n\nfunction at(sorted: readonly number[], fraction: number): number {\n return sorted[Math.min(sorted.length - 1, Math.floor(sorted.length * fraction))] ?? 0;\n}\n\nfunction ms(value: number): string {\n return `${value.toFixed(1)} ms`;\n}\n\nfunction machine(): string[] {\n const cores = cpus();\n const gb = (totalmem() / BYTES_PER_MB / 1024).toFixed(1);\n const terminal = process.env.WT_SESSION ? 'windows terminal' : (process.env.TERM_PROGRAM ?? 'unknown');\n\n return [\n ` node ${process.version} on ${process.platform} ${process.arch}`,\n ` cpu ${cores[0]?.model ?? 'unknown'} x${String(cores.length)}, ${gb} GB`,\n ` terminal ${terminal}, TERM=${process.env.TERM ?? 'unset'}, ${String(process.stdout.columns)}x${String(process.stdout.rows)}`\n ];\n}\n\nfunction startup(): string[] {\n const ready = marks.get('ready');\n if (ready === undefined) return [' startup never reached ready'];\n\n const lines = [` startup ${ms(ready)}`];\n let previous = 0;\n\n for (const phase of PHASES) {\n const at = marks.get(phase);\n if (at === undefined) continue;\n\n lines.push(` ${phase.padEnd(10)} ${ms(at - previous)}`);\n previous = at;\n }\n\n return lines;\n}\n\nexport function profileReport(): string | null {\n if (!enabled) return null;\n\n const session = performance.now();\n const sorted = [...renderTimes].sort((a, b) => a - b);\n const layoutTotal = renderTimes.reduce((sum, time) => sum + time, 0);\n const mb = (written / BYTES_PER_MB).toFixed(2);\n const share = (part: number): string => `${((part / session) * PERCENT).toFixed(1)}% of session`;\n\n const ready = marks.get('ready') ?? session;\n const idleFrames = renderTimes.length - framesAtReady;\n const idleSeconds = (session - ready) / MS_PER_SECOND;\n const idleRate = idleSeconds > 0 ? (idleFrames / idleSeconds).toFixed(1) : '0.0';\n\n return [\n 'seedcord dev profile',\n ...machine(),\n ` session ${ms(session)}`,\n ...startup(),\n ` frames ${String(renderTimes.length)}`,\n ` idle ${String(idleFrames)} frames over ${idleSeconds.toFixed(1)}s = ${idleRate} fps`,\n ` layout p50 ${ms(at(sorted, MEDIAN))}, p99 ${ms(at(sorted, NEAR_WORST))}, total ${ms(layoutTotal)}, ${share(layoutTotal)}`,\n ` stdout ${mb} MB over ${String(writes)} writes, ${ms(writeTotal)}, ${share(writeTotal)}`,\n ` log wrap ${ms(wrapTotal)} over ${String(wrapCalls)} builds, ${share(wrapTotal)}`\n ].join('\\n');\n}\n","/** How much of the dev UI the terminal has room for. */\nexport type Tier = 'full' | 'compact' | 'logs';\n\n// measured against the real rail with every framework channel plus headroom. Sidebar.test re-measures, so a\n// new rail section fails there before it clips at runtime.\nexport const FULL_ROWS = 30;\nexport const COMPACT_ROWS = 21;\n\n// the rail at its widest, plus the columns a log line uses for its prefix and a readable message\nexport const RAIL_COLUMNS = 80;\n\nexport function tierFor(rows: number, columns: number): Tier {\n if (columns < RAIL_COLUMNS) return 'logs';\n if (rows >= FULL_ROWS) return 'full';\n if (rows >= COMPACT_ROWS) return 'compact';\n return 'logs';\n}\n","import { Box, useInput, useWindowSize } from 'ink';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { Rule } from '#ui/components/primitives/Rule';\nimport { INITIAL_CURSOR } from '#ui/filterCursor';\nimport { useDevState } from '#ui/hooks/useDevState';\nimport { useLogs } from '#ui/hooks/useLogs';\nimport { useMeasuredBox } from '#ui/hooks/useMeasuredBox';\nimport { useRailWidth } from '#ui/hooks/useRailWidth';\nimport { useScroll } from '#ui/hooks/useScroll';\nimport { useUptime } from '#ui/hooks/useUptime';\nimport { dispatchHotkey } from '#ui/hotkeys';\nimport { DevLayout } from '#ui/layout/DevLayout';\nimport { expandRows, rowKey, wrapRows } from '#ui/logRows';\nimport { noticesOf } from '#ui/notices';\nimport { profileWrap } from '#ui/profile';\nimport { LogStore } from '#ui/stores/LogStore';\nimport { tierFor } from '#ui/tier';\n\nimport type { DevStore } from '#ui/stores/DevStore';\nimport type { LogLevel } from '@seedcord/types';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement } from 'react';\n\ninterface DevAppProps {\n readonly store: DevStore;\n readonly onReady: () => void;\n readonly onQuit?: () => Promise<void> | void;\n readonly onDisconnect?: () => Promise<void> | void;\n readonly onRestart?: () => Promise<void> | void;\n readonly onRefreshCommands?: (shouldRefresh: boolean) => Promise<void> | void;\n}\n\nexport function DevApp(props: DevAppProps): ReactElement {\n const { store, onReady } = props;\n const state = useDevState(store);\n const { rows, columns } = useWindowSize();\n\n const [enabled, setEnabled] = useState<ReadonlySet<string>>(() => new Set());\n const [enabledLevels, setEnabledLevels] = useState<ReadonlySet<LogLevel>>(() => new Set());\n const [cursor, setCursor] = useState(INITIAL_CURSOR);\n\n const logBoxRef = useRef<DOMElement | null>(null);\n const logBox = useMeasuredBox(logBoxRef);\n\n const railRef = useRef<DOMElement | null>(null);\n const railWidth = useRailWidth(railRef, state.phase, rows, columns);\n\n const tier = tierFor(rows, columns);\n const notices = noticesOf(state);\n\n const logs = useLogs(enabled, enabledLevels);\n // the label width only grows with a new entry, so the logs dep already covers it\n const logRows = useMemo(\n () =>\n profileWrap(() => wrapRows(expandRows(logs), logBox.width, Math.max(1, LogStore.instance.getLabelWidth()))),\n [logs, logBox.width]\n );\n const viewportHeight = Math.max(1, logBox.height);\n const scroll = useScroll(logRows, viewportHeight, rowKey);\n const uptimeMs = useUptime(state, tier !== 'logs');\n\n const interactive = !state.isBusy || state.restartRequired;\n\n useInput((input, key) => {\n dispatchHotkey({\n input,\n key,\n state,\n interactive,\n scroll,\n store,\n enabled,\n setEnabled,\n enabledLevels,\n setEnabledLevels,\n cursor,\n setCursor,\n filtersOpen: tier === 'full',\n onQuit: props.onQuit,\n onDisconnect: props.onDisconnect,\n onRestart: props.onRestart,\n onRefreshCommands: props.onRefreshCommands\n });\n });\n\n const isInitializedRef = useRef(false);\n useEffect(() => {\n if (isInitializedRef.current) return;\n isInitializedRef.current = true;\n\n LogStore.instance.clear();\n LogStore.instance.mount();\n onReady();\n\n return () => {\n LogStore.instance.unmount();\n };\n }, [onReady]);\n\n return (\n <Box flexDirection=\"column\" width={columns} height={rows} overflow=\"hidden\">\n {/* need the rule for some padding at the top */}\n <Rule />\n <DevLayout\n state={state}\n tier={tier}\n notices={notices}\n railRef={railRef}\n railWidth={railWidth}\n logBoxRef={logBoxRef}\n scroll={scroll}\n viewportHeight={viewportHeight}\n measured={logBox.height > 0}\n columns={columns}\n enabled={enabled}\n enabledLevels={enabledLevels}\n cursor={cursor}\n interactive={interactive}\n uptimeMs={uptimeMs}\n />\n </Box>\n );\n}\n","import { TypedEventEmitter } from '@seedcord/event-emitter';\nimport { assertNever } from '@seedcord/utils';\n\nimport type { DevEvent } from '#commands/dev/runtime/events';\nimport type { TunnelStatus } from '#commands/dev/tunnel/TunnelCoordinator';\nimport type { DevPhase } from './devPhase';\n\nexport interface DevTransport {\n // the transport package, '@seedcord/gateway' or '@seedcord/http'\n readonly name: string;\n readonly version: string;\n}\n\nexport interface DevState {\n readonly phase: DevPhase;\n readonly status: string;\n readonly error: Error | null;\n readonly isBusy: boolean;\n readonly transport: DevTransport | null;\n readonly restartRequired: boolean;\n readonly commandUpdatePrompt: string[] | null;\n readonly port: number | null;\n readonly tunnel: TunnelStatus | null;\n readonly quitArmed: boolean;\n readonly idleAnimation: boolean;\n}\n\nconst INITIAL: DevState = {\n phase: 'starting',\n status: 'Initializing…',\n error: null,\n isBusy: true,\n transport: null,\n restartRequired: false,\n commandUpdatePrompt: null,\n port: null,\n tunnel: null,\n quitArmed: false,\n idleAnimation: true\n};\n\nexport class DevStore extends TypedEventEmitter<{ change: [] }> {\n private state: DevState = INITIAL;\n\n // a stable reference between mutations, which useSyncExternalStore needs to avoid render loops\n public getState(): DevState {\n return this.state;\n }\n\n public setStatus(status: string): void {\n this.patch({ status });\n }\n\n public setBusy(isBusy: boolean): void {\n this.patch({ isBusy });\n }\n\n public setPhase(phase: DevPhase): void {\n this.patch({ phase });\n }\n\n public setError(error: Error | null): void {\n this.patch({ error });\n }\n\n public setTransport(transport: DevTransport | null): void {\n this.patch({ transport });\n }\n\n public setTunnel(tunnel: TunnelStatus | null): void {\n this.patch({ tunnel });\n }\n\n public setQuitArmed(quitArmed: boolean): void {\n this.patch({ quitArmed });\n }\n\n public setIdleAnimation(idleAnimation: boolean): void {\n this.patch({ idleAnimation });\n }\n\n public clearPrompt(): void {\n this.patch({ commandUpdatePrompt: null });\n }\n\n // keeps the r/d press to a single render before the runner swaps sessions\n public beginRestart(): void {\n this.patch({\n phase: 'starting',\n isBusy: true,\n restartRequired: false,\n error: null,\n status: 'Restarting…',\n port: null\n });\n }\n\n public beginDisconnect(): void {\n this.patch({\n phase: 'disconnected',\n isBusy: true,\n restartRequired: false,\n error: null,\n status: 'Disconnecting…',\n port: null\n });\n }\n\n public beginQuit(): void {\n this.patch({ phase: 'quitting', isBusy: true, status: 'Shutting down…' });\n }\n\n public apply(event: DevEvent): void {\n switch (event.type) {\n case 'restart-required': {\n this.patch({\n phase: 'restart-required',\n status: 'Restart required. Press r to restart.',\n restartRequired: true\n });\n break;\n }\n case 'command-update-prompt': {\n this.patch({ commandUpdatePrompt: event.files });\n break;\n }\n case 'server-listening': {\n this.patch({ port: event.port });\n break;\n }\n case 'module-loading':\n case 'module-loaded':\n case 'module-error':\n case 'file-change':\n case 'ready': {\n break;\n }\n default: {\n assertNever(event);\n }\n }\n }\n\n private patch(next: Partial<DevState>): void {\n this.state = { ...this.state, ...next };\n this.emit('change');\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\n\nimport { Logger } from '@seedcord/logger';\n\nconst TSC_GRACEFUL_EXIT_MS = 2000;\n\nexport class TscRunner {\n private process: ChildProcess | null = null;\n private readonly logger: Logger;\n\n constructor(\n private readonly tsconfigPath?: string,\n private readonly cwd?: string\n ) {\n this.logger = new Logger('Typecheck', { channel: 'tsc' });\n }\n\n public start(): void {\n if (this.process) return;\n\n const tscPath = this.resolveProjectTsc();\n if (!tscPath) {\n this.logger.error('Unable to resolve \"typescript\". Install it in the project to enable tsc --watch.');\n return;\n }\n\n const args = [tscPath, '--noEmit', '--watch', '--preserveWatchOutput', '--pretty'];\n if (this.tsconfigPath) {\n args.push('--project', this.tsconfigPath);\n }\n\n this.logger.debug('Starting tsc --watch...');\n\n this.process = spawn(process.execPath, args, {\n cwd: this.cwd ?? process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe']\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n const lines = data.toString().split('\\n');\n for (const line of lines) {\n if (line.trim()) {\n this.logger.debug(line.trimEnd());\n }\n }\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n const lines = data.toString().split('\\n');\n for (const line of lines) {\n if (line.trim()) {\n this.logger.error(line.trimEnd());\n }\n }\n });\n\n this.process.on('error', (err) => {\n this.logger.error(`Failed to start tsc: ${err.message}`);\n });\n\n this.process.on('exit', (code) => {\n if (code !== 0 && code !== null) {\n this.logger.error(`tsc exited with code ${code}`);\n } else {\n this.logger.debug('tsc exited.');\n }\n this.process = null;\n });\n }\n\n public stop(): void {\n const child = this.process;\n if (!child) return;\n\n this.logger.debug('Stopping tsc...');\n child.kill('SIGTERM');\n\n // justified: tsc --watch can ignore SIGTERM when stdin is detached (Windows/some Node builds), so escalate to SIGKILL after a grace window. unref so the timer never holds the event loop open.\n const killTimer = setTimeout(() => child.kill('SIGKILL'), TSC_GRACEFUL_EXIT_MS);\n killTimer.unref();\n child.once('exit', () => {\n clearTimeout(killTimer);\n });\n // start()'s 'exit' listener is what nulls the handle, so it stays set until then and blocks a second tsc spawning over the dying one\n }\n\n private resolveProjectTsc(): string | null {\n const projectDir = this.cwd ?? process.cwd();\n const manifest = resolve(projectDir, 'package.json');\n const projectRequire = existsSync(manifest) ? createRequire(manifest) : createRequire(import.meta.url);\n\n try {\n return projectRequire.resolve('typescript/bin/tsc');\n } catch {\n return null;\n }\n }\n}\n","import { existsSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { paint, SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { SeedcordBrand, type Brandable, type SeedcordInstance } from '@seedcord/types/internal';\n\nimport { profileMark } from '#ui/profile';\nimport { resolveDefaultExport } from '#utils/resolveDefaultExport';\n\nimport { TscRunner } from './TscRunner';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { DevStore } from '#ui/stores/DevStore';\nimport type { DevRuntime } from './runtime/DevRuntime';\nimport type { DevEventHandler } from './runtime/events';\n\nfunction isSeedcordInstance(candidate: unknown): candidate is SeedcordInstance {\n return typeof candidate === 'object' && candidate !== null && (candidate as Brandable)[SeedcordBrand] === true;\n}\n\nexport class DevSession {\n private stopResolve?: () => void;\n private instance?: SeedcordInstance;\n private isStopped = false;\n private startupPromise?: Promise<unknown>;\n private tscRunner?: TscRunner;\n private stopPromise?: Promise<void>;\n\n constructor(\n private readonly config: ResolvedSeedcordDevConfig,\n private readonly runtime: DevRuntime,\n private readonly store: DevStore,\n private readonly onEvent: DevEventHandler\n ) {}\n\n private async loadInstanceModule(): Promise<unknown> {\n await this.runtime.start({\n config: this.config,\n onEvent: (event) => {\n this.store.apply(event);\n this.onEvent(event);\n }\n });\n profileMark('vite');\n\n // vite's missing-entry message changed across a minor and broke detection\n if (!existsSync(this.config.instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [this.config.instance]);\n }\n\n try {\n const { module } = await this.runtime.loadEntry();\n profileMark('entry');\n return module;\n } catch (error: unknown) {\n const message = Error.isError(error) ? error.message : String(error);\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [this.config.instance, message]);\n }\n }\n\n private startTypecheck(): void {\n const { typecheck } = this.config;\n if (!typecheck.enabled) return;\n\n this.tscRunner = new TscRunner(typecheck.tsconfig, dirname(this.config.configFile));\n this.tscRunner.start();\n }\n\n public async start(onReady?: () => void): Promise<void> {\n const module = await this.loadInstanceModule();\n const exported = resolveDefaultExport(module);\n const instance = await Promise.resolve(exported);\n\n if (!isSeedcordInstance(instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliInstanceInvalid);\n }\n\n this.instance = instance;\n this.store.setTransport({ name: instance.augmentTarget, version: instance.version });\n\n try {\n this.store.setPhase('starting');\n this.store.setStatus('Starting Seedcord instance…');\n this.startupPromise = Promise.resolve(instance.start());\n await this.startupPromise;\n\n if (this.isStopped) {\n return;\n }\n\n this.store.setPhase('running');\n this.store.setStatus(`${paint.bold(instance.username ?? 'Bot')} is ready!`);\n profileMark('ready');\n onReady?.();\n // tsc competes with vite's cold transform when it starts any earlier\n this.startTypecheck();\n\n // resolved by stop(), and no signal handlers here so restarts never accumulate listeners\n await new Promise<void>((resolve) => {\n this.stopResolve = resolve;\n });\n } catch (error: unknown) {\n const reason = Error.isError(error) ? error.message : 'Unknown error';\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [this.config.instance, reason]);\n }\n }\n\n // quit, restart, disconnect, and dispose all call this\n public async stop(): Promise<void> {\n this.stopPromise ??= this.runStop();\n return this.stopPromise;\n }\n\n private async runStop(): Promise<void> {\n this.isStopped = true;\n this.tscRunner?.stop();\n this.instance?.startup.abort();\n\n if (this.startupPromise) {\n // so the shutdown below still runs\n try {\n await this.startupPromise;\n } catch {}\n }\n\n await this.instance?.shutdown.run(0, false);\n this.stopResolve?.();\n }\n\n public async dispose(): Promise<void> {\n await this.stop();\n await this.runtime.dispose();\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n this.runtime.refreshCommands?.(shouldRefresh);\n }\n}\n","import { relative, resolve } from 'node:path';\n\nimport { wrapHot } from '@seedcord/core/internal';\nimport { paint } from '@seedcord/errors';\nimport { TypedEventEmitter } from '@seedcord/event-emitter';\nimport { Logger } from '@seedcord/logger';\nimport { minimatch } from 'minimatch';\n\nimport type { ResolvedSeedcordDevConfig } from '#core/config/schema';\nimport type { DevEvent } from './events';\nimport type { HmrEventType, HmrUpdateEvent } from '@seedcord/types';\nimport type { DevChannel, SeedcordCliEvents, SeedcordFrameworkEvents } from '@seedcord/types/internal';\nimport type {\n EnvironmentModuleNode,\n HotUpdateOptions,\n ModuleNode,\n NormalizedHotChannel,\n Plugin,\n ViteDevServer\n} from 'vite';\n\nconst DEBOUNCE_MS = 250;\n\nexport class HmrPlugin extends TypedEventEmitter<{ event: [DevEvent] }> {\n private readonly logger: Logger;\n private readonly lastUpdate = new Map<string, number>();\n private readonly awaitingCreateEcho = new Set<string>();\n private server: ViteDevServer | null = null;\n private readonly dynamicRestartPatterns = new Set<string>();\n\n private get hot(): NormalizedHotChannel | undefined {\n return this.server?.environments.ssr.hot;\n }\n\n private get dev(): DevChannel<SeedcordCliEvents, SeedcordFrameworkEvents> | undefined {\n return this.hot ? wrapHot<SeedcordCliEvents, SeedcordFrameworkEvents>(this.hot) : undefined;\n }\n\n constructor(private readonly config: ResolvedSeedcordDevConfig) {\n super();\n this.logger = new Logger('HMR', { channel: 'hmr' });\n }\n\n public get plugin(): Plugin {\n return {\n name: 'seedcord:hmr',\n configureServer: this.configureServer.bind(this),\n hotUpdate: this.hotUpdate.bind(this)\n };\n }\n\n public sendRefreshCommands(shouldRefresh: boolean): void {\n this.dev?.send('seedcord:refresh-commands', { shouldRefresh });\n }\n\n private configureServer(server: ViteDevServer): void {\n this.server = server;\n server.watcher.on('add', (file) => this.handleFileEvent(file, 'create'));\n server.watcher.on('unlink', (file) => this.handleFileEvent(file, 'delete'));\n server.watcher.on('addDir', (file) => this.handleFileEvent(file, 'createDir'));\n server.watcher.on('unlinkDir', (file) => this.handleFileEvent(file, 'deleteDir'));\n\n // vite's watcher covers config.root only, which excludes the config file\n server.watcher.add(this.config.configFile);\n server.watcher.on('change', (file) => this.handleChange(file));\n\n this.dev?.on('seedcord:commands-update-prompt', (data) => {\n this.emit('event', { type: 'command-update-prompt', files: data.files });\n });\n\n this.dev?.on('seedcord:server-listening', (data) => {\n this.emit('event', { type: 'server-listening', port: data.port });\n });\n\n this.dev?.on('seedcord:register-critical-files', (data) => {\n for (const pattern of data.patterns) {\n this.dynamicRestartPatterns.add(pattern);\n }\n\n this.logger.debug(`Registered ${String(data.patterns.length)} critical file patterns`);\n });\n }\n\n // keyed per type, else an atomic-save rename (unlink then add) loses the add and the handler stays unloaded\n private isDebounced(file: string, type: HmrEventType): boolean {\n if (this.justSaw(file, type)) return true;\n this.lastUpdate.set(`${file}::${type}`, Date.now());\n return false;\n }\n\n private justSaw(file: string, type: HmrEventType): boolean {\n const last = this.lastUpdate.get(`${file}::${type}`);\n return last !== undefined && Date.now() - last < DEBOUNCE_MS;\n }\n\n // hotUpdate covers a critical file inside the root\n private handleChange(file: string): void {\n if (!this.isCriticalFile(file) || this.isDebounced(file, 'update')) return;\n this.reportRestartRequired(file);\n }\n\n private reportRestartRequired(file: string): void {\n const relPath = relative(process.cwd(), file);\n this.logger.warn(`${paint.coral('Critical file changed:')} ${paint.sky.bold(relPath)}. Restart required.`);\n this.emit('event', { type: 'restart-required' });\n }\n\n private handleFileEvent(file: string, type: HmrEventType): void {\n if (this.isDebounced(file, type)) return;\n if (type === 'create') this.awaitingCreateEcho.add(file);\n\n const relPath = relative(process.cwd(), file);\n const typeColor =\n type === 'create' || type === 'createDir'\n ? paint.mint\n : type === 'delete' || type === 'deleteDir'\n ? paint.coral\n : paint.sky;\n\n this.logger.trace(`${typeColor(type.toUpperCase())} ${paint.mute(relPath)}`);\n\n const payload: HmrUpdateEvent = { file, type, rollback: this.config.hmr?.rollback ?? true };\n\n this.dev?.send('seedcord:hmr', payload);\n }\n\n private hotUpdate(ctx: HotUpdateOptions): EnvironmentModuleNode[] {\n const { file, modules, server } = ctx;\n const type = 'update';\n\n // vite fires one update straight after the watcher's add, and the create already reloaded the file\n const isCreateEcho = this.awaitingCreateEcho.delete(file) && this.justSaw(file, 'create');\n if (isCreateEcho || this.isDebounced(file, type)) return [];\n\n const relPath = relative(process.cwd(), file);\n\n this.logger.trace(`${paint.sky(type.toUpperCase())} ${paint.mute(relPath)}`);\n\n if (this.isCriticalFile(file)) {\n this.reportRestartRequired(file);\n return [];\n }\n\n const moduleGraph = server.moduleGraph;\n const fileModules = moduleGraph.getModulesByFile(file);\n const allModules = fileModules ? [...fileModules] : [];\n\n const combinedModules = new Set([...modules, ...allModules]);\n const affectedModules = this.getAffectedModules([...combinedModules]);\n\n const filesToInvalidate = new Set([file, ...affectedModules]);\n\n for (const fileToInvalidate of filesToInvalidate) {\n const mods = moduleGraph.getModulesByFile(fileToInvalidate);\n if (mods) {\n for (const mod of mods) {\n moduleGraph.invalidateModule(mod);\n }\n }\n }\n\n // the runtime invalidates this module in its evaluated-modules graph on a file-change event.\n this.emit('event', { type: 'file-change', path: file });\n\n const payload: HmrUpdateEvent = { file, type, affectedModules, rollback: this.config.hmr?.rollback ?? true };\n\n this.dev?.send('seedcord:hmr', payload);\n\n // returning [] suppresses vite's default client HMR so invalidation runs through the runtime.\n return [];\n }\n\n private isCriticalFile(file: string): boolean {\n const root = this.config.root;\n const relPath = relative(root, file);\n\n if (this.config.hmr?.restart) {\n for (const pattern of this.config.hmr.restart) {\n if (minimatch(relPath, pattern)) {\n return true;\n }\n }\n }\n\n for (const pattern of this.dynamicRestartPatterns) {\n if (minimatch(relPath, pattern)) {\n return true;\n }\n }\n\n if (\n file === this.config.configFile ||\n file.endsWith('package.json') ||\n file.endsWith('tsconfig.json') ||\n file.endsWith('.env')\n ) {\n return true;\n }\n\n const entryPath = resolve(root, this.config.entry);\n const instancePath = resolve(root, this.config.instance);\n\n if (file === entryPath || file === instancePath) {\n return true;\n }\n\n return false;\n }\n\n private getAffectedModules(modules: (EnvironmentModuleNode | ModuleNode)[]): string[] {\n const affected = new Set<string>();\n const seen = new Set<string>();\n\n const traverse = (mod: EnvironmentModuleNode | ModuleNode): void => {\n if (!mod.file || seen.has(mod.file)) return;\n\n seen.add(mod.file);\n affected.add(mod.file);\n mod.importers.forEach(traverse);\n };\n\n modules.forEach(traverse);\n return [...affected];\n }\n}\n","import { realpathSync } from 'node:fs';\nimport { resolve, sep } from 'node:path';\n\nimport { defineConfig } from 'vite';\n\n// a **/logs/** glob would also swallow a source directory named logs\nexport function logsIgnore(root: string): (path: string) => boolean {\n // chokidar reports the resolved path, and a mac temp dir arrives through a symlink\n const logs = resolve(realpathSync(root), 'logs');\n\n return (path) => path === logs || path.startsWith(logs + sep);\n}\n\nexport default defineConfig({\n server: {\n middlewareMode: true,\n hmr: true,\n watch: {\n usePolling: false,\n ignored: ['**/node_modules/**', '**/dist/**', '**/.git/**']\n }\n },\n build: {\n ssr: true,\n outDir: 'dist',\n sourcemap: true,\n minify: false,\n rollupOptions: {\n output: {\n format: 'esm',\n preserveModules: true\n }\n }\n },\n ssr: {\n target: 'node',\n // logger stays external so the bot shares the CLI's LoggerChannelRegistry singleton the dev TUI reads through\n external: ['@seedcord/logger', '@seedcord/logger/node'],\n // an externalized package's import() of a project .ts file goes to node's loader, which cannot parse decorators\n // vite injects import.meta.hot only into modules it transforms, and HmrManager.init reads it\n noExternal: [/^@seedcord\\//],\n resolve: {\n conditions: ['node', 'import'],\n externalConditions: ['node']\n }\n },\n environments: {\n ssr: {\n resolve: {\n conditions: ['node', 'import'],\n externalConditions: ['node']\n }\n }\n },\n future: {\n removeSsrLoadModule: 'warn',\n removePluginHookHandleHotUpdate: 'warn',\n removePluginHookSsrArgument: 'warn',\n removeServerModuleGraph: 'warn',\n removeServerReloadModule: 'warn',\n removeServerPluginContainer: 'warn',\n removeServerHot: 'warn',\n removeServerTransformRequest: 'warn',\n removeServerWarmupRequest: 'warn'\n },\n clearScreen: false,\n logLevel: 'error',\n appType: 'custom'\n});\n","import { dirname, relative } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { createServer, createServerModuleRunner, mergeConfig } from 'vite';\nimport { EvaluatedModules } from 'vite/module-runner';\n// eslint-disable-next-line import-x/no-rename-default -- the package declares its default as `_default`\nimport tsconfigPaths from 'vite-tsconfig-paths';\n\nimport { HmrPlugin } from './HmrPlugin';\nimport viteConfig, { logsIgnore } from './vite.config';\n\nimport type { DevRuntime, DevRuntimeContext, DevRuntimeLoadResult } from './DevRuntime';\nimport type { DevEvent, DevEventHandler } from './events';\nimport type { ViteDevServer } from 'vite';\nimport type { ModuleRunner } from 'vite/module-runner';\n\nexport class ViteDevRuntime implements DevRuntime {\n private context: DevRuntimeContext | null = null;\n private viteServer: ViteDevServer | null = null;\n private moduleRunner: ModuleRunner | null = null;\n private eventHandler: DevEventHandler | null = null;\n private evaluatedModules: EvaluatedModules | null = null;\n private hmrPlugin: HmrPlugin | null = null;\n\n public async start(context: DevRuntimeContext): Promise<void> {\n this.context = context;\n this.eventHandler = context.onEvent ?? null;\n\n const projectRoot = this.context.config.root;\n\n this.emit({ type: 'module-loading', path: projectRoot });\n\n const hmrPlugin = new HmrPlugin(this.context.config);\n this.hmrPlugin = hmrPlugin;\n\n // vite searches its own root for a config file\n const config = mergeConfig(viteConfig, {\n root: projectRoot,\n configFile: false,\n server: { watch: { ignored: [logsIgnore(projectRoot)] } },\n plugins: [tsconfigPaths({ root: dirname(this.context.config.configFile) }), hmrPlugin.plugin]\n });\n\n this.viteServer = await createServer(config);\n\n this.evaluatedModules = new EvaluatedModules();\n this.moduleRunner = createServerModuleRunner(this.viteServer.environments.ssr, {\n evaluatedModules: this.evaluatedModules\n });\n\n hmrPlugin.on('event', this.handleHmrEvent.bind(this));\n\n this.emit({ type: 'module-loaded', path: projectRoot });\n this.emit({ type: 'ready' });\n }\n\n private handleHmrEvent(event: DevEvent): void {\n if (event.type === 'file-change') {\n this.invalidateModule(event.path);\n }\n this.emit(event);\n }\n\n private invalidateModule(file: string): void {\n const projectRoot = this.context?.config.root;\n if (!projectRoot || !this.evaluatedModules) return;\n\n const moduleId = toModuleId(projectRoot, file);\n const moduleNode = this.evaluatedModules.getModuleById(moduleId);\n if (moduleNode) {\n this.evaluatedModules.invalidateModule(moduleNode);\n }\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n this.hmrPlugin?.sendRefreshCommands(shouldRefresh);\n }\n\n public async loadEntry(): Promise<DevRuntimeLoadResult> {\n if (!this.context || !this.viteServer || !this.moduleRunner) {\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [\n this.context?.config.instance ?? 'runtime',\n 'ViteDevRuntime.start() must complete before loadEntry()'\n ]);\n }\n\n const { instance: entryPath } = this.context.config;\n const projectRoot = this.context.config.root;\n\n this.emit({ type: 'module-loading', path: entryPath });\n\n try {\n const moduleId = toModuleId(projectRoot, entryPath);\n\n const module = await this.moduleRunner.import<unknown>(moduleId);\n\n this.emit({ type: 'module-loaded', path: entryPath });\n\n return { module };\n } catch (error: unknown) {\n this.emit({ type: 'module-error', path: entryPath, error });\n throw error;\n }\n }\n\n public async dispose(): Promise<void> {\n // restart and disconnect dispose the runtime without exiting the process, so drop the event\n // wiring here, else each new session leaks the last one's listeners\n this.hmrPlugin?.removeAllListeners('event');\n\n if (this.viteServer) {\n await this.viteServer.close();\n this.viteServer = null;\n }\n\n this.moduleRunner = null;\n this.evaluatedModules = null;\n this.hmrPlugin = null;\n this.context = null;\n this.eventHandler = null;\n }\n\n private emit(event: DevEvent): void {\n this.eventHandler?.(event);\n }\n}\n\n// vite normalizes module ids to forward slashes. relative() yields backslashes on windows\nfunction toModuleId(projectRoot: string, file: string): string {\n return `/${relative(projectRoot, file).replaceAll('\\\\', '/')}`;\n}\n","import { existsSync } from 'node:fs';\nimport { delimiter, join } from 'node:path';\n\nimport { Envapter } from 'envapt';\n\nconst BINARY = 'cloudflared';\nconst DOWNLOADS = 'https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/';\n\nexport interface PathLookup {\n readonly pathVar: string | undefined;\n readonly pathExt: string | undefined;\n readonly platform: NodeJS.Platform;\n readonly delimiter: string;\n readonly exists: (candidate: string) => boolean;\n}\n\nexport function systemLookup(): PathLookup {\n return {\n pathVar: Envapter.get('PATH'),\n pathExt: Envapter.get('PATHEXT'),\n platform: process.platform,\n delimiter,\n exists: existsSync\n };\n}\n\nexport function findCloudflared(lookup: PathLookup): string | undefined {\n const suffixes = lookup.platform === 'win32' ? (lookup.pathExt?.split(';') ?? ['.EXE']) : [''];\n\n for (const dir of lookup.pathVar?.split(lookup.delimiter) ?? []) {\n for (const suffix of suffixes) {\n const candidate = join(dir, `${BINARY}${suffix}`);\n if (lookup.exists(candidate)) return candidate;\n }\n }\n\n return undefined;\n}\n\nexport function installHint(platform: NodeJS.Platform): string {\n if (platform === 'darwin') return 'brew install cloudflared';\n if (platform === 'win32') return 'winget install -e --id Cloudflare.cloudflared';\n return DOWNLOADS;\n}\n","const UNAUTHORIZED = 401;\nconst POLL_INTERVAL_MS = 250;\nconst BUDGET_MS = 60_000;\n\nexport const PROBE_SECONDS = BUDGET_MS / 1000;\n\nexport interface ProbeDeps {\n fetch: (url: string, init?: RequestInit) => Promise<Response>;\n wait: (ms: number) => Promise<void>;\n}\n\n// an unsigned POST reaches the engine on any path, and only a seedcord bot answers it with a 401\nexport async function awaitReachable(url: string, deps: ProbeDeps, signal: AbortSignal): Promise<boolean> {\n // one budget shared by every request, so a slow answer still gets the time left in it\n const budget = AbortSignal.any([signal, AbortSignal.timeout(BUDGET_MS)]);\n\n for (let attempt = 0; attempt < BUDGET_MS / POLL_INTERVAL_MS; attempt++) {\n try {\n const response = await deps.fetch(url, { method: 'POST', signal: budget });\n if (response.status === UNAUTHORIZED) return true;\n } catch {\n signal.throwIfAborted();\n }\n await deps.wait(POLL_INTERVAL_MS);\n }\n\n return false;\n}\n","import { spawn } from 'node:child_process';\nimport { createServer } from 'node:net';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { awaitReachable } from './probe';\n\nimport type { ProbeDeps } from './probe';\nimport type { ChildProcess } from 'node:child_process';\n\nconst POLL_INTERVAL_MS = 250;\nconst HOSTNAME_ATTEMPTS = 240;\nconst SETTLE_MS = 4000;\nconst GRACEFUL_EXIT_MS = 2000;\n\nexport interface TunnelDeps extends ProbeDeps {\n spawn: (command: string, args: string[]) => ChildProcess;\n freePort: () => Promise<number>;\n}\n\nfunction freePort(): Promise<number> {\n return new Promise((resolve, reject) => {\n const probe = createServer();\n probe.once('error', reject);\n probe.listen(0, '127.0.0.1', () => {\n // justified: address() is AddressInfo once a TCP server is listening\n const { port } = probe.address() as { port: number };\n probe.close(() => resolve(port));\n });\n });\n}\n\nexport function systemTunnelDeps(): TunnelDeps {\n return {\n spawn: (command, args) => spawn(command, args, { stdio: 'ignore' }),\n fetch: (url, init) => fetch(url, init),\n freePort,\n wait: (ms) => new Promise((resolve) => setTimeout(resolve, ms))\n };\n}\n\nexport class CloudflaredTunnel {\n private child: ChildProcess | undefined;\n private failure: Error | undefined;\n\n constructor(\n private readonly deps: TunnelDeps,\n private readonly binary: string,\n private readonly onLost: () => void\n ) {}\n\n public async open(signal: AbortSignal, targetPort: number, onResolving?: () => void): Promise<string> {\n const metricsPort = await this.deps.freePort();\n\n const child = this.deps.spawn(this.binary, [\n 'tunnel',\n '--url',\n `http://localhost:${String(targetPort)}`,\n '--metrics',\n `127.0.0.1:${String(metricsPort)}`\n ]);\n // without a listener node throws a spawn failure process-wide\n child.on('error', (error) => {\n this.failure = error;\n });\n // stop() clears this.child first, so a deliberate kill skips this\n child.on('exit', (code) => {\n if (this.child !== child) return;\n this.failure = new Error(`cloudflared exited early with code ${String(code)}`);\n });\n this.child = child;\n\n const url = `https://${await this.readHostname(metricsPort, signal)}`;\n onResolving?.();\n // the record lands ~2.5s later and an early lookup caches NXDOMAIN for a 30 minute negative TTL\n await this.deps.wait(SETTLE_MS);\n // local dns resolving doesn't mean discord's resolver has too, so this only shortens the wait\n await awaitReachable(url, this.deps, signal);\n child.once('exit', () => {\n if (this.child === child) this.onLost();\n });\n return url;\n }\n\n public stop(): void {\n const child = this.child;\n if (!child) return;\n\n this.child = undefined;\n this.failure = undefined;\n child.kill('SIGTERM');\n\n const escalate = setTimeout(() => child.kill('SIGKILL'), GRACEFUL_EXIT_MS);\n escalate.unref();\n child.once('exit', () => {\n clearTimeout(escalate);\n });\n }\n\n private async readHostname(metricsPort: number, signal: AbortSignal): Promise<string> {\n const budget = AbortSignal.any([signal, AbortSignal.timeout(HOSTNAME_ATTEMPTS * POLL_INTERVAL_MS)]);\n\n for (let attempt = 0; attempt < HOSTNAME_ATTEMPTS && !this.failure; attempt++) {\n signal.throwIfAborted();\n if (budget.aborted) break;\n const hostname = await this.pollOnce(metricsPort, budget);\n if (hostname) return hostname;\n await this.deps.wait(POLL_INTERVAL_MS);\n }\n\n const cause = this.failure;\n this.stop();\n throw new SeedcordError(\n SeedcordErrorCode.CliTunnelUrlUnavailable,\n [(HOSTNAME_ATTEMPTS * POLL_INTERVAL_MS) / 1000],\n { cause }\n );\n }\n\n private async pollOnce(metricsPort: number, signal: AbortSignal): Promise<string | undefined> {\n try {\n const response = await this.deps.fetch(`http://127.0.0.1:${String(metricsPort)}/quicktunnel`, { signal });\n // justified: the cloudflared metrics route returns this shape\n const { hostname } = (await response.json()) as { hostname?: string };\n return hostname === '' ? undefined : hostname; // empty until the edge assigns one\n } catch {\n return undefined;\n }\n }\n}\n","import { DiscordAPIError, REST } from '@discordjs/rest';\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { RESTJSONErrorCodes, Routes } from 'discord-api-types/v10';\n\nimport type { RESTGetCurrentApplicationResult, RESTPatchCurrentApplicationJSONBody } from 'discord-api-types/v10';\n\nconst FIELD = 'interactions_endpoint_url';\n\nexport type EndpointRest = Pick<REST, 'get' | 'patch'>;\n\n// discord verifies by posting a signed ping to the url, which fails until the hostname resolves on its side\nfunction unverified(error: unknown): boolean {\n if (!(error instanceof DiscordAPIError) || error.code !== RESTJSONErrorCodes.InvalidFormBodyOrContentType) {\n return false;\n }\n\n const { rawError } = error;\n return 'errors' in rawError && containsField(rawError.errors);\n}\n\nfunction containsField(errors: unknown): boolean {\n return typeof errors === 'object' && errors !== null && FIELD in errors;\n}\n\nexport class InteractionsEndpoint {\n private client: EndpointRest | undefined;\n\n constructor(private readonly makeRest: () => EndpointRest) {}\n\n // the token is read on the first request, since the bot module can repoint envapt while it loads\n public static create(token: () => string): InteractionsEndpoint {\n // without this the client silently waits out an exhausted bucket and the cli looks frozen\n const rest = new REST({ version: '10', rejectOnRateLimit: ['/applications'] });\n return new InteractionsEndpoint(() => rest.setToken(token()));\n }\n\n public async set(url: string, signal: AbortSignal): Promise<void> {\n signal.throwIfAborted();\n // justified: the discord api contract for this route\n const application = (await this.rest().get(Routes.currentApplication())) as RESTGetCurrentApplicationResult;\n if (application.interactions_endpoint_url === url) return;\n\n signal.throwIfAborted();\n try {\n await this.write(url);\n } catch (error: unknown) {\n if (!unverified(error)) throw error;\n throw new SeedcordError(SeedcordErrorCode.CliTunnelNotVerified, [url]);\n }\n }\n\n private rest(): EndpointRest {\n this.client ??= this.makeRest();\n return this.client;\n }\n\n public async clear(): Promise<void> {\n await this.write(null);\n }\n\n private async write(endpoint: string | null): Promise<void> {\n await this.rest().patch(Routes.currentApplication(), {\n body: { interactions_endpoint_url: endpoint } satisfies RESTPatchCurrentApplicationJSONBody\n });\n }\n}\n","import { paint } from '@seedcord/errors';\n\nimport { formatUptime } from '#ui/format';\n\nimport type { CloudflaredTunnel } from './CloudflaredTunnel';\nimport type { InteractionsEndpoint } from './InteractionsEndpoint';\nimport type { ILogger } from '@seedcord/types';\n\nconst PASTE_HINT = 'The tunnel is still up, so try pasting that URL into the dashboard.';\nconst RESTART_HINT = 'Restart for a fresh hostname, or set `tunnel` to an https URL you already serve.';\n\nexport type CoordinatorTunnel = Pick<CloudflaredTunnel, 'open' | 'stop'>;\n\nexport type TunnelPhase = 'opening' | 'resolving' | 'registering';\nexport type TunnelStatus = TunnelPhase | 'live' | 'lost';\n\nexport interface CoordinatorDeps {\n readonly makeTunnel: (onLost: () => void) => CoordinatorTunnel;\n // a quick hostname lasts only as long as this process, so quit clears the endpoint\n readonly kind: 'quick' | 'configured';\n readonly endpoint: Pick<InteractionsEndpoint, 'set' | 'clear'>;\n readonly onStatus: (status: TunnelStatus | null) => void;\n readonly logger: ILogger;\n}\n\n// a call, because a direct read of signal.aborted narrows to false past the first check\nfunction superseded(attempt: AbortController): boolean {\n return attempt.signal.aborted;\n}\n\nfunction opening(kind: CoordinatorDeps['kind']): string {\n return kind === 'quick' ? 'Requesting a cloudflared tunnel to port' : 'Checking if your tunnel reaches port';\n}\n\nexport class TunnelCoordinator {\n private target: number | undefined;\n private current: AbortController | undefined;\n\n constructor(private readonly deps: CoordinatorDeps) {}\n\n public async onPort(port: number): Promise<void> {\n if (this.target === port) return;\n\n this.target = port;\n const attempt = this.begin();\n const startedAt = Date.now();\n const since = (): string => paint.mute(`+${formatUptime(Date.now() - startedAt)}`);\n const tunnel = this.deps.makeTunnel(() => this.reportLost(attempt));\n // a later onPort has no handle on this tunnel. the abort is the only way back to stop it.\n attempt.signal.addEventListener('abort', () => tunnel.stop(), { once: true });\n let patched = false;\n\n try {\n this.deps.onStatus('opening');\n this.deps.logger.info(`${opening(this.deps.kind)} ${paint.sky.bold(String(port))}`);\n const url = await tunnel.open(attempt.signal, port, () => this.deps.onStatus('resolving'));\n if (superseded(attempt)) return;\n this.deps.logger.info(`Reachable at ${paint.sky.bold(url)} ${since()}`);\n\n this.deps.onStatus('registering');\n patched = true;\n await this.deps.endpoint.set(url, attempt.signal);\n if (superseded(attempt)) return;\n\n this.deps.onStatus('live');\n this.deps.logger.info(`Interactions endpoint set on the dev dashboard ${since()}`);\n } catch (error: unknown) {\n if (superseded(attempt)) return;\n // discord will refuse the same hostname again\n if (patched) attempt.abort();\n this.reportFailure(error, patched);\n }\n }\n\n private reportLost(attempt: AbortController): void {\n if (superseded(attempt)) return;\n\n this.target = undefined;\n this.deps.onStatus('lost');\n this.deps.logger.error('cloudflared exited, so the bot has no public endpoint');\n }\n\n private reportFailure(error: unknown, patched: boolean): void {\n // so a retry on this port is not skipped\n this.target = undefined;\n this.deps.onStatus(null);\n this.deps.logger.error('Tunnel setup failed, the bot runs without a public endpoint', error);\n // patched means the abort above stopped the tunnel. the paste hint only holds while it is up.\n if (this.deps.kind === 'quick') this.deps.logger.info(patched ? RESTART_HINT : PASTE_HINT);\n }\n\n public async stop(): Promise<void> {\n if (!this.current) return;\n\n this.target = undefined;\n this.current.abort();\n this.current = undefined;\n this.deps.onStatus(null);\n if (this.deps.kind === 'configured') return;\n\n try {\n await this.deps.endpoint.clear();\n } catch (error: unknown) {\n // a failed clear must not reject the quit path\n this.deps.logger.warn('Could not clear the interactions endpoint', error);\n }\n }\n\n private begin(): AbortController {\n this.current?.abort();\n this.current = new AbortController();\n return this.current;\n }\n}\n","import { SeedcordErrorCode, paint } from '@seedcord/errors';\nimport { SeedcordError, validateDiscordToken } from '@seedcord/errors/internal';\nimport { Envapter } from 'envapt';\n\nimport { findCloudflared, installHint, systemLookup } from './cloudflared';\nimport { CloudflaredTunnel, systemTunnelDeps } from './CloudflaredTunnel';\nimport { InteractionsEndpoint } from './InteractionsEndpoint';\nimport { awaitReachable, PROBE_SECONDS } from './probe';\nimport { TunnelCoordinator } from './TunnelCoordinator';\n\nimport type { ResolvedTunnel } from '#core/config/schema';\nimport type { TunnelStatus } from './TunnelCoordinator';\nimport type { ILogger } from '@seedcord/types';\n\nexport function missingCloudflaredHint(platform: NodeJS.Platform): string {\n const arrow = paint.mute('→');\n return [\n `${paint.sky.bold('cloudflared')} is missing, so a tunnel can't be set up for you. Discord won't have any url to reach this bot`,\n `${arrow} install it with ${paint.mint.bold(installHint(platform))}`,\n `${arrow} or set ${paint.amber('tunnel')} to an https url you already serve, like ${paint.sky.italic('https://bot.example.com')}`\n ].join('\\n');\n}\n\nexport function createTunnelCoordinator(\n logger: ILogger,\n onStatus: (status: TunnelStatus | null) => void,\n tunnel: ResolvedTunnel,\n findBinary: () => string | undefined = () => findCloudflared(systemLookup())\n): TunnelCoordinator | undefined {\n if (tunnel.mode === 'off') return undefined;\n\n const deps = systemTunnelDeps();\n const endpoint = InteractionsEndpoint.create(() => validateDiscordToken(Envapter.get('DISCORD_BOT_TOKEN')));\n\n if (tunnel.mode === 'url') {\n return new TunnelCoordinator({\n makeTunnel: () => ({\n // no answer here means your server is down or the url is wrong\n open: async (signal, _port, onResolving) => {\n onResolving?.();\n if (await awaitReachable(tunnel.url, deps, signal)) return tunnel.url;\n throw new SeedcordError(SeedcordErrorCode.CliTunnelUnreachable, [tunnel.url, PROBE_SECONDS]);\n },\n // the forwarder is the user's process\n stop: () => undefined\n }),\n kind: 'configured',\n endpoint,\n onStatus,\n logger\n });\n }\n\n const binary = findBinary();\n if (!binary) return undefined;\n\n return new TunnelCoordinator({\n makeTunnel: (onLost) => new CloudflaredTunnel(deps, binary, onLost),\n kind: 'quick',\n endpoint,\n onStatus,\n logger\n });\n}\n","import { missingCloudflaredHint } from './createTunnelCoordinator';\n\nimport type { ResolvedTunnel } from '#core/config/schema';\nimport type { TunnelCoordinator } from './TunnelCoordinator';\nimport type { DevEvent } from '../runtime/events';\nimport type { ILogger } from '@seedcord/types';\n\nfunction same(a: ResolvedTunnel | undefined, b: ResolvedTunnel): boolean {\n if (a?.mode !== b.mode) return false;\n return a.mode === 'url' && b.mode === 'url' ? a.url === b.url : true;\n}\n\nexport class TunnelRouter {\n private coordinator: TunnelCoordinator | undefined;\n private built: ResolvedTunnel | undefined;\n\n constructor(\n private readonly make: (tunnel: ResolvedTunnel) => TunnelCoordinator | undefined,\n private readonly logger: ILogger\n ) {}\n\n // the dev session calls this from a sync callback where a rejection would end up unhandled\n public route(tunnel: ResolvedTunnel, event: DevEvent): Promise<void> {\n if (event.type !== 'server-listening') return Promise.resolve();\n return this.routeTo(tunnel, event.port).catch((error: unknown) => {\n this.logger.error('Tunnel setup failed, the bot runs without a public endpoint', error);\n });\n }\n\n private async routeTo(tunnel: ResolvedTunnel, port: number): Promise<void> {\n // each restart reloads the config\n if (!same(this.built, tunnel)) {\n // clearing the old endpoint must finish before the replacement sets its own\n await this.stop();\n this.built = tunnel;\n this.coordinator = tunnel.mode === 'off' ? undefined : this.make(tunnel);\n if (tunnel.mode !== 'off' && !this.coordinator) {\n this.logger.warn(missingCloudflaredHint(process.platform));\n }\n }\n\n await this.coordinator?.onPort(port);\n }\n\n public stop(): Promise<void> {\n const running = this.coordinator;\n this.coordinator = undefined;\n return running?.stop() ?? Promise.resolve();\n }\n}\n","import { settleWithin } from '@seedcord/core/node/internal';\nimport { Logger } from '@seedcord/logger';\n\nimport { CodegenRunner } from '#commands/codegen/CodegenRunner';\nimport { ConfigLoader } from '#core/config/ConfigLoader';\nimport { ConfigLocator } from '#core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '#core/modules/RuntimeModuleLoader';\nimport { resetChannelColors } from '#ui/channelColor';\nimport { profileMark } from '#ui/profile';\n\nimport { DevSession } from './DevSession';\nimport { ViteDevRuntime } from './runtime/ViteDevRuntime';\nimport { createTunnelCoordinator } from './tunnel/createTunnelCoordinator';\nimport { TunnelRouter } from './tunnel/TunnelRouter';\n\nimport type { ResolvedSeedcordDevConfig, ResolvedTunnel } from '#core/config/schema';\nimport type { DevStore } from '#ui/stores/DevStore';\nimport type { TunnelCoordinator } from './tunnel/TunnelCoordinator';\nimport type { ILogger } from '@seedcord/types';\n\nconst TUNNEL_TEARDOWN_MS = 3000;\n\nexport interface DevRunnerDeps {\n readonly locator: ConfigLocator;\n readonly configLoader: ConfigLoader;\n readonly store: DevStore;\n readonly codegen: CodegenRunner;\n readonly codegenLogger: ILogger;\n readonly tunnel: TunnelRouter;\n}\n\nexport class DevRunner {\n private currentSession: DevSession | null = null;\n private signalResolve?: () => void;\n private shouldQuit = false;\n private quitting?: Promise<void>;\n private isDisconnected = false;\n private isRunning = false;\n private isRegenerating = false;\n\n constructor(private readonly deps: DevRunnerDeps) {}\n\n public static create(logger: Logger, store: DevStore): DevRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const codegenLogger = new Logger('Codegen', { channel: 'cli' });\n const tunnelLogger = new Logger('Tunnel', { channel: 'cli' });\n const makeCoordinator = (tunnel: ResolvedTunnel): TunnelCoordinator | undefined =>\n createTunnelCoordinator(tunnelLogger, (status) => store.setTunnel(status), tunnel);\n\n return new DevRunner({\n locator: new ConfigLocator(logger),\n configLoader: new ConfigLoader(moduleLoader, logger),\n store,\n codegen: CodegenRunner.create(codegenLogger),\n codegenLogger,\n tunnel: new TunnelRouter(makeCoordinator, tunnelLogger)\n });\n }\n\n public async run(): Promise<void> {\n if (this.isRunning) return;\n this.isRunning = true;\n\n try {\n while (!this.shouldQuit) {\n try {\n if (this.isDisconnected) {\n await this.handleDisconnected();\n continue;\n }\n\n await this.runSession();\n } catch (error: unknown) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- quit() flips shouldQuit during the awaited session, which TS cannot see from the loop guard\n if (this.shouldQuit) break;\n await this.handleError(error);\n }\n }\n } finally {\n this.isRunning = false;\n await this.quitting; // process.exit follows run() resolving\n }\n }\n\n private async handleDisconnected(): Promise<void> {\n this.deps.store.setPhase('disconnected');\n this.deps.store.setStatus('Disconnected. Press r to restart.');\n this.deps.store.setBusy(false);\n await this.waitForSignal();\n this.deps.store.setBusy(true);\n if (!this.shouldQuit) {\n this.isDisconnected = false;\n }\n }\n\n private async runSession(): Promise<void> {\n resetChannelColors();\n this.deps.store.setPhase('starting');\n this.deps.store.setBusy(true);\n const config = await this.loadConfig();\n profileMark('config');\n this.deps.store.setIdleAnimation(config.idleAnimation);\n const runtime = new ViteDevRuntime();\n this.currentSession = new DevSession(config, runtime, this.deps.store, (event) => {\n void this.deps.tunnel.route(config.tunnel, event);\n });\n\n try {\n await this.currentSession.start(() => {\n this.deps.store.setBusy(false);\n });\n } finally {\n this.deps.store.setBusy(true);\n await this.currentSession.dispose();\n this.currentSession = null;\n }\n }\n\n private async handleError(error: unknown): Promise<void> {\n this.deps.store.setPhase('error');\n this.deps.store.setError(Error.isError(error) ? error : new Error(String(error)));\n this.deps.store.setStatus('Press r to restart.');\n this.deps.store.setBusy(false);\n await this.waitForSignal();\n this.deps.store.setBusy(true);\n }\n\n // every caller drops this promise, so run() awaits it\n public async quit(): Promise<void> {\n this.quitting ??= this.runQuit();\n return this.quitting;\n }\n\n private async runQuit(): Promise<void> {\n this.shouldQuit = true;\n this.deps.store.setPhase('quitting');\n await this.currentSession?.stop();\n // the endpoint clear is a discord round trip\n await settleWithin(this.deps.tunnel.stop(), TUNNEL_TEARDOWN_MS);\n this.signalResolve?.();\n }\n\n public async restart(): Promise<void> {\n this.isDisconnected = false;\n await this.currentSession?.stop();\n this.signalResolve?.();\n }\n\n // the tunnel stays up because a disconnect is a short parked state the user leaves by pressing r\n public async disconnect(): Promise<void> {\n // waking the signal while already parked would fall through and start a fresh session\n if (this.isDisconnected) return;\n this.isDisconnected = true;\n await this.currentSession?.stop();\n this.signalResolve?.();\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n if (shouldRefresh) void this.regenerateRegistry();\n this.currentSession?.refreshCommands(shouldRefresh);\n }\n\n // regenerates so tsc picks up the new command option types\n private async regenerateRegistry(): Promise<void> {\n if (this.isRegenerating) return;\n this.isRegenerating = true;\n try {\n await this.deps.codegen.run(false);\n } catch (error: unknown) {\n // a codegen throw must not take the dev session down\n this.deps.codegenLogger.error('Command registry regeneration failed', error);\n } finally {\n this.isRegenerating = false;\n }\n }\n\n private async waitForSignal(): Promise<void> {\n return new Promise<void>((resolve) => {\n this.signalResolve = resolve;\n });\n }\n\n private async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n const configPath = this.deps.locator.locate();\n return this.deps.configLoader.load(configPath);\n }\n}\n","import { render } from 'ink';\nimport React from 'react';\n\nimport { BaseCommand } from '#core/BaseCommand';\nimport { DevApp } from '#ui/DevApp';\nimport { profileFrame, profileReport, profileStdout } from '#ui/profile';\nimport { DevStore } from '#ui/stores/DevStore';\nimport { LogStore } from '#ui/stores/LogStore';\n\nimport { DevRunner } from './DevRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class DevCommand extends BaseCommand {\n constructor() {\n super('dev', 'Run a Seedcord instance from the config file', 'Dev');\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .action(async () => {\n profileStdout();\n const store = new DevStore();\n const runner = DevRunner.create(this.logger, store);\n\n // ink intercepts Ctrl-C under raw mode. this fires only when stdin is not raw.\n const onSignal = (): void => {\n void runner.quit();\n };\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n\n try {\n await this.runDevApp(store, runner);\n } catch (error: unknown) {\n this.logger.error('Seedcord dev failed', error);\n process.exitCode = 1;\n } finally {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n }\n\n // the in-ui logs went with the unmount\n await this.printLogLocation();\n\n // ink's raw stdin and vite's dev server keep the event loop alive after teardown\n process.exit();\n });\n }\n\n // process.exit() drops whatever a piped stdout has not flushed\n private async write(text: string): Promise<void> {\n return new Promise((resolve) => {\n process.stdout.write(text, () => {\n resolve();\n });\n });\n }\n\n private async printLogLocation(): Promise<void> {\n await this.write('seedcord dev stopped. logs: logs/\\n');\n\n const report = profileReport();\n if (report !== null) await this.write(`${report}\\n`);\n }\n\n private async runDevApp(store: DevStore, runner: DevRunner): Promise<void> {\n let failure: { error: unknown } | undefined;\n let runResult: Promise<void> = Promise.resolve();\n\n const { unmount, waitUntilExit } = render(\n React.createElement(DevApp, {\n store,\n onQuit: () => runner.quit(),\n onDisconnect: () => runner.disconnect(),\n onRestart: () => runner.restart(),\n onRefreshCommands: (shouldRefresh: boolean) => runner.refreshCommands(shouldRefresh),\n onReady: () => {\n runResult = runner\n .run()\n .finally(async () => {\n // unmounting first drops the buffered lines\n await LogStore.instance.flush();\n unmount();\n })\n // node kills the process over an unwatched rejection\n .catch((error: unknown) => {\n failure = { error };\n });\n }\n }),\n // the alternate screen restores the terminal and scrollback on quit, and ink's ESC[3J purge never fires\n {\n exitOnCtrlC: false,\n alternateScreen: true,\n onRender: ({ renderTime }) => {\n profileFrame(renderTime);\n }\n }\n );\n\n await waitUntilExit();\n // a run-loop failure has to reach the action's catch before process.exit()\n await runResult;\n if (failure) throw failure.error;\n }\n}\n","import { Command } from '@commander-js/extra-typings';\nimport { Logger } from '@seedcord/logger';\nimport { installNodeDefaults } from '@seedcord/logger/node';\nimport { Envapter, Environment } from 'envapt';\n\nimport { BuildCommand } from '#commands/build/BuildCommand';\nimport { CodegenCommand } from '#commands/codegen/CodegenCommand';\nimport { CommandsCommand } from '#commands/commands/CommandsCommand';\nimport { DevCommand } from '#commands/dev/DevCommand';\n\nimport { version } from '.';\n\nasync function main(): Promise<void> {\n if (!process.env.ENV && !process.env.ENVIRONMENT && !process.env.NODE_ENV) {\n Envapter.environment = Environment.Development;\n }\n\n installNodeDefaults();\n\n const program = new Command().name('seedcord').description('seedcord CLI').version(version);\n\n new DevCommand().register(program);\n new BuildCommand().register(program);\n new CodegenCommand().register(program);\n new CommandsCommand().register(program);\n\n await program.parseAsync(process.argv);\n}\n\nvoid main().catch((error) => {\n const logger = new Logger('CLI', { channel: 'cli' });\n logger.error('Unexpected CLI error', error);\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,IAAsB,cAAtB,MAAkC;CAIV;CACA;CAJpB,AAAmB;CAEnB,YACI,AAAgB,MAChB,AAAgB,aAChB,OACF;EAHkB;EACA;EAGhB,KAAK,SAAS,IAAI,OAAO,OAAO,EAAE,SAAS,MAAM,CAAC;CACtD;AAGJ;;;;AChBA,SAAgB,qBAA6B,cAA+B;CACxE,IAAI,UAAmB;CACvB,MAAM,0BAAU,IAAI,IAAa;CAEjC,OAAO,oBAAoB,OAAO,KAAK,CAAC,QAAQ,IAAI,OAAO,GAAG;EAC1D,QAAQ,IAAI,OAAO;EACnB,UAAU,QAAQ;CACtB;CAEA,OAAO;AACX;AAEA,SAAS,oBAAoB,OAA+C;CACxE,OAAO,QAAQ,SAAS,OAAO,UAAU,YAAY,aAAa,KAAK;AAC3E;;;;ACKA,SAAS,cAAc,OAAkD;CACrE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC9E;AAEA,SAAS,iBAAiB,OAAyB;CAC/C,OAAO,UAAU,UAAa,OAAO,UAAU;AACnD;AAEA,SAAS,cAAc,OAAmC;CACtD,OAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,OAAO,SAAS,OAAO,SAAS,QAAQ;AACjF;AAEA,SAAS,aAAa,OAAe,UAAiC;CAClE,OAAO,IAAI,cAAc,kBAAkB,uBAAuB,CAAC,OAAO,QAAQ,CAAC;AACvF;AAEA,SAAS,cAAc,OAAsB;CACzC,IAAI,UAAU,QAAW;CACzB,IAAI,CAAC,cAAc,KAAK,GAAG,MAAM,aAAa,SAAS,WAAW;CAClE,IAAI,CAAC,iBAAiB,MAAM,MAAM,GAAG,MAAM,aAAa,gBAAgB,UAAU;CAClF,IAAI,CAAC,iBAAiB,MAAM,QAAQ,GAAG,MAAM,aAAa,kBAAkB,UAAU;CACtF,IAAI,CAAC,iBAAiB,MAAM,SAAS,GAAG,MAAM,aAAa,mBAAmB,UAAU;AAC5F;AAEA,SAAS,kBAAkB,OAAsB;CAC7C,IAAI,UAAU,UAAa,OAAO,UAAU,WAAW;CACvD,IAAI,CAAC,cAAc,KAAK,GAAG,MAAM,aAAa,iBAAiB,wBAAwB;CACvF,IAAI,CAAC,iBAAiB,MAAM,QAAQ,GAAG,MAAM,aAAa,0BAA0B,UAAU;AAClG;AAEA,SAAS,YAAY,OAAsB;CACvC,IAAI,UAAU,QAAW;CACzB,IAAI,CAAC,cAAc,KAAK,GAAG,MAAM,aAAa,OAAO,WAAW;CAChE,IAAI,MAAM,YAAY,UAAa,CAAC,cAAc,MAAM,OAAO,GAC3D,MAAM,aAAa,eAAe,qBAAqB;CAE3D,IAAI,MAAM,aAAa,UAAa,OAAO,MAAM,aAAa,WAC1D,MAAM,aAAa,gBAAgB,WAAW;CAElD,kBAAkB,MAAM,SAAS;AACrC;AAEA,SAAS,eAAe,OAAsB;CAC1C,IAAI,UAAU,UAAa,OAAO,UAAU,WAAW;CAEvD,IAAI,OAAO,UAAU,YAAY,IAAI,MAAM,KAAK,CAAC,EAAE,aAAa,UAC5D,MAAM,aAAa,UAAU,2BAA2B;AAEhE;AAEA,SAAS,cAAc,OAAqD;CACxE,IAAI,UAAU,OAAO,OAAO,EAAE,MAAM,MAAM;CAC1C,IAAI,OAAO,UAAU,UAAU,OAAO;EAAE,MAAM;EAAO,KAAK;CAAM;CAChE,OAAO,EAAE,MAAM,QAAQ;AAC3B;AAEA,SAAS,iBAAiB,OAAuC,MAAiC;CAC9F,IAAI,UAAU,UAAa,UAAU,OAAO,OAAO,EAAE,SAAS,MAAM;CACpE,IAAI,UAAU,QAAQ,MAAM,aAAa,QAAW,OAAO,EAAE,SAAS,KAAK;CAE3E,OAAO;EAAE,SAAS;EAAM,UAAU,QAAQ,MAAM,MAAM,QAAQ;CAAE;AACpE;AAEA,SAAS,eAAe,KAAgD;CACpE,IAAI,CAAC,cAAc,GAAG,GAAG,MAAM,IAAI,cAAc,kBAAkB,sBAAsB;CACzF,IAAI,OAAO,IAAI,aAAa,YAAY,IAAI,SAAS,WAAW,GAC5D,MAAM,IAAI,cAAc,kBAAkB,wBAAwB;CAEtE,IAAI,OAAO,IAAI,UAAU,YAAY,IAAI,MAAM,WAAW,GACtD,MAAM,IAAI,cAAc,kBAAkB,qBAAqB;CAEnE,IAAI,CAAC,iBAAiB,IAAI,IAAI,GAAG,MAAM,aAAa,QAAQ,UAAU;CACtE,IAAI,IAAI,kBAAkB,UAAa,OAAO,IAAI,kBAAkB,WAChE,MAAM,aAAa,iBAAiB,WAAW;CAEnD,eAAe,IAAI,MAAM;CACzB,cAAc,IAAI,KAAK;CACvB,YAAY,IAAI,GAAG;AACvB;AAEA,IAAa,eAAb,MAA0B;CAED;CACA;CAFrB,YACI,AAAiB,SACjB,AAAiB,QACnB;EAFmB;EACA;CAClB;CAEH,MAAa,KAAK,YAAwD;EACtE,MAAM,eAAe,MAAM,KAAK,QAAQ,aAAa,UAAU;EAC/D,MAAM,SAAkB,MAAM,QAAQ,QAAQ,qBAAqB,YAAY,CAAC;EAChF,eAAe,MAAM;EAErB,MAAM,YAAY,QAAQ,UAAU;EACpC,MAAM,OAAO,QAAQ,WAAW,OAAO,QAAQ,GAAG;EAClD,MAAM,WAAW,KAAK,kBAAkB,MAAM,OAAO,QAAQ;EAC7D,MAAM,QAAQ,KAAK,kBAAkB,MAAM,OAAO,KAAK;EACvD,KAAK,sBAAsB,MAAM,KAAK;EACtC,MAAM,QAAQ,KAAK,oBAAoB,WAAW,OAAO,KAAK;EAC9D,MAAM,YAAY,iBAAiB,OAAO,KAAK,WAAW,IAAI;EAE9D,KAAK,OAAO,MAAM,6BAA6B,YAAY;EAC3D,KAAK,OAAO,MAAM,kBAAkB,MAAM;EAC1C,KAAK,OAAO,MAAM,sBAAsB,UAAU;EAClD,KAAK,OAAO,MAAM,mBAAmB,OAAO;EAC5C,KAAK,OAAO,MAAM,0BAA0B,MAAM,QAAQ;EAC1D,IAAI,MAAM,UAAU,KAAK,OAAO,MAAM,4BAA4B,MAAM,UAAU;EAClF,IAAI,UAAU,SAAS,KAAK,OAAO,MAAM,uBAAuB,UAAU,YAAY,WAAW;EACjG,KAAK,OAAO,MAAM,uBAAuB,MAAM,WAAW;EAE1D,OAAO;GACH;GACA;GACA,YAAY;GACZ;GACA;GACA;GACA,eAAe,OAAO,iBAAiB;GACvC,QAAQ,cAAc,OAAO,MAAM;GACnC,KAAK,OAAO;EAChB;CACJ;CAEA,AAAQ,kBAAkB,MAAc,QAAwB;EAC5D,IAAI,WAAW,MAAM,GAAG,OAAO;EAC/B,OAAO,QAAQ,MAAM,MAAM;CAC/B;CAEA,AAAQ,sBAAsB,MAAc,OAAqB;EAC7D,MAAM,eAAe,SAAS,MAAM,KAAK;EACzC,IAAI,aAAa,WAAW,IAAI,KAAK,WAAW,YAAY,GACxD,MAAM,IAAI,cAAc,kBAAkB,2BAA2B,CAAC,OAAO,IAAI,CAAC;CAE1F;CAEA,AAAQ,oBACJ,WACA,OAC2B;EAC3B,MAAM,SAAS,QAAQ,WAAW,OAAO,UAAU,MAAM;EACzD,MAAM,iBAAiB,OAAO;EAC9B,MAAM,YAAY,iBAAiB,KAAK,iBAAiB,QAAQ,cAAc,IAAI,QAAQ,QAAQ,WAAW;EAC9G,MAAM,WAAW,OAAO,WAAW,QAAQ,WAAW,MAAM,QAAQ,IAAI;EAMxE,OAJmD,WAC7C;GAAE;GAAQ;GAAW;EAAS,IAC9B;GAAE;GAAQ;EAAU;CAG9B;CAEA,AAAQ,iBAAiB,QAAgB,WAA2B;EAChE,IAAI,WAAW,SAAS,GAAG,OAAO;EAClC,OAAO,QAAQ,QAAQ,SAAS;CACpC;AACJ;;;;AClKA,IAAa,gBAAb,MAA2B;CACM;CAA7B,YAAY,AAAiB,QAAiB;EAAjB;CAAkB;CAE/C,AAAO,OAAO,UAAU,QAAQ,IAAI,GAAW;EAC3C,MAAM,iBAAiB,QAAQ,OAAO;EACtC,KAAK,MAAM,aAAa,2BAA2B;GAC/C,MAAM,WAAW,KAAK,gBAAgB,SAAS;GAC/C,IAAI,WAAW,QAAQ,GAAG;IACtB,KAAK,OAAO,MAAM,mBAAmB,UAAU;IAC/C,OAAO;GACX;EACJ;EAEA,MAAM,IAAI,cAAc,kBAAkB,mBAAmB,CAAC,gBAAgB,yBAAyB,CAAC;CAC5G;AACJ;;;;ACPA,MAAM,gCAAgB,IAAI,IAAI;CAAC;CAAO;CAAQ;CAAQ;AAAM,CAAC;AAE7D,IAAa,sBAAb,MAAyD;CAOxB;CAN7B,AAAiB,OAAO,WAAW,YAAY,KAAK;EAChD,OAAO;EACP,gBAAgB;EAChB,YAAY;GAAC;GAAO;GAAQ;GAAQ;GAAQ;GAAO;GAAQ;EAAM;CACrE,CAAC;CAED,YAAY,AAAiB,UAAsC,CAAC,GAAG;EAA1C;CAA2C;CAExE,MAAa,aAAgC,WAAqC;EAC9E,MAAM,aAAa,QAAQ,SAAS;EACpC,IAAI,CAAC,WAAW,UAAU,GACtB,MAAM,IAAI,cAAc,kBAAkB,kBAAkB,CAAC,UAAU,CAAC;EAG5E,IAAI,KAAK,aAAa,UAAU,GAC5B,OAAO,KAAK,cAAuB,UAAU;EAGjD,OAAO,KAAK,eAAwB,UAAU;CAClD;CAEA,AAAQ,aAAa,UAA2B;EAC5C,IAAI,KAAK,QAAQ,UAAU,OAAO;EAClC,OAAO,cAAc,IAAI,QAAQ,QAAQ,CAAC,CAAC,YAAY,CAAC;CAC5D;CAEA,MAAc,cAAiC,WAAqC;EAChF,MAAM,YAAY,cAAc,SAAS,CAAC,CAAC;EAC3C,MAAM,WAAW,KAAK,gBAAgB,SAAS;EAE/C,IAAI;GACA,OAAQ,MAAM,SAAS,WAAW;IAAE,WAAW,YAAY;IAAK;GAAS,CAAC;EAC9E,SAAS,OAAgB;GACrB,MAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,MAAM,UAAU;GACtD,MAAM,IAAI,cAAc,kBAAkB,oBAAoB,CAAC,WAAW,MAAM,CAAC;EACrF;CACJ;CAEA,MAAc,eAAkC,WAAqC;EACjF,MAAM,YAAY,cAAc,SAAS,CAAC,CAAC;EAE3C,IAAI;GACA,OAAQ,MAAM,OAAO;EACzB,SAAS,aAAsB;GAC3B,IAAI;IACA,OAAO,MAAM,KAAK,KAAK,OAAO,SAAS;GAC3C,SAAS,eAAwB;IAC7B,MAAM,eAAe,MAAM,QAAQ,WAAW,IAAI,YAAY,UAAU;IACxE,MAAM,iBAAiB,MAAM,QAAQ,aAAa,IAAI,cAAc,UAAU;IAC9E,MAAM,IAAI,cAAc,kBAAkB,iBAAiB;KAAC;KAAW;KAAc;IAAc,CAAC;GACxG;EACJ;CACJ;CAEA,AAAQ,gBAAgB,WAAmC;EACvD,IAAI,KAAK,QAAQ,aAAa,QAC1B,OAAO,KAAK,QAAQ;EAGxB,OAAO,KAAK,oBAAoB,QAAQ,SAAS,CAAC,KAAK;CAC3D;CAEA,AAAQ,oBAAoB,UAAsC;EAC9D,MAAM,YAAY,QAAQ,UAAU,eAAe;EACnD,IAAI,WAAW,SAAS,GAAG,OAAO;EAElC,MAAM,SAAS,QAAQ,QAAQ;EAC/B,IAAI,WAAW,UAAU,OAAO;EAEhC,OAAO,KAAK,oBAAoB,MAAM;CAC1C;AACJ;;;;ACnFA,IAAa,kBAAb,MAA6B;CACI;CAA7B,YAAY,AAAiB,QAAiB;EAAjB;CAAkB;CAE/C,MAAa,MAAM,QAAmC,cAAqC;EACvF,MAAM,SAAS,OAAO,MAAM;EAE5B,MAAM,WAAW,WADM,KAAK,iBAAiB,SAAS,QAAQ,MAAM,GAAG,YAAY,CAC1C,EAAE;EAE3C,IAAI;GACA,MAAM,MAAM,QAAQ,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;GAChD,MAAM,UAAU,QAAQ,UAAU,MAAM;EAC5C,SAAS,OAAgB;GACrB,MAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,MAAM,UAAU;GACtD,MAAM,IAAI,cAAc,kBAAkB,yBAAyB,CAAC,QAAQ,MAAM,CAAC;EACvF;EAEA,KAAK,OAAO,KAAK,6BAA6B,QAAQ;CAC1D;CAEA,AAAQ,iBAAiB,UAA0B;EAC/C,MAAM,aAAa,SAAS,WAAW,MAAM,GAAG;EAChD,OAAO,WAAW,WAAW,GAAG,IAAI,aAAa,KAAK;CAC1D;AACJ;;;;ACXA,IAAa,2BAAb,MAAsC;CACL;CAA7B,YAAY,AAAiB,QAAiB;EAAjB;CAAkB;CAE/C,MAAa,MAAM,QAAyD;EACxE,MAAM,eAAe,KAAK,gBAAgB,MAAM;EAChD,MAAM,aAAa,QAAQ,OAAO,UAAU;EAE5C,MAAM,MAAM,OAAO,MAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;EAEpD,KAAK,OAAO,KAAK,2CAA2C,cAAc;EAE1E,IAAI;GACA,MAAM,KAAK,OAAO,YAAY,YAAY;GAC1C,MAAM,KAAK,kBAAkB,YAAY,YAAY;EACzD,SAAS,OAAgB;GACrB,IAAI,gBAAgB,KAAK,GAAG,MAAM;GAElC,MAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,MAAM,UAAU;GACtD,MAAM,IAAI,cAAc,kBAAkB,gBAAgB,CAAC,MAAM,CAAC;EACtE;EAEA,MAAM,eAAe,KAAK,oBAAoB,MAAM;EACpD,IAAI,CAAC,WAAW,YAAY,GACxB,MAAM,IAAI,cAAc,kBAAkB,gBAAgB,CACtD,wBAAwB,aAAa,qBACzC,CAAC;EAGL,KAAK,OAAO,KAAK,kBAAkB,cAAc;EACjD,OAAO,EAAE,aAAa;CAC1B;CAEA,MAAc,OAAO,YAAoB,cAAqC;EAC1E,MAAM,UAAU,KAAK,kBAAkB,UAAU;EAEjD,MAAM,OAAO;GAAC;GAAM;GAAc;GAAY;GAAS;EAAiB;EAExE,IAAI,CAAE,MAAM,KAAK,oBAAoB,YAAY,YAAY,GAAI,KAAK,KAAK,aAAa;EAExF,MAAM,SAAS,MAAM,KAAK,cAAc,YAAY,SAAS,IAAI;EACjE,IAAI,OAAO,aAAa,GAAG;EAE3B,MAAM,IAAI,cAAc,kBAAkB,gBAAgB,CACtD,mCAAmC,KAAK,eAAe,OAAO,MAAM,GACxE,CAAC;CACL;CAEA,MAAc,oBAAoB,YAAoB,cAAwC;EAC1F,MAAM,UAAU,KAAK,kBAAkB,UAAU;EACjD,MAAM,SAAS,MAAM,KAAK,cAAc,YAAY,SAAS;GAAC;GAAgB;GAAM;EAAY,CAAC;EACjG,IAAI,OAAO,aAAa,GAAG,OAAO;EAElC,IAAI;GAEA,OADe,KAAK,MAAM,OAAO,MACrB,CAAC,CAAC,iBAAiB,oBAAoB;EACvD,QAAQ;GACJ,OAAO;EACX;CACJ;CAGA,MAAc,kBAAkB,YAAoB,cAAqC;EACrF,MAAM,UAAU,KAAK,gBAAgB;EAErC,MAAM,SAAS,MAAM,KAAK,cAAc,YAAY,SAAS;GACzD;GACA;GACA;GACA;GACA;EACJ,CAAC;EACD,IAAI,OAAO,aAAa,GAAG;EAE3B,MAAM,IAAI,cAAc,kBAAkB,gBAAgB,CACtD,yCAAyC,KAAK,eAAe,OAAO,MAAM,GAC9E,CAAC;CACL;CAEA,AAAQ,kBAAkB,YAA4B;EAClD,MAAM,iBAAiB,KAAK,qBAAqB,UAAU;EAE3D,IAAI;GACA,OAAO,eAAe,QAAQ,oBAAoB;EACtD,SAAS,OAAgB;GACrB,MAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,MAAM,UAAU;GACtD,MAAM,IAAI,cAAc,kBAAkB,gBAAgB,CACtD,0EAA0E,QAC9E,CAAC;EACL;CACJ;CAEA,AAAQ,kBAA0B;EAG9B,OAFoBA,cAAkB,YAAY,GAEjC,CAAC,CAAC,QAAQ,6BAA6B;CAC5D;CAEA,AAAQ,qBAAqB,YAAoC;EAC7D,MAAM,YAAY,QAAQ,YAAY,cAAc;EACpD,IAAI,WAAW,SAAS,GAAG,OAAOA,cAAkB,SAAS;EAE7D,OAAOA,cAAkB,YAAY,GAAG;CAC5C;CAEA,MAAc,cAAc,KAAa,YAAoB,MAAwC;EACjG,OAAO,MAAM,KAAK,WAAW,QAAQ,UAAU,CAAC,YAAY,GAAG,IAAI,GAAG,GAAG;CAC7E;CAEA,AAAQ,WAAW,KAAa,MAAgB,KAAqC;EACjF,OAAO,IAAI,SAAS,gBAAgB,kBAAkB;GAClD,MAAM,QAAQ,MAAM,KAAK,MAAM;IAAE;IAAK,OAAO;KAAC;KAAU;KAAQ;IAAM;GAAE,CAAC;GAEzE,IAAI,SAAS;GAEb,MAAM,OAAO,GAAG,SAAS,UAAU;IAC/B,UAAU,OAAO,KAAK;GAC1B,CAAC;GAED,MAAM,OAAO,GAAG,SAAS,UAAU;IAC/B,UAAU,OAAO,KAAK;GAC1B,CAAC;GAED,MAAM,GAAG,SAAS,aAAa;GAE/B,MAAM,GAAG,UAAU,SAAS;IACxB,eAAe;KAAE,UAAU,QAAQ;KAAG;IAAO,CAAC;GAClD,CAAC;EACL,CAAC;CACL;CAEA,AAAQ,eAAe,MAAc,WAAW,MAAgB;EAC5D,MAAM,UAAU,KAAK,KAAK;EAC1B,IAAI,QAAQ,UAAU,UAAU,OAAO;EACvC,OAAO,GAAG,QAAQ,MAAM,GAAG,QAAQ,EAAE;CACzC;CAEA,AAAQ,gBAAgB,QAA2C;EAC/D,IAAI,OAAO,MAAM,UAAU;GACvB,IAAI,CAAC,WAAW,OAAO,MAAM,QAAQ,GACjC,MAAM,IAAI,cAAc,kBAAkB,0BAA0B,CAAC,OAAO,MAAM,QAAQ,CAAC;GAG/F,OAAO,OAAO,MAAM;EACxB;EAEA,MAAM,YAAY,QAAQ,OAAO,UAAU;EAC3C,MAAM,YAAY,CAAC,uBAAuB,eAAe,CAAC,CACrD,KAAK,SAAS,QAAQ,WAAW,IAAI,CAAC,CAAC,CACvC,MAAM,kBAAkB,WAAW,aAAa,CAAC;EAEtD,IAAI,WAAW,OAAO;EAEtB,MAAM,IAAI,cAAc,kBAAkB,0BAA0B,CAAC,SAAS,CAAC;CACnF;CAEA,AAAQ,oBAAoB,QAA2C;EACnE,MAAM,cAAc,SAAS,OAAO,MAAM,OAAO,KAAK;EACtD,MAAM,WAAW,YAAY,MAAM,GAAG,YAAY,SAAS,QAAQ,WAAW,CAAC,CAAC,MAAM;EAEtF,MAAM,WAAW,QAAQ,OAAO,MAAM,QAAQ,QAAQ;EAGtD,KAAK,MAAM,OAAO;GAFK;GAAO;GAAQ;EAER,GAAG;GAC7B,MAAM,YAAY,GAAG,WAAW;GAChC,IAAI,WAAW,SAAS,GAAG,OAAO;EACtC;EAGA,OAAO,GAAG,SAAS;CACvB;AACJ;;;;AChLA,IAAa,cAAb,MAAa,YAAY;CAEA;CACA;CACA;CACA;CACA;CALrB,YACI,AAAiB,SACjB,AAAiB,cACjB,AAAiB,SACjB,AAAiB,iBACjB,AAAiB,QACnB;EALmB;EACA;EACA;EACA;EACA;CAClB;CAEH,OAAc,OAAO,QAA8B;EAC/C,MAAM,eAAe,IAAI,oBAAoB;EAC7C,MAAM,UAAU,IAAI,cAAc,MAAM;EACxC,MAAM,eAAe,IAAI,aAAa,cAAc,MAAM;EAC1D,MAAM,UAAU,IAAI,yBAAyB,MAAM;EACnD,MAAM,kBAAkB,IAAI,gBAAgB,MAAM;EAElD,OAAO,IAAI,YAAY,SAAS,cAAc,SAAS,iBAAiB,MAAM;CAClF;CAEA,MAAa,MAAqB;EAC9B,MAAM,SAAS,MAAM,KAAK,WAAW;EACrC,KAAK,kBAAkB,OAAO,KAAK;EACnC,MAAM,EAAE,iBAAiB,MAAM,KAAK,QAAQ,MAAM,MAAM;EACxD,MAAM,KAAK,gBAAgB,MAAM,QAAQ,YAAY;EACrD,KAAK,OAAO,KAAK,uCAAuC;CAC5D;CAEA,MAAc,aAAiD;EAC3D,MAAM,aAAa,KAAK,QAAQ,OAAO;EACvC,OAAO,KAAK,aAAa,KAAK,UAAU;CAC5C;CAEA,AAAQ,kBAAkB,WAAyB;EAC/C,IAAI,CAAC,WAAW,SAAS,GACrB,MAAM,IAAI,cAAc,kBAAkB,kBAAkB,CAAC,SAAS,CAAC;CAE/E;AACJ;;;;AC5CA,IAAa,eAAb,cAAkC,YAAY;CAC1C,AAAiB;CAEjB,cAAc;EACV,MAAM,SAAS,mDAAmD,OAAO;EACzE,KAAK,SAAS,YAAY,OAAO,KAAK,MAAM;CAChD;CAEA,AAAO,SAAS,SAAwB;EACpC,QACK,QAAQ,KAAK,IAAI,CAAC,CAClB,YAAY,KAAK,WAAW,CAAC,CAC7B,OAAO,YAAY;GAChB,IAAI;IACA,MAAM,KAAK,OAAO,IAAI;GAC1B,SAAS,OAAgB;IACrB,KAAK,OAAO,MAAM,yBAAyB,KAAK;IAChD,IAAI,gBAAgB,KAAK,GAAG,QAAQ,WAAW;SAC1C,QAAQ,KAAK,CAAC;GACvB;EACJ,CAAC;CACT;AACJ;;;;ACaA,MAAM,eAAe;EAChB,6BAA6B,SAAS;EACtC,6BAA6B,UAAU;EACvC,6BAA6B,SAAS;EACtC,6BAA6B,UAAU;EACvC,6BAA6B,OAAO;EACpC,6BAA6B,UAAU;EACvC,6BAA6B,OAAO;EACpC,6BAA6B,cAAc;EAC3C,6BAA6B,aAAa;AAC/C;AAGA,SAAS,aAAa,UAAoF;CACtG,IAAI,CAAC,YAAY,SAAS,WAAW,GAAG,OAAO;CAC/C,OAAO,SAAS,OAAO,YAAY,YAAY,uBAAuB,KAAK,IAAI,WAAW;AAC9F;AAEA,SAAS,UAAU,aAAsC;CACrD,MAAM,SAAqB,CAAC;CAC5B,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,GACjD,OAAO,OAAO,MAAM,QAAQ,KAAK,IAAI,UAAU;CAEnD,OAAO;AACX;AAGA,IAAa,sBAAb,MAAiC;CACA;CAA7B,YAAY,AAAiB,QAAiB;EAAjB;CAAkB;CAE/C,AAAO,SAAS,UAAqC,aAAwC;EACzF,MAAM,QAAqB,CAAC;EAC5B,MAAM,gCAAgB,IAAI,IAAoB;EAC9C,MAAM,mCAAmB,IAAI,IAAoB;EACjD,MAAM,sCAAsB,IAAI,IAAoB;EACpD,MAAM,4BAAY,IAAI,IAA6C;EACnE,MAAM,+BAAe,IAAI,IAA6C;EAEtE,KAAK,MAAM,WAAW,UAAU;GAC5B,MAAM,EAAE,SAAS;GACjB,QAAQ,KAAK,MAAb;IACI,KAAK,uBAAuB;KACxB,KAAK,mBAAmB,QAAQ,MAAM,QAAQ,YAAY,kBAAkB,SAAS;KACrF;IAEJ,KAAK,uBAAuB;KACxB,KAAK,mBAAmB,WAAW,MAAM,QAAQ,YAAY,qBAAqB,YAAY;KAC9F;IAEJ,KAAK;IACL,KAAK,uBAAuB,WACxB,KAAK,aAAa,MAAM,QAAQ,YAAY,OAAO,aAAa;GAIxE;EACJ;EAEA,MAAM,mBAAmB,OAAO,YAAY,SAAS;EACrD,MAAM,sBAAsB,OAAO,YAAY,YAAY;EAC3D,MAAM,SAAS,UAAU,WAAW;EACpC,KAAK,OAAO,MACR,aAAa,OAAO,KAAK,KAAK,CAAC,CAAC,OAAO,mBAAmB,OAAO,KAAK,gBAAgB,CAAC,CAAC,OAAO,YAAY,OAAO,KAAK,mBAAmB,CAAC,CAAC,OAAO,oCAAoC,OAAO,KAAK,MAAM,CAAC,CAAC,OAAO,UACtN;EACA,OAAO;GAAE;GAAO;GAAkB;GAAqB;EAAO;CAClE;CAEA,AAAQ,aACJ,MACA,YACA,OACA,eACI;EACJ,KAAK,gBAAgB,IAAI;EACzB,MAAM,aAAa,aAAa,KAAK,QAAQ;EAC7C,KAAK,MAAM,QAAQ,cAAc,IAAI,GAAG;GAEpC,MAAM,YAAY,cAAc,IAAI,KAAK,KAAK;GAC9C,IAAI,cAAc,QACd,MAAM,IAAI,cAAc,kBAAkB,0BAA0B;IAChE,KAAK;IACL;IACA;GACJ,CAAC;GAEL,cAAc,IAAI,KAAK,OAAO,UAAU;GACxC,MAAM,KAAK,SAAS;IAAE,SAAS,KAAK,WAAW,KAAK,OAAO;IAAG,OAAO;GAAW;EACpF;CACJ;CAEA,AAAQ,mBACJ,MACA,MACA,YACA,cACA,OACI;EACJ,MAAM,YAAY,aAAa,IAAI,KAAK,IAAI;EAC5C,IAAI,cAAc,QACd,MAAM,IAAI,cAAc,kBAAkB,gCAAgC;GACtE;GACA,KAAK;GACL;GACA;EACJ,CAAC;EAEL,aAAa,IAAI,KAAK,MAAM,UAAU;EACtC,MAAM,IAAI,KAAK,MAAM,EAAE,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;CAC/D;CAIA,AAAQ,gBAAgB,MAA6D;EACjF,KAAK,MAAM,UAAU,KAAK,WAAW,CAAC,GAClC,IAAI,OAAO,SAAS,6BAA6B,oBAAoB,OAAO,WAAW,CAAC,EAAC,CAAE,WAAW,GAClG,KAAK,OAAO,KAAK,iBAAiB,KAAK,KAAK,GAAG,OAAO,KAAK,2CAA2C;CAGlH;CAEA,AAAQ,WAAW,SAAiD;EAChE,MAAM,QAAsB,CAAC;EAC7B,KAAK,MAAM,UAAU,SAAS;GAC1B,IACI,OAAO,SAAS,6BAA6B,cAC7C,OAAO,SAAS,6BAA6B,iBAE7C;GAEJ,MAAM,OAAO,QAAQ,KAAK,cAAc,MAAM;EAClD;EACA,OAAO;CACX;CAEA,AAAQ,cAAc,QAAkC;EAEpD,MAAM,UACF,aAAa,UAAU,OAAO,WAAW,OAAO,QAAQ,SAAS,IAC3D,OAAO,QAAQ,KAAK,WAAW,OAAO,KAAK,IAC3C;EACV,MAAM,eAAe,kBAAkB,UAAU,OAAO,iBAAiB,OAAO,OAAO;EAEvF,MAAM,eACF,mBAAmB,UAAU,OAAO,iBAAiB,OAAO,cAAc,SAAS,IAC7E,CAAC,GAAG,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,WAAW,QAAQ,MAAM,IAChE;EACV,OAAO;GACH,MAAM,aAAa,OAAO;GAC1B,UAAU,OAAO,YAAY;GAC7B,GAAI,WAAW,EAAE,QAAQ;GACzB,GAAI,gBAAgB,EAAE,aAAa;GACnC,GAAI,gBAAgB,EAAE,aAAa;EACvC;CACJ;AACJ;;;;AClMA,MAAM,SAAS;;AAGf,MAAM,cAAc;AAEpB,MAAM,aAAa;AACnB,MAAM,eAAe;AACrB,MAAM,YAAY;AAOlB,SAAgB,mBAAmB,UAAwB,QAAgB,SAAmC;CAC1G,MAAM,OAAO,CAAC,GAAI,SAAS,QAAQ,CAAC,CAAE,CAAC,CAAC,KAAK,OAAO;CACpD,MAAM,WAAW,YAAY,UAAa,KAAK,SAAS;CACxD,MAAM,YAAY,WAAW,eAAe,YAAY,SAAS,cAAc,QAAQ,SAAS,EAAE,UAAU;CAC5G,MAAM,WAAW,WAAW,yBAAyB,iBAAiB,IAAI,EAAE,aAAa;CAKzF,OACI,GAAG,GAHW,OAAO,MAAM,UAAU,sCAAsC,OAAO,SAGtE,SAAS,iCAAiC,gBAAgB,SAAS,KAAK,EAAE,oDAC1C,sBAAsB,SAAS,gBAAgB,EAAE,uDAC9C,sBAAsB,SAAS,mBAAmB,EAAE,qCACtE,gBAAgB,SAAS,MAAM,EAAE;AAGtE;AAIA,SAAS,iBAAiB,MAAiC;CACvD,OAAO,KAAK,KAAK,QAAQ,WAAW,UAAU,GAAG,EAAE,YAAY,YAAY,KAAK,cAAc,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI;AACtH;AAEA,SAAS,gBAAgB,QAA6B;CAClD,OAAO,OAAO,QAAQ,MAAM,CAAC,CACxB,MAAM,CAAC,QAAQ,CAAC,YAAY,QAAQ,OAAO,MAAM,CAAC,CAAC,CACnD,KAAK,CAAC,OAAO,SAAS,WAAW,UAAU,KAAK,EAAE,IAAI,UAAU,GAAG,EAAE,EAAE,CAAC,CACxE,KAAK,IAAI;AAClB;AAEA,SAAS,sBAAsB,OAAkC;CAC7D,OAAO,OAAO,QAAQ,KAAK,CAAC,CACvB,MAAM,CAAC,QAAQ,CAAC,YAAY,QAAQ,OAAO,MAAM,CAAC,CAAC,CACnD,KAAK,CAAC,MAAM,EAAE,aAAa,WAAW,UAAU,IAAI,EAAE,IAAI,eAAe,KAAK,EAAE,EAAE,CAAC,CACnF,KAAK,IAAI;AAClB;AAEA,SAAS,eAAe,OAAqC;CACzD,OAAO,YAAY,UAAU,SAAY,cAAc,IAAI,MAAM,GAAG;AACxE;AAGA,SAAS,gBAAgB,QAA4B;CACjD,OAAO,OAAO,QAAQ,MAAM,CAAC,CACxB,MAAM,CAAC,QAAQ,CAAC,YAAY,QAAQ,OAAO,MAAM,CAAC,CAAC,CACnD,KAAK,CAAC,KAAK,UAAU,WAAW,UAAU,GAAG,EAAE,KAAK,SAAS,UAAU,UAAU,cAAc,GAAG,CAAC,CACnG,KAAK,IAAI;AAClB;AAEA,SAAS,UAAU,KAA8B;CAC7C,MAAM,QAAQ,IAAI,UAAU,SAAY,cAAc,IAAI,IAAI,MAAM;CACpE,OAAO,cAAc,cAAc,IAAI,OAAO,EAAE,WAAW,MAAM;AACrE;AAEA,SAAS,cAAc,SAA+B;CAClD,MAAM,UAAU,OAAO,QAAQ,OAAO;CACtC,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,OAAO,KAAK,QAAQ,KAAK,CAAC,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE,IAAI,aAAa,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE;AACpG;AAEA,SAAS,aAAa,KAA0B;CAC5C,MAAM,QAAQ,CAAC,UAAU,IAAI,KAAK,IAAI,aAAa,IAAI,UAAU;CACjE,IAAI,IAAI,WAAW,IAAI,QAAQ,SAAS,GAAG,MAAM,KAAK,aAAa,IAAI,QAAQ,IAAI,YAAY,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE;CAC9G,IAAI,IAAI,cAAc,MAAM,KAAK,oBAAoB;CAErD,IAAI,IAAI,gBAAgB,IAAI,aAAa,SAAS,GAAG,MAAM,KAAK,kBAAkB,IAAI,aAAa,KAAK,IAAI,EAAE,EAAE;CAChH,OAAO,KAAK,MAAM,KAAK,IAAI,EAAE;AACjC;AAEA,SAAS,aAAa,OAAgC;CAClD,IAAI,OAAO,UAAU,UAAU,OAAO,OAAO,KAAK;CAClD,OAAO,IAAI,cAAc,KAAK,EAAE;AACpC;AAGA,SAAS,UAAU,MAAsB;CACrC,OAAO,WAAW,KAAK,IAAI,IAAI,OAAO,IAAI,cAAc,IAAI,EAAE;AAClE;AAEA,SAAS,cAAc,OAAuB;CAC1C,IAAI,UAAU;CACd,KAAK,MAAM,QAAQ,OAAO;EACtB,MAAM,OAAO,KAAK,WAAW,CAAC;EAC9B,QAAQ,MAAR;GACI,KAAK;IACD,WAAW;IACX;GAEJ,KAAK;IACD,WAAW,OAAO,GAAG;IACrB;GAEJ,KAAK;IACD,WAAW,OAAO,GAAG;IACrB;GAEJ,KAAK;IACD,WAAW,OAAO,GAAG;IACrB;GAEJ,KAAK;IACD,WAAW,OAAO,GAAG;IACrB;GAEJ,SACI,IAAI,OAAO,cAAc,WAAW,OAAO,GAAG,KAAK,KAAK,SAAS,SAAS,CAAC,CAAC,SAAS,GAAG,GAAG;QACtF,WAAW;EAExB;CACJ;CACA,OAAO;AACX;AAEA,SAAS,QAAQ,OAAe,QAAwB;CACpD,IAAI,QAAQ,QAAQ,OAAO;CAC3B,OAAO,QAAQ,SAAS,IAAI;AAChC;;;;AC9GA,MAAM,kBAAkB;AAExB,MAAM,kBAAkB;AAcxB,SAAS,aAAa,MAAc,UAA0B;CAC1D,MAAM,QAAQ,SAAS,MAAM,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,QAAQ,iBAAiB,EAAE;CACvF,OAAO,MAAM,WAAW,GAAG,IAAI,QAAQ,KAAK;AAChD;AAEA,IAAa,gBAAb,MAAa,cAAc;CAEF;CACA;CACA;CACA;CACA;CALrB,YACI,AAAiB,SACjB,AAAiB,cACjB,AAAiB,cACjB,AAAiB,WACjB,AAAiB,QACnB;EALmB;EACA;EACA;EACA;EACA;CAClB;CAEH,OAAc,OAAO,QAAgC;EACjD,MAAM,eAAe,IAAI,oBAAoB;EAC7C,MAAM,UAAU,IAAI,cAAc,MAAM;EACxC,MAAM,eAAe,IAAI,aAAa,cAAc,MAAM;EAC1D,MAAM,YAAY,IAAI,oBAAoB,MAAM;EAEhD,OAAO,IAAI,cAAc,SAAS,cAAc,cAAc,WAAW,MAAM;CACnF;CAEA,MAAa,IAAI,OAA+B;EAC5C,MAAM,SAAS,MAAM,KAAK,WAAW;EACrC,MAAM,EAAE,UAAU,QAAQ,eAAe,eAAe,MAAM,KAAK,KAAK,MAAM;EAC9E,MAAM,WAAW,mBAAmB,KAAK,UAAU,SAAS,UAAU,MAAM,GAAG,eAAe;GAC1F,WAAW,aAAa,OAAO,MAAM,OAAO,QAAQ;GACpD,MAAM;EACV,CAAC;EACD,MAAM,aAAa,QAAQ,OAAO,MAAM,eAAe;EAEvD,IAAI,OAAO;GACP,MAAM,KAAK,MAAM,UAAU,UAAU;GACrC;EACJ;EAEA,MAAM,KAAK,MAAM,UAAU,UAAU;CACzC;CAEA,MAAc,aAAiD;EAC3D,OAAO,KAAK,aAAa,KAAK,KAAK,QAAQ,OAAO,CAAC;CACvD;CAEA,MAAc,KAAK,QAAwD;EACvE,MAAM,EAAE,aAAa,QAAQ,eAAe,eAAe,MAAM,KAAK,gBAAgB,MAAM;EAE5F,MAAM,WAA6B,CAAC;EACpC,IAAI,aACA,WAAW,MAAM,WAAW,KAAK,KAAK,6BAAa,IAAI,IAAI,GAAG,IAAI,GAC9D,SAAS,KAAK,OAAO;EAG7B,OAAO;GAAE;GAAU;GAAQ;GAAe;EAAW;CACzD;CAIA,OAAe,KAAK,KAAa,MAAoB,QAAiD;EAClG,IAAI;EACJ,IAAI;GACA,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;EACxD,SAAS,OAAgB;GACrB,MAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,MAAM,UAAU;GAEtD,IAAI,QAAQ,MAAM,IAAI,cAAc,kBAAkB,iCAAiC,CAAC,KAAK,MAAM,CAAC;GACpG,KAAK,OAAO,KAAK,iCAAiC,IAAI,IAAI,OAAO,EAAE;GACnE;EACJ;EAEA,KAAK,MAAM,SAAS,SAAS;GACzB,MAAM,WAAW,KAAK,KAAK,MAAM,IAAI;GACrC,IAAI,MAAM,YAAY,GAClB,OAAO,KAAK,KAAK,UAAU,MAAM,KAAK;QACnC,IAAI,aAAa,KAAK,GAAG;IAC5B,MAAM,WAAW,MAAM,KAAK,aAAa,aAAsC,QAAQ;IACvF,KAAK,MAAM,YAAY,OAAO,OAAO,QAAQ,GAAG;KAE5C,IAAI,KAAK,IAAI,QAAQ,GAAG;KACxB,KAAK,IAAI,QAAQ;KACjB,MAAM,OAAO,KAAK,cAAc,QAAQ;KACxC,IAAI,MAAM,MAAM;MAAE,YAAY;MAAU;KAAK;IACjD;GACJ;EACJ;CACJ;CAEA,MAAc,gBACV,QACgF;EAGhF,KAAK,OAAO,MAAM,oDAAoD;EACtE,MAAM,SAAS,MAAM,KAAK,aAAa,aAAa,OAAO,QAAQ;EACnE,MAAM,WAAW,qBAAqB,MAAM;EAC5C,IAAI,CAAC,KAAK,mBAAmB,QAAQ,GACjC,MAAM,IAAI,cAAc,kBAAkB,kBAAkB;EAIhE,MAAM,eAAe,SAAS,OAAO,IAAI,SAAS;EAClD,OAAO;GACH,aAAa,eAAe,QAAQ,QAAQ,IAAI,GAAG,YAAY,IAAI;GACnE,QAAQ,SAAS,OAAO,IAAI,UAAU,CAAC;GACvC,eAAe,SAAS;GACxB,YAAY,SAAS;EACzB;CACJ;CAEA,AAAQ,cAAc,UAAuE;EACzF,IAAI,OAAO,aAAa,YAAY,OAAO;EAE3C,IAAI;EACJ,IAAI;GACA,WAAW,IAAK,SAA+B;EACnD,QAAQ;GACJ;EACJ;EAEA,IAAI,CAAC,KAAK,cAAc,QAAQ,GAAG,OAAO;EAC1C,MAAM,OAAO,SAAS,UAAU,OAAO;EACvC,IAAI,CAAC,KAAK,qBAAqB,IAAI,GAAG,OAAO;EAC7C,OAAO;CACX;CAEA,AAAQ,cAAc,OAAsC;EACxD,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;EACxD,MAAM,YAAa,MAAkC;EACrD,OACI,OAAO,cAAc,YACrB,cAAc,QACd,OAAQ,UAAuC,WAAW;CAElE;CAEA,AAAQ,qBAAqB,MAA+D;EACxF,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM,OAAO;EACtD,MAAM,EAAE,MAAM,SAAS;EACvB,IAAI,OAAO,SAAS,UAAU,OAAO;EAErC,OACI,SAAS,UACT,SAAS,uBAAuB,aAChC,SAAS,uBAAuB,QAChC,SAAS,uBAAuB;CAExC;CAEA,AAAQ,mBAAmB,WAAmD;EAC1E,OAAO,OAAO,cAAc,YAAY,cAAc,QAAS,UAAwB,mBAAmB;CAC9G;CAEA,MAAc,MAAM,UAAkB,YAAmC;EACrE,MAAM,MAAM,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;EACpD,MAAM,UAAU,YAAY,UAAU,MAAM;EAC5C,KAAK,OAAO,KAAK,4BAA4B,YAAY;CAC7D;CAEA,MAAc,MAAM,UAAkB,YAAmC;EAErE,KADe,WAAW,UAAU,IAAI,MAAM,SAAS,YAAY,MAAM,IAAI,QAC9D,UAAU;EAEzB,KAAK,OAAO,MAAM,sEAAsE,WAAW,EAAE;EACrG,QAAQ,WAAW;CACvB;AACJ;;;;ACrMA,IAAa,iBAAb,cAAoC,YAAY;CAC5C,AAAiB;CAEjB,cAAc;EACV,MAAM,WAAW,8DAA8D,SAAS;EACxF,KAAK,SAAS,cAAc,OAAO,KAAK,MAAM;CAClD;CAEA,AAAO,SAAS,SAAwB;EACpC,QACK,QAAQ,KAAK,IAAI,CAAC,CAClB,YAAY,KAAK,WAAW,CAAC,CAC7B,OAAO,WAAW,2EAA2E,CAAC,CAC9F,OAAO,OAAO,YAAY;GACvB,IAAI;IACA,MAAM,KAAK,OAAO,IAAI,QAAQ,SAAS,KAAK;GAChD,SAAS,OAAgB;IACrB,KAAK,OAAO,MAAM,2BAA2B,KAAK;IAClD,IAAI,gBAAgB,KAAK,GAAG,QAAQ,WAAW;SAC1C,QAAQ,KAAK,CAAC;GACvB;EACJ,CAAC;CACT;AACJ;;;;AC/BA,SAAgB,cAAc,MAAyB,gBAAkC;CACrF,OACI,CAAC,kBACD,QAAQ,MAAM,UAAU,QACxB,QAAQ,OAAO,UAAU,QAEzB,CAAC,QAAQ,IAAI,MACb,CAAC,KAAK;AAEd;;;;;;;;ACcA,SAAgB,sBACZ,aACA,QACA,OACS;CACT,MAAM,UAAqB,CAAC;CAE5B,KAAK,MAAM,EAAE,SAAS,WAAW,cAAc,QAC3C,KAAK,MAAM,WAAW,UAClB,IAAI,OACA,QAAQ,KAAK;EAAE;EAAS;EAAW,IAAI,QAAQ;EAAI,MAAM,QAAQ;EAAM,QAAQ;CAAQ,CAAC;MACrF,IAAI,YAAY,IAAI,QAAQ,IAAI,GACnC,QAAQ,KAAK;EAAE;EAAS;EAAW,IAAI,QAAQ;EAAI,MAAM,QAAQ;EAAM,QAAQ;CAAU,CAAC;CAKtG,OAAO;AACX;;;;ACuBA,MAAM,aAAa;AAEnB,IAAa,cAAb,MAAa,YAAgC;CACZ;CAA7B,YAAY,AAAiB,UAAyC;EAAzC;CAA0C;CAEvE,OAAc,SAAsB;EAChC,OAAO,IAAI,aAAa,UAAU,IAAI,KAAK,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC;CACjF;CAEA,MAAa,eAAe,OAAmB,OAAyC;EAEpF,IAAI,MAAM,SAAS,MAAM,WAAW,MAAM,IAAI,cAAc,kBAAkB,sBAAsB;EAEpG,IAAI,CAAC,MAAM,aAAa,MAAM,SAAS,WAAW,GAC9C,MAAM,IAAI,cAAc,kBAAkB,gBAAgB;EAG9D,MAAM,OAAO,KAAK,SAAS,KAAK;EAMhC,OAAO;GAAE,aALW,KAAK,aAAa,IAAI;GAK1B,QAJD,MAAM,YACf,MAAM,KAAK,eAAe,IAAI,IAC9B,MAAM,SAAS,KAAK,QAAQ;IAAE;IAAI,MAAM;GAAG,EAAE;EAE5B;CAC3B;CAEA,MAAa,cAAc,OAAwC;EAC/D,OAAO,KAAK,eAAe,KAAK,SAAS,KAAK,CAAC;CACnD;CAEA,MAAa,WACT,OACA,OACA,QACA,OACmB;EACnB,MAAM,OAAO,KAAK,SAAS,KAAK;EAChC,MAAM,cAAc,MAAM,KAAK,iBAAiB,MAAM,KAAK;EAE3D,MAAM,UAA2B,CAAC;EAClC,MAAM,UAA0B,CAAC;EACjC,IAAI,sBAAsB;EAC1B,KAAK,MAAM,SAAS,QAChB,IAAI;GAIA,MAAM,YAAW,MAHO,KAAK,IACzB,OAAO,yBAAyB,OAAO,MAAM,EAAE,CACnD,EACyB,CAAC,KAAK,aAAa;IAAE,IAAI,QAAQ;IAAI,MAAM,QAAQ;GAAK,EAAE;GACnF,uBAAuB,SAAS;GAChC,QAAQ,KAAK;IAAE,SAAS,MAAM;IAAI,WAAW,MAAM;IAAM;GAAS,CAAC;EACvE,SAAS,OAAgB;GACrB,QAAQ,KAAK;IACT,SAAS,MAAM;IACf,WAAW,MAAM;IACjB,QAAQ,MAAM,QAAQ,KAAK,IAAI,MAAM,UAAU;GACnD,CAAC;EACL;EAGJ,OAAO;GACH,SAAS,sBAAsB,aAAa,SAAS,KAAK;GAC1D;GACA,mBAAmB,QAAQ;GAC3B;GACA,oBAAoB,YAAY;EACpC;CACJ;CAEA,MAAa,eAAe,OAAe,OAAkB,SAA2C;EACpG,MAAM,OAAO,KAAK,SAAS,KAAK;EAChC,IAAI,UAAU;EACd,MAAM,SAA0B,CAAC;EAEjC,KAAK,MAAM,WAAW,SAClB,IAAI;GACA,MAAM,KAAK,OAAO,OAAO,wBAAwB,OAAO,QAAQ,SAAS,QAAQ,EAAE,CAAC;GACpF;EACJ,SAAS,OAAgB;GACrB,OAAO,KAAK;IAAE;IAAS,QAAQ,MAAM,QAAQ,KAAK,IAAI,MAAM,UAAU;GAAgB,CAAC;EAC3F;EAGJ,OAAO;GAAE;GAAS;EAAO;CAC7B;CAEA,MAAc,aAAa,MAAsC;EAC7D,IAAI;GAEA,QAAO,MADY,KAAK,IAAI,OAAO,mBAAmB,CAAC,EAC7C,CAAC;EACf,SAAS,OAAgB;GACrB,MAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,MAAM,UAAU;GACtD,MAAM,IAAI,cAAc,kBAAkB,wBAAwB,CAAC,MAAM,CAAC;EAC9E;CACJ;CAEA,MAAc,eAAe,MAA2C;EACpE,MAAM,SAAyB,CAAC;EAChC,IAAI;EAEJ,SAAS;GACL,MAAM,QAAQ,IAAI,gBAAgB,EAAE,OAAO,OAAO,UAAU,EAAE,CAAC;GAC/D,IAAI,OAAO,MAAM,IAAI,SAAS,KAAK;GAEnC,MAAM,OAAQ,MAAM,KAAK,IAAI,OAAO,WAAW,GAAG,EAAE,MAAM,CAAC;GAC3D,KAAK,MAAM,SAAS,MAAM,OAAO,KAAK;IAAE,IAAI,MAAM;IAAI,MAAM,MAAM;GAAK,CAAC;GAExE,QAAQ,KAAK,GAAG,EAAE,CAAC,EAAE;GACrB,IAAI,KAAK,SAAS,cAAc,CAAC,OAAO;EAC5C;EAEA,OAAO;CACX;CAEA,MAAc,iBAAiB,MAAkB,OAAwC;EACrF,MAAM,SAAU,MAAM,KAAK,IAAI,OAAO,oBAAoB,KAAK,CAAC;EAChE,OAAO,IAAI,IAAI,OAAO,KAAK,YAAY,QAAQ,IAAI,CAAC;CACxD;AACJ;;;;ACrLA,SAAgB,OAAO,OAAe,UAAkB,aAAa,GAAG,SAAS,IAAY;CACzF,OAAO,GAAG,MAAM,GAAG,UAAU,IAAI,WAAW;AAChD;AAEA,SAAgB,mBAAmB,MAAc,QAAyB;CACtE,OAAO,KAAK,YAAY,CAAC,CAAC,SAAS,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC;AAClE;;;;ACDA,SAAgB,aAAoB,OAA8B;CAC9D,IAAI,SAAS,KAAK,GAAG;EACjB,OAAO,YAAY;EACnB,MAAM,IAAI,cAAc,kBAAkB,YAAY;CAC1D;CACA,OAAO;AACX;;;;ACMA,MAAM,oBAAoB;AAE1B,MAAM,mBAAmB;AAEzB,eAAsB,aAAa,MAA8C;CAC7E,MAAM,UAAU,KAAK,MAAM,KAAK,UAAU;EAAE,OAAO,KAAK;EAAI,OAAO,KAAK;CAAK,EAAE;CAC/E,MAAM,WAAW,KAAK,YAAY;CAElC,IAAI,KAAK,MAAM,UAAU,kBACrB,OAAO,aAAa,MAAM,YAAoB;EAAE,SAAS,KAAK;EAAS;EAAS;EAAU,UAAU;CAAM,CAAC,CAAC;CAGhH,OAAO,aACH,MAAM,wBAAgC;EAClC,SAAS,KAAK;EACd;EACA;EACA,aAAa;EACb,SAAS,QAAQ,WACb,mBAAmB,OAAO,SAAS,IAAI,MAAM,KAAK,mBAAmB,OAAO,OAAO,KAAK,GAAG,MAAM;CACzG,CAAC,CACL;AACJ;;;;AC9BA,eAAsBC,SAAc,MAA4C;CAC5E,OAAO,aAAa,MAAMC,OAAY,IAAI,CAAC;AAC/C;AAEA,eAAsBC,UAAQ,MAAwC;CAClE,OAAO,aAAa,MAAMC,QAAa,IAAI,CAAC;AAChD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACTA,eAAe,YAAY,UAAmC;;;EAC1D,MAAM,mBAAK,gBAAgB;GAAE,OAAO,QAAQ;GAAO,QAAQ,QAAQ;EAAO,CAAC;EAC3E,OAAO,MAAM,IAAI,SAAiB,YAAY,GAAG,SAAS,UAAU,OAAO,CAAC;;;;;;AAChF;AAEA,eAAsB,aAAa,OAAe,QAAiB,MAAW,aAA+B;CACzG,OAAO,KAAK,mBAAmB,MAAM,0CAA0C;CAE/E,QAAO,MADc,IAAI,QAAQ,MAAM,oCAAoC,EAC9D,CAAC,KAAK,MAAM,OAAO,KAAK;AACzC;;;;ACGA,SAAS,aAAa,SAAkC;CACpD,MAAM,yBAAS,IAAI,IAAwB;CAC3C,KAAK,MAAM,WAAW,SAAS;EAC3B,MAAM,QAAQ,OAAO,IAAI,QAAQ,OAAO,KAAK;GAAE,WAAW,QAAQ;GAAW,UAAU,CAAC;EAAE;EAC1F,MAAM,SAAS,KAAK,OAAO;EAC3B,OAAO,IAAI,QAAQ,SAAS,KAAK;CACrC;CACA,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAC9B;AAEA,SAAS,eAAe,SAAiC;CACrD,OAAO,kBAAkB,OAAO,QAAQ,QAAQ,OAAO,EAAE,IAAI,QAAQ,KAAK,MAAM,EAAE,SAAS,CAAC,CAAC,KAAK,IAAI,EAAE;AAC5G;AAEA,SAAS,WAAW,MAAkB,SAA0D;CAyB5F,OAAO;EAvBH,eAAe;GACX,MAAM,CAAC;GACP,OAAO,6BAA6B,OAAO,KAAK,QAAQ,QAAQ,OAAO,EAAE;EAC7E;EACA,eAAe;GACX,MAAM,CAAC;GACP,OAAO,WAAW,OAAO,KAAK,mBAAmB,OAAO,EAAE;EAC9D;EACA,cAAc;GACV,MAAM,CACF,kEACA,0DACJ;GACA,OAAO;EACX;EACA,eAAe;GACX,MAAM,CACF,WAAW,OAAO,KAAK,qBAAqB,eAAe,EAAE,UAAU,OAAO,KAAK,mBAAmB,OAAO,EAAE,qCAC/G,uDACJ;GACA,OAAO;EACX;CAEU,EAAE;AACpB;;AAGA,IAAa,uBAAb,MAA4D;CACxD,MAAa,OAAc,SAAiB,MAA4B,MAA+B;EACnG,MAAM,SAAS,QAAQ;EACvB,OAAO,MAAM,OAAO;EACpB,IAAI;GACA,OAAO,MAAM,KAAK;EACtB,UAAU;GACN,OAAO,KAAK,QAAQ,OAAO;EAC/B;CACJ;CAEA,AAAO,QAAQ,MAAwB;EACnC,MAAM,OAAO,aAAa,KAAK,OAAO,CAAC,CAClC,KAAK,UAAU,GAAG,MAAM,KAAK,MAAM,SAAS,EAAE,IAAI,MAAM,SAAS,KAAK,MAAM,KAAK,EAAE,MAAM,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CACxG,KAAK,MAAM;EAChB,KAAK,MAAM,eAAe,OAAO,KAAK,QAAQ,QAAQ,eAAe,EAAE,uBAAuB;EAC9F,IAAI,KAAK,QAAQ,SAAS,GAAG,IAAI,KAAK,eAAe,KAAK,OAAO,CAAC;CACtE;CAEA,AAAO,cAAc,YAAsC;EACvD,OAAOC,UAAQ;GACX,SAAS,iBAAiB,WAAW,wCAAwC,WAAW;GACxF,cAAc;EAClB,CAAC;CACL;CAEA,AAAO,cAAc,OAAe,cAAwC;EACxE,MAAM,QAAQ,eAAe,IAAI,IAAI,OAAO,cAAc,OAAO,EAAE,uBAAuB;EAC1F,OAAOA,UAAQ;GACX,SAAS,UAAU,OAAO,OAAO,eAAe,EAAE,0BAA0B;GAC5E,cAAc;EAClB,CAAC;CACL;CAEA,AAAO,OAAO,UAAwB,SAA+B;EACjE,KAAK,MAAM,WAAW,SAAS,QAC3B,IAAI,KAAK,oBAAoB,QAAQ,QAAQ,KAAK,MAAM,QAAQ,QAAQ,UAAU,IAAI,QAAQ,OAAO,GAAG;EAE5G,IAAI,QAAQ,SAAS,GAAG,IAAI,KAAK,eAAe,OAAO,CAAC;EACxD,MAAM,WAAW,OAAO,SAAS,SAAS,eAAe,EAAE,6BAA6B;CAC5F;CAEA,AAAO,eAAe,MAAkB,SAA6B;EACjE,MAAM,QAAQ,WAAW,MAAM,OAAO;EACtC,KAAK,MAAM,QAAQ,MAAM,MAAM,IAAI,KAAK,IAAI;EAC5C,MAAM,MAAM,KAAK;CACrB;CAEA,AAAO,aAAmB;EACtB,MAAM,+BAA+B;CACzC;AACJ;;AAGA,IAAa,gBAAb,MAAqD;CAE5B;CACA;CAFrB,YACI,AAAiB,QACjB,AAAiB,KACnB;EAFmB;EACA;CAClB;CAEH,AAAO,OAAc,SAAiB,MAA4C;EAC9E,KAAK,OAAO,KAAK,OAAO;EACxB,OAAO,KAAK;CAChB;CAEA,AAAO,QAAQ,MAAwB;EACnC,KAAK,OAAO,KAAK,MAAM,KAAK,GAAG,OAAO,KAAK,QAAQ,QAAQ,eAAe,EAAE,uBAAuB,CAAC;EACpG,KAAK,MAAM,SAAS,aAAa,KAAK,OAAO,GAAG;GAC5C,KAAK,OAAO,KAAK,MAAM,IAAI,MAAM,SAAS,CAAC;GAC3C,KAAK,MAAM,WAAW,MAAM,UAAU,KAAK,OAAO,KAAK,KAAK,QAAQ,MAAM;EAC9E;EACA,KAAK,MAAM,QAAQ,KAAK,SAAS,KAAK,OAAO,KAAK,WAAW,KAAK,UAAU,IAAI,KAAK,OAAO,GAAG;CACnG;CAEA,AAAO,cAAc,YAAsC;EACvD,IAAI,KAAK,KAAK,OAAO,QAAQ,QAAQ,IAAI;EACzC,OAAO,QAAQ,OAAO,IAAI,cAAc,kBAAkB,6BAA6B,CAAC,UAAU,CAAC,CAAC;CACxG;CAGA,AAAO,cAAc,OAAe,cAAwC;EACxE,IAAI,KAAK,KAAK,OAAO,QAAQ,QAAQ,IAAI;EAEzC,IAAI,CAAC,QAAQ,MAAM,SAAS,CAAC,QAAQ,OAAO,OACxC,OAAO,QAAQ,OAAO,IAAI,cAAc,kBAAkB,qBAAqB,CAAC;EAEpF,IAAI,eAAe,GACf,KAAK,OAAO,KAAK,GAAG,OAAO,cAAc,OAAO,EAAE,yCAAyC;EAC/F,OAAO,aAAa,OAAO,KAAK,MAAM;CAC1C;CAEA,AAAO,OAAO,UAAwB,SAA+B;EACjE,KAAK,MAAM,WAAW,SAAS,QAC3B,KAAK,OAAO,KACR,oBAAoB,QAAQ,QAAQ,KAAK,MAAM,QAAQ,QAAQ,UAAU,IAAI,QAAQ,OAAO,GAChG;EAEJ,IAAI,QAAQ,SAAS,GAAG,KAAK,OAAO,KAAK,eAAe,OAAO,CAAC;EAChE,KAAK,OAAO,KACR,MAAM,KAAK,WAAW,OAAO,SAAS,SAAS,eAAe,EAAE,6BAA6B,CACjG;CACJ;CAEA,AAAO,eAAe,MAAkB,SAA6B;EACjE,MAAM,QAAQ,WAAW,MAAM,OAAO;EACtC,KAAK,MAAM,QAAQ,MAAM,MAAM,KAAK,OAAO,KAAK,IAAI;EACpD,KAAK,OAAO,KAAK,MAAM,KAAK,MAAM,KAAK,CAAC;CAC5C;CAEA,AAAO,aAAmB;EACtB,KAAK,OAAO,KAAK,MAAM,OAAO,mDAAmD,CAAC;CACtF;AACJ;;;;ACpJA,MAAa,sBAAsB;AAInC,SAAgB,aAAa,MAAkB,OAA8B;CACzE,IAAI,KAAK,sBAAsB,KAAK,KAAK,QAAQ,SAAS,GAAG,OAAO;CACpE,IAAI,KAAK,wBAAwB,GAAG,OAAO;CAC3C,IAAI,CAAC,SAAS,KAAK,uBAAuB,GAAG,OAAO;CACpD,OAAO;AACX;;AAGA,eAAsB,aAAa,SAAsC;CACrE,MAAM,EAAE,QAAQ,OAAO,OAAO,OAAO,WAAW,gBAAgB;CAEhE,MAAM,EAAE,OAAO,WAAW,MAAM,UAAU,OACtC,gCACM,OAAO,eAAe,OAAO,KAAK,GACxC,uBACJ;CAEA,IAAI,MAAM,aAAa,OAAO,gBAAgC,CAAE,MAAM,UAAU,cAAc,OAAO,MAAM,GACvG;CAEJ,MAAM,OAAO,MAAM,UAAU,OACzB,YAAY,OAAO,OAAO,QAAQ,OAAO,EAAE,uBACrC,OAAO,WAAW,OAAO,OAAO,aAAa,QAAQ,WAAW,GAAG,MAAM,KAAK,GACpF,WAAW,OAAO,OAAO,QAAQ,OAAO,EAAE,EAC9C;CAEA,IAAI,KAAK,QAAQ,WAAW,GAAG;EAC3B,UAAU,eAAe,MAAM,aAAa,MAAM,MAAM,KAAK,CAAC;EAC9D;CACJ;CAEA,UAAU,QAAQ,IAAI;CAEtB,IAAI,CAAC,OAAO;EACR,UAAU,WAAW;EACrB;CACJ;CAEA,IAAI,CAAE,MAAM,UAAU,cAAc,KAAK,QAAQ,QAAQ,KAAK,QAAQ,MAAM,GAAI;CAEhF,MAAM,WAAW,MAAM,UAAU,OAC7B,YAAY,OAAO,KAAK,QAAQ,QAAQ,eAAe,EAAE,UACnD,OAAO,eAAe,OAAO,OAAO,KAAK,OAAO,GACtD,oBACJ;CACA,UAAU,OAAO,UAAU,KAAK,OAAO;AAC3C;AAEA,SAAS,aAAa,QAAwB,aAA8C;CACxF,IAAI,CAAC,aAAa,QAAQ,OAAO;CACjC,MAAM,QAAQ,IAAI,IAAI,YAAY,KAAK,UAAU,CAAC,MAAM,IAAI,MAAM,IAAI,CAAC,CAAC;CACxE,OAAO,OAAO,KAAK,WAAW;EAAE,IAAI,MAAM;EAAI,MAAM,MAAM,IAAI,MAAM,EAAE,KAAK,MAAM;CAAK,EAAE;AAC5F;;;;ACnEA,eAAsB,kBAClB,QACA,OACA,OACA,QACa;CACb,MAAM,aAAa;EACf;EACA,OAAO;GAAE,UAAU,MAAM;GAAU,WAAW,MAAM;GAAW,OAAO,MAAM;EAAM;EAClF,OAAO,MAAM;EACb;EACA,WAAW,IAAI,cAAc,QAAQ,MAAM,GAAG;CAClD,CAAC;AACL;;;;ACdA,eAAsB,eAAe,QAAqB,OAA8B;CACpF,MAAM,mBAAmB;CAEzB,MAAM,OAAO,MAAM,WAAW,QAAQ,KAAK;CAC3C,IAAI,CAAC,MAAM;CAEX,MAAM,aAAa;EACf;EACA,OAAO,KAAK;EACZ,OAAO;EACP;EACA,WAAW,IAAI,qBAAqB;EACpC,aAAa,KAAK;CACtB,CAAC;AACL;AAEA,eAAe,WAAW,QAAqB,OAA+C;CAc1F,IAAI,MAbiBC,SAAO;EACxB,SAAS;EACT,SAAS,CACL;GAAE,OAAO;GAAQ,OAAO;EAAuB,GAC/C;GACI,OAAO;GACP,OAAO;GACP,MAAM;EACV,CACJ;CACJ,CAAC,MAGc,OAAO,OAAO,EAAE,OAAO;EAAE,UAAU,CAAC;EAAG,WAAW;EAAM,OAAO;CAAM,EAAE;CAEtF,MAAM,SAAS,QAAQ;CACvB,OAAO,MAAM,oCAAoC;CACjD,IAAI;CACJ,IAAI;EACA,SAAS,MAAM,OAAO,cAAc,KAAK;CAC7C,SAAS,OAAO;EACZ,OAAO,KAAK,iCAAiC;EAC7C,MAAM;CACV;CACA,OAAO,KAAK,SAAS,OAAO,OAAO,QAAQ,OAAO,EAAE,EAAE;CAEtD,IAAI,OAAO,WAAW,GAAG;EACrB,MAAM,0BAA0B;EAChC;CACJ;CAEA,IAAI;CACJ,IAAI,OAAO,SAAS,GAAG;EACnB,WAAW,MAAM,aAAa;GAAE,SAAS;GAA0B,OAAO;EAAO,CAAC;EAClF,IAAI,SAAS,WAAW,GAAG;GACvB,MAAM,qBAAqB;GAC3B;EACJ;CACJ,OAAO;EACH,MAAM,OAAO,OAAO;EACpB,IAAI,CAAC,MAAM,OAAO;EAClB,WAAW,CAAC,KAAK,EAAE;EACnB,IAAI,KAAK,yBAAyB,KAAK,KAAK,EAAE;CAClD;CAEA,MAAM,OAAO,MAAMA,SAAO;EACtB,SAAS;EACT,SAAS,CACL;GAAE,OAAO;GAAW,OAAO;EAAoD,GAC/E;GAAE,OAAO;GAAS,OAAO;EAA6C,CAC1E;CACJ,CAAC;CAED,OAAO;EAAE,OAAO;GAAE;GAAU,WAAW;GAAO,OAAO,SAAS;EAAQ;EAAG,aAAa;CAAO;AACjG;;;;AC9DA,SAAgB,cAAc,SAAmC;CAC7D,OAAO;EAAC,QAAQ;EAAO,QAAQ;EAAW,QAAQ;EAAO,QAAQ;CAAK,CAAC,CAAC,KAAK,OAAO,KAAK,QAAQ,MAAM,SAAS;AACpH;AAEA,IAAa,kBAAb,cAAqC,YAAY;CAC7C,AAAiB;CAEjB,cAAc;EACV,MAAM,YAAY,6CAA6C,UAAU;EACzE,KAAK,cAAc,YAAY,OAAO;CAC1C;CAEA,AAAO,SAAS,SAAwB;EACpC,QACK,QAAQ,KAAK,IAAI,CAAC,CAClB,YAAY,KAAK,WAAW,CAAC,CAC7B,OAAO,WAAW,mFAAmF,CAAC,CACtG,OAAO,oBAAoB,sBAAsB,CAAC,CAClD,OAAO,gBAAgB,6EAA6E,CAAC,CACrG,OAAO,WAAW,2DAA2D,CAAC,CAC9E,OAAO,WAAW,oEAAoE,CAAC,CACvF,OAAO,SAAS,+DAA+D,CAAC,CAChF,OAAO,OAAO,YACX,KAAK,IAAI;GACL,OAAO,QAAQ,SAAS;GACxB,OAAO,QAAQ,SAAS,CAAC;GACzB,WAAW,QAAQ,aAAa;GAChC,OAAO,QAAQ,SAAS;GACxB,OAAO,QAAQ,SAAS;GACxB,KAAK,QAAQ,OAAO;EACxB,CAAC,CACL;CACR;CAEA,MAAc,IAAI,SAAyC;EACvD,IAAI;GACA,MAAM,KAAK,SAAS,OAAO;EAC/B,SAAS,OAAgB;GAErB,IAAI,gBAAgB,OAAO,iBAAiB,kBAAkB,YAAY,GAAG;GAE7E,KAAK,OAAO,MAAM,4BAA4B,KAAK;GACnD,IAAI,gBAAgB,KAAK,GAAG,QAAQ,WAAW;QAC1C,QAAQ,KAAK,CAAC;EACvB;CACJ;CAEA,MAAc,SAAS,SAAyC;EAC5D,MAAM,QAAQ,cAAc,OAAO;EACnC,MAAM,cAAc,cAAc,SAAS,KAAK;EAEhD,IAAI,CAAC,eAAe,CAAC,OAAO;GACxB,KAAK,OAAO,KAAK,2DAA2D;GAC5E;EACJ;EAEA,MAAM,QAAQ,qBAAqB,SAAS,IAAI,mBAAmB,CAAC;EAEpE,IAAI,aAAa;GACb,MAAM,eAAe,KAAK,aAAa,KAAK;GAC5C;EACJ;EAEA,MAAM,kBACF,KAAK,aACL;GACI,UAAU,QAAQ;GAClB,WAAW,QAAQ;GACnB,OAAO,QAAQ;GACf,OAAO,QAAQ;GACf,KAAK,QAAQ;EACjB,GACA,OACA,KAAK,MACT;CACJ;AACJ;;;;AC3FA,SAAgB,OAAqB;CACjC,OACI,oCAAC,KAAD;EACI,YAAY;EACZ,aAAY;EACZ;EACA,cAAc;EACd,YAAY;EACZ,aAAa;EACb;CACH;AAET;;;;ACVA,MAAa,iBAA+B;CAAE,OAAO;CAAY,UAAU;CAAG,QAAQ;AAAE;AAExF,SAAgB,WACZ,QACA,MACA,cACA,YACY;CACZ,IAAI,SAAS,UACT,OAAO;EAAE,GAAG;EAAQ,OAAO,OAAO,UAAU,aAAa,WAAW;CAAW;CAGnF,MAAM,QAAQ,OAAO,UAAU,aAAa,eAAe;CAC3D,IAAI,UAAU,GAAG,OAAO;CAExB,MAAM,QAAQ,OAAO,UAAU,aAAa,OAAO,WAAW,OAAO;CACrE,MAAM,OAAO,SAAS,WAAW,QAAQ,KAAK,SAAS,QAAQ,QAAQ,KAAK;CAC5E,OAAO,OAAO,UAAU,aAAa;EAAE,GAAG;EAAQ,UAAU;CAAK,IAAI;EAAE,GAAG;EAAQ,QAAQ;CAAK;AACnG;AAGA,SAAgB,UAAU,QAA6B,OAAoB,OAA8B;CACrG,IAAI,QAAQ,UAAU,SAAS,UAAU,GAAG,OAAO;CACnD,QAAQ,UAAU,aAAa,OAAO,WAAW,OAAO,UAAU;AACtE;;;;AC7BA,SAAgB,YAAY,OAA2B;CACnD,MAAM,YAAY,aACb,aAAyB;EACtB,MAAM,GAAG,UAAU,QAAQ;EAC3B,aAAa;GACT,MAAM,IAAI,UAAU,QAAQ;EAChC;CACJ,GACA,CAAC,KAAK,CACV;CACA,MAAM,cAAc,kBAAkB,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC;CAC/D,OAAO,qBAAqB,WAAW,WAAW;AACtD;;;;ACCA,MAAM,cAAc;AAOpB,MAAM,qBAAqB;AAG3B,MAAM,MAAM,OAAO,aAAa,EAAE;AAElC,IAAa,WAAb,MAAa,iBAAiB,kBAAsD;CAChF,OAAe,YAA6B;CAE5C,AAAgB,OAAO;CAEvB,AAAQ,UAAsB,CAAC;CAC/B,AAAQ,SAAqB,CAAC;CAC9B,AAAQ,SAAS;CACjB,AAAQ,aAAmC;CAC3C,AAAQ,gBAAgB;CACxB,AAAQ,aAAmD;CAC3D,AAAiB,WAAW;CAC5B,AAAiB,kBAAkB;CAEnC,AAAQ,cAAc;EAClB,MAAM;CACV;CAEA,WAAkB,WAAqB;EACnC,SAAS,cAAc,IAAI,SAAS;EACpC,OAAO,SAAS;CACpB;CAEA,AAAO,QAAc;EACjB,IAAI,KAAK,YAAY;EACrB,KAAK,aAAa,sBAAsB,SAAS,YAAY,MAAM,EAC/D,aAAa,KACjB,CAAC;CACL;CAEA,AAAO,UAAgB;EACnB,IAAI,CAAC,KAAK,YAAY;EACtB,KAAK,WAAW,QAAQ;EACxB,KAAK,aAAa;CACtB;CAEA,AAAO,MAAM,QAAyB;EAGlC,MAAM,QAAQ,WAAW,MAAM,CAAC,CAAC,MAAM,YAAY;EAEnD,KAAK,MAAM,CAAC,OAAO,SAAS,MAAM,QAAQ,GAAG;GACzC,MAAM,OAAO,KAAK,WAAW,aAAa,SAAU,SAAS,MAAM,OAAO,EAAG;GAC7E,KAAK,OAAO,KAAK;IACb,IAAI,KAAK;IACT,SAAS,OAAO;IAChB,OAAO,OAAO;IACd,OAAO,OAAO;IACd,MAAM,UAAU;IAChB,OAAO,QAAQ,KAAK,YAAY,KAAK,IAAI;IACzC;IACA,WAAW,OAAO;GACtB,CAAC;EACL;EAEA,KAAK,eAAe;CACxB;CAGA,AAAO,UAA+B;EAClC,OAAO,KAAK;CAChB;CAGA,AAAO,cAAiC;EACpC,MAAM,uBAAO,IAAI,IAAY;EAC7B,KAAK,MAAM,SAAS,KAAK,SAAS,KAAK,IAAI,MAAM,OAAO;EACxD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK;CAC1B;CAEA,AAAO,gBAAwB;EAC3B,IAAI,QAAQ;EACZ,KAAK,MAAM,SAAS,KAAK,SAAS,IAAI,MAAM,MAAM,SAAS,OAAO,QAAQ,MAAM,MAAM;EACtF,OAAO,KAAK,IAAI,OAAO,KAAK,eAAe;CAC/C;CAEA,AAAO,QAAc;EACjB,KAAK,UAAU,CAAC;EAChB,KAAK,SAAS,CAAC;EACf,KAAK,KAAK,QAAQ;CACtB;CAGA,MAAa,QAAuB;EAChC,IAAI,KAAK,YAAY;GACjB,aAAa,KAAK,UAAU;GAC5B,KAAK,aAAa;EACtB;EACA,KAAK,YAAY;EACjB,MAAM,IAAI,SAAe,YAAY,aAAa,OAAO,CAAC;CAC9D;CAEA,AAAQ,iBAAuB;EAC3B,IAAI,KAAK,eAAe;EACxB,KAAK,gBAAgB;EACrB,KAAK,aAAa,iBAAiB,KAAK,YAAY,GAAG,kBAAkB;CAC7E;CAEA,AAAQ,cAAoB;EACxB,KAAK,aAAa;EAClB,KAAK,gBAAgB;EACrB,IAAI,KAAK,OAAO,WAAW,GAAG;EAE9B,MAAM,aAAa,CAAC,GAAG,KAAK,SAAS,GAAG,KAAK,MAAM;EACnD,KAAK,SAAS,CAAC;EACf,KAAK,UAAU,WAAW,SAAS,KAAK,WAAW,WAAW,MAAM,CAAC,KAAK,QAAQ,IAAI;EAEtF,KAAK,KAAK,QAAQ;CACtB;AACJ;;;;ACnIA,MAAM,iCAAsC,IAAI,IAAI;AACpD,MAAM,+BAAsC,IAAI,IAAI;AAGpD,SAAgB,WACZ,MACA,UACA,QACmB;CACnB,MAAM,cAAc,SAAS,SAAS;CACtC,MAAM,YAAY,OAAO,SAAS;CAClC,IAAI,eAAe,WAAW,OAAO;CACrC,OAAO,KAAK,QAAQ,SAAS,eAAe,SAAS,IAAI,IAAI,OAAO,OAAO,aAAa,OAAO,IAAI,IAAI,KAAK,EAAE;AAClH;AAIA,SAAgB,QAAQ,UAAgC,QAAqD;CACzG,MAAM,QAAQ,SAAS;CAEvB,MAAM,YAAY,aACb,OAAmB;EAChB,MAAM,GAAG,UAAU,EAAE;EACrB,aAAa;GACT,MAAM,IAAI,UAAU,EAAE;EAC1B;CACJ,GACA,CAAC,KAAK,CACV;CAEA,MAAM,cAAc,kBAAkB,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC;CAE9D,MAAM,UAAU,qBAAqB,WAAW,WAAW;CAE3D,OAAO,cACG,WAAW,SAAS,YAAY,gBAAgB,UAAU,YAAY,GAC5E;EAAC;EAAS;EAAU;CAAM,CAC9B;AACJ;;;;AClCA,MAAM,aAA0B;CAAE,OAAO;CAAG,QAAQ;AAAE;AAEtD,SAAgB,eAAe,KAAgD;CAC3E,MAAM,CAAC,KAAK,UAAU,SAAsB,UAAU;CAGtD,sBAAsB;EAClB,IAAI,CAAC,IAAI,SAAS;EAClB,MAAM,EAAE,OAAO,WAAW,eAAe,IAAI,OAAO;EAEpD,QAAQ,SAAU,KAAK,UAAU,SAAS,KAAK,WAAW,SAAS,OAAO;GAAE;GAAO;EAAO,CAAE;CAChG,CAAC;CAED,OAAO;AACX;;;;ACjBA,SAAgB,aACZ,SACA,OACA,MACA,SACa;CACb,MAAM,CAAC,WAAW,gBAAgB,SAAwB,IAAI;CAC9D,MAAM,kBAAkB,OAAO,IAAI;CAEnC,sBAAsB;EAClB,IAAI,UAAU,WAAW;GACrB,gBAAgB,UAAU;GAG1B,aAAa,IAAI;GACjB;EACJ;EACA,IAAI,CAAC,gBAAgB,WAAW,CAAC,QAAQ,SAAS;EAClD,MAAM,WAAW,eAAe,QAAQ,OAAO,CAAC,CAAC;EACjD,IAAI,WAAW,GAAG;GACd,gBAAgB,UAAU;GAE1B,aAAa,QAAQ;EACzB;CACJ,GAAG;EAAC;EAAM;EAAS;EAAO;CAAO,CAAC;CAElC,OAAO;AACX;;;;ACJA,SAAgB,kBACZ,OACA,gBACA,QACA,QACgB;CAChB,MAAM,SAAS,KAAK,IAAI,GAAG,cAAc;CACzC,MAAM,MAAM,MAAM;CAClB,MAAM,SAAS,KAAK,IAAI,GAAG,MAAM,MAAM;CAEvC,IAAI;CACJ,IAAI,WAAW,MACX,WAAW;MACR;EACH,MAAM,QAAQ,MAAM,WAAW,SAAS,OAAO,IAAI,MAAM,MAAM;EAC/D,WAAW,UAAU,KAAK,IAAI;CAClC;CACA,WAAW,KAAK,IAAI,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM;CAEjD,MAAM,UAAU,MAAM,MAAM,UAAU,WAAW,MAAM;CACvD,OAAO;EACH;EACA;EACA,WAAW,WAAW,QAAQ,YAAY;EAC1C,OAAO,aAAa;EACpB,OAAO;EACP,OAAO,OAAO,WAAW,QAAQ;CACrC;AACJ;AAEA,SAAgB,UACZ,OACA,gBACA,QACe;CACf,MAAM,CAAC,QAAQ,aAAa,SAA2B,IAAI;CAE3D,MAAM,SAAS,KAAK,IAAI,GAAG,cAAc;CACzC,MAAM,SAAS,KAAK,IAAI,GAAG,MAAM,SAAS,MAAM;CAChD,MAAM,OAAO,kBAAkB,OAAO,gBAAgB,QAAQ,MAAM;CAEpE,MAAM,YAAY,YAA0B;EACxC,MAAM,UAAU,KAAK,IAAI,KAAK,IAAI,GAAG,OAAO,GAAG,MAAM;EACrD,IAAI,WAAW,QAAQ;GACnB,UAAU,IAAI;GACd;EACJ;EACA,MAAM,QAAQ,MAAM;EACpB,UAAU,UAAU,SAAY,OAAO,OAAO,KAAK,CAAC;CACxD;CAEA,MAAM,MAAM,QAAQ,MAAY,SAAS,KAAK,WAAW,KAAK;CAC9D,MAAM,QAAQ,QAAQ,MAAY,SAAS,KAAK,WAAW,KAAK;CAEhE,OAAO;EACH,SAAS,KAAK;EACd,WAAW,KAAK;EAChB,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ;EACA;EACA,cAAc,GAAG,SAAS,CAAC;EAC3B,gBAAgB,KAAK,SAAS,CAAC;EAC/B,aAAa;GACT,MAAM,SAAS,MAAM;GACrB,UAAU,WAAW,SAAY,OAAO,OAAO,MAAM,CAAC;EAC1D;EACA,gBAAgB,UAAU,IAAI;CAClC;AACJ;;;;ACnGA,MAAa,KAAK;CACd,QAAQ;CACR,OAAO;CACP,OAAO;CACP,MAAM;CACN,MAAM;CACN,KAAK;AACT;;;;ACFA,SAAgB,cAAc,OAA0B;CACpD,OAAO,UAAU,aAAa,UAAU;AAC5C;AAGA,SAAgB,YAAY,OAA0B;CAClD,OAAO,UAAU,cAAc,UAAU,aAAa,UAAU;AACpE;AAYA,MAAa,aAAa;CACtB,UAAU;EAAE,OAAO;EAAY,MAAM;EAAK,OAAO,GAAG;EAAQ,MAAM;CAAU;CAC5E,SAAS;EAAE,OAAO;EAAW,MAAM;EAAK,OAAO,GAAG;EAAM,MAAM;CAAM;CACpE,oBAAoB;EAAE,OAAO;EAAoB,MAAM;EAAK,OAAO,GAAG;EAAM,MAAM;CAAS;CAC3F,cAAc;EAAE,OAAO;EAAW,MAAM;EAAK,OAAO,GAAG;EAAO,MAAM;CAAS;CAC7E,OAAO;EAAE,OAAO;EAAS,MAAM;EAAK,OAAO,GAAG;EAAK,MAAM;CAAS;CAClE,UAAU;EAAE,OAAO;EAAY,MAAM;EAAK,OAAO,GAAG;EAAO,MAAM;CAAU;AAC/E;;;;AC3BA,MAAM,UAAU;AAGhB,SAAgB,UAAU,OAAiB,OAA+B;CACtE,MAAM,SAAS,cAAc,MAAM,KAAK,KAAK;CAC7C,MAAM,EAAE,SAAS,aAAa;EAAE,UAAU;EAAS,UAAU;CAAO,CAAC;CACrE,OAAO,SAAS,OAAO;AAC3B;;;;ACZA,MAAM,UAAU;CACZ;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ;AAEA,MAAM,2BAAW,IAAI,IAAoB;AAEzC,SAAgB,aAAa,SAAyB;CAClD,MAAM,WAAW,SAAS,IAAI,OAAO;CACrC,IAAI,aAAa,QAAW,OAAO;CAEnC,MAAM,QAAQ,QAAQ,SAAS,OAAO,QAAQ,WAAW,QAAQ;CACjE,SAAS,IAAI,SAAS,KAAK;CAC3B,OAAO;AACX;AAGA,SAAgB,qBAA2B;CACvC,SAAS,MAAM;AACnB;;;;AC1BA,MAAa,gBAAqC;CAAC;CAAS;CAAQ;CAAQ;CAAS;AAAO;AAU5F,SAAS,QAAQ,EAAE,OAAO,QAAwD;CAC9E,OACI,oCAAC,YACG,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAQ;CAElB,GADD,OAAO,MAAM,GACZ,GACN,oCAAC,MAAD,EAAM,OAAO,GAAG,MAAqB,GAAd,KAAE,KAAY,CACnC;AAEd;AAEA,SAASC,OAAK,EACV,OACA,IACA,OACA,WAMa;CACb,OACI,oCAAC,KAAD,EAAK,aAAa,EAUb,GATA,KACG,oCAAC,MAAD;EAAa;EAAO,MAAM;EAAS,WAAW;CAExC,GADD,KACC,IAEN,oCAAC,MAAD;EAAM;EAAS,MAAM;EAAS,WAAW;CAEnC,GADD,KACC,CAET;AAEb;AAEA,SAAgB,YAAY,EACxB,UACA,iBACA,eACA,QACA,QAC+B;CAC/B,MAAM,cAAc,gBAAgB,SAAS;CAC7C,MAAM,YAAY,cAAc,SAAS;CACzC,MAAM,eAAe,UAAU,QAAQ,YAAY,SAAS,MAAM;CAClE,MAAM,aAAa,UAAU,QAAQ,UAAU,cAAc,MAAM;CAEnE,OACI,oCAAC,KAAD,EAAK,eAAc,SAmCd,GAlCA,OAAO,OACJ,oCAAC,MAAD;EAAM;EAAS,MAAK;CAEd,GAFyB,uBAEzB,GAEV,oCAAC,SAAD;EAAS,OAAM;EAAiB;CAAO,IACtC,OACG,oCAAC,KAAD;EAAK,YAAY;EAAG,UAAS;CAUxB,GATA,SAAS,KAAK,SAAS,UACpB,oCAACA,QAAD;EACI,KAAK;EACL,OAAO;EACP,IAAI,eAAe,gBAAgB,IAAI,OAAO;EAC9C,OAAO,aAAa,OAAO;EAC3B,SAAS,iBAAiB;CAC7B,EACJ,CACA,IACL,MAEJ,oCAAC,SAAD;EAAS,OAAM;EAAe;CAAO,IACpC,OACG,oCAAC,KAAD;EAAK,YAAY;EAAG,UAAS;CAUxB,GATA,cAAc,KAAK,OAAO,UACvB,oCAACA,QAAD;EACI,KAAK;EACL,OAAO;EACP,IAAI,aAAa,cAAc,IAAI,KAAK;EACxC,OAAO,YAAY;EACnB,SAAS,eAAe;CAC3B,EACJ,CACA,IACL,IACH;AAEb;;;;AChGA,SAAS,cAAc,MAA2B,SAAiB,KAA6C;CAC5G,MAAM,OAAO,KAAK,SAAS,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI;CAC1D,IAAI,KAAK,IAAI,OAAO,GAAG,KAAK,OAAO,OAAO;MACrC,KAAK,IAAI,OAAO;CACrB,OAAO,KAAK,SAAS,IAAI,yBAAS,IAAI,IAAY,IAAI;AAC1D;AAEA,SAAS,YAAY,MAA6B,OAAwC;CACtF,MAAM,OAAO,KAAK,SAAS,IAAI,IAAI,IAAI,aAAa,IAAI,IAAI,IAAI,IAAI;CACpE,IAAI,KAAK,IAAI,KAAK,GAAG,KAAK,OAAO,KAAK;MACjC,KAAK,IAAI,KAAK;CACnB,OAAO,KAAK,SAAS,cAAc,yBAAS,IAAI,IAAc,IAAI;AACtE;AAGA,SAAS,YAAY,MAA2B,SAAsC;CAClF,OAAO,KAAK,SAAS,KAAK,KAAK,IAAI,OAAO,oBAAI,IAAI,IAAY,oBAAI,IAAI,IAAI,CAAC,OAAO,CAAC;AACvF;AAEA,SAAS,UAAU,MAA6B,OAAwC;CACpF,OAAO,KAAK,SAAS,KAAK,KAAK,IAAI,KAAK,oBAAI,IAAI,IAAc,oBAAI,IAAI,IAAI,CAAC,KAAK,CAAC;AACrF;AAsBA,SAAS,KAAK,KAA0B;CACpC,IAAI,MAAM,UAAU;CACpB,AAAK,IAAI,SAAS;AACtB;AAGA,SAAS,iBAAiB,KAA6B;CACnD,IAAI,CAAC,IAAI,IAAI,QAAQ,IAAI,UAAU,KAAK,OAAO;CAE/C,IAAI,IAAI,MAAM,WAAW,KAAK,GAAG;MAC5B,IAAI,MAAM,aAAa,IAAI;CAChC,OAAO;AACX;AAEA,SAAS,aAAa,KAA6B;CAC/C,IAAI,CAAC,IAAI,MAAM,qBAAqB,OAAO;CAC3C,IAAI,IAAI,UAAU,KAAK;EACnB,AAAK,IAAI,oBAAoB,IAAI;EACjC,IAAI,MAAM,YAAY;CAC1B,OAAO,IAAI,IAAI,UAAU,KAAK;EAC1B,AAAK,IAAI,oBAAoB,KAAK;EAClC,IAAI,MAAM,YAAY;CAC1B;CACA,OAAO;AACX;AAEA,SAAS,cACL,KACA,UACA,WACA,SACI;CACJ,IAAI,IAAI,OAAO,UAAU,YAAY;EACjC,MAAM,QAAQ,UAAU,IAAI,QAAQ,YAAY,SAAS,MAAM;EAC/D,MAAM,UAAU,UAAU,OAAO,SAAY,SAAS;EACtD,IAAI,YAAY,QAAW,IAAI,WAAW,UAAU,IAAI,SAAS,SAAS,QAAQ,CAAC;EACnF;CACJ;CACA,MAAM,QAAQ,UAAU,IAAI,QAAQ,UAAU,cAAc,MAAM;CAClE,MAAM,QAAQ,UAAU,OAAO,SAAY,cAAc;CACzD,IAAI,UAAU,QAAW,IAAI,iBAAiB,QAAQ,IAAI,eAAe,KAAK,CAAC;AACnF;AAEA,SAAS,cAAc,KAA6B;CAChD,IAAI,CAAC,IAAI,aAAa,OAAO;CAE7B,MAAM,WAAW,SAAS,SAAS,YAAY;CAC/C,MAAM,QAAQ,QACV,IAAI,UAAU,WAAW,IAAI,QAAQ,KAAK,SAAS,QAAQ,cAAc,MAAM,CAAC;CAEpF,IAAI,IAAI,IAAI,WAAW,KAAK,MAAM;MAC7B,IAAI,IAAI,IAAI,YAAY,KAAK,OAAO;MACpC,IAAI,IAAI,IAAI,KAAK,KAAK,QAAQ;MAC9B,IAAI,IAAI,UAAU,KAAK,cAAc,KAAK,UAAU,aAAa,SAAS;MAC1E,IAAI,IAAI,UAAU,KAAK,cAAc,KAAK,UAAU,eAAe,WAAW;MAC9E,OAAO;CACZ,OAAO;AACX;AAEA,SAAS,aAAa,KAA6B;CAE/C,MAAM,EAAE,KAAK,OAAO,WAAW;CAC/B,IAAI,IAAI,SAAS,OAAO,GAAG;MACtB,IAAI,IAAI,WAAW,OAAO,KAAK;MAC/B,IAAI,IAAI,QAAQ,OAAO,OAAO;MAC9B,IAAI,IAAI,UAAU,OAAO,SAAS;MAClC,IAAI,IAAI,QAAQ,UAAU,KAAK,OAAO,MAAM;MAC5C,IAAI,IAAI,OAAO,UAAU,KAAK,OAAO,SAAS;MAC9C,OAAO;CACZ,OAAO;AACX;AAEA,SAAS,cAAc,KAA0B;CAC7C,MAAM,EAAE,OAAO,OAAO,UAAU;CAEhC,IAAI,UAAU,KAAK;EACf,KAAK,GAAG;EACR;CACJ;CACA,IAAI,CAAC,IAAI,aAAa;CAEtB,QAAQ,OAAR;EACI,KAAK;GACD,IAAI,CAAC,cAAc,MAAM,KAAK,GAAG;GACjC,MAAM,gBAAgB;GACtB,AAAK,IAAI,eAAe;GAExB;EAEJ,KAAK;GACD,MAAM,aAAa;GACnB,AAAK,IAAI,YAAY;GAErB;EAEJ,KAAK;GACD,SAAS,SAAS,MAAM;GACxB,IAAI,OAAO,SAAS;CAK5B;AACJ;AAGA,SAAgB,eAAe,KAA0B;CACrD,IAAI,iBAAiB,GAAG,GAAG;CAC3B,IAAI,IAAI,MAAM,WAAW,IAAI,MAAM,aAAa,KAAK;CACrD,IAAI,aAAa,GAAG,GAAG;CACvB,IAAI,cAAc,GAAG,GAAG;CACxB,IAAI,aAAa,GAAG,GAAG;CACvB,cAAc,GAAG;AACrB;;;;AC7JA,SAAgB,UAAU,EAAE,WAAW,SAA8C;CACjF,IAAI,WAAW,OAAO;CACtB,OACI,oCAAC,KAAD,EAAK,YAAY,EAEZ,GADD,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAM,MAAK;CAAoE,GAAxD,gBAAgB,MAAM,2BAAkC,CAC9F;AAEb;;;;ACTA,SAAgB,kBAAkB,EAAE,WAAwD;CACxF,IAAI,QAAQ,WAAW,GAAG,OAAO;CAEjC,OACI,oCAAC,KAAD;EAAK,YAAY;EAAG,eAAc;CAI7B,GAHA,QAAQ,KAAK,WACV,oCAAC,UAAD,EAAU,KAAK,OAAO,IAA4B,GAAtB,OAAO,IAAe,CACrD,CACA;AAEb;;;;ACpBA,MAAMC,kBAAgB;AACtB,MAAM,qBAAqB;AAC3B,MAAM,mBAAmB;AAEzB,SAAS,IAAI,OAAuB;CAChC,OAAO,MAAM,SAAS,CAAC,CAAC,SAAS,GAAG,GAAG;AAC3C;AAEA,SAAgB,aAAa,IAAoB;CAC7C,MAAM,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,KAAKA,eAAa,CAAC;CAC/D,MAAM,UAAU,eAAe;CAC/B,MAAM,eAAe,KAAK,MAAM,eAAe,kBAAkB;CACjE,MAAM,UAAU,eAAe;CAC/B,MAAM,QAAQ,KAAK,MAAM,eAAe,gBAAgB;CAExD,IAAI,QAAQ,GAAG,OAAO,GAAG,MAAM,IAAI,IAAI,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE;CACjE,IAAI,UAAU,GAAG,OAAO,GAAG,QAAQ,IAAI,IAAI,OAAO,EAAE;CACpD,OAAO,GAAG,QAAQ;AACtB;AAGA,SAAgB,YAAY,IAAoB;CAC5C,MAAM,IAAI,IAAI,KAAK,EAAE;CACrB,OAAO,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,CAAC;AAC5E;;;;AClBA,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,iBAAiB;AAEvB,MAAa,iBAAiB,eAC1B,KAAkC,aAAa,IAAI,YAAY;AAMnE,SAAS,YAAY,OAAsC;CACvD,OAAO,UAAU,UAAa,MAAM,UAAU;AAClD;AAEA,SAAS,WAAW,MAA2B,OAAwB;CACnE,MAAM,MAAM,KAAK;CACjB,MAAM,OAAO,KAAK,QAAQ;CAC1B,OAAO,KAAK,SAAS,QAAQ,YAAY,GAAG,KAAK,SAAS,UAAa,CAAC,KAAK,QAAQ,YAAY,IAAI;AACzG;AAEA,SAAS,YAAY,MAA2B,OAAwB;CACpE,MAAM,MAAM,KAAK;CACjB,MAAM,OAAO,KAAK,QAAQ;CAC1B,OAAO,QAAQ,UAAa,CAAC,IAAI,QAAQ,YAAY,GAAG,MAAM,SAAS,UAAa,KAAK;AAC7F;AAGA,SAAS,gBAAgB,MAA2B,OAAwB;CACxE,MAAM,OAAO,KAAK,QAAQ;CAC1B,OAAO,SAAS,UAAa,CAAC,KAAK,QAAQ,YAAY,IAAI;AAC/D;AAEA,SAAgB,WAAW,MAAqC;CAC5D,MAAM,OAAiB,CAAC;CACxB,KAAK,MAAM,CAAC,OAAO,UAAU,KAAK,QAAQ,GAAG;EACzC,IAAI,WAAW,MAAM,KAAK,KAAK,CAAC,gBAAgB,MAAM,KAAK,GACvD,KAAK,KAAK;GAAE,MAAM;GAAQ,KAAK,OAAO,MAAM;EAAK,CAAC;EAEtD,KAAK,KAAK;GAAE,MAAM;GAAS,KAAK,OAAO,MAAM,EAAE;GAAG;GAAO,MAAM,MAAM;GAAM,OAAO;EAAK,CAAC;EACxF,IAAI,YAAY,MAAM,KAAK,GAAG,KAAK,KAAK;GAAE,MAAM;GAAQ,KAAK,UAAU,MAAM;EAAK,CAAC;CACvF;CACA,OAAO;AACX;AAGA,SAAS,UAAU,OAAiB,OAAe,YAA4B;CAE3E,OAAO,SADQ,CAAC,MAAM,QAAQ,MAAM,UAAU,UAAU,YAAY,cAAc,UAAU;AAEhG;AAEA,SAAgB,SAAS,MAAyB,OAAe,YAA8B;CAC3F,OAAO,KAAK,SAAS,QAAQ;EACzB,IAAI,IAAI,SAAS,QAAQ,OAAO;EAEhC,MAAM,YAAY,UAAU,IAAI,OAAO,OAAO,UAAU;EAExD,IAAI,YAAY,gBAAgB,OAAO;EAIvC,OADc,SAAS,IAAI,MAAM,WAAW;GAAE,MAAM;GAAM,MAAM;EAAM,CAAC,CAAC,CAAC,MAAM,IACpE,CAAC,CAAC,KAAK,MAAM,WAAW;GAC/B,MAAM;GACN,KAAK,GAAG,IAAI,IAAI,GAAG,OAAO,KAAK;GAC/B,OAAO,IAAI;GAEX,MAAM,UAAU,IAAI,OAAO,KAAK,QAAQ,OAAO,EAAE;GACjD,OAAO,UAAU;EACrB,EAAE;CACN,CAAC;AACL;AAEA,SAAgB,OAAO,KAA8B;CACjD,OAAO,IAAI;AACf;;;;AChEA,MAAM,gBAAgB;AAEtB,MAAa,UAAU;AACvB,MAAM,MAAM;AACZ,MAAM,MAAM;AACZ,MAAM,QAAQ;AACd,MAAM,WAAW;AACjB,MAAM,YAAY;AAElB,MAAM,eAAyC;CAAE,OAAO;CAAK,MAAM;CAAK,MAAM;CAAK,OAAO;CAAK,OAAO;AAAI;AAE1G,MAAM,OAA0C;CAAE,MAAM;CAAW,OAAO;AAAU;AAEpF,SAAS,SAAS,OAAe,OAAuB;CACpD,OAAO,MAAM,SAAS,QAAQ,GAAG,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,aAAa;AAC9E;AAEA,SAAS,KAAK,EAAE,SAA4C;CACxD,OACI,oCAAC,MAAD;EAAM,iBAAiB,YAAY;EAAQ,OAAO;EAAW;CAEvD,GADD,IAAI,aAAa,OAAO,EACvB;AAEd;AAEA,SAAS,OAAO,EAAE,KAAK,cAAmE;CACtF,MAAM,QAAQ,SAAS,IAAI,OAAO,UAAU,CAAC,CAAC,SAAS,UAAU;CACjE,OACI,0DACI,oCAAC,MAAD,EAAM,OAAO,IAAI,MAAQ,IAAC,KAAC,oCAAC,MAAD,EAAM,eAA2C,GAAjC,YAAY,IAAI,SAAS,CAAQ,GAAC,KAAC,oCAAC,YAAM,KAAY,GAAE,KACnG,oCAAC,MAAD,EAAM,OAAO,aAAa,IAAI,OAAO,EAAc,GAAV,GAAU,CACrD;AAEV;AAQA,SAAS,SAAS,EAAE,KAAK,MAAM,cAAuC;CAClE,MAAM,OAAO,KAAK,IAAI;CAEtB,IAAI,MACA,OACI,oCAAC,MAAD,EAAM,MAAK,WAKL,GAJF,oCAAC,MAAD,EAAM,iBAAiB,KAEjB,GADF,oCAAC,QAAD;EAAa;EAAiB;CAAa,EACzC,GAAE,KACP,IACC;CAId,OACI,oCAAC,MAAD,EAAM,MAAK,WAEL,GADF,oCAAC,QAAD;EAAa;EAAiB;CAAa,IAAC,KAAE,IAC5C;AAEd;AAEA,SAAS,SAAS,EAAE,MAAM,cAAoD;CAC1E,OACI,oCAAC,MAAD,EAAM,MAAK,WAGL,GAFD,IAAI,OAAO,cAAc,UAAU,IAAI,CAAC,GACzC,oCAAC,MAAD,EAAM,eAAsB,GAAZ,KAAY,GAAC,KAAE,IAC7B;AAEd;AAEA,SAAS,iBAAiB,EAAE,KAAK,MAAM,cAAuC;CAC1E,IAAI,IAAI,UAAU,SACd,OACI,oCAAC,MAAD,EAAM,MAAK,WAKL,GAJF,oCAAC,MAAD;EAAM,OAAO,YAAY;EAAO;CAE1B,GADD,GACC,GACN,oCAAC,MAAD,EAAM,UAAU,IAAI,MAAmB,GAAX,IAAW,CACrC;CAId,OACI,oCAAC,MAAD,EAAM,MAAK,WAGL,GAFD,IAAI,OAAO,cAAc,UAAU,IAAI,CAAC,GACzC,oCAAC,MAAD,EAAM,eAAsB,GAAZ,KAAY,GAAC,KAAE,IAC7B;AAEd;AASA,SAAgB,kBAAkB,EAAE,SAAS,gBAAgB,YAAyD;CAClH,IAAI,CAAC,UAAU,OAAO;CAEtB,IAAI,iBAAiB,eACjB,OACI,oCAAC,KAAD;EAAK,UAAU;EAAG,YAAW;EAAS,gBAAe;EAAS,UAAS;CAIlE,GAHD,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAM;EAAK,MAAK;CAE1B,GADD,OACC,CACL;CAIb,MAAM,aAAa,KAAK,IAAI,GAAG,SAAS,SAAS,cAAc,CAAC;CAEhE,OAEI,oCAAC,KAAD;EAAK,eAAc;EAAS,UAAU;EAAG,gBAAe;EAAW,UAAS;CAYvE,GAXA,QAAQ,WAAW,IAChB,oCAAC,MAAD,EAAM,eAAgC,GAAvB,mBAAuB,IAEtC,QAAQ,KAAK,QAAQ;EACjB,IAAI,IAAI,SAAS,QAAQ,OAAO,oCAAC,MAAD,EAAM,KAAK,IAAI,IAAM;EACrD,MAAM,QAAQ;GAAE,KAAK,IAAI;GAAO,MAAM,IAAI;GAAM;EAAW;EAE3D,IAAI,CAAC,IAAI,MAAM,MAAM,OAAO,oCAAC,kBAAD;GAAkB,KAAK,IAAI;GAAK,GAAI;EAAQ;EACxE,OAAO,IAAI,QAAQ,oCAAC,UAAD;GAAU,KAAK,IAAI;GAAK,GAAI;EAAQ,KAAI,oCAAC,UAAD;GAAU,KAAK,IAAI;GAAK,GAAI;EAAQ;CACnG,CAAC,CAEJ;AAEb;;;;ACvIA,SAAgB,OAAO,EAAE,WAAsC;CAC3D,OACI,oCAAC,YACG,oCAAC,MAAD;EAAM;EAAK,OAAO,MAAM;CAElB,GAFyB,MAEzB,GACN,oCAAC,MAAD;EAAM;EAAK,OAAO,MAAM;CAElB,GAFwB,MAExB,GACL,YAAY,OAAO,OAAO,oCAAC,MAAD,EAAM,OAAO,MAAM,KAAyB,GAAnB,QAAK,OAAc,CACrE;AAEd;;;;ACfA,MAAM,WAAW;AAEjB,SAAgB,SAAS,EAAE,UAAU,QAAsD;CACvF,MAAM,EAAE,UAAU,aAAa;EAAE,UAAU;EAAU,UAAU;CAAQ,CAAC;CACxE,MAAM,MAAM,CAAC,WAAW,QAAQ,MAAM;CAEtC,OAAO,oCAAC,MAAD,EAAM,OAAO,GAAG,IAA4B,GAAtB,MAAM,MAAM,GAAU;AACvD;;;;ACGA,SAAS,MAAM,EAAE,OAAO,OAAO,WAAqD;CAChF,MAAM,OAAO,WAAW;CACxB,IAAI,UAAU,QAAQ,OAAO,YAAY,KAAK,IAAI,oCAAC,UAAD,EAAmB,QAAU,KAAI,oCAAC,YAAM,KAAK,IAAW;CAG1G,IAAI,KAAK,SAAS,WAAW,OAAO,oCAAC,SAAD;EAAS,KAAI;EAAW,MAAK;CAAY;CAE7E,IAAI,KAAK,SAAS,SAAS,SAAS,OAAO,oCAAC,SAAD;EAAS,KAAI;EAAU,MAAK;CAAW;CAClF,OAAO,oCAAC,YAAM,KAAK,IAAW;AAClC;AAEA,SAAgB,YAAY,EAAE,OAAO,QAAQ,SAAS,UAAU,QAAwC;CACpG,MAAM,OAAO,WAAW;CACxB,OACI,oCAAC,MAAD;EAAM,OAAO,KAAK;EAAO;CAEnB,GADF,oCAAC,OAAD;EAAc;EAAc;EAAgB;CAAU,IAAC,KAAE,KAAK,KAC5D;AAEd;;;;ACnBA,SAAS,OAAO,EAAE,UAAU,QAAQ,UAAU,MAAM,YAAY,SAAoC;CAChG,MAAM,WAAW,CAAC,UAAU,GAAG,QAAQ,YAAY,GAAG,OAAO,GAAG;CAChE,MAAM,cAAc,UAAU,GAAG,QAAQ,GAAG;CAC5C,OACI,oCAAC,KAAD,EAAK,aAAa,EAKb,GAJD,oCAAC,MAAD;EAAM,OAAO;EAAU;CAEjB,GADD,QACC,GACN,oCAAC,MAAD,EAAM,OAAO,YAA4B,GAAf,KAAE,MAAa,CACxC;AAEb;AAEA,MAAM,sCAAsB,IAAI,IAAc;CAAC;CAAoB;CAAgB;AAAO,CAAC;AAQ3F,SAAgB,YAAY,EAAE,OAAO,aAAa,aAA6C;CAC3F,OACI,oCAAC,KAAD,EAAK,eAAc,SAOd,GAND,oCAAC,QAAD;EAAQ,UAAS;EAAI,QAAO;CAAQ,IACpC,oCAAC,QAAD;EAAQ,UAAS;EAAI,QAAO;EAAU,SAAS;EAAa,WAAW,oBAAoB,IAAI,KAAK;CAAI,IACxG,oCAAC,QAAD;EAAQ,UAAS;EAAI,QAAO;EAAa,SAAS,eAAe,cAAc,KAAK;CAAI,IACxF,oCAAC,QAAD;EAAQ,UAAS;EAAI,QAAO;EAAQ,SAAS;CAAc,IAC3D,oCAAC,QAAD;EAAQ,UAAS;EAAK,QAAO;CAAU,IACvC,oCAAC,QAAD;EAAQ,UAAS;EAAM,QAAO;EAAa,WAAW,CAAC;CAAY,EAClE;AAEb;AAEA,SAAgB,aAA2B;CACvC,OACI,oCAAC,KAAD,EAAK,eAAc,SAKd,GAJD,oCAAC,QAAD;EAAQ,UAAS;EAAK,QAAO;CAAU,IACvC,oCAAC,QAAD;EAAQ,UAAS;EAAM,QAAO;CAAS,IACvC,oCAAC,QAAD;EAAQ,UAAS;EAAQ,QAAO;CAAU,IAC1C,oCAAC,QAAD;EAAQ,UAAS;EAAI,QAAO;CAAU,EACrC;AAEb;;;;ACrCA,MAAa,WAAW;AAGxB,MAAM,mBAAmB;AAEzB,MAAM,UAAU;AAehB,SAAS,KAAK,EAAE,OAAO,SAAyD;CAC5E,OACI,oCAAC,YACG,oCAAC,MAAD,EAAM,eAA+C,GAArC,MAAM,OAAO,gBAAgB,CAAQ,GACpD,KACC;AAEd;AAEA,SAAS,YAAY,QAA8B;CAC/C,OAAO,WAAW,UAAU,WAAW,SAAS,SAAS,GAAG,OAAO;AACvE;AAEA,SAAS,eAAe,EAAE,QAA8B;CACpD,OAAO,KAAK,QAAQ,cAAc,EAAE;AACxC;AAEA,SAAS,YAAY,EAAE,OAAO,YAAwE;CAClG,OACI,oCAAC,KAAD,EAAK,eAAc,SAWd,GAVD,oCAAC,aAAD;EAAa,OAAO,MAAM;EAAO,SAAS,MAAM;CAAgB,IAC/D,MAAM,SAAS,oCAAC,YAAM,MAAM,MAAa,IAAI,MAC7C,MAAM,cAAc,OAAO,OACxB,oCAAC,MAAD;EAAM,OAAO,eAAe,MAAM,SAAS;EAAG,OAAO,IAAI,MAAM,UAAU;CAAY,IAExF,aAAa,OAAO,OAAO,oCAAC,MAAD;EAAM,OAAM;EAAK,OAAO,aAAa,QAAQ;CAAI,IAE5E,MAAM,SAAS,OAAO,OAAO,oCAAC,MAAD;EAAM,OAAM;EAAO,OAAO,OAAO,MAAM,IAAI;CAAI,IAC5E,MAAM,WAAW,OAAO,OAAO,oCAAC,MAAD;EAAM,OAAM;EAAS,OAAO,YAAY,MAAM,MAAM;CAAI,IACxF,oCAAC,MAAD;EAAM,OAAM;EAAO,OAAO;CAAU,EACnC;AAEb;AAGA,SAAgB,QAAQ,EACpB,OACA,SACA,eACA,UACA,WACA,aACA,QACA,OACA,aACA,OAC2B;CAC3B,OACI,oCAAC,KAAD;EACS;EACL,eAAc;EACd,OAAO,SAAS;EAChB;EACA,YAAY;EACZ,UAAU;EACV,UAAS;CAsCR,GApCD,oCAAC,KAAD,EAAK,YAAY,EAEZ,GADD,oCAAC,QAAD,EAAiB,QAAU,EAC1B,GACL,oCAAC,KAAD;EAAK,YAAY;EAAG,WAAW;CAE1B,GADD,oCAAC,aAAD;EAAoB;EAAiB;CAAW,EAC/C,GACL,oCAAC,KAAD;EAAK,YAAY;EAAG,WAAW;EAAG,eAAc;CAQ3C,GAPD,oCAAC,aAAD;EACI,UAAU,SAAS,SAAS,YAAY;EACxC,iBAAiB;EACF;EACP;EACR,MAAM;CACT,EACA,GACJ,cACG,oCAAC,KAAD;EAAK,YAAY;EAAG,WAAW;EAAG,eAAc;CAG3C,GAFD,oCAAC,gBAAY,GACb,oCAAC,UAAM,CACN,IACL,MAEJ,oCAAC,KAAD;EAAK,YAAY;EAAG,WAAW,cAAc,IAAI;CAE5C,GADD,oCAAC,aAAD;EAAa,OAAO,MAAM;EAAoB;EAAwB;CAAY,EACjF,GACL,oCAAC,KAAD,EAAK,UAAU,EAAI,IACnB,oCAAC,KAAD;EAAK,YAAY;EAAG,gBAAe;CAS9B,GARA,YAAY,MAAM,KAAK,IACpB,oCAAC,YACG,oCAAC,UAAD,EAAU,SAAS,MAAM,cAAgB,IACzC,oCAAC,MAAD,EAAM,eAAoB,GAAX,OAAW,CACxB,IAEN,oCAAC,MAAD,EAAM,eAAqB,GAAZ,QAAY,CAE9B,CACJ;AAEb;;;;AC7HA,MAAM,OAAO;AAGb,MAAM,eAAe;;AASrB,SAAgB,WAAW,EAAE,OAAO,SAAS,WAA0C;CACnF,MAAM,CAAC,KAAK,GAAG,QAAQ;CAEvB,OACI,oCAAC,KAAD;EAAK,YAAY;EAAG,gBAAe;EAAgB,UAAU;CAoBxD,GAnBD,oCAAC,KAAD;EAAK,YAAY;EAAG,UAAS;CAQxB,GAPD,oCAAC,MAAD,EAAM,MAAK,WAML,GALF,oCAAC,QAAD,EAAQ,SAAS,KAAO,IAAE,KAC1B,oCAAC,aAAD;EAAa,OAAO,MAAM;EAAO,OAAM;EAAO,SAAS,MAAM;CAAgB,IAC5E,KAAK,UAAU,oCAAC,MAAD,EAAM,eAAkB,GAAT,KAAS,IAAI,MAC3C,KAAK,UAAU,oCAAC,MAAD,EAAM,OAAO,GAAG,KAAyB,GAAlB,IAAI,OAAc,IAAI,MAC5D,KAAK,SAAS,IAAI,oCAAC,MAAD,EAAM,eAAgC,GAAvB,QAAK,KAAK,MAAa,IAAI,IAC3D,CACL,GAEL,oCAAC,KAAD;EAAK,YAAY;EAAG,YAAY;CAQ3B,GAPA,MACG,oCAAC,MAAD;EAAM;EAAK,OAAO,GAAG;CAEf,GADD,IAAI,MACH,IACN,MAEH,CAAC,OAAO,WAAW,eAAe,oCAAC,MAAD,EAAM,eAAqB,GAAX,IAAW,IAAI,IACjE,CACJ;AAEb;;;;ACTA,SAAgB,UAAU,OAAqC;CAC3D,MAAM,EAAE,OAAO,MAAM,SAAS,SAAS,WAAW,WAAW,QAAQ,gBAAgB,aAAa;CAClG,MAAM,EAAE,SAAS,SAAS,eAAe,QAAQ,aAAa,aAAa;CAC3E,MAAM,SAAS,SAAS,UAAU,SAAS;CAE3C,OACI,oCAAC,KAAD,EAAK,UAAU,EAqCV,GApCA,SACG,oCAAC,SAAD;EACI,KAAK;EACE;EACE;EACM;EACL;EACV,WAAW,OAAO;EACL;EACL;EACR,OAAO;EACP,aAAa,SAAS;CACzB,KACD,MACJ,oCAAC,KAAD;EACI,eAAc;EACd,UAAU;EACV,UAAU;EACV,aAAY;EACZ,aAAY;EACZ,WAAW;EACX,aAAa;EACb,cAAc;EACd,YAAY;EACZ,aAAa,SAAS,IAAI;EAC1B,UAAS;CAUR,GARA,SAAS,OAAO,oCAAC,YAAD;EAAmB;EAAgB;EAAkB;CAAU,IAC/E,SAAS,OAAO,oCAAC,UAAM,GACxB,oCAAC,WAAD;EAAW,WAAW,OAAO;EAAW,OAAO,OAAO;CAAQ,IAE9D,oCAAC,KAAD;EAAK,KAAK;EAAW,UAAU;EAAG,WAAW;EAAG,UAAS;CAEpD,GADD,oCAAC,mBAAD;EAAmB,SAAS,OAAO;EAAyB;EAA0B;CAAW,EAChG,GACJ,SAAS,oCAAC,mBAAD,EAA4B,QAAU,KAAI,IACnD,CACJ;AAEb;;;;AC3EA,SAAgB,qBAAqB,EAAE,SAAkD;CACrF,OACI,oCAAC,KAAD;EAAK,aAAY;EAAQ,aAAa,GAAG;EAAM,eAAc;EAAS,UAAU;CAY3E,GAXD,oCAAC,YACG,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAM;CAEhB,GAFqB,mBAErB,CACJ,GACL,MAAM,KAAK,SACR,oCAAC,MAAD;EAAM,KAAK;EAAM,OAAO,GAAG;CAErB,GAF6B,MAC5B,IACD,CACT,GACD,oCAAC,YAAK,yBAA6B,CAClC;AAEb;;;;ACpBA,MAAM,sBAAsB;AAM5B,SAAgB,aAAa,EAAE,SAA0C;CAErE,MAAM,UAAU,MAAM,OAAO,MAAM,IAAI,KAAK,CAAC,EAAC,CAAE,MAAM,CAAC;CACvD,MAAM,UAAU,OAAO,MAAM,GAAG,mBAAmB;CACnD,MAAM,SAAS,OAAO,SAAS,QAAQ;CAEvC,OACI,oCAAC,KAAD;EAAK,eAAc;EAAS,aAAY;EAAQ,aAAa,GAAG;EAAK,UAAU;CAwB1E,GAvBD,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAK;CAEf,GAFoB,WACd,MAAM,IACZ,GACN,oCAAC,YAAM,MAAM,OAAc,GAC1B,QAAQ,SAAS,KACd,oCAAC,KAAD;EAAK,WAAW;EAAG,eAAc;CAO5B,GANA,QAAQ,KAAK,SACV,oCAAC,MAAD;EAAM,KAAK;EAAM;EAAS,MAAK;CAEzB,GADD,IACC,CACT,GACA,SAAS,KAAK,oCAAC,MAAD,EAAM,eAAkE,GAAxD,KAAK,OAAO,YAAY,WAAW,IAAI,KAAK,KAAY,CACtF,GAET,oCAAC,KAAD,EAAK,WAAW,EAQX,GAPD,oCAAC,YAAK,SACI,KACN,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAM;CAEhB,GAFqB,GAErB,GAAE,KAAI,YAEV,CACL,CACJ;AAEb;;;;ACvCA,SAAgB,kBAAgC;CAC5C,OACI,oCAAC,KAAD;EAAK,aAAY;EAAQ,aAAa,GAAG;EAAM,eAAc;EAAS,UAAU;CAW3E,GAVD,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAM;CAEhB,GAFqB,OAErB,GACN,oCAAC,YAAK,SACI,KACN,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAM;CAEhB,GAFqB,QAErB,GAAE,KAAI,yCAEV,CACL;AAEb;;;;ACfA,SAAgB,sBAAoC;CAChD,OACI,oCAAC,KAAD;EAAK,aAAY;EAAQ,aAAa,GAAG;EAAM,eAAc;EAAS,UAAU;CAW3E,GAVD,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAM;CAEhB,GAFqB,kBAErB,GACN,oCAAC,YAAK,wCACmC,KACrC,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAM;CAEhB,GAFqB,GAErB,GAAE,KAAI,YAEV,CACL;AAEb;;;;ACbA,MAAM,QAAqD;CACvD,CAAC,WAAW,oBAAoB;CAChC,CAAC,aAAa,0BAA0B;CACxC,CAAC,eAAe,oCAAoC;AACxD;AAEA,SAAS,OAAO,EAAE,MAAM,UAA4D;CAChF,IAAI,MAAM,OAAO,oCAAC,MAAD,EAAM,OAAO,GAAG,KAAc,GAAR,IAAQ;CAC/C,IAAI,QAAQ,OAAO,oCAAC,SAAD,EAAS,MAAK,OAAQ;CACzC,OAAO,oCAAC,MAAD,EAAM,OAAO,GAAG,MAAc,GAAP,GAAO;AACzC;AAEA,SAAgB,kBAAkB,EAAE,SAA+C;CAC/E,MAAM,KAAK,MAAM,WAAW,CAAC,UAAU,SAAS,KAAK;CAErD,OACI,oCAAC,KAAD;EAAK,aAAY;EAAQ,aAAa,GAAG;EAAQ,eAAc;EAAS,UAAU;CAS7E,GARD,oCAAC,MAAD;EAAM,OAAO,GAAG;EAAQ;CAElB,GAFuB,uCAEvB,GACL,MAAM,KAAK,CAAC,MAAM,QAAQ,UACvB,oCAAC,MAAD;EAAM,KAAK;EAAM,UAAU,QAAQ;CAE7B,GADF,oCAAC,QAAD;EAAQ,MAAM,QAAQ;EAAI,QAAQ,UAAU;CAAK,IAAC,KAAE,KAClD,CACT,CACA;AAEb;;;;ACbA,MAAM,UAAU;AAEhB,SAAS,aAAa,QAAiD;CACnE,OAAO,WAAW,QAAQ,WAAW,UAAU,WAAW,SAAS,OAAO;AAC9E;;AAGA,SAAgB,UAAU,OAAoC;CAC1D,MAAM,UAAoB,CAAC;CAE3B,IAAI,MAAM,WACN,QAAQ,KAAK;EAAE,KAAK;EAAQ,SAAS;EAAS,QAAQ;EAAsB,MAAM,oCAAC,qBAAiB;CAAE,CAAC;CAG3G,IAAI,MAAM,qBAAqB;EAC3B,MAAM,QAAQ,MAAM,oBAAoB;EACxC,QAAQ,KAAK;GACT,KAAK;GACL,SAAS,GAAG,MAAM,UAAU,UAAU,IAAI,KAAK,IAAI;GACnD,QAAQ;GACR,MAAM,oCAAC,sBAAD,EAAsB,OAAO,CAAC,GAAG,MAAM,mBAAmB,EAAI;EACxE,CAAC;CACL;CAEA,IAAI,MAAM,OACN,QAAQ,KAAK;EACT,KAAK;EACL,SAAS,MAAM,MAAM;EACrB,QAAQ;EACR,MAAM,oCAAC,cAAD,EAAc,OAAO,MAAM,MAAQ;CAC7C,CAAC;CAGL,IAAI,MAAM,iBACN,QAAQ,KAAK;EAAE,KAAK;EAAW,SAAS;EAAI,QAAQ;EAAS,MAAM,oCAAC,yBAAqB;CAAE,CAAC;CAGhG,MAAM,QAAQ,aAAa,MAAM,MAAM;CACvC,IAAI,OACA,QAAQ,KAAK;EACT,KAAK;EACL,SAAS;EACT,QAAQ;EACR,MAAM,oCAAC,mBAAD,EAA0B,MAAQ;CAC5C,CAAC;CAGL,OAAO;AACX;;;;AClEA,MAAM,UAAU,SAAS,WAAW,wBAAwB,KAAK;AAEjE,MAAM,SAAS;AACf,MAAM,aAAa;AACnB,MAAM,eAAe;AACrB,MAAM,UAAU;AAChB,MAAM,gBAAgB;AAGtB,MAAM,SAAS;CAAC;CAAU;CAAQ;CAAS;AAAO;AAGlD,MAAM,wBAAQ,IAAI,IAAmB;AACrC,MAAM,cAAwB,CAAC;AAC/B,IAAI,YAAY;AAChB,IAAI,YAAY;AAChB,IAAI,SAAS;AACb,IAAI,UAAU;AACd,IAAI,aAAa;AACjB,IAAI,gBAAgB;AAEpB,SAAgB,YAAY,OAAoB;CAC5C,IAAI,CAAC,SAAS;CAGd,MAAM,IAAI,OAAO,YAAY,IAAI,CAAC;CAGlC,IAAI,UAAU,SAAS,gBAAgB,YAAY;AACvD;AAEA,SAAgB,aAAa,YAA0B;CACnD,IAAI,SAAS,YAAY,KAAK,UAAU;AAC5C;AAGA,SAAgB,YAAkB,OAAyB;CACvD,IAAI,CAAC,SAAS,OAAO,MAAM;CAE3B,MAAM,UAAU,YAAY,IAAI;CAChC,MAAM,OAAO,MAAM;CACnB,aAAa,YAAY,IAAI,IAAI;CACjC;CAEA,OAAO;AACX;AAGA,SAAgB,gBAAsB;CAClC,IAAI,CAAC,SAAS;CAEd,MAAM,WAAWC,UAAQ,OAAO,MAAM,KAAKA,UAAQ,MAAM;CAEzD,UAAQ,OAAO,SAAS,OAA4B,GAAG,SAAkB;EACrE;EACA,WAAW,OAAO,UAAU,WAAW,OAAO,WAAW,KAAK,IAAI,MAAM;EAExE,MAAM,UAAU,YAAY,IAAI;EAChC,MAAM,UAAU,SAAS,OAAO,GAAG,IAAI;EACvC,cAAc,YAAY,IAAI,IAAI;EAElC,OAAO;CACX;AACJ;AAEA,SAAS,GAAG,QAA2B,UAA0B;CAC7D,OAAO,OAAO,KAAK,IAAI,OAAO,SAAS,GAAG,KAAK,MAAM,OAAO,SAAS,QAAQ,CAAC,MAAM;AACxF;AAEA,SAAS,GAAG,OAAuB;CAC/B,OAAO,GAAG,MAAM,QAAQ,CAAC,EAAE;AAC/B;AAEA,SAAS,UAAoB;CACzB,MAAM,QAAQ,KAAK;CACnB,MAAM,MAAM,SAAS,IAAI,eAAe,KAAI,CAAE,QAAQ,CAAC;CACvD,MAAM,WAAWA,UAAQ,IAAI,aAAa,qBAAsBA,UAAQ,IAAI,gBAAgB;CAE5F,OAAO;EACH,kBAAkBA,UAAQ,QAAQ,MAAMA,UAAQ,SAAS,GAAGA,UAAQ;EACpE,kBAAkB,MAAM,EAAE,EAAE,SAAS,UAAU,IAAI,OAAO,MAAM,MAAM,EAAE,IAAI,GAAG;EAC/E,kBAAkB,SAAS,SAASA,UAAQ,IAAI,QAAQ,QAAQ,IAAI,OAAOA,UAAQ,OAAO,OAAO,EAAE,GAAG,OAAOA,UAAQ,OAAO,IAAI;CACpI;AACJ;AAEA,SAAS,UAAoB;CACzB,MAAM,QAAQ,MAAM,IAAI,OAAO;CAC/B,IAAI,UAAU,QAAW,OAAO,CAAC,oCAAoC;CAErE,MAAM,QAAQ,CAAC,kBAAkB,GAAG,KAAK,GAAG;CAC5C,IAAI,WAAW;CAEf,KAAK,MAAM,SAAS,QAAQ;EACxB,MAAM,KAAK,MAAM,IAAI,KAAK;EAC1B,IAAI,OAAO,QAAW;EAEtB,MAAM,KAAK,OAAO,MAAM,OAAO,EAAE,EAAE,GAAG,GAAG,KAAK,QAAQ,GAAG;EACzD,WAAW;CACf;CAEA,OAAO;AACX;AAEA,SAAgB,gBAA+B;CAC3C,IAAI,CAAC,SAAS,OAAO;CAErB,MAAM,UAAU,YAAY,IAAI;CAChC,MAAM,SAAS,CAAC,GAAG,WAAW,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;CACpD,MAAM,cAAc,YAAY,QAAQ,KAAK,SAAS,MAAM,MAAM,CAAC;CACnE,MAAM,MAAM,UAAU,aAAY,CAAE,QAAQ,CAAC;CAC7C,MAAM,SAAS,SAAyB,IAAK,OAAO,UAAW,QAAO,CAAE,QAAQ,CAAC,EAAE;CAEnF,MAAM,QAAQ,MAAM,IAAI,OAAO,KAAK;CACpC,MAAM,aAAa,YAAY,SAAS;CACxC,MAAM,eAAe,UAAU,SAAS;CACxC,MAAM,WAAW,cAAc,KAAK,aAAa,YAAW,CAAE,QAAQ,CAAC,IAAI;CAE3E,OAAO;EACH;EACA,GAAG,QAAQ;EACX,kBAAkB,GAAG,OAAO;EAC5B,GAAG,QAAQ;EACX,kBAAkB,OAAO,YAAY,MAAM;EAC3C,kBAAkB,OAAO,UAAU,EAAE,eAAe,YAAY,QAAQ,CAAC,EAAE,MAAM,SAAS;EAC1F,sBAAsB,GAAG,GAAG,QAAQ,MAAM,CAAC,EAAE,QAAQ,GAAG,GAAG,QAAQ,UAAU,CAAC,EAAE,UAAU,GAAG,WAAW,EAAE,IAAI,MAAM,WAAW;EAC/H,kBAAkB,GAAG,WAAW,OAAO,MAAM,EAAE,WAAW,GAAG,UAAU,EAAE,IAAI,MAAM,UAAU;EAC7F,kBAAkB,GAAG,SAAS,EAAE,QAAQ,OAAO,SAAS,EAAE,WAAW,MAAM,SAAS;CACxF,CAAC,CAAC,KAAK,IAAI;AACf;;;;AChIA,MAAa,YAAY;AACzB,MAAa,eAAe;AAG5B,MAAa,eAAe;AAE5B,SAAgB,QAAQ,MAAc,SAAuB;CACzD,IAAI,cAAwB,OAAO;CACnC,IAAI,YAAmB,OAAO;CAC9B,IAAI,YAAsB,OAAO;CACjC,OAAO;AACX;;;;ACiBA,SAAgB,OAAO,OAAkC;CACrD,MAAM,EAAE,OAAO,YAAY;CAC3B,MAAM,QAAQ,YAAY,KAAK;CAC/B,MAAM,EAAE,MAAM,YAAY,cAAc;CAExC,MAAM,CAAC,SAAS,cAAc,+BAAoC,IAAI,IAAI,CAAC;CAC3E,MAAM,CAAC,eAAe,oBAAoB,+BAAsC,IAAI,IAAI,CAAC;CACzF,MAAM,CAAC,QAAQ,aAAa,SAAS,cAAc;CAEnD,MAAM,YAAY,OAA0B,IAAI;CAChD,MAAM,SAAS,eAAe,SAAS;CAEvC,MAAM,UAAU,OAA0B,IAAI;CAC9C,MAAM,YAAY,aAAa,SAAS,MAAM,OAAO,MAAM,OAAO;CAElE,MAAM,OAAO,QAAQ,MAAM,OAAO;CAClC,MAAM,UAAU,UAAU,KAAK;CAE/B,MAAM,OAAO,QAAQ,SAAS,aAAa;CAE3C,MAAM,UAAU,cAER,kBAAkB,SAAS,WAAW,IAAI,GAAG,OAAO,OAAO,KAAK,IAAI,GAAG,SAAS,SAAS,cAAc,CAAC,CAAC,CAAC,GAC9G,CAAC,MAAM,OAAO,KAAK,CACvB;CACA,MAAM,iBAAiB,KAAK,IAAI,GAAG,OAAO,MAAM;CAChD,MAAM,SAAS,UAAU,SAAS,gBAAgB,MAAM;CACxD,MAAM,WAAW,UAAU,OAAO,SAAS,MAAM;CAEjD,MAAM,cAAc,CAAC,MAAM,UAAU,MAAM;CAE3C,UAAU,OAAO,QAAQ;EACrB,eAAe;GACX;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,aAAa,SAAS;GACtB,QAAQ,MAAM;GACd,cAAc,MAAM;GACpB,WAAW,MAAM;GACjB,mBAAmB,MAAM;EAC7B,CAAC;CACL,CAAC;CAED,MAAM,mBAAmB,OAAO,KAAK;CACrC,gBAAgB;EACZ,IAAI,iBAAiB,SAAS;EAC9B,iBAAiB,UAAU;EAE3B,SAAS,SAAS,MAAM;EACxB,SAAS,SAAS,MAAM;EACxB,QAAQ;EAER,aAAa;GACT,SAAS,SAAS,QAAQ;EAC9B;CACJ,GAAG,CAAC,OAAO,CAAC;CAEZ,OACI,oCAAC,KAAD;EAAK,eAAc;EAAS,OAAO;EAAS,QAAQ;EAAM,UAAS;CAoB9D,GAlBD,oCAAC,UAAM,GACP,oCAAC,WAAD;EACW;EACD;EACG;EACA;EACE;EACA;EACH;EACQ;EAChB,UAAU,OAAO,SAAS;EACjB;EACA;EACM;EACP;EACK;EACH;CACb,EACA;AAEb;;;;AChGA,MAAM,UAAoB;CACtB,OAAO;CACP,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,WAAW;CACX,iBAAiB;CACjB,qBAAqB;CACrB,MAAM;CACN,QAAQ;CACR,WAAW;CACX,eAAe;AACnB;AAEA,IAAa,WAAb,cAA8B,kBAAkC;CAC5D,AAAQ,QAAkB;CAG1B,AAAO,WAAqB;EACxB,OAAO,KAAK;CAChB;CAEA,AAAO,UAAU,QAAsB;EACnC,KAAK,MAAM,EAAE,OAAO,CAAC;CACzB;CAEA,AAAO,QAAQ,QAAuB;EAClC,KAAK,MAAM,EAAE,OAAO,CAAC;CACzB;CAEA,AAAO,SAAS,OAAuB;EACnC,KAAK,MAAM,EAAE,MAAM,CAAC;CACxB;CAEA,AAAO,SAAS,OAA2B;EACvC,KAAK,MAAM,EAAE,MAAM,CAAC;CACxB;CAEA,AAAO,aAAa,WAAsC;EACtD,KAAK,MAAM,EAAE,UAAU,CAAC;CAC5B;CAEA,AAAO,UAAU,QAAmC;EAChD,KAAK,MAAM,EAAE,OAAO,CAAC;CACzB;CAEA,AAAO,aAAa,WAA0B;EAC1C,KAAK,MAAM,EAAE,UAAU,CAAC;CAC5B;CAEA,AAAO,iBAAiB,eAA8B;EAClD,KAAK,MAAM,EAAE,cAAc,CAAC;CAChC;CAEA,AAAO,cAAoB;EACvB,KAAK,MAAM,EAAE,qBAAqB,KAAK,CAAC;CAC5C;CAGA,AAAO,eAAqB;EACxB,KAAK,MAAM;GACP,OAAO;GACP,QAAQ;GACR,iBAAiB;GACjB,OAAO;GACP,QAAQ;GACR,MAAM;EACV,CAAC;CACL;CAEA,AAAO,kBAAwB;EAC3B,KAAK,MAAM;GACP,OAAO;GACP,QAAQ;GACR,iBAAiB;GACjB,OAAO;GACP,QAAQ;GACR,MAAM;EACV,CAAC;CACL;CAEA,AAAO,YAAkB;EACrB,KAAK,MAAM;GAAE,OAAO;GAAY,QAAQ;GAAM,QAAQ;EAAiB,CAAC;CAC5E;CAEA,AAAO,MAAM,OAAuB;EAChC,QAAQ,MAAM,MAAd;GACI,KAAK;IACD,KAAK,MAAM;KACP,OAAO;KACP,QAAQ;KACR,iBAAiB;IACrB,CAAC;IACD;GAEJ,KAAK;IACD,KAAK,MAAM,EAAE,qBAAqB,MAAM,MAAM,CAAC;IAC/C;GAEJ,KAAK;IACD,KAAK,MAAM,EAAE,MAAM,MAAM,KAAK,CAAC;IAC/B;GAEJ,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,SACD;GAEJ,SACI,YAAY,KAAK;EAEzB;CACJ;CAEA,AAAQ,MAAM,MAA+B;EACzC,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,GAAG;EAAK;EACtC,KAAK,KAAK,QAAQ;CACtB;AACJ;;;;AC5IA,MAAM,uBAAuB;AAE7B,IAAa,YAAb,MAAuB;CAKE;CACA;CALrB,AAAQ,UAA+B;CACvC,AAAiB;CAEjB,YACI,AAAiB,cACjB,AAAiB,KACnB;EAFmB;EACA;EAEjB,KAAK,SAAS,IAAI,OAAO,aAAa,EAAE,SAAS,MAAM,CAAC;CAC5D;CAEA,AAAO,QAAc;EACjB,IAAI,KAAK,SAAS;EAElB,MAAM,UAAU,KAAK,kBAAkB;EACvC,IAAI,CAAC,SAAS;GACV,KAAK,OAAO,MAAM,oFAAkF;GACpG;EACJ;EAEA,MAAM,OAAO;GAAC;GAAS;GAAY;GAAW;GAAyB;EAAU;EACjF,IAAI,KAAK,cACL,KAAK,KAAK,aAAa,KAAK,YAAY;EAG5C,KAAK,OAAO,MAAM,yBAAyB;EAE3C,KAAK,UAAU,MAAM,QAAQ,UAAU,MAAM;GACzC,KAAK,KAAK,OAAO,QAAQ,IAAI;GAC7B,OAAO;IAAC;IAAU;IAAQ;GAAM;EACpC,CAAC;EAED,KAAK,QAAQ,QAAQ,GAAG,SAAS,SAAiB;GAC9C,MAAM,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM,IAAI;GACxC,KAAK,MAAM,QAAQ,OACf,IAAI,KAAK,KAAK,GACV,KAAK,OAAO,MAAM,KAAK,QAAQ,CAAC;EAG5C,CAAC;EAED,KAAK,QAAQ,QAAQ,GAAG,SAAS,SAAiB;GAC9C,MAAM,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM,IAAI;GACxC,KAAK,MAAM,QAAQ,OACf,IAAI,KAAK,KAAK,GACV,KAAK,OAAO,MAAM,KAAK,QAAQ,CAAC;EAG5C,CAAC;EAED,KAAK,QAAQ,GAAG,UAAU,QAAQ;GAC9B,KAAK,OAAO,MAAM,wBAAwB,IAAI,SAAS;EAC3D,CAAC;EAED,KAAK,QAAQ,GAAG,SAAS,SAAS;GAC9B,IAAI,SAAS,KAAK,SAAS,MACvB,KAAK,OAAO,MAAM,wBAAwB,MAAM;QAEhD,KAAK,OAAO,MAAM,aAAa;GAEnC,KAAK,UAAU;EACnB,CAAC;CACL;CAEA,AAAO,OAAa;EAChB,MAAM,QAAQ,KAAK;EACnB,IAAI,CAAC,OAAO;EAEZ,KAAK,OAAO,MAAM,iBAAiB;EACnC,MAAM,KAAK,SAAS;EAGpB,MAAM,YAAY,iBAAiB,MAAM,KAAK,SAAS,GAAG,oBAAoB;EAC9E,UAAU,MAAM;EAChB,MAAM,KAAK,cAAc;GACrB,aAAa,SAAS;EAC1B,CAAC;CAEL;CAEA,AAAQ,oBAAmC;EACvC,MAAM,aAAa,KAAK,OAAO,QAAQ,IAAI;EAC3C,MAAM,WAAW,QAAQ,YAAY,cAAc;EACnD,MAAM,iBAAiB,WAAW,QAAQ,IAAI,cAAc,QAAQ,IAAI,cAAc,YAAY,GAAG;EAErG,IAAI;GACA,OAAO,eAAe,QAAQ,oBAAoB;EACtD,QAAQ;GACJ,OAAO;EACX;CACJ;AACJ;;;;ACnFA,SAAS,mBAAmB,WAAmD;CAC3E,OAAO,OAAO,cAAc,YAAY,cAAc,QAAS,UAAwB,mBAAmB;AAC9G;AAEA,IAAa,aAAb,MAAwB;CASC;CACA;CACA;CACA;CAXrB,AAAQ;CACR,AAAQ;CACR,AAAQ,YAAY;CACpB,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YACI,AAAiB,QACjB,AAAiB,SACjB,AAAiB,OACjB,AAAiB,SACnB;EAJmB;EACA;EACA;EACA;CAClB;CAEH,MAAc,qBAAuC;EACjD,MAAM,KAAK,QAAQ,MAAM;GACrB,QAAQ,KAAK;GACb,UAAU,UAAU;IAChB,KAAK,MAAM,MAAM,KAAK;IACtB,KAAK,QAAQ,KAAK;GACtB;EACJ,CAAC;EACD,YAAY,MAAM;EAGlB,IAAI,CAAC,WAAW,KAAK,OAAO,QAAQ,GAChC,MAAM,IAAI,cAAc,kBAAkB,kBAAkB,CAAC,KAAK,OAAO,QAAQ,CAAC;EAGtF,IAAI;GACA,MAAM,EAAE,WAAW,MAAM,KAAK,QAAQ,UAAU;GAChD,YAAY,OAAO;GACnB,OAAO;EACX,SAAS,OAAgB;GACrB,MAAM,UAAU,MAAM,QAAQ,KAAK,IAAI,MAAM,UAAU,OAAO,KAAK;GACnE,MAAM,IAAI,cAAc,kBAAkB,gBAAgB,CAAC,KAAK,OAAO,UAAU,OAAO,CAAC;EAC7F;CACJ;CAEA,AAAQ,iBAAuB;EAC3B,MAAM,EAAE,cAAc,KAAK;EAC3B,IAAI,CAAC,UAAU,SAAS;EAExB,KAAK,YAAY,IAAI,UAAU,UAAU,UAAU,QAAQ,KAAK,OAAO,UAAU,CAAC;EAClF,KAAK,UAAU,MAAM;CACzB;CAEA,MAAa,MAAM,SAAqC;EACpD,MAAM,SAAS,MAAM,KAAK,mBAAmB;EAC7C,MAAM,WAAW,qBAAqB,MAAM;EAC5C,MAAM,WAAW,MAAM,QAAQ,QAAQ,QAAQ;EAE/C,IAAI,CAAC,mBAAmB,QAAQ,GAC5B,MAAM,IAAI,cAAc,kBAAkB,kBAAkB;EAGhE,KAAK,WAAW;EAChB,KAAK,MAAM,aAAa;GAAE,MAAM,SAAS;GAAe,SAAS,SAAS;EAAQ,CAAC;EAEnF,IAAI;GACA,KAAK,MAAM,SAAS,UAAU;GAC9B,KAAK,MAAM,UAAU,6BAA6B;GAClD,KAAK,iBAAiB,QAAQ,QAAQ,SAAS,MAAM,CAAC;GACtD,MAAM,KAAK;GAEX,IAAI,KAAK,WACL;GAGJ,KAAK,MAAM,SAAS,SAAS;GAC7B,KAAK,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,YAAY,KAAK,EAAE,WAAW;GAC1E,YAAY,OAAO;GACnB,UAAU;GAEV,KAAK,eAAe;GAGpB,MAAM,IAAI,SAAe,YAAY;IACjC,KAAK,cAAc;GACvB,CAAC;EACL,SAAS,OAAgB;GACrB,MAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,MAAM,UAAU;GACtD,MAAM,IAAI,cAAc,kBAAkB,gBAAgB,CAAC,KAAK,OAAO,UAAU,MAAM,CAAC;EAC5F;CACJ;CAGA,MAAa,OAAsB;EAC/B,KAAK,gBAAgB,KAAK,QAAQ;EAClC,OAAO,KAAK;CAChB;CAEA,MAAc,UAAyB;EACnC,KAAK,YAAY;EACjB,KAAK,WAAW,KAAK;EACrB,KAAK,UAAU,QAAQ,MAAM;EAE7B,IAAI,KAAK,gBAEL,IAAI;GACA,MAAM,KAAK;EACf,QAAQ,CAAC;EAGb,MAAM,KAAK,UAAU,SAAS,IAAI,GAAG,KAAK;EAC1C,KAAK,cAAc;CACvB;CAEA,MAAa,UAAyB;EAClC,MAAM,KAAK,KAAK;EAChB,MAAM,KAAK,QAAQ,QAAQ;CAC/B;CAEA,AAAO,gBAAgB,eAA8B;EACjD,KAAK,QAAQ,kBAAkB,aAAa;CAChD;AACJ;;;;ACrHA,MAAM,cAAc;AAEpB,IAAa,YAAb,cAA+B,kBAAyC;CAevC;CAd7B,AAAiB;CACjB,AAAiB,6BAAa,IAAI,IAAoB;CACtD,AAAiB,qCAAqB,IAAI,IAAY;CACtD,AAAQ,SAA+B;CACvC,AAAiB,yCAAyB,IAAI,IAAY;CAE1D,IAAY,MAAwC;EAChD,OAAO,KAAK,QAAQ,aAAa,IAAI;CACzC;CAEA,IAAY,MAA0E;EAClF,OAAO,KAAK,MAAM,QAAoD,KAAK,GAAG,IAAI;CACtF;CAEA,YAAY,AAAiB,QAAmC;EAC5D,MAAM;EADmB;EAEzB,KAAK,SAAS,IAAI,OAAO,OAAO,EAAE,SAAS,MAAM,CAAC;CACtD;CAEA,IAAW,SAAiB;EACxB,OAAO;GACH,MAAM;GACN,iBAAiB,KAAK,gBAAgB,KAAK,IAAI;GAC/C,WAAW,KAAK,UAAU,KAAK,IAAI;EACvC;CACJ;CAEA,AAAO,oBAAoB,eAA8B;EACrD,KAAK,KAAK,KAAK,6BAA6B,EAAE,cAAc,CAAC;CACjE;CAEA,AAAQ,gBAAgB,QAA6B;EACjD,KAAK,SAAS;EACd,OAAO,QAAQ,GAAG,QAAQ,SAAS,KAAK,gBAAgB,MAAM,QAAQ,CAAC;EACvE,OAAO,QAAQ,GAAG,WAAW,SAAS,KAAK,gBAAgB,MAAM,QAAQ,CAAC;EAC1E,OAAO,QAAQ,GAAG,WAAW,SAAS,KAAK,gBAAgB,MAAM,WAAW,CAAC;EAC7E,OAAO,QAAQ,GAAG,cAAc,SAAS,KAAK,gBAAgB,MAAM,WAAW,CAAC;EAGhF,OAAO,QAAQ,IAAI,KAAK,OAAO,UAAU;EACzC,OAAO,QAAQ,GAAG,WAAW,SAAS,KAAK,aAAa,IAAI,CAAC;EAE7D,KAAK,KAAK,GAAG,oCAAoC,SAAS;GACtD,KAAK,KAAK,SAAS;IAAE,MAAM;IAAyB,OAAO,KAAK;GAAM,CAAC;EAC3E,CAAC;EAED,KAAK,KAAK,GAAG,8BAA8B,SAAS;GAChD,KAAK,KAAK,SAAS;IAAE,MAAM;IAAoB,MAAM,KAAK;GAAK,CAAC;EACpE,CAAC;EAED,KAAK,KAAK,GAAG,qCAAqC,SAAS;GACvD,KAAK,MAAM,WAAW,KAAK,UACvB,KAAK,uBAAuB,IAAI,OAAO;GAG3C,KAAK,OAAO,MAAM,cAAc,OAAO,KAAK,SAAS,MAAM,EAAE,wBAAwB;EACzF,CAAC;CACL;CAGA,AAAQ,YAAY,MAAc,MAA6B;EAC3D,IAAI,KAAK,QAAQ,MAAM,IAAI,GAAG,OAAO;EACrC,KAAK,WAAW,IAAI,GAAG,KAAK,IAAI,QAAQ,KAAK,IAAI,CAAC;EAClD,OAAO;CACX;CAEA,AAAQ,QAAQ,MAAc,MAA6B;EACvD,MAAM,OAAO,KAAK,WAAW,IAAI,GAAG,KAAK,IAAI,MAAM;EACnD,OAAO,SAAS,UAAa,KAAK,IAAI,IAAI,OAAO;CACrD;CAGA,AAAQ,aAAa,MAAoB;EACrC,IAAI,CAAC,KAAK,eAAe,IAAI,KAAK,KAAK,YAAY,MAAM,QAAQ,GAAG;EACpE,KAAK,sBAAsB,IAAI;CACnC;CAEA,AAAQ,sBAAsB,MAAoB;EAC9C,MAAM,UAAU,SAAS,QAAQ,IAAI,GAAG,IAAI;EAC5C,KAAK,OAAO,KAAK,GAAG,MAAM,MAAM,wBAAwB,EAAE,GAAG,MAAM,IAAI,KAAK,OAAO,EAAE,oBAAoB;EACzG,KAAK,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;CACnD;CAEA,AAAQ,gBAAgB,MAAc,MAA0B;EAC5D,IAAI,KAAK,YAAY,MAAM,IAAI,GAAG;EAClC,IAAI,SAAS,UAAU,KAAK,mBAAmB,IAAI,IAAI;EAEvD,MAAM,UAAU,SAAS,QAAQ,IAAI,GAAG,IAAI;EAC5C,MAAM,YACF,SAAS,YAAY,SAAS,cACxB,MAAM,OACN,SAAS,YAAY,SAAS,cAC5B,MAAM,QACN,MAAM;EAElB,KAAK,OAAO,MAAM,GAAG,UAAU,KAAK,YAAY,CAAC,EAAE,GAAG,MAAM,KAAK,OAAO,GAAG;EAE3E,MAAM,UAA0B;GAAE;GAAM;GAAM,UAAU,KAAK,OAAO,KAAK,YAAY;EAAK;EAE1F,KAAK,KAAK,KAAK,gBAAgB,OAAO;CAC1C;CAEA,AAAQ,UAAU,KAAgD;EAC9D,MAAM,EAAE,MAAM,SAAS,WAAW;EAClC,MAAM,OAAO;EAIb,IADqB,KAAK,mBAAmB,OAAO,IAAI,KAAK,KAAK,QAAQ,MAAM,QAAQ,KACpE,KAAK,YAAY,MAAM,IAAI,GAAG,OAAO,CAAC;EAE1D,MAAM,UAAU,SAAS,QAAQ,IAAI,GAAG,IAAI;EAE5C,KAAK,OAAO,MAAM,GAAG,MAAM,IAAI,KAAK,YAAY,CAAC,EAAE,GAAG,MAAM,KAAK,OAAO,GAAG;EAE3E,IAAI,KAAK,eAAe,IAAI,GAAG;GAC3B,KAAK,sBAAsB,IAAI;GAC/B,OAAO,CAAC;EACZ;EAEA,MAAM,cAAc,OAAO;EAC3B,MAAM,cAAc,YAAY,iBAAiB,IAAI;EACrD,MAAM,aAAa,cAAc,CAAC,GAAG,WAAW,IAAI,CAAC;EAErD,MAAM,kCAAkB,IAAI,IAAI,CAAC,GAAG,SAAS,GAAG,UAAU,CAAC;EAC3D,MAAM,kBAAkB,KAAK,mBAAmB,CAAC,GAAG,eAAe,CAAC;EAEpE,MAAM,oCAAoB,IAAI,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC;EAE5D,KAAK,MAAM,oBAAoB,mBAAmB;GAC9C,MAAM,OAAO,YAAY,iBAAiB,gBAAgB;GAC1D,IAAI,MACA,KAAK,MAAM,OAAO,MACd,YAAY,iBAAiB,GAAG;EAG5C;EAGA,KAAK,KAAK,SAAS;GAAE,MAAM;GAAe,MAAM;EAAK,CAAC;EAEtD,MAAM,UAA0B;GAAE;GAAM;GAAM;GAAiB,UAAU,KAAK,OAAO,KAAK,YAAY;EAAK;EAE3G,KAAK,KAAK,KAAK,gBAAgB,OAAO;EAGtC,OAAO,CAAC;CACZ;CAEA,AAAQ,eAAe,MAAuB;EAC1C,MAAM,OAAO,KAAK,OAAO;EACzB,MAAM,UAAU,SAAS,MAAM,IAAI;EAEnC,IAAI,KAAK,OAAO,KAAK,SACjB;QAAK,MAAM,WAAW,KAAK,OAAO,IAAI,SAClC,IAAI,UAAU,SAAS,OAAO,GAC1B,OAAO;EAEf;EAGJ,KAAK,MAAM,WAAW,KAAK,wBACvB,IAAI,UAAU,SAAS,OAAO,GAC1B,OAAO;EAIf,IACI,SAAS,KAAK,OAAO,cACrB,KAAK,SAAS,cAAc,KAC5B,KAAK,SAAS,eAAe,KAC7B,KAAK,SAAS,MAAM,GAEpB,OAAO;EAGX,MAAM,YAAY,QAAQ,MAAM,KAAK,OAAO,KAAK;EACjD,MAAM,eAAe,QAAQ,MAAM,KAAK,OAAO,QAAQ;EAEvD,IAAI,SAAS,aAAa,SAAS,cAC/B,OAAO;EAGX,OAAO;CACX;CAEA,AAAQ,mBAAmB,SAA2D;EAClF,MAAM,2BAAW,IAAI,IAAY;EACjC,MAAM,uBAAO,IAAI,IAAY;EAE7B,MAAM,YAAY,QAAkD;GAChE,IAAI,CAAC,IAAI,QAAQ,KAAK,IAAI,IAAI,IAAI,GAAG;GAErC,KAAK,IAAI,IAAI,IAAI;GACjB,SAAS,IAAI,IAAI,IAAI;GACrB,IAAI,UAAU,QAAQ,QAAQ;EAClC;EAEA,QAAQ,QAAQ,QAAQ;EACxB,OAAO,CAAC,GAAG,QAAQ;CACvB;AACJ;;;;AC1NA,SAAgB,WAAW,MAAyC;CAEhE,MAAM,OAAO,QAAQ,aAAa,IAAI,GAAG,MAAM;CAE/C,QAAQ,SAAS,SAAS,QAAQ,KAAK,WAAW,OAAO,GAAG;AAChE;AAEA,0BAAe,aAAa;CACxB,QAAQ;EACJ,gBAAgB;EAChB,KAAK;EACL,OAAO;GACH,YAAY;GACZ,SAAS;IAAC;IAAsB;IAAc;GAAY;EAC9D;CACJ;CACA,OAAO;EACH,KAAK;EACL,QAAQ;EACR,WAAW;EACX,QAAQ;EACR,eAAe,EACX,QAAQ;GACJ,QAAQ;GACR,iBAAiB;EACrB,EACJ;CACJ;CACA,KAAK;EACD,QAAQ;EAER,UAAU,CAAC,oBAAoB,uBAAuB;EAGtD,YAAY,CAAC,cAAc;EAC3B,SAAS;GACL,YAAY,CAAC,QAAQ,QAAQ;GAC7B,oBAAoB,CAAC,MAAM;EAC/B;CACJ;CACA,cAAc,EACV,KAAK,EACD,SAAS;EACL,YAAY,CAAC,QAAQ,QAAQ;EAC7B,oBAAoB,CAAC,MAAM;CAC/B,EACJ,EACJ;CACA,QAAQ;EACJ,qBAAqB;EACrB,iCAAiC;EACjC,6BAA6B;EAC7B,yBAAyB;EACzB,0BAA0B;EAC1B,6BAA6B;EAC7B,iBAAiB;EACjB,8BAA8B;EAC9B,2BAA2B;CAC/B;CACA,aAAa;CACb,UAAU;CACV,SAAS;AACb,CAAC;;;;ACnDD,IAAa,iBAAb,MAAkD;CAC9C,AAAQ,UAAoC;CAC5C,AAAQ,aAAmC;CAC3C,AAAQ,eAAoC;CAC5C,AAAQ,eAAuC;CAC/C,AAAQ,mBAA4C;CACpD,AAAQ,YAA8B;CAEtC,MAAa,MAAM,SAA2C;EAC1D,KAAK,UAAU;EACf,KAAK,eAAe,QAAQ,WAAW;EAEvC,MAAM,cAAc,KAAK,QAAQ,OAAO;EAExC,KAAK,KAAK;GAAE,MAAM;GAAkB,MAAM;EAAY,CAAC;EAEvD,MAAM,YAAY,IAAI,UAAU,KAAK,QAAQ,MAAM;EACnD,KAAK,YAAY;EAGjB,MAAM,SAAS,YAAYC,qBAAY;GACnC,MAAM;GACN,YAAY;GACZ,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,WAAW,WAAW,CAAC,EAAE,EAAE;GACxD,SAAS,CAAC,cAAc,EAAE,MAAM,QAAQ,KAAK,QAAQ,OAAO,UAAU,EAAE,CAAC,GAAG,UAAU,MAAM;EAChG,CAAC;EAED,KAAK,aAAa,MAAM,aAAa,MAAM;EAE3C,KAAK,mBAAmB,IAAI,iBAAiB;EAC7C,KAAK,eAAe,yBAAyB,KAAK,WAAW,aAAa,KAAK,EAC3E,kBAAkB,KAAK,iBAC3B,CAAC;EAED,UAAU,GAAG,SAAS,KAAK,eAAe,KAAK,IAAI,CAAC;EAEpD,KAAK,KAAK;GAAE,MAAM;GAAiB,MAAM;EAAY,CAAC;EACtD,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;CAC/B;CAEA,AAAQ,eAAe,OAAuB;EAC1C,IAAI,MAAM,SAAS,eACf,KAAK,iBAAiB,MAAM,IAAI;EAEpC,KAAK,KAAK,KAAK;CACnB;CAEA,AAAQ,iBAAiB,MAAoB;EACzC,MAAM,cAAc,KAAK,SAAS,OAAO;EACzC,IAAI,CAAC,eAAe,CAAC,KAAK,kBAAkB;EAE5C,MAAM,WAAW,WAAW,aAAa,IAAI;EAC7C,MAAM,aAAa,KAAK,iBAAiB,cAAc,QAAQ;EAC/D,IAAI,YACA,KAAK,iBAAiB,iBAAiB,UAAU;CAEzD;CAEA,AAAO,gBAAgB,eAA8B;EACjD,KAAK,WAAW,oBAAoB,aAAa;CACrD;CAEA,MAAa,YAA2C;EACpD,IAAI,CAAC,KAAK,WAAW,CAAC,KAAK,cAAc,CAAC,KAAK,cAC3C,MAAM,IAAI,cAAc,kBAAkB,gBAAgB,CACtD,KAAK,SAAS,OAAO,YAAY,WACjC,yDACJ,CAAC;EAGL,MAAM,EAAE,UAAU,cAAc,KAAK,QAAQ;EAC7C,MAAM,cAAc,KAAK,QAAQ,OAAO;EAExC,KAAK,KAAK;GAAE,MAAM;GAAkB,MAAM;EAAU,CAAC;EAErD,IAAI;GACA,MAAM,WAAW,WAAW,aAAa,SAAS;GAElD,MAAM,SAAS,MAAM,KAAK,aAAa,OAAgB,QAAQ;GAE/D,KAAK,KAAK;IAAE,MAAM;IAAiB,MAAM;GAAU,CAAC;GAEpD,OAAO,EAAE,OAAO;EACpB,SAAS,OAAgB;GACrB,KAAK,KAAK;IAAE,MAAM;IAAgB,MAAM;IAAW;GAAM,CAAC;GAC1D,MAAM;EACV;CACJ;CAEA,MAAa,UAAyB;EAGlC,KAAK,WAAW,mBAAmB,OAAO;EAE1C,IAAI,KAAK,YAAY;GACjB,MAAM,KAAK,WAAW,MAAM;GAC5B,KAAK,aAAa;EACtB;EAEA,KAAK,eAAe;EACpB,KAAK,mBAAmB;EACxB,KAAK,YAAY;EACjB,KAAK,UAAU;EACf,KAAK,eAAe;CACxB;CAEA,AAAQ,KAAK,OAAuB;EAChC,KAAK,eAAe,KAAK;CAC7B;AACJ;AAGA,SAAS,WAAW,aAAqB,MAAsB;CAC3D,OAAO,IAAI,SAAS,aAAa,IAAI,CAAC,CAAC,WAAW,MAAM,GAAG;AAC/D;;;;AC9HA,MAAM,SAAS;AACf,MAAM,YAAY;AAUlB,SAAgB,eAA2B;CACvC,OAAO;EACH,SAAS,SAAS,IAAI,MAAM;EAC5B,SAAS,SAAS,IAAI,SAAS;EAC/B,UAAU,QAAQ;EAClB;EACA,QAAQ;CACZ;AACJ;AAEA,SAAgB,gBAAgB,QAAwC;CACpE,MAAM,WAAW,OAAO,aAAa,UAAW,OAAO,SAAS,MAAM,GAAG,KAAK,CAAC,MAAM,IAAK,CAAC,EAAE;CAE7F,KAAK,MAAM,OAAO,OAAO,SAAS,MAAM,OAAO,SAAS,KAAK,CAAC,GAC1D,KAAK,MAAM,UAAU,UAAU;EAC3B,MAAM,YAAY,KAAK,KAAK,GAAG,SAAS,QAAQ;EAChD,IAAI,OAAO,OAAO,SAAS,GAAG,OAAO;CACzC;AAIR;AAEA,SAAgB,YAAY,UAAmC;CAC3D,IAAI,aAAa,UAAU,OAAO;CAClC,IAAI,aAAa,SAAS,OAAO;CACjC,OAAO;AACX;;;;AC3CA,MAAM,eAAe;AACrB,MAAMC,qBAAmB;AACzB,MAAM,YAAY;AAElB,MAAa,gBAAgB,YAAY;AAQzC,eAAsB,eAAe,KAAa,MAAiB,QAAuC;CAEtG,MAAM,SAAS,YAAY,IAAI,CAAC,QAAQ,YAAY,QAAQ,SAAS,CAAC,CAAC;CAEvE,KAAK,IAAI,UAAU,GAAG,UAAU,YAAYA,oBAAkB,WAAW;EACrE,IAAI;GAEA,KAAI,MADmB,KAAK,MAAM,KAAK;IAAE,QAAQ;IAAQ,QAAQ;GAAO,CAAC,EAC7D,CAAC,WAAW,cAAc,OAAO;EACjD,QAAQ;GACJ,OAAO,eAAe;EAC1B;EACA,MAAM,KAAK,KAAKA,kBAAgB;CACpC;CAEA,OAAO;AACX;;;;AChBA,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,YAAY;AAClB,MAAM,mBAAmB;AAOzB,SAAS,WAA4B;CACjC,OAAO,IAAI,SAAS,SAAS,WAAW;EACpC,MAAM,QAAQC,eAAa;EAC3B,MAAM,KAAK,SAAS,MAAM;EAC1B,MAAM,OAAO,GAAG,mBAAmB;GAE/B,MAAM,EAAE,SAAS,MAAM,QAAQ;GAC/B,MAAM,YAAY,QAAQ,IAAI,CAAC;EACnC,CAAC;CACL,CAAC;AACL;AAEA,SAAgB,mBAA+B;CAC3C,OAAO;EACH,QAAQ,SAAS,SAAS,MAAM,SAAS,MAAM,EAAE,OAAO,SAAS,CAAC;EAClE,QAAQ,KAAK,SAAS,MAAM,KAAK,IAAI;EACrC;EACA,OAAO,OAAO,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;CAClE;AACJ;AAEA,IAAa,oBAAb,MAA+B;CAKN;CACA;CACA;CANrB,AAAQ;CACR,AAAQ;CAER,YACI,AAAiB,MACjB,AAAiB,QACjB,AAAiB,QACnB;EAHmB;EACA;EACA;CAClB;CAEH,MAAa,KAAK,QAAqB,YAAoB,aAA2C;EAClG,MAAM,cAAc,MAAM,KAAK,KAAK,SAAS;EAE7C,MAAM,QAAQ,KAAK,KAAK,MAAM,KAAK,QAAQ;GACvC;GACA;GACA,oBAAoB,OAAO,UAAU;GACrC;GACA,aAAa,OAAO,WAAW;EACnC,CAAC;EAED,MAAM,GAAG,UAAU,UAAU;GACzB,KAAK,UAAU;EACnB,CAAC;EAED,MAAM,GAAG,SAAS,SAAS;GACvB,IAAI,KAAK,UAAU,OAAO;GAC1B,KAAK,0BAAU,IAAI,MAAM,sCAAsC,OAAO,IAAI,GAAG;EACjF,CAAC;EACD,KAAK,QAAQ;EAEb,MAAM,MAAM,WAAW,MAAM,KAAK,aAAa,aAAa,MAAM;EAClE,cAAc;EAEd,MAAM,KAAK,KAAK,KAAK,SAAS;EAE9B,MAAM,eAAe,KAAK,KAAK,MAAM,MAAM;EAC3C,MAAM,KAAK,cAAc;GACrB,IAAI,KAAK,UAAU,OAAO,KAAK,OAAO;EAC1C,CAAC;EACD,OAAO;CACX;CAEA,AAAO,OAAa;EAChB,MAAM,QAAQ,KAAK;EACnB,IAAI,CAAC,OAAO;EAEZ,KAAK,QAAQ;EACb,KAAK,UAAU;EACf,MAAM,KAAK,SAAS;EAEpB,MAAM,WAAW,iBAAiB,MAAM,KAAK,SAAS,GAAG,gBAAgB;EACzE,SAAS,MAAM;EACf,MAAM,KAAK,cAAc;GACrB,aAAa,QAAQ;EACzB,CAAC;CACL;CAEA,MAAc,aAAa,aAAqB,QAAsC;EAClF,MAAM,SAAS,YAAY,IAAI,CAAC,QAAQ,YAAY,QAAQ,GAAoC,CAAC,CAAC;EAElG,KAAK,IAAI,UAAU,GAAG,UAAU,qBAAqB,CAAC,KAAK,SAAS,WAAW;GAC3E,OAAO,eAAe;GACtB,IAAI,OAAO,SAAS;GACpB,MAAM,WAAW,MAAM,KAAK,SAAS,aAAa,MAAM;GACxD,IAAI,UAAU,OAAO;GACrB,MAAM,KAAK,KAAK,KAAK,gBAAgB;EACzC;EAEA,MAAM,QAAQ,KAAK;EACnB,KAAK,KAAK;EACV,MAAM,IAAI,cACN,kBAAkB,yBAClB,CAAE,MAAwC,GAAI,GAC9C,EAAE,MAAM,CACZ;CACJ;CAEA,MAAc,SAAS,aAAqB,QAAkD;EAC1F,IAAI;GAGA,MAAM,EAAE,aAAc,OAAM,MAFL,KAAK,KAAK,MAAM,oBAAoB,OAAO,WAAW,EAAE,eAAe,EAAE,OAAO,CAAC,EAEpE,CAAC,KAAK;GAC1C,OAAO,aAAa,KAAK,SAAY;EACzC,QAAQ;GACJ;EACJ;CACJ;AACJ;;;;AC3HA,MAAM,QAAQ;AAKd,SAAS,WAAW,OAAyB;CACzC,IAAI,EAAE,iBAAiB,oBAAoB,MAAM,SAAS,mBAAmB,8BACzE,OAAO;CAGX,MAAM,EAAE,aAAa;CACrB,OAAO,YAAY,YAAY,cAAc,SAAS,MAAM;AAChE;AAEA,SAAS,cAAc,QAA0B;CAC7C,OAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,SAAS;AACrE;AAEA,IAAa,uBAAb,MAAa,qBAAqB;CAGD;CAF7B,AAAQ;CAER,YAAY,AAAiB,UAA8B;EAA9B;CAA+B;CAG5D,OAAc,OAAO,OAA2C;EAE5D,MAAM,OAAO,IAAI,KAAK;GAAE,SAAS;GAAM,mBAAmB,CAAC,eAAe;EAAE,CAAC;EAC7E,OAAO,IAAI,2BAA2B,KAAK,SAAS,MAAM,CAAC,CAAC;CAChE;CAEA,MAAa,IAAI,KAAa,QAAoC;EAC9D,OAAO,eAAe;EAGtB,KAAI,MADuB,KAAK,KAAK,CAAC,CAAC,IAAI,OAAO,mBAAmB,CAAC,EACvD,CAAC,8BAA8B,KAAK;EAEnD,OAAO,eAAe;EACtB,IAAI;GACA,MAAM,KAAK,MAAM,GAAG;EACxB,SAAS,OAAgB;GACrB,IAAI,CAAC,WAAW,KAAK,GAAG,MAAM;GAC9B,MAAM,IAAI,cAAc,kBAAkB,sBAAsB,CAAC,GAAG,CAAC;EACzE;CACJ;CAEA,AAAQ,OAAqB;EACzB,KAAK,WAAW,KAAK,SAAS;EAC9B,OAAO,KAAK;CAChB;CAEA,MAAa,QAAuB;EAChC,MAAM,KAAK,MAAM,IAAI;CACzB;CAEA,MAAc,MAAM,UAAwC;EACxD,MAAM,KAAK,KAAK,CAAC,CAAC,MAAM,OAAO,mBAAmB,GAAG,EACjD,MAAM,EAAE,2BAA2B,SAAS,EAChD,CAAC;CACL;AACJ;;;;AC1DA,MAAM,aAAa;AACnB,MAAM,eAAe;AAiBrB,SAAS,WAAW,SAAmC;CACnD,OAAO,QAAQ,OAAO;AAC1B;AAEA,SAAS,QAAQ,MAAuC;CACpD,OAAO,SAAS,UAAU,4CAA4C;AAC1E;AAEA,IAAa,oBAAb,MAA+B;CAIE;CAH7B,AAAQ;CACR,AAAQ;CAER,YAAY,AAAiB,MAAuB;EAAvB;CAAwB;CAErD,MAAa,OAAO,MAA6B;EAC7C,IAAI,KAAK,WAAW,MAAM;EAE1B,KAAK,SAAS;EACd,MAAM,UAAU,KAAK,MAAM;EAC3B,MAAM,YAAY,KAAK,IAAI;EAC3B,MAAM,cAAsB,MAAM,KAAK,IAAI,aAAa,KAAK,IAAI,IAAI,SAAS,GAAG;EACjF,MAAM,SAAS,KAAK,KAAK,iBAAiB,KAAK,WAAW,OAAO,CAAC;EAElE,QAAQ,OAAO,iBAAiB,eAAe,OAAO,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;EAC5E,IAAI,UAAU;EAEd,IAAI;GACA,KAAK,KAAK,SAAS,SAAS;GAC5B,KAAK,KAAK,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,IAAI,EAAE,GAAG,MAAM,IAAI,KAAK,OAAO,IAAI,CAAC,GAAG;GAClF,MAAM,MAAM,MAAM,OAAO,KAAK,QAAQ,QAAQ,YAAY,KAAK,KAAK,SAAS,WAAW,CAAC;GACzF,IAAI,WAAW,OAAO,GAAG;GACzB,KAAK,KAAK,OAAO,KAAK,gBAAgB,MAAM,IAAI,KAAK,GAAG,EAAE,GAAG,MAAM,GAAG;GAEtE,KAAK,KAAK,SAAS,aAAa;GAChC,UAAU;GACV,MAAM,KAAK,KAAK,SAAS,IAAI,KAAK,QAAQ,MAAM;GAChD,IAAI,WAAW,OAAO,GAAG;GAEzB,KAAK,KAAK,SAAS,MAAM;GACzB,KAAK,KAAK,OAAO,KAAK,kDAAkD,MAAM,GAAG;EACrF,SAAS,OAAgB;GACrB,IAAI,WAAW,OAAO,GAAG;GAEzB,IAAI,SAAS,QAAQ,MAAM;GAC3B,KAAK,cAAc,OAAO,OAAO;EACrC;CACJ;CAEA,AAAQ,WAAW,SAAgC;EAC/C,IAAI,WAAW,OAAO,GAAG;EAEzB,KAAK,SAAS;EACd,KAAK,KAAK,SAAS,MAAM;EACzB,KAAK,KAAK,OAAO,MAAM,uDAAuD;CAClF;CAEA,AAAQ,cAAc,OAAgB,SAAwB;EAE1D,KAAK,SAAS;EACd,KAAK,KAAK,SAAS,IAAI;EACvB,KAAK,KAAK,OAAO,MAAM,+DAA+D,KAAK;EAE3F,IAAI,KAAK,KAAK,SAAS,SAAS,KAAK,KAAK,OAAO,KAAK,UAAU,eAAe,UAAU;CAC7F;CAEA,MAAa,OAAsB;EAC/B,IAAI,CAAC,KAAK,SAAS;EAEnB,KAAK,SAAS;EACd,KAAK,QAAQ,MAAM;EACnB,KAAK,UAAU;EACf,KAAK,KAAK,SAAS,IAAI;EACvB,IAAI,KAAK,KAAK,SAAS,cAAc;EAErC,IAAI;GACA,MAAM,KAAK,KAAK,SAAS,MAAM;EACnC,SAAS,OAAgB;GAErB,KAAK,KAAK,OAAO,KAAK,6CAA6C,KAAK;EAC5E;CACJ;CAEA,AAAQ,QAAyB;EAC7B,KAAK,SAAS,MAAM;EACpB,KAAK,UAAU,IAAI,gBAAgB;EACnC,OAAO,KAAK;CAChB;AACJ;;;;ACnGA,SAAgB,uBAAuB,UAAmC;CACtE,MAAM,QAAQ,MAAM,KAAK,GAAG;CAC5B,OAAO;EACH,GAAG,MAAM,IAAI,KAAK,aAAa,EAAE;EACjC,GAAG,MAAM,mBAAmB,MAAM,KAAK,KAAK,YAAY,QAAQ,CAAC;EACjE,GAAG,MAAM,UAAU,MAAM,MAAM,QAAQ,EAAE,2CAA2C,MAAM,IAAI,OAAO,yBAAyB;CAClI,CAAC,CAAC,KAAK,IAAI;AACf;AAEA,SAAgB,wBACZ,QACA,UACA,QACA,mBAA6C,gBAAgB,aAAa,CAAC,GAC9C;CAC7B,IAAI,OAAO,SAAS,OAAO,OAAO;CAElC,MAAM,OAAO,iBAAiB;CAC9B,MAAM,WAAW,qBAAqB,aAAa,qBAAqB,SAAS,IAAI,mBAAmB,CAAC,CAAC;CAE1G,IAAI,OAAO,SAAS,OAChB,OAAO,IAAI,kBAAkB;EACzB,mBAAmB;GAEf,MAAM,OAAO,QAAQ,OAAO,gBAAgB;IACxC,cAAc;IACd,IAAI,MAAM,eAAe,OAAO,KAAK,MAAM,MAAM,GAAG,OAAO,OAAO;IAClE,MAAM,IAAI,cAAc,kBAAkB,sBAAsB,CAAC,OAAO,OAAkB,CAAC;GAC/F;GAEA,YAAY;EAChB;EACA,MAAM;EACN;EACA;EACA;CACJ,CAAC;CAGL,MAAM,SAAS,WAAW;CAC1B,IAAI,CAAC,QAAQ,OAAO;CAEpB,OAAO,IAAI,kBAAkB;EACzB,aAAa,WAAW,IAAI,kBAAkB,MAAM,QAAQ,MAAM;EAClE,MAAM;EACN;EACA;EACA;CACJ,CAAC;AACL;;;;ACxDA,SAAS,KAAK,GAA+B,GAA4B;CACrE,IAAI,GAAG,SAAS,EAAE,MAAM,OAAO;CAC/B,OAAO,EAAE,SAAS,SAAS,EAAE,SAAS,QAAQ,EAAE,QAAQ,EAAE,MAAM;AACpE;AAEA,IAAa,eAAb,MAA0B;CAKD;CACA;CALrB,AAAQ;CACR,AAAQ;CAER,YACI,AAAiB,MACjB,AAAiB,QACnB;EAFmB;EACA;CAClB;CAGH,AAAO,MAAM,QAAwB,OAAgC;EACjE,IAAI,MAAM,SAAS,oBAAoB,OAAO,QAAQ,QAAQ;EAC9D,OAAO,KAAK,QAAQ,QAAQ,MAAM,IAAI,CAAC,CAAC,OAAO,UAAmB;GAC9D,KAAK,OAAO,MAAM,+DAA+D,KAAK;EAC1F,CAAC;CACL;CAEA,MAAc,QAAQ,QAAwB,MAA6B;EAEvE,IAAI,CAAC,KAAK,KAAK,OAAO,MAAM,GAAG;GAE3B,MAAM,KAAK,KAAK;GAChB,KAAK,QAAQ;GACb,KAAK,cAAc,OAAO,SAAS,QAAQ,SAAY,KAAK,KAAK,MAAM;GACvE,IAAI,OAAO,SAAS,SAAS,CAAC,KAAK,aAC/B,KAAK,OAAO,KAAK,uBAAuB,QAAQ,QAAQ,CAAC;EAEjE;EAEA,MAAM,KAAK,aAAa,OAAO,IAAI;CACvC;CAEA,AAAO,OAAsB;EACzB,MAAM,UAAU,KAAK;EACrB,KAAK,cAAc;EACnB,OAAO,SAAS,KAAK,KAAK,QAAQ,QAAQ;CAC9C;AACJ;;;;AC7BA,MAAM,qBAAqB;AAW3B,IAAa,YAAb,MAAa,UAAU;CASU;CAR7B,AAAQ,iBAAoC;CAC5C,AAAQ;CACR,AAAQ,aAAa;CACrB,AAAQ;CACR,AAAQ,iBAAiB;CACzB,AAAQ,YAAY;CACpB,AAAQ,iBAAiB;CAEzB,YAAY,AAAiB,MAAqB;EAArB;CAAsB;CAEnD,OAAc,OAAO,QAAgB,OAA4B;EAC7D,MAAM,eAAe,IAAI,oBAAoB;EAC7C,MAAM,gBAAgB,IAAI,OAAO,WAAW,EAAE,SAAS,MAAM,CAAC;EAC9D,MAAM,eAAe,IAAI,OAAO,UAAU,EAAE,SAAS,MAAM,CAAC;EAC5D,MAAM,mBAAmB,WACrB,wBAAwB,eAAe,WAAW,MAAM,UAAU,MAAM,GAAG,MAAM;EAErF,OAAO,IAAI,UAAU;GACjB,SAAS,IAAI,cAAc,MAAM;GACjC,cAAc,IAAI,aAAa,cAAc,MAAM;GACnD;GACA,SAAS,cAAc,OAAO,aAAa;GAC3C;GACA,QAAQ,IAAI,aAAa,iBAAiB,YAAY;EAC1D,CAAC;CACL;CAEA,MAAa,MAAqB;EAC9B,IAAI,KAAK,WAAW;EACpB,KAAK,YAAY;EAEjB,IAAI;GACA,OAAO,CAAC,KAAK,YACT,IAAI;IACA,IAAI,KAAK,gBAAgB;KACrB,MAAM,KAAK,mBAAmB;KAC9B;IACJ;IAEA,MAAM,KAAK,WAAW;GAC1B,SAAS,OAAgB;IAErB,IAAI,KAAK,YAAY;IACrB,MAAM,KAAK,YAAY,KAAK;GAChC;EAER,UAAU;GACN,KAAK,YAAY;GACjB,MAAM,KAAK;EACf;CACJ;CAEA,MAAc,qBAAoC;EAC9C,KAAK,KAAK,MAAM,SAAS,cAAc;EACvC,KAAK,KAAK,MAAM,UAAU,mCAAmC;EAC7D,KAAK,KAAK,MAAM,QAAQ,KAAK;EAC7B,MAAM,KAAK,cAAc;EACzB,KAAK,KAAK,MAAM,QAAQ,IAAI;EAC5B,IAAI,CAAC,KAAK,YACN,KAAK,iBAAiB;CAE9B;CAEA,MAAc,aAA4B;EACtC,mBAAmB;EACnB,KAAK,KAAK,MAAM,SAAS,UAAU;EACnC,KAAK,KAAK,MAAM,QAAQ,IAAI;EAC5B,MAAM,SAAS,MAAM,KAAK,WAAW;EACrC,YAAY,QAAQ;EACpB,KAAK,KAAK,MAAM,iBAAiB,OAAO,aAAa;EACrD,MAAM,UAAU,IAAI,eAAe;EACnC,KAAK,iBAAiB,IAAI,WAAW,QAAQ,SAAS,KAAK,KAAK,QAAQ,UAAU;GAC9E,AAAK,KAAK,KAAK,OAAO,MAAM,OAAO,QAAQ,KAAK;EACpD,CAAC;EAED,IAAI;GACA,MAAM,KAAK,eAAe,YAAY;IAClC,KAAK,KAAK,MAAM,QAAQ,KAAK;GACjC,CAAC;EACL,UAAU;GACN,KAAK,KAAK,MAAM,QAAQ,IAAI;GAC5B,MAAM,KAAK,eAAe,QAAQ;GAClC,KAAK,iBAAiB;EAC1B;CACJ;CAEA,MAAc,YAAY,OAA+B;EACrD,KAAK,KAAK,MAAM,SAAS,OAAO;EAChC,KAAK,KAAK,MAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;EAChF,KAAK,KAAK,MAAM,UAAU,qBAAqB;EAC/C,KAAK,KAAK,MAAM,QAAQ,KAAK;EAC7B,MAAM,KAAK,cAAc;EACzB,KAAK,KAAK,MAAM,QAAQ,IAAI;CAChC;CAGA,MAAa,OAAsB;EAC/B,KAAK,aAAa,KAAK,QAAQ;EAC/B,OAAO,KAAK;CAChB;CAEA,MAAc,UAAyB;EACnC,KAAK,aAAa;EAClB,KAAK,KAAK,MAAM,SAAS,UAAU;EACnC,MAAM,KAAK,gBAAgB,KAAK;EAEhC,MAAM,aAAa,KAAK,KAAK,OAAO,KAAK,GAAG,kBAAkB;EAC9D,KAAK,gBAAgB;CACzB;CAEA,MAAa,UAAyB;EAClC,KAAK,iBAAiB;EACtB,MAAM,KAAK,gBAAgB,KAAK;EAChC,KAAK,gBAAgB;CACzB;CAGA,MAAa,aAA4B;EAErC,IAAI,KAAK,gBAAgB;EACzB,KAAK,iBAAiB;EACtB,MAAM,KAAK,gBAAgB,KAAK;EAChC,KAAK,gBAAgB;CACzB;CAEA,AAAO,gBAAgB,eAA8B;EACjD,IAAI,eAAe,AAAK,KAAK,mBAAmB;EAChD,KAAK,gBAAgB,gBAAgB,aAAa;CACtD;CAGA,MAAc,qBAAoC;EAC9C,IAAI,KAAK,gBAAgB;EACzB,KAAK,iBAAiB;EACtB,IAAI;GACA,MAAM,KAAK,KAAK,QAAQ,IAAI,KAAK;EACrC,SAAS,OAAgB;GAErB,KAAK,KAAK,cAAc,MAAM,wCAAwC,KAAK;EAC/E,UAAU;GACN,KAAK,iBAAiB;EAC1B;CACJ;CAEA,MAAc,gBAA+B;EACzC,OAAO,IAAI,SAAe,YAAY;GAClC,KAAK,gBAAgB;EACzB,CAAC;CACL;CAEA,MAAc,aAAiD;EAC3D,MAAM,aAAa,KAAK,KAAK,QAAQ,OAAO;EAC5C,OAAO,KAAK,KAAK,aAAa,KAAK,UAAU;CACjD;AACJ;;;;AC7KA,IAAa,aAAb,cAAgC,YAAY;CACxC,cAAc;EACV,MAAM,OAAO,gDAAgD,KAAK;CACtE;CAEA,AAAO,SAAS,SAAwB;EACpC,QACK,QAAQ,KAAK,IAAI,CAAC,CAClB,YAAY,KAAK,WAAW,CAAC,CAC7B,OAAO,YAAY;GAChB,cAAc;GACd,MAAM,QAAQ,IAAI,SAAS;GAC3B,MAAM,SAAS,UAAU,OAAO,KAAK,QAAQ,KAAK;GAGlD,MAAM,iBAAuB;IACzB,AAAK,OAAO,KAAK;GACrB;GACA,QAAQ,KAAK,UAAU,QAAQ;GAC/B,QAAQ,KAAK,WAAW,QAAQ;GAEhC,IAAI;IACA,MAAM,KAAK,UAAU,OAAO,MAAM;GACtC,SAAS,OAAgB;IACrB,KAAK,OAAO,MAAM,uBAAuB,KAAK;IAC9C,QAAQ,WAAW;GACvB,UAAU;IACN,QAAQ,IAAI,UAAU,QAAQ;IAC9B,QAAQ,IAAI,WAAW,QAAQ;GACnC;GAGA,MAAM,KAAK,iBAAiB;GAG5B,QAAQ,KAAK;EACjB,CAAC;CACT;CAGA,MAAc,MAAM,MAA6B;EAC7C,OAAO,IAAI,SAAS,YAAY;GAC5B,QAAQ,OAAO,MAAM,YAAY;IAC7B,QAAQ;GACZ,CAAC;EACL,CAAC;CACL;CAEA,MAAc,mBAAkC;EAC5C,MAAM,KAAK,MAAM,qCAAqC;EAEtD,MAAM,SAAS,cAAc;EAC7B,IAAI,WAAW,MAAM,MAAM,KAAK,MAAM,GAAG,OAAO,GAAG;CACvD;CAEA,MAAc,UAAU,OAAiB,QAAkC;EACvE,IAAI;EACJ,IAAI,YAA2B,QAAQ,QAAQ;EAE/C,MAAM,EAAE,SAAS,kBAAkB,OAC/B,MAAM,cAAc,QAAQ;GACxB;GACA,cAAc,OAAO,KAAK;GAC1B,oBAAoB,OAAO,WAAW;GACtC,iBAAiB,OAAO,QAAQ;GAChC,oBAAoB,kBAA2B,OAAO,gBAAgB,aAAa;GACnF,eAAe;IACX,YAAY,OACP,IAAI,CAAC,CACL,QAAQ,YAAY;KAEjB,MAAM,SAAS,SAAS,MAAM;KAC9B,QAAQ;IACZ,CAAC,CAAC,CAED,OAAO,UAAmB;KACvB,UAAU,EAAE,MAAM;IACtB,CAAC;GACT;EACJ,CAAC,GAED;GACI,aAAa;GACb,iBAAiB;GACjB,WAAW,EAAE,iBAAiB;IAC1B,aAAa,UAAU;GAC3B;EACJ,CACJ;EAEA,MAAM,cAAc;EAEpB,MAAM;EACN,IAAI,SAAS,MAAM,QAAQ;CAC/B;AACJ;;;;AChGA,eAAe,OAAsB;CACjC,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,IAAI,eAAe,CAAC,QAAQ,IAAI,UAC7D,SAAS,cAAc,YAAY;CAGvC,oBAAoB;CAEpB,MAAM,UAAU,IAAI,QAAQ,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,YAAY,cAAc,CAAC,CAAC,QAAQ,OAAO;CAE1F,IAAI,WAAW,CAAC,CAAC,SAAS,OAAO;CACjC,IAAI,aAAa,CAAC,CAAC,SAAS,OAAO;CACnC,IAAI,eAAe,CAAC,CAAC,SAAS,OAAO;CACrC,IAAI,gBAAgB,CAAC,CAAC,SAAS,OAAO;CAEtC,MAAM,QAAQ,WAAW,QAAQ,IAAI;AACzC;AAEK,KAAK,CAAC,CAAC,OAAO,UAAU;CAEzB,IADmB,OAAO,OAAO,EAAE,SAAS,MAAM,CAC7C,CAAC,CAAC,MAAM,wBAAwB,KAAK;CAC1C,QAAQ,KAAK,CAAC;AAClB,CAAC"}
|