@botlr/cli 0.2.0 → 0.4.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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/config.ts","../src/client.ts","../src/commands/list.ts","../src/commands/pull.ts","../src/lock.ts","../src/manifest.ts","../src/registry.ts","../src/init.ts","../src/typegen.ts","../src/commands/push.ts","../src/drift.ts","../src/commands/status.ts","../src/status.ts","../src/commands/init.ts","../src/output.ts"],"sourcesContent":["import { Command, InvalidArgumentError } from \"commander\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { loadConfig, type ConfigOverrides } from \"./config\";\nimport { listSections } from \"./commands/list\";\nimport { pullSections } from \"./commands/pull\";\nimport { pushSection, PushConflict } from \"./commands/push\";\nimport { sectionStatuses } from \"./commands/status\";\nimport { initSections } from \"./commands/init\";\nimport { fail, table } from \"./output\";\nimport { formatDriftWarning } from \"./drift\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nfunction parseVersion(value: string): number {\n const n = Number.parseInt(value, 10);\n if (!Number.isInteger(n) || n < 1) throw new InvalidArgumentError(\"version must be a positive integer\");\n return n;\n}\n\ntype CommonOptions = { framework?: string; dir?: string };\n\nfunction overrides(opts: CommonOptions): ConfigOverrides {\n return { framework: opts.framework, dir: opts.dir };\n}\n\nfunction withCommon(cmd: Command): Command {\n return cmd\n .option(\"--framework <name>\", \"source variant, for example react-next (default from config)\")\n .option(\"--dir <path>\", \"sections directory (default from config, components/sections)\");\n}\n\nasync function run(action: () => Promise<void>): Promise<void> {\n try {\n await action();\n } catch (error) {\n if (error instanceof PushConflict) {\n const latest = error.latest ? `v${error.latest.version} (${error.latest.contentHash.slice(0, 12)})` : \"none\";\n fail(`${error.message}\\n latest on server: ${latest}\\n pull first, or push --force to overwrite`);\n }\n fail((error as Error).message);\n }\n}\n\nconst program = new Command(\"botlr\")\n .description(\"Pull and push section source between a Botlr site and this app\")\n .version(version)\n .configureHelp({ sortSubcommands: true });\n\nwithCommon(\n program\n .command(\"pull [names...]\")\n .description(\"pull sections into the sections directory; writes <name>.botlr.json and the lock file\")\n .option(\"--all\", \"every section the server lists for the framework\")\n .option(\"--version <n>\", \"a specific version instead of the latest\", parseVersion)\n .option(\"--shared\", \"the shared row (per section definition) even when the app has its own\")\n .option(\"--force\", \"overwrite files that changed locally since the last pull\")\n .option(\"--no-registry\", \"do not add the section to the registry file\")\n .option(\"--no-types\", \"do not write <name>.props.ts from the definition's props schema\"),\n).action((names: string[], opts: CommonOptions & { all?: boolean; version?: number; shared?: boolean; force?: boolean; registry?: boolean; types?: boolean }) =>\n run(async () => {\n if (names.length === 0 && !opts.all) fail(\"name a section or pass --all\");\n if (opts.all && opts.version !== undefined) fail(\"--version needs a single section name\");\n const config = await loadConfig(process.cwd(), overrides(opts));\n const results = await pullSections(config, {\n names,\n all: opts.all,\n version: opts.version,\n shared: opts.shared,\n force: opts.force,\n noRegistry: opts.registry === false,\n noTypes: opts.types === false,\n });\n if (results.length === 0) {\n console.log(\"nothing to pull\");\n return;\n }\n for (const r of results) {\n if (r.skipped) {\n console.log(`skip ${r.name}: ${r.skipped}`);\n continue;\n }\n console.log(`pull ${r.name} ${r.scope} v${r.version} (${r.files.length} file${r.files.length === 1 ? \"\" : \"s\"})`);\n if (r.types?.changed) console.log(` types: wrote ${r.types.interfaceName} to ${path.relative(process.cwd(), r.types.file)}`);\n if (r.typesNotice) console.log(` types: ${r.typesNotice}`);\n const registry = r.registry;\n if (!registry) continue;\n const file = path.relative(process.cwd(), registry.file);\n if (registry.notice) console.log(` registry: ${registry.notice}`);\n else if (registry.changed) {\n const what = [registry.addedImport ? \"import\" : \"\", registry.addedEntry ? `\"${r.name}\" entry` : \"\"].filter(Boolean).join(\" and \");\n console.log(` registry: added ${what} to ${file}`);\n }\n }\n }),\n);\n\nwithCommon(\n program\n .command(\"push <name>\")\n .description(\"push the section's files and manifest as a new version (needs BOTLR_PAT)\")\n .option(\"-m, --message <text>\", \"a note on the version, at most 500 characters\")\n .option(\"--shared\", \"write the shared row (per section definition) instead of this app's row\")\n .option(\"--create\", \"create the section definition when the dashboard does not have it\")\n .option(\"--force\", \"skip the conflict check (omits baseVersion)\"),\n).action((name: string, opts: CommonOptions & { message?: string; shared?: boolean; create?: boolean; force?: boolean }) =>\n run(async () => {\n const config = await loadConfig(process.cwd(), overrides(opts));\n const result = await pushSection(config, {\n name,\n message: opts.message,\n shared: opts.shared,\n create: opts.create,\n force: opts.force,\n });\n if (result.created) console.log(`pushed ${result.name} ${result.scope} v${result.version}`);\n else console.log(`${result.name} ${result.scope} v${result.version} already matches, nothing pushed`);\n if (result.drift) process.stderr.write(`${formatDriftWarning(result.name, result.drift)}\\n`);\n }),\n);\n\nconst sections = program.command(\"sections\").description(\"list, inspect and bootstrap sections\");\n\nwithCommon(sections.command(\"list\").description(\"every section the server has source for\")).action(\n (opts: CommonOptions) =>\n run(async () => {\n const config = await loadConfig(process.cwd(), overrides(opts));\n const rows = await listSections(config);\n if (rows.length === 0) {\n console.log(`no ${config.framework} sections for app ${config.appId}`);\n return;\n }\n const v = (s: { version: number } | null) => (s ? `v${s.version}` : \"-\");\n console.log(\n table(\n rows.map((s) => [s.name, s.title, v(s.instance), v(s.shared), s.effective]),\n [\"name\", \"title\", \"instance\", \"shared\", \"effective\"],\n ),\n );\n }),\n);\n\nwithCommon(\n sections\n .command(\"status [names...]\")\n .description(\"clean | modified | behind | diverged per local manifest\")\n .option(\"--offline\", \"compare with the lock file only, without asking the server\"),\n).action((names: string[], opts: CommonOptions & { offline?: boolean }) =>\n run(async () => {\n const config = await loadConfig(process.cwd(), overrides(opts));\n const rows = await sectionStatuses(config, { names, offline: opts.offline });\n if (rows.length === 0) {\n console.log(`no *.botlr.json manifests in ${config.sectionsDir}`);\n return;\n }\n console.log(\n table(\n rows.map((r) => [\n r.name,\n r.status,\n r.local === null ? \"-\" : `v${r.local}`,\n r.remote === null ? \"-\" : `v${r.remote}`,\n r.scope,\n r.detail ?? \"\",\n ]),\n [\"name\", \"status\", \"local\", \"remote\", \"scope\", \"\"],\n ),\n );\n for (const r of rows) {\n if (r.drift) process.stderr.write(`${formatDriftWarning(r.name, r.drift)}\\n`);\n }\n if (rows.some((r) => r.status === \"diverged\" || r.status === \"error\")) process.exitCode = 1;\n }),\n);\n\nwithCommon(\n sections\n .command(\"init\")\n .description(\"derive first <name>.botlr.json manifests from publisher-section-registry.ts and the XDefinition exports\")\n .option(\"--force\", \"overwrite manifests that already exist\")\n .option(\"--dry-run\", \"show what would be written\"),\n).action((opts: CommonOptions & { force?: boolean; dryRun?: boolean }) =>\n run(async () => {\n const config = await loadConfig(process.cwd(), overrides(opts));\n const results = await initSections(config, { force: opts.force, dryRun: opts.dryRun });\n for (const r of results) {\n console.log(`${r.written ? \"write\" : opts.dryRun ? \"would\" : \"keep \"} ${r.name} -> ${r.file}`);\n }\n if (results.length === 0) console.log(\"the registry maps no components with a file next to it\");\n else console.log(`\\nreview the manifests, then push each section: botlr push <name> --create`);\n }),\n);\n\nprogram.parseAsync(process.argv).catch((error: unknown) => fail((error as Error).message));\n","import { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport const CONFIG_FILE = \"botlr.config.json\";\nexport const DEFAULT_FRAMEWORK = \"react-next\";\nexport const DEFAULT_SECTIONS_DIR = \"components/sections\";\nexport const DEFAULT_REGISTRY_FILE = \"publisher-section-registry.ts\";\n\n/** `botlr.config.json` */\nexport interface BotlrCliConfigFile {\n baseUrl?: string;\n appId?: string;\n framework?: string;\n sectionsDir?: string;\n /** Registry file `pull` keeps up to date, relative to `sectionsDir`. Default `publisher-section-registry.ts`. */\n registryFile?: string;\n /** Write `<name>.props.ts` after a pull. Default true; `false` turns it off (`--no-types` does per call). */\n types?: boolean;\n}\n\nexport interface ResolvedConfig {\n /** Directory holding `botlr.config.json` (or the cwd when there is none). Paths resolve against it. */\n root: string;\n configPath: string | null;\n baseUrl: string;\n appId: string;\n framework: string;\n /** Absolute path of the sections directory. */\n sectionsDir: string;\n /** Absolute path of the registry file (`sectionsDir/publisher-section-registry.ts` by default); it may not exist. */\n registryFile: string;\n /** Whether `pull` writes `<name>.props.ts` from the definition's schema. */\n types: boolean;\n /** Site token, `BOTLR_API_KEY`. */\n apiKey: string | undefined;\n /** Personal access token, `BOTLR_PAT`. */\n personalToken: string | undefined;\n}\n\nexport interface ConfigOverrides {\n framework?: string;\n /** Sections directory, relative to the cwd (as typed on the command line). */\n dir?: string;\n baseUrl?: string;\n appId?: string;\n}\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigError\";\n }\n}\n\nasync function exists(file: string): Promise<boolean> {\n try {\n await access(file);\n return true;\n } catch {\n return false;\n }\n}\n\n/** The nearest `botlr.config.json` at or above `startDir`, or null. */\nexport async function findConfigFile(startDir: string): Promise<string | null> {\n let dir = path.resolve(startDir);\n for (;;) {\n const candidate = path.join(dir, CONFIG_FILE);\n if (await exists(candidate)) return candidate;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\nexport async function readConfigFile(file: string): Promise<BotlrCliConfigFile> {\n const raw = await readFile(file, \"utf8\");\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new ConfigError(`${file} must hold a JSON object`);\n }\n return parsed as BotlrCliConfigFile;\n } catch (error) {\n if (error instanceof ConfigError) throw error;\n throw new ConfigError(`${file} is not valid JSON: ${(error as Error).message}`);\n }\n}\n\n/**\n * The effective config: command-line overrides, then environment\n * (`BOTLR_BASE_URL`, `BOTLR_APP_ID`, `BOTLR_FRAMEWORK`, `BOTLR_SECTIONS_DIR`),\n * then `botlr.config.json`, then defaults. Tokens come from `BOTLR_API_KEY`\n * and `BOTLR_PAT` only.\n */\nexport async function loadConfig(\n cwd: string,\n overrides: ConfigOverrides = {},\n env: NodeJS.ProcessEnv = process.env,\n): Promise<ResolvedConfig> {\n const configPath = await findConfigFile(cwd);\n const file = configPath ? await readConfigFile(configPath) : {};\n const root = configPath ? path.dirname(configPath) : path.resolve(cwd);\n\n const baseUrl = overrides.baseUrl ?? env.BOTLR_BASE_URL ?? file.baseUrl;\n const appId = overrides.appId ?? env.BOTLR_APP_ID ?? file.appId;\n if (!baseUrl) {\n throw new ConfigError(`No baseUrl: set it in ${CONFIG_FILE} or BOTLR_BASE_URL`);\n }\n if (!appId) {\n throw new ConfigError(`No appId: set it in ${CONFIG_FILE} or BOTLR_APP_ID`);\n }\n\n const sectionsDir = overrides.dir\n ? path.resolve(cwd, overrides.dir)\n : path.resolve(root, env.BOTLR_SECTIONS_DIR ?? file.sectionsDir ?? DEFAULT_SECTIONS_DIR);\n\n return {\n root,\n configPath,\n baseUrl: baseUrl.replace(/\\/+$/, \"\"),\n appId,\n framework: overrides.framework ?? env.BOTLR_FRAMEWORK ?? file.framework ?? DEFAULT_FRAMEWORK,\n sectionsDir,\n registryFile: path.resolve(sectionsDir, file.registryFile ?? DEFAULT_REGISTRY_FILE),\n types: file.types !== false,\n apiKey: env.BOTLR_API_KEY || undefined,\n personalToken: env.BOTLR_PAT || undefined,\n };\n}\n","import { createBotlrClient, type BotlrClient } from \"@botlr/sdk\";\nimport { ConfigError, type ResolvedConfig } from \"./config\";\n\n/** A client from the resolved config. `needPersonalToken` makes a missing `BOTLR_PAT` an error up front. */\nexport function clientFor(config: ResolvedConfig, options: { needPersonalToken?: boolean } = {}): BotlrClient {\n if (!config.apiKey && !options.needPersonalToken) {\n // Reads work without a token against a dev server; warn once so a 401 is no surprise.\n process.stderr.write(\"botlr: BOTLR_API_KEY is not set, requests go out without a site token\\n\");\n }\n if (options.needPersonalToken && !config.personalToken) {\n throw new ConfigError(\"Pushing needs BOTLR_PAT: a personal access token with the write:sections scope\");\n }\n return createBotlrClient({\n baseUrl: config.baseUrl,\n appId: config.appId,\n apiKey: config.apiKey,\n personalToken: config.personalToken,\n });\n}\n","import type { SectionSourceSummary } from \"@botlr/sdk\";\nimport type { ResolvedConfig } from \"../config\";\nimport { clientFor } from \"../client\";\n\nexport async function listSections(config: ResolvedConfig): Promise<SectionSourceSummary[]> {\n const client = clientFor(config);\n const listing = await client.sections.list({ framework: config.framework });\n return listing.sections;\n}\n","import { contentHash, type SectionSourcePullResponse, type SectionSourceScope } from \"@botlr/sdk\";\nimport type { ResolvedConfig } from \"../config\";\nimport { clientFor } from \"../client\";\nimport { nextLockEntry, readLock, writeLock, type LockEntry } from \"../lock\";\nimport { readManifest, readSectionFiles, writeManifestIfChanged, writeSectionFiles } from \"../manifest\";\nimport { registerSection, type RegistryUpdate } from \"../registry\";\nimport { writePropsTypes, type PropsTypesUpdate } from \"../typegen\";\n\nexport interface PullOptions {\n /** Section names; empty with `all: true` pulls every section the server lists. */\n names: string[];\n all?: boolean;\n version?: number;\n /** Pull the shared row even when the app has its own. */\n shared?: boolean;\n /** Overwrite local files that changed since the last pull. */\n force?: boolean;\n /** Leave the registry file alone. */\n noRegistry?: boolean;\n /** Do not write `<name>.props.ts`; also off when the config says `types: false`. */\n noTypes?: boolean;\n}\n\nexport interface PullResult {\n name: string;\n scope: SectionSourceScope;\n version: number;\n files: string[];\n /** Set when the section was skipped instead of written. */\n skipped?: string;\n /** Whether `<name>.botlr.json` changed; false when the local manifest already said the same. */\n manifestChanged?: boolean;\n /** What happened to the registry file; absent for skipped sections and with `noRegistry`. */\n registry?: RegistryUpdate;\n /** What happened to `<name>.props.ts`; absent when types are off or the section has no definition. */\n types?: PropsTypesUpdate;\n /** Why no prop types were written, when they were expected. */\n typesNotice?: string;\n}\n\n/** Content hash of the local files, or null when the manifest or a file is missing. */\nasync function localHash(sectionsDir: string, name: string): Promise<string | null> {\n try {\n const manifest = await readManifest(sectionsDir, name);\n return await contentHash(await readSectionFiles(sectionsDir, manifest));\n } catch {\n return null;\n }\n}\n\nexport async function pullSections(config: ResolvedConfig, options: PullOptions): Promise<PullResult[]> {\n const client = clientFor(config);\n const scope: SectionSourceScope | undefined = options.shared ? \"shared\" : undefined;\n\n let names = options.names;\n if (options.all) {\n const listing = await client.sections.list({ framework: config.framework });\n names = listing.sections\n .filter((s) => (options.shared ? s.shared : s.instance || s.shared))\n .map((s) => s.name);\n }\n if (names.length === 0) return [];\n\n const lock = await readLock(config.root);\n const results: PullResult[] = [];\n\n for (const name of names) {\n const entry = lock[name];\n if (entry && !options.force) {\n const current = await localHash(config.sectionsDir, name);\n if (current !== null && current !== entry.contentHash) {\n results.push({ name, scope: entry.scope, version: entry.version, files: [], skipped: \"modified locally, use --force to overwrite\" });\n continue;\n }\n }\n\n const response: SectionSourcePullResponse = await client.sections.pull(name, {\n framework: config.framework,\n version: options.version,\n scope,\n });\n const { source } = response;\n\n const files = await writeSectionFiles(config.sectionsDir, source.files);\n const manifest = await writeManifestIfChanged(config.sectionsDir, name, source.manifest);\n const registry = options.noRegistry\n ? undefined\n : await registerSection(config.sectionsDir, config.registryFile, source.manifest);\n\n let types: PropsTypesUpdate | undefined;\n let typesNotice: string | undefined;\n if (config.types && !options.noTypes) {\n if (response.definition) {\n types = await writePropsTypes(config.sectionsDir, source.manifest, response.definition.schema);\n } else {\n typesNotice = \"no section definition resolves for this section, no prop types written\";\n }\n }\n\n const fresh: LockEntry = {\n scope: source.scope,\n framework: source.framework,\n version: source.version,\n contentHash: source.contentHash,\n pulledAt: new Date().toISOString(),\n };\n lock[name] = nextLockEntry(entry, fresh);\n results.push({\n name,\n scope: source.scope,\n version: source.version,\n files,\n manifestChanged: manifest.changed,\n registry,\n types,\n typesNotice,\n });\n }\n\n await writeLock(config.root, lock);\n return results;\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { SectionSourceScope } from \"@botlr/sdk\";\n\nexport const LOCK_DIR = \".botlr\";\nexport const LOCK_FILE = \"sections.lock.json\";\n\nexport interface LockEntry {\n scope: SectionSourceScope;\n framework: string;\n version: number;\n contentHash: string;\n /**\n * ISO timestamp of the pull or push that first put this version here. A\n * pull that lands the same scope, version and hash again keeps it, so\n * re-pulling does not touch the lock file.\n */\n pulledAt: string;\n}\n\n/**\n * `.botlr/sections.lock.json`: one entry per section name, for the whole\n * app. The lock is not keyed by directory: `--dir` points a command at\n * another sections directory but still records into this one lock, so a\n * section name means one thing per app whichever directory holds it.\n */\nexport type SectionsLock = Record<string, LockEntry>;\n\n/**\n * The entry to record after a pull or push: `fresh` with the previous\n * `pulledAt` kept when scope, framework, version and hash are unchanged.\n */\nexport function nextLockEntry(previous: LockEntry | undefined, fresh: LockEntry): LockEntry {\n if (\n previous &&\n previous.scope === fresh.scope &&\n previous.framework === fresh.framework &&\n previous.version === fresh.version &&\n previous.contentHash === fresh.contentHash\n ) {\n return { ...fresh, pulledAt: previous.pulledAt };\n }\n return fresh;\n}\n\nexport function lockPath(root: string): string {\n return path.join(root, LOCK_DIR, LOCK_FILE);\n}\n\nexport async function readLock(root: string): Promise<SectionsLock> {\n try {\n const raw = await readFile(lockPath(root), \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return {};\n return parsed as SectionsLock;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n throw error;\n }\n}\n\nexport async function writeLock(root: string, lock: SectionsLock): Promise<void> {\n const file = lockPath(root);\n await mkdir(path.dirname(file), { recursive: true });\n const sorted = Object.fromEntries(Object.entries(lock).sort(([a], [b]) => a.localeCompare(b)));\n await writeFile(file, `${JSON.stringify(sorted, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function updateLock(root: string, name: string, entry: LockEntry): Promise<SectionsLock> {\n const lock = await readLock(root);\n lock[name] = nextLockEntry(lock[name], entry);\n await writeLock(root, lock);\n return lock;\n}\n","import { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n isValidSectionPath,\n stripManifestState,\n type SectionManifest,\n type SectionSourceFileInput,\n} from \"@botlr/sdk\";\n\nexport const MANIFEST_SUFFIX = \".botlr.json\";\n\nexport class ManifestError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ManifestError\";\n }\n}\n\nexport function manifestPath(sectionsDir: string, name: string): string {\n return path.join(sectionsDir, `${name}${MANIFEST_SUFFIX}`);\n}\n\n/** Section names that have a manifest in `sectionsDir`, sorted. */\nexport async function listManifests(sectionsDir: string): Promise<string[]> {\n let entries: string[];\n try {\n entries = await readdir(sectionsDir);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n return entries\n .filter((entry) => entry.endsWith(MANIFEST_SUFFIX))\n .map((entry) => entry.slice(0, -MANIFEST_SUFFIX.length))\n .sort();\n}\n\nexport async function readManifest(sectionsDir: string, name: string): Promise<SectionManifest> {\n const file = manifestPath(sectionsDir, name);\n let raw: string;\n try {\n raw = await readFile(file, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new ManifestError(`No manifest for '${name}': expected ${file}`);\n }\n throw error;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n throw new ManifestError(`${file} is not valid JSON: ${(error as Error).message}`);\n }\n return validateManifest(parsed, file);\n}\n\nexport function validateManifest(value: unknown, where = \"manifest\"): SectionManifest {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new ManifestError(`${where} must be a JSON object`);\n }\n const m = value as Record<string, unknown>;\n if (typeof m.section !== \"string\" || !m.section) throw new ManifestError(`${where}: 'section' is required`);\n if (typeof m.entry !== \"string\" || !m.entry) throw new ManifestError(`${where}: 'entry' is required`);\n if (!Array.isArray(m.files) || m.files.length === 0 || !m.files.every((f) => typeof f === \"string\")) {\n throw new ManifestError(`${where}: 'files' must list at least one path`);\n }\n const files = m.files as string[];\n for (const file of files) {\n if (!isValidSectionPath(file)) throw new ManifestError(`${where}: invalid file path '${file}'`);\n }\n if (!files.includes(m.entry)) throw new ManifestError(`${where}: 'entry' (${m.entry}) must be listed in 'files'`);\n if (m.framework !== undefined && typeof m.framework !== \"string\") {\n throw new ManifestError(`${where}: 'framework' must be a string`);\n }\n return m as unknown as SectionManifest;\n}\n\n/** Top-level manifest keys in the order the CLI writes them; anything else follows alphabetically. */\nexport const MANIFEST_KEY_ORDER = [\n \"section\",\n \"framework\",\n \"entry\",\n \"exportName\",\n \"files\",\n \"title\",\n \"description\",\n \"category\",\n \"icon\",\n \"dependencies\",\n \"schema\",\n] as const;\n\nconst DEPENDENCIES_KEY_ORDER = [\"npm\", \"internal\"] as const;\n\nfunction orderKeys(value: Record<string, unknown>, first: readonly string[]): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const key of first) {\n if (key in value && value[key] !== undefined) out[key] = value[key];\n }\n for (const key of Object.keys(value).sort()) {\n if (first.includes(key) || value[key] === undefined) continue;\n out[key] = value[key];\n }\n return out;\n}\n\nfunction normalizeNested(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(normalizeNested);\n if (value && typeof value === \"object\") {\n const record = value as Record<string, unknown>;\n const ordered = orderKeys(record, []);\n for (const key of Object.keys(ordered)) ordered[key] = normalizeNested(ordered[key]);\n return ordered;\n }\n return value;\n}\n\n/**\n * The manifest with pull state removed and keys in a fixed order: the known\n * keys first (`MANIFEST_KEY_ORDER`), then unknown keys alphabetically;\n * `dependencies` lists `npm` before `internal`, and every nested object is\n * sorted alphabetically. Arrays keep their order. The server stores\n * manifests as jsonb, which forgets key order, so this is what makes a pull\n * after a push write the same bytes.\n */\nexport function normalizeManifest(manifest: SectionManifest): SectionManifest {\n const stripped = stripManifestState(manifest) as Record<string, unknown>;\n const ordered = orderKeys(stripped, MANIFEST_KEY_ORDER);\n for (const key of Object.keys(ordered)) {\n if (key === \"dependencies\" && ordered[key] && typeof ordered[key] === \"object\" && !Array.isArray(ordered[key])) {\n const deps = orderKeys(ordered[key] as Record<string, unknown>, DEPENDENCIES_KEY_ORDER);\n for (const depKey of Object.keys(deps)) deps[depKey] = normalizeNested(deps[depKey]);\n ordered[key] = deps;\n } else {\n ordered[key] = normalizeNested(ordered[key]);\n }\n }\n return ordered as unknown as SectionManifest;\n}\n\n/** The exact text `writeManifest` writes: normalized, 2-space JSON, trailing newline. */\nexport function formatManifest(manifest: SectionManifest): string {\n return `${JSON.stringify(normalizeManifest(manifest), null, 2)}\\n`;\n}\n\n/** True when two manifests hold the same data, whatever their key order or formatting. */\nexport function manifestsEqual(a: SectionManifest, b: SectionManifest): boolean {\n return formatManifest(a) === formatManifest(b);\n}\n\n/** Write `<name>.botlr.json` without any pull state, in the CLI's fixed key order. */\nexport async function writeManifest(sectionsDir: string, name: string, manifest: SectionManifest): Promise<string> {\n const file = manifestPath(sectionsDir, name);\n await mkdir(sectionsDir, { recursive: true });\n await writeFile(file, formatManifest(manifest), \"utf8\");\n return file;\n}\n\n/**\n * Like `writeManifest`, but leaves the file alone when it already holds the\n * same manifest (compared after normalization, so a hand-formatted file that\n * says the same thing is not rewritten). Returns whether the file changed.\n */\nexport async function writeManifestIfChanged(\n sectionsDir: string,\n name: string,\n manifest: SectionManifest,\n): Promise<{ file: string; changed: boolean }> {\n const file = manifestPath(sectionsDir, name);\n try {\n const existing = JSON.parse(await readFile(file, \"utf8\")) as unknown;\n if (existing && typeof existing === \"object\" && !Array.isArray(existing)) {\n if (manifestsEqual(existing as SectionManifest, manifest)) return { file, changed: false };\n }\n } catch {\n // missing or unreadable: write it\n }\n await writeManifest(sectionsDir, name, manifest);\n return { file, changed: true };\n}\n\n/** The files a manifest lists, read from `sectionsDir`, in manifest order. */\nexport async function readSectionFiles(\n sectionsDir: string,\n manifest: SectionManifest,\n): Promise<SectionSourceFileInput[]> {\n return Promise.all(\n manifest.files.map(async (relative) => {\n const file = safeJoin(sectionsDir, relative);\n try {\n return { path: relative, content: await readFile(file, \"utf8\") };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new ManifestError(`Missing file '${relative}' listed in ${manifest.section}${MANIFEST_SUFFIX}`);\n }\n throw error;\n }\n }),\n );\n}\n\n/** Write pulled files under `sectionsDir`, creating sub-directories. */\nexport async function writeSectionFiles(sectionsDir: string, files: SectionSourceFileInput[]): Promise<string[]> {\n const written: string[] = [];\n for (const file of files) {\n const target = safeJoin(sectionsDir, file.path);\n await mkdir(path.dirname(target), { recursive: true });\n await writeFile(target, file.content, \"utf8\");\n written.push(target);\n }\n return written;\n}\n\n/** `relative` joined under `dir`, refusing paths the bridge would not accept. */\nexport function safeJoin(dir: string, relative: string): string {\n if (!isValidSectionPath(relative)) throw new ManifestError(`Invalid file path '${relative}'`);\n const target = path.resolve(dir, relative);\n const base = path.resolve(dir);\n if (target !== base && !target.startsWith(base + path.sep)) {\n throw new ManifestError(`File path '${relative}' escapes ${dir}`);\n }\n return target;\n}\n","/**\n * Registry upkeep: after a pull, make sure the satellite's\n * `publisher-section-registry.ts` imports the pulled component and maps the\n * section slug to it. The file is edited in place, by text: existing imports,\n * entries, comments and formatting are kept, and nothing is ever removed.\n */\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { SectionManifest } from \"@botlr/sdk\";\nimport { parseRegistry } from \"./init\";\n\nconst SOURCE_EXTENSIONS = [\".tsx\", \".ts\", \".jsx\", \".js\", \".mjs\", \".cjs\"];\n\nexport interface RegistryAddition {\n slug: string;\n exportName: string;\n /** Module specifier to import from, for example `./markdown`. */\n importPath: string;\n}\n\nexport interface RegistryEditResult {\n source: string;\n /** True when an import or a map entry was appended. */\n changed: boolean;\n addedImport: boolean;\n addedEntry: boolean;\n}\n\n/** `./markdown` for a registry at `sectionsDir` and an entry `markdown.tsx`; `./parts/x` for `parts/x.tsx`. */\nexport function importPathFor(registryFile: string, entryFile: string): string {\n const relative = path.relative(path.dirname(registryFile), entryFile).split(path.sep).join(\"/\");\n const ext = path.extname(relative);\n const bare = SOURCE_EXTENSIONS.includes(ext) ? relative.slice(0, -ext.length) : relative;\n return bare.startsWith(\".\") ? bare : `./${bare}`;\n}\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/**\n * Return `source` with `import { exportName } from \"importPath\";` added after\n * the last import and `slug: exportName,` added as the last entry of the\n * registry object. Each is skipped when it is already there. Quote style,\n * semicolons, indentation and trailing commas follow the surrounding code.\n */\nexport function addRegistryEntry(source: string, addition: RegistryAddition): RegistryEditResult {\n const { slug, exportName, importPath } = addition;\n if (!IDENTIFIER.test(exportName)) throw new Error(`'${exportName}' is not a valid export name`);\n\n const eol = source.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n let out = source;\n let addedImport = false;\n let addedEntry = false;\n\n // 1. Import.\n const importRe = /^[ \\t]*import\\s*(?:type\\s*)?\\{([^}]*)\\}\\s*from\\s*([\"'])([^\"']+)\\2[ \\t]*;?[ \\t]*$/gm;\n const imports = [...out.matchAll(importRe)];\n const alreadyImported = imports.some((m) =>\n m[1]!.split(\",\").some((raw) => raw.trim().split(/\\s+as\\s+/).pop()?.trim() === exportName),\n );\n if (!alreadyImported) {\n const last = imports.at(-1);\n const quote = last?.[2] ?? '\"';\n const semicolon = last ? last[0].trimEnd().endsWith(\";\") : true;\n const line = `import { ${exportName} } from ${quote}${importPath}${quote}${semicolon ? \";\" : \"\"}`;\n if (last) {\n const end = last.index! + last[0].length;\n out = `${out.slice(0, end)}${eol}${line}${out.slice(end)}`;\n } else {\n out = `${line}${eol}${eol}${out}`;\n }\n addedImport = true;\n }\n\n // 2. Map entry.\n const alreadyMapped = parseRegistry(out).some((e) => e.slug === slug) || hasEntry(out, slug);\n if (!alreadyMapped) {\n const object = findRegistryObject(out);\n if (!object) throw new Error(\"could not find the registry object (`export const ... = { ... }`)\");\n const body = out.slice(object.bodyStart, object.bodyEnd);\n const entryLines = body.split(/\\r?\\n/).filter((l) => /^\\s*(?:\"[^\"]+\"|'[^']+'|[A-Za-z0-9_$-]+)\\s*:/.test(l));\n const lastEntry = entryLines.at(-1);\n const indent = lastEntry?.match(/^\\s*/)?.[0] ?? \" \";\n const key = IDENTIFIER.test(slug) ? slug : `\"${slug}\"`;\n const entryLine = `${indent}${key}: ${exportName},`;\n\n let newBody = body;\n if (lastEntry !== undefined) {\n const stripped = lastEntry.replace(/\\/\\/.*$/, \"\").trimEnd();\n if (!stripped.endsWith(\",\")) {\n // Give the previous last entry a trailing comma so ours can follow it.\n const at = newBody.lastIndexOf(lastEntry);\n const fixed = lastEntry.replace(/^(\\s*(?:\"[^\"]+\"|'[^']+'|[A-Za-z0-9_$-]+)\\s*:\\s*[A-Za-z0-9_$]+)/, \"$1,\");\n newBody = `${newBody.slice(0, at)}${fixed}${newBody.slice(at + lastEntry.length)}`;\n }\n }\n newBody = `${newBody.replace(/\\s*$/, \"\")}${eol}${entryLine}`;\n out = `${out.slice(0, object.bodyStart)}${newBody}${out.slice(object.bodyEnd)}`;\n addedEntry = true;\n }\n\n return { source: out, changed: addedImport || addedEntry, addedImport, addedEntry };\n}\n\nfunction hasEntry(source: string, slug: string): boolean {\n const object = findRegistryObject(source);\n if (!object) return false;\n const body = source.slice(object.bodyStart, object.bodyEnd);\n const escaped = slug.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return new RegExp(`^\\\\s*(?:\"${escaped}\"|'${escaped}'|${escaped})\\\\s*:`, \"m\").test(body);\n}\n\n/** Offsets of the text between `{` and the closing `\\n}` of the registry object literal. */\nfunction findRegistryObject(source: string): { bodyStart: number; bodyEnd: number } | null {\n const open = source.match(/export\\s+const\\s+\\w+\\s*(?::[^=]*)?=\\s*\\{/) ?? source.match(/=\\s*\\{/);\n if (!open || open.index === undefined) return null;\n const bodyStart = open.index + open[0].length;\n const close = /\\r?\\n\\}/g;\n close.lastIndex = bodyStart;\n const closeMatch = close.exec(source);\n if (!closeMatch) return null;\n return { bodyStart, bodyEnd: closeMatch.index };\n}\n\nexport interface RegistryUpdate {\n /** Absolute path of the registry file. */\n file: string;\n /** False when nothing was added or the registry could not be updated. */\n changed: boolean;\n addedImport?: boolean;\n addedEntry?: boolean;\n /** Why nothing was written, for the user. */\n notice?: string;\n}\n\n/**\n * Add the pulled section to the registry file, when there is one. Returns a\n * notice instead of throwing when the registry is missing or the manifest has\n * no `exportName`, since a pull should still succeed.\n */\nexport async function registerSection(\n sectionsDir: string,\n registryFile: string,\n manifest: SectionManifest,\n): Promise<RegistryUpdate> {\n const name = path.basename(registryFile);\n let source: string;\n try {\n source = await readFile(registryFile, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return { file: registryFile, changed: false, notice: `no ${name} in ${path.dirname(registryFile)}, register the section yourself` };\n }\n throw error;\n }\n if (!manifest.exportName) {\n return { file: registryFile, changed: false, notice: `manifest has no exportName, ${name} not updated` };\n }\n const importPath = importPathFor(registryFile, path.resolve(sectionsDir, manifest.entry));\n let edit: RegistryEditResult;\n try {\n edit = addRegistryEntry(source, { slug: manifest.section, exportName: manifest.exportName, importPath });\n } catch (error) {\n return { file: registryFile, changed: false, notice: `${name} not updated: ${(error as Error).message}` };\n }\n if (edit.changed) await writeFile(registryFile, edit.source, \"utf8\");\n return { file: registryFile, changed: edit.changed, addedImport: edit.addedImport, addedEntry: edit.addedEntry };\n}\n","/**\n * `botlr sections init`: derive first manifests from a satellite app's\n * section components. It reads the registry map\n * (`publisher-section-registry.ts`) to learn which slug maps to which\n * component file, and each component's inline `XDefinition` export for the\n * title, category, description and icon. Nothing is pushed.\n */\nimport { readFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { SectionFieldSchema, SectionManifest, SectionSchemaField } from \"@botlr/sdk\";\n\nimport { DEFAULT_REGISTRY_FILE } from \"./config\";\n\n/** @deprecated use `DEFAULT_REGISTRY_FILE` from config; the path is configurable as `registryFile`. */\nexport const REGISTRY_FILE = DEFAULT_REGISTRY_FILE;\n\nexport interface RegistryEntry {\n slug: string;\n exportName: string;\n /** Module specifier as imported, for example `./Hero` */\n importPath: string;\n}\n\n/** Parse `import { X } from \"./File\"` plus `slug: X` map entries from a registry source. */\nexport function parseRegistry(source: string): RegistryEntry[] {\n const importedFrom = new Map<string, string>();\n const importRe = /import\\s*(?:type\\s*)?\\{([^}]*)\\}\\s*from\\s*[\"']([^\"']+)[\"']/g;\n for (const match of source.matchAll(importRe)) {\n const names = match[1]!;\n const spec = match[2]!;\n for (const raw of names.split(\",\")) {\n const name = raw.trim().split(/\\s+as\\s+/).pop()?.trim();\n if (name) importedFrom.set(name, spec);\n }\n }\n\n const bodyMatch = source.match(/=\\s*\\{([\\s\\S]*?)\\n\\}\\s*;?/);\n if (!bodyMatch) return [];\n const entries: RegistryEntry[] = [];\n const entryRe = /^\\s*(?:\"([^\"]+)\"|'([^']+)'|([A-Za-z0-9_$-]+))\\s*:\\s*([A-Za-z0-9_$]+)\\s*,?\\s*(?:\\/\\/.*)?$/gm;\n for (const match of bodyMatch[1]!.matchAll(entryRe)) {\n const slug = match[1] ?? match[2] ?? match[3]!;\n const exportName = match[4]!;\n const importPath = importedFrom.get(exportName);\n if (!importPath || !importPath.startsWith(\".\")) continue;\n entries.push({ slug, exportName, importPath });\n }\n return entries;\n}\n\nexport interface DefinitionMeta {\n name?: string;\n heading?: string;\n category?: string;\n description?: string;\n icon?: string;\n /** The identifier `schema:` refers to, for example `HeroSchema`. */\n schemaName?: string;\n}\n\n/** Scalar fields of an `export const XDefinition = { ... }` block, when the file has one. */\nexport function parseDefinition(source: string): DefinitionMeta | null {\n const match = source.match(/export\\s+const\\s+\\w+Definition\\s*=\\s*\\{([\\s\\S]*?)\\n\\}/);\n if (!match) return null;\n const body = match[1]!;\n const field = (key: string): string | undefined => {\n const m = body.match(new RegExp(`(?:^|\\\\n)\\\\s*${key}\\\\s*:\\\\s*(?:\"([^\"]*)\"|'([^']*)'|\\`([^\\`]*)\\`)`));\n return m ? (m[1] ?? m[2] ?? m[3]) : undefined;\n };\n const schemaName = body.match(/(?:^|\\n)\\s*schema\\s*:\\s*([A-Za-z_$][A-Za-z0-9_$]*)\\s*,?/)?.[1];\n return {\n name: field(\"name\"),\n heading: field(\"heading\"),\n category: field(\"category\"),\n description: field(\"description\"),\n icon: field(\"icon\"),\n ...(schemaName ? { schemaName } : {}),\n };\n}\n\n/** Split `a: z.string(), b: z.object({ x: z.number() })` on the commas at depth 0. */\nfunction splitTopLevel(body: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let quote: string | null = null;\n let current = \"\";\n for (let i = 0; i < body.length; i++) {\n const ch = body[i]!;\n if (quote) {\n current += ch;\n if (ch === \"\\\\\") current += body[++i] ?? \"\";\n else if (ch === quote) quote = null;\n continue;\n }\n if (ch === \"/\" && body[i + 1] === \"/\") {\n while (i < body.length && body[i] !== \"\\n\") i++;\n current += \"\\n\";\n continue;\n }\n if (ch === '\"' || ch === \"'\" || ch === \"`\") quote = ch;\n else if (\"([{\".includes(ch)) depth++;\n else if (\")]}\".includes(ch)) depth--;\n if (ch === \",\" && depth === 0) {\n parts.push(current);\n current = \"\";\n continue;\n }\n current += ch;\n }\n parts.push(current);\n return parts.map((p) => p.trim()).filter(Boolean);\n}\n\n/** The literal values of `z.enum([...])`, or null when they are not all string literals. */\nfunction enumValues(expr: string): string[] | null {\n const m = expr.match(/^z\\.enum\\(\\s*\\[([\\s\\S]*?)\\]/);\n if (!m) return null;\n const values: string[] = [];\n for (const raw of splitTopLevel(m[1]!)) {\n const lit = raw.match(/^(?:\"([^\"]*)\"|'([^']*)'|`([^`]*)`)$/);\n if (!lit) return null;\n values.push(lit[1] ?? lit[2] ?? lit[3]!);\n }\n return values;\n}\n\n/**\n * A best-effort field DSL entry for one zod expression, or null when the\n * expression is not one the CLI understands. `.optional()`, `.nullable()`,\n * `.nullish()` and `.default(...)` make the field optional; anything else is\n * required.\n */\nexport function zodFieldToSchemaField(expr: string): SectionSchemaField | null {\n const source = expr.trim();\n const optional = /\\.(optional|nullable|nullish|default)\\(/.test(source);\n let field: SectionSchemaField | null = null;\n if (/^z\\.string\\(/.test(source)) field = { type: /\\.(email)\\(/.test(source) ? \"email\" : /\\.(url)\\(/.test(source) ? \"url\" : \"text\" };\n else if (/^z\\.number\\(/.test(source)) field = { type: /\\.int\\(/.test(source) ? \"integer\" : \"number\" };\n else if (/^z\\.boolean\\(/.test(source)) field = { type: \"boolean\" };\n else if (/^z\\.enum\\(/.test(source)) {\n const options = enumValues(source);\n field = options ? { type: \"select\", options } : { type: \"select\" };\n } else if (/^z\\.array\\(/.test(source)) field = { type: \"array\" };\n else if (/^z\\.(object|record)\\(/.test(source)) field = { type: \"json\" };\n else if (/^z\\.union\\(\\s*\\[\\s*z\\.string\\(\\)\\s*,\\s*z\\.(any|object|record)\\(/.test(source)) field = { type: \"asset\" };\n if (!field) return null;\n if (!optional) field.required = true;\n const describe = source.match(/\\.describe\\(\\s*(?:\"([^\"]*)\"|'([^']*)'|`([^`]*)`)\\s*\\)/);\n const label = describe ? (describe[1] ?? describe[2] ?? describe[3]) : undefined;\n if (label) field.label = label;\n return field;\n}\n\n/**\n * The field DSL for `export const <schemaName> = z.object({ ... })` in a\n * component source, from the fields the CLI can read; null when the schema\n * is not found or no field could be read.\n */\nexport function parseZodSchema(source: string, schemaName: string): SectionFieldSchema | null {\n const start = source.match(new RegExp(`(?:export\\\\s+)?const\\\\s+${schemaName}\\\\s*=\\\\s*z\\\\.object\\\\(\\\\s*\\\\{`));\n if (!start || start.index === undefined) return null;\n const open = start.index + start[0].length;\n let depth = 1;\n let end = -1;\n for (let i = open; i < source.length; i++) {\n const ch = source[i];\n if (ch === \"{\" || ch === \"(\" || ch === \"[\") depth++;\n else if (ch === \"}\" || ch === \")\" || ch === \"]\") {\n depth--;\n if (depth === 0) {\n end = i;\n break;\n }\n }\n }\n if (end < 0) return null;\n const schema: SectionFieldSchema = {};\n for (const entry of splitTopLevel(source.slice(open, end))) {\n const m = entry.match(/^(?:\"([^\"]+)\"|'([^']+)'|([A-Za-z_$][A-Za-z0-9_$]*))\\s*:\\s*([\\s\\S]+)$/);\n if (!m) continue;\n const field = zodFieldToSchemaField(m[4]!);\n if (field) schema[m[1] ?? m[2] ?? m[3]!] = field;\n }\n return Object.keys(schema).length ? schema : null;\n}\n\n/** Module specifiers a source file imports, split into relative and package imports. */\nexport function parseImports(source: string): { internal: string[]; npm: string[] } {\n const internal = new Set<string>();\n const npm = new Set<string>();\n const re = /(?:import|export)\\s+(?:[^\"';]*?\\s+from\\s+)?[\"']([^\"']+)[\"']|import\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g;\n for (const match of source.matchAll(re)) {\n const spec = match[1] ?? match[2];\n if (!spec) continue;\n if (spec.startsWith(\".\") || spec.startsWith(\"@/\") || spec.startsWith(\"~/\")) internal.add(spec);\n else npm.add(spec.startsWith(\"@\") ? spec.split(\"/\").slice(0, 2).join(\"/\") : spec.split(\"/\")[0]!);\n }\n return { internal: [...internal].sort(), npm: [...npm].sort() };\n}\n\nconst SOURCE_EXTENSIONS = [\".tsx\", \".ts\", \".jsx\", \".js\"];\n\nasync function resolveImport(sectionsDir: string, spec: string): Promise<string | null> {\n const base = path.resolve(sectionsDir, spec);\n for (const ext of SOURCE_EXTENSIONS) {\n try {\n await readFile(base + ext);\n return base + ext;\n } catch {\n // try the next extension\n }\n }\n return null;\n}\n\nexport interface DerivedManifest {\n name: string;\n manifest: SectionManifest;\n /** The component file, absolute. */\n entryFile: string;\n}\n\nexport interface DeriveOptions {\n framework: string;\n /** npm dependency ranges to record, usually from the app's package.json. */\n npmVersions?: Record<string, string>;\n /** Registry file to read; `sectionsDir/publisher-section-registry.ts` by default. */\n registryFile?: string;\n}\n\n/** One manifest per registry entry whose component file exists. */\nexport async function deriveManifests(sectionsDir: string, options: DeriveOptions): Promise<DerivedManifest[]> {\n const registrySource = await readFile(options.registryFile ?? path.join(sectionsDir, DEFAULT_REGISTRY_FILE), \"utf8\");\n const entries = parseRegistry(registrySource);\n const out: DerivedManifest[] = [];\n for (const entry of entries) {\n const entryFile = await resolveImport(sectionsDir, entry.importPath);\n if (!entryFile) continue;\n const source = await readFile(entryFile, \"utf8\");\n const meta = parseDefinition(source);\n const schema = meta?.schemaName ? parseZodSchema(source, meta.schemaName) : null;\n const imports = parseImports(source);\n const relative = path.relative(sectionsDir, entryFile).split(path.sep).join(\"/\");\n const npm: Record<string, string> = {};\n for (const pkg of imports.npm) {\n if (pkg === \"react\" || pkg === \"next\") continue;\n npm[pkg] = options.npmVersions?.[pkg] ?? \"*\";\n }\n const manifest: SectionManifest = {\n section: entry.slug,\n framework: options.framework,\n entry: relative,\n exportName: entry.exportName,\n files: [relative],\n ...(meta?.heading ? { title: meta.heading } : {}),\n ...(meta?.description ? { description: meta.description } : {}),\n ...(meta?.category ? { category: meta.category } : {}),\n ...(meta?.icon ? { icon: meta.icon } : {}),\n dependencies: {\n ...(Object.keys(npm).length ? { npm } : {}),\n ...(imports.internal.length ? { internal: imports.internal } : {}),\n },\n ...(schema ? { schema } : {}),\n };\n out.push({ name: entry.slug, manifest, entryFile });\n }\n return out;\n}\n\n/** `dependencies` + `devDependencies` of the nearest package.json above `dir`, for version ranges. */\nexport async function readNpmVersions(dir: string): Promise<Record<string, string>> {\n let current = path.resolve(dir);\n for (;;) {\n try {\n const raw = await readFile(path.join(current, \"package.json\"), \"utf8\");\n const pkg = JSON.parse(raw) as { dependencies?: Record<string, string>; devDependencies?: Record<string, string> };\n return { ...pkg.devDependencies, ...pkg.dependencies };\n } catch {\n const parent = path.dirname(current);\n if (parent === current) return {};\n current = parent;\n }\n }\n}\n\n/** Whether the registry file exists (`sectionsDir/publisher-section-registry.ts`, or `registryFile` when given). */\nexport async function hasRegistry(sectionsDir: string, registryFile?: string): Promise<boolean> {\n const file = registryFile ?? path.join(sectionsDir, DEFAULT_REGISTRY_FILE);\n try {\n return (await readdir(path.dirname(file))).includes(path.basename(file));\n } catch {\n return false;\n }\n}\n","/**\n * Prop type generation: a section definition's props schema (as the\n * dashboard stores it) in, a TypeScript interface out. `pull` writes\n * `<name>.props.ts` next to the manifest so a component can type its props\n * from the dashboard instead of repeating the schema in zod.\n */\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n isFieldSchema,\n isFormBuilderSchema,\n type SectionFormBuilderNode,\n type SectionManifest,\n type SectionSchemaField,\n} from \"@botlr/sdk\";\n\nexport const PROPS_SUFFIX = \".props.ts\";\n\nconst STRING_TYPES = new Set([\n \"text\", \"textarea\", \"markdown\", \"richtext\", \"string\", \"email\", \"tel\", \"url\",\n \"icon\", \"color\", \"date\", \"datetime\", \"timestamp\", \"timestamptz\", \"uuid\",\n]);\nconst NUMBER_TYPES = new Set([\"number\", \"integer\", \"currency\"]);\nconst BOOLEAN_TYPES = new Set([\"boolean\"]);\nconst STRING_LIST_TYPES = new Set([\"multiselect\", \"tags\"]);\nconst LIST_TYPES = new Set([\"array\", \"list\", \"repeater\"]);\nconst OBJECT_TYPES = new Set([\"json\", \"jsonb\", \"object\"]);\nconst REFERENCE_TYPES = new Set([\n \"asset\", \"asset-picker-image\", \"asset-picker-file\", \"asset-picker-video\", \"media\",\n \"document\", \"page\", \"post\", \"reference\", \"relation\", \"entity_reference\",\n \"app_instance\", \"forum_thread\",\n]);\nconst REFERENCE_TYPE = \"string | Record<string, unknown>\";\nconst OBJECT_TYPE = \"Record<string, unknown>\";\n/** Node kinds of the FormBuilder format that only group other nodes. */\nconst GROUP_NODE_TYPES = new Set([\"section\", \"fieldset\", \"composite\", \"group\"]);\n\n/** One property of the generated interface. */\nexport interface PropField {\n name: string;\n /** TypeScript type text. */\n type: string;\n required: boolean;\n /** Doc comment lines (label, help text), without the comment markers. */\n doc: string[];\n}\n\nfunction literal(value: unknown): string | null {\n if (typeof value === \"string\") return JSON.stringify(value);\n if (typeof value === \"number\" && Number.isFinite(value)) return String(value);\n return null;\n}\n\n/** The union of a select's option values, or null when the options are not plain values or `{ value }` objects. */\nexport function optionUnion(options: unknown): string | null {\n if (!Array.isArray(options) || options.length === 0) return null;\n const literals: string[] = [];\n for (const option of options) {\n const raw = option && typeof option === \"object\" ? (option as { value?: unknown }).value : option;\n const lit = literal(raw);\n if (lit === null) return null;\n if (!literals.includes(lit)) literals.push(lit);\n }\n return literals.join(\" | \");\n}\n\nfunction wrapArray(type: string): string {\n return /^[A-Za-z0-9_<>, ]+$/.test(type) ? `${type}[]` : `Array<${type}>`;\n}\n\n/** The TypeScript type for one field of the field DSL (or a FormBuilder field node, given its field type). */\nexport function tsTypeForField(field: { type?: unknown; options?: unknown; multiple?: unknown; fields?: unknown }): string {\n const kind = typeof field.type === \"string\" ? field.type : \"\";\n const multiple = field.multiple === true;\n if (kind === \"select\") {\n const union = optionUnion(field.options) ?? \"string\";\n return multiple ? wrapArray(union) : union;\n }\n if (STRING_TYPES.has(kind)) return \"string\";\n if (NUMBER_TYPES.has(kind)) return \"number\";\n if (BOOLEAN_TYPES.has(kind)) return \"boolean\";\n if (STRING_LIST_TYPES.has(kind)) return \"string[]\";\n if (kind === \"repeater\" && Array.isArray(field.fields)) {\n const items = collectFormBuilderFields(field.fields as SectionFormBuilderNode[]);\n return items.length ? `Array<${inlineObject(items)}>` : \"unknown[]\";\n }\n if (LIST_TYPES.has(kind)) return \"unknown[]\";\n if (OBJECT_TYPES.has(kind)) return OBJECT_TYPE;\n if (REFERENCE_TYPES.has(kind)) return multiple ? `Array<${REFERENCE_TYPE}>` : REFERENCE_TYPE;\n return \"unknown\";\n}\n\nfunction docFor(field: { label?: unknown; helpText?: unknown; description?: unknown }): string[] {\n const doc: string[] = [];\n for (const value of [field.label, field.helpText ?? field.description]) {\n if (typeof value === \"string\" && value.trim()) doc.push(value.trim());\n }\n return doc;\n}\n\n/** Properties for the field DSL, in schema order. Non-object values are skipped. */\nexport function collectDslFields(schema: Record<string, unknown>): PropField[] {\n const out: PropField[] = [];\n for (const [name, value] of Object.entries(schema)) {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) continue;\n const field = value as SectionSchemaField;\n out.push({ name, type: tsTypeForField(field), required: field.required === true, doc: docFor(field) });\n }\n return out;\n}\n\n/** Properties for the FormBuilder format: field and repeater nodes, with groups flattened. */\nexport function collectFormBuilderFields(nodes: SectionFormBuilderNode[]): PropField[] {\n const out: PropField[] = [];\n for (const node of nodes) {\n if (!node || typeof node !== \"object\") continue;\n if (GROUP_NODE_TYPES.has(node.type) && Array.isArray(node.children)) {\n out.push(...collectFormBuilderFields(node.children));\n continue;\n }\n const name = typeof node.name === \"string\" && node.name ? node.name : typeof node.key === \"string\" ? node.key : \"\";\n if (!name) continue;\n const kind = node.type === \"field\" ? (node.fieldType ?? \"\") : (node.fieldType ?? node.type);\n const type = tsTypeForField({ type: kind, options: node.options, multiple: node.multiple, fields: node.fields });\n out.push({ name, type, required: node.required === true, doc: docFor(node) });\n }\n return out;\n}\n\n/** Properties for a definition schema in either format; empty for anything else. */\nexport function collectFields(schema: unknown): PropField[] {\n if (isFormBuilderSchema(schema)) return collectFormBuilderFields(schema.nodes);\n if (isFieldSchema(schema)) return collectDslFields(schema);\n return [];\n}\n\n/** The property names a definition schema defines, in either format. */\nexport function schemaFieldNames(schema: unknown): string[] {\n return collectFields(schema).map((f) => f.name);\n}\n\nconst IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\nfunction propertyKey(name: string): string {\n return IDENTIFIER_RE.test(name) ? name : JSON.stringify(name);\n}\n\nfunction inlineObject(fields: PropField[]): string {\n return `{ ${fields.map((f) => `${propertyKey(f.name)}${f.required ? \"\" : \"?\"}: ${f.type}`).join(\"; \")} }`;\n}\n\n/** `hero-banner` or `forum_new_thread` → `HeroBanner` / `ForumNewThread`. */\nexport function pascalCase(slug: string): string {\n const words = slug.split(/[^A-Za-z0-9]+/).filter(Boolean);\n const name = words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(\"\");\n return /^[0-9]/.test(name) ? `Section${name}` : name || \"Section\";\n}\n\n/** `<ExportName>Props`, from the manifest's `exportName` or a PascalCase of the slug. */\nexport function propsInterfaceName(manifest: Pick<SectionManifest, \"section\" | \"exportName\">): string {\n const base = manifest.exportName && IDENTIFIER_RE.test(manifest.exportName) ? manifest.exportName : pascalCase(manifest.section);\n return `${base}Props`;\n}\n\nexport interface GenerateOptions {\n /** Section slug, named in the header comment. */\n section: string;\n interfaceName: string;\n}\n\n/** The full text of `<name>.props.ts` for a definition schema. */\nexport function generatePropsSource(schema: unknown, options: GenerateOptions): string {\n const fields = collectFields(schema);\n const lines: string[] = [\n `// Generated by @botlr/cli from the Botlr section definition \"${options.section}\".`,\n \"// Do not edit: the props schema lives in the dashboard, and `botlr pull` rewrites this file.\",\n \"\",\n ];\n if (fields.length === 0) {\n lines.push(\"/** The definition has no props yet; define them in the dashboard and pull again. */\");\n lines.push(`export type ${options.interfaceName} = Record<string, unknown>;`);\n return `${lines.join(\"\\n\")}\\n`;\n }\n lines.push(`export interface ${options.interfaceName} {`);\n fields.forEach((field, index) => {\n if (index > 0 && field.doc.length) lines.push(\"\");\n if (field.doc.length === 1) lines.push(` /** ${field.doc[0]} */`);\n else if (field.doc.length > 1) lines.push(\" /**\", ...field.doc.map((d) => ` * ${d}`), \" */\");\n lines.push(` ${propertyKey(field.name)}${field.required ? \"\" : \"?\"}: ${field.type};`);\n });\n lines.push(\"}\");\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nexport function propsPath(sectionsDir: string, name: string): string {\n return path.join(sectionsDir, `${name}${PROPS_SUFFIX}`);\n}\n\nexport interface PropsTypesUpdate {\n file: string;\n interfaceName: string;\n /** False when the file already held the generated text. */\n changed: boolean;\n}\n\n/**\n * Write `<name>.props.ts` for a section, leaving the file alone when its\n * text is already what would be generated.\n */\nexport async function writePropsTypes(\n sectionsDir: string,\n manifest: SectionManifest,\n schema: unknown,\n): Promise<PropsTypesUpdate> {\n const interfaceName = propsInterfaceName(manifest);\n const file = propsPath(sectionsDir, manifest.section);\n const text = generatePropsSource(schema, { section: manifest.section, interfaceName });\n try {\n if ((await readFile(file, \"utf8\")) === text) return { file, interfaceName, changed: false };\n } catch {\n // missing: write it\n }\n await mkdir(sectionsDir, { recursive: true });\n await writeFile(file, text, \"utf8\");\n return { file, interfaceName, changed: true };\n}\n","import {\n BotlrConflictError,\n contentHash,\n type SectionSourcePushResponse,\n type SectionSourceScope,\n} from \"@botlr/sdk\";\nimport type { ResolvedConfig } from \"../config\";\nimport { clientFor } from \"../client\";\nimport { readLock, updateLock } from \"../lock\";\nimport { compareSchemas, type SchemaDrift } from \"../drift\";\nimport { ManifestError, readManifest, readSectionFiles } from \"../manifest\";\n\nexport interface PushOptions {\n name: string;\n message?: string;\n shared?: boolean;\n create?: boolean;\n /** Omit `baseVersion` so the server skips the conflict check. */\n force?: boolean;\n}\n\nexport interface PushResult {\n name: string;\n created: boolean;\n scope: SectionSourceScope;\n version: number;\n contentHash: string;\n /** Set when the manifest's `schema` and the definition's schema list different props. */\n drift?: SchemaDrift;\n}\n\nexport class PushConflict extends Error {\n constructor(\n message: string,\n public readonly latest: { version: number; contentHash: string } | null,\n ) {\n super(message);\n this.name = \"PushConflict\";\n }\n}\n\nexport async function pushSection(config: ResolvedConfig, options: PushOptions): Promise<PushResult> {\n const client = clientFor(config, { needPersonalToken: true });\n const { name } = options;\n const manifest = await readManifest(config.sectionsDir, name);\n if (manifest.section !== name) {\n throw new ManifestError(`${name}.botlr.json says section '${manifest.section}', expected '${name}'`);\n }\n if (manifest.framework && manifest.framework !== config.framework) {\n throw new ManifestError(\n `${name}.botlr.json is for framework '${manifest.framework}', the config says '${config.framework}'`,\n );\n }\n manifest.framework = config.framework;\n\n const files = await readSectionFiles(config.sectionsDir, manifest);\n const localHash = await contentHash(files);\n const targetScope: SectionSourceScope = options.shared ? \"shared\" : \"instance\";\n\n let baseVersion: number | undefined;\n if (!options.force) {\n const lock = (await readLock(config.root))[name];\n if (lock && lock.scope === targetScope) {\n baseVersion = lock.version;\n } else {\n // No lock for this scope: base on what the server has right now.\n const listing = await client.sections.list({ framework: config.framework });\n const summary = listing.sections.find((s) => s.name === name);\n const remote = summary ? (targetScope === \"shared\" ? summary.shared : summary.instance) : null;\n baseVersion = remote?.version ?? 0;\n if (remote && lock === undefined && remote.contentHash === localHash) {\n // Already on the server, nothing to push; let the server answer 200.\n }\n }\n }\n\n let response: SectionSourcePushResponse;\n try {\n response = await client.sections.push(name, {\n framework: config.framework,\n manifest,\n files,\n shared: options.shared ?? false,\n baseVersion,\n message: options.message,\n create: options.create ?? false,\n });\n } catch (error) {\n if (error instanceof BotlrConflictError) {\n throw new PushConflict(error.message, error.latest);\n }\n throw error;\n }\n\n await updateLock(config.root, name, {\n scope: response.scope,\n framework: config.framework,\n version: response.version,\n contentHash: response.contentHash,\n pulledAt: new Date().toISOString(),\n });\n\n const drift = compareSchemas(manifest, response.definition?.schema) ?? undefined;\n\n return {\n name,\n created: response.created,\n scope: response.scope,\n version: response.version,\n contentHash: response.contentHash,\n drift,\n };\n}\n","/**\n * Schema drift: the props a section's code expects (the manifest's optional\n * `schema`, field DSL only) against the props the dashboard defines (the\n * section definition's schema from the server). The CLI only reports the\n * difference; the dashboard owns the definition's schema.\n */\nimport { isFieldSchema, type SectionManifest } from \"@botlr/sdk\";\nimport { schemaFieldNames } from \"./typegen\";\n\nexport interface SchemaDrift {\n /** Props the code lists that the dashboard does not define. */\n missingInDashboard: string[];\n /** Props the dashboard defines that the code does not list. */\n missingInCode: string[];\n}\n\n/** The manifest's `schema` when it is a field DSL object, else null. */\nexport function manifestSchema(manifest: SectionManifest): Record<string, unknown> | null {\n const schema = manifest.schema;\n return isFieldSchema(schema) ? schema : null;\n}\n\n/**\n * Key difference between the code's schema (field DSL) and the definition's\n * schema (either format). Null when the manifest has no schema object or\n * the keys match.\n */\nexport function compareSchemas(manifest: SectionManifest, definitionSchema: unknown): SchemaDrift | null {\n const code = manifestSchema(manifest);\n if (!code) return null;\n const codeKeys = new Set(Object.keys(code).filter((k) => code[k] && typeof code[k] === \"object\"));\n const dashboardKeys = new Set(schemaFieldNames(definitionSchema));\n const missingInDashboard = [...codeKeys].filter((k) => !dashboardKeys.has(k)).sort();\n const missingInCode = [...dashboardKeys].filter((k) => !codeKeys.has(k)).sort();\n if (missingInDashboard.length === 0 && missingInCode.length === 0) return null;\n return { missingInDashboard, missingInCode };\n}\n\n/** The warning text for a drift, one line per direction, pointing at the dashboard. */\nexport function formatDriftWarning(name: string, drift: SchemaDrift): string {\n const lines = [`warning: props schema of '${name}' differs between the code and the dashboard`];\n if (drift.missingInDashboard.length) {\n lines.push(` the code expects props the dashboard does not define: ${drift.missingInDashboard.join(\", \")}`);\n }\n if (drift.missingInCode.length) {\n lines.push(` the dashboard defines props the code does not list: ${drift.missingInCode.join(\", \")}`);\n }\n lines.push(` the dashboard owns the schema: edit it there, or update 'schema' in ${name}.botlr.json`);\n return lines.join(\"\\n\");\n}\n","import { contentHash, type SectionManifest, type SectionSourceSummary } from \"@botlr/sdk\";\nimport type { ResolvedConfig } from \"../config\";\nimport { clientFor } from \"../client\";\nimport { compareSchemas, manifestSchema, type SchemaDrift } from \"../drift\";\nimport { readLock, type LockEntry } from \"../lock\";\nimport { listManifests, readManifest, readSectionFiles } from \"../manifest\";\nimport { computeStatus, remoteForLock, type SectionStatus } from \"../status\";\n\nexport interface SectionStatusRow {\n name: string;\n status: SectionStatus | \"error\";\n local: number | null;\n remote: number | null;\n scope: string;\n detail?: string;\n /** Set when the manifest's `schema` and the dashboard's definition list different props (not offline). */\n drift?: SchemaDrift;\n}\n\nexport async function sectionStatuses(\n config: ResolvedConfig,\n options: { names?: string[]; offline?: boolean } = {},\n): Promise<SectionStatusRow[]> {\n const names = options.names?.length ? options.names : await listManifests(config.sectionsDir);\n const lock = await readLock(config.root);\n\n let summaries = new Map<string, SectionSourceSummary>();\n const client = options.offline ? null : clientFor(config);\n if (client) {\n const listing = await client.sections.list({ framework: config.framework });\n summaries = new Map(listing.sections.map((s) => [s.name, s]));\n }\n\n // The listing carries no schema; fetch the definition only for manifests that have a schema to compare.\n const driftFor = async (manifest: SectionManifest): Promise<SchemaDrift | undefined> => {\n if (!client || !manifestSchema(manifest) || !summaries.has(manifest.section)) return undefined;\n try {\n const pulled = await client.sections.pull(manifest.section, { framework: config.framework });\n return compareSchemas(manifest, pulled.definition?.schema) ?? undefined;\n } catch {\n return undefined;\n }\n };\n\n const rows: SectionStatusRow[] = [];\n for (const name of names) {\n const entry: LockEntry | undefined = lock[name];\n const summary = summaries.get(name);\n const remote = remoteForLock(summary, entry);\n try {\n const manifest = await readManifest(config.sectionsDir, name);\n const localHash = await contentHash(await readSectionFiles(config.sectionsDir, manifest));\n rows.push({\n name,\n status: computeStatus({ localHash, lock: entry, remote }),\n local: entry?.version ?? null,\n remote: remote?.version ?? null,\n scope: entry?.scope ?? summary?.effective ?? \"-\",\n drift: await driftFor(manifest),\n });\n } catch (error) {\n rows.push({\n name,\n status: \"error\",\n local: entry?.version ?? null,\n remote: remote?.version ?? null,\n scope: entry?.scope ?? \"-\",\n detail: (error as Error).message,\n });\n }\n }\n return rows;\n}\n","import type { SectionSourceScopeSummary, SectionSourceSummary } from \"@botlr/sdk\";\nimport type { LockEntry } from \"./lock\";\n\n/**\n * - `clean`: local files equal the lock, and the lock is the server's latest\n * - `modified`: local files changed since the pull, server unchanged\n * - `behind`: local files equal the lock, but the server has a newer version\n * - `diverged`: both changed\n * - `untracked`: a manifest with no lock entry (never pulled or pushed from here)\n */\nexport type SectionStatus = \"clean\" | \"modified\" | \"behind\" | \"diverged\" | \"untracked\";\n\nexport interface StatusInput {\n /** Content hash of the local files listed in the manifest. */\n localHash: string;\n lock: LockEntry | undefined;\n /** Latest version on the server for the lock's scope; null when the server has none. */\n remote: SectionSourceScopeSummary | null | undefined;\n}\n\nexport function computeStatus({ localHash, lock, remote }: StatusInput): SectionStatus {\n if (!lock) return \"untracked\";\n const localChanged = localHash !== lock.contentHash;\n const remoteChanged = remote != null && remote.contentHash !== lock.contentHash;\n if (localChanged && remoteChanged) return \"diverged\";\n if (localChanged) return \"modified\";\n if (remoteChanged) return \"behind\";\n return \"clean\";\n}\n\n/** The server summary that corresponds to a lock entry's scope. */\nexport function remoteForLock(\n summary: SectionSourceSummary | undefined,\n lock: LockEntry | undefined,\n): SectionSourceScopeSummary | null | undefined {\n if (!summary) return undefined;\n if (!lock) return summary.effective === \"shared\" ? summary.shared : summary.instance;\n return lock.scope === \"shared\" ? summary.shared : summary.instance;\n}\n","import type { ResolvedConfig } from \"../config\";\nimport { deriveManifests, hasRegistry, readNpmVersions } from \"../init\";\nimport { listManifests, writeManifest } from \"../manifest\";\n\nexport interface InitOptions {\n /** Overwrite manifests that already exist. */\n force?: boolean;\n /** Only derive, write nothing. */\n dryRun?: boolean;\n}\n\nexport interface InitResult {\n name: string;\n file: string;\n entry: string;\n written: boolean;\n}\n\n/**\n * Derive `<slug>.botlr.json` for every component the registry maps. The\n * manifests are a starting point: review them, then `botlr push <name>`\n * (with `--create` for sections the dashboard does not know yet).\n */\nexport async function initSections(config: ResolvedConfig, options: InitOptions = {}): Promise<InitResult[]> {\n if (!(await hasRegistry(config.sectionsDir, config.registryFile))) {\n throw new Error(`No ${config.registryFile}; sections init reads the registry map to find components`);\n }\n const existing = new Set(await listManifests(config.sectionsDir));\n const npmVersions = await readNpmVersions(config.sectionsDir);\n const derived = await deriveManifests(config.sectionsDir, {\n framework: config.framework,\n npmVersions,\n registryFile: config.registryFile,\n });\n\n const results: InitResult[] = [];\n for (const { name, manifest, entryFile } of derived) {\n const skip = existing.has(name) && !options.force;\n let file = `${name}.botlr.json`;\n if (!skip && !options.dryRun) {\n file = await writeManifest(config.sectionsDir, name, manifest);\n }\n results.push({ name, file, entry: entryFile, written: !skip && !options.dryRun });\n }\n return results;\n}\n","/** Minimal table printing without a dependency. */\nexport function table(rows: string[][], header?: string[]): string {\n const all = header ? [header, ...rows] : rows;\n if (all.length === 0) return \"\";\n const widths = all[0]!.map((_, col) => Math.max(...all.map((row) => (row[col] ?? \"\").length)));\n const line = (row: string[]) => row.map((cell, i) => cell.padEnd(widths[i]!)).join(\" \").trimEnd();\n const out = all.map(line);\n if (header) out.splice(1, 0, widths.map((w) => \"-\".repeat(w)).join(\" \"));\n return out.join(\"\\n\");\n}\n\nexport function fail(message: string): never {\n process.stderr.write(`botlr: ${message}\\n`);\n process.exit(1);\n}\n"],"mappings":";;;AAAA,SAAS,SAAS,4BAA4B;AAC9C,SAAS,qBAAqB;AAC9B,OAAOA,WAAU;;;ACFjB,SAAS,QAAQ,gBAAgB;AACjC,OAAO,UAAU;AAEV,IAAM,cAAc;AACpB,IAAM,oBAAoB;AAC1B,IAAM,uBAAuB;AAC7B,IAAM,wBAAwB;AAyC9B,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEA,eAAe,OAAO,MAAgC;AACpD,MAAI;AACF,UAAM,OAAO,IAAI;AACjB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,eAAe,UAA0C;AAC7E,MAAI,MAAM,KAAK,QAAQ,QAAQ;AAC/B,aAAS;AACP,UAAM,YAAY,KAAK,KAAK,KAAK,WAAW;AAC5C,QAAI,MAAM,OAAO,SAAS,EAAG,QAAO;AACpC,UAAM,SAAS,KAAK,QAAQ,GAAG;AAC/B,QAAI,WAAW,IAAK,QAAO;AAC3B,UAAM;AAAA,EACR;AACF;AAEA,eAAsB,eAAe,MAA2C;AAC9E,QAAM,MAAM,MAAM,SAAS,MAAM,MAAM;AACvC,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAClE,YAAM,IAAI,YAAY,GAAG,IAAI,0BAA0B;AAAA,IACzD;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,YAAa,OAAM;AACxC,UAAM,IAAI,YAAY,GAAG,IAAI,uBAAwB,MAAgB,OAAO,EAAE;AAAA,EAChF;AACF;AAQA,eAAsB,WACpB,KACAC,aAA6B,CAAC,GAC9B,MAAyB,QAAQ,KACR;AACzB,QAAM,aAAa,MAAM,eAAe,GAAG;AAC3C,QAAM,OAAO,aAAa,MAAM,eAAe,UAAU,IAAI,CAAC;AAC9D,QAAM,OAAO,aAAa,KAAK,QAAQ,UAAU,IAAI,KAAK,QAAQ,GAAG;AAErE,QAAM,UAAUA,WAAU,WAAW,IAAI,kBAAkB,KAAK;AAChE,QAAM,QAAQA,WAAU,SAAS,IAAI,gBAAgB,KAAK;AAC1D,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,YAAY,yBAAyB,WAAW,oBAAoB;AAAA,EAChF;AACA,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,YAAY,uBAAuB,WAAW,kBAAkB;AAAA,EAC5E;AAEA,QAAM,cAAcA,WAAU,MAC1B,KAAK,QAAQ,KAAKA,WAAU,GAAG,IAC/B,KAAK,QAAQ,MAAM,IAAI,sBAAsB,KAAK,eAAe,oBAAoB;AAEzF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,SAAS,QAAQ,QAAQ,QAAQ,EAAE;AAAA,IACnC;AAAA,IACA,WAAWA,WAAU,aAAa,IAAI,mBAAmB,KAAK,aAAa;AAAA,IAC3E;AAAA,IACA,cAAc,KAAK,QAAQ,aAAa,KAAK,gBAAgB,qBAAqB;AAAA,IAClF,OAAO,KAAK,UAAU;AAAA,IACtB,QAAQ,IAAI,iBAAiB;AAAA,IAC7B,eAAe,IAAI,aAAa;AAAA,EAClC;AACF;;;ACjIA,SAAS,yBAA2C;AAI7C,SAAS,UAAU,QAAwB,UAA2C,CAAC,GAAgB;AAC5G,MAAI,CAAC,OAAO,UAAU,CAAC,QAAQ,mBAAmB;AAEhD,YAAQ,OAAO,MAAM,yEAAyE;AAAA,EAChG;AACA,MAAI,QAAQ,qBAAqB,CAAC,OAAO,eAAe;AACtD,UAAM,IAAI,YAAY,gFAAgF;AAAA,EACxG;AACA,SAAO,kBAAkB;AAAA,IACvB,SAAS,OAAO;AAAA,IAChB,OAAO,OAAO;AAAA,IACd,QAAQ,OAAO;AAAA,IACf,eAAe,OAAO;AAAA,EACxB,CAAC;AACH;;;ACdA,eAAsB,aAAa,QAAyD;AAC1F,QAAM,SAAS,UAAU,MAAM;AAC/B,QAAM,UAAU,MAAM,OAAO,SAAS,KAAK,EAAE,WAAW,OAAO,UAAU,CAAC;AAC1E,SAAO,QAAQ;AACjB;;;ACRA,SAAS,mBAA4E;;;ACArF,SAAS,OAAO,YAAAC,WAAU,iBAAiB;AAC3C,OAAOC,WAAU;AAGV,IAAM,WAAW;AACjB,IAAM,YAAY;AA2BlB,SAAS,cAAc,UAAiC,OAA6B;AAC1F,MACE,YACA,SAAS,UAAU,MAAM,SACzB,SAAS,cAAc,MAAM,aAC7B,SAAS,YAAY,MAAM,WAC3B,SAAS,gBAAgB,MAAM,aAC/B;AACA,WAAO,EAAE,GAAG,OAAO,UAAU,SAAS,SAAS;AAAA,EACjD;AACA,SAAO;AACT;AAEO,SAAS,SAAS,MAAsB;AAC7C,SAAOA,MAAK,KAAK,MAAM,UAAU,SAAS;AAC5C;AAEA,eAAsB,SAAS,MAAqC;AAClE,MAAI;AACF,UAAM,MAAM,MAAMD,UAAS,SAAS,IAAI,GAAG,MAAM;AACjD,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC;AAC5E,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,QAAO,CAAC;AAChE,UAAM;AAAA,EACR;AACF;AAEA,eAAsB,UAAU,MAAc,MAAmC;AAC/E,QAAM,OAAO,SAAS,IAAI;AAC1B,QAAM,MAAMC,MAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,QAAM,SAAS,OAAO,YAAY,OAAO,QAAQ,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;AAC7F,QAAM,UAAU,MAAM,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,GAAM,MAAM;AACtE;AAEA,eAAsB,WAAW,MAAc,MAAc,OAAyC;AACpG,QAAM,OAAO,MAAM,SAAS,IAAI;AAChC,OAAK,IAAI,IAAI,cAAc,KAAK,IAAI,GAAG,KAAK;AAC5C,QAAM,UAAU,MAAM,IAAI;AAC1B,SAAO;AACT;;;ACzEA,SAAS,SAAAC,QAAO,YAAAC,WAAU,SAAS,aAAAC,kBAAiB;AACpD,OAAOC,WAAU;AACjB;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAEA,IAAM,kBAAkB;AAExB,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,aAAa,aAAqB,MAAsB;AACtE,SAAOA,MAAK,KAAK,aAAa,GAAG,IAAI,GAAG,eAAe,EAAE;AAC3D;AAGA,eAAsB,cAAc,aAAwC;AAC1E,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,QAAQ,WAAW;AAAA,EACrC,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,SAAU,QAAO,CAAC;AAChE,UAAM;AAAA,EACR;AACA,SAAO,QACJ,OAAO,CAAC,UAAU,MAAM,SAAS,eAAe,CAAC,EACjD,IAAI,CAAC,UAAU,MAAM,MAAM,GAAG,CAAC,gBAAgB,MAAM,CAAC,EACtD,KAAK;AACV;AAEA,eAAsB,aAAa,aAAqB,MAAwC;AAC9F,QAAM,OAAO,aAAa,aAAa,IAAI;AAC3C,MAAI;AACJ,MAAI;AACF,UAAM,MAAMF,UAAS,MAAM,MAAM;AAAA,EACnC,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,UAAU;AACtD,YAAM,IAAI,cAAc,oBAAoB,IAAI,eAAe,IAAI,EAAE;AAAA,IACvE;AACA,UAAM;AAAA,EACR;AACA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG;AAAA,EACzB,SAAS,OAAO;AACd,UAAM,IAAI,cAAc,GAAG,IAAI,uBAAwB,MAAgB,OAAO,EAAE;AAAA,EAClF;AACA,SAAO,iBAAiB,QAAQ,IAAI;AACtC;AAEO,SAAS,iBAAiB,OAAgB,QAAQ,YAA6B;AACpF,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,UAAM,IAAI,cAAc,GAAG,KAAK,wBAAwB;AAAA,EAC1D;AACA,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,YAAY,YAAY,CAAC,EAAE,QAAS,OAAM,IAAI,cAAc,GAAG,KAAK,yBAAyB;AAC1G,MAAI,OAAO,EAAE,UAAU,YAAY,CAAC,EAAE,MAAO,OAAM,IAAI,cAAc,GAAG,KAAK,uBAAuB;AACpG,MAAI,CAAC,MAAM,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,WAAW,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ,GAAG;AACnG,UAAM,IAAI,cAAc,GAAG,KAAK,uCAAuC;AAAA,EACzE;AACA,QAAM,QAAQ,EAAE;AAChB,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,mBAAmB,IAAI,EAAG,OAAM,IAAI,cAAc,GAAG,KAAK,wBAAwB,IAAI,GAAG;AAAA,EAChG;AACA,MAAI,CAAC,MAAM,SAAS,EAAE,KAAK,EAAG,OAAM,IAAI,cAAc,GAAG,KAAK,cAAc,EAAE,KAAK,6BAA6B;AAChH,MAAI,EAAE,cAAc,UAAa,OAAO,EAAE,cAAc,UAAU;AAChE,UAAM,IAAI,cAAc,GAAG,KAAK,gCAAgC;AAAA,EAClE;AACA,SAAO;AACT;AAGO,IAAM,qBAAqB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,yBAAyB,CAAC,OAAO,UAAU;AAEjD,SAAS,UAAU,OAAgC,OAAmD;AACpG,QAAM,MAA+B,CAAC;AACtC,aAAW,OAAO,OAAO;AACvB,QAAI,OAAO,SAAS,MAAM,GAAG,MAAM,OAAW,KAAI,GAAG,IAAI,MAAM,GAAG;AAAA,EACpE;AACA,aAAW,OAAO,OAAO,KAAK,KAAK,EAAE,KAAK,GAAG;AAC3C,QAAI,MAAM,SAAS,GAAG,KAAK,MAAM,GAAG,MAAM,OAAW;AACrD,QAAI,GAAG,IAAI,MAAM,GAAG;AAAA,EACtB;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAyB;AAChD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,eAAe;AAC1D,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,SAAS;AACf,UAAM,UAAU,UAAU,QAAQ,CAAC,CAAC;AACpC,eAAW,OAAO,OAAO,KAAK,OAAO,EAAG,SAAQ,GAAG,IAAI,gBAAgB,QAAQ,GAAG,CAAC;AACnF,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAUO,SAAS,kBAAkB,UAA4C;AAC5E,QAAM,WAAW,mBAAmB,QAAQ;AAC5C,QAAM,UAAU,UAAU,UAAU,kBAAkB;AACtD,aAAW,OAAO,OAAO,KAAK,OAAO,GAAG;AACtC,QAAI,QAAQ,kBAAkB,QAAQ,GAAG,KAAK,OAAO,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,QAAQ,QAAQ,GAAG,CAAC,GAAG;AAC9G,YAAM,OAAO,UAAU,QAAQ,GAAG,GAA8B,sBAAsB;AACtF,iBAAW,UAAU,OAAO,KAAK,IAAI,EAAG,MAAK,MAAM,IAAI,gBAAgB,KAAK,MAAM,CAAC;AACnF,cAAQ,GAAG,IAAI;AAAA,IACjB,OAAO;AACL,cAAQ,GAAG,IAAI,gBAAgB,QAAQ,GAAG,CAAC;AAAA,IAC7C;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,eAAe,UAAmC;AAChE,SAAO,GAAG,KAAK,UAAU,kBAAkB,QAAQ,GAAG,MAAM,CAAC,CAAC;AAAA;AAChE;AAGO,SAAS,eAAe,GAAoB,GAA6B;AAC9E,SAAO,eAAe,CAAC,MAAM,eAAe,CAAC;AAC/C;AAGA,eAAsB,cAAc,aAAqB,MAAc,UAA4C;AACjH,QAAM,OAAO,aAAa,aAAa,IAAI;AAC3C,QAAMD,OAAM,aAAa,EAAE,WAAW,KAAK,CAAC;AAC5C,QAAME,WAAU,MAAM,eAAe,QAAQ,GAAG,MAAM;AACtD,SAAO;AACT;AAOA,eAAsB,uBACpB,aACA,MACA,UAC6C;AAC7C,QAAM,OAAO,aAAa,aAAa,IAAI;AAC3C,MAAI;AACF,UAAM,WAAW,KAAK,MAAM,MAAMD,UAAS,MAAM,MAAM,CAAC;AACxD,QAAI,YAAY,OAAO,aAAa,YAAY,CAAC,MAAM,QAAQ,QAAQ,GAAG;AACxE,UAAI,eAAe,UAA6B,QAAQ,EAAG,QAAO,EAAE,MAAM,SAAS,MAAM;AAAA,IAC3F;AAAA,EACF,QAAQ;AAAA,EAER;AACA,QAAM,cAAc,aAAa,MAAM,QAAQ;AAC/C,SAAO,EAAE,MAAM,SAAS,KAAK;AAC/B;AAGA,eAAsB,iBACpB,aACA,UACmC;AACnC,SAAO,QAAQ;AAAA,IACb,SAAS,MAAM,IAAI,OAAO,aAAa;AACrC,YAAM,OAAO,SAAS,aAAa,QAAQ;AAC3C,UAAI;AACF,eAAO,EAAE,MAAM,UAAU,SAAS,MAAMA,UAAS,MAAM,MAAM,EAAE;AAAA,MACjE,SAAS,OAAO;AACd,YAAK,MAAgC,SAAS,UAAU;AACtD,gBAAM,IAAI,cAAc,iBAAiB,QAAQ,eAAe,SAAS,OAAO,GAAG,eAAe,EAAE;AAAA,QACtG;AACA,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAGA,eAAsB,kBAAkB,aAAqB,OAAoD;AAC/G,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,OAAO;AACxB,UAAM,SAAS,SAAS,aAAa,KAAK,IAAI;AAC9C,UAAMD,OAAMG,MAAK,QAAQ,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AACrD,UAAMD,WAAU,QAAQ,KAAK,SAAS,MAAM;AAC5C,YAAQ,KAAK,MAAM;AAAA,EACrB;AACA,SAAO;AACT;AAGO,SAAS,SAAS,KAAa,UAA0B;AAC9D,MAAI,CAAC,mBAAmB,QAAQ,EAAG,OAAM,IAAI,cAAc,sBAAsB,QAAQ,GAAG;AAC5F,QAAM,SAASC,MAAK,QAAQ,KAAK,QAAQ;AACzC,QAAM,OAAOA,MAAK,QAAQ,GAAG;AAC7B,MAAI,WAAW,QAAQ,CAAC,OAAO,WAAW,OAAOA,MAAK,GAAG,GAAG;AAC1D,UAAM,IAAI,cAAc,cAAc,QAAQ,aAAa,GAAG,EAAE;AAAA,EAClE;AACA,SAAO;AACT;;;ACzNA,SAAS,YAAAC,WAAU,aAAAC,kBAAiB;AACpC,OAAOC,WAAU;;;ACAjB,SAAS,YAAAC,WAAU,WAAAC,gBAAe;AAClC,OAAOC,WAAU;AAgBV,SAAS,cAAc,QAAiC;AAC7D,QAAM,eAAe,oBAAI,IAAoB;AAC7C,QAAM,WAAW;AACjB,aAAW,SAAS,OAAO,SAAS,QAAQ,GAAG;AAC7C,UAAM,QAAQ,MAAM,CAAC;AACrB,UAAM,OAAO,MAAM,CAAC;AACpB,eAAW,OAAO,MAAM,MAAM,GAAG,GAAG;AAClC,YAAM,OAAO,IAAI,KAAK,EAAE,MAAM,UAAU,EAAE,IAAI,GAAG,KAAK;AACtD,UAAI,KAAM,cAAa,IAAI,MAAM,IAAI;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,YAAY,OAAO,MAAM,2BAA2B;AAC1D,MAAI,CAAC,UAAW,QAAO,CAAC;AACxB,QAAM,UAA2B,CAAC;AAClC,QAAM,UAAU;AAChB,aAAW,SAAS,UAAU,CAAC,EAAG,SAAS,OAAO,GAAG;AACnD,UAAM,OAAO,MAAM,CAAC,KAAK,MAAM,CAAC,KAAK,MAAM,CAAC;AAC5C,UAAM,aAAa,MAAM,CAAC;AAC1B,UAAM,aAAa,aAAa,IAAI,UAAU;AAC9C,QAAI,CAAC,cAAc,CAAC,WAAW,WAAW,GAAG,EAAG;AAChD,YAAQ,KAAK,EAAE,MAAM,YAAY,WAAW,CAAC;AAAA,EAC/C;AACA,SAAO;AACT;AAaO,SAAS,gBAAgB,QAAuC;AACrE,QAAM,QAAQ,OAAO,MAAM,uDAAuD;AAClF,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,MAAM,CAAC;AACpB,QAAM,QAAQ,CAAC,QAAoC;AACjD,UAAM,IAAI,KAAK,MAAM,IAAI,OAAO,gBAAgB,GAAG,+CAA+C,CAAC;AACnG,WAAO,IAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,IAAK;AAAA,EACtC;AACA,QAAM,aAAa,KAAK,MAAM,yDAAyD,IAAI,CAAC;AAC5F,SAAO;AAAA,IACL,MAAM,MAAM,MAAM;AAAA,IAClB,SAAS,MAAM,SAAS;AAAA,IACxB,UAAU,MAAM,UAAU;AAAA,IAC1B,aAAa,MAAM,aAAa;AAAA,IAChC,MAAM,MAAM,MAAM;AAAA,IAClB,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,EACrC;AACF;AAGA,SAAS,cAAc,MAAwB;AAC7C,QAAM,QAAkB,CAAC;AACzB,MAAI,QAAQ;AACZ,MAAI,QAAuB;AAC3B,MAAI,UAAU;AACd,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,KAAK,KAAK,CAAC;AACjB,QAAI,OAAO;AACT,iBAAW;AACX,UAAI,OAAO,KAAM,YAAW,KAAK,EAAE,CAAC,KAAK;AAAA,eAChC,OAAO,MAAO,SAAQ;AAC/B;AAAA,IACF;AACA,QAAI,OAAO,OAAO,KAAK,IAAI,CAAC,MAAM,KAAK;AACrC,aAAO,IAAI,KAAK,UAAU,KAAK,CAAC,MAAM,KAAM;AAC5C,iBAAW;AACX;AAAA,IACF;AACA,QAAI,OAAO,OAAO,OAAO,OAAO,OAAO,IAAK,SAAQ;AAAA,aAC3C,MAAM,SAAS,EAAE,EAAG;AAAA,aACpB,MAAM,SAAS,EAAE,EAAG;AAC7B,QAAI,OAAO,OAAO,UAAU,GAAG;AAC7B,YAAM,KAAK,OAAO;AAClB,gBAAU;AACV;AAAA,IACF;AACA,eAAW;AAAA,EACb;AACA,QAAM,KAAK,OAAO;AAClB,SAAO,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAClD;AAGA,SAAS,WAAW,MAA+B;AACjD,QAAM,IAAI,KAAK,MAAM,6BAA6B;AAClD,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,SAAmB,CAAC;AAC1B,aAAW,OAAO,cAAc,EAAE,CAAC,CAAE,GAAG;AACtC,UAAM,MAAM,IAAI,MAAM,qCAAqC;AAC3D,QAAI,CAAC,IAAK,QAAO;AACjB,WAAO,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC,CAAE;AAAA,EACzC;AACA,SAAO;AACT;AAQO,SAAS,sBAAsB,MAAyC;AAC7E,QAAM,SAAS,KAAK,KAAK;AACzB,QAAM,WAAW,0CAA0C,KAAK,MAAM;AACtE,MAAI,QAAmC;AACvC,MAAI,eAAe,KAAK,MAAM,EAAG,SAAQ,EAAE,MAAM,cAAc,KAAK,MAAM,IAAI,UAAU,YAAY,KAAK,MAAM,IAAI,QAAQ,OAAO;AAAA,WACzH,eAAe,KAAK,MAAM,EAAG,SAAQ,EAAE,MAAM,UAAU,KAAK,MAAM,IAAI,YAAY,SAAS;AAAA,WAC3F,gBAAgB,KAAK,MAAM,EAAG,SAAQ,EAAE,MAAM,UAAU;AAAA,WACxD,aAAa,KAAK,MAAM,GAAG;AAClC,UAAM,UAAU,WAAW,MAAM;AACjC,YAAQ,UAAU,EAAE,MAAM,UAAU,QAAQ,IAAI,EAAE,MAAM,SAAS;AAAA,EACnE,WAAW,cAAc,KAAK,MAAM,EAAG,SAAQ,EAAE,MAAM,QAAQ;AAAA,WACtD,wBAAwB,KAAK,MAAM,EAAG,SAAQ,EAAE,MAAM,OAAO;AAAA,WAC7D,kEAAkE,KAAK,MAAM,EAAG,SAAQ,EAAE,MAAM,QAAQ;AACjH,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,CAAC,SAAU,OAAM,WAAW;AAChC,QAAM,WAAW,OAAO,MAAM,uDAAuD;AACrF,QAAM,QAAQ,WAAY,SAAS,CAAC,KAAK,SAAS,CAAC,KAAK,SAAS,CAAC,IAAK;AACvE,MAAI,MAAO,OAAM,QAAQ;AACzB,SAAO;AACT;AAOO,SAAS,eAAe,QAAgB,YAA+C;AAC5F,QAAM,QAAQ,OAAO,MAAM,IAAI,OAAO,2BAA2B,UAAU,+BAA+B,CAAC;AAC3G,MAAI,CAAC,SAAS,MAAM,UAAU,OAAW,QAAO;AAChD,QAAM,OAAO,MAAM,QAAQ,MAAM,CAAC,EAAE;AACpC,MAAI,QAAQ;AACZ,MAAI,MAAM;AACV,WAAS,IAAI,MAAM,IAAI,OAAO,QAAQ,KAAK;AACzC,UAAM,KAAK,OAAO,CAAC;AACnB,QAAI,OAAO,OAAO,OAAO,OAAO,OAAO,IAAK;AAAA,aACnC,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC/C;AACA,UAAI,UAAU,GAAG;AACf,cAAM;AACN;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,MAAM,EAAG,QAAO;AACpB,QAAM,SAA6B,CAAC;AACpC,aAAW,SAAS,cAAc,OAAO,MAAM,MAAM,GAAG,CAAC,GAAG;AAC1D,UAAM,IAAI,MAAM,MAAM,sEAAsE;AAC5F,QAAI,CAAC,EAAG;AACR,UAAM,QAAQ,sBAAsB,EAAE,CAAC,CAAE;AACzC,QAAI,MAAO,QAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAE,IAAI;AAAA,EAC7C;AACA,SAAO,OAAO,KAAK,MAAM,EAAE,SAAS,SAAS;AAC/C;AAGO,SAAS,aAAa,QAAuD;AAClF,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,MAAM,oBAAI,IAAY;AAC5B,QAAM,KAAK;AACX,aAAW,SAAS,OAAO,SAAS,EAAE,GAAG;AACvC,UAAM,OAAO,MAAM,CAAC,KAAK,MAAM,CAAC;AAChC,QAAI,CAAC,KAAM;AACX,QAAI,KAAK,WAAW,GAAG,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,IAAI,EAAG,UAAS,IAAI,IAAI;AAAA,QACxF,KAAI,IAAI,KAAK,WAAW,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,CAAC,CAAE;AAAA,EACjG;AACA,SAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE;AAChE;AAEA,IAAM,oBAAoB,CAAC,QAAQ,OAAO,QAAQ,KAAK;AAEvD,eAAe,cAAc,aAAqB,MAAsC;AACtF,QAAM,OAAOC,MAAK,QAAQ,aAAa,IAAI;AAC3C,aAAW,OAAO,mBAAmB;AACnC,QAAI;AACF,YAAMC,UAAS,OAAO,GAAG;AACzB,aAAO,OAAO;AAAA,IAChB,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAkBA,eAAsB,gBAAgB,aAAqB,SAAoD;AAC7G,QAAM,iBAAiB,MAAMA,UAAS,QAAQ,gBAAgBD,MAAK,KAAK,aAAa,qBAAqB,GAAG,MAAM;AACnH,QAAM,UAAU,cAAc,cAAc;AAC5C,QAAM,MAAyB,CAAC;AAChC,aAAW,SAAS,SAAS;AAC3B,UAAM,YAAY,MAAM,cAAc,aAAa,MAAM,UAAU;AACnE,QAAI,CAAC,UAAW;AAChB,UAAM,SAAS,MAAMC,UAAS,WAAW,MAAM;AAC/C,UAAM,OAAO,gBAAgB,MAAM;AACnC,UAAM,SAAS,MAAM,aAAa,eAAe,QAAQ,KAAK,UAAU,IAAI;AAC5E,UAAM,UAAU,aAAa,MAAM;AACnC,UAAM,WAAWD,MAAK,SAAS,aAAa,SAAS,EAAE,MAAMA,MAAK,GAAG,EAAE,KAAK,GAAG;AAC/E,UAAM,MAA8B,CAAC;AACrC,eAAW,OAAO,QAAQ,KAAK;AAC7B,UAAI,QAAQ,WAAW,QAAQ,OAAQ;AACvC,UAAI,GAAG,IAAI,QAAQ,cAAc,GAAG,KAAK;AAAA,IAC3C;AACA,UAAM,WAA4B;AAAA,MAChC,SAAS,MAAM;AAAA,MACf,WAAW,QAAQ;AAAA,MACnB,OAAO;AAAA,MACP,YAAY,MAAM;AAAA,MAClB,OAAO,CAAC,QAAQ;AAAA,MAChB,GAAI,MAAM,UAAU,EAAE,OAAO,KAAK,QAAQ,IAAI,CAAC;AAAA,MAC/C,GAAI,MAAM,cAAc,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,MAC7D,GAAI,MAAM,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,MACpD,GAAI,MAAM,OAAO,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,MACxC,cAAc;AAAA,QACZ,GAAI,OAAO,KAAK,GAAG,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC;AAAA,QACzC,GAAI,QAAQ,SAAS,SAAS,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MAClE;AAAA,MACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC7B;AACA,QAAI,KAAK,EAAE,MAAM,MAAM,MAAM,UAAU,UAAU,CAAC;AAAA,EACpD;AACA,SAAO;AACT;AAGA,eAAsB,gBAAgB,KAA8C;AAClF,MAAI,UAAUA,MAAK,QAAQ,GAAG;AAC9B,aAAS;AACP,QAAI;AACF,YAAM,MAAM,MAAMC,UAASD,MAAK,KAAK,SAAS,cAAc,GAAG,MAAM;AACrE,YAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,aAAO,EAAE,GAAG,IAAI,iBAAiB,GAAG,IAAI,aAAa;AAAA,IACvD,QAAQ;AACN,YAAM,SAASA,MAAK,QAAQ,OAAO;AACnC,UAAI,WAAW,QAAS,QAAO,CAAC;AAChC,gBAAU;AAAA,IACZ;AAAA,EACF;AACF;AAGA,eAAsB,YAAY,aAAqB,cAAyC;AAC9F,QAAM,OAAO,gBAAgBA,MAAK,KAAK,aAAa,qBAAqB;AACzE,MAAI;AACF,YAAQ,MAAME,SAAQF,MAAK,QAAQ,IAAI,CAAC,GAAG,SAASA,MAAK,SAAS,IAAI,CAAC;AAAA,EACzE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AD1RA,IAAMG,qBAAoB,CAAC,QAAQ,OAAO,QAAQ,OAAO,QAAQ,MAAM;AAkBhE,SAAS,cAAc,cAAsB,WAA2B;AAC7E,QAAM,WAAWC,MAAK,SAASA,MAAK,QAAQ,YAAY,GAAG,SAAS,EAAE,MAAMA,MAAK,GAAG,EAAE,KAAK,GAAG;AAC9F,QAAM,MAAMA,MAAK,QAAQ,QAAQ;AACjC,QAAM,OAAOD,mBAAkB,SAAS,GAAG,IAAI,SAAS,MAAM,GAAG,CAAC,IAAI,MAAM,IAAI;AAChF,SAAO,KAAK,WAAW,GAAG,IAAI,OAAO,KAAK,IAAI;AAChD;AAEA,IAAM,aAAa;AAQZ,SAAS,iBAAiB,QAAgB,UAAgD;AAC/F,QAAM,EAAE,MAAM,YAAY,WAAW,IAAI;AACzC,MAAI,CAAC,WAAW,KAAK,UAAU,EAAG,OAAM,IAAI,MAAM,IAAI,UAAU,8BAA8B;AAE9F,QAAM,MAAM,OAAO,SAAS,MAAM,IAAI,SAAS;AAC/C,MAAI,MAAM;AACV,MAAI,cAAc;AAClB,MAAI,aAAa;AAGjB,QAAM,WAAW;AACjB,QAAM,UAAU,CAAC,GAAG,IAAI,SAAS,QAAQ,CAAC;AAC1C,QAAM,kBAAkB,QAAQ;AAAA,IAAK,CAAC,MACpC,EAAE,CAAC,EAAG,MAAM,GAAG,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,EAAE,MAAM,UAAU,EAAE,IAAI,GAAG,KAAK,MAAM,UAAU;AAAA,EAC1F;AACA,MAAI,CAAC,iBAAiB;AACpB,UAAM,OAAO,QAAQ,GAAG,EAAE;AAC1B,UAAM,QAAQ,OAAO,CAAC,KAAK;AAC3B,UAAM,YAAY,OAAO,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,GAAG,IAAI;AAC3D,UAAM,OAAO,YAAY,UAAU,WAAW,KAAK,GAAG,UAAU,GAAG,KAAK,GAAG,YAAY,MAAM,EAAE;AAC/F,QAAI,MAAM;AACR,YAAM,MAAM,KAAK,QAAS,KAAK,CAAC,EAAE;AAClC,YAAM,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,MAAM,GAAG,CAAC;AAAA,IAC1D,OAAO;AACL,YAAM,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG;AAAA,IACjC;AACA,kBAAc;AAAA,EAChB;AAGA,QAAM,gBAAgB,cAAc,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK,SAAS,KAAK,IAAI;AAC3F,MAAI,CAAC,eAAe;AAClB,UAAM,SAAS,mBAAmB,GAAG;AACrC,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,mEAAmE;AAChG,UAAM,OAAO,IAAI,MAAM,OAAO,WAAW,OAAO,OAAO;AACvD,UAAM,aAAa,KAAK,MAAM,OAAO,EAAE,OAAO,CAAC,MAAM,8CAA8C,KAAK,CAAC,CAAC;AAC1G,UAAM,YAAY,WAAW,GAAG,EAAE;AAClC,UAAM,SAAS,WAAW,MAAM,MAAM,IAAI,CAAC,KAAK;AAChD,UAAM,MAAM,WAAW,KAAK,IAAI,IAAI,OAAO,IAAI,IAAI;AACnD,UAAM,YAAY,GAAG,MAAM,GAAG,GAAG,KAAK,UAAU;AAEhD,QAAI,UAAU;AACd,QAAI,cAAc,QAAW;AAC3B,YAAM,WAAW,UAAU,QAAQ,WAAW,EAAE,EAAE,QAAQ;AAC1D,UAAI,CAAC,SAAS,SAAS,GAAG,GAAG;AAE3B,cAAM,KAAK,QAAQ,YAAY,SAAS;AACxC,cAAM,QAAQ,UAAU,QAAQ,kEAAkE,KAAK;AACvG,kBAAU,GAAG,QAAQ,MAAM,GAAG,EAAE,CAAC,GAAG,KAAK,GAAG,QAAQ,MAAM,KAAK,UAAU,MAAM,CAAC;AAAA,MAClF;AAAA,IACF;AACA,cAAU,GAAG,QAAQ,QAAQ,QAAQ,EAAE,CAAC,GAAG,GAAG,GAAG,SAAS;AAC1D,UAAM,GAAG,IAAI,MAAM,GAAG,OAAO,SAAS,CAAC,GAAG,OAAO,GAAG,IAAI,MAAM,OAAO,OAAO,CAAC;AAC7E,iBAAa;AAAA,EACf;AAEA,SAAO,EAAE,QAAQ,KAAK,SAAS,eAAe,YAAY,aAAa,WAAW;AACpF;AAEA,SAAS,SAAS,QAAgB,MAAuB;AACvD,QAAM,SAAS,mBAAmB,MAAM;AACxC,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,OAAO,OAAO,MAAM,OAAO,WAAW,OAAO,OAAO;AAC1D,QAAM,UAAU,KAAK,QAAQ,uBAAuB,MAAM;AAC1D,SAAO,IAAI,OAAO,YAAY,OAAO,MAAM,OAAO,KAAK,OAAO,UAAU,GAAG,EAAE,KAAK,IAAI;AACxF;AAGA,SAAS,mBAAmB,QAA+D;AACzF,QAAM,OAAO,OAAO,MAAM,0CAA0C,KAAK,OAAO,MAAM,QAAQ;AAC9F,MAAI,CAAC,QAAQ,KAAK,UAAU,OAAW,QAAO;AAC9C,QAAM,YAAY,KAAK,QAAQ,KAAK,CAAC,EAAE;AACvC,QAAM,QAAQ;AACd,QAAM,YAAY;AAClB,QAAM,aAAa,MAAM,KAAK,MAAM;AACpC,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,EAAE,WAAW,SAAS,WAAW,MAAM;AAChD;AAkBA,eAAsB,gBACpB,aACA,cACA,UACyB;AACzB,QAAM,OAAOC,MAAK,SAAS,YAAY;AACvC,MAAI;AACJ,MAAI;AACF,aAAS,MAAMC,UAAS,cAAc,MAAM;AAAA,EAC9C,SAAS,OAAO;AACd,QAAK,MAAgC,SAAS,UAAU;AACtD,aAAO,EAAE,MAAM,cAAc,SAAS,OAAO,QAAQ,MAAM,IAAI,OAAOD,MAAK,QAAQ,YAAY,CAAC,kCAAkC;AAAA,IACpI;AACA,UAAM;AAAA,EACR;AACA,MAAI,CAAC,SAAS,YAAY;AACxB,WAAO,EAAE,MAAM,cAAc,SAAS,OAAO,QAAQ,+BAA+B,IAAI,eAAe;AAAA,EACzG;AACA,QAAM,aAAa,cAAc,cAAcA,MAAK,QAAQ,aAAa,SAAS,KAAK,CAAC;AACxF,MAAI;AACJ,MAAI;AACF,WAAO,iBAAiB,QAAQ,EAAE,MAAM,SAAS,SAAS,YAAY,SAAS,YAAY,WAAW,CAAC;AAAA,EACzG,SAAS,OAAO;AACd,WAAO,EAAE,MAAM,cAAc,SAAS,OAAO,QAAQ,GAAG,IAAI,iBAAkB,MAAgB,OAAO,GAAG;AAAA,EAC1G;AACA,MAAI,KAAK,QAAS,OAAME,WAAU,cAAc,KAAK,QAAQ,MAAM;AACnE,SAAO,EAAE,MAAM,cAAc,SAAS,KAAK,SAAS,aAAa,KAAK,aAAa,YAAY,KAAK,WAAW;AACjH;;;AEhKA,SAAS,SAAAC,QAAO,YAAAC,WAAU,aAAAC,kBAAiB;AAC3C,OAAOC,WAAU;AACjB;AAAA,EACE;AAAA,EACA;AAAA,OAIK;AAEA,IAAM,eAAe;AAE5B,IAAM,eAAe,oBAAI,IAAI;AAAA,EAC3B;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAY;AAAA,EAAY;AAAA,EAAU;AAAA,EAAS;AAAA,EAAO;AAAA,EACtE;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAa;AAAA,EAAe;AACnE,CAAC;AACD,IAAM,eAAe,oBAAI,IAAI,CAAC,UAAU,WAAW,UAAU,CAAC;AAC9D,IAAM,gBAAgB,oBAAI,IAAI,CAAC,SAAS,CAAC;AACzC,IAAM,oBAAoB,oBAAI,IAAI,CAAC,eAAe,MAAM,CAAC;AACzD,IAAM,aAAa,oBAAI,IAAI,CAAC,SAAS,QAAQ,UAAU,CAAC;AACxD,IAAM,eAAe,oBAAI,IAAI,CAAC,QAAQ,SAAS,QAAQ,CAAC;AACxD,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EAAS;AAAA,EAAsB;AAAA,EAAqB;AAAA,EAAsB;AAAA,EAC1E;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAa;AAAA,EAAY;AAAA,EACrD;AAAA,EAAgB;AAClB,CAAC;AACD,IAAM,iBAAiB;AACvB,IAAM,cAAc;AAEpB,IAAM,mBAAmB,oBAAI,IAAI,CAAC,WAAW,YAAY,aAAa,OAAO,CAAC;AAY9E,SAAS,QAAQ,OAA+B;AAC9C,MAAI,OAAO,UAAU,SAAU,QAAO,KAAK,UAAU,KAAK;AAC1D,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO,OAAO,KAAK;AAC5E,SAAO;AACT;AAGO,SAAS,YAAY,SAAiC;AAC3D,MAAI,CAAC,MAAM,QAAQ,OAAO,KAAK,QAAQ,WAAW,EAAG,QAAO;AAC5D,QAAM,WAAqB,CAAC;AAC5B,aAAW,UAAU,SAAS;AAC5B,UAAM,MAAM,UAAU,OAAO,WAAW,WAAY,OAA+B,QAAQ;AAC3F,UAAM,MAAM,QAAQ,GAAG;AACvB,QAAI,QAAQ,KAAM,QAAO;AACzB,QAAI,CAAC,SAAS,SAAS,GAAG,EAAG,UAAS,KAAK,GAAG;AAAA,EAChD;AACA,SAAO,SAAS,KAAK,KAAK;AAC5B;AAEA,SAAS,UAAU,MAAsB;AACvC,SAAO,sBAAsB,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,SAAS,IAAI;AACvE;AAGO,SAAS,eAAe,OAA4F;AACzH,QAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAC3D,QAAM,WAAW,MAAM,aAAa;AACpC,MAAI,SAAS,UAAU;AACrB,UAAM,QAAQ,YAAY,MAAM,OAAO,KAAK;AAC5C,WAAO,WAAW,UAAU,KAAK,IAAI;AAAA,EACvC;AACA,MAAI,aAAa,IAAI,IAAI,EAAG,QAAO;AACnC,MAAI,aAAa,IAAI,IAAI,EAAG,QAAO;AACnC,MAAI,cAAc,IAAI,IAAI,EAAG,QAAO;AACpC,MAAI,kBAAkB,IAAI,IAAI,EAAG,QAAO;AACxC,MAAI,SAAS,cAAc,MAAM,QAAQ,MAAM,MAAM,GAAG;AACtD,UAAM,QAAQ,yBAAyB,MAAM,MAAkC;AAC/E,WAAO,MAAM,SAAS,SAAS,aAAa,KAAK,CAAC,MAAM;AAAA,EAC1D;AACA,MAAI,WAAW,IAAI,IAAI,EAAG,QAAO;AACjC,MAAI,aAAa,IAAI,IAAI,EAAG,QAAO;AACnC,MAAI,gBAAgB,IAAI,IAAI,EAAG,QAAO,WAAW,SAAS,cAAc,MAAM;AAC9E,SAAO;AACT;AAEA,SAAS,OAAO,OAAiF;AAC/F,QAAM,MAAgB,CAAC;AACvB,aAAW,SAAS,CAAC,MAAM,OAAO,MAAM,YAAY,MAAM,WAAW,GAAG;AACtE,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAG,KAAI,KAAK,MAAM,KAAK,CAAC;AAAA,EACtE;AACA,SAAO;AACT;AAGO,SAAS,iBAAiB,QAA8C;AAC7E,QAAM,MAAmB,CAAC;AAC1B,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAClD,QAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG;AACjE,UAAM,QAAQ;AACd,QAAI,KAAK,EAAE,MAAM,MAAM,eAAe,KAAK,GAAG,UAAU,MAAM,aAAa,MAAM,KAAK,OAAO,KAAK,EAAE,CAAC;AAAA,EACvG;AACA,SAAO;AACT;AAGO,SAAS,yBAAyB,OAA8C;AACrF,QAAM,MAAmB,CAAC;AAC1B,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,QAAI,iBAAiB,IAAI,KAAK,IAAI,KAAK,MAAM,QAAQ,KAAK,QAAQ,GAAG;AACnE,UAAI,KAAK,GAAG,yBAAyB,KAAK,QAAQ,CAAC;AACnD;AAAA,IACF;AACA,UAAM,OAAO,OAAO,KAAK,SAAS,YAAY,KAAK,OAAO,KAAK,OAAO,OAAO,KAAK,QAAQ,WAAW,KAAK,MAAM;AAChH,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,KAAK,SAAS,UAAW,KAAK,aAAa,KAAO,KAAK,aAAa,KAAK;AACtF,UAAM,OAAO,eAAe,EAAE,MAAM,MAAM,SAAS,KAAK,SAAS,UAAU,KAAK,UAAU,QAAQ,KAAK,OAAO,CAAC;AAC/G,QAAI,KAAK,EAAE,MAAM,MAAM,UAAU,KAAK,aAAa,MAAM,KAAK,OAAO,IAAI,EAAE,CAAC;AAAA,EAC9E;AACA,SAAO;AACT;AAGO,SAAS,cAAc,QAA8B;AAC1D,MAAI,oBAAoB,MAAM,EAAG,QAAO,yBAAyB,OAAO,KAAK;AAC7E,MAAI,cAAc,MAAM,EAAG,QAAO,iBAAiB,MAAM;AACzD,SAAO,CAAC;AACV;AAGO,SAAS,iBAAiB,QAA2B;AAC1D,SAAO,cAAc,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AAChD;AAEA,IAAM,gBAAgB;AAEtB,SAAS,YAAY,MAAsB;AACzC,SAAO,cAAc,KAAK,IAAI,IAAI,OAAO,KAAK,UAAU,IAAI;AAC9D;AAEA,SAAS,aAAa,QAA6B;AACjD,SAAO,KAAK,OAAO,IAAI,CAAC,MAAM,GAAG,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,WAAW,KAAK,GAAG,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC;AACvG;AAGO,SAAS,WAAW,MAAsB;AAC/C,QAAM,QAAQ,KAAK,MAAM,eAAe,EAAE,OAAO,OAAO;AACxD,QAAM,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE;AAC7E,SAAO,SAAS,KAAK,IAAI,IAAI,UAAU,IAAI,KAAK,QAAQ;AAC1D;AAGO,SAAS,mBAAmB,UAAmE;AACpG,QAAM,OAAO,SAAS,cAAc,cAAc,KAAK,SAAS,UAAU,IAAI,SAAS,aAAa,WAAW,SAAS,OAAO;AAC/H,SAAO,GAAG,IAAI;AAChB;AASO,SAAS,oBAAoB,QAAiB,SAAkC;AACrF,QAAM,SAAS,cAAc,MAAM;AACnC,QAAM,QAAkB;AAAA,IACtB,iEAAiE,QAAQ,OAAO;AAAA,IAChF;AAAA,IACA;AAAA,EACF;AACA,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,KAAK,sFAAsF;AACjG,UAAM,KAAK,eAAe,QAAQ,aAAa,6BAA6B;AAC5E,WAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA;AAAA,EAC5B;AACA,QAAM,KAAK,oBAAoB,QAAQ,aAAa,IAAI;AACxD,SAAO,QAAQ,CAAC,OAAO,UAAU;AAC/B,QAAI,QAAQ,KAAK,MAAM,IAAI,OAAQ,OAAM,KAAK,EAAE;AAChD,QAAI,MAAM,IAAI,WAAW,EAAG,OAAM,KAAK,SAAS,MAAM,IAAI,CAAC,CAAC,KAAK;AAAA,aACxD,MAAM,IAAI,SAAS,EAAG,OAAM,KAAK,SAAS,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM,QAAQ,CAAC,EAAE,GAAG,OAAO;AAChG,UAAM,KAAK,KAAK,YAAY,MAAM,IAAI,CAAC,GAAG,MAAM,WAAW,KAAK,GAAG,KAAK,MAAM,IAAI,GAAG;AAAA,EACvF,CAAC;AACD,QAAM,KAAK,GAAG;AACd,SAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA;AAC5B;AAEO,SAAS,UAAU,aAAqB,MAAsB;AACnE,SAAOA,MAAK,KAAK,aAAa,GAAG,IAAI,GAAG,YAAY,EAAE;AACxD;AAaA,eAAsB,gBACpB,aACA,UACA,QAC2B;AAC3B,QAAM,gBAAgB,mBAAmB,QAAQ;AACjD,QAAM,OAAO,UAAU,aAAa,SAAS,OAAO;AACpD,QAAM,OAAO,oBAAoB,QAAQ,EAAE,SAAS,SAAS,SAAS,cAAc,CAAC;AACrF,MAAI;AACF,QAAK,MAAMF,UAAS,MAAM,MAAM,MAAO,KAAM,QAAO,EAAE,MAAM,eAAe,SAAS,MAAM;AAAA,EAC5F,QAAQ;AAAA,EAER;AACA,QAAMD,OAAM,aAAa,EAAE,WAAW,KAAK,CAAC;AAC5C,QAAME,WAAU,MAAM,MAAM,MAAM;AAClC,SAAO,EAAE,MAAM,eAAe,SAAS,KAAK;AAC9C;;;ALxLA,eAAe,UAAU,aAAqB,MAAsC;AAClF,MAAI;AACF,UAAM,WAAW,MAAM,aAAa,aAAa,IAAI;AACrD,WAAO,MAAM,YAAY,MAAM,iBAAiB,aAAa,QAAQ,CAAC;AAAA,EACxE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,aAAa,QAAwB,SAA6C;AACtG,QAAM,SAAS,UAAU,MAAM;AAC/B,QAAM,QAAwC,QAAQ,SAAS,WAAW;AAE1E,MAAI,QAAQ,QAAQ;AACpB,MAAI,QAAQ,KAAK;AACf,UAAM,UAAU,MAAM,OAAO,SAAS,KAAK,EAAE,WAAW,OAAO,UAAU,CAAC;AAC1E,YAAQ,QAAQ,SACb,OAAO,CAAC,MAAO,QAAQ,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAO,EAClE,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EACtB;AACA,MAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAEhC,QAAM,OAAO,MAAM,SAAS,OAAO,IAAI;AACvC,QAAM,UAAwB,CAAC;AAE/B,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,KAAK,IAAI;AACvB,QAAI,SAAS,CAAC,QAAQ,OAAO;AAC3B,YAAM,UAAU,MAAM,UAAU,OAAO,aAAa,IAAI;AACxD,UAAI,YAAY,QAAQ,YAAY,MAAM,aAAa;AACrD,gBAAQ,KAAK,EAAE,MAAM,OAAO,MAAM,OAAO,SAAS,MAAM,SAAS,OAAO,CAAC,GAAG,SAAS,6CAA6C,CAAC;AACnI;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAsC,MAAM,OAAO,SAAS,KAAK,MAAM;AAAA,MAC3E,WAAW,OAAO;AAAA,MAClB,SAAS,QAAQ;AAAA,MACjB;AAAA,IACF,CAAC;AACD,UAAM,EAAE,OAAO,IAAI;AAEnB,UAAM,QAAQ,MAAM,kBAAkB,OAAO,aAAa,OAAO,KAAK;AACtE,UAAM,WAAW,MAAM,uBAAuB,OAAO,aAAa,MAAM,OAAO,QAAQ;AACvF,UAAM,WAAW,QAAQ,aACrB,SACA,MAAM,gBAAgB,OAAO,aAAa,OAAO,cAAc,OAAO,QAAQ;AAElF,QAAI;AACJ,QAAI;AACJ,QAAI,OAAO,SAAS,CAAC,QAAQ,SAAS;AACpC,UAAI,SAAS,YAAY;AACvB,gBAAQ,MAAM,gBAAgB,OAAO,aAAa,OAAO,UAAU,SAAS,WAAW,MAAM;AAAA,MAC/F,OAAO;AACL,sBAAc;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,QAAmB;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,WAAW,OAAO;AAAA,MAClB,SAAS,OAAO;AAAA,MAChB,aAAa,OAAO;AAAA,MACpB,WAAU,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnC;AACA,SAAK,IAAI,IAAI,cAAc,OAAO,KAAK;AACvC,YAAQ,KAAK;AAAA,MACX;AAAA,MACA,OAAO,OAAO;AAAA,MACd,SAAS,OAAO;AAAA,MAChB;AAAA,MACA,iBAAiB,SAAS;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,OAAO,MAAM,IAAI;AACjC,SAAO;AACT;;;AMzHA;AAAA,EACE;AAAA,EACA,eAAAE;AAAA,OAGK;;;ACCP,SAAS,iBAAAC,sBAA2C;AAW7C,SAAS,eAAe,UAA2D;AACxF,QAAM,SAAS,SAAS;AACxB,SAAOC,eAAc,MAAM,IAAI,SAAS;AAC1C;AAOO,SAAS,eAAe,UAA2B,kBAA+C;AACvG,QAAM,OAAO,eAAe,QAAQ;AACpC,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,WAAW,IAAI,IAAI,OAAO,KAAK,IAAI,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAChG,QAAM,gBAAgB,IAAI,IAAI,iBAAiB,gBAAgB,CAAC;AAChE,QAAM,qBAAqB,CAAC,GAAG,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,CAAC,EAAE,KAAK;AACnF,QAAM,gBAAgB,CAAC,GAAG,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,KAAK;AAC9E,MAAI,mBAAmB,WAAW,KAAK,cAAc,WAAW,EAAG,QAAO;AAC1E,SAAO,EAAE,oBAAoB,cAAc;AAC7C;AAGO,SAAS,mBAAmB,MAAc,OAA4B;AAC3E,QAAM,QAAQ,CAAC,6BAA6B,IAAI,8CAA8C;AAC9F,MAAI,MAAM,mBAAmB,QAAQ;AACnC,UAAM,KAAK,2DAA2D,MAAM,mBAAmB,KAAK,IAAI,CAAC,EAAE;AAAA,EAC7G;AACA,MAAI,MAAM,cAAc,QAAQ;AAC9B,UAAM,KAAK,yDAAyD,MAAM,cAAc,KAAK,IAAI,CAAC,EAAE;AAAA,EACtG;AACA,QAAM,KAAK,yEAAyE,IAAI,aAAa;AACrG,SAAO,MAAM,KAAK,IAAI;AACxB;;;ADlBO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YACE,SACgB,QAChB;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EAJkB;AAKpB;AAEA,eAAsB,YAAY,QAAwB,SAA2C;AACnG,QAAM,SAAS,UAAU,QAAQ,EAAE,mBAAmB,KAAK,CAAC;AAC5D,QAAM,EAAE,KAAK,IAAI;AACjB,QAAM,WAAW,MAAM,aAAa,OAAO,aAAa,IAAI;AAC5D,MAAI,SAAS,YAAY,MAAM;AAC7B,UAAM,IAAI,cAAc,GAAG,IAAI,6BAA6B,SAAS,OAAO,gBAAgB,IAAI,GAAG;AAAA,EACrG;AACA,MAAI,SAAS,aAAa,SAAS,cAAc,OAAO,WAAW;AACjE,UAAM,IAAI;AAAA,MACR,GAAG,IAAI,iCAAiC,SAAS,SAAS,uBAAuB,OAAO,SAAS;AAAA,IACnG;AAAA,EACF;AACA,WAAS,YAAY,OAAO;AAE5B,QAAM,QAAQ,MAAM,iBAAiB,OAAO,aAAa,QAAQ;AACjE,QAAMC,aAAY,MAAMC,aAAY,KAAK;AACzC,QAAM,cAAkC,QAAQ,SAAS,WAAW;AAEpE,MAAI;AACJ,MAAI,CAAC,QAAQ,OAAO;AAClB,UAAM,QAAQ,MAAM,SAAS,OAAO,IAAI,GAAG,IAAI;AAC/C,QAAI,QAAQ,KAAK,UAAU,aAAa;AACtC,oBAAc,KAAK;AAAA,IACrB,OAAO;AAEL,YAAM,UAAU,MAAM,OAAO,SAAS,KAAK,EAAE,WAAW,OAAO,UAAU,CAAC;AAC1E,YAAM,UAAU,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC5D,YAAM,SAAS,UAAW,gBAAgB,WAAW,QAAQ,SAAS,QAAQ,WAAY;AAC1F,oBAAc,QAAQ,WAAW;AACjC,UAAI,UAAU,SAAS,UAAa,OAAO,gBAAgBD,YAAW;AAAA,MAEtE;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,OAAO,SAAS,KAAK,MAAM;AAAA,MAC1C,WAAW,OAAO;AAAA,MAClB;AAAA,MACA;AAAA,MACA,QAAQ,QAAQ,UAAU;AAAA,MAC1B;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB,QAAQ,QAAQ,UAAU;AAAA,IAC5B,CAAC;AAAA,EACH,SAAS,OAAO;AACd,QAAI,iBAAiB,oBAAoB;AACvC,YAAM,IAAI,aAAa,MAAM,SAAS,MAAM,MAAM;AAAA,IACpD;AACA,UAAM;AAAA,EACR;AAEA,QAAM,WAAW,OAAO,MAAM,MAAM;AAAA,IAClC,OAAO,SAAS;AAAA,IAChB,WAAW,OAAO;AAAA,IAClB,SAAS,SAAS;AAAA,IAClB,aAAa,SAAS;AAAA,IACtB,WAAU,oBAAI,KAAK,GAAE,YAAY;AAAA,EACnC,CAAC;AAED,QAAM,QAAQ,eAAe,UAAU,SAAS,YAAY,MAAM,KAAK;AAEvE,SAAO;AAAA,IACL;AAAA,IACA,SAAS,SAAS;AAAA,IAClB,OAAO,SAAS;AAAA,IAChB,SAAS,SAAS;AAAA,IAClB,aAAa,SAAS;AAAA,IACtB;AAAA,EACF;AACF;;;AEhHA,SAAS,eAAAE,oBAAoE;;;ACoBtE,SAAS,cAAc,EAAE,WAAAC,YAAW,MAAM,OAAO,GAA+B;AACrF,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,eAAeA,eAAc,KAAK;AACxC,QAAM,gBAAgB,UAAU,QAAQ,OAAO,gBAAgB,KAAK;AACpE,MAAI,gBAAgB,cAAe,QAAO;AAC1C,MAAI,aAAc,QAAO;AACzB,MAAI,cAAe,QAAO;AAC1B,SAAO;AACT;AAGO,SAAS,cACd,SACA,MAC8C;AAC9C,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,CAAC,KAAM,QAAO,QAAQ,cAAc,WAAW,QAAQ,SAAS,QAAQ;AAC5E,SAAO,KAAK,UAAU,WAAW,QAAQ,SAAS,QAAQ;AAC5D;;;ADnBA,eAAsB,gBACpB,QACA,UAAmD,CAAC,GACvB;AAC7B,QAAM,QAAQ,QAAQ,OAAO,SAAS,QAAQ,QAAQ,MAAM,cAAc,OAAO,WAAW;AAC5F,QAAM,OAAO,MAAM,SAAS,OAAO,IAAI;AAEvC,MAAI,YAAY,oBAAI,IAAkC;AACtD,QAAM,SAAS,QAAQ,UAAU,OAAO,UAAU,MAAM;AACxD,MAAI,QAAQ;AACV,UAAM,UAAU,MAAM,OAAO,SAAS,KAAK,EAAE,WAAW,OAAO,UAAU,CAAC;AAC1E,gBAAY,IAAI,IAAI,QAAQ,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAAA,EAC9D;AAGA,QAAM,WAAW,OAAO,aAAgE;AACtF,QAAI,CAAC,UAAU,CAAC,eAAe,QAAQ,KAAK,CAAC,UAAU,IAAI,SAAS,OAAO,EAAG,QAAO;AACrF,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,SAAS,KAAK,SAAS,SAAS,EAAE,WAAW,OAAO,UAAU,CAAC;AAC3F,aAAO,eAAe,UAAU,OAAO,YAAY,MAAM,KAAK;AAAA,IAChE,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,OAA2B,CAAC;AAClC,aAAW,QAAQ,OAAO;AACxB,UAAM,QAA+B,KAAK,IAAI;AAC9C,UAAM,UAAU,UAAU,IAAI,IAAI;AAClC,UAAM,SAAS,cAAc,SAAS,KAAK;AAC3C,QAAI;AACF,YAAM,WAAW,MAAM,aAAa,OAAO,aAAa,IAAI;AAC5D,YAAMC,aAAY,MAAMC,aAAY,MAAM,iBAAiB,OAAO,aAAa,QAAQ,CAAC;AACxF,WAAK,KAAK;AAAA,QACR;AAAA,QACA,QAAQ,cAAc,EAAE,WAAAD,YAAW,MAAM,OAAO,OAAO,CAAC;AAAA,QACxD,OAAO,OAAO,WAAW;AAAA,QACzB,QAAQ,QAAQ,WAAW;AAAA,QAC3B,OAAO,OAAO,SAAS,SAAS,aAAa;AAAA,QAC7C,OAAO,MAAM,SAAS,QAAQ;AAAA,MAChC,CAAC;AAAA,IACH,SAAS,OAAO;AACd,WAAK,KAAK;AAAA,QACR;AAAA,QACA,QAAQ;AAAA,QACR,OAAO,OAAO,WAAW;AAAA,QACzB,QAAQ,QAAQ,WAAW;AAAA,QAC3B,OAAO,OAAO,SAAS;AAAA,QACvB,QAAS,MAAgB;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;;;AEjDA,eAAsB,aAAa,QAAwB,UAAuB,CAAC,GAA0B;AAC3G,MAAI,CAAE,MAAM,YAAY,OAAO,aAAa,OAAO,YAAY,GAAI;AACjE,UAAM,IAAI,MAAM,MAAM,OAAO,YAAY,2DAA2D;AAAA,EACtG;AACA,QAAM,WAAW,IAAI,IAAI,MAAM,cAAc,OAAO,WAAW,CAAC;AAChE,QAAM,cAAc,MAAM,gBAAgB,OAAO,WAAW;AAC5D,QAAM,UAAU,MAAM,gBAAgB,OAAO,aAAa;AAAA,IACxD,WAAW,OAAO;AAAA,IAClB;AAAA,IACA,cAAc,OAAO;AAAA,EACvB,CAAC;AAED,QAAM,UAAwB,CAAC;AAC/B,aAAW,EAAE,MAAM,UAAU,UAAU,KAAK,SAAS;AACnD,UAAM,OAAO,SAAS,IAAI,IAAI,KAAK,CAAC,QAAQ;AAC5C,QAAI,OAAO,GAAG,IAAI;AAClB,QAAI,CAAC,QAAQ,CAAC,QAAQ,QAAQ;AAC5B,aAAO,MAAM,cAAc,OAAO,aAAa,MAAM,QAAQ;AAAA,IAC/D;AACA,YAAQ,KAAK,EAAE,MAAM,MAAM,OAAO,WAAW,SAAS,CAAC,QAAQ,CAAC,QAAQ,OAAO,CAAC;AAAA,EAClF;AACA,SAAO;AACT;;;AC5CO,SAAS,MAAM,MAAkB,QAA2B;AACjE,QAAM,MAAM,SAAS,CAAC,QAAQ,GAAG,IAAI,IAAI;AACzC,MAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,QAAM,SAAS,IAAI,CAAC,EAAG,IAAI,CAAC,GAAG,QAAQ,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,IAAI,GAAG,KAAK,IAAI,MAAM,CAAC,CAAC;AAC7F,QAAM,OAAO,CAAC,QAAkB,IAAI,IAAI,CAAC,MAAM,MAAM,KAAK,OAAO,OAAO,CAAC,CAAE,CAAC,EAAE,KAAK,IAAI,EAAE,QAAQ;AACjG,QAAM,MAAM,IAAI,IAAI,IAAI;AACxB,MAAI,OAAQ,KAAI,OAAO,GAAG,GAAG,OAAO,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;AACxE,SAAO,IAAI,KAAK,IAAI;AACtB;AAEO,SAAS,KAAK,SAAwB;AAC3C,UAAQ,OAAO,MAAM,UAAU,OAAO;AAAA,CAAI;AAC1C,UAAQ,KAAK,CAAC;AAChB;;;AfFA,IAAME,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,EAAE,QAAQ,IAAIA,SAAQ,iBAAiB;AAE7C,SAAS,aAAa,OAAuB;AAC3C,QAAM,IAAI,OAAO,SAAS,OAAO,EAAE;AACnC,MAAI,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,EAAG,OAAM,IAAI,qBAAqB,oCAAoC;AACtG,SAAO;AACT;AAIA,SAAS,UAAU,MAAsC;AACvD,SAAO,EAAE,WAAW,KAAK,WAAW,KAAK,KAAK,IAAI;AACpD;AAEA,SAAS,WAAW,KAAuB;AACzC,SAAO,IACJ,OAAO,sBAAsB,8DAA8D,EAC3F,OAAO,gBAAgB,+DAA+D;AAC3F;AAEA,eAAe,IAAI,QAA4C;AAC7D,MAAI;AACF,UAAM,OAAO;AAAA,EACf,SAAS,OAAO;AACd,QAAI,iBAAiB,cAAc;AACjC,YAAM,SAAS,MAAM,SAAS,IAAI,MAAM,OAAO,OAAO,KAAK,MAAM,OAAO,YAAY,MAAM,GAAG,EAAE,CAAC,MAAM;AACtG,WAAK,GAAG,MAAM,OAAO;AAAA,sBAAyB,MAAM;AAAA,2CAA8C;AAAA,IACpG;AACA,SAAM,MAAgB,OAAO;AAAA,EAC/B;AACF;AAEA,IAAM,UAAU,IAAI,QAAQ,OAAO,EAChC,YAAY,gEAAgE,EAC5E,QAAQ,OAAO,EACf,cAAc,EAAE,iBAAiB,KAAK,CAAC;AAE1C;AAAA,EACE,QACG,QAAQ,iBAAiB,EACzB,YAAY,uFAAuF,EACnG,OAAO,SAAS,kDAAkD,EAClE,OAAO,iBAAiB,4CAA4C,YAAY,EAChF,OAAO,YAAY,uEAAuE,EAC1F,OAAO,WAAW,0DAA0D,EAC5E,OAAO,iBAAiB,6CAA6C,EACrE,OAAO,cAAc,iEAAiE;AAC3F,EAAE;AAAA,EAAO,CAAC,OAAiB,SACzB,IAAI,YAAY;AACd,QAAI,MAAM,WAAW,KAAK,CAAC,KAAK,IAAK,MAAK,8BAA8B;AACxE,QAAI,KAAK,OAAO,KAAK,YAAY,OAAW,MAAK,uCAAuC;AACxF,UAAM,SAAS,MAAM,WAAW,QAAQ,IAAI,GAAG,UAAU,IAAI,CAAC;AAC9D,UAAM,UAAU,MAAM,aAAa,QAAQ;AAAA,MACzC;AAAA,MACA,KAAK,KAAK;AAAA,MACV,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK,aAAa;AAAA,MAC9B,SAAS,KAAK,UAAU;AAAA,IAC1B,CAAC;AACD,QAAI,QAAQ,WAAW,GAAG;AACxB,cAAQ,IAAI,iBAAiB;AAC7B;AAAA,IACF;AACA,eAAW,KAAK,SAAS;AACvB,UAAI,EAAE,SAAS;AACb,gBAAQ,IAAI,SAAS,EAAE,IAAI,KAAK,EAAE,OAAO,EAAE;AAC3C;AAAA,MACF;AACA,cAAQ,IAAI,SAAS,EAAE,IAAI,IAAI,EAAE,KAAK,KAAK,EAAE,OAAO,KAAK,EAAE,MAAM,MAAM,QAAQ,EAAE,MAAM,WAAW,IAAI,KAAK,GAAG,GAAG;AACjH,UAAI,EAAE,OAAO,QAAS,SAAQ,IAAI,sBAAsB,EAAE,MAAM,aAAa,OAAOC,MAAK,SAAS,QAAQ,IAAI,GAAG,EAAE,MAAM,IAAI,CAAC,EAAE;AAChI,UAAI,EAAE,YAAa,SAAQ,IAAI,gBAAgB,EAAE,WAAW,EAAE;AAC9D,YAAM,WAAW,EAAE;AACnB,UAAI,CAAC,SAAU;AACf,YAAM,OAAOA,MAAK,SAAS,QAAQ,IAAI,GAAG,SAAS,IAAI;AACvD,UAAI,SAAS,OAAQ,SAAQ,IAAI,mBAAmB,SAAS,MAAM,EAAE;AAAA,eAC5D,SAAS,SAAS;AACzB,cAAM,OAAO,CAAC,SAAS,cAAc,WAAW,IAAI,SAAS,aAAa,IAAI,EAAE,IAAI,YAAY,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,OAAO;AAChI,gBAAQ,IAAI,yBAAyB,IAAI,OAAO,IAAI,EAAE;AAAA,MACxD;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA;AAAA,EACE,QACG,QAAQ,aAAa,EACrB,YAAY,0EAA0E,EACtF,OAAO,wBAAwB,+CAA+C,EAC9E,OAAO,YAAY,yEAAyE,EAC5F,OAAO,YAAY,mEAAmE,EACtF,OAAO,WAAW,6CAA6C;AACpE,EAAE;AAAA,EAAO,CAAC,MAAc,SACtB,IAAI,YAAY;AACd,UAAM,SAAS,MAAM,WAAW,QAAQ,IAAI,GAAG,UAAU,IAAI,CAAC;AAC9D,UAAM,SAAS,MAAM,YAAY,QAAQ;AAAA,MACvC;AAAA,MACA,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,IACd,CAAC;AACD,QAAI,OAAO,QAAS,SAAQ,IAAI,UAAU,OAAO,IAAI,IAAI,OAAO,KAAK,KAAK,OAAO,OAAO,EAAE;AAAA,QACrF,SAAQ,IAAI,GAAG,OAAO,IAAI,IAAI,OAAO,KAAK,KAAK,OAAO,OAAO,kCAAkC;AACpG,QAAI,OAAO,MAAO,SAAQ,OAAO,MAAM,GAAG,mBAAmB,OAAO,MAAM,OAAO,KAAK,CAAC;AAAA,CAAI;AAAA,EAC7F,CAAC;AACH;AAEA,IAAM,WAAW,QAAQ,QAAQ,UAAU,EAAE,YAAY,sCAAsC;AAE/F,WAAW,SAAS,QAAQ,MAAM,EAAE,YAAY,yCAAyC,CAAC,EAAE;AAAA,EAC1F,CAAC,SACC,IAAI,YAAY;AACd,UAAM,SAAS,MAAM,WAAW,QAAQ,IAAI,GAAG,UAAU,IAAI,CAAC;AAC9D,UAAM,OAAO,MAAM,aAAa,MAAM;AACtC,QAAI,KAAK,WAAW,GAAG;AACrB,cAAQ,IAAI,MAAM,OAAO,SAAS,qBAAqB,OAAO,KAAK,EAAE;AACrE;AAAA,IACF;AACA,UAAM,IAAI,CAAC,MAAmC,IAAI,IAAI,EAAE,OAAO,KAAK;AACpE,YAAQ;AAAA,MACN;AAAA,QACE,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,SAAS,CAAC;AAAA,QAC1E,CAAC,QAAQ,SAAS,YAAY,UAAU,WAAW;AAAA,MACrD;AAAA,IACF;AAAA,EACF,CAAC;AACL;AAEA;AAAA,EACE,SACG,QAAQ,mBAAmB,EAC3B,YAAY,yDAAyD,EACrE,OAAO,aAAa,4DAA4D;AACrF,EAAE;AAAA,EAAO,CAAC,OAAiB,SACzB,IAAI,YAAY;AACd,UAAM,SAAS,MAAM,WAAW,QAAQ,IAAI,GAAG,UAAU,IAAI,CAAC;AAC9D,UAAM,OAAO,MAAM,gBAAgB,QAAQ,EAAE,OAAO,SAAS,KAAK,QAAQ,CAAC;AAC3E,QAAI,KAAK,WAAW,GAAG;AACrB,cAAQ,IAAI,gCAAgC,OAAO,WAAW,EAAE;AAChE;AAAA,IACF;AACA,YAAQ;AAAA,MACN;AAAA,QACE,KAAK,IAAI,CAAC,MAAM;AAAA,UACd,EAAE;AAAA,UACF,EAAE;AAAA,UACF,EAAE,UAAU,OAAO,MAAM,IAAI,EAAE,KAAK;AAAA,UACpC,EAAE,WAAW,OAAO,MAAM,IAAI,EAAE,MAAM;AAAA,UACtC,EAAE;AAAA,UACF,EAAE,UAAU;AAAA,QACd,CAAC;AAAA,QACD,CAAC,QAAQ,UAAU,SAAS,UAAU,SAAS,EAAE;AAAA,MACnD;AAAA,IACF;AACA,eAAW,KAAK,MAAM;AACpB,UAAI,EAAE,MAAO,SAAQ,OAAO,MAAM,GAAG,mBAAmB,EAAE,MAAM,EAAE,KAAK,CAAC;AAAA,CAAI;AAAA,IAC9E;AACA,QAAI,KAAK,KAAK,CAAC,MAAM,EAAE,WAAW,cAAc,EAAE,WAAW,OAAO,EAAG,SAAQ,WAAW;AAAA,EAC5F,CAAC;AACH;AAEA;AAAA,EACE,SACG,QAAQ,MAAM,EACd,YAAY,yGAAyG,EACrH,OAAO,WAAW,wCAAwC,EAC1D,OAAO,aAAa,4BAA4B;AACrD,EAAE;AAAA,EAAO,CAAC,SACR,IAAI,YAAY;AACd,UAAM,SAAS,MAAM,WAAW,QAAQ,IAAI,GAAG,UAAU,IAAI,CAAC;AAC9D,UAAM,UAAU,MAAM,aAAa,QAAQ,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO,CAAC;AACrF,eAAW,KAAK,SAAS;AACvB,cAAQ,IAAI,GAAG,EAAE,UAAU,UAAU,KAAK,SAAS,UAAU,OAAO,IAAI,EAAE,IAAI,OAAO,EAAE,IAAI,EAAE;AAAA,IAC/F;AACA,QAAI,QAAQ,WAAW,EAAG,SAAQ,IAAI,wDAAwD;AAAA,QACzF,SAAQ,IAAI;AAAA,yEAA4E;AAAA,EAC/F,CAAC;AACH;AAEA,QAAQ,WAAW,QAAQ,IAAI,EAAE,MAAM,CAAC,UAAmB,KAAM,MAAgB,OAAO,CAAC;","names":["path","overrides","readFile","path","mkdir","readFile","writeFile","path","readFile","writeFile","path","readFile","readdir","path","path","readFile","readdir","SOURCE_EXTENSIONS","path","readFile","writeFile","mkdir","readFile","writeFile","path","contentHash","isFieldSchema","isFieldSchema","localHash","contentHash","contentHash","localHash","localHash","contentHash","require","path"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/config.ts","../src/client.ts","../src/commands/list.ts","../src/commands/pull.ts","../src/lock.ts","../src/manifest.ts","../src/registry.ts","../src/init.ts","../src/typegen.ts","../src/commands/push.ts","../src/drift.ts","../src/commands/status.ts","../src/status.ts","../src/commands/init.ts","../src/commands/schema.ts","../src/schema-diff.ts","../src/output.ts"],"sourcesContent":["import { Command, InvalidArgumentError } from \"commander\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { loadConfig, type ConfigOverrides } from \"./config\";\nimport { listSections } from \"./commands/list\";\nimport { pullSections } from \"./commands/pull\";\nimport { pushSection, PushConflict } from \"./commands/push\";\nimport { sectionStatuses } from \"./commands/status\";\nimport { initSections } from \"./commands/init\";\nimport { pullSchemas, pushSchema, SchemaFormatConflict, SchemaRejected } from \"./commands/schema\";\nimport { fail, table } from \"./output\";\nimport { formatDriftWarning } from \"./drift\";\nimport { formatSchemaDiff, type SchemaPushPreview } from \"./schema-diff\";\nimport { createInterface } from \"node:readline/promises\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nfunction parseVersion(value: string): number {\n const n = Number.parseInt(value, 10);\n if (!Number.isInteger(n) || n < 1) throw new InvalidArgumentError(\"version must be a positive integer\");\n return n;\n}\n\ntype CommonOptions = { framework?: string; dir?: string };\n\nfunction overrides(opts: CommonOptions): ConfigOverrides {\n return { framework: opts.framework, dir: opts.dir };\n}\n\nfunction withCommon(cmd: Command): Command {\n return cmd\n .option(\"--framework <name>\", \"source variant, for example react-next (default from config)\")\n .option(\"--dir <path>\", \"sections directory (default from config, components/sections)\");\n}\n\nasync function run(action: () => Promise<void>): Promise<void> {\n try {\n await action();\n } catch (error) {\n if (error instanceof PushConflict) {\n const latest = error.latest ? `v${error.latest.version} (${error.latest.contentHash.slice(0, 12)})` : \"none\";\n fail(`${error.message}\\n latest on server: ${latest}\\n pull first, or push --force to overwrite`);\n }\n if (error instanceof SchemaFormatConflict) {\n if (error.preview) console.log(formatSchemaDiff(error.preview));\n fail(\n `${error.message}\\n dashboard: ${error.currentFormat}\\n code: ${error.newFormat}\\n` +\n ` rerun with --force to replace the ${error.currentFormat} schema: botlr schema push ${error.sectionName} --force`,\n );\n }\n if (error instanceof SchemaRejected) {\n fail(`the server rejected the schema of '${error.sectionName}': ${error.message}`);\n }\n fail((error as Error).message);\n }\n}\n\nconst program = new Command(\"botlr\")\n .description(\"Pull and push section source between a Botlr site and this app\")\n .version(version)\n .configureHelp({ sortSubcommands: true });\n\nwithCommon(\n program\n .command(\"pull [names...]\")\n .description(\"pull sections into the sections directory; writes <name>.botlr.json and the lock file\")\n .option(\"--all\", \"every section the server lists for the framework\")\n .option(\"--version <n>\", \"a specific version instead of the latest\", parseVersion)\n .option(\"--shared\", \"the shared row (per section definition) even when the app has its own\")\n .option(\"--force\", \"overwrite files that changed locally since the last pull\")\n .option(\"--no-registry\", \"do not add the section to the registry file\")\n .option(\"--no-types\", \"do not write <name>.props.ts from the definition's props schema\"),\n).action((names: string[], opts: CommonOptions & { all?: boolean; version?: number; shared?: boolean; force?: boolean; registry?: boolean; types?: boolean }) =>\n run(async () => {\n if (names.length === 0 && !opts.all) fail(\"name a section or pass --all\");\n if (opts.all && opts.version !== undefined) fail(\"--version needs a single section name\");\n const config = await loadConfig(process.cwd(), overrides(opts));\n const results = await pullSections(config, {\n names,\n all: opts.all,\n version: opts.version,\n shared: opts.shared,\n force: opts.force,\n noRegistry: opts.registry === false,\n noTypes: opts.types === false,\n });\n if (results.length === 0) {\n console.log(\"nothing to pull\");\n return;\n }\n for (const r of results) {\n if (r.skipped) {\n console.log(`skip ${r.name}: ${r.skipped}`);\n continue;\n }\n console.log(`pull ${r.name} ${r.scope} v${r.version} (${r.files.length} file${r.files.length === 1 ? \"\" : \"s\"})`);\n if (r.types?.changed) console.log(` types: wrote ${r.types.interfaceName} to ${path.relative(process.cwd(), r.types.file)}`);\n if (r.typesNotice) console.log(` types: ${r.typesNotice}`);\n const registry = r.registry;\n if (!registry) continue;\n const file = path.relative(process.cwd(), registry.file);\n if (registry.notice) console.log(` registry: ${registry.notice}`);\n else if (registry.changed) {\n const what = [registry.addedImport ? \"import\" : \"\", registry.addedEntry ? `\"${r.name}\" entry` : \"\"].filter(Boolean).join(\" and \");\n console.log(` registry: added ${what} to ${file}`);\n }\n }\n }),\n);\n\nwithCommon(\n program\n .command(\"push <name>\")\n .description(\"push the section's files and manifest as a new version (needs BOTLR_PAT)\")\n .option(\"-m, --message <text>\", \"a note on the version, at most 500 characters\")\n .option(\"--shared\", \"write the shared row (per section definition) instead of this app's row\")\n .option(\"--create\", \"create the section definition when the dashboard does not have it\")\n .option(\"--force\", \"skip the conflict check (omits baseVersion)\"),\n).action((name: string, opts: CommonOptions & { message?: string; shared?: boolean; create?: boolean; force?: boolean }) =>\n run(async () => {\n const config = await loadConfig(process.cwd(), overrides(opts));\n const result = await pushSection(config, {\n name,\n message: opts.message,\n shared: opts.shared,\n create: opts.create,\n force: opts.force,\n });\n if (result.created) console.log(`pushed ${result.name} ${result.scope} v${result.version}`);\n else console.log(`${result.name} ${result.scope} v${result.version} already matches, nothing pushed`);\n if (result.drift) process.stderr.write(`${formatDriftWarning(result.name, result.drift)}\\n`);\n }),\n);\n\nconst sections = program.command(\"sections\").description(\"list, inspect and bootstrap sections\");\n\nwithCommon(sections.command(\"list\").description(\"every section the server has source for\")).action(\n (opts: CommonOptions) =>\n run(async () => {\n const config = await loadConfig(process.cwd(), overrides(opts));\n const rows = await listSections(config);\n if (rows.length === 0) {\n console.log(`no ${config.framework} sections for app ${config.appId}`);\n return;\n }\n const v = (s: { version: number } | null) => (s ? `v${s.version}` : \"-\");\n console.log(\n table(\n rows.map((s) => [s.name, s.title, v(s.instance), v(s.shared), s.effective]),\n [\"name\", \"title\", \"instance\", \"shared\", \"effective\"],\n ),\n );\n }),\n);\n\nwithCommon(\n sections\n .command(\"status [names...]\")\n .description(\"clean | modified | behind | diverged per local manifest\")\n .option(\"--offline\", \"compare with the lock file only, without asking the server\"),\n).action((names: string[], opts: CommonOptions & { offline?: boolean }) =>\n run(async () => {\n const config = await loadConfig(process.cwd(), overrides(opts));\n const rows = await sectionStatuses(config, { names, offline: opts.offline });\n if (rows.length === 0) {\n console.log(`no *.botlr.json manifests in ${config.sectionsDir}`);\n return;\n }\n console.log(\n table(\n rows.map((r) => [\n r.name,\n r.status,\n r.local === null ? \"-\" : `v${r.local}`,\n r.remote === null ? \"-\" : `v${r.remote}`,\n r.scope,\n r.detail ?? \"\",\n ]),\n [\"name\", \"status\", \"local\", \"remote\", \"scope\", \"\"],\n ),\n );\n for (const r of rows) {\n if (r.drift) process.stderr.write(`${formatDriftWarning(r.name, r.drift)}\\n`);\n }\n if (rows.some((r) => r.status === \"diverged\" || r.status === \"error\")) process.exitCode = 1;\n }),\n);\n\nwithCommon(\n sections\n .command(\"init\")\n .description(\"derive first <name>.botlr.json manifests from publisher-section-registry.ts and the XDefinition exports\")\n .option(\"--force\", \"overwrite manifests that already exist\")\n .option(\"--dry-run\", \"show what would be written\"),\n).action((opts: CommonOptions & { force?: boolean; dryRun?: boolean }) =>\n run(async () => {\n const config = await loadConfig(process.cwd(), overrides(opts));\n const results = await initSections(config, { force: opts.force, dryRun: opts.dryRun });\n for (const r of results) {\n console.log(`${r.written ? \"write\" : opts.dryRun ? \"would\" : \"keep \"} ${r.name} -> ${r.file}`);\n }\n if (results.length === 0) console.log(\"the registry maps no components with a file next to it\");\n else console.log(`\\nreview the manifests, then push each section: botlr push <name> --create`);\n }),\n);\n\nconst schema = program\n .command(\"schema\")\n .description(\"copy a section's props schema between the dashboard and <name>.botlr.json\");\n\nwithCommon(\n schema\n .command(\"pull [names...]\")\n .description(\"write the dashboard's props schema into <name>.botlr.json as 'schema', then regenerate <name>.props.ts\")\n .option(\"--all\", \"every section with a manifest in the sections directory\")\n .option(\"--no-types\", \"do not write <name>.props.ts afterwards\"),\n).action((names: string[], opts: CommonOptions & { all?: boolean; types?: boolean }) =>\n run(async () => {\n if (names.length === 0 && !opts.all) fail(\"name a section or pass --all\");\n const config = await loadConfig(process.cwd(), overrides(opts));\n const results = await pullSchemas(config, { names, all: opts.all, noTypes: opts.types === false });\n if (results.length === 0) {\n console.log(`no *.botlr.json manifests in ${config.sectionsDir}`);\n return;\n }\n for (const r of results) {\n if (r.error) {\n console.log(`skip ${r.name}: ${r.error}`);\n process.exitCode = 1;\n continue;\n }\n const format = r.format ? ` (${r.format})` : \"\";\n if (r.changed) console.log(`pull ${r.name}: wrote schema${format} to ${path.relative(process.cwd(), r.file)}`);\n else console.log(`pull ${r.name}: schema unchanged${format}`);\n if (r.types?.changed) console.log(` types: wrote ${r.types.interfaceName} to ${path.relative(process.cwd(), r.types.file)}`);\n }\n }),\n);\n\n/** Ask on the terminal; refuse to guess when there is none. */\nasync function confirmOnTerminal(preview: SchemaPushPreview): Promise<boolean> {\n console.log(formatSchemaDiff(preview));\n if (!process.stdin.isTTY) {\n fail(`not a terminal: rerun with --yes to push the schema of '${preview.name}' without asking`);\n }\n const question =\n preview.expected === \"merged\"\n ? `merge the code's fields into the dashboard's ${preview.currentFormat} schema of '${preview.name}'? [y/N] `\n : preview.force && preview.currentFormat !== preview.nextFormat\n ? `replace the dashboard's ${preview.currentFormat} schema of '${preview.name}' with the code's ${preview.nextFormat} schema? [y/N] `\n : `replace the dashboard's schema of '${preview.name}' with the code's? [y/N] `;\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n try {\n const answer = await rl.question(question);\n return /^y(es)?$/i.test(answer.trim());\n } finally {\n rl.close();\n }\n}\n\nwithCommon(\n schema\n .command(\"push <name>\")\n .description(\"send the manifest's 'schema' to the dashboard as the definition's props schema (needs BOTLR_PAT)\")\n .option(\"--force\", \"replace the schema outright, instead of merging the code's fields into a FormBuilder schema\")\n .option(\"-y, --yes\", \"push without asking\")\n .option(\"--no-types\", \"do not write <name>.props.ts afterwards\"),\n).action((name: string, opts: CommonOptions & { force?: boolean; yes?: boolean; types?: boolean }) =>\n run(async () => {\n const config = await loadConfig(process.cwd(), overrides(opts));\n const result = await pushSchema(config, {\n name,\n force: opts.force,\n noTypes: opts.types === false,\n confirm: opts.yes\n ? (preview) => {\n console.log(formatSchemaDiff(preview));\n return true;\n }\n : confirmOnTerminal,\n });\n if (!result.pushed) {\n console.log(`nothing pushed`);\n return;\n }\n const formats = result.previousFormat && result.format && result.previousFormat !== result.format\n ? ` (${result.previousFormat} -> ${result.format})`\n : result.format ? ` (${result.format})` : \"\";\n if (!result.changed) console.log(`schema of ${result.name}: nothing to change${formats}`);\n else if (result.mode === \"merged\") {\n const added = result.added?.length ? `added ${result.added.join(\", \")}` : \"added nothing\";\n const kept = result.preview.diff.kept.length ? `; kept ${result.preview.diff.kept.join(\", \")}` : \"\";\n console.log(`merged schema of ${result.name}${formats}: ${added}${kept}`);\n } else console.log(`replaced schema of ${result.name}${formats}`);\n if (result.dashboardOnly?.length) {\n console.log(` the dashboard also defines: ${result.dashboardOnly.join(\", \")} (not in the code)`);\n }\n if (result.types?.changed) console.log(` types: wrote ${result.types.interfaceName} to ${path.relative(process.cwd(), result.types.file)}`);\n }),\n);\n\nprogram.parseAsync(process.argv).catch((error: unknown) => fail((error as Error).message));\n","import { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport const CONFIG_FILE = \"botlr.config.json\";\nexport const DEFAULT_FRAMEWORK = \"react-next\";\nexport const DEFAULT_SECTIONS_DIR = \"components/sections\";\nexport const DEFAULT_REGISTRY_FILE = \"publisher-section-registry.ts\";\n\n/** `botlr.config.json` */\nexport interface BotlrCliConfigFile {\n baseUrl?: string;\n appId?: string;\n framework?: string;\n sectionsDir?: string;\n /** Registry file `pull` keeps up to date, relative to `sectionsDir`. Default `publisher-section-registry.ts`. */\n registryFile?: string;\n /** Write `<name>.props.ts` after a pull. Default true; `false` turns it off (`--no-types` does per call). */\n types?: boolean;\n}\n\nexport interface ResolvedConfig {\n /** Directory holding `botlr.config.json` (or the cwd when there is none). Paths resolve against it. */\n root: string;\n configPath: string | null;\n baseUrl: string;\n appId: string;\n framework: string;\n /** Absolute path of the sections directory. */\n sectionsDir: string;\n /** Absolute path of the registry file (`sectionsDir/publisher-section-registry.ts` by default); it may not exist. */\n registryFile: string;\n /** Whether `pull` writes `<name>.props.ts` from the definition's schema. */\n types: boolean;\n /** Site token, `BOTLR_API_KEY`. */\n apiKey: string | undefined;\n /** Personal access token, `BOTLR_PAT`. */\n personalToken: string | undefined;\n}\n\nexport interface ConfigOverrides {\n framework?: string;\n /** Sections directory, relative to the cwd (as typed on the command line). */\n dir?: string;\n baseUrl?: string;\n appId?: string;\n}\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigError\";\n }\n}\n\nasync function exists(file: string): Promise<boolean> {\n try {\n await access(file);\n return true;\n } catch {\n return false;\n }\n}\n\n/** The nearest `botlr.config.json` at or above `startDir`, or null. */\nexport async function findConfigFile(startDir: string): Promise<string | null> {\n let dir = path.resolve(startDir);\n for (;;) {\n const candidate = path.join(dir, CONFIG_FILE);\n if (await exists(candidate)) return candidate;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\nexport async function readConfigFile(file: string): Promise<BotlrCliConfigFile> {\n const raw = await readFile(file, \"utf8\");\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new ConfigError(`${file} must hold a JSON object`);\n }\n return parsed as BotlrCliConfigFile;\n } catch (error) {\n if (error instanceof ConfigError) throw error;\n throw new ConfigError(`${file} is not valid JSON: ${(error as Error).message}`);\n }\n}\n\n/**\n * The effective config: command-line overrides, then environment\n * (`BOTLR_BASE_URL`, `BOTLR_APP_ID`, `BOTLR_FRAMEWORK`, `BOTLR_SECTIONS_DIR`),\n * then `botlr.config.json`, then defaults. Tokens come from `BOTLR_API_KEY`\n * and `BOTLR_PAT` only.\n */\nexport async function loadConfig(\n cwd: string,\n overrides: ConfigOverrides = {},\n env: NodeJS.ProcessEnv = process.env,\n): Promise<ResolvedConfig> {\n const configPath = await findConfigFile(cwd);\n const file = configPath ? await readConfigFile(configPath) : {};\n const root = configPath ? path.dirname(configPath) : path.resolve(cwd);\n\n const baseUrl = overrides.baseUrl ?? env.BOTLR_BASE_URL ?? file.baseUrl;\n const appId = overrides.appId ?? env.BOTLR_APP_ID ?? file.appId;\n if (!baseUrl) {\n throw new ConfigError(`No baseUrl: set it in ${CONFIG_FILE} or BOTLR_BASE_URL`);\n }\n if (!appId) {\n throw new ConfigError(`No appId: set it in ${CONFIG_FILE} or BOTLR_APP_ID`);\n }\n\n const sectionsDir = overrides.dir\n ? path.resolve(cwd, overrides.dir)\n : path.resolve(root, env.BOTLR_SECTIONS_DIR ?? file.sectionsDir ?? DEFAULT_SECTIONS_DIR);\n\n return {\n root,\n configPath,\n baseUrl: baseUrl.replace(/\\/+$/, \"\"),\n appId,\n framework: overrides.framework ?? env.BOTLR_FRAMEWORK ?? file.framework ?? DEFAULT_FRAMEWORK,\n sectionsDir,\n registryFile: path.resolve(sectionsDir, file.registryFile ?? DEFAULT_REGISTRY_FILE),\n types: file.types !== false,\n apiKey: env.BOTLR_API_KEY || undefined,\n personalToken: env.BOTLR_PAT || undefined,\n };\n}\n","import { createBotlrClient, type BotlrClient } from \"@botlr/sdk\";\nimport { ConfigError, type ResolvedConfig } from \"./config\";\n\n/** A client from the resolved config. `needPersonalToken` makes a missing `BOTLR_PAT` an error up front. */\nexport function clientFor(config: ResolvedConfig, options: { needPersonalToken?: boolean } = {}): BotlrClient {\n if (!config.apiKey && !options.needPersonalToken) {\n // Reads work without a token against a dev server; warn once so a 401 is no surprise.\n process.stderr.write(\"botlr: BOTLR_API_KEY is not set, requests go out without a site token\\n\");\n }\n if (options.needPersonalToken && !config.personalToken) {\n throw new ConfigError(\"Pushing needs BOTLR_PAT: a personal access token with the write:sections scope\");\n }\n return createBotlrClient({\n baseUrl: config.baseUrl,\n appId: config.appId,\n apiKey: config.apiKey,\n personalToken: config.personalToken,\n });\n}\n","import type { SectionSourceSummary } from \"@botlr/sdk\";\nimport type { ResolvedConfig } from \"../config\";\nimport { clientFor } from \"../client\";\n\nexport async function listSections(config: ResolvedConfig): Promise<SectionSourceSummary[]> {\n const client = clientFor(config);\n const listing = await client.sections.list({ framework: config.framework });\n return listing.sections;\n}\n","import { contentHash, type SectionSourcePullResponse, type SectionSourceScope } from \"@botlr/sdk\";\nimport type { ResolvedConfig } from \"../config\";\nimport { clientFor } from \"../client\";\nimport { nextLockEntry, readLock, writeLock, type LockEntry } from \"../lock\";\nimport { readManifest, readSectionFiles, writeManifestIfChanged, writeSectionFiles } from \"../manifest\";\nimport { registerSection, type RegistryUpdate } from \"../registry\";\nimport { writePropsTypes, type PropsTypesUpdate } from \"../typegen\";\n\nexport interface PullOptions {\n /** Section names; empty with `all: true` pulls every section the server lists. */\n names: string[];\n all?: boolean;\n version?: number;\n /** Pull the shared row even when the app has its own. */\n shared?: boolean;\n /** Overwrite local files that changed since the last pull. */\n force?: boolean;\n /** Leave the registry file alone. */\n noRegistry?: boolean;\n /** Do not write `<name>.props.ts`; also off when the config says `types: false`. */\n noTypes?: boolean;\n}\n\nexport interface PullResult {\n name: string;\n scope: SectionSourceScope;\n version: number;\n files: string[];\n /** Set when the section was skipped instead of written. */\n skipped?: string;\n /** Whether `<name>.botlr.json` changed; false when the local manifest already said the same. */\n manifestChanged?: boolean;\n /** What happened to the registry file; absent for skipped sections and with `noRegistry`. */\n registry?: RegistryUpdate;\n /** What happened to `<name>.props.ts`; absent when types are off or the section has no definition. */\n types?: PropsTypesUpdate;\n /** Why no prop types were written, when they were expected. */\n typesNotice?: string;\n}\n\n/** Content hash of the local files, or null when the manifest or a file is missing. */\nasync function localHash(sectionsDir: string, name: string): Promise<string | null> {\n try {\n const manifest = await readManifest(sectionsDir, name);\n return await contentHash(await readSectionFiles(sectionsDir, manifest));\n } catch {\n return null;\n }\n}\n\nexport async function pullSections(config: ResolvedConfig, options: PullOptions): Promise<PullResult[]> {\n const client = clientFor(config);\n const scope: SectionSourceScope | undefined = options.shared ? \"shared\" : undefined;\n\n let names = options.names;\n if (options.all) {\n const listing = await client.sections.list({ framework: config.framework });\n names = listing.sections\n .filter((s) => (options.shared ? s.shared : s.instance || s.shared))\n .map((s) => s.name);\n }\n if (names.length === 0) return [];\n\n const lock = await readLock(config.root);\n const results: PullResult[] = [];\n\n for (const name of names) {\n const entry = lock[name];\n if (entry && !options.force) {\n const current = await localHash(config.sectionsDir, name);\n if (current !== null && current !== entry.contentHash) {\n results.push({ name, scope: entry.scope, version: entry.version, files: [], skipped: \"modified locally, use --force to overwrite\" });\n continue;\n }\n }\n\n const response: SectionSourcePullResponse = await client.sections.pull(name, {\n framework: config.framework,\n version: options.version,\n scope,\n });\n const { source } = response;\n\n const files = await writeSectionFiles(config.sectionsDir, source.files);\n const manifest = await writeManifestIfChanged(config.sectionsDir, name, source.manifest);\n const registry = options.noRegistry\n ? undefined\n : await registerSection(config.sectionsDir, config.registryFile, source.manifest);\n\n let types: PropsTypesUpdate | undefined;\n let typesNotice: string | undefined;\n if (config.types && !options.noTypes) {\n if (response.definition) {\n types = await writePropsTypes(config.sectionsDir, source.manifest, response.definition.schema);\n } else {\n typesNotice = \"no section definition resolves for this section, no prop types written\";\n }\n }\n\n const fresh: LockEntry = {\n scope: source.scope,\n framework: source.framework,\n version: source.version,\n contentHash: source.contentHash,\n pulledAt: new Date().toISOString(),\n };\n lock[name] = nextLockEntry(entry, fresh);\n results.push({\n name,\n scope: source.scope,\n version: source.version,\n files,\n manifestChanged: manifest.changed,\n registry,\n types,\n typesNotice,\n });\n }\n\n await writeLock(config.root, lock);\n return results;\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { SectionSourceScope } from \"@botlr/sdk\";\n\nexport const LOCK_DIR = \".botlr\";\nexport const LOCK_FILE = \"sections.lock.json\";\n\nexport interface LockEntry {\n scope: SectionSourceScope;\n framework: string;\n version: number;\n contentHash: string;\n /**\n * ISO timestamp of the pull or push that first put this version here. A\n * pull that lands the same scope, version and hash again keeps it, so\n * re-pulling does not touch the lock file.\n */\n pulledAt: string;\n}\n\n/**\n * `.botlr/sections.lock.json`: one entry per section name, for the whole\n * app. The lock is not keyed by directory: `--dir` points a command at\n * another sections directory but still records into this one lock, so a\n * section name means one thing per app whichever directory holds it.\n */\nexport type SectionsLock = Record<string, LockEntry>;\n\n/**\n * The entry to record after a pull or push: `fresh` with the previous\n * `pulledAt` kept when scope, framework, version and hash are unchanged.\n */\nexport function nextLockEntry(previous: LockEntry | undefined, fresh: LockEntry): LockEntry {\n if (\n previous &&\n previous.scope === fresh.scope &&\n previous.framework === fresh.framework &&\n previous.version === fresh.version &&\n previous.contentHash === fresh.contentHash\n ) {\n return { ...fresh, pulledAt: previous.pulledAt };\n }\n return fresh;\n}\n\nexport function lockPath(root: string): string {\n return path.join(root, LOCK_DIR, LOCK_FILE);\n}\n\nexport async function readLock(root: string): Promise<SectionsLock> {\n try {\n const raw = await readFile(lockPath(root), \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return {};\n return parsed as SectionsLock;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n throw error;\n }\n}\n\nexport async function writeLock(root: string, lock: SectionsLock): Promise<void> {\n const file = lockPath(root);\n await mkdir(path.dirname(file), { recursive: true });\n const sorted = Object.fromEntries(Object.entries(lock).sort(([a], [b]) => a.localeCompare(b)));\n await writeFile(file, `${JSON.stringify(sorted, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function updateLock(root: string, name: string, entry: LockEntry): Promise<SectionsLock> {\n const lock = await readLock(root);\n lock[name] = nextLockEntry(lock[name], entry);\n await writeLock(root, lock);\n return lock;\n}\n","import { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n isValidSectionPath,\n stripManifestState,\n type SectionManifest,\n type SectionSourceFileInput,\n} from \"@botlr/sdk\";\n\nexport const MANIFEST_SUFFIX = \".botlr.json\";\n\nexport class ManifestError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ManifestError\";\n }\n}\n\nexport function manifestPath(sectionsDir: string, name: string): string {\n return path.join(sectionsDir, `${name}${MANIFEST_SUFFIX}`);\n}\n\n/** Section names that have a manifest in `sectionsDir`, sorted. */\nexport async function listManifests(sectionsDir: string): Promise<string[]> {\n let entries: string[];\n try {\n entries = await readdir(sectionsDir);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n throw error;\n }\n return entries\n .filter((entry) => entry.endsWith(MANIFEST_SUFFIX))\n .map((entry) => entry.slice(0, -MANIFEST_SUFFIX.length))\n .sort();\n}\n\nexport async function readManifest(sectionsDir: string, name: string): Promise<SectionManifest> {\n const file = manifestPath(sectionsDir, name);\n let raw: string;\n try {\n raw = await readFile(file, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new ManifestError(`No manifest for '${name}': expected ${file}`);\n }\n throw error;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n throw new ManifestError(`${file} is not valid JSON: ${(error as Error).message}`);\n }\n return validateManifest(parsed, file);\n}\n\nexport function validateManifest(value: unknown, where = \"manifest\"): SectionManifest {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new ManifestError(`${where} must be a JSON object`);\n }\n const m = value as Record<string, unknown>;\n if (typeof m.section !== \"string\" || !m.section) throw new ManifestError(`${where}: 'section' is required`);\n if (typeof m.entry !== \"string\" || !m.entry) throw new ManifestError(`${where}: 'entry' is required`);\n if (!Array.isArray(m.files) || m.files.length === 0 || !m.files.every((f) => typeof f === \"string\")) {\n throw new ManifestError(`${where}: 'files' must list at least one path`);\n }\n const files = m.files as string[];\n for (const file of files) {\n if (!isValidSectionPath(file)) throw new ManifestError(`${where}: invalid file path '${file}'`);\n }\n if (!files.includes(m.entry)) throw new ManifestError(`${where}: 'entry' (${m.entry}) must be listed in 'files'`);\n if (m.framework !== undefined && typeof m.framework !== \"string\") {\n throw new ManifestError(`${where}: 'framework' must be a string`);\n }\n return m as unknown as SectionManifest;\n}\n\n/** Top-level manifest keys in the order the CLI writes them; anything else follows alphabetically. */\nexport const MANIFEST_KEY_ORDER = [\n \"section\",\n \"framework\",\n \"entry\",\n \"exportName\",\n \"files\",\n \"title\",\n \"description\",\n \"category\",\n \"icon\",\n \"dependencies\",\n \"schema\",\n] as const;\n\nconst DEPENDENCIES_KEY_ORDER = [\"npm\", \"internal\"] as const;\n\nfunction orderKeys(value: Record<string, unknown>, first: readonly string[]): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const key of first) {\n if (key in value && value[key] !== undefined) out[key] = value[key];\n }\n for (const key of Object.keys(value).sort()) {\n if (first.includes(key) || value[key] === undefined) continue;\n out[key] = value[key];\n }\n return out;\n}\n\nfunction normalizeNested(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(normalizeNested);\n if (value && typeof value === \"object\") {\n const record = value as Record<string, unknown>;\n const ordered = orderKeys(record, []);\n for (const key of Object.keys(ordered)) ordered[key] = normalizeNested(ordered[key]);\n return ordered;\n }\n return value;\n}\n\n/**\n * The manifest with pull state removed and keys in a fixed order: the known\n * keys first (`MANIFEST_KEY_ORDER`), then unknown keys alphabetically;\n * `dependencies` lists `npm` before `internal`, and every nested object is\n * sorted alphabetically. Arrays keep their order. The server stores\n * manifests as jsonb, which forgets key order, so this is what makes a pull\n * after a push write the same bytes.\n */\nexport function normalizeManifest(manifest: SectionManifest): SectionManifest {\n const stripped = stripManifestState(manifest) as Record<string, unknown>;\n const ordered = orderKeys(stripped, MANIFEST_KEY_ORDER);\n for (const key of Object.keys(ordered)) {\n if (key === \"dependencies\" && ordered[key] && typeof ordered[key] === \"object\" && !Array.isArray(ordered[key])) {\n const deps = orderKeys(ordered[key] as Record<string, unknown>, DEPENDENCIES_KEY_ORDER);\n for (const depKey of Object.keys(deps)) deps[depKey] = normalizeNested(deps[depKey]);\n ordered[key] = deps;\n } else {\n ordered[key] = normalizeNested(ordered[key]);\n }\n }\n return ordered as unknown as SectionManifest;\n}\n\n/** The exact text `writeManifest` writes: normalized, 2-space JSON, trailing newline. */\nexport function formatManifest(manifest: SectionManifest): string {\n return `${JSON.stringify(normalizeManifest(manifest), null, 2)}\\n`;\n}\n\n/** True when two manifests hold the same data, whatever their key order or formatting. */\nexport function manifestsEqual(a: SectionManifest, b: SectionManifest): boolean {\n return formatManifest(a) === formatManifest(b);\n}\n\n/** Write `<name>.botlr.json` without any pull state, in the CLI's fixed key order. */\nexport async function writeManifest(sectionsDir: string, name: string, manifest: SectionManifest): Promise<string> {\n const file = manifestPath(sectionsDir, name);\n await mkdir(sectionsDir, { recursive: true });\n await writeFile(file, formatManifest(manifest), \"utf8\");\n return file;\n}\n\n/**\n * Like `writeManifest`, but leaves the file alone when it already holds the\n * same manifest (compared after normalization, so a hand-formatted file that\n * says the same thing is not rewritten). Returns whether the file changed.\n */\nexport async function writeManifestIfChanged(\n sectionsDir: string,\n name: string,\n manifest: SectionManifest,\n): Promise<{ file: string; changed: boolean }> {\n const file = manifestPath(sectionsDir, name);\n try {\n const existing = JSON.parse(await readFile(file, \"utf8\")) as unknown;\n if (existing && typeof existing === \"object\" && !Array.isArray(existing)) {\n if (manifestsEqual(existing as SectionManifest, manifest)) return { file, changed: false };\n }\n } catch {\n // missing or unreadable: write it\n }\n await writeManifest(sectionsDir, name, manifest);\n return { file, changed: true };\n}\n\n/** The files a manifest lists, read from `sectionsDir`, in manifest order. */\nexport async function readSectionFiles(\n sectionsDir: string,\n manifest: SectionManifest,\n): Promise<SectionSourceFileInput[]> {\n return Promise.all(\n manifest.files.map(async (relative) => {\n const file = safeJoin(sectionsDir, relative);\n try {\n return { path: relative, content: await readFile(file, \"utf8\") };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new ManifestError(`Missing file '${relative}' listed in ${manifest.section}${MANIFEST_SUFFIX}`);\n }\n throw error;\n }\n }),\n );\n}\n\n/** Write pulled files under `sectionsDir`, creating sub-directories. */\nexport async function writeSectionFiles(sectionsDir: string, files: SectionSourceFileInput[]): Promise<string[]> {\n const written: string[] = [];\n for (const file of files) {\n const target = safeJoin(sectionsDir, file.path);\n await mkdir(path.dirname(target), { recursive: true });\n await writeFile(target, file.content, \"utf8\");\n written.push(target);\n }\n return written;\n}\n\n/** `relative` joined under `dir`, refusing paths the bridge would not accept. */\nexport function safeJoin(dir: string, relative: string): string {\n if (!isValidSectionPath(relative)) throw new ManifestError(`Invalid file path '${relative}'`);\n const target = path.resolve(dir, relative);\n const base = path.resolve(dir);\n if (target !== base && !target.startsWith(base + path.sep)) {\n throw new ManifestError(`File path '${relative}' escapes ${dir}`);\n }\n return target;\n}\n","/**\n * Registry upkeep: after a pull, make sure the satellite's\n * `publisher-section-registry.ts` imports the pulled component and maps the\n * section slug to it. The file is edited in place, by text: existing imports,\n * entries, comments and formatting are kept, and nothing is ever removed.\n */\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { SectionManifest } from \"@botlr/sdk\";\nimport { parseRegistry } from \"./init\";\n\nconst SOURCE_EXTENSIONS = [\".tsx\", \".ts\", \".jsx\", \".js\", \".mjs\", \".cjs\"];\n\nexport interface RegistryAddition {\n slug: string;\n exportName: string;\n /** Module specifier to import from, for example `./markdown`. */\n importPath: string;\n}\n\nexport interface RegistryEditResult {\n source: string;\n /** True when an import or a map entry was appended. */\n changed: boolean;\n addedImport: boolean;\n addedEntry: boolean;\n}\n\n/** `./markdown` for a registry at `sectionsDir` and an entry `markdown.tsx`; `./parts/x` for `parts/x.tsx`. */\nexport function importPathFor(registryFile: string, entryFile: string): string {\n const relative = path.relative(path.dirname(registryFile), entryFile).split(path.sep).join(\"/\");\n const ext = path.extname(relative);\n const bare = SOURCE_EXTENSIONS.includes(ext) ? relative.slice(0, -ext.length) : relative;\n return bare.startsWith(\".\") ? bare : `./${bare}`;\n}\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/**\n * Return `source` with `import { exportName } from \"importPath\";` added after\n * the last import and `slug: exportName,` added as the last entry of the\n * registry object. Each is skipped when it is already there. Quote style,\n * semicolons, indentation and trailing commas follow the surrounding code.\n */\nexport function addRegistryEntry(source: string, addition: RegistryAddition): RegistryEditResult {\n const { slug, exportName, importPath } = addition;\n if (!IDENTIFIER.test(exportName)) throw new Error(`'${exportName}' is not a valid export name`);\n\n const eol = source.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n let out = source;\n let addedImport = false;\n let addedEntry = false;\n\n // 1. Import.\n const importRe = /^[ \\t]*import\\s*(?:type\\s*)?\\{([^}]*)\\}\\s*from\\s*([\"'])([^\"']+)\\2[ \\t]*;?[ \\t]*$/gm;\n const imports = [...out.matchAll(importRe)];\n const alreadyImported = imports.some((m) =>\n m[1]!.split(\",\").some((raw) => raw.trim().split(/\\s+as\\s+/).pop()?.trim() === exportName),\n );\n if (!alreadyImported) {\n const last = imports.at(-1);\n const quote = last?.[2] ?? '\"';\n const semicolon = last ? last[0].trimEnd().endsWith(\";\") : true;\n const line = `import { ${exportName} } from ${quote}${importPath}${quote}${semicolon ? \";\" : \"\"}`;\n if (last) {\n const end = last.index! + last[0].length;\n out = `${out.slice(0, end)}${eol}${line}${out.slice(end)}`;\n } else {\n out = `${line}${eol}${eol}${out}`;\n }\n addedImport = true;\n }\n\n // 2. Map entry.\n const alreadyMapped = parseRegistry(out).some((e) => e.slug === slug) || hasEntry(out, slug);\n if (!alreadyMapped) {\n const object = findRegistryObject(out);\n if (!object) throw new Error(\"could not find the registry object (`export const ... = { ... }`)\");\n const body = out.slice(object.bodyStart, object.bodyEnd);\n const entryLines = body.split(/\\r?\\n/).filter((l) => /^\\s*(?:\"[^\"]+\"|'[^']+'|[A-Za-z0-9_$-]+)\\s*:/.test(l));\n const lastEntry = entryLines.at(-1);\n const indent = lastEntry?.match(/^\\s*/)?.[0] ?? \" \";\n const key = IDENTIFIER.test(slug) ? slug : `\"${slug}\"`;\n const entryLine = `${indent}${key}: ${exportName},`;\n\n let newBody = body;\n if (lastEntry !== undefined) {\n const stripped = lastEntry.replace(/\\/\\/.*$/, \"\").trimEnd();\n if (!stripped.endsWith(\",\")) {\n // Give the previous last entry a trailing comma so ours can follow it.\n const at = newBody.lastIndexOf(lastEntry);\n const fixed = lastEntry.replace(/^(\\s*(?:\"[^\"]+\"|'[^']+'|[A-Za-z0-9_$-]+)\\s*:\\s*[A-Za-z0-9_$]+)/, \"$1,\");\n newBody = `${newBody.slice(0, at)}${fixed}${newBody.slice(at + lastEntry.length)}`;\n }\n }\n newBody = `${newBody.replace(/\\s*$/, \"\")}${eol}${entryLine}`;\n out = `${out.slice(0, object.bodyStart)}${newBody}${out.slice(object.bodyEnd)}`;\n addedEntry = true;\n }\n\n return { source: out, changed: addedImport || addedEntry, addedImport, addedEntry };\n}\n\nfunction hasEntry(source: string, slug: string): boolean {\n const object = findRegistryObject(source);\n if (!object) return false;\n const body = source.slice(object.bodyStart, object.bodyEnd);\n const escaped = slug.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return new RegExp(`^\\\\s*(?:\"${escaped}\"|'${escaped}'|${escaped})\\\\s*:`, \"m\").test(body);\n}\n\n/** Offsets of the text between `{` and the closing `\\n}` of the registry object literal. */\nfunction findRegistryObject(source: string): { bodyStart: number; bodyEnd: number } | null {\n const open = source.match(/export\\s+const\\s+\\w+\\s*(?::[^=]*)?=\\s*\\{/) ?? source.match(/=\\s*\\{/);\n if (!open || open.index === undefined) return null;\n const bodyStart = open.index + open[0].length;\n const close = /\\r?\\n\\}/g;\n close.lastIndex = bodyStart;\n const closeMatch = close.exec(source);\n if (!closeMatch) return null;\n return { bodyStart, bodyEnd: closeMatch.index };\n}\n\nexport interface RegistryUpdate {\n /** Absolute path of the registry file. */\n file: string;\n /** False when nothing was added or the registry could not be updated. */\n changed: boolean;\n addedImport?: boolean;\n addedEntry?: boolean;\n /** Why nothing was written, for the user. */\n notice?: string;\n}\n\n/**\n * Add the pulled section to the registry file, when there is one. Returns a\n * notice instead of throwing when the registry is missing or the manifest has\n * no `exportName`, since a pull should still succeed.\n */\nexport async function registerSection(\n sectionsDir: string,\n registryFile: string,\n manifest: SectionManifest,\n): Promise<RegistryUpdate> {\n const name = path.basename(registryFile);\n let source: string;\n try {\n source = await readFile(registryFile, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return { file: registryFile, changed: false, notice: `no ${name} in ${path.dirname(registryFile)}, register the section yourself` };\n }\n throw error;\n }\n if (!manifest.exportName) {\n return { file: registryFile, changed: false, notice: `manifest has no exportName, ${name} not updated` };\n }\n const importPath = importPathFor(registryFile, path.resolve(sectionsDir, manifest.entry));\n let edit: RegistryEditResult;\n try {\n edit = addRegistryEntry(source, { slug: manifest.section, exportName: manifest.exportName, importPath });\n } catch (error) {\n return { file: registryFile, changed: false, notice: `${name} not updated: ${(error as Error).message}` };\n }\n if (edit.changed) await writeFile(registryFile, edit.source, \"utf8\");\n return { file: registryFile, changed: edit.changed, addedImport: edit.addedImport, addedEntry: edit.addedEntry };\n}\n","/**\n * `botlr sections init`: derive first manifests from a satellite app's\n * section components. It reads the registry map\n * (`publisher-section-registry.ts`) to learn which slug maps to which\n * component file, and each component's inline `XDefinition` export for the\n * title, category, description and icon. Nothing is pushed.\n */\nimport { readFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { SectionFieldSchema, SectionManifest, SectionSchemaField } from \"@botlr/sdk\";\n\nimport { DEFAULT_REGISTRY_FILE } from \"./config\";\n\n/** @deprecated use `DEFAULT_REGISTRY_FILE` from config; the path is configurable as `registryFile`. */\nexport const REGISTRY_FILE = DEFAULT_REGISTRY_FILE;\n\nexport interface RegistryEntry {\n slug: string;\n exportName: string;\n /** Module specifier as imported, for example `./Hero` */\n importPath: string;\n}\n\n/** Parse `import { X } from \"./File\"` plus `slug: X` map entries from a registry source. */\nexport function parseRegistry(source: string): RegistryEntry[] {\n const importedFrom = new Map<string, string>();\n const importRe = /import\\s*(?:type\\s*)?\\{([^}]*)\\}\\s*from\\s*[\"']([^\"']+)[\"']/g;\n for (const match of source.matchAll(importRe)) {\n const names = match[1]!;\n const spec = match[2]!;\n for (const raw of names.split(\",\")) {\n const name = raw.trim().split(/\\s+as\\s+/).pop()?.trim();\n if (name) importedFrom.set(name, spec);\n }\n }\n\n const bodyMatch = source.match(/=\\s*\\{([\\s\\S]*?)\\n\\}\\s*;?/);\n if (!bodyMatch) return [];\n const entries: RegistryEntry[] = [];\n const entryRe = /^\\s*(?:\"([^\"]+)\"|'([^']+)'|([A-Za-z0-9_$-]+))\\s*:\\s*([A-Za-z0-9_$]+)\\s*,?\\s*(?:\\/\\/.*)?$/gm;\n for (const match of bodyMatch[1]!.matchAll(entryRe)) {\n const slug = match[1] ?? match[2] ?? match[3]!;\n const exportName = match[4]!;\n const importPath = importedFrom.get(exportName);\n if (!importPath || !importPath.startsWith(\".\")) continue;\n entries.push({ slug, exportName, importPath });\n }\n return entries;\n}\n\nexport interface DefinitionMeta {\n name?: string;\n heading?: string;\n category?: string;\n description?: string;\n icon?: string;\n /** The identifier `schema:` refers to, for example `HeroSchema`. */\n schemaName?: string;\n}\n\n/** Scalar fields of an `export const XDefinition = { ... }` block, when the file has one. */\nexport function parseDefinition(source: string): DefinitionMeta | null {\n const match = source.match(/export\\s+const\\s+\\w+Definition\\s*=\\s*\\{([\\s\\S]*?)\\n\\}/);\n if (!match) return null;\n const body = match[1]!;\n const field = (key: string): string | undefined => {\n const m = body.match(new RegExp(`(?:^|\\\\n)\\\\s*${key}\\\\s*:\\\\s*(?:\"([^\"]*)\"|'([^']*)'|\\`([^\\`]*)\\`)`));\n return m ? (m[1] ?? m[2] ?? m[3]) : undefined;\n };\n const schemaName = body.match(/(?:^|\\n)\\s*schema\\s*:\\s*([A-Za-z_$][A-Za-z0-9_$]*)\\s*,?/)?.[1];\n return {\n name: field(\"name\"),\n heading: field(\"heading\"),\n category: field(\"category\"),\n description: field(\"description\"),\n icon: field(\"icon\"),\n ...(schemaName ? { schemaName } : {}),\n };\n}\n\n/** Split `a: z.string(), b: z.object({ x: z.number() })` on the commas at depth 0. */\nfunction splitTopLevel(body: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let quote: string | null = null;\n let current = \"\";\n for (let i = 0; i < body.length; i++) {\n const ch = body[i]!;\n if (quote) {\n current += ch;\n if (ch === \"\\\\\") current += body[++i] ?? \"\";\n else if (ch === quote) quote = null;\n continue;\n }\n if (ch === \"/\" && body[i + 1] === \"/\") {\n while (i < body.length && body[i] !== \"\\n\") i++;\n current += \"\\n\";\n continue;\n }\n if (ch === '\"' || ch === \"'\" || ch === \"`\") quote = ch;\n else if (\"([{\".includes(ch)) depth++;\n else if (\")]}\".includes(ch)) depth--;\n if (ch === \",\" && depth === 0) {\n parts.push(current);\n current = \"\";\n continue;\n }\n current += ch;\n }\n parts.push(current);\n return parts.map((p) => p.trim()).filter(Boolean);\n}\n\n/** The literal values of `z.enum([...])`, or null when they are not all string literals. */\nfunction enumValues(expr: string): string[] | null {\n const m = expr.match(/^z\\.enum\\(\\s*\\[([\\s\\S]*?)\\]/);\n if (!m) return null;\n const values: string[] = [];\n for (const raw of splitTopLevel(m[1]!)) {\n const lit = raw.match(/^(?:\"([^\"]*)\"|'([^']*)'|`([^`]*)`)$/);\n if (!lit) return null;\n values.push(lit[1] ?? lit[2] ?? lit[3]!);\n }\n return values;\n}\n\n/**\n * A best-effort field DSL entry for one zod expression, or null when the\n * expression is not one the CLI understands. `.optional()`, `.nullable()`,\n * `.nullish()` and `.default(...)` make the field optional; anything else is\n * required.\n */\nexport function zodFieldToSchemaField(expr: string): SectionSchemaField | null {\n const source = expr.trim();\n const optional = /\\.(optional|nullable|nullish|default)\\(/.test(source);\n let field: SectionSchemaField | null = null;\n if (/^z\\.string\\(/.test(source)) field = { type: /\\.(email)\\(/.test(source) ? \"email\" : /\\.(url)\\(/.test(source) ? \"url\" : \"text\" };\n else if (/^z\\.number\\(/.test(source)) field = { type: /\\.int\\(/.test(source) ? \"integer\" : \"number\" };\n else if (/^z\\.boolean\\(/.test(source)) field = { type: \"boolean\" };\n else if (/^z\\.enum\\(/.test(source)) {\n const options = enumValues(source);\n field = options ? { type: \"select\", options } : { type: \"select\" };\n } else if (/^z\\.array\\(/.test(source)) field = { type: \"array\" };\n else if (/^z\\.(object|record)\\(/.test(source)) field = { type: \"json\" };\n else if (/^z\\.union\\(\\s*\\[\\s*z\\.string\\(\\)\\s*,\\s*z\\.(any|object|record)\\(/.test(source)) field = { type: \"asset\" };\n if (!field) return null;\n if (!optional) field.required = true;\n const describe = source.match(/\\.describe\\(\\s*(?:\"([^\"]*)\"|'([^']*)'|`([^`]*)`)\\s*\\)/);\n const label = describe ? (describe[1] ?? describe[2] ?? describe[3]) : undefined;\n if (label) field.label = label;\n return field;\n}\n\n/**\n * The field DSL for `export const <schemaName> = z.object({ ... })` in a\n * component source, from the fields the CLI can read; null when the schema\n * is not found or no field could be read.\n */\nexport function parseZodSchema(source: string, schemaName: string): SectionFieldSchema | null {\n const start = source.match(new RegExp(`(?:export\\\\s+)?const\\\\s+${schemaName}\\\\s*=\\\\s*z\\\\.object\\\\(\\\\s*\\\\{`));\n if (!start || start.index === undefined) return null;\n const open = start.index + start[0].length;\n let depth = 1;\n let end = -1;\n for (let i = open; i < source.length; i++) {\n const ch = source[i];\n if (ch === \"{\" || ch === \"(\" || ch === \"[\") depth++;\n else if (ch === \"}\" || ch === \")\" || ch === \"]\") {\n depth--;\n if (depth === 0) {\n end = i;\n break;\n }\n }\n }\n if (end < 0) return null;\n const schema: SectionFieldSchema = {};\n for (const entry of splitTopLevel(source.slice(open, end))) {\n const m = entry.match(/^(?:\"([^\"]+)\"|'([^']+)'|([A-Za-z_$][A-Za-z0-9_$]*))\\s*:\\s*([\\s\\S]+)$/);\n if (!m) continue;\n const field = zodFieldToSchemaField(m[4]!);\n if (field) schema[m[1] ?? m[2] ?? m[3]!] = field;\n }\n return Object.keys(schema).length ? schema : null;\n}\n\n/** Module specifiers a source file imports, split into relative and package imports. */\nexport function parseImports(source: string): { internal: string[]; npm: string[] } {\n const internal = new Set<string>();\n const npm = new Set<string>();\n const re = /(?:import|export)\\s+(?:[^\"';]*?\\s+from\\s+)?[\"']([^\"']+)[\"']|import\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g;\n for (const match of source.matchAll(re)) {\n const spec = match[1] ?? match[2];\n if (!spec) continue;\n if (spec.startsWith(\".\") || spec.startsWith(\"@/\") || spec.startsWith(\"~/\")) internal.add(spec);\n else npm.add(spec.startsWith(\"@\") ? spec.split(\"/\").slice(0, 2).join(\"/\") : spec.split(\"/\")[0]!);\n }\n return { internal: [...internal].sort(), npm: [...npm].sort() };\n}\n\nconst SOURCE_EXTENSIONS = [\".tsx\", \".ts\", \".jsx\", \".js\"];\n\nasync function resolveImport(sectionsDir: string, spec: string): Promise<string | null> {\n const base = path.resolve(sectionsDir, spec);\n for (const ext of SOURCE_EXTENSIONS) {\n try {\n await readFile(base + ext);\n return base + ext;\n } catch {\n // try the next extension\n }\n }\n return null;\n}\n\nexport interface DerivedManifest {\n name: string;\n manifest: SectionManifest;\n /** The component file, absolute. */\n entryFile: string;\n}\n\nexport interface DeriveOptions {\n framework: string;\n /** npm dependency ranges to record, usually from the app's package.json. */\n npmVersions?: Record<string, string>;\n /** Registry file to read; `sectionsDir/publisher-section-registry.ts` by default. */\n registryFile?: string;\n}\n\n/** One manifest per registry entry whose component file exists. */\nexport async function deriveManifests(sectionsDir: string, options: DeriveOptions): Promise<DerivedManifest[]> {\n const registrySource = await readFile(options.registryFile ?? path.join(sectionsDir, DEFAULT_REGISTRY_FILE), \"utf8\");\n const entries = parseRegistry(registrySource);\n const out: DerivedManifest[] = [];\n for (const entry of entries) {\n const entryFile = await resolveImport(sectionsDir, entry.importPath);\n if (!entryFile) continue;\n const source = await readFile(entryFile, \"utf8\");\n const meta = parseDefinition(source);\n const schema = meta?.schemaName ? parseZodSchema(source, meta.schemaName) : null;\n const imports = parseImports(source);\n const relative = path.relative(sectionsDir, entryFile).split(path.sep).join(\"/\");\n const npm: Record<string, string> = {};\n for (const pkg of imports.npm) {\n if (pkg === \"react\" || pkg === \"next\") continue;\n npm[pkg] = options.npmVersions?.[pkg] ?? \"*\";\n }\n const manifest: SectionManifest = {\n section: entry.slug,\n framework: options.framework,\n entry: relative,\n exportName: entry.exportName,\n files: [relative],\n ...(meta?.heading ? { title: meta.heading } : {}),\n ...(meta?.description ? { description: meta.description } : {}),\n ...(meta?.category ? { category: meta.category } : {}),\n ...(meta?.icon ? { icon: meta.icon } : {}),\n dependencies: {\n ...(Object.keys(npm).length ? { npm } : {}),\n ...(imports.internal.length ? { internal: imports.internal } : {}),\n },\n ...(schema ? { schema } : {}),\n };\n out.push({ name: entry.slug, manifest, entryFile });\n }\n return out;\n}\n\n/** `dependencies` + `devDependencies` of the nearest package.json above `dir`, for version ranges. */\nexport async function readNpmVersions(dir: string): Promise<Record<string, string>> {\n let current = path.resolve(dir);\n for (;;) {\n try {\n const raw = await readFile(path.join(current, \"package.json\"), \"utf8\");\n const pkg = JSON.parse(raw) as { dependencies?: Record<string, string>; devDependencies?: Record<string, string> };\n return { ...pkg.devDependencies, ...pkg.dependencies };\n } catch {\n const parent = path.dirname(current);\n if (parent === current) return {};\n current = parent;\n }\n }\n}\n\n/** Whether the registry file exists (`sectionsDir/publisher-section-registry.ts`, or `registryFile` when given). */\nexport async function hasRegistry(sectionsDir: string, registryFile?: string): Promise<boolean> {\n const file = registryFile ?? path.join(sectionsDir, DEFAULT_REGISTRY_FILE);\n try {\n return (await readdir(path.dirname(file))).includes(path.basename(file));\n } catch {\n return false;\n }\n}\n","/**\n * Prop type generation: a section definition's props schema (as the\n * dashboard stores it) in, a TypeScript interface out. `pull` writes\n * `<name>.props.ts` next to the manifest so a component can type its props\n * from the dashboard instead of repeating the schema in zod.\n */\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n isFieldSchema,\n isFormBuilderSchema,\n type SectionFormBuilderNode,\n type SectionManifest,\n type SectionSchemaField,\n} from \"@botlr/sdk\";\n\nexport const PROPS_SUFFIX = \".props.ts\";\n\nconst STRING_TYPES = new Set([\n \"text\", \"textarea\", \"markdown\", \"richtext\", \"string\", \"email\", \"tel\", \"url\",\n \"icon\", \"color\", \"date\", \"datetime\", \"timestamp\", \"timestamptz\", \"uuid\",\n]);\nconst NUMBER_TYPES = new Set([\"number\", \"integer\", \"currency\"]);\nconst BOOLEAN_TYPES = new Set([\"boolean\"]);\nconst STRING_LIST_TYPES = new Set([\"multiselect\", \"tags\"]);\nconst LIST_TYPES = new Set([\"array\", \"list\", \"repeater\"]);\nconst OBJECT_TYPES = new Set([\"json\", \"jsonb\", \"object\"]);\nconst REFERENCE_TYPES = new Set([\n \"asset\", \"asset-picker-image\", \"asset-picker-file\", \"asset-picker-video\", \"media\",\n \"document\", \"page\", \"post\", \"reference\", \"relation\", \"entity_reference\",\n \"app_instance\", \"forum_thread\",\n]);\nconst REFERENCE_TYPE = \"string | Record<string, unknown>\";\nconst OBJECT_TYPE = \"Record<string, unknown>\";\n/** Node kinds of the FormBuilder format that only group other nodes. */\nconst GROUP_NODE_TYPES = new Set([\"section\", \"fieldset\", \"composite\", \"group\"]);\n\n/** One property of the generated interface. */\nexport interface PropField {\n name: string;\n /** TypeScript type text. */\n type: string;\n required: boolean;\n /** Doc comment lines (label, help text), without the comment markers. */\n doc: string[];\n}\n\nfunction literal(value: unknown): string | null {\n if (typeof value === \"string\") return JSON.stringify(value);\n if (typeof value === \"number\" && Number.isFinite(value)) return String(value);\n return null;\n}\n\n/** The union of a select's option values, or null when the options are not plain values or `{ value }` objects. */\nexport function optionUnion(options: unknown): string | null {\n if (!Array.isArray(options) || options.length === 0) return null;\n const literals: string[] = [];\n for (const option of options) {\n const raw = option && typeof option === \"object\" ? (option as { value?: unknown }).value : option;\n const lit = literal(raw);\n if (lit === null) return null;\n if (!literals.includes(lit)) literals.push(lit);\n }\n return literals.join(\" | \");\n}\n\nfunction wrapArray(type: string): string {\n return /^[A-Za-z0-9_<>, ]+$/.test(type) ? `${type}[]` : `Array<${type}>`;\n}\n\n/** The TypeScript type for one field of the field DSL (or a FormBuilder field node, given its field type). */\nexport function tsTypeForField(field: { type?: unknown; options?: unknown; multiple?: unknown; fields?: unknown }): string {\n const kind = typeof field.type === \"string\" ? field.type : \"\";\n const multiple = field.multiple === true;\n if (kind === \"select\") {\n const union = optionUnion(field.options) ?? \"string\";\n return multiple ? wrapArray(union) : union;\n }\n if (STRING_TYPES.has(kind)) return \"string\";\n if (NUMBER_TYPES.has(kind)) return \"number\";\n if (BOOLEAN_TYPES.has(kind)) return \"boolean\";\n if (STRING_LIST_TYPES.has(kind)) return \"string[]\";\n if (kind === \"repeater\" && Array.isArray(field.fields)) {\n const items = collectFormBuilderFields(field.fields as SectionFormBuilderNode[]);\n return items.length ? `Array<${inlineObject(items)}>` : \"unknown[]\";\n }\n if (LIST_TYPES.has(kind)) return \"unknown[]\";\n if (OBJECT_TYPES.has(kind)) return OBJECT_TYPE;\n if (REFERENCE_TYPES.has(kind)) return multiple ? `Array<${REFERENCE_TYPE}>` : REFERENCE_TYPE;\n return \"unknown\";\n}\n\nfunction docFor(field: { label?: unknown; helpText?: unknown; description?: unknown }): string[] {\n const doc: string[] = [];\n for (const value of [field.label, field.helpText ?? field.description]) {\n if (typeof value === \"string\" && value.trim()) doc.push(value.trim());\n }\n return doc;\n}\n\n/** Properties for the field DSL, in schema order. Non-object values are skipped. */\nexport function collectDslFields(schema: Record<string, unknown>): PropField[] {\n const out: PropField[] = [];\n for (const [name, value] of Object.entries(schema)) {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) continue;\n const field = value as SectionSchemaField;\n out.push({ name, type: tsTypeForField(field), required: field.required === true, doc: docFor(field) });\n }\n return out;\n}\n\n/** Properties for the FormBuilder format: field and repeater nodes, with groups flattened. */\nexport function collectFormBuilderFields(nodes: SectionFormBuilderNode[]): PropField[] {\n const out: PropField[] = [];\n for (const node of nodes) {\n if (!node || typeof node !== \"object\") continue;\n if (GROUP_NODE_TYPES.has(node.type) && Array.isArray(node.children)) {\n out.push(...collectFormBuilderFields(node.children));\n continue;\n }\n const name = typeof node.name === \"string\" && node.name ? node.name : typeof node.key === \"string\" ? node.key : \"\";\n if (!name) continue;\n const kind = node.type === \"field\" ? (node.fieldType ?? \"\") : (node.fieldType ?? node.type);\n const type = tsTypeForField({ type: kind, options: node.options, multiple: node.multiple, fields: node.fields });\n out.push({ name, type, required: node.required === true, doc: docFor(node) });\n }\n return out;\n}\n\n/** Properties for a definition schema in either format; empty for anything else. */\nexport function collectFields(schema: unknown): PropField[] {\n if (isFormBuilderSchema(schema)) return collectFormBuilderFields(schema.nodes);\n if (isFieldSchema(schema)) return collectDslFields(schema);\n return [];\n}\n\n/** The property names a definition schema defines, in either format. */\nexport function schemaFieldNames(schema: unknown): string[] {\n return collectFields(schema).map((f) => f.name);\n}\n\nconst IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\nfunction propertyKey(name: string): string {\n return IDENTIFIER_RE.test(name) ? name : JSON.stringify(name);\n}\n\nfunction inlineObject(fields: PropField[]): string {\n return `{ ${fields.map((f) => `${propertyKey(f.name)}${f.required ? \"\" : \"?\"}: ${f.type}`).join(\"; \")} }`;\n}\n\n/** `hero-banner` or `forum_new_thread` → `HeroBanner` / `ForumNewThread`. */\nexport function pascalCase(slug: string): string {\n const words = slug.split(/[^A-Za-z0-9]+/).filter(Boolean);\n const name = words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(\"\");\n return /^[0-9]/.test(name) ? `Section${name}` : name || \"Section\";\n}\n\n/** `<ExportName>Props`, from the manifest's `exportName` or a PascalCase of the slug. */\nexport function propsInterfaceName(manifest: Pick<SectionManifest, \"section\" | \"exportName\">): string {\n const base = manifest.exportName && IDENTIFIER_RE.test(manifest.exportName) ? manifest.exportName : pascalCase(manifest.section);\n return `${base}Props`;\n}\n\nexport interface GenerateOptions {\n /** Section slug, named in the header comment. */\n section: string;\n interfaceName: string;\n}\n\n/** The full text of `<name>.props.ts` for a definition schema. */\nexport function generatePropsSource(schema: unknown, options: GenerateOptions): string {\n const fields = collectFields(schema);\n const lines: string[] = [\n `// Generated by @botlr/cli from the Botlr section definition \"${options.section}\".`,\n \"// Do not edit: the props schema lives in the dashboard, and `botlr pull` rewrites this file.\",\n \"\",\n ];\n if (fields.length === 0) {\n lines.push(\"/** The definition has no props yet; define them in the dashboard and pull again. */\");\n lines.push(`export type ${options.interfaceName} = Record<string, unknown>;`);\n return `${lines.join(\"\\n\")}\\n`;\n }\n lines.push(`export interface ${options.interfaceName} {`);\n fields.forEach((field, index) => {\n if (index > 0 && field.doc.length) lines.push(\"\");\n if (field.doc.length === 1) lines.push(` /** ${field.doc[0]} */`);\n else if (field.doc.length > 1) lines.push(\" /**\", ...field.doc.map((d) => ` * ${d}`), \" */\");\n lines.push(` ${propertyKey(field.name)}${field.required ? \"\" : \"?\"}: ${field.type};`);\n });\n lines.push(\"}\");\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nexport function propsPath(sectionsDir: string, name: string): string {\n return path.join(sectionsDir, `${name}${PROPS_SUFFIX}`);\n}\n\nexport interface PropsTypesUpdate {\n file: string;\n interfaceName: string;\n /** False when the file already held the generated text. */\n changed: boolean;\n}\n\n/**\n * Write `<name>.props.ts` for a section, leaving the file alone when its\n * text is already what would be generated.\n */\nexport async function writePropsTypes(\n sectionsDir: string,\n manifest: SectionManifest,\n schema: unknown,\n): Promise<PropsTypesUpdate> {\n const interfaceName = propsInterfaceName(manifest);\n const file = propsPath(sectionsDir, manifest.section);\n const text = generatePropsSource(schema, { section: manifest.section, interfaceName });\n try {\n if ((await readFile(file, \"utf8\")) === text) return { file, interfaceName, changed: false };\n } catch {\n // missing: write it\n }\n await mkdir(sectionsDir, { recursive: true });\n await writeFile(file, text, \"utf8\");\n return { file, interfaceName, changed: true };\n}\n","import {\n BotlrConflictError,\n contentHash,\n type SectionSourcePushResponse,\n type SectionSourceScope,\n} from \"@botlr/sdk\";\nimport type { ResolvedConfig } from \"../config\";\nimport { clientFor } from \"../client\";\nimport { readLock, updateLock } from \"../lock\";\nimport { compareSchemas, type SchemaDrift } from \"../drift\";\nimport { ManifestError, readManifest, readSectionFiles } from \"../manifest\";\n\nexport interface PushOptions {\n name: string;\n message?: string;\n shared?: boolean;\n create?: boolean;\n /** Omit `baseVersion` so the server skips the conflict check. */\n force?: boolean;\n}\n\nexport interface PushResult {\n name: string;\n created: boolean;\n scope: SectionSourceScope;\n version: number;\n contentHash: string;\n /** Set when the manifest's `schema` and the definition's schema list different props. */\n drift?: SchemaDrift;\n}\n\nexport class PushConflict extends Error {\n constructor(\n message: string,\n public readonly latest: { version: number; contentHash: string } | null,\n ) {\n super(message);\n this.name = \"PushConflict\";\n }\n}\n\nexport async function pushSection(config: ResolvedConfig, options: PushOptions): Promise<PushResult> {\n const client = clientFor(config, { needPersonalToken: true });\n const { name } = options;\n const manifest = await readManifest(config.sectionsDir, name);\n if (manifest.section !== name) {\n throw new ManifestError(`${name}.botlr.json says section '${manifest.section}', expected '${name}'`);\n }\n if (manifest.framework && manifest.framework !== config.framework) {\n throw new ManifestError(\n `${name}.botlr.json is for framework '${manifest.framework}', the config says '${config.framework}'`,\n );\n }\n manifest.framework = config.framework;\n\n const files = await readSectionFiles(config.sectionsDir, manifest);\n const localHash = await contentHash(files);\n const targetScope: SectionSourceScope = options.shared ? \"shared\" : \"instance\";\n\n let baseVersion: number | undefined;\n if (!options.force) {\n const lock = (await readLock(config.root))[name];\n if (lock && lock.scope === targetScope) {\n baseVersion = lock.version;\n } else {\n // No lock for this scope: base on what the server has right now.\n const listing = await client.sections.list({ framework: config.framework });\n const summary = listing.sections.find((s) => s.name === name);\n const remote = summary ? (targetScope === \"shared\" ? summary.shared : summary.instance) : null;\n baseVersion = remote?.version ?? 0;\n if (remote && lock === undefined && remote.contentHash === localHash) {\n // Already on the server, nothing to push; let the server answer 200.\n }\n }\n }\n\n let response: SectionSourcePushResponse;\n try {\n response = await client.sections.push(name, {\n framework: config.framework,\n manifest,\n files,\n shared: options.shared ?? false,\n baseVersion,\n message: options.message,\n create: options.create ?? false,\n });\n } catch (error) {\n if (error instanceof BotlrConflictError) {\n throw new PushConflict(error.message, error.latest);\n }\n throw error;\n }\n\n await updateLock(config.root, name, {\n scope: response.scope,\n framework: config.framework,\n version: response.version,\n contentHash: response.contentHash,\n pulledAt: new Date().toISOString(),\n });\n\n const drift = compareSchemas(manifest, response.definition?.schema) ?? undefined;\n\n return {\n name,\n created: response.created,\n scope: response.scope,\n version: response.version,\n contentHash: response.contentHash,\n drift,\n };\n}\n","/**\n * Schema drift: the props a section's code expects (the manifest's optional\n * `schema`, field DSL only) against the props the dashboard defines (the\n * section definition's schema from the server). The CLI only reports the\n * difference; the dashboard owns the definition's schema.\n */\nimport { schemaFormat, type SectionManifest, type SectionSchema } from \"@botlr/sdk\";\nimport { schemaFieldNames } from \"./typegen\";\n\nexport interface SchemaDrift {\n /** Props the code lists that the dashboard does not define. */\n missingInDashboard: string[];\n /** Props the dashboard defines that the code does not list. */\n missingInCode: string[];\n}\n\n/** The manifest's `schema` when it is a schema object in either format, else null. */\nexport function manifestSchema(manifest: SectionManifest): SectionSchema | null {\n const schema = manifest.schema;\n return schemaFormat(schema) ? (schema as SectionSchema) : null;\n}\n\n/**\n * Key difference between the code's schema and the definition's schema\n * (either format on either side; FormBuilder schemas contribute their node\n * names). Null when the manifest has no schema object or the keys match.\n */\nexport function compareSchemas(manifest: SectionManifest, definitionSchema: unknown): SchemaDrift | null {\n const code = manifestSchema(manifest);\n if (!code) return null;\n const codeKeys = new Set(schemaFieldNames(code));\n const dashboardKeys = new Set(schemaFieldNames(definitionSchema));\n const missingInDashboard = [...codeKeys].filter((k) => !dashboardKeys.has(k)).sort();\n const missingInCode = [...dashboardKeys].filter((k) => !codeKeys.has(k)).sort();\n if (missingInDashboard.length === 0 && missingInCode.length === 0) return null;\n return { missingInDashboard, missingInCode };\n}\n\n/** The warning text for a drift, one line per direction, naming the two commands that resolve it. */\nexport function formatDriftWarning(name: string, drift: SchemaDrift): string {\n const lines = [`warning: props schema of '${name}' differs between the code and the dashboard`];\n if (drift.missingInDashboard.length) {\n lines.push(` the code expects props the dashboard does not define: ${drift.missingInDashboard.join(\", \")}`);\n }\n if (drift.missingInCode.length) {\n lines.push(` the dashboard defines props the code does not list: ${drift.missingInCode.join(\", \")}`);\n }\n lines.push(` the dashboard owns the schema; a code push never changes it. To resolve:`);\n lines.push(` botlr schema pull ${name} takes the dashboard's schema into ${name}.botlr.json`);\n lines.push(` botlr schema push ${name} sends the code's schema to the dashboard`);\n return lines.join(\"\\n\");\n}\n","import { contentHash, type SectionManifest, type SectionSourceSummary } from \"@botlr/sdk\";\nimport type { ResolvedConfig } from \"../config\";\nimport { clientFor } from \"../client\";\nimport { compareSchemas, manifestSchema, type SchemaDrift } from \"../drift\";\nimport { readLock, type LockEntry } from \"../lock\";\nimport { listManifests, readManifest, readSectionFiles } from \"../manifest\";\nimport { computeStatus, remoteForLock, type SectionStatus } from \"../status\";\n\nexport interface SectionStatusRow {\n name: string;\n status: SectionStatus | \"error\";\n local: number | null;\n remote: number | null;\n scope: string;\n detail?: string;\n /** Set when the manifest's `schema` and the dashboard's definition list different props (not offline). */\n drift?: SchemaDrift;\n}\n\nexport async function sectionStatuses(\n config: ResolvedConfig,\n options: { names?: string[]; offline?: boolean } = {},\n): Promise<SectionStatusRow[]> {\n const names = options.names?.length ? options.names : await listManifests(config.sectionsDir);\n const lock = await readLock(config.root);\n\n let summaries = new Map<string, SectionSourceSummary>();\n const client = options.offline ? null : clientFor(config);\n if (client) {\n const listing = await client.sections.list({ framework: config.framework });\n summaries = new Map(listing.sections.map((s) => [s.name, s]));\n }\n\n // The listing carries no schema; fetch the definition only for manifests that have a schema to compare.\n const driftFor = async (manifest: SectionManifest): Promise<SchemaDrift | undefined> => {\n if (!client || !manifestSchema(manifest) || !summaries.has(manifest.section)) return undefined;\n try {\n const pulled = await client.sections.pull(manifest.section, { framework: config.framework });\n return compareSchemas(manifest, pulled.definition?.schema) ?? undefined;\n } catch {\n return undefined;\n }\n };\n\n const rows: SectionStatusRow[] = [];\n for (const name of names) {\n const entry: LockEntry | undefined = lock[name];\n const summary = summaries.get(name);\n const remote = remoteForLock(summary, entry);\n try {\n const manifest = await readManifest(config.sectionsDir, name);\n const localHash = await contentHash(await readSectionFiles(config.sectionsDir, manifest));\n rows.push({\n name,\n status: computeStatus({ localHash, lock: entry, remote }),\n local: entry?.version ?? null,\n remote: remote?.version ?? null,\n scope: entry?.scope ?? summary?.effective ?? \"-\",\n drift: await driftFor(manifest),\n });\n } catch (error) {\n rows.push({\n name,\n status: \"error\",\n local: entry?.version ?? null,\n remote: remote?.version ?? null,\n scope: entry?.scope ?? \"-\",\n detail: (error as Error).message,\n });\n }\n }\n return rows;\n}\n","import type { SectionSourceScopeSummary, SectionSourceSummary } from \"@botlr/sdk\";\nimport type { LockEntry } from \"./lock\";\n\n/**\n * - `clean`: local files equal the lock, and the lock is the server's latest\n * - `modified`: local files changed since the pull, server unchanged\n * - `behind`: local files equal the lock, but the server has a newer version\n * - `diverged`: both changed\n * - `untracked`: a manifest with no lock entry (never pulled or pushed from here)\n */\nexport type SectionStatus = \"clean\" | \"modified\" | \"behind\" | \"diverged\" | \"untracked\";\n\nexport interface StatusInput {\n /** Content hash of the local files listed in the manifest. */\n localHash: string;\n lock: LockEntry | undefined;\n /** Latest version on the server for the lock's scope; null when the server has none. */\n remote: SectionSourceScopeSummary | null | undefined;\n}\n\nexport function computeStatus({ localHash, lock, remote }: StatusInput): SectionStatus {\n if (!lock) return \"untracked\";\n const localChanged = localHash !== lock.contentHash;\n const remoteChanged = remote != null && remote.contentHash !== lock.contentHash;\n if (localChanged && remoteChanged) return \"diverged\";\n if (localChanged) return \"modified\";\n if (remoteChanged) return \"behind\";\n return \"clean\";\n}\n\n/** The server summary that corresponds to a lock entry's scope. */\nexport function remoteForLock(\n summary: SectionSourceSummary | undefined,\n lock: LockEntry | undefined,\n): SectionSourceScopeSummary | null | undefined {\n if (!summary) return undefined;\n if (!lock) return summary.effective === \"shared\" ? summary.shared : summary.instance;\n return lock.scope === \"shared\" ? summary.shared : summary.instance;\n}\n","import type { ResolvedConfig } from \"../config\";\nimport { deriveManifests, hasRegistry, readNpmVersions } from \"../init\";\nimport { listManifests, writeManifest } from \"../manifest\";\n\nexport interface InitOptions {\n /** Overwrite manifests that already exist. */\n force?: boolean;\n /** Only derive, write nothing. */\n dryRun?: boolean;\n}\n\nexport interface InitResult {\n name: string;\n file: string;\n entry: string;\n written: boolean;\n}\n\n/**\n * Derive `<slug>.botlr.json` for every component the registry maps. The\n * manifests are a starting point: review them, then `botlr push <name>`\n * (with `--create` for sections the dashboard does not know yet).\n */\nexport async function initSections(config: ResolvedConfig, options: InitOptions = {}): Promise<InitResult[]> {\n if (!(await hasRegistry(config.sectionsDir, config.registryFile))) {\n throw new Error(`No ${config.registryFile}; sections init reads the registry map to find components`);\n }\n const existing = new Set(await listManifests(config.sectionsDir));\n const npmVersions = await readNpmVersions(config.sectionsDir);\n const derived = await deriveManifests(config.sectionsDir, {\n framework: config.framework,\n npmVersions,\n registryFile: config.registryFile,\n });\n\n const results: InitResult[] = [];\n for (const { name, manifest, entryFile } of derived) {\n const skip = existing.has(name) && !options.force;\n let file = `${name}.botlr.json`;\n if (!skip && !options.dryRun) {\n file = await writeManifest(config.sectionsDir, name, manifest);\n }\n results.push({ name, file, entry: entryFile, written: !skip && !options.dryRun });\n }\n return results;\n}\n","/**\n * `botlr schema pull` and `botlr schema push`: the explicit way to resolve\n * drift between the manifest's `schema` (what the code expects) and the\n * dashboard's definition schema. A source push never touches the schema;\n * these two commands do, in the direction the user picks.\n */\nimport {\n BotlrError,\n BotlrSchemaFormatConflictError,\n botlrErrorMessage,\n type SectionSchema,\n type SectionSchemaPushMode,\n} from \"@botlr/sdk\";\nimport type { ResolvedConfig } from \"../config\";\nimport { clientFor } from \"../client\";\nimport { listManifests, ManifestError, readManifest, writeManifestIfChanged } from \"../manifest\";\nimport { previewSchemaPush, type SchemaPushPreview } from \"../schema-diff\";\nimport { writePropsTypes, type PropsTypesUpdate } from \"../typegen\";\n\nexport interface SchemaPullOptions {\n /** Section names; empty with `all: true` means every manifest in the sections directory. */\n names: string[];\n all?: boolean;\n /** Do not write `<name>.props.ts`; also off when the config says `types: false`. */\n noTypes?: boolean;\n}\n\nexport interface SchemaPullResult {\n name: string;\n /** Whether `<name>.botlr.json` changed; false when its `schema` already equalled the dashboard's. */\n changed: boolean;\n /** The manifest file. */\n file: string;\n format?: string;\n /** What happened to `<name>.props.ts`; absent when types are off or the pull failed. */\n types?: PropsTypesUpdate;\n /** Why nothing was written: no manifest, or no section type of that name in the app. */\n error?: string;\n}\n\nfunction isNotFound(error: unknown): boolean {\n return error instanceof BotlrError && error.status === 404;\n}\n\n/** Copy the dashboard's schema into each manifest's `schema`, then regenerate the prop types. */\nexport async function pullSchemas(config: ResolvedConfig, options: SchemaPullOptions): Promise<SchemaPullResult[]> {\n const client = clientFor(config);\n const names = options.all ? await listManifests(config.sectionsDir) : options.names;\n const results: SchemaPullResult[] = [];\n\n for (const name of names) {\n let manifest;\n try {\n manifest = await readManifest(config.sectionsDir, name);\n } catch (error) {\n results.push({ name, changed: false, file: \"\", error: (error as Error).message });\n continue;\n }\n let definition;\n try {\n definition = (await client.sections.getSchema(name)).definition;\n } catch (error) {\n if (!isNotFound(error)) throw error;\n results.push({ name, changed: false, file: \"\", error: `the app has no section type '${name}' (botlr push ${name} --create adds one)` });\n continue;\n }\n\n const updated = { ...manifest, schema: definition.schema as SectionSchema };\n const written = await writeManifestIfChanged(config.sectionsDir, name, updated);\n const types =\n config.types && !options.noTypes ? await writePropsTypes(config.sectionsDir, manifest, definition.schema) : undefined;\n results.push({ name, changed: written.changed, file: written.file, format: definition.format, types });\n }\n return results;\n}\n\nexport interface SchemaPushOptions {\n name: string;\n /** Replace the schema outright whatever the formats, instead of merging into a FormBuilder schema. */\n force?: boolean;\n /**\n * Asked once with the preview before anything is sent; return false to\n * stop. Omit to push without asking (`--yes`).\n */\n confirm?: (preview: SchemaPushPreview) => Promise<boolean> | boolean;\n /** Do not write `<name>.props.ts` afterwards; also off when the config says `types: false`. */\n noTypes?: boolean;\n}\n\nexport interface SchemaPushResult {\n name: string;\n preview: SchemaPushPreview;\n /** False when `confirm` said no; nothing was sent. */\n pushed: boolean;\n /** From the server: false when nothing had to change. */\n changed?: boolean;\n previousFormat?: string;\n format?: string;\n /** What the server did: replaced the schema, or merged the code's fields into a FormBuilder schema. */\n mode?: SectionSchemaPushMode;\n /** Field names that became new nodes (`merged`). */\n added?: string[];\n /** Node names only the dashboard defines, kept (`merged`). */\n dashboardOnly?: string[];\n types?: PropsTypesUpdate;\n}\n\n/**\n * A FormBuilder schema pushed at a field-DSL definition without `--force`:\n * raised before anything is sent when the formats are known (then `preview`\n * is set), or from the server's 409.\n */\nexport class SchemaFormatConflict extends Error {\n constructor(\n public readonly sectionName: string,\n public readonly currentFormat: string,\n public readonly newFormat: string,\n message?: string,\n public readonly preview?: SchemaPushPreview,\n ) {\n super(message ?? `the schema of '${sectionName}' is stored as ${currentFormat}, the manifest's is ${newFormat}`);\n this.name = \"SchemaFormatConflict\";\n }\n}\n\n/** 422: the server refused the schema (not an object of fields, or the definition is not project-scoped). */\nexport class SchemaRejected extends Error {\n constructor(public readonly sectionName: string, message: string) {\n super(message);\n this.name = \"SchemaRejected\";\n }\n}\n\n/** Send the manifest's `schema` to the dashboard, after showing the diff and asking. */\nexport async function pushSchema(config: ResolvedConfig, options: SchemaPushOptions): Promise<SchemaPushResult> {\n const client = clientFor(config, { needPersonalToken: true });\n const { name } = options;\n const manifest = await readManifest(config.sectionsDir, name);\n const next = manifest.schema;\n if (!next || typeof next !== \"object\" || Array.isArray(next)) {\n throw new ManifestError(\n `${name}.botlr.json has no 'schema' object to push; add one, or run 'botlr schema pull ${name}' to take the dashboard's`,\n );\n }\n\n let current;\n try {\n current = (await client.sections.getSchema(name)).definition;\n } catch (error) {\n if (!isNotFound(error)) throw error;\n throw new ManifestError(`the app has no section type '${name}'; push the code first with 'botlr push ${name} --create'`);\n }\n\n const force = options.force ?? false;\n const preview = previewSchemaPush(name, current.schema, next, { currentFormat: current.format, force });\n if (preview.expected === \"conflict\") {\n // The server would answer 409; stop before asking.\n throw new SchemaFormatConflict(name, preview.currentFormat!, preview.nextFormat!, undefined, preview);\n }\n if (options.confirm && !(await options.confirm(preview))) {\n return { name, preview, pushed: false };\n }\n\n let response;\n try {\n response = await client.sections.putSchema(name, { schema: next, force });\n } catch (error) {\n if (error instanceof BotlrSchemaFormatConflictError) {\n throw new SchemaFormatConflict(name, error.currentFormat, error.newFormat, botlrErrorMessage(error));\n }\n if (error instanceof BotlrError && error.status === 422) {\n throw new SchemaRejected(name, botlrErrorMessage(error) ?? \"the server rejected the schema (422)\");\n }\n throw error;\n }\n\n const types =\n config.types && !options.noTypes\n ? await writePropsTypes(config.sectionsDir, manifest, response.definition.schema)\n : undefined;\n\n return {\n name,\n preview,\n pushed: true,\n changed: response.changed,\n previousFormat: response.previousFormat,\n format: response.definition.format,\n mode: response.mode,\n added: response.added,\n dashboardOnly: response.dashboardOnly,\n types,\n };\n}\n","/**\n * Field-key diff between two props schemas, for `botlr schema push` to show\n * before it replaces the dashboard's schema with the code's. Field DSL keys\n * are the object's keys; FormBuilder schemas contribute their node names\n * (groups flattened), so the two formats can be compared with each other.\n */\nimport { schemaFormat, type SectionSchemaFormat } from \"@botlr/sdk\";\nimport { schemaFieldNames } from \"./typegen\";\n\nexport interface SchemaKeyDiff {\n /** Keys the new schema has that the current one lacks. */\n added: string[];\n /** Keys the current schema has that the new one lacks. */\n removed: string[];\n /** Keys both have. */\n kept: string[];\n}\n\n/** The field keys of a schema in either format, in schema order and without duplicates. */\nexport function schemaKeys(schema: unknown): string[] {\n return [...new Set(schemaFieldNames(schema))];\n}\n\n/** Keys added, removed and kept going from `current` to `next`; each list sorted. */\nexport function diffSchemaKeys(current: unknown, next: unknown): SchemaKeyDiff {\n const currentKeys = new Set(schemaKeys(current));\n const nextKeys = new Set(schemaKeys(next));\n return {\n added: [...nextKeys].filter((k) => !currentKeys.has(k)).sort(),\n removed: [...currentKeys].filter((k) => !nextKeys.has(k)).sort(),\n kept: [...nextKeys].filter((k) => currentKeys.has(k)).sort(),\n };\n}\n\nexport interface SchemaPushPreview {\n name: string;\n /** The dashboard's current schema. */\n current: unknown;\n /** Its format as the server reports it, else as detected. */\n currentFormat: SectionSchemaFormat | null;\n /** The manifest's schema, about to replace it. */\n next: unknown;\n nextFormat: SectionSchemaFormat | null;\n diff: SchemaKeyDiff;\n /** Whether `--force` was given. */\n force: boolean;\n /** What the server is expected to do with this push. */\n expected: ExpectedPushMode;\n}\n\n/**\n * - `replaced`: same format, or `--force`\n * - `merged`: field-DSL fields at a FormBuilder schema; the server adds nodes and keeps the rest\n * - `conflict`: a FormBuilder schema at a field-DSL one; the server answers 409 without `--force`\n */\nexport type ExpectedPushMode = \"replaced\" | \"merged\" | \"conflict\";\n\n/** True when both formats are known and differ. */\nexport function formatsDiffer(preview: Pick<SchemaPushPreview, \"currentFormat\" | \"nextFormat\">): boolean {\n return !!preview.currentFormat && !!preview.nextFormat && preview.currentFormat !== preview.nextFormat;\n}\n\nexport function expectedPushMode(preview: Pick<SchemaPushPreview, \"currentFormat\" | \"nextFormat\" | \"force\">): ExpectedPushMode {\n if (preview.force || !formatsDiffer(preview)) return \"replaced\";\n return preview.currentFormat === \"form-builder\" && preview.nextFormat === \"field-dsl\" ? \"merged\" : \"conflict\";\n}\n\n/** The preview for a push, with formats detected from the schemas unless given. */\nexport function previewSchemaPush(\n name: string,\n current: unknown,\n next: unknown,\n options: { currentFormat?: SectionSchemaFormat | null; nextFormat?: SectionSchemaFormat | null; force?: boolean } = {},\n): SchemaPushPreview {\n const formats = {\n currentFormat: options.currentFormat ?? schemaFormat(current),\n nextFormat: options.nextFormat ?? schemaFormat(next),\n force: options.force ?? false,\n };\n return { name, current, next, diff: diffSchemaKeys(current, next), ...formats, expected: expectedPushMode(formats) };\n}\n\nfunction plural(n: number, word: string): string {\n return `${n} ${word}${n === 1 ? \"\" : \"s\"}`;\n}\n\nfunction formatName(format: SectionSchemaFormat | null): string {\n return format ?? \"unknown\";\n}\n\n/**\n * The diff as the CLI prints it: one header line with both formats and\n * field counts (and, for a merge, what the server will do), then one line\n * per non-empty direction. The `kept` line is always printed, with \"none\"\n * when nothing survives. In a merge the dashboard's extra nodes are kept,\n * so that line says so instead of \"removed\".\n */\nexport function formatSchemaDiff(preview: SchemaPushPreview): string {\n const { diff, expected } = preview;\n let header =\n `schema of '${preview.name}': dashboard has ${formatName(preview.currentFormat)} ` +\n `(${plural(schemaKeys(preview.current).length, \"field\")}), ` +\n `code has ${formatName(preview.nextFormat)} (${plural(schemaKeys(preview.next).length, \"field\")})`;\n if (expected === \"merged\") {\n header += \": the server will add the missing fields as FormBuilder nodes and keep the dashboard's (format kept; --force would replace it)\";\n }\n const lines = [header];\n if (diff.added.length) lines.push(` + added ${diff.added.join(\", \")}`);\n if (diff.removed.length) {\n lines.push(expected === \"merged\" ? ` ~ dashboard only, kept ${diff.removed.join(\", \")}` : ` - removed ${diff.removed.join(\", \")}`);\n }\n lines.push(` = kept ${diff.kept.length ? diff.kept.join(\", \") : \"none\"}`);\n if (formatsDiffer(preview) && expected !== \"merged\") {\n lines.push(\n preview.force\n ? ` the formats differ: replacing ${preview.currentFormat} with ${preview.nextFormat} (--force)`\n : ` the formats differ: the push needs --force to replace ${preview.currentFormat} with ${preview.nextFormat}`,\n );\n }\n if (!diff.added.length && !diff.removed.length) lines.push(\" the field keys match; only field settings may change\");\n return lines.join(\"\\n\");\n}\n","/** Minimal table printing without a dependency. */\nexport function table(rows: string[][], header?: string[]): string {\n const all = header ? [header, ...rows] : rows;\n if (all.length === 0) return \"\";\n const widths = all[0]!.map((_, col) => Math.max(...all.map((row) => (row[col] ?? \"\").length)));\n const line = (row: string[]) => row.map((cell, i) => cell.padEnd(widths[i]!)).join(\" \").trimEnd();\n const out = all.map(line);\n if (header) out.splice(1, 0, widths.map((w) => \"-\".repeat(w)).join(\" \"));\n return out.join(\"\\n\");\n}\n\nexport function fail(message: string): never {\n process.stderr.write(`botlr: ${message}\\n`);\n process.exit(1);\n}\n"],"mappings":"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","names":["path","overrides","readFile","path","mkdir","readFile","writeFile","path","readFile","writeFile","path","readFile","readdir","path","schema","path","readFile","readdir","SOURCE_EXTENSIONS","path","readFile","writeFile","mkdir","readFile","writeFile","path","schema","contentHash","schema","localHash","contentHash","contentHash","localHash","localHash","contentHash","schemaFormat","schema","schemaFormat","require","path"]}