@rness/cli 0.22.1 → 0.22.2

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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/fs.ts","../src/core/frontmatter.ts","../src/core/collect.ts","../src/core/scope.ts","../src/core/context.ts","../src/core/contract.ts","../src/core/documents.ts","../src/core/contained.ts","../src/presets/agent-pulse.1.json","../src/presets/collection.1.json","../src/core/presets.ts","../src/core/board-declaration.ts","../src/core/git.ts","../src/core/remote.ts","../src/core/manifest.ts","../src/version.ts","../src/core/pm.ts","../src/core/status.ts","../src/board/urls.ts","../src/core/github.ts","../src/core/github-projects.ts","../src/core/github-issues.ts","../src/core/github-journal.ts","../src/core/auth.ts","../src/core/device-flow.ts","../src/board/body.ts","../src/board/collection.ts","../src/board/layout.ts","../src/board/plan.ts","../src/core/github-board.ts","../src/core/github-oauth-provider.ts","../src/core/repos.ts","../src/core/terminal.ts","../src/core/workspace.ts","../src/core/style.ts","../src/report.ts","../src/commands/login.ts","../src/core/browser.ts","../src/core/providers.ts","../src/core/setup-git.ts","../src/core/progress.ts","../src/core/ui.ts","../src/board/journal-state.ts","../src/commands/board.ts","../src/board/detached.ts","../src/board/noted.ts","../src/board/opened.ts","../src/core/board-migration.ts","../src/core/board-merge.ts","../src/core/preset-board.ts"],"sourcesContent":["import {\n access,\n lstat,\n readFile,\n rename,\n rm,\n writeFile,\n} from 'node:fs/promises'\nimport { basename, dirname, join } from 'node:path'\n\nexport async function exists(p: string): Promise<boolean> {\n try {\n await access(p)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * True when `p` is itself a symbolic link (the link is not followed). False\n * when it does not exist. Callers use it to leave a `CLAUDE.md → AGENTS.md`\n * link alone: reading follows the link and the atomic rename would replace it.\n */\nexport async function isSymlink(p: string): Promise<boolean> {\n try {\n return (await lstat(p)).isSymbolicLink()\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') return false\n throw e\n }\n}\n\n/** File content, or null when the file does not exist; any other error propagates. */\nexport async function readOrNull(p: string): Promise<string | null> {\n try {\n return await readFile(p, 'utf8')\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') return null\n throw e\n }\n}\n\nlet sequence = 0\n\n/** Write to a temporary file in the same directory, then rename over the target. */\nexport async function writeFileAtomic(p: string, text: string): Promise<void> {\n sequence += 1\n const tmp = join(dirname(p), `.${basename(p)}.${process.pid}.${sequence}.tmp`)\n await writeFile(tmp, text, 'utf8')\n try {\n await rename(tmp, p)\n } catch (e) {\n await rm(tmp, { force: true }).catch(() => undefined)\n throw e\n }\n}\n","import { parse } from 'yaml'\n\nimport type { Fields } from './types.ts'\n\n// The inner group is optional so that `---\\n---\\n` (an empty block with no line\n// between the fences) is still recognised as front matter.\nconst FRONT_MATTER = /^---\\r?\\n(?:([\\s\\S]*?)\\r?\\n)?---(?:\\r?\\n|$)/\n\nfunction fail(message: string): never {\n throw new Error(`front matter: ${message}`)\n}\n\n/** Strip a leading UTF-8 BOM so `---` is still recognised as the first thing in the file. */\nfunction stripBom(source: string): string {\n return source.startsWith('') ? source.slice(1) : source\n}\n\n/**\n * Parse the leading `---` block as YAML (1.2 core schema: `2026-09-07` stays a\n * string, `1` becomes a number). Returns null when there is no block, `{}`\n * for an empty block, and throws a `front matter:`-prefixed error when the\n * YAML is invalid or is not a mapping.\n */\nexport function parseFrontMatter(source: string): Fields | null {\n const match = stripBom(source).match(FRONT_MATTER)\n if (match === null) return null\n const block = match[1] ?? ''\n if (block.trim() === '') return {}\n let doc: unknown\n try {\n // 'error': suppress the printed YAMLWarning (e.g. an unresolved `!!tag`)\n // without silencing real parse errors — `logLevel: 'silent'` would do that too.\n doc = parse(block, { logLevel: 'error' })\n } catch (e) {\n fail(\n e instanceof Error\n ? (e.message.split('\\n')[0] ?? 'invalid YAML').replace(/:$/, '')\n : 'invalid YAML'\n )\n }\n if (doc === null || doc === undefined) return {}\n if (typeof doc !== 'object' || Array.isArray(doc))\n fail('block must be a mapping of keys to values')\n return doc as Fields\n}\n\n/**\n * The document text with its leading `---` block removed, along with the blank\n * lines that separated it from the body. Purely textual: a block whose YAML is\n * invalid is still stripped, so a broken file never leaks `---` fences into a\n * rendered block. Returns the (BOM-stripped) source unchanged when there is no\n * front matter.\n */\nexport function stripFrontMatter(source: string): string {\n const text = stripBom(source)\n const match = text.match(FRONT_MATTER)\n if (match === null) return text\n return text.slice(match[0].length).replace(/^(?:[ \\t]*\\r?\\n)+/, '')\n}\n\nexport function extractTitle(source: string): string | null {\n return (\n stripBom(source)\n .match(/^# (.+)$/m)?.[1]\n ?.trim() ?? null\n )\n}\n","import { glob, readFile } from 'node:fs/promises'\nimport { join, posix, sep } from 'node:path'\n\nimport {\n extractTitle,\n parseFrontMatter,\n stripFrontMatter,\n} from './frontmatter.ts'\nimport type { MarkdownItem } from './types.ts'\n\nfunction toPosix(rel: string): string {\n return rel.split(sep).join(posix.sep)\n}\n\n/**\n * One Markdown file as the collections read it. A front matter that fails\n * to parse leaves `fields: null` and the error in `fieldsError`.\n */\nexport function markdownItem(\n path: string,\n rel: string,\n body: string\n): MarkdownItem {\n let fields: MarkdownItem['fields'] = null\n let fieldsError: string | null = null\n try {\n fields = parseFrontMatter(body)\n } catch (e) {\n fieldsError = e instanceof Error ? e.message : String(e)\n }\n return {\n path,\n rel,\n fields,\n fieldsError,\n title: extractTitle(body),\n body,\n content: stripFrontMatter(body),\n }\n}\n\n/**\n * Every `*.md` under `dir`, recursively, sorted by `rel`. A missing directory\n * yields []. A file whose front matter fails to parse is kept with\n * `fields: null` and the error in `fieldsError`, so one broken file cannot\n * hide a whole collection.\n */\nexport async function collectMarkdown(dir: string): Promise<MarkdownItem[]> {\n const rels: string[] = []\n for await (const rel of glob('**/*.md', { cwd: dir })) rels.push(toPosix(rel))\n const items = await Promise.all(\n rels.map(async (rel) => {\n const path = join(dir, ...rel.split(posix.sep))\n return markdownItem(path, rel, await readFile(path, 'utf8'))\n })\n )\n return items.sort((a, b) => (a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0))\n}\n","import type { Manifest } from './types.ts'\n\nfunction isPrefix(prefix: string, target: string): boolean {\n return prefix === target || target.startsWith(`${prefix}/`)\n}\n\n/** The scope whose `path` is the longest path-segment prefix of `relDir`; null = global. */\nexport function resolveScope(\n manifest: Manifest,\n relDir: string\n): string | null {\n let best: string | null = null\n let bestLen = -1\n for (const [name, entry] of Object.entries(manifest.scopes)) {\n if (isPrefix(entry.path, relDir) && entry.path.length > bestLen) {\n best = name\n bestLen = entry.path.length\n }\n }\n return best\n}\n\n/** `scope` then its transitive `extends`, nearest first, de-duplicated. Throws on a cycle. */\nexport function scopeChain(manifest: Manifest, scope: string | null): string[] {\n if (scope === null) return []\n const chain: string[] = []\n const seen = new Set<string>()\n const visit = (name: string, stack: Set<string>): void => {\n if (stack.has(name)) throw new Error(`extends cycle at scope \"${name}\"`)\n if (seen.has(name)) return\n seen.add(name)\n chain.push(name)\n stack.add(name)\n const entry = Object.hasOwn(manifest.scopes, name)\n ? manifest.scopes[name]\n : undefined\n for (const target of entry?.extends ?? []) visit(target, stack)\n stack.delete(name)\n }\n visit(scope, new Set())\n return chain\n}\n","import { join } from 'node:path'\n\nimport { collectMarkdown } from './collect.ts'\nimport { scopeChain } from './scope.ts'\nimport type {\n CollectionName,\n Context,\n ContextCollection,\n ContextFile,\n Manifest,\n MarkdownItem,\n} from './types.ts'\n\nexport const COLLECTIONS: readonly CollectionName[] = [\n 'standards',\n 'adr',\n 'specs',\n 'plans',\n 'skills',\n]\n\n/** The first path segment of `rel`, or null for a file at the collection root. */\nexport function ownerScope(rel: string): string | null {\n const slash = rel.indexOf('/')\n return slash === -1 ? null : rel.slice(0, slash)\n}\n\ntype Owned = MarkdownItem & { scope: string | null }\n\n/**\n * The file's place defines its scope (spec 0003 §4.0): collection-root files\n * are global, `<scope>/**` files belong to that scope. A file under a\n * directory outside the chain is ignored; front matter never re-routes.\n */\nasync function assembleCollection(\n dir: string,\n name: CollectionName,\n chain: string[]\n): Promise<ContextCollection> {\n const items = await collectMarkdown(dir)\n const groups = new Map<string, Owned[]>(chain.map((s) => [s, []]))\n const rootFiles: Owned[] = []\n for (const item of items) {\n const owner = ownerScope(item.rel)\n if (owner === null) rootFiles.push({ ...item, scope: null })\n else groups.get(owner)?.push({ ...item, scope: owner })\n }\n const files: ContextFile[] = []\n const push = (f: Owned): void => {\n files.push({\n rel: f.rel,\n scope: f.scope,\n title: f.title,\n body: f.body,\n content: f.content,\n })\n }\n for (const s of chain) for (const f of groups.get(s) ?? []) push(f)\n for (const f of rootFiles) push(f)\n return { name, files }\n}\n\nexport interface AssembleInput {\n rnessDir: string\n manifest: Manifest\n scope: string | null\n}\n\n/** Resolve every scoped collection for `scope` (null = global only). */\nexport async function assembleContext({\n rnessDir,\n manifest,\n scope,\n}: AssembleInput): Promise<Context> {\n const chain = scopeChain(manifest, scope)\n const collections = await Promise.all(\n COLLECTIONS.map((name) =>\n assembleCollection(join(rnessDir, name), name, chain)\n )\n )\n return { scope, collections }\n}\n","import { join } from 'node:path'\n\nimport { collectMarkdown, markdownItem } from './collect.ts'\nimport { COLLECTIONS } from './context.ts'\nimport { documentNumber } from './documents.ts'\nimport type { CollectionName } from './types.ts'\n\n/** Collections whose files must carry front matter with a `status`. */\nexport const STATUSES: Partial<Record<CollectionName, readonly string[]>> = {\n adr: ['Proposed', 'Accepted', 'Rejected', 'Superseded'],\n specs: [\n 'Draft',\n 'Proposed',\n 'Approved',\n 'Implemented',\n 'Superseded',\n 'Rejected',\n ],\n plans: ['Draft', 'Ready', 'In progress', 'Blocked', 'Completed', 'Abandoned'],\n}\nconst SKIP = new Set(['adr/0000-template.md'])\n/** Front-matter keys from the withdrawn routing feature — the directory decides. */\nconst PLACEMENT_KEYS = ['scopes', 'scope'] as const\n\n/**\n * One file of `.rness/` read from a text rather than the disk: what an edit\n * would leave, checked before it is written (spec 0029 §4.3).\n */\nexport interface ContractOverride {\n /** `.rness/`-relative, POSIX: `specs/0001-a.md`. */\n rel: string\n text: string\n}\n\n/** The collection's files, with the override in place of (or beside) its file. */\nasync function itemsOf(\n rnessDir: string,\n name: CollectionName,\n override: ContractOverride | undefined\n) {\n const items = await collectMarkdown(join(rnessDir, name))\n const prefix = `${name}/`\n if (override === undefined || !override.rel.startsWith(prefix)) return items\n const rel = override.rel.slice(prefix.length)\n const item = markdownItem(\n join(rnessDir, ...override.rel.split('/')),\n rel,\n override.text\n )\n return [...items.filter((i) => i.rel !== rel), item].sort((a, b) =>\n a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0\n )\n}\n\n/**\n * Human-readable problems across every collection; empty when the tree is\n * valid. With an override, that one file is read from its text.\n */\nexport async function checkContract(\n rnessDir: string,\n override?: ContractOverride\n): Promise<string[]> {\n const problems: string[] = []\n for (const name of COLLECTIONS) {\n const allowed = STATUSES[name]\n const items = await itemsOf(rnessDir, name, override)\n // One number, one document (spec 0028 §9): the clash a merge of two\n // branches that each made the next document can still produce.\n const byNumber = new Map<string, string[]>()\n for (const item of items) {\n const where = `${name}/${item.rel}`\n if (SKIP.has(where)) continue\n const number = allowed === undefined ? null : documentNumber(item.rel)\n if (number !== null)\n byNumber.set(number, [...(byNumber.get(number) ?? []), where])\n }\n for (const [number, files] of byNumber) {\n if (files.length < 2) continue\n for (const where of files)\n problems.push(\n `${where}: the number ${number} is also that of ${files\n .filter((f) => f !== where)\n .join(', ')}`\n )\n }\n // `rness doc new` numbers every document of these collections; a file\n // written another way (a dated name, a bare slug) gets the next number.\n const next = String(\n Math.max(0, ...[...byNumber.keys()].map(Number)) + 1\n ).padStart(4, '0')\n for (const item of items) {\n const where = `${name}/${item.rel}`\n if (SKIP.has(where)) continue\n if (allowed !== undefined && documentNumber(item.rel) === null)\n problems.push(\n `${where}: not numbered; name it ${next}-<slug>.md, the next number of ${name}`\n )\n if (item.fieldsError !== null) {\n problems.push(`${where}: invalid front matter (${item.fieldsError})`)\n continue\n }\n if (item.fields !== null) {\n for (const key of PLACEMENT_KEYS) {\n if (Object.hasOwn(item.fields, key)) {\n problems.push(\n `${where}: front matter \"${key}\" is not supported: the directory decides the scope; move the file`\n )\n }\n }\n }\n if (allowed === undefined) continue\n if (item.fields === null) {\n problems.push(`${where}: missing a front-matter block`)\n continue\n }\n if (item.title === null) problems.push(`${where}: missing a \"# \" title`)\n const status = item.fields['status']\n if (status === undefined || status === null || status === '') {\n problems.push(`${where}: missing \"status\"`)\n } else if (typeof status !== 'string' || !allowed.includes(status)) {\n problems.push(\n `${where}: unknown status ${JSON.stringify(status)} (expected ${allowed.join(', ')})`\n )\n }\n }\n }\n return problems\n}\n","import { posix } from 'node:path'\n\n/**\n * The date of a dated file name (`2026-10-02-slug.md`), the naming of other\n * agents' plan skills. A plausible date only: `0039-10-02-review.md` is\n * document 0039 with a title that starts with digits.\n */\nexport function documentDate(rel: string): string | null {\n return (\n /^((?:19|20)\\d{2}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01]))-/.exec(\n posix.basename(rel)\n )?.[1] ?? null\n )\n}\n\n/** A document's number: the `NNNN` its file name starts with, else null. */\nexport function documentNumber(rel: string): string | null {\n // A dated file name starts with four digits too: a date, not a number.\n if (documentDate(rel) !== null) return null\n return /^(\\d{4})-/.exec(posix.basename(rel))?.[1] ?? null\n}\n\n/**\n * The scaffold's heading is `NNNN - Title`; an older document may carry an\n * em dash or an en dash after the number. The number is shown once.\n */\nexport function documentTitle(heading: string, number: string | null): string {\n if (number === null) return heading\n const rest = new RegExp(`^${number}\\\\s*[\\u2014\\u2013:-]\\\\s*(.+)$`).exec(\n heading\n )?.[1]\n return rest ?? heading\n}\n","import { realpath } from 'node:fs/promises'\nimport { isAbsolute, join, relative } from 'node:path'\n\n/**\n * A path of `.rness/` as `rness.json` may name one (`marketing/README.md`):\n * relative, plain segments, none hidden and none `..`. `rness.json` is the\n * organization's: a path out of `.rness` would publish a developer's file\n * (a key, a token) on GitHub at their next sync.\n */\nexport const RNESS_PATH =\n /^[A-Za-z0-9_-][A-Za-z0-9._-]*(?:\\/[A-Za-z0-9_-][A-Za-z0-9._-]*)*$/\n\n/**\n * `rel` under `root`, refused when its real path — links followed — leads\n * out of `root`'s. Throws ENOENT as `realpath` does when it is not there.\n */\nexport async function containedPath(\n root: string,\n rel: string\n): Promise<string> {\n if (!RNESS_PATH.test(rel))\n throw new Error(`${rel} is not a path within .rness`)\n const path = join(root, ...rel.split('/'))\n const [realRoot, real] = await Promise.all([realpath(root), realpath(path)])\n const inside = relative(realRoot, real)\n if (inside === '' || inside.startsWith('..') || isAbsolute(inside))\n throw new Error(`${rel} leads out of .rness: rness reads nothing there`)\n return path\n}\n","{\n \"title\": \"Agent Pulse\",\n \"collections\": \"all\",\n \"colors\": {\n \"Draft\": \"gray\",\n \"Proposed\": \"blue\",\n \"Ready\": \"blue\",\n \"Approved\": \"purple\",\n \"In progress\": \"yellow\",\n \"Blocked\": \"red\",\n \"Accepted\": \"green\",\n \"Implemented\": \"green\",\n \"Completed\": \"green\",\n \"Rejected\": \"red\",\n \"Superseded\": \"yellow\",\n \"Abandoned\": \"gray\",\n \"ADR\": \"purple\",\n \"Specs\": \"blue\",\n \"Plans\": \"orange\",\n \"working\": \"green\"\n },\n \"fields\": {\n \"Collection\": {\n \"type\": \"select\",\n \"from\": \"$collection\"\n },\n \"Agent\": {\n \"type\": \"select\",\n \"from\": \"$agent\",\n \"options\": [\"working\"]\n },\n \"Working session\": {\n \"type\": \"text\",\n \"from\": \"$session\"\n },\n \"Session history\": {\n \"type\": \"text\",\n \"from\": \"$sessions\"\n }\n },\n \"views\": [\n {\n \"name\": \"All\",\n \"layout\": \"table\",\n \"fields\": [\"Title\", \"Collection\", \"Status\", \"Working session\"]\n },\n {\n \"name\": \"ADR\",\n \"layout\": \"board\",\n \"collection\": \"adr\",\n \"columns\": \"ADR status\"\n },\n {\n \"name\": \"Specs\",\n \"layout\": \"board\",\n \"collection\": \"specs\",\n \"columns\": \"Specs status\"\n },\n {\n \"name\": \"Plans\",\n \"layout\": \"board\",\n \"collection\": \"plans\",\n \"columns\": \"Plans status\"\n },\n {\n \"name\": \"Working\",\n \"layout\": \"table\",\n \"filter\": \"agent:working\",\n \"fields\": [\"Title\", \"Collection\", \"Status\", \"Working session\"]\n }\n ],\n \"hooks\": {\n \"session-start\": [\"mark-in-progress\"],\n \"edit\": [\"mark\"],\n \"session-end\": [\"clear-marks\"]\n }\n}\n","{\n \"title\": \"{label}\",\n \"collections\": {\n \"{collection}\": { \"label\": \"{label}\", \"statuses\": \"found\" }\n },\n \"colors\": {\n \"Draft\": \"gray\",\n \"Proposed\": \"blue\",\n \"Ready\": \"blue\",\n \"Approved\": \"purple\",\n \"In progress\": \"yellow\",\n \"Blocked\": \"red\",\n \"Accepted\": \"green\",\n \"Implemented\": \"green\",\n \"Completed\": \"green\",\n \"Rejected\": \"red\",\n \"Superseded\": \"yellow\",\n \"Abandoned\": \"gray\",\n \"working\": \"green\"\n },\n \"fields\": {\n \"Collection\": { \"type\": \"select\", \"from\": \"$collection\" },\n \"Agent\": { \"type\": \"select\", \"from\": \"$agent\", \"options\": [\"working\"] },\n \"Working session\": { \"type\": \"text\", \"from\": \"$session\" },\n \"Session history\": { \"type\": \"text\", \"from\": \"$sessions\" }\n },\n \"views\": [\n {\n \"name\": \"All\",\n \"layout\": \"table\",\n \"fields\": [\"Title\", \"Collection\", \"Status\", \"Working session\"]\n },\n { \"name\": \"{label}\", \"layout\": \"board\", \"collection\": \"{collection}\" },\n {\n \"name\": \"Working\",\n \"layout\": \"table\",\n \"filter\": \"agent:working\",\n \"fields\": [\"Title\", \"Collection\", \"Status\", \"Working session\"]\n }\n ]\n}\n","import agentPulse1 from '../presets/agent-pulse.1.json' with { type: 'json' }\nimport collection1 from '../presets/collection.1.json' with { type: 'json' }\n\n/**\n * The boards rness ships (spec 0031 §3): `agent-pulse`, and `collection`,\n * a template for one directory's own board. Each preset keeps every\n * revision it had, oldest first: a board records the one it was made from,\n * and `sync` merges a newer one into it (plan 0045). Bundled, never read\n * from disk: the running copy's folder may be gone during an upgrade.\n */\n\nexport type PresetName = 'agent-pulse' | 'collection'\n\nconst REVISIONS: Readonly<Record<PresetName, readonly unknown[]>> = {\n 'agent-pulse': [agentPulse1],\n collection: [collection1],\n}\n\nconst REF = /^([a-z][a-z0-9-]*)\\/([1-9][0-9]*)$/\n\n/** A tab's label, as `rness status` makes it for a directory: capitalised. */\nexport const labelOf = (name: string): string =>\n `${name.charAt(0).toUpperCase()}${name.slice(1)}`\n\n/** The latest revision of a preset, as a board records it: `agent-pulse/1`. */\nexport const currentPreset = (name: PresetName): string =>\n `${name}/${REVISIONS[name].length}`\n\nfunction revisionOf(ref: string): unknown {\n const [, name, n] = REF.exec(ref) ?? []\n if (name === undefined || n === undefined || !Object.hasOwn(REVISIONS, name))\n return undefined\n return REVISIONS[name as PresetName][Number(n) - 1]\n}\n\n/** Whether this rness bundles that revision. */\nexport const isPresetRevision = (ref: string): boolean =>\n revisionOf(ref) !== undefined\n\n/** The preset's name in a reference: `agent-pulse/1` → `agent-pulse`. */\nexport const presetNameOf = (ref: string): string => ref.split('/')[0] ?? ''\n\n/** `{collection}` and `{label}` in keys and texts, for one directory. */\nfunction instantiate(value: unknown, collection: string): unknown {\n const fill = (s: string): string =>\n s\n .replaceAll('{collection}', collection)\n .replaceAll('{label}', labelOf(collection))\n if (typeof value === 'string') return fill(value)\n if (Array.isArray(value)) return value.map((v) => instantiate(v, collection))\n if (value !== null && typeof value === 'object')\n return Object.fromEntries(\n Object.entries(value).map(([k, v]) => [\n fill(k),\n instantiate(v, collection),\n ])\n )\n return value\n}\n\n/** A revision's board, without its number, a fresh copy: `collection` names the directory a template is for. */\nexport function presetTemplate(\n ref: string,\n vars: { collection: string }\n): Record<string, unknown> {\n const revision = revisionOf(ref)\n if (revision === undefined) throw new Error(`no preset ${ref}`)\n return instantiate(revision, vars.collection) as Record<string, unknown>\n}\n","import { RNESS_PATH } from './contained.ts'\nimport { STATUSES } from './contract.ts'\nimport { isPresetRevision, labelOf, presetNameOf } from './presets.ts'\n\n/**\n * A board as `rness.json` declares it (spec 0031 §2.2): what a GitHub\n * Project shows of `.rness/`. rness keeps the engine (one issue per\n * document, `Path`, `Status`, the label `rness`); everything here is the\n * team's. A declaration is read whole or refused, naming its full key.\n */\n\nexport const OPTION_COLORS = [\n 'gray',\n 'blue',\n 'green',\n 'yellow',\n 'orange',\n 'red',\n 'pink',\n 'purple',\n] as const\nexport type OptionColor = (typeof OPTION_COLORS)[number]\n\nexport const FIELD_TYPES = ['text', 'date', 'select', 'number'] as const\nexport type FieldType = (typeof FIELD_TYPES)[number]\n\n/** What rness knows of a document, for a field's `from` (spec 0031 §2.4). */\nexport const SOURCES = [\n '$collection',\n '$status',\n '$agent',\n '$session',\n '$sessions',\n '$id',\n] as const\nexport type Source = (typeof SOURCES)[number]\n\n/** The option a field from `$agent` carries while a session works on the card. */\nexport const WORKING = 'working'\n\nexport interface FieldDeclaration {\n type: FieldType\n /** Front-matter keys or `$` sources, the first present winning. */\n from: string[]\n /** A select's options, in order; values found elsewhere follow. */\n options: string[]\n}\n\n/** `contract`, `found`, or the statuses in order (spec 0031 §2.3). */\nexport type StatusesDeclaration = 'contract' | 'found' | string[]\n\nexport interface CollectionDeclaration {\n label: string\n statuses: StatusesDeclaration\n /** A single-select field of this collection's statuses alone; null: none. */\n field: string | null\n}\n\nexport const VIEW_LAYOUTS = ['board', 'table', 'roadmap'] as const\nexport type ViewLayout = (typeof VIEW_LAYOUTS)[number]\n\nexport interface ViewDeclaration {\n name: string\n layout: ViewLayout\n /** Only this collection's cards; null: every card of the board. */\n collection: string | null\n /** A GitHub filter added to the view's own. */\n filter: string | null\n /** A board's columns: a single-select field; null: `Status`. */\n columns: string | null\n /** A table's columns, in order; null: GitHub's default. */\n fields: string[] | null\n /** A roadmap's date field. */\n date: string | null\n}\n\nexport type LabelSource = { kind: 'directory' } | { kind: 'key'; key: string }\n\n/** The session events a board's actions run at (spec 0032 §2): Claude Code's hooks. */\nexport const HOOK_EVENTS = ['session-start', 'edit', 'session-end'] as const\nexport type HookEvent = (typeof HOOK_EVENTS)[number]\n\n/** An action of the catalogue (spec 0032 §3), its parameters filled. */\nexport type BoardAction =\n | { action: 'mark' }\n | { action: 'mark-in-progress'; collections: string[]; statuses: string[] }\n | { action: 'clear-marks' }\n /** The agent's journal (spec 0030, 0032 §6): where notes go, how many per session and plan. */\n | { action: 'journal'; to: 'plan' | 'repo'; limit: number }\n | { action: 'journal-summary' }\nexport type ActionName = BoardAction['action']\n\n/** Each action, its event, and its parameters with their defaults (`undefined`: required). */\nexport const ACTIONS: Readonly<\n Record<\n ActionName,\n { event: HookEvent; parameters: Readonly<Record<string, unknown>> }\n >\n> = {\n mark: { event: 'edit', parameters: {} },\n 'mark-in-progress': {\n event: 'session-start',\n parameters: { collections: ['plans'], statuses: ['In progress'] },\n },\n 'clear-marks': { event: 'session-end', parameters: {} },\n journal: { event: 'session-start', parameters: { to: undefined, limit: 5 } },\n 'journal-summary': { event: 'session-end', parameters: {} },\n}\n\n/** The actions that write marks: they need a select from `$agent` with `working`. */\nconst MARKING: readonly ActionName[] = [\n 'mark',\n 'mark-in-progress',\n 'clear-marks',\n]\n\n/** A board's actions by event; an event it declares nothing at is absent. */\nexport type BoardHooks = Partial<Record<HookEvent, BoardAction[]>>\n\nexport interface BoardDeclaration {\n /** The project on the provider; null until `board push` creates it (spec 0033 §4). */\n number: number | null\n /** The preset and revision it was made from, `agent-pulse/1`; null: none. */\n preset: string | null\n title: string | null\n description: string | null\n /** A file of `.rness/` whose text, front matter removed, is the README. */\n readme: string | null\n /** A directory of `.rness/` whose files are the status updates. */\n updates: string | null\n collections: 'all' | Record<string, CollectionDeclaration>\n colors: Record<string, OptionColor>\n fields: Record<string, FieldDeclaration>\n labels: LabelSource | null\n views: ViewDeclaration[]\n /** What a session does to the board (spec 0032); none by default. */\n hooks: BoardHooks\n /** The entry as `rness.json` holds it: what is written back. */\n source: Record<string, unknown>\n}\n\n/** The fields every board has, and GitHub's own: a declared one of the same name is refused. */\nexport const TAKEN_FIELDS: readonly string[] = [\n 'Path',\n 'Status',\n 'Title',\n 'Assignees',\n 'Labels',\n 'Linked pull requests',\n 'Milestone',\n 'Repository',\n 'Reviewers',\n 'Type',\n 'Parent issue',\n 'Sub-issues progress',\n]\n/** What a table view may show besides the board's fields. */\nconst SHOWN_FIELDS: readonly string[] = [\n 'Title',\n 'Status',\n 'Labels',\n 'Assignees',\n 'Path',\n]\n\nconst BOARD_KEYS = [\n 'number',\n 'preset',\n 'title',\n 'description',\n 'readme',\n 'updates',\n 'collections',\n 'colors',\n 'fields',\n 'labels',\n 'views',\n 'hooks',\n]\nconst COLLECTION_KEYS = ['label', 'statuses', 'field']\nconst FIELD_KEYS = ['type', 'from', 'options']\nconst VIEW_KEYS = [\n 'name',\n 'layout',\n 'collection',\n 'filter',\n 'columns',\n 'fields',\n 'date',\n]\n/** The key a view's layout alone takes. */\nconst LAYOUT_KEY: Readonly<Record<string, ViewLayout>> = {\n columns: 'board',\n fields: 'table',\n date: 'roadmap',\n}\n\n/** A directory of `.rness/`, as a collection names it: never hidden, never a path. */\nconst DIRECTORY = /^[A-Za-z0-9][A-Za-z0-9._-]*$/\nconst PRESET = /^[a-z][a-z0-9-]*\\/[1-9][0-9]*$/\n\n/** A refused declaration: its full key and why. */\nexport class BoardRefused extends Error {\n readonly key: string\n readonly reason: string\n constructor(key: string, reason: string) {\n super(`\"${key}\" ${reason}`)\n this.key = key\n this.reason = reason\n }\n /** The same refusal said as `\"key\": reason`, for a reason that is a sentence of its own. */\n withColon(): BoardRefused {\n this.message = `\"${this.key}\": ${this.reason}`\n return this\n }\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n v !== null && typeof v === 'object' && !Array.isArray(v)\n\nconst isText = (v: unknown): v is string =>\n typeof v === 'string' && v.trim() !== ''\n\nconst isNames = (v: unknown): v is string[] =>\n Array.isArray(v) && v.every(isText) && new Set(v).size === v.length\n\nconst taken = (name: string): boolean =>\n TAKEN_FIELDS.some((t) => t.toLowerCase() === name.toLowerCase())\n\n/** The contract's statuses of a collection that has them; undefined: none. */\nexport const contractOf = (collection: string): readonly string[] | undefined =>\n // A directory named `constructor` is no member of the contract's table.\n Object.hasOwn(STATUSES, collection)\n ? (STATUSES as Readonly<Record<string, readonly string[] | undefined>>)[\n collection\n ]\n : undefined\n\nfunction unknownKeys(\n value: Record<string, unknown>,\n keys: readonly string[],\n at: string,\n what: string\n): void {\n for (const k of Object.keys(value))\n if (!keys.includes(k))\n throw new BoardRefused(`${at}.${k}`, `is not a key of ${what}`)\n}\n\nfunction optionalText(\n value: Record<string, unknown>,\n key: string,\n at: string\n): string | null {\n const v = value[key]\n if (v === undefined) return null\n if (!isText(v)) throw new BoardRefused(`${at}.${key}`, 'must be text')\n return v\n}\n\nfunction readCollection(\n name: string,\n value: unknown,\n at: string\n): CollectionDeclaration {\n if (!DIRECTORY.test(name))\n throw new BoardRefused(at, 'must name a directory of .rness')\n if (!isRecord(value))\n throw new BoardRefused(at, 'must be an object, as { \"statuses\": \"found\" }')\n unknownKeys(value, COLLECTION_KEYS, at, 'a collection')\n const label = optionalText(value, 'label', at) ?? labelOf(name)\n const raw = value['statuses']\n const contract = contractOf(name)\n let statuses: StatusesDeclaration\n if (raw === 'contract') {\n if (contract === undefined)\n throw new BoardRefused(\n `${at}.statuses`,\n 'is \"contract\" only for adr, specs and plans'\n )\n statuses = 'contract'\n } else if (raw === 'found') statuses = 'found'\n else if (isNames(raw) && raw.length > 0) {\n // A valid document whose status has no column would vanish from the board.\n const missing = (contract ?? []).filter((s) => !raw.includes(s))\n if (missing.length > 0)\n throw new BoardRefused(\n `${at}.statuses`,\n `must hold every status of the contract: ${missing.join(', ')} ${\n missing.length === 1 ? 'is' : 'are'\n } missing`\n )\n statuses = [...raw]\n } else\n throw new BoardRefused(\n `${at}.statuses`,\n 'must be \"contract\", \"found\" or a list of statuses'\n )\n const field = optionalText(value, 'field', at)\n if (field !== null && taken(field))\n throw new BoardRefused(\n `${at}.field`,\n 'is a field of rness or of GitHub: name it otherwise'\n )\n return { label, statuses, field }\n}\n\nfunction readField(name: string, value: unknown, at: string): FieldDeclaration {\n if (taken(name))\n throw new BoardRefused(\n at,\n 'is a field of rness or of GitHub: name it otherwise'\n )\n if (!isRecord(value))\n throw new BoardRefused(\n at,\n 'must be an object, as { \"type\": \"text\", \"from\": \"key\" }'\n )\n unknownKeys(value, FIELD_KEYS, at, 'a field')\n const type = FIELD_TYPES.find((t) => t === value['type'])\n if (type === undefined)\n throw new BoardRefused(\n `${at}.type`,\n `must be one of ${FIELD_TYPES.join(', ')}`\n )\n const raw = value['from']\n const from = isText(raw) ? [raw] : raw\n if (!isNames(from) || from.length === 0)\n throw new BoardRefused(\n `${at}.from`,\n 'must be a front-matter key, a $ source, or a list of them'\n )\n for (const f of from)\n if (f.startsWith('$') && !(SOURCES as readonly string[]).includes(f))\n throw new BoardRefused(\n `${at}.from`,\n `names ${f}, which rness does not know: ${SOURCES.slice(0, -1).join(', ')} or ${SOURCES.at(-1)}`\n )\n const rawOptions = value['options'] ?? []\n if (\n !(Array.isArray(rawOptions) && rawOptions.length === 0) &&\n !isNames(rawOptions)\n )\n throw new BoardRefused(`${at}.options`, 'must be a list of names')\n const options = [...(rawOptions as string[])]\n if (\n from.includes('$agent') &&\n (type !== 'select' || !options.includes(WORKING))\n )\n throw new BoardRefused(\n at,\n `is a select from $agent: it needs the option ${WORKING}`\n )\n return { type, from: [...from], options }\n}\n\nfunction readLabels(value: unknown, at: string): LabelSource | null {\n if (value === undefined) return null\n if (!isText(value))\n throw new BoardRefused(at, 'must be directory or a front-matter key')\n return value === 'directory'\n ? { kind: 'directory' }\n : { kind: 'key', key: value }\n}\n\ninterface Known {\n collections: 'all' | Record<string, CollectionDeclaration>\n fields: Record<string, FieldDeclaration>\n}\n\n/** A single-select a board view's columns may follow. */\nfunction isColumn(name: string, k: Known): boolean {\n if (name === 'Status') return true\n if (k.fields[name]?.type === 'select') return true\n if (k.collections === 'all') return name.endsWith(' status')\n return Object.values(k.collections).some((c) => c.field === name)\n}\n\n/** A field a table view may show. */\nfunction isShown(name: string, k: Known): boolean {\n return (\n SHOWN_FIELDS.includes(name) ||\n Object.hasOwn(k.fields, name) ||\n (k.collections === 'all'\n ? name.endsWith(' status')\n : Object.values(k.collections).some((c) => c.field === name))\n )\n}\n\nfunction readView(value: unknown, at: string, k: Known): ViewDeclaration {\n if (!isRecord(value))\n throw new BoardRefused(\n at,\n 'must be an object, as { \"name\": \"Board\", \"layout\": \"board\" }'\n )\n unknownKeys(value, VIEW_KEYS, at, 'a view')\n if (!isText(value['name']))\n throw new BoardRefused(`${at}.name`, 'must be text')\n const layout = VIEW_LAYOUTS.find((l) => l === value['layout'])\n if (layout === undefined)\n throw new BoardRefused(\n `${at}.layout`,\n `must be ${VIEW_LAYOUTS.slice(0, -1).join(', ')} or ${VIEW_LAYOUTS.at(-1)}`\n )\n for (const [key, only] of Object.entries(LAYOUT_KEY))\n if (value[key] !== undefined && only !== layout)\n throw new BoardRefused(`${at}.${key}`, `is a key of a ${only} view only`)\n const collection = optionalText(value, 'collection', at)\n if (collection !== null) {\n if (k.collections !== 'all' && !Object.hasOwn(k.collections, collection))\n throw new BoardRefused(\n `${at}.collection`,\n `names ${collection}, which is not on this board`\n )\n if (\n !Object.values(k.fields).some(\n (f) => f.type === 'select' && f.from.includes('$collection')\n )\n )\n throw new BoardRefused(\n `${at}.collection`,\n 'needs a select field from $collection to filter by'\n )\n }\n const columns = optionalText(value, 'columns', at)\n if (columns !== null && !isColumn(columns, k))\n throw new BoardRefused(\n `${at}.columns`,\n \"must name a single-select field: Status, a collection's field or a declared select\"\n )\n let fields: string[] | null = null\n if (value['fields'] !== undefined) {\n if (!isNames(value['fields']) || value['fields'].length === 0)\n throw new BoardRefused(`${at}.fields`, 'must be a list of field names')\n const unknown = value['fields'].find((f) => !isShown(f, k))\n if (unknown !== undefined)\n throw new BoardRefused(\n `${at}.fields`,\n `names ${unknown}, which is no field of this board`\n )\n fields = [...value['fields']]\n }\n const date = optionalText(value, 'date', at)\n if (\n layout === 'roadmap' &&\n (date === null || k.fields[date]?.type !== 'date')\n )\n throw new BoardRefused(`${at}.date`, 'must name a date field')\n return {\n name: value['name'],\n layout,\n collection,\n filter: optionalText(value, 'filter', at),\n columns,\n fields,\n date,\n }\n}\n\n/** Whether a board has the fields a mark writes: a select from `$agent` with `working`. */\nconst marks = (fields: Record<string, FieldDeclaration>): boolean =>\n Object.values(fields).some(\n (f) =>\n f.type === 'select' &&\n f.from.includes('$agent') &&\n f.options.includes(WORKING)\n )\n\n/** `hooks`: each event's actions, each from the catalogue, its requirements met (spec 0032 §3). */\nfunction readHooks(\n value: unknown,\n at: string,\n fields: Record<string, FieldDeclaration>,\n holdsPlans: boolean\n): BoardHooks {\n if (value === undefined) return {}\n if (!isRecord(value)) throw new BoardRefused(at, 'must map events to actions')\n const hooks: BoardHooks = {}\n for (const [event, list] of Object.entries(value)) {\n const where = `${at}.${event}`\n const known = HOOK_EVENTS.find((e) => e === event)\n if (known === undefined)\n throw new BoardRefused(\n where,\n `is not an event: ${HOOK_EVENTS.slice(0, -1).join(', ')} or ${HOOK_EVENTS.at(-1)}`\n )\n if (!Array.isArray(list)) throw new BoardRefused(where, 'must list actions')\n const actions: BoardAction[] = []\n for (const [i, item] of list.entries()) {\n const key = `${where}[${i}]`\n const raw: Record<string, unknown> | null =\n typeof item === 'string'\n ? { action: item }\n : isRecord(item)\n ? item\n : null\n const name = raw?.['action']\n const names = Object.keys(ACTIONS) as ActionName[]\n const action = names.find((a) => a === name)\n if (raw === null || action === undefined)\n throw new BoardRefused(\n key,\n `names ${typeof name === 'string' ? name : JSON.stringify(item)}, which is no action: ${names.slice(0, -1).join(', ')} or ${names.at(-1)}`\n )\n const spec = ACTIONS[action]\n if (spec.event !== known)\n throw new BoardRefused(\n key,\n `${action} is an action of ${spec.event}, not of ${known}`\n ).withColon()\n for (const p of Object.keys(raw))\n if (p !== 'action' && !Object.hasOwn(spec.parameters, p))\n throw new BoardRefused(\n `${key}.${p}`,\n `is not a parameter of ${action}`\n )\n if (actions.some((a) => a.action === action))\n throw new BoardRefused(key, `${action} is there already`).withColon()\n if (MARKING.includes(action) && !marks(fields))\n throw new BoardRefused(\n key,\n `${action} needs a select field from $agent with the option ${WORKING}`\n ).withColon()\n if (action === 'journal' && !holdsPlans)\n throw new BoardRefused(\n key,\n 'journal needs the plans on its board'\n ).withColon()\n if (action === 'mark-in-progress') {\n const list = (p: string): string[] => {\n const v = raw[p] ?? spec.parameters[p]\n if (!isNames(v) || v.length === 0)\n throw new BoardRefused(`${key}.${p}`, `must list ${p}`)\n return [...v]\n }\n actions.push({\n action,\n collections: list('collections'),\n statuses: list('statuses'),\n })\n } else if (action === 'journal') {\n const to = raw['to']\n if (to !== 'plan' && to !== 'repo')\n throw new BoardRefused(`${key}.to`, 'must be plan or repo')\n const limit = raw['limit'] ?? spec.parameters['limit']\n if (typeof limit !== 'number' || !Number.isInteger(limit) || limit < 1)\n throw new BoardRefused(\n `${key}.limit`,\n 'must be a number of notes, 1 or more'\n )\n actions.push({ action, to, limit })\n } else actions.push({ action })\n }\n hooks[known] = actions\n }\n // A summary closes a journal: one this board keeps.\n const ends = hooks['session-end'] ?? []\n const at_ = ends.findIndex((a) => a.action === 'journal-summary')\n if (\n at_ !== -1 &&\n !(hooks['session-start'] ?? []).some((a) => a.action === 'journal')\n )\n throw new BoardRefused(\n `${at}.session-end[${at_}]`,\n 'journal-summary needs journal at session-start on its board'\n ).withColon()\n return hooks\n}\n\n/** The name of Agent Pulse in `boards`; any other names a directory of `.rness/`. */\nexport const PULSE = 'pulse'\n\n/** The preset a board of that name is made from: Agent Pulse for `pulse`, else a collection's. */\nexport const presetFor = (name: string): 'agent-pulse' | 'collection' =>\n name === PULSE ? 'agent-pulse' : 'collection'\n\nconst PRESET_NAME = /^[a-z][a-z0-9-]*(?:\\/[1-9][0-9]*)?$/\n\n/**\n * One entry of `boards` that is a string: a preset not created yet, by name\n * or revision (spec 0033 §4) — `agent-pulse` for `pulse`, `collection` for\n * any other name. The string as written, or {@link BoardRefused}.\n */\nexport function readPresetEntry(\n name: string,\n value: string,\n knows: (ref: string) => boolean = isPresetRevision\n): string {\n const at = `boards.${name}`\n const preset = presetFor(name)\n if (!PRESET_NAME.test(value))\n throw new BoardRefused(at, `must name a preset, as \"${preset}\"`)\n if (presetNameOf(value) !== preset)\n throw new BoardRefused(\n at,\n name === PULSE\n ? `names ${value}: ${PULSE} is made from ${preset}`\n : `names ${value}: a collection's board is made from ${preset}`\n )\n if (value.includes('/') && !knows(value))\n throw new BoardRefused(at, `names ${value}, which this rness does not have`)\n return value\n}\n\n/**\n * One entry of `boards` that is an object: the board, read whole, or\n * {@link BoardRefused}; without `number` until `board push` creates it.\n * `knows` says which preset revisions there are: this rness's, unless a\n * caller brings its own.\n */\nexport function parseBoard(\n name: string,\n value: unknown,\n knows: (ref: string) => boolean = isPresetRevision\n): BoardDeclaration {\n const at = `boards.${name}`\n if (!isRecord(value))\n throw new BoardRefused(\n at,\n 'must be an object, as { \"collections\": …, \"views\": … }'\n )\n unknownKeys(value, BOARD_KEYS, at, 'a board')\n const number = value['number'] ?? null\n if (\n number !== null &&\n (typeof number !== 'number' || !Number.isInteger(number) || number < 1)\n )\n throw new BoardRefused(`${at}.number`, 'must be a project number')\n const preset = value['preset']\n if (\n preset !== undefined &&\n (typeof preset !== 'string' || !PRESET.test(preset))\n )\n throw new BoardRefused(\n `${at}.preset`,\n 'must name a preset and its revision, as agent-pulse/1'\n )\n if (typeof preset === 'string' && !knows(preset))\n throw new BoardRefused(\n `${at}.preset`,\n `names ${preset}, which this rness does not have`\n )\n\n const rawCollections = value['collections']\n let collections: BoardDeclaration['collections']\n if (rawCollections === 'all') collections = 'all'\n else if (isRecord(rawCollections) && Object.keys(rawCollections).length > 0)\n collections = Object.fromEntries(\n Object.entries(rawCollections).map(([c, v]) => [\n c,\n readCollection(c, v, `${at}.collections.${c}`),\n ])\n )\n else\n throw new BoardRefused(\n `${at}.collections`,\n 'must name at least one collection, or be \"all\"'\n )\n\n const rawColors = value['colors'] ?? {}\n if (!isRecord(rawColors))\n throw new BoardRefused(`${at}.colors`, 'must map options to colours')\n const colors: Record<string, OptionColor> = {}\n for (const [option, c] of Object.entries(rawColors)) {\n const color = OPTION_COLORS.find((o) => o === c)\n if (color === undefined)\n throw new BoardRefused(\n `${at}.colors.${option}`,\n `must be one of ${OPTION_COLORS.join(', ')}`\n )\n colors[option] = color\n }\n\n const rawFields = value['fields'] ?? {}\n if (!isRecord(rawFields))\n throw new BoardRefused(`${at}.fields`, 'must map names to fields')\n const fields = Object.fromEntries(\n Object.entries(rawFields).map(([f, v]) => [\n f,\n readField(f, v, `${at}.fields.${f}`),\n ])\n )\n if (collections !== 'all')\n for (const [c, decl] of Object.entries(collections))\n if (decl.field !== null && Object.hasOwn(fields, decl.field))\n throw new BoardRefused(\n `${at}.collections.${c}.field`,\n `names ${decl.field}, which fields declares too`\n )\n\n const known: Known = { collections, fields }\n const rawViews = value['views']\n if (!Array.isArray(rawViews) || rawViews.length === 0)\n throw new BoardRefused(`${at}.views`, 'must list at least one view')\n const views: ViewDeclaration[] = []\n for (const [i, v] of rawViews.entries()) {\n const view = readView(v, `${at}.views[${i}]`, known)\n if (views.some((w) => w.name === view.name))\n throw new BoardRefused(\n `${at}.views[${i}].name`,\n `is ${view.name} again: a view's name is unique on its board`\n )\n views.push(view)\n }\n\n // rness.json is the organization's: a path out of .rness would publish a\n // developer's file on GitHub at their next sync.\n const within = (key: string): string | null => {\n const path = optionalText(value, key, at)\n if (path !== null && !RNESS_PATH.test(path))\n throw new BoardRefused(\n `${at}.${key}`,\n `must be a path within .rness, as ${key === 'readme' ? 'marketing/README.md' : 'marketing/updates'}`\n )\n return path\n }\n return {\n number,\n preset: (preset as string | undefined) ?? null,\n title: optionalText(value, 'title', at),\n description: optionalText(value, 'description', at),\n readme: within('readme'),\n updates: within('updates'),\n collections,\n colors,\n fields,\n labels: readLabels(value['labels'], `${at}.labels`),\n views,\n hooks: readHooks(\n value['hooks'],\n `${at}.hooks`,\n fields,\n collections === 'all' || Object.hasOwn(collections, 'plans')\n ),\n source: value,\n }\n}\n","import { execFile } from 'node:child_process'\nimport { dirname, resolve } from 'node:path'\nimport { promisify } from 'node:util'\n\nimport type { GitCredentials } from './provider.ts'\n\nconst execFileP = promisify(execFile)\n\n// Answers git's `get` with what the environment holds. The token is never in\n// an argument, a URL or a config file: only in the child's environment.\nconst ENV_HELPER =\n '!f() { test \"$1\" = get && printf \"username=%s\\\\npassword=%s\\\\n\" \"$RNESS_GIT_USERNAME\" \"$RNESS_GIT_TOKEN\"; }; f'\n\n/**\n * How one git command is given credentials (spec 0004 §4): the helpers git\n * would otherwise consult are cleared, and one that lives for this command\n * only reads the child's environment. Nothing when there are none.\n */\nexport function withCredentials(\n credentials: GitCredentials | null | undefined\n): {\n args: string[]\n env: Record<string, string>\n} {\n if (credentials === null || credentials === undefined)\n return { args: [], env: {} }\n return {\n args: ['-c', 'credential.helper=', '-c', `credential.helper=${ENV_HELPER}`],\n env: {\n RNESS_GIT_USERNAME: credentials.username,\n RNESS_GIT_TOKEN: credentials.password,\n },\n }\n}\n\nasync function git(\n args: readonly string[],\n cwd?: string,\n credentials?: GitCredentials | null\n): Promise<string> {\n const auth = withCredentials(credentials)\n try {\n const { stdout } = await execFileP('git', [...auth.args, ...args], {\n ...(cwd === undefined ? {} : { cwd }),\n env: {\n ...process.env,\n ...auth.env,\n GIT_TERMINAL_PROMPT: '0',\n // Pin the command to `cwd` itself: without a ceiling, git walks up and\n // a plain directory under `org/` would report — or be pulled into —\n // whatever repository happens to sit above the workspace root. git\n // ignores a relative ceiling entry, hence the resolve().\n ...(cwd === undefined\n ? {}\n : { GIT_CEILING_DIRECTORIES: dirname(resolve(cwd)) }),\n },\n maxBuffer: 16 * 1024 * 1024,\n })\n return stdout\n } catch (e) {\n const err = e as { stderr?: string; message?: string }\n const text =\n err.stderr !== undefined && err.stderr !== ''\n ? err.stderr\n : (err.message ?? 'unknown error')\n const first =\n text.split('\\n').find((l) => l.trim() !== '') ?? 'unknown error'\n throw new Error(`git ${args[0] ?? ''} failed: ${first.trim()}`, {\n cause: e,\n })\n }\n}\n\n/** Reject a value git could parse as an option (e.g. a `rness.json` URL starting with `-`). */\nexport function positional(value: string, what: string): string {\n if (value.startsWith('-'))\n throw new Error(`refusing suspicious ${what}: ${value}`)\n return value\n}\n\n/** `git clone <url> <dir>`; `dir` must not exist. */\nexport async function clone(\n url: string,\n dir: string,\n credentials?: GitCredentials | null\n): Promise<void> {\n await git(\n [\n 'clone',\n '--quiet',\n '--',\n positional(url, 'repository url'),\n positional(dir, 'directory'),\n ],\n undefined,\n credentials\n )\n}\n\n/**\n * True when `git status --porcelain` prints nothing, ignoring the paths in\n * `ignore` (rness-managed files such as `AGENTS.md`/`CLAUDE.md` that sync\n * itself writes into every clone and that should never veto an auto-pull).\n */\nexport async function isClean(\n dir: string,\n ignore: readonly string[] = []\n): Promise<boolean> {\n const pathspec = ignore.map((p) => `:!${p}`)\n return (\n (\n await git(\n [\n 'status',\n '--porcelain',\n // Every untracked file on its own line: a directory folded into one\n // `?? dir/` entry would slip past a pathspec naming a file inside it.\n '--untracked-files=all',\n ...(pathspec.length > 0 ? ['--', ...pathspec] : []),\n ],\n dir\n )\n ).trim() === ''\n )\n}\n\n/**\n * Which of `paths` differ from `HEAD` in `dir` — modified, added or untracked\n * (ignored ones are not). Paths relative to `dir`, in git's order.\n */\nexport async function changedPaths(\n dir: string,\n paths: readonly string[]\n): Promise<string[]> {\n if (paths.length === 0) return []\n const entries = (\n await git(\n ['status', '--porcelain', '-z', '--untracked-files=all', '--', ...paths],\n dir\n )\n ).split('\\0')\n const changed: string[] = []\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i] ?? ''\n if (entry.length < 4) continue\n changed.push(entry.slice(3))\n // A rename or copy is followed by its source path.\n if (entry[0] === 'R' || entry[0] === 'C') i++\n }\n return changed\n}\n\n/**\n * Which of `paths` the history of `HEAD` in `dir` holds — a document gone\n * from the working tree was there (spec 0018 §2). One `git log` a path,\n * nothing fetched. `HEAD`, not every ref: a teammate's document fetched but\n * not merged is not this clone's. `--full-history`: a path added and removed\n * on a branch merged back counts. A path is literal, never an option or a\n * glob. One git cannot answer for — no repository, no commit yet, outside\n * the repository — is not seen: git does not vouch for it.\n */\nexport async function seenPaths(\n dir: string,\n paths: readonly string[]\n): Promise<Set<string>> {\n const seen = new Set<string>()\n for (const path of new Set(paths)) {\n try {\n const commit = await git(\n [\n 'log',\n '-1',\n '--full-history',\n '--format=%H',\n 'HEAD',\n '--',\n `:(literal)${path}`,\n ],\n dir\n )\n if (commit.trim() !== '') seen.add(path)\n } catch {\n // Not seen: see above.\n }\n }\n return seen\n}\n\n/**\n * `name` in the git directory of `dir`, absolute — its worktree's own for a\n * linked worktree (`git rev-parse --git-path`). Never pushed. Null when\n * `dir` is no repository.\n */\nexport async function gitPath(\n dir: string,\n name: string\n): Promise<string | null> {\n try {\n const path = (await git(['rev-parse', '--git-path', name], dir)).trim()\n return path === '' ? null : resolve(dir, path)\n } catch {\n return null\n }\n}\n\nexport async function pullFastForward(\n dir: string,\n credentials?: GitCredentials | null\n): Promise<void> {\n await git(['pull', '--ff-only', '--quiet'], dir, credentials)\n}\n\n/** `git remote add origin <url>` then `git push -u origin main`, in `dir`. */\nexport async function publish(\n dir: string,\n url: string,\n credentials?: GitCredentials | null\n): Promise<void> {\n await git(['remote', 'add', 'origin', positional(url, 'repository url')], dir)\n await git(['push', '--quiet', '-u', 'origin', 'main'], dir, credentials)\n}\n\n/** The commit `HEAD` names in `dir`; null without a repository or a commit. */\nexport async function headOf(dir: string): Promise<string | null> {\n try {\n return (\n (await git(['rev-parse', '--verify', '--quiet', 'HEAD'], dir)).trim() ||\n null\n )\n } catch {\n return null\n }\n}\n\n/** The branch checked out in `dir`; null when `HEAD` is detached, or without a repository. */\nexport async function branchOf(dir: string): Promise<string | null> {\n try {\n return (\n (await git(['symbolic-ref', '--quiet', '--short', 'HEAD'], dir)).trim() ||\n null\n )\n } catch {\n return null\n }\n}\n\n/** The commits reachable from `to` and not from `from`, oldest first, abbreviated. */\nexport async function commitsBetween(\n dir: string,\n from: string,\n to = 'HEAD'\n): Promise<string[]> {\n const range = `${positional(from, 'revision')}..${positional(to, 'revision')}`\n return (await git(['rev-list', '--reverse', '--abbrev-commit', range], dir))\n .split('\\n')\n .map((l) => l.trim())\n .filter((l) => l !== '')\n}\n\n/** The `origin` URL, or null when `dir` is not a clone with an origin. */\nexport async function originUrl(dir: string): Promise<string | null> {\n try {\n return (await git(['remote', 'get-url', 'origin'], dir)).trim()\n } catch {\n return null\n }\n}\n\n/** `git init -q -b main <dir>` (the directory must exist). */\nexport async function init(dir: string): Promise<void> {\n await git(['init', '-q', '-b', 'main'], dir)\n}\n\n/** `git add -A && git commit -q -m <message>` in `dir`. */\nexport async function commitAll(dir: string, message: string): Promise<void> {\n await git(['add', '-A'], dir)\n await git(['commit', '-q', '-m', message], dir)\n}\n","import { spawn } from 'node:child_process'\n\nimport { positional, withCredentials } from './git.ts'\nimport type { GitCredentials } from './provider.ts'\n\nexport const DEFAULT_HOST = 'https://github.com/'\nexport const SSH_HOST = 'git@github.com:'\n\n/** `<host><org>/<repo>.git`; `host` ends with `/` (https, file) or `:` (ssh). */\nexport function repoUrl(host: string, org: string, repo: string): string {\n return `${host}${org}/${repo}.git`\n}\n\nexport type Probe =\n { kind: 'found' } | { kind: 'not-found' } | { kind: 'error'; message: string }\n\nconst AUTH = [\n /authentication failed/i,\n /permission denied/i,\n /could not read username/i,\n /terminal prompts disabled/i,\n]\nconst NOT_FOUND = [\n /repository .*not found/i,\n /does not appear to be a git repository/i,\n]\n\nfunction firstLine(text: string): string {\n return (\n text\n .split('\\n')\n .find((l) => l.trim() !== '')\n ?.trim() ?? 'unknown error'\n )\n}\n\n/**\n * Interpret `git ls-remote --exit-code <url> HEAD`. Auth patterns win over\n * not-found ones: GitHub tells strangers a private repository does not exist,\n * so \"not found\" only counts when nothing points at a credentials problem.\n * Exit 2 is \"no HEAD\" — an empty repository that does exist.\n */\nexport function classifyProbe(\n url: string,\n exitCode: number,\n stderr: string\n): Probe {\n if (exitCode === 0 || exitCode === 2) return { kind: 'found' }\n if (AUTH.some((r) => r.test(stderr)))\n return {\n kind: 'error',\n message: `cannot access ${url}: ${firstLine(stderr)}`,\n }\n if (NOT_FOUND.some((r) => r.test(stderr))) return { kind: 'not-found' }\n return { kind: 'error', message: `cannot reach ${url}: ${firstLine(stderr)}` }\n}\n\n/**\n * How long, after the child has exited, the stderr pipe may still deliver what\n * git wrote before exiting. `'exit'` can precede the last `'data'` event, and\n * an empty stderr would be classified as an unreachable remote — but a\n * grandchild (a credential helper) can hold the pipe open for as long as it\n * likes, so the wait is bounded and `'close'` is never awaited.\n */\nconst STDERR_FLUSH_MS = 200\n\n/**\n * `git ls-remote --exit-code <url> HEAD`, classified (see `classifyProbe`).\n * Never hangs: the child is killed after `timeoutMs`, and the answer never\n * waits on `'close'`, so a credential helper left holding the stderr pipe\n * cannot keep the caller pending. The child stays in this process's group so\n * that Ctrl-C in the terminal reaches it too.\n */\nexport async function probeRemote(\n url: string,\n timeoutMs = 60_000,\n credentials?: GitCredentials | null\n): Promise<Probe> {\n // Before anything spawns, and outside the promise: a url git would read as\n // an option must fail loudly rather than reach the command line.\n positional(url, 'repository url')\n return new Promise<Probe>((resolve) => {\n const auth = withCredentials(credentials)\n const child = spawn(\n 'git',\n [...auth.args, 'ls-remote', '--exit-code', url, 'HEAD'],\n {\n stdio: ['ignore', 'ignore', 'pipe'],\n env: { ...process.env, ...auth.env, GIT_TERMINAL_PROMPT: '0' },\n }\n )\n const chunks: string[] = []\n child.stderr?.setEncoding('utf8')\n child.stderr?.on('data', (chunk: string) => chunks.push(chunk))\n\n let settled = false\n const settle = (probe: Probe): void => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n // Release the pipe: a grandchild still holding it open would otherwise\n // keep the event loop alive long after the answer is known.\n child.stderr?.destroy()\n resolve(probe)\n }\n const timer = setTimeout(() => {\n // Only the child git itself: a grandchild it orphaned is harmless, and\n // killing a whole process group would mean detaching from ours, which\n // costs the terminal's Ctrl-C.\n child.kill('SIGKILL')\n settle({\n kind: 'error',\n message: `cannot reach ${url}: timed out after ${Math.round(timeoutMs / 1000)}s`,\n })\n }, timeoutMs)\n\n child.on('error', (e: Error) => settle(classifyProbe(url, 1, e.message)))\n child.on('exit', (code) => {\n const finish = (): void =>\n settle(classifyProbe(url, code ?? 1, chunks.join('')))\n const stderr = child.stderr\n if (stderr === null || stderr.readableEnded || stderr.destroyed)\n return finish()\n const flush = setTimeout(finish, STDERR_FLUSH_MS)\n const done = (): void => {\n clearTimeout(flush)\n finish()\n }\n stderr.once('end', done)\n stderr.once('error', done)\n })\n })\n}\n","import { readFile } from 'node:fs/promises'\nimport { basename, join } from 'node:path'\n\nimport {\n BoardRefused,\n PULSE,\n parseBoard,\n readPresetEntry,\n} from './board-declaration.ts'\nimport { writeFileAtomic } from './fs.ts'\nimport { repoUrl } from './remote.ts'\nimport type {\n BoardEntry,\n Boards,\n Manifest,\n ProviderName,\n RefusedBoard,\n RepoEntry,\n ScopeEntry,\n} from './types.ts'\n\n/**\n * A repository or scope name: what GitHub allows in a repository name, in\n * lowercase — letters, digits, `.`, `_` and `-`. Not `.` or `..` (the name is\n * a directory under `org/`), and no leading `-` (git would read an option).\n */\nexport const NAME = /^(?!\\.{1,2}$)[a-z0-9._][a-z0-9._-]*$/\n\n/**\n * The organization's context repository. It holds the catalogue and is cloned\n * as `<root>/.rness`, so it is never a member of the workspace it defines:\n * `create` does not offer it and `add` refuses it (spec 0009).\n */\nexport const CONTEXT_REPO = '.rness'\n\n/**\n * Names that are never a repository of the workspace, whatever they look like\n * (spec 0009). A leading dot is an ordinary first character — `.github`\n * carries an organization's profile, its templates and its shared workflows —\n * so the rule cannot be a shape: it is this list. Add a name here rather than\n * inventing another filter.\n *\n * - `.rness` — the context repository: it holds the catalogue and is already\n * cloned as `<root>/.rness`.\n * - `.git` — a git directory, were `org/` ever to sit inside a repository.\n * - `node_modules` — an install run one directory too high.\n */\nexport const EXCLUDED_NAMES: ReadonlySet<string> = new Set([\n CONTEXT_REPO,\n '.git',\n 'node_modules',\n])\n\n/**\n * Whether a repository of the organization can become a member of the\n * workspace. Everything active is, but an excluded name; an archived\n * repository is read-only on GitHub, so a block written into it could never be\n * pushed back. `create` filters its listing with this, and counts with it, so\n * the number it announces and the list it offers cannot disagree.\n */\nexport function isMemberRepo(repo: {\n name: string\n archived: boolean\n}): boolean {\n return !repo.archived && !EXCLUDED_NAMES.has(repo.name.toLowerCase())\n}\n\n/**\n * Whether a directory under `org/` is one of the workspace's clones. It must\n * be a name the catalogue could hold: a directory `rness add` could never\n * declare is not reported as an undeclared clone, since the command suggested\n * to bring it in would refuse it.\n */\nexport function isWorkspaceClone(name: string): boolean {\n return NAME.test(name) && !EXCLUDED_NAMES.has(name)\n}\n/** How the rule reads in an error message. */\nexport const NAME_RULE =\n \"lowercase letters, digits, '.', '_' and '-', not starting with '-'\"\n\n/**\n * A GitHub organization (or user) name: alphanumerics and single hyphens, not\n * at either end, at most 39 characters. Used exactly as typed — GitHub\n * resolves names case-insensitively, but the URLs and `rness.json` keep the\n * spelling the user chose.\n */\nexport const ORG_NAME = /^[A-Za-z0-9](?:[A-Za-z0-9]|-(?=[A-Za-z0-9])){0,38}$/\n\n/** Every top-level key contract 1 defines. */\nconst KEYS = [\n 'contract',\n 'provider',\n 'org',\n 'agents',\n 'boards',\n // Former names of `boards`, still read: `sync` renames them (spec 0033 §3).\n 'projects',\n 'pulse',\n 'repos',\n 'scopes',\n]\n\nfunction fail(message: string): never {\n throw new Error(`rness.json: ${message}`)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction checkPath(scope: string, path: unknown): string {\n if (typeof path !== 'string' || path === '')\n fail(`scope \"${scope}\" needs a string \"path\"`)\n if (path.startsWith('/')) fail(`scope \"${scope}\" path must be relative`)\n if (path.split('/').includes('..'))\n fail(`scope \"${scope}\" path must not contain \"..\"`)\n if (path.split('/').some((segment) => segment === ''))\n fail(`scope \"${scope}\" path must not contain empty segments`)\n return path\n}\n\nfunction readOrg(value: unknown): string | null {\n if (value === undefined || value === null) return null\n if (typeof value !== 'string' || !ORG_NAME.test(value)) {\n fail(\n `\"org\" must be a GitHub organization name (got ${JSON.stringify(value)})`\n )\n }\n return value\n}\n\n/**\n * The name the workspace goes by — in its blocks and its session titles: the\n * organization, else the root directory's name. A workspace without `org` is\n * a blank one (spec 0012), a normal state rather than a slip to warn about.\n */\nexport function workspaceName(manifest: Manifest, root: string): string {\n return manifest.org ?? basename(root)\n}\n\n/** An agent name as `agents` holds it: lowercase letters, digits and `-`. */\nconst AGENT_NAME = /^[a-z][a-z0-9-]*$/\n\n/** `agents`, when present: a list of unique agent names (spec 0011 §3.1). */\nfunction readAgents(value: unknown): string[] | null {\n if (value === undefined) return null\n if (\n !Array.isArray(value) ||\n !value.every((v) => typeof v === 'string' && AGENT_NAME.test(v)) ||\n new Set(value).size !== value.length\n )\n fail(\n `\"agents\" must be a list of unique agent names (got ${JSON.stringify(value)})`\n )\n return [...(value as string[])]\n}\n\n/** The hosting providers `provider` may name (spec 0017 §2.1). */\nexport const PROVIDER_NAMES: readonly ProviderName[] = [\n 'github',\n 'gitlab',\n 'atlassian',\n]\n\n/** `provider`, when present: one of {@link PROVIDER_NAMES}. */\nfunction readProvider(value: unknown): ProviderName | null {\n if (value === undefined) return null\n const name = PROVIDER_NAMES.find((n) => n === value)\n if (name === undefined)\n fail(\n `\"provider\" must be one of ${PROVIDER_NAMES.join(', ')} (got ${JSON.stringify(value)})`\n )\n return name\n}\n\n/** The former `pulse`, 0.12 to 0.16: Agent Pulse alone, by number. */\nfunction readPulse(value: unknown): Boards {\n if (\n !isRecord(value) ||\n Object.keys(value).length !== 1 ||\n typeof value.project !== 'number' ||\n !Number.isInteger(value.project) ||\n value.project < 1\n )\n fail(\n `\"pulse\" must be { \"project\": <number> } (got ${JSON.stringify(value)})`\n )\n return { [PULSE]: value.project }\n}\n\n/** A board's project number, whatever its form in `boards`; null until `board push` creates it. */\nexport const projectNumber = (entry: BoardEntry): number | null =>\n typeof entry === 'number'\n ? entry\n : typeof entry === 'string'\n ? null\n : entry.number\n\nexport { PULSE }\n/** A name `boards` takes: a directory name, never hidden or a path. */\nconst BOARD_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/\n\nconst isProjectNumber = (n: unknown): n is number =>\n typeof n === 'number' && Number.isInteger(n) && n >= 1\n\n/**\n * `boards`, when present: names to boards — one declared whole (spec 0031\n * §2), a preset not created yet (spec 0033 §4), or a number (a board made\n * before 0.21.0) — the projects of those created distinct. A board refused\n * is set aside with its reason; the rest is read.\n */\nfunction readBoardEntries(value: unknown): {\n boards: Boards | null\n refused: RefusedBoard[]\n} {\n const entries = isRecord(value) ? Object.entries(value) : []\n const numbers = entries.flatMap(([, n]) =>\n isRecord(n) ? (isProjectNumber(n['number']) ? [n['number']] : []) : [n]\n )\n if (\n entries.length === 0 ||\n !entries.every(\n ([name, n]) =>\n BOARD_NAME.test(name) &&\n (isProjectNumber(n) || typeof n === 'string' || isRecord(n))\n ) ||\n new Set(numbers).size !== numbers.length\n )\n fail(\n `\"boards\" must map names to boards on distinct projects, as { \"pulse\": \"agent-pulse\", \"marketing\": 5 } (got ${JSON.stringify(value)})`\n )\n const boards: Boards = {}\n const refused: RefusedBoard[] = []\n for (const [name, entry] of entries) {\n if (isProjectNumber(entry)) {\n boards[name] = entry\n continue\n }\n try {\n boards[name] =\n typeof entry === 'string'\n ? readPresetEntry(name, entry)\n : parseBoard(name, entry)\n } catch (e) {\n if (!(e instanceof BoardRefused)) throw e\n refused.push({ name, reason: e.message, source: entry })\n }\n }\n return {\n boards: Object.keys(boards).length === 0 ? null : boards,\n refused,\n }\n}\n\n/** The keys that have held the boards, newest first (spec 0033 §3). */\nconst HOLDERS = ['boards', 'projects', 'pulse'] as const\n\n/**\n * `boards`, else the former `projects` read as `boards`, else the former\n * `pulse` read as `boards.pulse`; more than one of them refused.\n */\nfunction readBoardsOrFormer(data: Record<string, unknown>): {\n boards: Boards | null\n refused: RefusedBoard[]\n formerKey?: 'projects' | 'pulse'\n} {\n const present = HOLDERS.filter((k) => data[k] !== undefined)\n if (present.length > 1)\n fail(\n `${present.map((k) => JSON.stringify(k)).join(' and ')} at once: keep \"boards\" only`\n )\n const key = present[0]\n if (key === undefined) return { boards: null, refused: [] }\n if (key === 'pulse')\n return { boards: readPulse(data.pulse), refused: [], formerKey: key }\n const read = readBoardEntries(data[key])\n return key === 'boards' ? read : { ...read, formerKey: key }\n}\n\n/** The key, else the first repository URL's host (github.com → github), else github. */\nexport function providerOf(manifest: Manifest): ProviderName {\n if (manifest.provider !== null) return manifest.provider\n const url = Object.values(manifest.repos)[0]?.url ?? ''\n const host = /^(?:[a-z+]+:\\/\\/(?:[^@/]*@)?|[^@/]+@)([^/:]+)/i.exec(url)?.[1]\n if (host?.toLowerCase().includes('gitlab')) return 'gitlab'\n return 'github'\n}\n\nfunction readRepos(value: unknown): Record<string, RepoEntry> {\n const raw = value ?? {}\n if (!isRecord(raw)) fail('\"repos\" must be an object')\n const repos: Record<string, RepoEntry> = {}\n for (const [name, entry] of Object.entries(raw)) {\n if (!NAME.test(name))\n fail(`repo name \"${name}\" may only contain ${NAME_RULE}`)\n if (!isRecord(entry) || typeof entry.url !== 'string')\n fail(`repo \"${name}\" needs a string \"url\"`)\n repos[name] = { url: entry.url }\n }\n return repos\n}\n\nfunction readScopes(value: unknown): Record<string, ScopeEntry> {\n const raw = value ?? {}\n if (!isRecord(raw)) fail('\"scopes\" must be an object')\n const scopes: Record<string, ScopeEntry> = {}\n for (const [name, entry] of Object.entries(raw)) {\n if (!NAME.test(name))\n fail(`scope name \"${name}\" may only contain ${NAME_RULE}`)\n if (!isRecord(entry)) fail(`scope \"${name}\" must be an object`)\n const path = checkPath(name, entry.path)\n const ext = entry.extends ?? []\n if (!Array.isArray(ext) || !ext.every((t) => typeof t === 'string')) {\n fail(`scope \"${name}\" extends must be an array of scope names`)\n }\n scopes[name] = { path, extends: ext as string[] }\n }\n for (const [name, entry] of Object.entries(scopes)) {\n for (const target of entry.extends) {\n if (!Object.hasOwn(scopes, target))\n fail(`scope \"${name}\" extends unknown scope \"${target}\"`)\n }\n }\n return scopes\n}\n\n/** Read and validate `<rnessDir>/rness.json`. Every error starts with `rness.json:`. */\nexport async function loadManifest(rnessDir: string): Promise<Manifest> {\n let raw: string\n try {\n raw = await readFile(join(rnessDir, 'rness.json'), 'utf8')\n } catch {\n fail('not found')\n }\n return parseManifest(raw)\n}\n\n/** Validate the text of a `rness.json`, as `loadManifest` does the file's. */\nexport function parseManifest(raw: string): Manifest {\n let data: unknown\n try {\n data = JSON.parse(raw)\n } catch (e) {\n fail(`invalid JSON (${e instanceof Error ? e.message : String(e)})`)\n }\n if (!isRecord(data)) fail('must be a JSON object')\n if (data.contract !== 1)\n fail(`unsupported contract: ${JSON.stringify(data.contract)} (expected 1)`)\n // Refuse what this contract does not define: a typo (`scope`, `repo`) or a\n // key from a later contract would otherwise be read as nothing at all.\n for (const key of Object.keys(data)) {\n if (!KEYS.includes(key)) fail(`unknown key ${JSON.stringify(key)}`)\n }\n const { boards, refused, formerKey } = readBoardsOrFormer(data)\n return {\n contract: 1,\n provider: readProvider(data.provider),\n org: readOrg(data.org),\n agents: readAgents(data.agents),\n boards,\n ...(refused.length === 0 ? {} : { refused }),\n ...(formerKey === undefined ? {} : { formerKey }),\n repos: readRepos(data.repos),\n scopes: readScopes(data.scopes),\n }\n}\n\n/** A value of `boards` as written: a number, a preset, or a board's JSON indented under its key. */\nconst boardEntry = (name: string, value: unknown): string =>\n ` ${JSON.stringify(name)}: ${JSON.stringify(value, null, 2).replaceAll('\\n', '\\n ')}`\n\nconst isScalar = (v: unknown): boolean =>\n typeof v === 'number' || typeof v === 'string'\n\n/**\n * `boards` as written, whatever key it was read from: on one line while\n * every board is a number or a preset; else each entry on its own lines, a\n * refused board kept as it was written.\n */\nfunction boardsLines(manifest: Manifest): string[] {\n const entries: (readonly [string, unknown])[] = [\n ...Object.entries(manifest.boards ?? {}).map(\n ([name, b]) =>\n [name, isScalar(b) ? b : (b as { source: unknown }).source] as const\n ),\n ...(manifest.refused ?? []).map((r) => [r.name, r.source] as const),\n ]\n if (entries.length === 0) return []\n if (entries.every(([, v]) => isScalar(v)))\n return [\n ` \"boards\": { ${entries\n .map(([name, v]) => `${JSON.stringify(name)}: ${JSON.stringify(v)}`)\n .join(', ')} },`,\n ]\n return [\n ' \"boards\": {',\n entries.map(([name, v]) => boardEntry(name, v)).join(',\\n'),\n ' },',\n ]\n}\n\n/** Serialise in the contract's key order; atomic write. */\nexport async function writeManifest(\n rnessDir: string,\n manifest: Manifest\n): Promise<void> {\n const repos = Object.entries(manifest.repos).map(\n ([name, r]) =>\n ` ${JSON.stringify(name)}: { \"url\": ${JSON.stringify(r.url)} }`\n )\n const scopes = Object.entries(manifest.scopes).map(([name, s]) => {\n const ext =\n s.extends.length === 0\n ? ''\n : `, \"extends\": [${s.extends.map((e) => JSON.stringify(e)).join(', ')}]`\n return ` ${JSON.stringify(name)}: { \"path\": ${JSON.stringify(s.path)}${ext} }`\n })\n const lines = ['{', ' \"contract\": 1,']\n if (manifest.provider !== null)\n lines.push(` \"provider\": ${JSON.stringify(manifest.provider)},`)\n if (manifest.org !== null)\n lines.push(` \"org\": ${JSON.stringify(manifest.org)},`)\n if (manifest.agents !== null)\n lines.push(\n ` \"agents\": [${manifest.agents.map((a) => JSON.stringify(a)).join(', ')}],`\n )\n lines.push(...boardsLines(manifest))\n lines.push(\n ' \"repos\": {',\n repos.join(',\\n'),\n ' },',\n ' \"scopes\": {',\n scopes.join(',\\n'),\n ' }',\n '}'\n )\n const text = `${lines.filter((l) => l !== '').join('\\n')}\\n`\n await writeFileAtomic(join(rnessDir, 'rness.json'), text)\n}\n\nconst FULL_URL = /^(https?:\\/\\/|git@|ssh:\\/\\/|file:\\/\\/)/\n\n/** `web` → `<host><org>/web.git`; `other/api` → `<host>other/api.git`; a full URL is kept. */\nexport function parseRepoSpec(\n spec: string,\n org: string | null,\n host: string\n): { name: string; url: string } {\n let url: string\n if (FULL_URL.test(spec)) {\n url = spec\n } else {\n const parts = spec.split('/')\n if (parts.length === 1) {\n // A blank workspace has no owner to expand a bare name with (spec 0012).\n if (org === null)\n throw new Error(\n 'this workspace has no GitHub organization: give <owner>/<repo> or a git URL'\n )\n url = repoUrl(host, org, spec)\n } else if (\n parts.length === 2 &&\n parts[0] !== undefined &&\n parts[1] !== undefined\n )\n url = repoUrl(host, parts[0], parts[1])\n else\n throw new Error(\n `repository name \"${spec}\" is not a name (use <repo>, <owner>/<repo>, or a URL)`\n )\n }\n const last = url.replace(/\\/+$/, '').split(/[/:]/).at(-1) ?? ''\n const name = last.endsWith('.git') ? last.slice(0, -4) : last\n if (!NAME.test(name))\n throw new Error(`repository name \"${name}\" may only contain ${NAME_RULE}`)\n return { name, url }\n}\n","// Single source of the package version. test/version.test.ts keeps it equal\n// to package.json; bump both together.\nexport const VERSION = '0.22.1'\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst execFileP = promisify(execFile)\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun'\nexport const PACKAGE_MANAGERS: readonly PackageManager[] = [\n 'npm',\n 'pnpm',\n 'yarn',\n 'bun',\n]\n\nexport function isPackageManager(value: string): value is PackageManager {\n return (PACKAGE_MANAGERS as readonly string[]).includes(value)\n}\n\n/** The manager that launched us (`npm_config_user_agent`: `pnpm/12.2.1 npm/? node/…`), else npm. */\nexport function detectPackageManager(\n userAgent: string = process.env['npm_config_user_agent'] ?? ''\n): PackageManager {\n const name = userAgent.split('/')[0] ?? ''\n return isPackageManager(name) ? name : 'npm'\n}\n\nfunction firstLine(text: string): string {\n return (\n text\n .split('\\n')\n .find((l) => l.trim() !== '')\n ?.trim() ?? 'unknown error'\n )\n}\n\nexport async function packageManagerVersion(\n pm: PackageManager\n): Promise<string> {\n try {\n const { stdout } = await execFileP(pm, ['--version'])\n return stdout.trim()\n } catch (e) {\n throw new Error(`${pm} is not available on PATH`, { cause: e })\n }\n}\n\n/**\n * The rness CLI run through `pm`, without a global install: what the next\n * steps of `create` are written with, so they work on the machine that ran it.\n * Inside a workspace the fetched copy hands over to the pinned one. Yarn 1 has\n * no `dlx`, and an unknown yarn may be one: npx comes with Node.\n */\nexport function rnessRunner(\n pm: PackageManager,\n version: string | null\n): string {\n if (pm === 'pnpm') return 'pnpm dlx @rness/cli'\n if (pm === 'bun') return 'bunx @rness/cli'\n if (pm === 'yarn' && Number(version?.split('.')[0]) >= 2)\n return 'yarn dlx @rness/cli'\n return 'npx @rness/cli'\n}\n\n/**\n * How `pm` runs a binary its own install put in `node_modules/.bin`,\n * without the network: what a developer types inside `.rness` (spec 0019\n * §5). Unlike `rnessRunner`, nothing is fetched.\n */\nexport function localRunner(pm: PackageManager): string {\n if (pm === 'pnpm') return 'pnpm'\n if (pm === 'yarn') return 'yarn'\n if (pm === 'bun') return 'bunx'\n return 'npx'\n}\n\n/**\n * The rness command as the user can type it again, for every hint and next\n * step: launched through a package manager — npx, pnpm dlx, yarn dlx, bunx,\n * `pnpm create`, a package script, which all set `npm_config_user_agent` —\n * that manager's runner; else the `rness` they typed, a global install.\n */\nexport function rnessCommand(env: NodeJS.ProcessEnv = process.env): string {\n const agent = env['npm_config_user_agent'] ?? ''\n if (agent === '') return 'rness'\n const pm = detectPackageManager(agent)\n const [name, version] = (agent.split(' ')[0] ?? '').split('/')\n return rnessRunner(pm, name === pm ? (version ?? null) : null)\n}\n\nconst BARE_NPM_CODE = /^npm (error|ERR!) code \\S+$/\n\n/**\n * The line of a failed install worth showing. npm leads with its error code\n * (`npm error code ETARGET`) and says what is wrong on the next line\n * (`…No matching version found for @rness/cli@0.4.0.`): that one is kept. The\n * code is shown only when nothing follows it.\n */\nexport function installErrorLine(stderr: string): string {\n const lines = stderr\n .split('\\n')\n .map((l) => l.trim())\n .filter((l) => l !== '')\n return lines.find((l) => !BARE_NPM_CODE.test(l)) ?? firstLine(stderr)\n}\n\nconst FROZEN: Record<PackageManager, readonly string[]> = {\n npm: ['ci'],\n pnpm: ['install', '--frozen-lockfile'],\n yarn: ['install', '--immutable'],\n bun: ['install', '--frozen-lockfile'],\n}\n\n/** The install that refuses to touch a committed lockfile (spec 0008 §4). */\nexport function frozenArgs(pm: PackageManager): string[] {\n return [...FROZEN[pm]]\n}\n\n/** `<pm> install` in `dir`; output is swallowed, failure is one line. */\nexport async function installDependencies(\n pm: PackageManager,\n dir: string,\n opts: { frozen?: boolean } = {}\n): Promise<void> {\n const args = opts.frozen === true ? frozenArgs(pm) : ['install']\n try {\n await execFileP(pm, args, { cwd: dir, maxBuffer: 16 * 1024 * 1024 })\n } catch (e) {\n const err = e as { stderr?: string; message: string }\n throw new Error(\n `${pm} ${args.join(' ')} failed in ${dir}: ${installErrorLine(err.stderr ?? err.message)}`,\n { cause: e }\n )\n }\n}\n","import { readdir } from 'node:fs/promises'\nimport { join, posix } from 'node:path'\n\nimport { collectMarkdown } from './collect.ts'\nimport { assembleContext } from './context.ts'\nimport { documentDate, documentNumber, documentTitle } from './documents.ts'\nimport { parseFrontMatter } from './frontmatter.ts'\nimport type { Manifest, MarkdownItem, Workspace } from './types.ts'\n\n/** One document of a tab (spec 0016 §2.1). */\nexport interface StatusRow {\n /** `NNNN`, else `YYYY-MM-DD`, else the file name. */\n id: string\n title: string\n /** As written; null when missing or when the front matter does not parse. */\n status: string | null\n /** Relative to `.rness/`. */\n path: string\n /**\n * The Claude Code sessions that wrote or changed it, oldest first, each\n * once (spec 0020 §3.1, 0022 §3); absent when it records none.\n */\n sessions?: SessionEntry[]\n}\n\n/** A session in `sessions:`: its id, and the agent it ran as when recorded. */\nexport interface SessionEntry {\n id: string\n agent?: string\n}\n\nexport interface StatusTab {\n /** The directory. */\n name: string\n label: string\n rows: StatusRow[]\n}\n\n/** The contract's collections that carry a status: always shown. */\nconst FIXED: readonly (readonly [string, string])[] = [\n ['adr', 'ADR'],\n ['specs', 'Specs'],\n ['plans', 'Plans'],\n]\n/** Never a discovered tab: the fixed ones, the contract's other collections, dependencies. */\nconst NOT_DISCOVERED: ReadonlySet<string> = new Set([\n ...FIXED.map(([name]) => name),\n 'standards',\n 'skills',\n 'node_modules',\n])\nconst TEMPLATE = 'adr/0000-template.md'\n\nfunction statusOf(item: MarkdownItem): string | null {\n const status = item.fields?.['status']\n return typeof status === 'string' && status !== '' ? status : null\n}\n\n/**\n * `sessions:` as its entries: `{ id, agent }`, or a bare id as 0.15 wrote\n * it. Anything else is left out, and an id listed twice keeps its first\n * entry (spec 0022 §3).\n */\nfunction sessionsOf(item: MarkdownItem): SessionEntry[] {\n const listed = item.fields?.['sessions']\n if (!Array.isArray(listed)) return []\n const entries = new Map<string, SessionEntry>()\n for (const entry of listed) {\n const fields =\n typeof entry === 'string'\n ? { id: entry }\n : entry !== null && typeof entry === 'object'\n ? (entry as Record<string, unknown>)\n : {}\n const { id, agent } = fields\n if (typeof id !== 'string' || id === '' || entries.has(id)) continue\n entries.set(\n id,\n typeof agent === 'string' && agent !== '' ? { id, agent } : { id }\n )\n }\n return [...entries.values()]\n}\n\nfunction rowOf(dir: string, item: MarkdownItem): StatusRow {\n const base = posix.basename(item.rel, '.md')\n const date = documentDate(item.rel)\n const number = documentNumber(item.rel)\n const sessions = sessionsOf(item)\n return {\n id: date ?? number ?? base,\n title: documentTitle(item.title ?? base, number),\n status: statusOf(item),\n path: `${dir}/${item.rel}`,\n ...(sessions.length > 0 ? { sessions } : {}),\n }\n}\n\n/** Newest first: file names descending, then paths. */\nfunction newestFirst(a: StatusRow, b: StatusRow): number {\n const [x, y] = [posix.basename(a.path), posix.basename(b.path)]\n if (x !== y) return x < y ? 1 : -1\n return a.path < b.path ? 1 : a.path > b.path ? -1 : 0\n}\n\n/**\n * The tabs of `rness status` (spec 0016 §2.1): ADR, Specs and Plans, then\n * every other top-level directory of `.rness/` holding a Markdown file\n * whose front matter has a status — alphabetically, with those files only.\n */\nexport async function statusTabs(rnessDir: string): Promise<StatusTab[]> {\n const tabs: StatusTab[] = []\n for (const [name, label] of FIXED) {\n const rows = (await collectMarkdown(join(rnessDir, name)))\n .map((item) => rowOf(name, item))\n .filter((row) => row.path !== TEMPLATE)\n tabs.push({ name, label, rows: rows.sort(newestFirst) })\n }\n const entries = await readdir(rnessDir, { withFileTypes: true }).catch(\n () => []\n )\n const discovered = entries\n .filter(\n (e) =>\n e.isDirectory() &&\n !e.name.startsWith('.') &&\n !NOT_DISCOVERED.has(e.name)\n )\n .map((e) => e.name)\n .sort()\n for (const name of discovered) {\n const rows = (await collectMarkdown(join(rnessDir, name)))\n .filter((item) => statusOf(item) !== null)\n .map((item) => rowOf(name, item))\n if (rows.length > 0)\n tabs.push({\n name,\n label: `${name.charAt(0).toUpperCase()}${name.slice(1)}`,\n rows: rows.sort(newestFirst),\n })\n }\n return tabs\n}\n\n/** A tab by its name or label, whatever the case. */\nexport function findTab(\n tabs: readonly StatusTab[],\n wanted: string\n): StatusTab | undefined {\n const w = wanted.toLowerCase()\n return tabs.find(\n (tab) => tab.name.toLowerCase() === w || tab.label.toLowerCase() === w\n )\n}\n\nexport type StatusTone = 'done' | 'dropped' | 'missing' | 'active'\n\nconst DONE: ReadonlySet<string> = new Set([\n 'accepted',\n 'implemented',\n 'completed',\n 'published',\n])\nconst DROPPED: ReadonlySet<string> = new Set([\n 'rejected',\n 'superseded',\n 'abandoned',\n])\n\n/** What a status says at a glance (spec 0016 §2.1), whatever its case. */\nexport function statusTone(status: string | null): StatusTone {\n if (status === null) return 'missing'\n const s = status.toLowerCase()\n if (DONE.has(s)) return 'done'\n if (DROPPED.has(s)) return 'dropped'\n return 'active'\n}\n\nconst cell = (text: string): string => text.replaceAll('|', '\\\\|')\n\n/** The tabs as Markdown, off a terminal (spec 0016 §2.3). */\nexport function statusMarkdown(\n workspace: string,\n tabs: readonly StatusTab[]\n): string {\n const out = [`${workspace} · status`, '']\n for (const tab of tabs) {\n out.push(`## ${tab.label} (${tab.rows.length})`, '')\n if (tab.rows.length === 0) {\n out.push('_Nothing yet._', '')\n continue\n }\n out.push('| Id | Title | Status |', '| --- | --- | --- |')\n for (const row of tab.rows)\n out.push(\n `| ${cell(row.id)} | ${cell(row.title)} | ${cell(row.status ?? '?')} |`\n )\n out.push('')\n }\n return out.join('\\n')\n}\n\n/** The plans of the scope whose status is In progress, as `.rness/`-relative paths. */\nexport async function plansInProgress(\n ws: Workspace,\n manifest: Manifest,\n scope: string | null\n): Promise<string[]> {\n return documentsIn(ws, manifest, scope, ['plans'], ['In progress'])\n}\n\n/**\n * The documents of `collections` whose status is one of `statuses`, as\n * `.rness/`-relative paths: of the scope for a collection of the contract\n * (`adr`, `specs`, `plans`), which scopes apply to; every one for another\n * directory, which no scope divides.\n */\nexport async function documentsIn(\n ws: Workspace,\n manifest: Manifest,\n scope: string | null,\n collections: readonly string[],\n statuses: readonly string[]\n): Promise<string[]> {\n const context = await assembleContext({\n rnessDir: ws.rnessDir,\n manifest,\n scope,\n })\n const paths: string[] = []\n const contract = context.collections.map((c) => c.name as string)\n for (const name of collections) {\n const scoped = context.collections.find((c) => c.name === name)\n if (scoped !== undefined) {\n for (const f of scoped.files)\n try {\n const status = parseFrontMatter(f.body)?.['status']\n if (typeof status === 'string' && statuses.includes(status))\n paths.push(`${name}/${f.rel}`)\n } catch {\n // A front matter that does not parse is no status.\n }\n continue\n }\n if (contract.includes(name)) continue\n const tab = (await statusTabs(ws.rnessDir)).find((t) => t.name === name)\n for (const row of tab?.rows ?? [])\n if (row.status !== null && statuses.includes(row.status))\n paths.push(row.path)\n }\n return paths\n}\n","/**\n * Where the boards live on GitHub (spec 0017 §2, 0018 §3): the board, one\n * item of it, a document and an issue of `.rness`. Strings only: nothing\n * here reaches GitHub.\n */\n\nexport const boardUrl = (org: string, project: number): string =>\n `https://github.com/orgs/${org}/projects/${project}`\n\n/**\n * The board filtered on one document, by its `Path` field: the one item.\n * `filterQuery` is the board's own query parameter (verified 2026-10-05).\n */\nexport const itemUrl = (org: string, project: number, path: string): string =>\n `${boardUrl(org, project)}?filterQuery=${encodeURIComponent(`path:\"${path}\"`)}`\n\nexport const blobUrl = (org: string, path: string): string =>\n `https://github.com/${org}/.rness/blob/main/${encodeURI(path)}`\n\nexport const issueUrl = (org: string, number: number): string =>\n `https://github.com/${org}/.rness/issues/${number}`\n","import { setTimeout as delay } from 'node:timers/promises'\n\nimport { rnessCommand } from './pm.ts'\n\n/** The public GitHub REST API; `--github-api` overrides it in tests. */\nexport const DEFAULT_GITHUB_API = 'https://api.github.com'\n\n/** Guards against a server that always answers `rel=\"next\"`. */\nexport const MAX_PAGES = 50\nexport const PER_PAGE = 100\n\nconst addLater = (): string =>\n `; add repositories later with ${rnessCommand()} add <repo>`\n\nexport interface OrgRepository {\n name: string\n private: boolean\n archived: boolean\n}\n\nexport interface RepositoryListing {\n repositories: OrgRepository[]\n /**\n * Which endpoint answered. `/users/<name>/repos` lists a personal account's\n * public repositories only, whatever the token; `self` is `/user/repos`, the\n * logged-in user's own account, private repositories included.\n */\n owner: 'org' | 'user' | 'self'\n /** `MAX_PAGES` stopped the listing while GitHub still announced a next page. */\n truncated: boolean\n}\n\nexport interface ListRepositoriesOptions {\n /** Sent as `Authorization: Bearer <token>` when given; without it only public repositories are listed. */\n token?: string | undefined\n apiBase?: string\n /** Per request. */\n timeoutMs?: number\n /**\n * The login the token belongs to, asked only when `owner` turns out not to\n * be an organization: its own account is listed through `/user/repos`.\n */\n self?: () => Promise<string | null>\n}\n\nconst NEXT = /<[^>]*>\\s*;\\s*rel=\"next\"/\n\nfunction isRepository(value: unknown): value is OrgRepository {\n if (value === null || typeof value !== 'object') return false\n const r = value as Record<string, unknown>\n return (\n typeof r['name'] === 'string' &&\n typeof r['private'] === 'boolean' &&\n typeof r['archived'] === 'boolean'\n )\n}\n\nfunction reason(e: unknown): string {\n // undici reports every network failure as `TypeError: fetch failed`; the\n // useful part (ECONNREFUSED, ENOTFOUND, …) is its cause.\n if (e instanceof Error && e.cause instanceof Error) return e.cause.message\n return e instanceof Error ? e.message : String(e)\n}\n\ninterface Page {\n status: number\n headers: Headers\n body: unknown\n}\n\n/**\n * GitHub's own words, relayed as they came: the `message` of a refusal, a\n * GraphQL error. The boards name them as GitHub's; rness's own errors are\n * plain `Error`s and keep their words.\n */\nexport class GitHubMessageError extends Error {}\n\nasync function getPage(\n url: string,\n headers: Record<string, string>,\n timeoutMs: number,\n init: { method?: string; body?: string; errorBody?: boolean } = {}\n): Promise<Page> {\n const { errorBody, ...request } = init\n const signal = AbortSignal.timeout(timeoutMs)\n let res: Response\n try {\n res = await fetch(url, { headers, signal, ...request })\n } catch (e) {\n throw new Error(`cannot reach the GitHub API: ${reason(e)}`, { cause: e })\n }\n if (!res.ok) {\n if (errorBody === true) {\n const parsed: unknown = await res.json().catch(() => undefined)\n return { status: res.status, headers: res.headers, body: parsed }\n }\n // Drain the body so the connection is released; its content is not used.\n await res.body?.cancel().catch(() => undefined)\n return { status: res.status, headers: res.headers, body: undefined }\n }\n let text: string\n try {\n text = await res.text()\n } catch (e) {\n throw new Error(`cannot reach the GitHub API: ${reason(e)}`, { cause: e })\n }\n try {\n return { status: res.status, headers: res.headers, body: JSON.parse(text) }\n } catch (e) {\n throw new Error(\n `GitHub API answered invalid JSON for ${new URL(url).pathname}`,\n { cause: e }\n )\n }\n}\n\nexport function httpError(page: Page, path: string): Error {\n const cause = { status: page.status, path }\n if (page.status === 401)\n return new Error('GitHub rejected the token (401)', { cause })\n // GitHub signals a primary rate limit with 403 and no remaining requests,\n // a secondary one with 403 or 429 and `retry-after`.\n if (\n page.status === 429 ||\n (page.status === 403 &&\n (page.headers.get('x-ratelimit-remaining') === '0' ||\n page.headers.has('retry-after')))\n ) {\n return new Error(\n `GitHub API rate limit reached; set GITHUB_TOKEN or add repositories later with ${rnessCommand()} add`,\n { cause }\n )\n }\n return new Error(\n `GitHub API answered ${page.status} for ${path}${addLater()}`,\n { cause }\n )\n}\n\n/**\n * Every repository of the organization `owner` — or, when GitHub knows no\n * such organization, the public ones of the personal account — following the\n * `Link` header page by page, up to `MAX_PAGES`. Errors are one line, each\n * with its `cause`.\n */\nexport async function listRepositories(\n owner: string,\n options: ListRepositoriesOptions\n): Promise<RepositoryListing> {\n const base = (options.apiBase ?? DEFAULT_GITHUB_API).replace(/\\/+$/, '')\n const timeoutMs = options.timeoutMs ?? 15_000\n const headers: Record<string, string> = {\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'User-Agent': 'rness-cli',\n }\n if (options.token !== undefined && options.token !== '')\n headers['Authorization'] = `Bearer ${options.token}`\n\n const encoded = encodeURIComponent(owner)\n interface Kind {\n path: string\n query: string\n owner: RepositoryListing['owner']\n }\n const ORG: Kind = {\n path: `/orgs/${encoded}/repos`,\n query: 'type=all',\n owner: 'org',\n }\n const USER: Kind = {\n path: `/users/${encoded}/repos`,\n query: 'type=owner',\n owner: 'user',\n }\n const SELF: Kind = {\n path: '/user/repos',\n query: 'affiliation=owner',\n owner: 'self',\n }\n const url = (k: Kind, n: number): string =>\n `${base}${k.path}?${k.query}&per_page=${PER_PAGE}&page=${n}`\n let kind: Kind = ORG\n const repositories: OrgRepository[] = []\n for (let n = 1; n <= MAX_PAGES; n++) {\n let page = await getPage(url(kind, n), headers, timeoutMs)\n if (n === 1 && page.status === 404) {\n // Not an organization: a personal account answers on /users instead.\n const self = (await options.self?.()) ?? null\n kind = self?.toLowerCase() === owner.toLowerCase() ? SELF : USER\n page = await getPage(url(kind, n), headers, timeoutMs)\n if (page.status === 404) {\n throw new Error(\n `GitHub has no organization or user named \"${owner}\" (or it is not visible to you)${addLater()}`,\n { cause: { status: 404, path: kind.path } }\n )\n }\n }\n if (page.status < 200 || page.status >= 300)\n throw httpError(page, kind.path)\n if (!Array.isArray(page.body) || !page.body.every(isRepository)) {\n throw new Error(\n `GitHub API answered an unexpected body for ${kind.path}`,\n {\n cause: page.body,\n }\n )\n }\n for (const r of page.body)\n repositories.push({\n name: r.name,\n private: r.private,\n archived: r.archived,\n })\n if (!NEXT.test(page.headers.get('link') ?? ''))\n return {\n repositories,\n owner: kind.owner,\n truncated: false,\n }\n }\n return {\n repositories,\n owner: kind.owner,\n truncated: true,\n }\n}\n\n/** What rness waits in all, per process, on GitHub's rate limits (spec 0018 §4). */\nexport const WAIT_BUDGET_MS = 600_000\n/** GitHub's advice when a rate limit names no time. */\nconst DEFAULT_WAIT_MS = 60_000\n/** A wait is never shorter: a server answering `retry-after: 0` cannot make rness spin. */\nconst MIN_WAIT_MS = 1_000\nexport const RATE_LIMIT_OUTLASTED =\n \"GitHub's rate limit outlasted the 10 minutes rness waits\"\n\n/** How rness waits on a rate limit: the budget left, a clock, a sleep (tests inject them). */\nexport interface RateWait {\n left: number\n now(): number\n sleep(ms: number): Promise<void>\n}\n\nexport function rateWait(\n sleep: (ms: number) => Promise<void> = (ms) => delay(ms)\n): RateWait {\n return { left: WAIT_BUDGET_MS, now: () => Date.now(), sleep }\n}\n\n/** The wait of a process that was given none: one budget for all its requests. */\nconst PROCESS_WAIT = rateWait()\n\n/** The budget cannot cover what GitHub asks. */\nexport class RateLimitError extends Error {}\n\nconst messageOf = (body: unknown): string => {\n const m =\n body !== null && typeof body === 'object'\n ? (body as Record<string, unknown>)['message']\n : undefined\n return typeof m === 'string' ? m : ''\n}\n\n/**\n * How long GitHub asks to wait before the same request, in ms, or null when\n * the answer is no rate limit. A limit is a 429; a 403 with `retry-after`,\n * no request left, or \"rate limit\" in its message; or `limited`, a 200\n * whose GraphQL errors say RATE_LIMITED. The wait is `retry-after`, else\n * the reset of a spent primary limit, else a minute (docs.github.com, \"Rate\n * limits for the REST API\" and \"... for the GraphQL API\", read 2026-09-30).\n */\nexport function rateDelay(\n page: { status: number; headers: Headers; body: unknown },\n now: number,\n limited = false\n): number | null {\n const h = page.headers\n const spent = h.get('x-ratelimit-remaining') === '0'\n const hit =\n limited ||\n page.status === 429 ||\n (page.status === 403 &&\n (h.has('retry-after') ||\n spent ||\n /rate limit/i.test(messageOf(page.body))))\n if (!hit) return null\n const after = (h.get('retry-after') ?? '').trim()\n if (/^\\d+$/.test(after)) return Number(after) * 1000\n const reset = (h.get('x-ratelimit-reset') ?? '').trim()\n if (spent && /^\\d+$/.test(reset))\n return Math.max(0, Number(reset) * 1000 - now)\n return DEFAULT_WAIT_MS\n}\n\n/** Sleeps `ms` (a second at least) out of the budget, or throws when the budget cannot cover it. */\nexport async function waitOut(options: ApiOptions, ms: number): Promise<void> {\n const wait = options.wait ?? PROCESS_WAIT\n const spent = Math.max(ms, MIN_WAIT_MS)\n if (spent > wait.left) throw new RateLimitError(RATE_LIMIT_OUTLASTED)\n wait.left -= spent\n await wait.sleep(spent)\n}\n\nexport interface ApiOptions {\n token: string\n apiBase?: string\n timeoutMs?: number\n /** Rate-limit waits; default: this process's. */\n wait?: RateWait\n}\n\nfunction apiHeaders(token: string): Record<string, string> {\n return {\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'User-Agent': 'rness-cli',\n Authorization: `Bearer ${token}`,\n }\n}\n\n/** One authenticated GET whose error body is kept: GitHub explains a 403 there. */\nasync function getJson(\n path: string,\n options: ApiOptions\n): Promise<{ status: number; body: unknown }> {\n const base = (options.apiBase ?? DEFAULT_GITHUB_API).replace(/\\/+$/, '')\n let res: Response\n try {\n res = await fetch(`${base}${path}`, {\n headers: apiHeaders(options.token),\n signal: AbortSignal.timeout(options.timeoutMs ?? 15_000),\n })\n } catch (e) {\n throw new Error(`cannot reach the GitHub API: ${reason(e)}`, { cause: e })\n }\n const body: unknown = await res.json().catch(() => undefined)\n return { status: res.status, body }\n}\n\n/**\n * One authenticated JSON POST; a non-ok answer becomes `httpError`, the\n * parsed body of an ok one is returned (`undefined` when it is empty). A rate\n * limit is waited out of the process's budget and the request sent again.\n */\nexport async function postJson(\n path: string,\n payload: unknown,\n options: ApiOptions,\n /** Show GitHub's own `message` when it refuses (the Projects client); 401 and 429 keep `httpError`'s words. */\n explain = false,\n /** An answer of 200 that is a rate limit all the same (GraphQL's RATE_LIMITED). */\n limited: (body: unknown) => boolean = () => false\n): Promise<unknown> {\n const base = (options.apiBase ?? DEFAULT_GITHUB_API).replace(/\\/+$/, '')\n const clock = options.wait ?? PROCESS_WAIT\n for (;;) {\n const page = await getPage(\n `${base}${path}`,\n { ...apiHeaders(options.token), 'Content-Type': 'application/json' },\n options.timeoutMs ?? 15_000,\n // A refusal's body says whether it is a rate limit. A timeout throws\n // above and is never retried: the write may have been made.\n { method: 'POST', body: JSON.stringify(payload), errorBody: true }\n )\n const ok = page.status >= 200 && page.status < 300\n const wait = rateDelay(page, clock.now(), ok && limited(page.body))\n if (wait !== null) {\n await waitOut(options, wait)\n continue\n }\n if (!ok) {\n const message =\n explain &&\n page.status !== 401 &&\n page.status !== 429 &&\n page.body !== null &&\n typeof page.body === 'object'\n ? (page.body as { message?: unknown }).message\n : undefined\n if (typeof message === 'string' && message !== '')\n throw new GitHubMessageError(message, {\n cause: { status: page.status, path },\n })\n throw httpError(page, path)\n }\n return page.body\n }\n}\n\n/**\n * The scopes of a classic or OAuth token: `X-OAuth-Scopes` of GET /user,\n * split on \", \". Null when the header is absent (a fine-grained or App\n * token). Throws when GitHub cannot be asked, so that no one mistakes it for\n * a missing scope: `cannot reach GitHub: <why>`, the 401 line, or GitHub's\n * own message.\n */\nexport async function getScopes(options: ApiOptions): Promise<string[] | null> {\n const base = (options.apiBase ?? DEFAULT_GITHUB_API).replace(/\\/+$/, '')\n let res: Response\n try {\n res = await fetch(`${base}/user`, {\n headers: apiHeaders(options.token),\n signal: AbortSignal.timeout(options.timeoutMs ?? 15_000),\n })\n } catch (e) {\n throw new Error(`cannot reach GitHub: ${reason(e)}`, { cause: e })\n }\n const body: unknown = await res.json().catch(() => undefined)\n if (res.status !== 200) {\n const cause = { status: res.status, path: '/user' }\n if (res.status === 401)\n throw new Error('GitHub rejected the token (401)', { cause })\n const message =\n body !== null && typeof body === 'object'\n ? (body as Record<string, unknown>)['message']\n : undefined\n if (typeof message === 'string' && message !== '')\n throw new GitHubMessageError(message, { cause })\n throw new Error(`GitHub API answered ${res.status} for /user`, { cause })\n }\n const header = res.headers.get('x-oauth-scopes')\n if (header === null) return null\n return header\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s !== '')\n}\n\n/** The login a token belongs to. */\nexport async function getUser(options: ApiOptions): Promise<{ login: string }> {\n const { status, body } = await getJson('/user', options)\n if (status === 401) throw new Error('GitHub rejected the token (401)')\n const login =\n body !== null && typeof body === 'object'\n ? (body as Record<string, unknown>)['login']\n : undefined\n if (status !== 200 || typeof login !== 'string')\n throw new Error(`GitHub API answered ${status} for /user`)\n return { login }\n}\n\nexport interface UserMembership {\n login: string\n /** `admin` is an owner. */\n role: string\n}\n\n/**\n * The organizations the token's user is an active member of (`read:org`),\n * with the user's role, first page of 100. An organization that restricts\n * OAuth apps and has not approved this one is not in the answer.\n */\nexport async function listUserMemberships(\n options: ApiOptions\n): Promise<UserMembership[]> {\n const { status, body } = await getJson(\n `/user/memberships/orgs?state=active&per_page=${PER_PAGE}`,\n options\n )\n if (status !== 200 || !Array.isArray(body))\n throw new Error(`GitHub API answered ${status} for /user/memberships/orgs`)\n const memberships: UserMembership[] = []\n for (const m of body as unknown[]) {\n if (m === null || typeof m !== 'object') continue\n const entry = m as Record<string, unknown>\n const org = entry['organization']\n const login =\n org !== null && typeof org === 'object'\n ? (org as Record<string, unknown>)['login']\n : undefined\n if (typeof login !== 'string' || entry['state'] !== 'active') continue\n memberships.push({\n login,\n role: typeof entry['role'] === 'string' ? entry['role'] : '',\n })\n }\n return memberships\n}\n\nexport type OrgMembership = 'member' | 'not-member' | 'restricted' | 'unknown'\n\n/**\n * The user's standing in `org`. `restricted`: the organization limits OAuth\n * apps and has not approved this one, so its private repositories are hidden\n * from the token — GitHub says so in the body of a 403.\n */\nexport async function getOrgMembership(\n org: string,\n options: ApiOptions\n): Promise<OrgMembership> {\n const { status, body } = await getJson(\n `/user/memberships/orgs/${encodeURIComponent(org)}`,\n options\n )\n if (status === 200) {\n const state =\n body !== null && typeof body === 'object'\n ? (body as Record<string, unknown>)['state']\n : undefined\n return state === 'active' ? 'member' : 'not-member'\n }\n if (status === 404) return 'not-member'\n if (status === 403) {\n const message =\n body !== null && typeof body === 'object'\n ? String((body as Record<string, unknown>)['message'] ?? '')\n : ''\n if (/OAuth App access restrictions/i.test(message)) return 'restricted'\n }\n return 'unknown'\n}\n\nexport type CreateRepositoryResult =\n | { kind: 'created' }\n /** GitHub said the name is taken (422). */\n | { kind: 'exists' }\n /** Not allowed, in GitHub's words. */\n | { kind: 'refused'; reason: string }\n\n/**\n * Create the private repository `owner/name`: in the organization `owner`,\n * or — when GitHub knows no such organization and `owner` is the token's own\n * account (`self`) — under the user.\n */\nexport async function createRepository(\n owner: string,\n name: string,\n options: ApiOptions & { self?: string | null }\n): Promise<CreateRepositoryResult> {\n const base = (options.apiBase ?? DEFAULT_GITHUB_API).replace(/\\/+$/, '')\n const post = async (\n path: string\n ): Promise<{ status: number; message: string }> => {\n let res: Response\n try {\n res = await fetch(`${base}${path}`, {\n method: 'POST',\n headers: {\n ...apiHeaders(options.token),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ name, private: true }),\n signal: AbortSignal.timeout(options.timeoutMs ?? 15_000),\n })\n } catch (e) {\n throw new Error(`cannot reach the GitHub API: ${reason(e)}`, { cause: e })\n }\n const body: unknown = await res.json().catch(() => undefined)\n const message =\n body !== null && typeof body === 'object'\n ? String((body as Record<string, unknown>)['message'] ?? '')\n : ''\n return { status: res.status, message }\n }\n let answer = await post(`/orgs/${encodeURIComponent(owner)}/repos`)\n if (\n answer.status === 404 &&\n options.self !== undefined &&\n options.self !== null &&\n options.self.toLowerCase() === owner.toLowerCase()\n )\n answer = await post('/user/repos')\n if (answer.status === 201) return { kind: 'created' }\n if (answer.status === 422) return { kind: 'exists' }\n return {\n kind: 'refused',\n reason:\n answer.message === ''\n ? `GitHub answered ${answer.status}`\n : `${answer.message} (${answer.status})`,\n }\n}\n","import { type ApiOptions, GitHubMessageError, postJson } from './github.ts'\n\n/**\n * GitHub Projects (v2) over HTTP: GraphQL for projects, fields and items,\n * REST for views. No business logic; errors carry GitHub's own message.\n */\n\ninterface GraphqlAnswer<T> {\n data?: T\n errors?: { message?: string; type?: string }[]\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object'\n}\n\n/** GitHub's GraphQL answers a spent budget with 200 and an error of this type. */\nconst rateLimited = (body: unknown): boolean =>\n isRecord(body) &&\n Array.isArray(body['errors']) &&\n body['errors'].some(\n (e: unknown) => isRecord(e) && e['type'] === 'RATE_LIMITED'\n )\n\nasync function graphqlRaw<T>(\n query: string,\n variables: Record<string, unknown>,\n options: ApiOptions\n): Promise<GraphqlAnswer<T>> {\n const body = await postJson(\n '/graphql',\n { query, variables },\n options,\n true,\n rateLimited\n )\n return isRecord(body) ? (body as GraphqlAnswer<T>) : {}\n}\n\nfunction firstError(answer: GraphqlAnswer<unknown>): Error | null {\n const first = answer.errors?.[0]\n return first === undefined\n ? null\n : new GitHubMessageError(first.message ?? 'GitHub GraphQL error')\n}\n\nexport async function graphql<T>(\n query: string,\n variables: Record<string, unknown>,\n options: ApiOptions\n): Promise<T> {\n const answer = await graphqlRaw<T>(query, variables, options)\n const error = firstError(answer)\n if (error !== null) throw error\n if (answer.data === undefined)\n throw new Error('GitHub GraphQL answered without data')\n return answer.data\n}\n\n/** As `graphql`, but null when every error is NOT_FOUND: an unknown repository is no failure. */\nexport async function graphqlFound<T>(\n query: string,\n variables: Record<string, unknown>,\n options: ApiOptions\n): Promise<T | null> {\n const answer = await graphqlRaw<T>(query, variables, options)\n const errors = answer.errors ?? []\n if (errors.length > 0 && errors.every((e) => e.type === 'NOT_FOUND'))\n return null\n const error = firstError(answer)\n if (error !== null) throw error\n return answer.data ?? null\n}\n\nexport async function orgId(org: string, o: ApiOptions): Promise<string> {\n const d = await graphql<{ organization: { id: string } | null }>(\n 'query($login: String!) { organization(login: $login) { id } }',\n { login: org },\n o\n )\n if (d.organization === null)\n throw new Error(`GitHub knows no organization ${org}`)\n return d.organization.id\n}\n\nexport async function createProject(\n ownerId: string,\n title: string,\n o: ApiOptions\n): Promise<{ id: string; number: number; url: string }> {\n const d = await graphql<{\n createProjectV2: { projectV2: { id: string; number: number; url: string } }\n }>(\n `\n mutation ($ownerId: ID!, $title: String!) {\n createProjectV2(input: { ownerId: $ownerId, title: $title }) {\n projectV2 {\n id\n number\n url\n }\n }\n }\n `,\n { ownerId, title },\n o\n )\n return d.createProjectV2.projectV2\n}\n\nexport async function findProject(\n org: string,\n number: number,\n o: ApiOptions\n): Promise<{ id: string; url: string } | null> {\n const answer = await graphqlRaw<{\n organization: { projectV2: { id: string; url: string } | null } | null\n }>(\n `query($login: String!, $number: Int!) {\n organization(login: $login) { projectV2(number: $number) { id url } }\n }`,\n { login: org, number },\n o\n )\n // An unknown project is a NOT_FOUND error, not an absent value.\n const errors = answer.errors ?? []\n if (errors.length > 0 && errors.every((e) => e.type === 'NOT_FOUND'))\n return null\n const error = firstError(answer)\n if (error !== null) throw error\n return answer.data?.organization?.projectV2 ?? null\n}\n\nexport interface Field {\n id: string\n /** The numeric id REST project views refer to fields by. */\n databaseId: number\n name: string\n /** GitHub's `ProjectV2FieldType`: `TEXT`, `SINGLE_SELECT`, `DATE`, `NUMBER`, … */\n dataType: string\n options: { id: string; name: string; color?: string }[] | null\n}\n\ninterface RawField {\n id?: string\n databaseId?: number\n name?: string\n dataType?: string\n options?: { id: string; name: string; color?: string }[]\n}\n\nfunction toField(raw: RawField): Field {\n const databaseId = raw.databaseId\n // REST views address fields by this id: a missing one must not become 0.\n if (typeof databaseId !== 'number')\n throw new Error(\n `GitHub returned the field \"${raw.name ?? raw.id ?? ''}\" without a database id`\n )\n return {\n id: raw.id ?? '',\n databaseId,\n name: raw.name ?? '',\n dataType:\n raw.dataType ??\n (raw.options === undefined || raw.options === null\n ? 'TEXT'\n : 'SINGLE_SELECT'),\n options: raw.options ?? null,\n }\n}\n\nexport async function fields(\n projectId: string,\n o: ApiOptions\n): Promise<Field[]> {\n const d = await graphql<{ node: { fields: { nodes: RawField[] } } }>(\n `\n query ($projectId: ID!) {\n node(id: $projectId) {\n ... on ProjectV2 {\n fields(first: 100) {\n nodes {\n ${FIELD_SELECTION}\n }\n }\n }\n }\n }\n `,\n { projectId },\n o\n )\n // Fragments that match no field type leave an empty node.\n return d.node.fields.nodes\n .filter((n) => n.id !== undefined)\n .map((n) => toField(n))\n}\n\n/** An option to send: `color` is a ProjectV2SingleSelectFieldOptionColor (GRAY, BLUE, …). */\nexport interface OptionInput {\n name: string\n color: string\n}\n\nconst optionInput = (o: OptionInput, id?: string) => ({\n ...(id === undefined ? {} : { id }),\n name: o.name,\n color: o.color,\n description: '',\n})\n\nconst FIELD_SELECTION = `... on ProjectV2FieldCommon { id databaseId name dataType }\n ... on ProjectV2SingleSelectField { options { id name color } }`\n\nexport async function createField(\n projectId: string,\n name: string,\n kind: 'TEXT' | 'DATE' | 'NUMBER' | { options: OptionInput[] },\n o: ApiOptions\n): Promise<Field> {\n const single = typeof kind !== 'string'\n const d = await graphql<{\n createProjectV2Field: { projectV2Field: RawField }\n }>(\n `mutation($projectId: ID!, $name: String!, $dataType: ProjectV2CustomFieldType!${\n single ? ', $options: [ProjectV2SingleSelectFieldOptionInput!]' : ''\n }) {\n createProjectV2Field(input: {\n projectId: $projectId, name: $name, dataType: $dataType${\n single ? ', singleSelectOptions: $options' : ''\n }\n }) { projectV2Field { ${FIELD_SELECTION} } }\n }`,\n {\n projectId,\n name,\n dataType: single ? 'SINGLE_SELECT' : kind,\n ...(single ? { options: kind.options.map((n) => optionInput(n)) } : {}),\n },\n o\n )\n return toField(d.createProjectV2Field.projectV2Field)\n}\n\n/** Sets a single-select field's options to `options`, resending existing ids so item values survive. */\nexport async function setOptions(\n field: Field,\n options: OptionInput[],\n o: ApiOptions\n): Promise<Field> {\n const ids = new Map((field.options ?? []).map((opt) => [opt.name, opt.id]))\n const d = await graphql<{\n updateProjectV2Field: { projectV2Field: RawField }\n }>(\n `mutation($fieldId: ID!, $options: [ProjectV2SingleSelectFieldOptionInput!]) {\n updateProjectV2Field(input: { fieldId: $fieldId, singleSelectOptions: $options }) {\n projectV2Field { ${FIELD_SELECTION} }\n }\n }`,\n {\n fieldId: field.id,\n options: options.map((n) => optionInput(n, ids.get(n.name))),\n },\n o\n )\n return toField(d.updateProjectV2Field.projectV2Field)\n}\n\n/** Renames a field in place: its id, its values and the views showing it stay (spec 0022 §2). */\nexport async function renameField(\n fieldId: string,\n name: string,\n o: ApiOptions\n): Promise<Field> {\n const d = await graphql<{\n updateProjectV2Field: { projectV2Field: RawField }\n }>(\n `mutation($fieldId: ID!, $name: String!) {\n updateProjectV2Field(input: { fieldId: $fieldId, name: $name }) {\n projectV2Field { ${FIELD_SELECTION} }\n }\n }`,\n { fieldId, name },\n o\n )\n return toField(d.updateProjectV2Field.projectV2Field)\n}\n\n/** The issue an item is (spec 0018 §2). */\nexport interface RawIssue {\n id: string\n number: number\n open: boolean\n /** `owner/name`. */\n repository: string\n /** Null: listed without bodies. */\n body: string | null\n labels: string[]\n}\n\nexport interface RawItem {\n id: string\n /** A draft's id; null for any other content. */\n draftId: string | null\n /** The issue the item is; null for a draft or other content (a pull request). */\n issue: RawIssue | null\n /** The draft's or the issue's title. */\n title: string\n archived: boolean\n /** Field name → text or option name. */\n values: Record<string, string>\n}\n\ninterface ItemNode {\n id: string\n isArchived?: boolean\n /** A draft has no `number`; content that is neither is `{}`. */\n content?: {\n id?: string\n title?: string\n number?: number\n state?: string\n body?: string\n repository?: { nameWithOwner?: string }\n labels?: { nodes: { name?: string }[] }\n } | null\n fieldValues?: {\n nodes: {\n text?: string\n name?: string\n date?: string\n number?: number\n field?: { name?: string }\n }[]\n }\n}\n\n/**\n * The project's items, archived ones included. `bodies: false` leaves the\n * issues' bodies out of the query — the heaviest part of a listing — and\n * each issue's `body` null.\n */\nexport async function listItems(\n projectId: string,\n o: ApiOptions,\n { bodies = true }: { bodies?: boolean } = {}\n): Promise<RawItem[]> {\n const items: RawItem[] = []\n let cursor: string | null = null\n for (;;) {\n const d: {\n node: {\n items: {\n nodes: ItemNode[]\n pageInfo: { hasNextPage: boolean; endCursor: string | null }\n }\n }\n } = await graphql(\n `\n query ($projectId: ID!, $cursor: String) {\n node(id: $projectId) {\n ... on ProjectV2 {\n items(first: 100, after: $cursor) {\n nodes {\n id\n isArchived\n content {\n ... on DraftIssue {\n id\n title\n }\n ... on Issue {\n id\n number\n title\n state\n ${bodies ? 'body' : ''}\n repository {\n nameWithOwner\n }\n labels(first: 20) {\n nodes {\n name\n }\n }\n }\n }\n fieldValues(first: 50) {\n nodes {\n ... on ProjectV2ItemFieldTextValue {\n text\n field {\n ... on ProjectV2FieldCommon {\n name\n }\n }\n }\n ... on ProjectV2ItemFieldSingleSelectValue {\n name\n field {\n ... on ProjectV2FieldCommon {\n name\n }\n }\n }\n ... on ProjectV2ItemFieldDateValue {\n date\n field {\n ... on ProjectV2FieldCommon {\n name\n }\n }\n }\n ... on ProjectV2ItemFieldNumberValue {\n number\n field {\n ... on ProjectV2FieldCommon {\n name\n }\n }\n }\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n `,\n { projectId, cursor },\n o\n )\n for (const n of d.node.items.nodes) {\n const values: Record<string, string> = {}\n for (const v of n.fieldValues?.nodes ?? []) {\n const field = v.field?.name\n const value =\n v.text ??\n v.name ??\n v.date ??\n (v.number === undefined ? undefined : String(v.number))\n if (field !== undefined && value !== undefined) values[field] = value\n }\n const c = n.content\n const issue =\n c?.id !== undefined && c.number !== undefined\n ? {\n id: c.id,\n number: c.number,\n open: c.state === 'OPEN',\n repository: c.repository?.nameWithOwner ?? '',\n body: bodies ? (c.body ?? '') : null,\n labels: (c.labels?.nodes ?? [])\n .map((l) => l.name ?? '')\n .filter((l) => l !== ''),\n }\n : null\n items.push({\n id: n.id,\n draftId: issue === null ? (c?.id ?? null) : null,\n issue,\n title: c?.title ?? '',\n archived: n.isArchived === true,\n values,\n })\n }\n const { hasNextPage, endCursor } = d.node.items.pageInfo\n if (!hasNextPage || endCursor === null) return items\n cursor = endCursor\n }\n}\n\nexport async function setValue(\n projectId: string,\n itemId: string,\n fieldId: string,\n value:\n | { text: string }\n | { optionId: string }\n | { date: string }\n | { number: number }\n | null,\n o: ApiOptions\n): Promise<void> {\n if (value === null) {\n await graphql(\n `\n mutation ($projectId: ID!, $itemId: ID!, $fieldId: ID!) {\n clearProjectV2ItemFieldValue(\n input: { projectId: $projectId, itemId: $itemId, fieldId: $fieldId }\n ) {\n projectV2Item {\n id\n }\n }\n }\n `,\n { projectId, itemId, fieldId },\n o\n )\n return\n }\n await graphql(\n `\n mutation (\n $projectId: ID!\n $itemId: ID!\n $fieldId: ID!\n $value: ProjectV2FieldValue!\n ) {\n updateProjectV2ItemFieldValue(\n input: {\n projectId: $projectId\n itemId: $itemId\n fieldId: $fieldId\n value: $value\n }\n ) {\n projectV2Item {\n id\n }\n }\n }\n `,\n {\n projectId,\n itemId,\n fieldId,\n value:\n 'optionId' in value ? { singleSelectOptionId: value.optionId } : value,\n },\n o\n )\n}\n\nexport async function archive(\n projectId: string,\n itemId: string,\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation ($projectId: ID!, $itemId: ID!) {\n archiveProjectV2Item(\n input: { projectId: $projectId, itemId: $itemId }\n ) {\n item {\n id\n }\n }\n }\n `,\n { projectId, itemId },\n o\n )\n}\n\n/** Adds an issue to the project (`addProjectV2ItemById`); returns the item's id. */\nexport async function addItem(\n projectId: string,\n contentId: string,\n o: ApiOptions\n): Promise<string> {\n const d = await graphql<{ addProjectV2ItemById: { item: { id: string } } }>(\n `\n mutation ($projectId: ID!, $contentId: ID!) {\n addProjectV2ItemById(\n input: { projectId: $projectId, contentId: $contentId }\n ) {\n item {\n id\n }\n }\n }\n `,\n { projectId, contentId },\n o\n )\n return d.addProjectV2ItemById.item.id\n}\n\n/** Makes a draft item an issue of the repository; the item keeps its id and fields (spec 0018 §1). */\nexport async function convertDraft(\n itemId: string,\n repositoryId: string,\n o: ApiOptions\n): Promise<{ id: string; number: number }> {\n const d = await graphql<{\n convertProjectV2DraftIssueItemToIssue: {\n item: { content: { id?: string; number?: number } | null }\n }\n }>(\n `\n mutation ($itemId: ID!, $repositoryId: ID!) {\n convertProjectV2DraftIssueItemToIssue(\n input: { itemId: $itemId, repositoryId: $repositoryId }\n ) {\n item {\n id\n content {\n ... on Issue {\n id\n number\n }\n }\n }\n }\n }\n `,\n { itemId, repositoryId },\n o\n )\n const content = d.convertProjectV2DraftIssueItemToIssue.item.content\n const id = content?.id\n const number = content?.number\n if (id === undefined || number === undefined)\n throw new Error(`GitHub converted the item ${itemId} without an issue`)\n return { id, number }\n}\n\n/** The repositories the project is linked to, as `owner/name`. */\nexport async function linkedRepositories(\n projectId: string,\n o: ApiOptions\n): Promise<string[]> {\n const d = await graphql<{\n node: { repositories: { nodes: { nameWithOwner: string }[] } } | null\n }>(\n `\n query ($projectId: ID!) {\n node(id: $projectId) {\n ... on ProjectV2 {\n repositories(first: 100) {\n nodes {\n nameWithOwner\n }\n }\n }\n }\n }\n `,\n { projectId },\n o\n )\n return (d.node?.repositories.nodes ?? []).map((r) => r.nameWithOwner)\n}\n\n/** Links the project to a repository: it shows in the repository's Projects tab (spec 0018 §2). */\nexport async function linkRepository(\n projectId: string,\n repositoryId: string,\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation ($projectId: ID!, $repositoryId: ID!) {\n linkProjectV2ToRepository(\n input: { projectId: $projectId, repositoryId: $repositoryId }\n ) {\n repository {\n id\n }\n }\n }\n `,\n { projectId, repositoryId },\n o\n )\n}\n\n/**\n * REST `POST /orgs/{org}/projectsV2/{number}/views` (docs.github.com/en/rest/projects/views,\n * read 2026-09-29). `groupBy` is a field's `databaseId`, sent as\n * `vertical_group_by` (board columns), which the API takes as a one-item array.\n */\nexport async function createView(\n org: string,\n number: number,\n view: {\n name: string\n layout: 'board' | 'table' | 'roadmap'\n /** Null: none. */\n filter: string | null\n groupBy?: number\n /** Fields' `databaseId`s, in column order; sent as `visible_fields`. */\n visibleFields?: number[]\n },\n o: ApiOptions\n): Promise<void> {\n const body: Record<string, unknown> = { name: view.name, layout: view.layout }\n if (view.filter !== null) body['filter'] = view.filter\n if (view.groupBy !== undefined) {\n if (!Number.isInteger(view.groupBy))\n throw new Error(\n `a view groups by a field's database id, not ${view.groupBy}`\n )\n body['vertical_group_by'] = [view.groupBy]\n }\n if (view.visibleFields !== undefined) {\n if (!view.visibleFields.every(Number.isInteger))\n throw new Error('a view shows fields by their database ids')\n body['visible_fields'] = view.visibleFields\n }\n await postJson(\n `/orgs/${encodeURIComponent(org)}/projectsV2/${number}/views`,\n body,\n o,\n true\n )\n}\n\nexport interface View {\n id: string\n name: string\n /** GitHub's `BOARD_LAYOUT`, `TABLE_LAYOUT` or `ROADMAP_LAYOUT`. */\n layout: string\n /** The name of the field a board's columns follow; null: none. */\n columnField: string | null\n /** As it was given (read on rness-dev's Agent Pulse, 2026-10-06); null: none. */\n filter: string | null\n /** The fields it shows, by name, in the project's order, not the view's. */\n fields: string[]\n}\n\n/** The views of a project, in order, through GraphQL: the REST docs list no endpoint for them. */\nexport async function views(projectId: string, o: ApiOptions): Promise<View[]> {\n const d = await graphql<{\n node: {\n views: {\n nodes: {\n id: string\n name: string\n layout: string\n filter?: string | null\n fields?: { nodes: { name?: string }[] } | null\n verticalGroupByFields: { nodes: { name?: string }[] } | null\n }[]\n }\n } | null\n }>(\n `\n query ($projectId: ID!) {\n node(id: $projectId) {\n ... on ProjectV2 {\n views(first: 50) {\n nodes {\n id\n name\n layout\n filter\n fields(first: 50) {\n nodes {\n ... on ProjectV2FieldCommon {\n name\n }\n }\n }\n verticalGroupByFields(first: 1) {\n nodes {\n ... on ProjectV2FieldCommon {\n name\n }\n }\n }\n }\n }\n }\n }\n }\n `,\n { projectId },\n o\n )\n return (d.node?.views.nodes ?? []).map((n) => ({\n id: n.id,\n name: n.name,\n layout: n.layout,\n columnField: n.verticalGroupByFields?.nodes[0]?.name ?? null,\n filter: n.filter === undefined || n.filter === '' ? null : n.filter,\n fields: (n.fields?.nodes ?? []).flatMap((f) =>\n f.name === undefined ? [] : [f.name]\n ),\n }))\n}\n\n/** Deletes a view (`deleteProjectV2View`): the way to change what a board's columns follow. */\nexport async function deleteView(viewId: string, o: ApiOptions): Promise<void> {\n await graphql(\n `\n mutation ($viewId: ID!) {\n deleteProjectV2View(input: { viewId: $viewId }) {\n clientMutationId\n }\n }\n `,\n { viewId },\n o\n )\n}\n\n/** GraphQL's names of the layouts the REST API calls board, table and roadmap. */\nexport const LAYOUTS = {\n board: 'BOARD_LAYOUT',\n table: 'TABLE_LAYOUT',\n roadmap: 'ROADMAP_LAYOUT',\n} as const\n\n/**\n * `updateProjectV2View` (GraphQL schema, read 2026-10-06): a view changed in\n * place, its id, sort and widths kept — its name, layout, filter, and the\n * fields it shows by node id, in column order. Neither a board's columns\n * nor a roadmap's date are in its input.\n */\nexport async function updateView(\n viewId: string,\n change: {\n name?: string\n layout?: keyof typeof LAYOUTS\n /** `''` clears it. */\n filter?: string\n visibleFieldIds?: string[]\n },\n o: ApiOptions\n): Promise<void> {\n const vars: Record<string, unknown> = { viewId }\n const declare: string[] = ['$viewId: ID!']\n const input: string[] = ['viewId: $viewId']\n if (change.name !== undefined) {\n vars['name'] = change.name\n declare.push('$name: String')\n input.push('name: $name')\n }\n if (change.layout !== undefined) {\n vars['layout'] = LAYOUTS[change.layout]\n declare.push('$layout: ProjectV2ViewLayout')\n input.push('layout: $layout')\n }\n if (change.filter !== undefined) {\n vars['filter'] = change.filter\n declare.push('$filter: String')\n input.push('filter: $filter')\n }\n if (change.visibleFieldIds !== undefined) {\n vars['visibleFieldIds'] = change.visibleFieldIds\n declare.push('$visibleFieldIds: [ID!]')\n input.push('configuration: { visibleFieldIds: $visibleFieldIds }')\n }\n await graphql(\n `mutation (${declare.join(', ')}) {\n updateProjectV2View(input: { ${input.join(', ')} }) {\n projectV2View {\n id\n }\n }\n }`,\n vars,\n o\n )\n}\n\n/** A view renamed, the fields it shows given: `updateView` with both. */\nexport async function renameView(\n viewId: string,\n name: string,\n visibleFieldIds: string[],\n o: ApiOptions\n): Promise<void> {\n await updateView(viewId, { name, visibleFieldIds }, o)\n}\n\n/** Takes an item off the project (`deleteProjectV2Item`); its issue stays as it is (spec 0025 §3). */\nexport async function deleteItem(\n projectId: string,\n itemId: string,\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation ($projectId: ID!, $itemId: ID!) {\n deleteProjectV2Item(input: { projectId: $projectId, itemId: $itemId }) {\n deletedItemId\n }\n }\n `,\n { projectId, itemId },\n o\n )\n}\n\n/** A project's README and short description, as GitHub holds them ('' when unset). */\nexport async function projectText(\n projectId: string,\n o: ApiOptions\n): Promise<{ readme: string; shortDescription: string }> {\n const d = await graphql<{\n node: {\n projectReadme: string | null\n projectDescription: string | null\n } | null\n }>(\n `\n query ($projectId: ID!) {\n node(id: $projectId) {\n ... on ProjectV2 {\n projectReadme: readme\n projectDescription: shortDescription\n }\n }\n }\n `,\n { projectId },\n o\n )\n return {\n readme: d.node?.projectReadme ?? '',\n shortDescription: d.node?.projectDescription ?? '',\n }\n}\n\n/** Writes a project's README, its short description, or both (`updateProjectV2`). */\nexport async function updateProjectText(\n projectId: string,\n text: { readme?: string; shortDescription?: string },\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation ($projectId: ID!, $readme: String, $shortDescription: String) {\n updateProjectV2(\n input: {\n projectId: $projectId\n readme: $readme\n shortDescription: $shortDescription\n }\n ) {\n projectV2 {\n id\n }\n }\n }\n `,\n { projectId, ...text },\n o\n )\n}\n\n/** A status update of a project; `status` is GitHub's `ON_TRACK`, `AT_RISK`, … */\nexport interface StatusUpdateNode {\n id: string\n body: string\n status: string | null\n startDate: string | null\n targetDate: string | null\n}\n\n/** A project's status updates, 100 at most: a collection posts one a week (spec 0025 §4). */\nexport async function statusUpdates(\n projectId: string,\n o: ApiOptions\n): Promise<StatusUpdateNode[]> {\n const d = await graphql<{\n node: { statusUpdates: { nodes: StatusUpdateNode[] } } | null\n }>(\n `\n query ($projectId: ID!) {\n node(id: $projectId) {\n ... on ProjectV2 {\n statusUpdates(first: 100) {\n nodes {\n id\n body\n status\n startDate\n targetDate\n }\n }\n }\n }\n }\n `,\n { projectId },\n o\n )\n return d.node?.statusUpdates.nodes ?? []\n}\n\nexport interface StatusUpdateInput {\n body: string\n status: string\n startDate: string | null\n targetDate: string | null\n}\n\nexport async function createStatusUpdate(\n projectId: string,\n update: StatusUpdateInput,\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation (\n $projectId: ID!\n $body: String!\n $status: ProjectV2StatusUpdateStatus!\n $startDate: Date\n $targetDate: Date\n ) {\n createProjectV2StatusUpdate(\n input: {\n projectId: $projectId\n body: $body\n status: $status\n startDate: $startDate\n targetDate: $targetDate\n }\n ) {\n statusUpdate {\n id\n }\n }\n }\n `,\n { projectId, ...update },\n o\n )\n}\n\nexport async function updateStatusUpdate(\n statusUpdateId: string,\n update: StatusUpdateInput,\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation (\n $statusUpdateId: ID!\n $body: String!\n $status: ProjectV2StatusUpdateStatus!\n $startDate: Date\n $targetDate: Date\n ) {\n updateProjectV2StatusUpdate(\n input: {\n statusUpdateId: $statusUpdateId\n body: $body\n status: $status\n startDate: $startDate\n targetDate: $targetDate\n }\n ) {\n statusUpdate {\n id\n }\n }\n }\n `,\n { statusUpdateId, ...update },\n o\n )\n}\n","import { graphql, graphqlFound } from './github-projects.ts'\nimport { type ApiOptions, postJson } from './github.ts'\n\n/**\n * A repository's issues over GitHub's API: what a board's items are made\n * of (spec 0018 §2). No board logic; errors carry GitHub's own message.\n */\n\nexport interface Repository {\n /** The node id. */\n id: string\n /** `hasIssuesEnabled`. */\n issues: boolean\n /** The node id of the label asked for; null: the repository has none. */\n labelId: string | null\n}\n\n/** `owner/name`: its id, its Issues switch and one label; null when GitHub shows no such repository. */\nexport async function repository(\n owner: string,\n name: string,\n label: string,\n o: ApiOptions\n): Promise<Repository | null> {\n const d = await graphqlFound<{\n repository: {\n id: string\n hasIssuesEnabled: boolean\n label: { id: string } | null\n } | null\n }>(\n `query($owner: String!, $name: String!, $label: String!) {\n repository(owner: $owner, name: $name) { id hasIssuesEnabled label(name: $label) { id } }\n }`,\n { owner, name, label },\n o\n )\n const r = d?.repository ?? null\n return r === null\n ? null\n : { id: r.id, issues: r.hasIssuesEnabled, labelId: r.label?.id ?? null }\n}\n\n/** An open issue of a repository, with what adopting it needs. */\nexport interface OpenIssue {\n id: string\n number: number\n title: string\n body: string\n}\n\n/**\n * The open issues of `owner/name` that carry `label`, 100 a page. The\n * repository's issues, unlike a project's items, show an issue as soon as it\n * is created: a push looks here before creating one (spec 0020 §7).\n */\nexport async function openIssues(\n owner: string,\n name: string,\n label: string,\n o: ApiOptions\n): Promise<OpenIssue[]> {\n const found: OpenIssue[] = []\n let after: string | null = null\n for (;;) {\n const d: {\n repository: {\n issues: {\n nodes: OpenIssue[]\n pageInfo: { hasNextPage: boolean; endCursor: string | null }\n }\n } | null\n } = await graphql(\n `\n query (\n $owner: String!\n $name: String!\n $label: String!\n $after: String\n ) {\n repository(owner: $owner, name: $name) {\n issues(first: 100, after: $after, states: OPEN, labels: [$label]) {\n nodes {\n id\n number\n title\n body\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n `,\n { owner, name, label, after },\n o\n )\n const page = d.repository?.issues\n if (page === undefined) return found\n found.push(...page.nodes)\n if (!page.pageInfo.hasNextPage || page.pageInfo.endCursor === null)\n return found\n after = page.pageInfo.endCursor\n }\n}\n\n/** Creates a label (REST `POST /repos/{owner}/{repo}/labels`, docs read 2026-09-30); returns its node id. */\nexport async function createLabel(\n owner: string,\n name: string,\n label: { name: string; color: string; description: string },\n o: ApiOptions\n): Promise<string> {\n const body = await postJson(\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/labels`,\n label,\n o,\n true\n )\n const id =\n body !== null && typeof body === 'object'\n ? (body as Record<string, unknown>)['node_id']\n : undefined\n if (typeof id !== 'string')\n throw new Error(`GitHub created the label ${label.name} without a node id`)\n return id\n}\n\nexport async function createIssue(\n repositoryId: string,\n issue: { title: string; body: string; labelIds: string[] },\n o: ApiOptions\n): Promise<{ id: string; number: number }> {\n const d = await graphql<{\n createIssue: { issue: { id: string; number: number } }\n }>(\n `\n mutation (\n $repositoryId: ID!\n $title: String!\n $body: String\n $labelIds: [ID!]\n ) {\n createIssue(\n input: {\n repositoryId: $repositoryId\n title: $title\n body: $body\n labelIds: $labelIds\n }\n ) {\n issue {\n id\n number\n }\n }\n }\n `,\n { repositoryId, ...issue },\n o\n )\n return d.createIssue.issue\n}\n\n/** A title, a body, or both: a variable left out leaves its field as it is. */\nexport async function updateIssue(\n id: string,\n change: { title?: string; body?: string },\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation ($id: ID!, $title: String, $body: String) {\n updateIssue(input: { id: $id, title: $title, body: $body }) {\n issue {\n id\n }\n }\n }\n `,\n { id, ...change },\n o\n )\n}\n\n/** Closes an issue as not planned: its document is gone (spec 0018 §2). */\nexport async function closeIssue(id: string, o: ApiOptions): Promise<void> {\n await graphql(\n `\n mutation ($id: ID!) {\n closeIssue(input: { issueId: $id, stateReason: NOT_PLANNED }) {\n issue {\n id\n }\n }\n }\n `,\n { id },\n o\n )\n}\n\nexport async function reopenIssue(id: string, o: ApiOptions): Promise<void> {\n await graphql(\n `\n mutation ($id: ID!) {\n reopenIssue(input: { issueId: $id }) {\n issue {\n id\n }\n }\n }\n `,\n { id },\n o\n )\n}\n\nexport async function addLabels(\n id: string,\n labelIds: string[],\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation ($id: ID!, $labelIds: [ID!]!) {\n addLabelsToLabelable(input: { labelableId: $id, labelIds: $labelIds }) {\n clientMutationId\n }\n }\n `,\n { id, labelIds },\n o\n )\n}\n\n/** Every label of `owner/name`, by name: the ids a collection's labels are added by (spec 0025 §4). */\nexport async function labelIds(\n owner: string,\n name: string,\n o: ApiOptions\n): Promise<Map<string, string>> {\n const ids = new Map<string, string>()\n let after: string | null = null\n for (;;) {\n const d: {\n repository: {\n labelList: {\n nodes: { id: string; name: string }[]\n pageInfo: { hasNextPage: boolean; endCursor: string | null }\n }\n } | null\n } = await graphql(\n `\n query ($owner: String!, $name: String!, $after: String) {\n repository(owner: $owner, name: $name) {\n labelList: labels(first: 100, after: $after) {\n nodes {\n id\n name\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n `,\n { owner, name, after },\n o\n )\n const list = d.repository?.labelList\n for (const l of list?.nodes ?? []) ids.set(l.name, l.id)\n if (list?.pageInfo.hasNextPage !== true || list.pageInfo.endCursor === null)\n return ids\n after = list.pageInfo.endCursor\n }\n}\n\nexport async function removeLabels(\n id: string,\n labelIds: string[],\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation ($id: ID!, $labelIds: [ID!]!) {\n removeLabelsFromLabelable(\n input: { labelableId: $id, labelIds: $labelIds }\n ) {\n clientMutationId\n }\n }\n `,\n { id, labelIds },\n o\n )\n}\n","import * as gi from './github-issues.ts'\nimport { graphql, graphqlFound } from './github-projects.ts'\nimport type { ApiOptions } from './github.ts'\n\n/**\n * The agent journal on GitHub (spec 0030 §3, §8): a plan's implementation\n * issue in the repository where the commits are, labelled `rness:plan`,\n * found again by the last line of its body; a sub-issue of the plan's issue\n * in `.rness`; the notes as comments; the pull request of a branch.\n */\n\nexport const JOURNAL_LABEL = 'rness:plan'\nconst JOURNAL_LABEL_COLOR = '0e8a16'\nconst JOURNAL_LABEL_DESCRIPTION = 'An implementation of a plan of .rness'\n\n/** The last line of an implementation issue's body: how it is found again. */\nexport const journalMarker = (planPath: string): string =>\n `<!-- rness journal ${planPath} -->`\n\n/** An issue a note can go to: its node id, its number and its repository, `owner/name`. */\nexport interface JournalIssue {\n id: string\n number: number\n repository: string\n}\n\n/** Why a repository takes no implementation issue: §3.4's fallback reads it. */\nexport class JournalRefused extends Error {\n readonly why: 'issues' | 'missing'\n constructor(why: 'issues' | 'missing', message: string) {\n super(message)\n this.why = why\n }\n}\n\nconst lastLine = (body: string): string =>\n body\n .trimEnd()\n .split(/\\r\\n?|\\n/)\n .at(-1)\n ?.trim() ?? ''\n\n/** The open implementation issue of `planPath` in `owner/name`, or null. */\nexport async function journalIssue(\n owner: string,\n name: string,\n planPath: string,\n o: ApiOptions\n): Promise<JournalIssue | null> {\n const marker = journalMarker(planPath)\n const found = (await gi.openIssues(owner, name, JOURNAL_LABEL, o)).find(\n (i) => lastLine(i.body) === marker\n )\n return found === undefined\n ? null\n : { id: found.id, number: found.number, repository: `${owner}/${name}` }\n}\n\n/**\n * A new implementation issue of `planPath` in `owner/name`, its label made\n * when the repository lacks it. A repository with its Issues off, or that\n * this login cannot see, is {@link JournalRefused}; a write GitHub refuses\n * throws as GitHub says.\n */\nexport async function createJournalIssue(\n owner: string,\n name: string,\n planPath: string,\n issue: { title: string; body: string },\n o: ApiOptions\n): Promise<JournalIssue> {\n const repo = await gi.repository(owner, name, JOURNAL_LABEL, o)\n if (repo === null)\n throw new JournalRefused(\n 'missing',\n `${owner}/${name} is not on GitHub, or this login cannot see it`\n )\n if (!repo.issues)\n throw new JournalRefused('issues', `${owner}/${name} takes no issues`)\n const labelId =\n repo.labelId ??\n (await gi.createLabel(\n owner,\n name,\n {\n name: JOURNAL_LABEL,\n color: JOURNAL_LABEL_COLOR,\n description: JOURNAL_LABEL_DESCRIPTION,\n },\n o\n ))\n const made = await gi.createIssue(\n repo.id,\n {\n title: issue.title,\n body: `${issue.body.trimEnd()}\\n\\n${journalMarker(planPath)}\\n`,\n labelIds: [labelId],\n },\n o\n )\n return { ...made, repository: `${owner}/${name}` }\n}\n\n/** The issue `number` of `owner/name`: its node id and whether it is open; null when there is none. */\nexport async function issueOf(\n owner: string,\n name: string,\n number: number,\n o: ApiOptions\n): Promise<{ id: string; number: number; open: boolean } | null> {\n const d = await graphqlFound<{\n repository: { issue: { id: string; number: number; state: string } | null }\n }>(\n `query($owner: String!, $name: String!, $number: Int!) {\n repository(owner: $owner, name: $name) { issue(number: $number) { id number state } }\n }`,\n { owner, name, number },\n o\n )\n const i = d?.repository.issue ?? null\n return i === null\n ? null\n : { id: i.id, number: i.number, open: i.state === 'OPEN' }\n}\n\n/** `child` made a sub-issue of `parent` (GraphQL `addSubIssue`, schema read 2026-10-06). */\nexport async function addSubIssue(\n parentId: string,\n childId: string,\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation ($issueId: ID!, $subIssueId: ID!) {\n addSubIssue(input: { issueId: $issueId, subIssueId: $subIssueId }) {\n issue {\n id\n }\n }\n }\n `,\n { issueId: parentId, subIssueId: childId },\n o\n )\n}\n\n/** A comment on an issue (GraphQL `addComment`). */\nexport async function comment(\n issueId: string,\n body: string,\n o: ApiOptions\n): Promise<void> {\n await graphql(\n `\n mutation ($subjectId: ID!, $body: String!) {\n addComment(input: { subjectId: $subjectId, body: $body }) {\n commentEdge {\n node {\n id\n }\n }\n }\n }\n `,\n { subjectId: issueId, body },\n o\n )\n}\n\n/** The latest pull request whose head is `branch` in `owner/name`: its number and state; null when there is none. */\nexport async function pullRequestFor(\n owner: string,\n name: string,\n branch: string,\n o: ApiOptions\n): Promise<{ number: number; state: string } | null> {\n const d = await graphqlFound<{\n repository: {\n pullRequests: { nodes: { number: number; state: string }[] }\n }\n }>(\n `query($owner: String!, $name: String!, $branch: String!) {\n repository(owner: $owner, name: $name) {\n pullRequests(headRefName: $branch, first: 1, orderBy: { field: CREATED_AT, direction: DESC }) {\n nodes { number state }\n }\n }\n }`,\n { owner, name, branch },\n o\n )\n const pr = d?.repository.pullRequests.nodes[0]\n return pr === undefined ? null : { number: pr.number, state: pr.state }\n}\n","import { chmod, mkdir, open, readFile, rm, stat } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nimport {\n RefreshRejected,\n type TokenSet,\n refreshTokenSet,\n} from './device-flow.ts'\nimport { writeFileAtomic } from './fs.ts'\nimport { rnessCommand } from './pm.ts'\n\n// Where the GitHub login lives (spec 0004 §1): one file, readable by its\n// owner only. No keychain: that needs a native dependency.\n\nexport interface StoredLogin {\n login: string\n tokens: TokenSet\n}\n\n/** `$XDG_CONFIG_HOME/rness`, else `~/.config/rness`; `%APPDATA%\\rness` on Windows. */\nexport function configDir(): string {\n const xdg = process.env['XDG_CONFIG_HOME']\n if (xdg !== undefined && xdg !== '') return join(xdg, 'rness')\n const appData = process.env['APPDATA']\n if (process.platform === 'win32' && appData !== undefined && appData !== '')\n return join(appData, 'rness')\n return join(homedir(), '.config', 'rness')\n}\n\nconst authFile = (): string => join(configDir(), 'auth.json')\nconst lockFile = (): string => join(configDir(), 'auth.lock')\n\nfunction isTokenSet(v: unknown): v is TokenSet {\n if (v === null || typeof v !== 'object') return false\n const t = v as Record<string, unknown>\n return typeof t['accessToken'] === 'string' && t['accessToken'] !== ''\n}\n\nexport async function readAuth(): Promise<StoredLogin | null> {\n try {\n const parsed: unknown = JSON.parse(await readFile(authFile(), 'utf8'))\n const entry =\n parsed !== null && typeof parsed === 'object'\n ? (parsed as Record<string, unknown>)['github.com']\n : undefined\n if (entry === null || typeof entry !== 'object') return null\n const { login, tokens } = entry as Record<string, unknown>\n if (typeof login !== 'string' || !isTokenSet(tokens)) return null\n return {\n login,\n tokens: {\n accessToken: tokens.accessToken,\n expiresAt: tokens.expiresAt ?? null,\n refreshToken: tokens.refreshToken ?? null,\n refreshExpiresAt: tokens.refreshExpiresAt ?? null,\n scopes: tokens.scopes ?? '',\n },\n }\n } catch {\n return null\n }\n}\n\nexport async function writeAuth(login: StoredLogin): Promise<void> {\n const dir = configDir()\n await mkdir(dir, { recursive: true, mode: 0o700 })\n const file = authFile()\n await writeFileAtomic(\n file,\n `${JSON.stringify({ 'github.com': login }, null, 2)}\\n`\n )\n await chmod(file, 0o600)\n}\n\nexport async function clearAuth(): Promise<void> {\n await rm(authFile(), { force: true })\n}\n\nexport type TokenSource = 'GITHUB_TOKEN' | 'GH_TOKEN' | 'login'\n\nexport interface ResolvedToken {\n token: string\n source: TokenSource\n /** Known for a stored login only. */\n login: string | null\n}\n\n/** The token the environment provides, which wins over the stored login (CI, scripts). */\nexport function envToken(): ResolvedToken | null {\n for (const source of ['GITHUB_TOKEN', 'GH_TOKEN'] as const) {\n const token = process.env[source]\n if (token !== undefined && token !== '')\n return { token, source, login: null }\n }\n return null\n}\n\n/** Refresh when the access token has less than this left. */\nconst REFRESH_MARGIN_MS = 5 * 60_000\nconst LOCK_WAIT_MS = 10_000\nconst LOCK_STALE_MS = 30_000\n\nexport interface ResolveDeps {\n now?: () => number\n /** One line for the user when the login turns out to be over. */\n notify?: (line: string) => void\n}\n\nconst fresh = (tokens: TokenSet, now: number): boolean =>\n tokens.expiresAt === null || tokens.expiresAt - now > REFRESH_MARGIN_MS\n\n/**\n * Hold `auth.lock` while `work` runs. A refresh token is single-use and git\n * calls `rness git-credential` in parallel: two refreshes at once would\n * invalidate each other. Null when the lock could not be had in time.\n */\nasync function withLock<T>(work: () => Promise<T>): Promise<T | null> {\n await mkdir(configDir(), { recursive: true, mode: 0o700 })\n const file = lockFile()\n const deadline = Date.now() + LOCK_WAIT_MS\n for (;;) {\n try {\n const handle = await open(file, 'wx')\n await handle.close()\n break\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== 'EEXIST') throw e\n const age = await stat(file).then(\n (s) => Date.now() - s.mtimeMs,\n () => 0\n )\n if (age > LOCK_STALE_MS) await rm(file, { force: true })\n else if (Date.now() > deadline) return null\n else await new Promise<void>((r) => setTimeout(r, 50))\n }\n }\n try {\n return await work()\n } finally {\n await rm(file, { force: true })\n }\n}\n\n/**\n * The GitHub token to act with: `GITHUB_TOKEN`, then `GH_TOKEN`, then the\n * stored login — refreshed when it is about to expire. Null when there is\n * none. A network failure during the refresh never ends the login: an\n * offline `git pull` must not log anyone out.\n */\nexport async function resolveToken(\n deps: ResolveDeps = {}\n): Promise<ResolvedToken | null> {\n const env = envToken()\n if (env !== null) return env\n const now = deps.now ?? Date.now\n const stored = await readAuth()\n if (stored === null) return null\n const answer = (s: StoredLogin): ResolvedToken => ({\n token: s.tokens.accessToken,\n source: 'login',\n login: s.login,\n })\n if (fresh(stored.tokens, now())) return answer(stored)\n\n const refreshed = await withLock(async (): Promise<StoredLogin | null> => {\n // Another process may have renewed it while this one waited.\n const current = await readAuth()\n if (current === null) return null\n if (fresh(current.tokens, now())) return current\n if (current.tokens.refreshToken === null) return null\n try {\n const tokens = await refreshTokenSet(current.tokens.refreshToken, now)\n const next = { login: current.login, tokens }\n await writeAuth(next)\n return next\n } catch (e) {\n if (e instanceof RefreshRejected) {\n await clearAuth()\n ;(deps.notify ?? ((l) => process.stderr.write(`${l}\\n`)))(\n `your GitHub login expired; run ${rnessCommand()} login`\n )\n return null\n }\n // Offline: keep the login, and the token while it is still valid.\n const expiresAt = current.tokens.expiresAt\n return expiresAt !== null && expiresAt > now() ? current : null\n }\n })\n return refreshed === null ? null : answer(refreshed)\n}\n","// GitHub's OAuth device flow (spec 0004 §2): no client secret, no redirect,\n// and it works where there is no local browser. Refreshing a token obtained\n// this way needs no secret either (GitHub documentation, read 2026-09-19).\n\n/** The OAuth App \"Rness\" of the rness-dev organization. Public by nature. */\nconst GITHUB_CLIENT_ID = 'Ov23liv1ia2UWeWttsOK'\nconst GITHUB_WEB = 'https://github.com'\nexport const SCOPES = 'repo read:org'\n/** The extra scope boards need to read a GitHub Project. */\nexport const BOARD_SCOPE = 'project'\n\nexport function clientId(): string {\n return process.env['RNESS_GITHUB_CLIENT_ID'] ?? GITHUB_CLIENT_ID\n}\n\n/**\n * The OAuth app's page in the user's settings: where an owner approves rness\n * for an organization that restricts OAuth apps, a member asks for it, and\n * anyone revokes what `rness login` was granted (spec 0028 §3). Doing any of\n * it by API needs the client secret.\n */\nexport function approvalUrl(): string {\n return `https://github.com/settings/connections/applications/${clientId()}`\n}\n\n/** `https://github.com`; `RNESS_GITHUB_WEB` overrides it in tests. */\nexport function webBase(): string {\n return (process.env['RNESS_GITHUB_WEB'] ?? GITHUB_WEB).replace(/\\/+$/, '')\n}\n\nexport interface DeviceCode {\n deviceCode: string\n userCode: string\n verificationUri: string\n /** Seconds. */\n expiresIn: number\n interval: number\n}\n\nexport interface TokenSet {\n accessToken: string\n /** Epoch milliseconds; null for a token that does not expire. */\n expiresAt: number | null\n refreshToken: string | null\n refreshExpiresAt: number | null\n scopes: string\n}\n\n/** GitHub said no: the message is one line for the user. */\nexport class LoginError extends Error {}\n/** GitHub refused the refresh token: the login is over. Not a network error. */\nexport class RefreshRejected extends Error {}\n\nfunction reason(e: unknown): string {\n if (e instanceof Error) {\n return e.name === 'TimeoutError' ? 'timed out' : e.message\n }\n return String(e)\n}\n\nasync function post(\n path: string,\n params: Record<string, string>\n): Promise<Record<string, unknown>> {\n let res: Response\n try {\n res = await fetch(`${webBase()}${path}`, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'User-Agent': 'rness-cli',\n },\n body: new URLSearchParams(params).toString(),\n signal: AbortSignal.timeout(15_000),\n })\n } catch (e) {\n throw new Error(`cannot reach github.com: ${reason(e)}`, { cause: e })\n }\n let body: unknown\n try {\n body = await res.json()\n } catch (e) {\n throw new Error(`github.com answered ${res.status} for ${path}`, {\n cause: e,\n })\n }\n if (body === null || typeof body !== 'object')\n throw new Error(`github.com answered an unexpected body for ${path}`)\n return body as Record<string, unknown>\n}\n\nconst str = (v: unknown): string | null => (typeof v === 'string' ? v : null)\nconst num = (v: unknown): number | null =>\n typeof v === 'number' && Number.isFinite(v) ? v : null\n\nfunction tokenSet(body: Record<string, unknown>, now: number): TokenSet | null {\n const accessToken = str(body['access_token'])\n if (accessToken === null) return null\n const expiresIn = num(body['expires_in'])\n const refreshIn = num(body['refresh_token_expires_in'])\n return {\n accessToken,\n expiresAt: expiresIn === null ? null : now + expiresIn * 1000,\n refreshToken: str(body['refresh_token']),\n refreshExpiresAt: refreshIn === null ? null : now + refreshIn * 1000,\n scopes: str(body['scope']) ?? '',\n }\n}\n\nexport async function requestDeviceCode(\n scopes: string = SCOPES\n): Promise<DeviceCode> {\n const id = clientId()\n if (id === '')\n throw new LoginError(\n 'rness has no GitHub client ID yet; set RNESS_GITHUB_CLIENT_ID'\n )\n const body = await post('/login/device/code', {\n client_id: id,\n scope: scopes,\n })\n const deviceCode = str(body['device_code'])\n const userCode = str(body['user_code'])\n const verificationUri = str(body['verification_uri'])\n if (deviceCode === null || userCode === null || verificationUri === null) {\n const error = str(body['error'])\n throw new LoginError(\n error === 'device_flow_disabled'\n ? 'the device flow is not enabled on the rness GitHub app'\n : `github.com refused to start the login${error === null ? '' : ` (${error})`}`\n )\n }\n return {\n deviceCode,\n userCode,\n verificationUri,\n expiresIn: num(body['expires_in']) ?? 900,\n interval: num(body['interval']) ?? 5,\n }\n}\n\nexport interface PollDeps {\n sleep?: (ms: number) => Promise<void>\n now?: () => number\n}\n\n/** Ask every `interval` seconds until the user approved, refused, or the code expired. */\nexport async function pollForToken(\n code: DeviceCode,\n deps: PollDeps = {}\n): Promise<TokenSet> {\n const sleep =\n deps.sleep ?? ((ms: number) => new Promise<void>((r) => setTimeout(r, ms)))\n const now = deps.now ?? Date.now\n const deadline = now() + code.expiresIn * 1000\n let interval = code.interval\n for (;;) {\n await sleep(interval * 1000)\n const body = await post('/login/oauth/access_token', {\n client_id: clientId(),\n device_code: code.deviceCode,\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n })\n const tokens = tokenSet(body, now())\n if (tokens !== null) return tokens\n const error = str(body['error'])\n if (error === 'authorization_pending') {\n if (now() > deadline)\n throw new LoginError('the code expired before it was approved')\n continue\n }\n if (error === 'slow_down') {\n interval = (num(body['interval']) ?? interval) + 5\n continue\n }\n if (error === 'expired_token')\n throw new LoginError('the code expired before it was approved')\n if (error === 'access_denied')\n throw new LoginError('the login was cancelled on github.com')\n throw new LoginError(`github.com refused the login (${error ?? 'unknown'})`)\n }\n}\n\n/** A new token set for a refresh token. `RefreshRejected` when GitHub says the login is over. */\nexport async function refreshTokenSet(\n refreshToken: string,\n now: () => number = Date.now\n): Promise<TokenSet> {\n const body = await post('/login/oauth/access_token', {\n client_id: clientId(),\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n })\n const tokens = tokenSet(body, now())\n if (tokens !== null) return tokens\n throw new RefreshRejected(str(body['error']) ?? 'refused')\n}\n","import { createHash } from 'node:crypto'\nimport { posix } from 'node:path'\n\nimport { stripFrontMatter } from '../core/frontmatter.ts'\nimport { blobUrl, issueUrl } from './urls.ts'\n\n/**\n * A document of `.rness/` as its issue's body (spec 0018 §3): the same\n * document gives the same body, byte for byte. Pure: the caller reads the\n * files and knows the issue numbers.\n */\n\n/** GitHub's limit for an issue body, in characters (spec 0018 §3.5). */\nexport const BODY_LIMIT = 65_536\n\nexport interface BodySource {\n /** The document's path in `.rness/`, with `/`: `specs/0016-cli-status.md`. */\n path: string\n /** The document as read. */\n text: string\n org: string\n /** The issue number of every document on the board, by path. */\n numbers: ReadonlyMap<string, number>\n /** Every file of `.rness/`, by path. */\n files: ReadonlySet<string>\n}\n\n/** A body's first line (spec 0018 §3.1); the whole body of an issue whose document is not written yet. */\nexport function headerOf(path: string, org: string): string {\n return `\\`${path}\\` · [on GitHub](${blobUrl(org, path)})`\n}\n\nconst digest = (text: string): string =>\n createHash('sha256').update(text, 'utf8').digest('hex').slice(0, 12)\nconst comment = (d: string): string => `<!-- rness ${d} -->`\n/** What the digest line adds to a body, with the blank line before it. */\nconst TAIL = `\\n\\n${comment('0'.repeat(12))}`.length\nconst LAST_LINE = /\\n\\n<!-- rness ([0-9a-f]{12}) -->\\s*$/\n\n/**\n * The digest a body's last line carries, when it is the digest of what\n * precedes it; null otherwise — no such line, or a body edited by hand\n * (spec 0018 §4). CRLF, as GitHub's editor stores it, reads as LF.\n */\nexport function digestOf(body: string): string | null {\n const text = body.replace(/\\r\\n?/g, '\\n')\n const m = LAST_LINE.exec(text)\n const d = m?.[1]\n if (m === null || d === undefined) return null\n return digest(text.slice(0, m.index)) === d ? d : null\n}\n\nconst OPENER = /^[ \\t]*(`{3,}|~{3,})(.*)$/\nconst CLOSER = /^[ \\t]*(`{3,}|~{3,})[ \\t]*$/\n\n/** Per line: whether it is code — a fence, or inside one. Fences may be indented (a list item's), with spaces or tabs. */\nfunction fenced(lines: readonly string[]): boolean[] {\n const code: boolean[] = []\n let run: string | null = null\n for (const line of lines) {\n if (run === null) {\n const m = OPENER.exec(line)\n const fence = m?.[1]\n // A backtick fence's info string holds no backtick (CommonMark 4.5).\n if (\n fence !== undefined &&\n !(fence.startsWith('`') && (m?.[2] ?? '').includes('`'))\n )\n run = fence\n code.push(run !== null)\n continue\n }\n code.push(true)\n const fence = CLOSER.exec(line)?.[1]\n if (\n fence !== undefined &&\n fence[0] === run[0] &&\n fence.length >= run.length\n )\n run = null\n }\n return code\n}\n\nconst TITLE = /^ {0,3}#(?:[ \\t]|$)/\n\n/** Without the first `#` heading outside code, nor the blank lines after it (spec 0018 §3.2). */\nfunction withoutTitle(lines: readonly string[]): string[] {\n const code = fenced(lines)\n const at = lines.findIndex((line, i) => code[i] !== true && TITLE.test(line))\n if (at < 0) return [...lines]\n let end = at + 1\n while (end < lines.length && (lines[end] ?? '').trim() === '') end++\n return [...lines.slice(0, at), ...lines.slice(end)]\n}\n\nconst SCHEME = /^[a-zA-Z][a-zA-Z0-9+.-]*:/\nconst IMAGE = /\\.(?:png|jpe?g|gif|svg|webp|avif)$/i\n\nconst decoded = (path: string): string => {\n try {\n return decodeURI(path)\n } catch {\n return path\n }\n}\n\n/** A link's destination (spec 0018 §3.3); as written when absolute, or no file of `.rness/`. */\nfunction target(dest: string, s: BodySource): string {\n const raw = dest.startsWith('<') ? dest.slice(1, -1) : dest\n if (\n raw === '' ||\n SCHEME.test(raw) ||\n raw.startsWith('//') ||\n raw.startsWith('#')\n )\n return dest\n const hash = raw.indexOf('#')\n const pathPart = hash < 0 ? raw : raw.slice(0, hash)\n const anchor = hash < 0 ? '' : raw.slice(hash)\n const file = decoded(\n posix.normalize(\n pathPart.startsWith('/')\n ? pathPart.slice(1)\n : posix.join(posix.dirname(s.path), pathPart)\n )\n )\n const number = s.numbers.get(file)\n if (number !== undefined) return issueUrl(s.org, number)\n if (!s.files.has(file)) return dest\n return `${blobUrl(s.org, file)}${IMAGE.test(file) ? '?raw=true' : ''}${anchor}`\n}\n\n/**\n * What neutralizing leaves alone, and where a link's destination is: a code\n * span (it may cross a line), an HTML comment, an autolink, a reference\n * definition's destination, an inline link's destination, a bare URL.\n */\nconst PROTECTED = new RegExp(\n [\n /(?<!`)(`+)(?!`)[\\s\\S]*?(?<!`)\\1(?!`)/.source,\n /<!--[\\s\\S]*?-->/.source,\n /<[a-zA-Z][a-zA-Z0-9+.-]*:[^\\s<>]*>/.source,\n /^ {0,3}\\[(?:[^\\]\\\\\\n]|\\\\.)+\\]:[ \\t]*(?<def><[^>\\n]*>|\\S+)/.source,\n /\\]\\([ \\t]*(?<dest><[^>\\n]*>|[^\\s()]+)/.source,\n /\\b(?:https?:\\/\\/|www\\.)[^\\s<>]*[^\\s<>.,:;\"')\\]]/.source,\n ].join('|'),\n 'gm'\n)\n// `\\@name` mentions no one; `\\#4` still links issue 4 (spec 0018 §1).\nconst MENTION = /(^|[^A-Za-z0-9`\\\\])@([A-Za-z0-9][A-Za-z0-9-]*)/g\nconst REFERENCE = /(^|[^A-Za-z0-9&#/])#(\\d+)(?![A-Za-z0-9])/g\nconst ZWSP = '\\u200B'\n\n/** Prose made harmless (spec 0018 §3.4): it mentions no one and names no issue. */\nconst neutral = (text: string): string =>\n text.replace(MENTION, '$1\\\\@$2').replace(REFERENCE, `$1#${ZWSP}$2`)\n\nfunction inline(text: string, s: BodySource): string {\n let out = ''\n let from = 0\n for (const m of text.matchAll(PROTECTED)) {\n const at = m.index ?? 0\n out += neutral(text.slice(from, at))\n const dest = m.groups?.['dest'] ?? m.groups?.['def']\n out +=\n dest === undefined\n ? m[0]\n : `${m[0].slice(0, m[0].length - dest.length)}${target(dest, s)}`\n from = at + m[0].length\n }\n return out + neutral(text.slice(from))\n}\n\n/** Links rewritten and prose neutralized a paragraph at a time; fenced blocks as they are. */\nfunction rewrite(lines: readonly string[], s: BodySource): string[] {\n const code = fenced(lines)\n const out: string[] = []\n let paragraph: string[] = []\n const flush = (): void => {\n if (paragraph.length > 0) out.push(inline(paragraph.join('\\n'), s))\n paragraph = []\n }\n lines.forEach((line, i) => {\n if (code[i] === true || line.trim() === '') {\n flush()\n out.push(line)\n } else paragraph.push(line)\n })\n flush()\n return out\n}\n\n/**\n * `text` cut before its last blank line outside code that leaves room for\n * `rest` and the digest (spec 0018 §3.5). The blank line after the first\n * line always qualifies.\n */\nfunction cut(text: string, rest: string): string {\n const room = BODY_LIMIT - TAIL - 2 - rest.length\n const lines = text.split('\\n')\n const code = fenced(lines)\n let length = -1\n let at = 1\n for (let k = 1; k < lines.length; k++) {\n length += 1 + (lines[k - 1] ?? '').length\n if (length > room) break\n if (code[k] !== true && (lines[k] ?? '').trim() === '') at = k\n }\n return `${lines.slice(0, at).join('\\n').trimEnd()}\\n\\n${rest}`\n}\n\nexport function issueBody(s: BodySource): string {\n const lines = withoutTitle(\n stripFrontMatter(s.text.replace(/\\r\\n?/g, '\\n')).split('\\n')\n )\n const content = rewrite(lines, s)\n .join('\\n')\n .replace(/^(?:[ \\t]*\\n)+/, '')\n .trimEnd()\n const header = headerOf(s.path, s.org)\n const whole = content === '' ? header : `${header}\\n\\n${content}`\n const text =\n whole.length + TAIL <= BODY_LIMIT\n ? whole\n : cut(whole, `The rest: ${blobUrl(s.org, s.path)}`)\n return `${text}\\n\\n${comment(digest(text))}`\n}\n","import { readFile, readdir } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nimport { containedPath } from '../core/contained.ts'\nimport { parseFrontMatter, stripFrontMatter } from '../core/frontmatter.ts'\nimport type { Fields } from '../core/types.ts'\n\n/**\n * What a collection with a project of its own says of it, in its files\n * (spec 0025 §4): `README.md` for the project's README, description,\n * columns, fields and labels; `updates/` for its status updates. The CLI\n * adds no field or label of its own: a collection declares them.\n */\n\nexport type FieldType = 'text' | 'date' | 'select' | 'number'\nconst FIELD_TYPES: readonly FieldType[] = ['text', 'date', 'select', 'number']\n\n/** A field a collection declares: filled from `from`, the first key present winning. */\nexport interface DeclaredField {\n name: string\n type: FieldType\n from: string[]\n /** A `select`'s options, in order; values found elsewhere follow. */\n options: string[]\n}\n\n/** Where a document's labels come from: its subdirectory, or a front-matter key. */\nexport type LabelSource = { kind: 'directory' } | { kind: 'key'; key: string }\n\nexport interface CollectionShape {\n /** `README.md` without its front matter; null when there is none. */\n readme: string | null\n description: string | null\n /** The columns, in order, each there even when empty; null: the documents'. */\n statuses: string[] | null\n fields: DeclaredField[]\n labels: LabelSource | null\n}\n\n/**\n * The fields a project of rness already has, and GitHub's own: a declared\n * field of the same name would be written over, or refused.\n */\nconst TAKEN = new Set(\n [\n 'Status',\n 'Collection',\n 'Agent',\n 'Working session',\n 'Path',\n 'Session history',\n 'Title',\n 'Assignees',\n 'Labels',\n 'Linked pull requests',\n 'Milestone',\n 'Repository',\n 'Reviewers',\n 'Type',\n 'Parent issue',\n 'Sub-issues progress',\n ].map((n) => n.toLowerCase())\n)\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n v !== null && typeof v === 'object' && !Array.isArray(v)\n\nconst isNames = (v: unknown): v is string[] =>\n Array.isArray(v) &&\n v.every((s) => typeof s === 'string' && s.trim() !== '') &&\n new Set(v).size === v.length\n\nasync function readText(path: string): Promise<string | null> {\n try {\n return await readFile(path, 'utf8')\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') return null\n throw e\n }\n}\n\nfunction readField(where: string, name: string, value: unknown): DeclaredField {\n const key = `fields.${name}`\n if (TAKEN.has(name.toLowerCase()))\n throw new Error(`${where}: \"${key}\" is a field of rness: name it otherwise`)\n if (!isRecord(value))\n throw new Error(`${where}: \"fields\" must map names to { type, from }`)\n const type = FIELD_TYPES.find((t) => t === value['type'])\n if (type === undefined)\n throw new Error(\n `${where}: \"${key}.type\" must be one of ${FIELD_TYPES.join(', ')}`\n )\n const raw = value['from']\n const from = typeof raw === 'string' && raw !== '' ? [raw] : raw\n if (!isNames(from) || from.length === 0)\n throw new Error(\n `${where}: \"${key}.from\" must be a front-matter key or a list of them`\n )\n const options = value['options'] ?? []\n if (!isNames(options) && !(Array.isArray(options) && options.length === 0))\n throw new Error(`${where}: \"${key}.options\" must be a list of names`)\n return { name, type, from, options: [...(options as string[])] }\n}\n\nfunction readLabels(where: string, value: unknown): LabelSource | null {\n if (value === undefined || value === null) return null\n if (typeof value !== 'string' || value.trim() === '')\n throw new Error(\n `${where}: \"labels\" must be directory or a front-matter key`\n )\n return value === 'directory'\n ? { kind: 'directory' }\n : { kind: 'key', key: value }\n}\n\n/** `<collection>/README.md`, read and checked; a declaration that cannot be read throws, naming its key. */\nexport async function readShape(\n rnessDir: string,\n collection: string\n): Promise<CollectionShape> {\n const where = `${collection}/README.md`\n const text = await readText(join(rnessDir, collection, 'README.md'))\n if (text === null)\n return {\n readme: null,\n description: null,\n statuses: null,\n fields: [],\n labels: null,\n }\n let front: Fields | null\n try {\n front = parseFrontMatter(text)\n } catch (e) {\n throw new Error(`${where}: ${e instanceof Error ? e.message : String(e)}`, {\n cause: e,\n })\n }\n const f = front ?? {}\n const description = f['description'] ?? null\n if (description !== null && typeof description !== 'string')\n throw new Error(`${where}: \"description\" must be text`)\n const statuses = f['statuses'] ?? null\n if (statuses !== null && !isNames(statuses))\n throw new Error(`${where}: \"statuses\" must be a list of names`)\n const fields = f['fields'] ?? {}\n if (!isRecord(fields))\n throw new Error(`${where}: \"fields\" must map names to { type, from }`)\n return {\n readme: stripFrontMatter(text),\n description: description === null ? null : description.trim(),\n statuses: statuses === null ? null : [...statuses],\n fields: Object.entries(fields).map(([name, v]) =>\n readField(where, name, v)\n ),\n labels: readLabels(where, f['labels']),\n }\n}\n\n/** A date's day as written: `2026-10-13T15:00+02:00` is `2026-10-13`. */\nfunction dayOf(value: unknown): string | null {\n if (value instanceof Date && !Number.isNaN(value.getTime()))\n return value.toISOString().slice(0, 10)\n if (typeof value !== 'string') return null\n const day = /^(\\d{4}-\\d{2}-\\d{2})(?:$|[T ])/.exec(value.trim())?.[1]\n return day ?? null\n}\n\nfunction valueOf(field: DeclaredField, fields: Fields): string | null {\n const key = field.from.find(\n (k) => fields[k] !== undefined && fields[k] !== null && fields[k] !== ''\n )\n if (key === undefined) return null\n const raw = fields[key]\n switch (field.type) {\n case 'date':\n return dayOf(raw)\n case 'number': {\n const n = typeof raw === 'number' ? raw : Number(raw)\n return typeof raw !== 'boolean' && Number.isFinite(n) ? String(n) : null\n }\n default:\n if (Array.isArray(raw)) return raw.map(String).join(', ')\n return typeof raw === 'object' ? null : String(raw)\n }\n}\n\n/**\n * A document's declared values and labels, from its front matter and its\n * path within the collection (`linkedin/a.md`). A value that its type cannot\n * read is no value: one card is no reason to stop a sync.\n */\nexport function valuesOf(\n shape: CollectionShape,\n fields: Fields,\n rel: string\n): { values: Record<string, string | null>; labels: string[] } {\n const values = Object.fromEntries(\n shape.fields.map((f) => [f.name, valueOf(f, fields)])\n )\n const labels: string[] = []\n if (shape.labels?.kind === 'directory') {\n const slash = rel.indexOf('/')\n if (slash > 0) labels.push(rel.slice(0, slash))\n } else if (shape.labels?.kind === 'key') {\n const raw = fields[shape.labels.key]\n for (const v of Array.isArray(raw) ? raw : [raw])\n if (typeof v === 'string' && v.trim() !== '' && !labels.includes(v))\n labels.push(v.trim())\n }\n return { values, labels }\n}\n\nexport type Health =\n 'on-track' | 'at-risk' | 'off-track' | 'complete' | 'inactive'\nconst HEALTHS: readonly Health[] = [\n 'on-track',\n 'at-risk',\n 'off-track',\n 'complete',\n 'inactive',\n]\n\n/** A status update of a collection's project: a file of `updates/`. */\nexport interface StatusUpdate {\n /** Relative to `.rness/`: its marker on the project. */\n path: string\n health: Health\n startDate: string | null\n targetDate: string | null\n body: string\n}\n\n/** `dir/*.md` (`marketing/updates`), in the order of their names; a file without a health throws, naming it. */\nexport async function readUpdates(\n rnessDir: string,\n dir: string\n): Promise<StatusUpdate[]> {\n let at: string\n let names: string[]\n try {\n // rness.json names it: a directory out of .rness is refused, and a file\n // there that is a link is no file (`isFile`), never followed out.\n at = await containedPath(rnessDir, dir)\n names = (\n await readdir(at, {\n withFileTypes: true,\n })\n )\n .filter((e) => e.isFile() && e.name.endsWith('.md'))\n .map((e) => e.name)\n .sort()\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') return []\n throw e\n }\n const updates: StatusUpdate[] = []\n for (const name of names) {\n const path = `${dir}/${name}`\n const text = (await readText(join(at, name))) ?? ''\n let front: Fields | null\n try {\n front = parseFrontMatter(text)\n } catch (e) {\n throw new Error(\n `${path}: ${e instanceof Error ? e.message : String(e)}`,\n {\n cause: e,\n }\n )\n }\n const health = HEALTHS.find((h) => h === front?.['health'])\n if (health === undefined)\n throw new Error(`${path}: \"health\" must be one of ${HEALTHS.join(', ')}`)\n updates.push({\n path,\n health,\n startDate: dayOf(front?.['start_date']),\n targetDate: dayOf(front?.['target_date']),\n body: stripFrontMatter(text),\n })\n }\n return updates\n}\n","import type {\n BoardDeclaration,\n FieldDeclaration,\n OptionColor,\n ViewLayout,\n} from '../core/board-declaration.ts'\nimport { contractOf } from '../core/board-declaration.ts'\nimport { labelOf } from '../core/presets.ts'\nimport { type StatusTab, statusTone } from '../core/status.ts'\nimport type { Fields } from '../core/types.ts'\nimport { headerOf } from './body.ts'\nimport { type DeclaredField, valuesOf } from './collection.ts'\n\nexport type { OptionColor } from '../core/board-declaration.ts'\n\n/**\n * A board's shape for the adapter, built from its declaration (spec 0031)\n * and the documents of `.rness/`: the options of `Status`, the fields to\n * make, the views and the labels. The adapter adds the engine's own: `Path`\n * and the label `rness` (spec 0031 §1).\n */\nexport interface Layout {\n /** The options of `Status`, in order. */\n statuses: string[]\n /** The fields besides `Status` and `Path`, in the order they are made. */\n fields: LayoutField[]\n views: LayoutView[]\n /** The labels the board's documents carry besides `rness`. */\n labels: string[]\n /** Declared colours by option name; an option not named takes its kind's. */\n colors: Readonly<Record<string, OptionColor>>\n}\n\n/**\n * A field to make. A select's `kind` says how its options are coloured: a\n * status as its tone, a collection pink, a declared option keeps its own.\n */\nexport type LayoutField =\n | {\n name: string\n type: 'select'\n kind: 'status' | 'collection' | 'declared'\n options: string[]\n /** Its options kept in this order, those GitHub has besides after. */\n reorder: boolean\n }\n | { name: string; type: 'text' | 'date' | 'number' }\n\nexport interface LayoutView {\n name: string\n layout: ViewLayout\n /** The view's filter as GitHub keeps it; null: none. */\n filter: string | null\n /** A board's columns; `Status` unless a collection's or a declared select. */\n columns: string | null\n /** A table's fields, in order; null: GitHub's default. */\n fields: string[] | null\n}\n\n/** One collection of a board, for this workspace's documents. */\nexport interface BoardCollection {\n /** The directory. */\n name: string\n label: string\n /** Its steps, in order: the options its field and the board's `Status` take. */\n statuses: string[]\n field: string | null\n tab: StatusTab\n}\n\n/** What one document should look like as an item of the board. */\nexport interface Desired {\n path: string\n title: string\n /** What a new issue carries until pass 2 writes its body: the first line. */\n body: string\n status: string | null\n /** The collection's own status field, which carries `status` too; null: it has none. */\n statusField: string | null\n /**\n * Every declared field the sync writes, by name: all but those from\n * `$agent` and `$session`, which a session's marks write (spec 0017 §5).\n */\n values: Record<string, string | null>\n /** The labels its issue carries besides `rness`. */\n labels: string[]\n /** Labels the board makes that its issue must not carry. */\n unlabels: string[]\n}\n\n/** `?` is how `rness status` shows a document without a status. */\nconst statusOf = (status: string | null): string | null =>\n status === null || status === '?' ? null : status\n\n/** The contract's statuses, in lifecycle order; the board's options follow it. */\nconst LIFECYCLE = [\n 'Draft',\n 'Proposed',\n 'Ready',\n 'Approved',\n 'In progress',\n 'Blocked',\n 'Accepted',\n 'Implemented',\n 'Completed',\n 'Rejected',\n 'Superseded',\n 'Abandoned',\n]\n\nconst TONE_COLORS = {\n done: 'green',\n dropped: 'gray',\n active: 'yellow',\n} as const\n\n/**\n * The colour of a select's option: as declared, else by its kind — a status\n * by its tone (a status nobody declared still reads done, dropped or under\n * way), a collection pink. Null: a declared option keeps the colour it has.\n */\nexport function optionColor(\n colors: Readonly<Record<string, OptionColor>>,\n kind: 'status' | 'collection' | 'declared',\n name: string\n): OptionColor | null {\n const declared = colors[name]\n if (declared !== undefined) return declared\n if (kind === 'collection') return 'pink'\n if (kind === 'declared') return null\n const tone = statusTone(name)\n return tone === 'missing' ? 'gray' : TONE_COLORS[tone]\n}\n\n/** The name of a collection's status field under `\"collections\": \"all\"`: `ADR status`. */\nexport const statusFieldName = (label: string): string => `${label} status`\n\n/** The lifecycle's statuses of `found` first, in its order, then the others as found. */\nconst inLifecycleOrder = (found: Iterable<string>): string[] => {\n const all = new Set(found)\n return [\n ...LIFECYCLE.filter((s) => all.has(s)),\n ...[...all].filter((s) => !LIFECYCLE.includes(s)),\n ]\n}\n\n/** Each value once, in the order first met. */\nconst once = (values: Iterable<string>): string[] => [...new Set(values)]\n\nconst foundIn = (tab: StatusTab): string[] =>\n tab.rows\n .map((row) => statusOf(row.status))\n .filter((s): s is string => s !== null)\n\n/** The tab of a directory, empty when it has no document yet. */\nconst tabOf = (tabs: readonly StatusTab[], name: string): StatusTab =>\n tabs.find((t) => t.name === name) ?? { name, label: labelOf(name), rows: [] }\n\n/**\n * A board's collections in this workspace (spec 0031 §2.3), in order.\n * `\"all\"`: `adr`, `specs` and `plans` with the contract's statuses, then\n * every other directory `rness status` finds with those found — but a\n * collection another board holds (`owned`). Each has its status field.\n */\nexport function collectionsOf(\n board: BoardDeclaration,\n tabs: readonly StatusTab[],\n owned: (collection: string) => boolean = () => false\n): BoardCollection[] {\n if (board.collections === 'all')\n return tabs\n .filter((t) => !owned(t.name))\n .map((tab) => {\n const statuses = inLifecycleOrder([\n ...(contractOf(tab.name) ?? []),\n ...foundIn(tab),\n ])\n // A directory whose documents carry no status yet: columns by Status.\n return {\n name: tab.name,\n label: tab.label,\n statuses,\n field: statuses.length > 0 ? statusFieldName(tab.label) : null,\n tab,\n }\n })\n return Object.entries(board.collections).map(([name, c]) => {\n const tab = tabOf(tabs, name)\n const found = foundIn(tab)\n return {\n name,\n label: c.label,\n statuses:\n c.statuses === 'contract'\n ? inLifecycleOrder([...(contractOf(name) ?? []), ...found])\n : c.statuses === 'found'\n ? inLifecycleOrder(found)\n : once([...c.statuses, ...found]),\n field: c.field,\n tab: { ...tab, label: c.label },\n }\n })\n}\n\n/** The field a board's `$collection` select is: what a collection's view filters by. */\nconst collectionField = (board: BoardDeclaration): string | null =>\n Object.entries(board.fields).find(\n ([, f]) => f.type === 'select' && f.from.includes('$collection')\n )?.[0] ?? null\n\n/** A view of one collection's cards: `collection:\"ADR\"`, the field's name in lowercase. */\nexport const collectionFilter = (field: string, label: string): string =>\n `${field.toLowerCase()}:\"${label}\"`\n\n/**\n * The declared views, and under `\"collections\": \"all\"` one board view for\n * each collection no view names, after the last view of a collection (spec\n * 0031 §3).\n */\nfunction viewsOf(\n board: BoardDeclaration,\n collections: readonly BoardCollection[]\n): LayoutView[] {\n const field = collectionField(board)\n const labelOfCollection = (name: string): string =>\n collections.find((c) => c.name === name)?.label ?? labelOf(name)\n const views: LayoutView[] = board.views.map((v) => ({\n name: v.name,\n layout: v.layout,\n filter:\n [\n v.collection === null || field === null\n ? null\n : collectionFilter(field, labelOfCollection(v.collection)),\n v.filter,\n ]\n .filter((f): f is string => f !== null)\n .join(' ') || null,\n columns: v.layout === 'board' ? (v.columns ?? 'Status') : null,\n fields: v.fields,\n }))\n if (board.collections !== 'all' || field === null) return views\n const named = new Set(\n board.views.flatMap((v) => (v.collection === null ? [] : [v.collection]))\n )\n const extra = collections\n .filter((c) => !named.has(c.name))\n .map((c) => ({\n name: c.label,\n layout: 'board' as const,\n filter: collectionFilter(field, c.label),\n columns: c.field ?? 'Status',\n fields: null,\n }))\n const last = board.views.findLastIndex((v) => v.collection !== null)\n views.splice(last + 1, 0, ...extra)\n return views\n}\n\nconst isSource = (from: string): boolean => from.startsWith('$')\n\n/** The declared fields from front matter alone, as the reader of values takes them. */\nconst asDeclared = (name: string, f: FieldDeclaration): DeclaredField => ({\n name,\n type: f.type,\n from: f.from,\n options: f.options,\n})\n\n/** The board's shape (spec 0031 §2); `want` gives a declared select the options its documents carry. */\nexport function layoutOf(\n board: BoardDeclaration,\n collections: readonly BoardCollection[],\n want: readonly Desired[]\n): Layout {\n const statuses =\n collections.length === 1\n ? (collections[0]?.statuses ?? [])\n : inLifecycleOrder(collections.flatMap((c) => c.statuses))\n const fields: LayoutField[] = []\n const declared = Object.entries(board.fields)\n // Where a card is first: its collection, then its steps, then the rest.\n for (const [name, f] of declared)\n if (f.type === 'select' && f.from[0] === '$collection')\n fields.push({\n name,\n type: 'select',\n kind: 'collection',\n options: collections.map((c) => c.label),\n reorder: false,\n })\n for (const c of collections)\n if (c.field !== null && c.statuses.length > 0)\n fields.push({\n name: c.field,\n type: 'select',\n kind: 'status',\n options: c.statuses,\n reorder: true,\n })\n for (const [name, f] of declared) {\n if (f.type === 'select' && f.from[0] === '$collection') continue\n if (f.type !== 'select') {\n fields.push({ name, type: f.type })\n continue\n }\n const status = f.from[0] === '$status'\n fields.push({\n name,\n type: 'select',\n kind: status ? 'status' : 'declared',\n options: status\n ? statuses\n : once([\n ...f.options,\n ...want\n .map((w) => w.values[name])\n .filter((v): v is string => typeof v === 'string'),\n ]),\n reorder: !f.from.every(isSource),\n })\n }\n return {\n statuses,\n fields,\n views: viewsOf(board, collections),\n // Made only when a document carries it: a directory with no card is no\n // label, though one carrying it once is taken off (`unlabels`).\n labels: once(want.flatMap((w) => w.labels)),\n colors: board.colors,\n }\n}\n\nconst sessionsOf = (row: StatusTab['rows'][number]): string | null =>\n row.sessions\n ?.map((e) => (e.agent === undefined ? e.id : `${e.agent} · ${e.id}`))\n .join(', ') ?? null\n\n/** Whether a board's fields or labels read the documents' front matter. */\nexport const readsFrontMatter = (board: BoardDeclaration): boolean =>\n board.labels !== null ||\n Object.values(board.fields).some((f) => f.from.some((k) => !isSource(k)))\n\n/**\n * Each document of the board's collections as an item: its title, status,\n * declared values (`fronts`: its front matter by path) and labels.\n * `directories`: a collection's subdirectories, whose labels a document\n * that left them loses.\n */\nexport function desiredOf(\n board: BoardDeclaration,\n collections: readonly BoardCollection[],\n org: string,\n fronts: ReadonlyMap<string, Fields> = new Map(),\n directories: ReadonlyMap<string, readonly string[]> = new Map()\n): Desired[] {\n const written = Object.entries(board.fields).filter(\n ([, f]) => !f.from.includes('$agent') && !f.from.includes('$session')\n )\n const shape = {\n readme: null,\n description: null,\n statuses: null,\n fields: written\n .filter(([, f]) => !f.from.every(isSource))\n .map(([name, f]) => asDeclared(name, f)),\n labels: board.labels,\n }\n const wanted = collections.flatMap((c) =>\n c.tab.rows.map((row) => {\n const front = fronts.get(row.path) ?? {}\n const read = valuesOf(shape, front, row.path.slice(c.name.length + 1))\n const status = statusOf(row.status)\n const sources: Record<string, string | null> = {\n $collection: c.label,\n $status: status,\n $sessions: sessionsOf(row),\n $id: row.id,\n }\n const values: Record<string, string | null> = {}\n for (const [name, f] of written) {\n let value: string | null = null\n for (const from of f.from) {\n value = isSource(from)\n ? (sources[from] ?? null)\n : (valuesOf(\n {\n ...shape,\n fields: [asDeclared(name, { ...f, from: [from] })],\n },\n front,\n ''\n ).values[name] ?? null)\n if (value !== null) break\n }\n values[name] = value\n }\n return {\n path: row.path,\n title: `${row.id} - ${row.title}`,\n body: headerOf(row.path, org),\n status,\n statusField: c.field,\n values,\n labels: read.labels,\n unlabels: [] as string[],\n }\n })\n )\n if (board.labels === null) return wanted\n // What the board labels: its documents' labels, then its collections'\n // subdirectories', so a label nobody carries any more is still taken off.\n const made = once([\n ...wanted.flatMap((w) => w.labels),\n ...(board.labels.kind === 'directory'\n ? collections.flatMap((c) => directories.get(c.name) ?? [])\n : []),\n ])\n return wanted.map((w) => ({\n ...w,\n unlabels: made.filter((l) => !w.labels.includes(l)),\n }))\n}\n","import { digestOf } from './body.ts'\nimport type { Desired } from './layout.ts'\n\n/** An item's issue in `.rness`, as the provider reads it. */\nexport interface ItemIssue {\n number: number\n open: boolean\n /** It carries the label `rness`, in any case. */\n labelled: boolean\n /** Null: listed without bodies (`items(board, { bodies: false })`). */\n body: string | null\n /** Every label it carries, as GitHub names them. */\n labels: string[]\n}\n\n/** An item of the board, as the provider reads it. */\nexport interface BoardItem {\n id: string\n /**\n * Null: not rness's — no `Path`, or content that is neither a draft nor an\n * issue of the organization's `.rness` (spec 0018 §2); `planSync` adopts\n * one such issue a stopped sync left, by its body's first line.\n */\n path: string | null\n /** Its issue in `.rness`; null: a draft of 0.12.0, which becomes one. */\n issue: ItemIssue | null\n title: string\n status: string | null\n /** The value of the collection's own status field. */\n collectionStatus: string | null\n type: string | null\n agent: string | null\n session: string | null\n /** `Sessions`, which a session's end never clears (spec 0020 §3.2). */\n sessions: string | null\n /** Every field's value by field name, text, option, date or number as text. */\n values: Record<string, string>\n}\n\n/** What `apply` gave a document that had no issue: its item and its number. */\nexport interface Placed {\n id: string\n number: number\n /**\n * The issue was there already — open, labelled, the document's first line\n * as its body — and was added to the board instead of made again.\n */\n adopted?: true\n}\n\n/** Pass 2: an issue's body, once every document has its number. */\nexport type BodyStep = { kind: 'body'; id: string; body: string }\n\nexport type Step =\n /** Pass 1 (spec 0018 §4): the document's issue, title, label and fields. */\n | { kind: 'create'; want: Desired }\n | { kind: 'convert'; id: string; want: Desired }\n | { kind: 'update'; id: string; want: Desired; reopen: boolean }\n | { kind: 'unchanged'; id: string }\n /** The document is gone: its issue closed as not planned, its item archived. */\n | { kind: 'close'; id: string }\n /**\n * The document's collection has a project of its own (spec 0025 §3): the\n * item leaves this board, its issue left as it is.\n */\n | { kind: 'remove'; id: string }\n /** A draft left over: archived. */\n | { kind: 'archive'; id: string }\n | BodyStep\n\nconst lower = (labels: readonly string[]): Set<string> =>\n new Set(labels.map((l) => l.toLowerCase()))\n\n/** A label wanted and missing, or one the collection makes on an issue that must not carry it. */\nfunction labelsDiffer(item: BoardItem, w: Desired): boolean {\n if (w.labels.length === 0 && w.unlabels.length === 0) return false\n const carried = lower(item.issue?.labels ?? [])\n return (\n w.labels.some((l) => !carried.has(l.toLowerCase())) ||\n w.unlabels.some((l) => carried.has(l.toLowerCase()))\n )\n}\n\nconst differs = (item: BoardItem, w: Desired): boolean =>\n item.title !== w.title ||\n item.status !== w.status ||\n (w.statusField !== null &&\n (item.values[w.statusField] ?? null) !== w.status) ||\n Object.entries(w.values).some(\n ([name, value]) => (item.values[name] ?? null) !== value\n ) ||\n labelsDiffer(item, w)\n\n/** Of several items on one path, the one kept: an open issue, then a closed one, the lowest number first; a draft last. */\nconst rank = (i: BoardItem): number =>\n i.issue === null ? 2 : i.issue.open ? 0 : 1\nconst keptFirst = (a: BoardItem, b: BoardItem): number =>\n rank(a) - rank(b) || (a.issue?.number ?? 0) - (b.issue?.number ?? 0)\n\nconst gone = (item: BoardItem): Step =>\n item.issue === null\n ? { kind: 'archive', id: item.id }\n : { kind: 'close', id: item.id }\n\n/** A body's first line; a CR ends a line as GitHub's editor writes it. */\nexport const firstLine = (body: string): string =>\n body.split(/\\r\\n?|\\n/, 1)[0] ?? ''\n\n/**\n * Issues of `.rness` on the board without `Path` that a sync made and left\n * there: it stopped before writing their `Path` (spec 0018 §2). Labelled\n * `rness`, their body's first line is a document's (§3.1), which\n * `Desired.body` is. By that line, the one to keep first.\n */\nfunction strays(have: readonly BoardItem[]): Map<string, BoardItem[]> {\n const byLine = new Map<string, BoardItem[]>()\n for (const item of have) {\n if (\n item.path !== null ||\n item.issue === null ||\n item.issue.body === null ||\n !item.issue.labelled\n )\n continue\n const line = firstLine(item.issue.body)\n byLine.set(line, [...(byLine.get(line) ?? []), item])\n }\n for (const items of byLine.values()) items.sort(keptFirst)\n return byLine\n}\n\n/**\n * The paths `planSync` judges: on the board, no document wanted there — once\n * each. This clone's git, or its record of the issues it opened, decides\n * (`isGone`).\n */\nexport function unwantedPaths(\n want: readonly Desired[],\n have: readonly BoardItem[]\n): string[] {\n const wanted = new Set(want.map((w) => w.path))\n const paths = new Set<string>()\n for (const item of have)\n if (item.path !== null && !wanted.has(item.path)) paths.add(item.path)\n return [...paths]\n}\n\n/** The issues this clone's syncs opened, by number: the path each was opened for (spec 0018 §2). */\nexport type Opened = ReadonlyMap<number, string>\n\n/**\n * Whether an item no document wants is gone (spec 0018 §2): its path is in\n * `seen` — this clone's git holds it, its tree no longer does — or this\n * clone opened its issue for that path (`opened`): a document its agent\n * wrote, then renamed or deleted before any commit. Any other is a\n * teammate's document, or the same developer's from another clone, not\n * pulled yet. A draft has no issue: git's word alone.\n */\nfunction isGone(\n path: string,\n item: BoardItem,\n seen: ReadonlySet<string>,\n opened: Opened\n): boolean {\n return (\n seen.has(path) ||\n (item.issue !== null && opened.get(item.issue.number) === path)\n )\n}\n\n/**\n * Pass 1, one way (spec 0018 §2, §4): items are found by `path`. A document\n * without one adopts the issue a stopped sync left without `Path`, or gets\n * a new one; a draft of 0.12.0 becomes one; a closed issue is reopened;\n * whatever differs is written back. Items that are not rness's are left\n * alone — and so is a stray whose document has an item: adopting it only\n * ever replaces a second issue. An item with no document is closed only\n * when it `isGone`; any other is unchanged. Told nothing, it closes nothing.\n */\nexport function planSync(\n want: readonly Desired[],\n have: readonly BoardItem[],\n seen: ReadonlySet<string> = new Set(),\n opened: Opened = new Map(),\n elsewhere: (path: string) => boolean = () => false\n): Step[] {\n const byPath = new Map<string, BoardItem[]>()\n for (const item of have)\n if (item.path !== null)\n byPath.set(item.path, [...(byPath.get(item.path) ?? []), item])\n const kept = new Map<string, BoardItem>()\n const surplus: Step[] = []\n for (const [path, items] of byPath) {\n const [keep, ...rest] = [...items].sort(keptFirst)\n if (keep !== undefined) kept.set(path, keep)\n surplus.push(...rest.map(gone))\n }\n const left = strays(have)\n const steps: Step[] = []\n const wanted = new Set<string>()\n for (const w of want) {\n wanted.add(w.path)\n const item = kept.get(w.path) ?? left.get(w.body)?.[0]\n if (item === undefined) steps.push({ kind: 'create', want: w })\n else if (item.issue === null)\n steps.push({ kind: 'convert', id: item.id, want: w })\n else if (\n item.path === null ||\n !item.issue.open ||\n !item.issue.labelled ||\n differs(item, w)\n )\n steps.push({\n kind: 'update',\n id: item.id,\n want: w,\n reopen: !item.issue.open,\n })\n else steps.push({ kind: 'unchanged', id: item.id })\n }\n for (const [path, item] of kept)\n if (!wanted.has(path))\n steps.push(\n // Its own project holds it now: off this board, not closed.\n elsewhere(path)\n ? { kind: 'remove', id: item.id }\n : isGone(path, item, seen, opened)\n ? gone(item)\n : { kind: 'unchanged', id: item.id }\n )\n return [...steps, ...surplus]\n}\n\n/**\n * The record after a sync (spec 0018 §2): each issue it created added, for\n * its path; forgotten, one whose path git has seen (`seen` covers every\n * recorded path), one this sync closed or archived (`closed`, by item), one\n * no longer on the board.\n */\nexport function stillOpened(\n opened: Opened,\n have: readonly BoardItem[],\n seen: ReadonlySet<string>,\n closed: ReadonlySet<string>,\n created: ReadonlyMap<string, Placed>\n): Map<number, string> {\n const items = new Map<number, string>()\n for (const item of have)\n if (item.issue !== null) items.set(item.issue.number, item.id)\n const next = new Map<number, string>()\n for (const [number, path] of opened) {\n const id = items.get(number)\n if (id !== undefined && !closed.has(id) && !seen.has(path))\n next.set(number, path)\n }\n for (const [path, placed] of created) next.set(placed.number, path)\n return next\n}\n\n/** A document's issue after pass 1: its item, its number, its body as read (null: none worth reading). */\nexport interface Issued {\n id: string\n number: number\n body: string | null\n}\n\n/** Each document's issue after pass 1, by path: as the board listed it, or as pass 1 placed it. */\nexport function issuedAfter(\n steps: readonly Step[],\n have: readonly BoardItem[],\n placed: ReadonlyMap<string, Placed>\n): Map<string, Issued> {\n const byId = new Map(have.map((i) => [i.id, i]))\n const issued = new Map<string, Issued>()\n for (const step of steps) {\n if (step.kind === 'create' || step.kind === 'convert') {\n const p = placed.get(step.want.path)\n if (p !== undefined) issued.set(step.want.path, { ...p, body: null })\n } else if (step.kind === 'update' || step.kind === 'unchanged') {\n const item = byId.get(step.id)\n // An adopted issue is listed without `Path`: its step names its document.\n const path = step.kind === 'update' ? step.want.path : item?.path\n if (item === undefined || path == null || item.issue === null) continue\n issued.set(path, {\n id: item.id,\n number: item.issue.number,\n body: item.issue.body,\n })\n }\n }\n return issued\n}\n\n/** Pass 2 (spec 0018 §4): a body is written when its issue's does not carry its digest. */\nexport function planBodies(\n bodies: ReadonlyMap<string, string>,\n issued: ReadonlyMap<string, Issued>\n): BodyStep[] {\n const steps: BodyStep[] = []\n for (const [path, body] of bodies) {\n const i = issued.get(path)\n if (i === undefined) continue\n if (i.body === null || digestOf(i.body) !== digestOf(body))\n steps.push({ kind: 'body', id: i.id, body })\n }\n return steps\n}\n","import type { StatusUpdate } from '../board/collection.ts'\nimport type { Desired, LayoutView } from '../board/layout.ts'\nimport {\n type Layout,\n type OptionColor,\n collectionFilter,\n optionColor,\n} from '../board/layout.ts'\nimport {\n type BoardItem,\n type Placed,\n type Step,\n firstLine,\n} from '../board/plan.ts'\nimport * as gi from './github-issues.ts'\nimport * as gh from './github-projects.ts'\nimport type { ApiOptions } from './github.ts'\nimport type { Board, MarkFields, Provider } from './provider.ts'\n\n/** A board on a GitHub project: its layout (spec 0017 §3, kept by spec 0018 §6), its items issues of `.rness` (spec 0018 §2–§5). */\n\nexport const PROJECT_TITLE = 'Agent Pulse'\nconst WORKING = 'working'\nconst WORKING_VIEW = 'Working'\n/** The engine's field: where an item belongs, `adr/0001-a.md` (spec 0031 §1). */\nconst PATH_FIELD = 'Path'\n/** The repository whose issues are the board's items (spec 0018 §2). */\nconst MEMORY = '.rness'\n/** The label every one of them carries: `-label:rness` leaves them out of the Issues tab. */\nexport const LABEL = 'rness'\n/** The session working on a document now; cleared when it ends (spec 0017 §5). */\nconst WORKING_SESSION = 'Working session'\n/** Every session that wrote or changed a document; never cleared (spec 0020 §3). */\nconst SESSION_HISTORY = 'Session history'\n/** What 0.15 named them: renamed at the next sync, read and written under either name until then (spec 0022 §2). */\nconst FORMERLY: Readonly<Record<string, string>> = {\n [WORKING_SESSION]: 'Session',\n [SESSION_HISTORY]: 'Sessions',\n}\n/** A value of an item, under the field's name or, on a board not renamed yet, its former one. */\nconst valueOf = (values: Record<string, string>, name: string): string | null =>\n values[name] ?? values[FORMERLY[name] ?? ''] ?? null\nconst LABEL_COLOR = '5319e7'\nconst LABEL_DESCRIPTION = 'A document of .rness, on a board of rness'\n/** A label a collection's README declares for its documents (spec 0025 §4). */\nconst OWN_LABEL_COLOR = 'ededed'\nconst OWN_LABEL_DESCRIPTION =\n 'A label a collection of .rness gives its documents'\n/** The roadmap a collection's project gets when it declares a date field. */\nconst CALENDAR_VIEW = 'Calendar'\n/** How a status update names the file it came from; GitHub does not show it. */\nconst markerOf = (path: string): string => `<!-- rness: ${path} -->`\n/** A declared field's type as GitHub names it. */\nconst DATA_TYPE = {\n text: 'TEXT',\n date: 'DATE',\n number: 'NUMBER',\n select: 'SINGLE_SELECT',\n} as const\n/** GitHub's type as `rness.json` names it, for a refusal. */\nconst READABLE_TYPE: Readonly<Record<string, string>> = {\n TEXT: 'text',\n DATE: 'date',\n NUMBER: 'number',\n SINGLE_SELECT: 'select',\n}\n/** GitHub's own fields, which a project lists with the others. */\nconst GITHUB_FIELDS = new Set(\n [\n 'Title',\n 'Assignees',\n 'Labels',\n 'Linked pull requests',\n 'Milestone',\n 'Repository',\n 'Reviewers',\n 'Type',\n 'Parent issue',\n 'Sub-issues progress',\n 'Tracks',\n 'Tracked by',\n ].map((n) => n.toLowerCase())\n)\n/**\n * A view rness made in a release before it was declared: a collection's\n * (its name in its filter), the `Working` table, `All`, a `Calendar`. Not\n * declared any more, it goes; any other view is the team's (spec 0031 §4).\n */\nconst rnessOwn = (v: gh.View): boolean =>\n (v.filter !== null &&\n v.filter === collectionFilter(COLLECTION_FIELD, v.name)) ||\n (v.name === WORKING_VIEW && v.filter === WORKING_FILTER) ||\n (v.name === ALL_VIEW && v.filter === null && v.layout === 'TABLE_LAYOUT') ||\n (v.name === CALENDAR_VIEW && v.layout === 'ROADMAP_LAYOUT')\n/** GitHub's label names ignore case: `Rness` is the label `rness`. */\nconst labelled = (labels: readonly string[]): boolean =>\n labels.some((l) => l.toLowerCase() === LABEL.toLowerCase())\n\n/**\n * SPIKE-DEPENDENT CHOICES (not yet verified live): the names of the two\n * fields rness's board is grouped and filtered by, and `viewFilter` below.\n * Every use goes through these constants, so a fallback (`rness status`\n * instead of Status) is a change to `STATUS_FIELD`, `statusField` and\n * `viewFilter` only. The collection field is `Collection`, not `Type`:\n * `type:` is GitHub's own filter qualifier for issue types, and an\n * organization using issue types has a built-in `Type` field (spec 0017 §3).\n */\nexport const STATUS_FIELD = 'Status'\n/** What rness calls the first view GitHub gives a new project. */\nconst ALL_VIEW = 'All'\nconst DEFAULT_VIEW = 'View 1'\nexport const COLLECTION_FIELD = 'Collection'\n\n/**\n * SPIKE-DEPENDENT CHOICE 1 of 2: the board's Status\n * is the built-in single-select field every project has. If the API refuses\n * to edit its options, the fallback is a created field `rness status` — change\n * this one function.\n */\nexport function statusField(fields: readonly gh.Field[]): gh.Field {\n const field = fields.find((f) => f.name === STATUS_FIELD)\n if (field === undefined || field.options === null)\n throw new Error(\n `the GitHub project has no single-select field ${STATUS_FIELD}`\n )\n return field\n}\n\n/**\n * SPIKE-DEPENDENT CHOICE 2 of 2 (not yet verified live): the filter string of\n * a board view of one collection, and of the Working table. If GitHub's\n * filter syntax differs from `field:\"value\"`, change these two lines.\n */\nexport const viewFilter = (collection: string): string =>\n `${COLLECTION_FIELD.toLowerCase()}:\"${collection}\"`\nexport const WORKING_FILTER = 'agent:working'\n\ninterface Cache {\n projectId: string\n fields?: gh.Field[]\n /** The items as last read: the values `apply` compares against. */\n known: Map<string, gh.RawItem>\n /**\n * Made by this process and not laid out yet: its Status still carries\n * GitHub's default options, which the first `ensureLayout` replaces.\n */\n fresh?: boolean\n /** `.rness`'s open issues labelled `rness`, read at the first create. */\n open?: gi.OpenIssue[]\n}\n\n/** How a single-select's options are coloured (`optionColor`). */\ntype OptionKind = 'status' | 'collection' | 'declared'\n\nconst namesOf = (field: gh.Field): string[] =>\n (field.options ?? []).map((o) => o.name)\n\n/** `wanted` first, in its order, then the rest as they were. */\nconst orderedFirst = (\n wanted: readonly string[],\n all: readonly string[]\n): string[] => {\n const first = wanted.filter((n) => all.includes(n))\n return [...first, ...all.filter((n) => !first.includes(n))]\n}\n\n/** The adapter's board methods, for one process: project ids and fields are cached per board. */\nexport class GitHubBoards implements Pick<\n Provider,\n | 'checkIssues'\n | 'createBoard'\n | 'board'\n | 'ensureLayout'\n | 'items'\n | 'apply'\n | 'mark'\n> {\n readonly #o: ApiOptions\n readonly #cache = new Map<string, Cache>()\n /** Each organization's `.rness`, as first read: its id, its Issues, its label. */\n readonly #memories = new Map<string, gi.Repository>()\n /** Each organization's `.rness` labels by name, read when a collection needs one. */\n readonly #labels = new Map<string, Map<string, string>>()\n\n constructor(options: ApiOptions) {\n this.#o = options\n }\n\n #key = (b: { org: string; number: number }): string => `${b.org}/${b.number}`\n\n async #cacheOf(board: Board): Promise<Cache> {\n const cached = this.#cache.get(this.#key(board))\n if (cached !== undefined) return cached\n const project = await gh.findProject(board.org, board.number, this.#o)\n if (project === null)\n throw new Error(`GitHub has no project ${board.number} in ${board.org}`)\n return this.#remember(board, project.id)\n }\n\n #remember(board: Board, projectId: string): Cache {\n const cache: Cache = { projectId, known: new Map() }\n this.#cache.set(this.#key(board), cache)\n return cache\n }\n\n async #fields(board: Board): Promise<gh.Field[]> {\n const cache = await this.#cacheOf(board)\n cache.fields ??= await gh.fields(cache.projectId, this.#o)\n return cache.fields\n }\n\n async #memory(org: string): Promise<gi.Repository> {\n const known = this.#memories.get(org)\n if (known !== undefined) return known\n const found = await gi.repository(org, MEMORY, LABEL, this.#o)\n if (found === null)\n throw new Error(\n `boards need ${org}/${MEMORY} on GitHub: it is not there, or this login cannot see it`\n )\n this.#memories.set(org, found)\n return found\n }\n\n async checkIssues(org: string): Promise<void> {\n if (!(await this.#memory(org)).issues)\n throw new Error(\n `boards need Issues on ${org}/${MEMORY}: turn them on in its Settings`\n )\n }\n\n /** The project only: the caller declares it before `ensureLayout` builds it. */\n async createBoard(org: string, title = PROJECT_TITLE): Promise<Board> {\n const project = await gh.createProject(\n await gh.orgId(org, this.#o),\n title,\n this.#o\n )\n const board = { org, number: project.number, url: project.url }\n this.#remember(board, project.id).fresh = true\n return board\n }\n\n async board(org: string, number: number): Promise<Board | null> {\n const project = await gh.findProject(org, number, this.#o)\n if (project === null) return null\n const board = { org, number, url: project.url }\n // A project this process just made keeps what it knows: its default\n // statuses are still to replace.\n if (!this.#cache.has(this.#key(board))) this.#remember(board, project.id)\n return board\n }\n\n async ensureLayout(board: Board, layout: Layout): Promise<string[]> {\n const cache = await this.#cacheOf(board)\n const fields = await gh.fields(cache.projectId, this.#o)\n const added: string[] = []\n\n const enumOf = (c: OptionColor): string => c.toUpperCase()\n const colorOf = (kind: OptionKind, name: string): string | null => {\n const c = optionColor(layout.colors, kind, name)\n return c === null ? null : enumOf(c)\n }\n const inputs = (\n existing: gh.Field['options'],\n kind: OptionKind,\n wanted: readonly string[],\n names: readonly string[]\n ): gh.OptionInput[] =>\n names.map((name) => {\n const had = existing?.find((o) => o.name === name)?.color\n // An option rness does not know keeps the colour it has.\n const color = wanted.includes(name) ? colorOf(kind, name) : null\n return { name, color: color ?? had ?? 'GRAY' }\n })\n const withOptions = async (\n field: gh.Field,\n kind: OptionKind,\n wanted: readonly string[],\n reorder: boolean\n ): Promise<gh.Field> => {\n const now = namesOf(field)\n const missing = wanted.filter((n) => !now.includes(n))\n // Existing options stay: a hand-made one is not rness's to remove.\n const grown = [...now, ...missing]\n const next = reorder ? orderedFirst(wanted, grown) : grown\n const ordered = !next.every((n, i) => n === now[i])\n const recoloured = (field.options ?? []).some((o) => {\n const color = wanted.includes(o.name) ? colorOf(kind, o.name) : null\n return color !== null && o.color !== undefined && o.color !== color\n })\n if (!ordered && !recoloured) return field\n added.push(...missing.map((n) => `option ${n}`))\n if (missing.length === 0 && ordered) added.push('ordered options')\n if (recoloured && !added.includes('coloured options'))\n added.push('coloured options')\n // setOptions resends the ids of the kept options: items keep their value.\n return gh.setOptions(\n field,\n inputs(field.options, kind, wanted, next),\n this.#o\n )\n }\n const typed = (name: string, type: string): gh.Field | undefined => {\n const field = fields.find((f) => f.name === name)\n if (field !== undefined && field.dataType !== type)\n throw new Error(\n `the project's field ${name} is not a ${READABLE_TYPE[type] ?? type} field: rename it on the project, or in rness.json`\n )\n return field\n }\n const single = async (\n name: string,\n kind: OptionKind,\n wanted: readonly string[],\n reorder: boolean\n ): Promise<gh.Field | null> => {\n const field = typed(name, 'SINGLE_SELECT')\n if (field !== undefined) return withOptions(field, kind, wanted, reorder)\n // GitHub takes no single-select field without options: none yet, none made.\n if (wanted.length === 0) return null\n added.push(`field ${name}`)\n return gh.createField(\n cache.projectId,\n name,\n { options: inputs(null, kind, wanted, wanted) },\n this.#o\n )\n }\n const plain = async (\n name: string,\n type: 'text' | 'date' | 'number'\n ): Promise<gh.Field> => {\n const field = typed(name, DATA_TYPE[type])\n if (field !== undefined) return field\n // A field 0.15 named otherwise is renamed, not made again: its values\n // and the views showing it stay.\n const was = fields.find((f) => f.name === FORMERLY[name])\n if (type === 'text' && was !== undefined) {\n added.push(`renamed field ${was.name} → ${name}`)\n return gh.renameField(was.id, name, this.#o)\n }\n added.push(`field ${name}`)\n return gh.createField(cache.projectId, name, DATA_TYPE[type], this.#o)\n }\n\n // A new project's Status carries GitHub's default options: replaced, not\n // extended, once. After that, options are only ever added.\n const fresh = cache.fresh === true && layout.statuses.length > 0\n cache.fresh = false\n if (fresh) added.push(...layout.statuses.map((n) => `option ${n}`))\n const status = fresh\n ? await gh.setOptions(\n statusField(fields),\n inputs(null, 'status', layout.statuses, layout.statuses),\n this.#o\n )\n : await withOptions(statusField(fields), 'status', layout.statuses, true)\n // The engine's: where each item belongs (spec 0031 §1).\n const path = await plain(PATH_FIELD, 'text')\n const made: gh.Field[] = []\n for (const f of layout.fields) {\n const field =\n f.type === 'select'\n ? await single(f.name, f.kind, f.options, f.reorder)\n : await plain(f.name, f.type)\n if (field !== null) made.push(field)\n }\n const all = [status, path, ...made]\n // A field no longer declared stays on the project, no longer written.\n const declared = new Set([\n ...layout.fields.map((f) => f.name),\n ...Object.values(FORMERLY),\n ])\n for (const f of fields)\n if (\n f.name !== STATUS_FIELD &&\n f.name !== PATH_FIELD &&\n !GITHUB_FIELDS.has(f.name.toLowerCase()) &&\n !declared.has(f.name)\n )\n added.push(\n `note field ${f.name} is no longer declared: delete it on GitHub if unwanted`\n )\n\n const byName = (name: string): gh.Field | undefined =>\n all.find((f) => f.name === name) ?? fields.find((f) => f.name === name)\n // A field not made yet (a select with no option) is shown once it is.\n const shown = (names: readonly string[] | null) =>\n names === null\n ? null\n : names.flatMap((n) => {\n const f = byName(n)\n return f === undefined ? [] : [f]\n })\n const current = await gh.views(cache.projectId, this.#o)\n // The views by name as GitHub orders them once this is done: a view made\n // goes last, as GitHub adds it.\n const after = current.map((v) => v.name)\n const gone = (name: string) => after.splice(after.indexOf(name), 1)\n // GitHub's first view (`View 1`) becomes the first declared one when it\n // is a table that is not there yet; any other first view is the team's.\n const first = current[0]\n const lead = layout.views[0]\n let renamed: string | null = null\n if (\n first !== undefined &&\n lead !== undefined &&\n first.name === DEFAULT_VIEW &&\n lead.layout === 'table' &&\n !current.some((v) => v.name === lead.name)\n ) {\n added.push(`view ${lead.name}`)\n const visible = shown(lead.fields)\n await gh.updateView(\n first.id,\n {\n name: lead.name,\n ...(lead.filter === null ? {} : { filter: lead.filter }),\n ...(visible === null\n ? {}\n : { visibleFieldIds: visible.map((f) => f.id) }),\n },\n this.#o\n )\n renamed = first.id\n after[0] = lead.name\n }\n const create = async (view: LayoutView): Promise<void> => {\n const column = view.columns === null ? null : byName(view.columns)\n if (view.columns !== null && column === undefined)\n throw new Error(`the project has no field ${view.columns} to column by`)\n await gh.createView(\n board.org,\n board.number,\n {\n name: view.name,\n layout: view.layout,\n filter: view.filter,\n ...(column === null || column === undefined\n ? {}\n : { groupBy: column.databaseId }),\n ...(view.fields === null\n ? {}\n : {\n visibleFields: (shown(view.fields) ?? []).map(\n (f) => f.databaseId\n ),\n }),\n },\n this.#o\n )\n }\n for (const view of layout.views) {\n if (renamed !== null && view === lead) continue\n const there = current.find((v) => v.name === view.name)\n if (there === undefined) {\n added.push(`view ${view.name}`)\n await create(view)\n after.push(view.name)\n continue\n }\n // GitHub changes neither a board's columns nor a roadmap's date in\n // place: a view whose layout or columns differ is made again.\n if (\n there.layout !== gh.LAYOUTS[view.layout] ||\n (view.layout === 'board' && there.columnField !== view.columns)\n ) {\n await gh.deleteView(there.id, this.#o)\n added.push(\n `view ${view.name} remade${\n view.layout === 'board' ? `, columns ${view.columns}` : ''\n }`\n )\n await create(view)\n gone(view.name)\n after.push(view.name)\n continue\n }\n // GitHub returns a filter as it was given, and the fields shown in\n // the project's order: compared as a set (read 2026-10-06).\n const filter = there.filter !== view.filter\n const visible = shown(view.fields)\n const fieldsDiffer =\n visible !== null &&\n (visible.length !== there.fields.length ||\n visible.some((f) => !there.fields.includes(f.name)))\n if (filter || fieldsDiffer) {\n added.push(`updated view ${view.name}`)\n await gh.updateView(\n there.id,\n {\n ...(filter ? { filter: view.filter ?? '' } : {}),\n ...(fieldsDiffer && visible !== null\n ? { visibleFieldIds: visible.map((f) => f.id) }\n : {}),\n },\n this.#o\n )\n }\n }\n // A view no longer declared: rness's own goes, the team's stays, named.\n const wanted = new Set(layout.views.map((v) => v.name))\n for (const v of current) {\n if (v.id === renamed || wanted.has(v.name)) continue\n if (rnessOwn(v)) {\n await gh.deleteView(v.id, this.#o)\n added.push(`deleted view ${v.name}`)\n gone(v.name)\n } else\n added.push(\n `note view ${v.name} is not declared: delete it on GitHub if unwanted`\n )\n }\n const order = after.filter((n) => wanted.has(n))\n const declaredOrder = layout.views\n .map((v) => v.name)\n .filter((n) => order.includes(n))\n if (order.some((n, i) => n !== declaredOrder[i]))\n added.push(\n 'note views are not in the declared order: GitHub keeps them as they were made'\n )\n\n // The items' repository (spec 0018 §2): its label, and the board linked\n // to it — read first, so an unchanged board costs no write.\n const memory = await this.#memory(board.org)\n if (memory.labelId === null) {\n memory.labelId = await gi.createLabel(\n board.org,\n MEMORY,\n { name: LABEL, color: LABEL_COLOR, description: LABEL_DESCRIPTION },\n this.#o\n )\n added.push(`label ${LABEL}`)\n }\n for (const name of layout.labels)\n if ((await this.#ownLabel(board.org, name)).made)\n added.push(`label ${name}`)\n const repository = `${board.org}/${MEMORY}`\n const linked = await gh.linkedRepositories(cache.projectId, this.#o)\n if (!linked.some((r) => r.toLowerCase() === repository.toLowerCase())) {\n await gh.linkRepository(cache.projectId, memory.id, this.#o)\n added.push(`link ${repository}`)\n }\n cache.fields = [\n ...all,\n ...fields.filter((f) => !all.some((a) => a.id === f.id)),\n ]\n return added\n }\n\n /** A collection's label on `.rness`, made when missing; its id, and whether this made it. */\n async #ownLabel(\n org: string,\n name: string\n ): Promise<{ id: string; made: boolean }> {\n let ids = this.#labels.get(org)\n if (ids === undefined) {\n ids = await gi.labelIds(org, MEMORY, this.#o)\n this.#labels.set(org, ids)\n }\n // GitHub's label names ignore case.\n const known = [...ids].find(([n]) => n.toLowerCase() === name.toLowerCase())\n if (known !== undefined) return { id: known[1], made: false }\n const id = await gi.createLabel(\n org,\n MEMORY,\n {\n name,\n color: OWN_LABEL_COLOR,\n description: OWN_LABEL_DESCRIPTION,\n },\n this.#o\n )\n ids.set(name, id)\n return { id, made: true }\n }\n\n async items(\n board: Board,\n options: { bodies?: boolean } = {}\n ): Promise<BoardItem[]> {\n const cache = await this.#cacheOf(board)\n const raw = await gh.listItems(cache.projectId, this.#o, options)\n cache.known = new Map(raw.map((r) => [r.id, r]))\n const memory = `${board.org}/${MEMORY}`.toLowerCase()\n return raw\n .filter((r) => !r.archived)\n .map((r) => {\n const issue =\n r.issue !== null && r.issue.repository.toLowerCase() === memory\n ? r.issue\n : null\n // rness's: a draft of 0.12.0 or an issue of .rness, with Path. Any\n // other item is the team's (spec 0018 §2).\n const ours = r.draftId !== null || issue !== null\n return {\n id: r.id,\n path: ours ? (r.values['Path'] ?? null) : null,\n issue:\n issue === null\n ? null\n : {\n number: issue.number,\n open: issue.open,\n labelled: labelled(issue.labels),\n body: issue.body,\n labels: [...issue.labels],\n },\n title: r.title,\n status: r.values[STATUS_FIELD] ?? null,\n collectionStatus:\n r.values[`${r.values[COLLECTION_FIELD] ?? ''} status`] ?? null,\n type: r.values[COLLECTION_FIELD] ?? null,\n agent: r.values['Agent'] ?? null,\n session: valueOf(r.values, WORKING_SESSION),\n sessions: valueOf(r.values, SESSION_HISTORY),\n values: { ...r.values },\n }\n })\n }\n\n async #set(\n board: Board,\n itemId: string,\n name: string,\n value: string | null\n ): Promise<void> {\n const cache = await this.#cacheOf(board)\n const fields = await this.#fields(board)\n const field =\n fields.find((f) => f.name === name) ??\n fields.find((f) => f.name === FORMERLY[name])\n if (field === undefined) throw new Error(`the board has no field ${name}`)\n let sent:\n | { text: string }\n | { optionId: string }\n | { date: string }\n | { number: number }\n | null = null\n if (value !== null && field.dataType === 'DATE') sent = { date: value }\n else if (value !== null && field.dataType === 'NUMBER')\n sent = { number: Number(value) }\n else if (value !== null && field.options === null) sent = { text: value }\n else if (value !== null) {\n const option = field.options?.find((opt) => opt.name === value)\n if (option === undefined)\n throw new Error(`the field ${name} has no option ${value}`)\n sent = { optionId: option.id }\n }\n await gh.setValue(cache.projectId, itemId, field.id, sent, this.#o)\n const known = cache.known.get(itemId)\n if (known === undefined) return\n if (value === null) delete known.values[field.name]\n else known.values[field.name] = value\n }\n\n async apply(board: Board, step: Step): Promise<Placed | null> {\n if (step.kind === 'unchanged') return null\n const cache = await this.#cacheOf(board)\n if (step.kind === 'create') return this.#create(board, cache, step.want)\n if (step.kind === 'remove') {\n // Its collection's own project holds it (spec 0025 §3): off this board only.\n await gh.deleteItem(cache.projectId, step.id, this.#o)\n cache.known.delete(step.id)\n return null\n }\n const known = await this.#known(board, step.id)\n if (step.kind === 'archive' || step.kind === 'close') {\n // A document gone: its issue closed as not planned (spec 0018 §2).\n if (step.kind === 'close' && known.issue?.open === true)\n await gi.closeIssue(known.issue.id, this.#o)\n await gh.archive(cache.projectId, step.id, this.#o)\n cache.known.delete(step.id)\n return null\n }\n if (step.kind === 'body') {\n const issue = this.#issueOf(known)\n await gi.updateIssue(issue.id, { body: step.body }, this.#o)\n issue.body = step.body\n return null\n }\n const labelId = await this.#labelId(board)\n if (step.kind === 'convert') {\n const made = await gh.convertDraft(\n step.id,\n (await this.#memory(board.org)).id,\n this.#o\n )\n known.draftId = null\n known.issue = {\n ...made,\n open: true,\n repository: `${board.org}/${MEMORY}`,\n body: '',\n labels: [],\n }\n await this.#issue(known, step.want, labelId)\n await this.#ownLabels(board.org, known, step.want)\n await this.#values(board, step.id, step.want)\n return { id: step.id, number: made.number }\n }\n const issue = this.#issueOf(known)\n if (step.reopen) {\n await gi.reopenIssue(issue.id, this.#o)\n issue.open = true\n }\n await this.#issue(known, step.want, labelId)\n await this.#ownLabels(board.org, known, step.want)\n await this.#values(board, step.id, step.want)\n return null\n }\n\n /**\n * An open issue of `.rness`, labelled `rness`, whose body starts with the\n * document's first line — made by an earlier sync whose item the board's\n * listing did not show yet, 18 s later (spec 0020 §7) — or null. Read once\n * per process, at the first create; an issue taken is taken off the list.\n */\n async #adoptable(\n board: Board,\n cache: Cache,\n want: Desired\n ): Promise<gi.OpenIssue | null> {\n cache.open ??= await gi.openIssues(board.org, MEMORY, LABEL, this.#o)\n const at = cache.open.findIndex((i) => firstLine(i.body) === want.body)\n if (at === -1) return null\n return cache.open.splice(at, 1)[0] ?? null\n }\n\n /**\n * A new document's issue: labelled, the first line as body, added to the\n * board, Path first. One already made for it is added instead: GitHub adds\n * an issue already on the board as the item it is, so no second one.\n */\n async #create(board: Board, cache: Cache, want: Desired): Promise<Placed> {\n const memory = await this.#memory(board.org)\n const labelId = await this.#labelId(board)\n const found = await this.#adoptable(board, cache, want)\n if (found !== null) {\n const id = await gh.addItem(cache.projectId, found.id, this.#o)\n const known: gh.RawItem = cache.known.get(id) ?? {\n id,\n draftId: null,\n issue: {\n id: found.id,\n number: found.number,\n open: true,\n repository: `${board.org}/${MEMORY}`,\n body: found.body,\n labels: [LABEL],\n },\n title: found.title,\n archived: false,\n values: {},\n }\n cache.known.set(id, known)\n await this.#issue(known, want, labelId)\n await this.#ownLabels(board.org, known, want)\n await this.#values(board, id, want)\n return { id, number: found.number, adopted: true }\n }\n const made = await gi.createIssue(\n memory.id,\n { title: want.title, body: want.body, labelIds: [labelId] },\n this.#o\n )\n const id = await gh.addItem(cache.projectId, made.id, this.#o)\n cache.known.set(id, {\n id,\n draftId: null,\n issue: {\n ...made,\n open: true,\n repository: `${board.org}/${MEMORY}`,\n body: want.body,\n labels: [LABEL],\n },\n title: want.title,\n archived: false,\n values: {},\n })\n await this.#ownLabels(board.org, cache.known.get(id)!, want)\n await this.#values(board, id, want)\n return { id, number: made.number }\n }\n\n /** The label and the title an issue of the board carries. */\n async #issue(\n known: gh.RawItem,\n want: Desired,\n labelId: string\n ): Promise<void> {\n const issue = this.#issueOf(known)\n if (!labelled(issue.labels)) {\n await gi.addLabels(issue.id, [labelId], this.#o)\n issue.labels.push(LABEL)\n }\n if (known.title !== want.title) {\n await gi.updateIssue(issue.id, { title: want.title }, this.#o)\n known.title = want.title\n }\n }\n\n /** The labels a collection gives the issue, and those it takes off (spec 0025 §4). */\n async #ownLabels(\n org: string,\n known: gh.RawItem,\n want: Desired\n ): Promise<void> {\n if (want.labels.length === 0 && want.unlabels.length === 0) return\n const issue = this.#issueOf(known)\n const carried = (name: string): string | undefined =>\n issue.labels.find((l) => l.toLowerCase() === name.toLowerCase())\n const add = want.labels.filter((l) => carried(l) === undefined)\n const off = want.unlabels.filter((l) => carried(l) !== undefined)\n if (add.length > 0) {\n const ids: string[] = []\n for (const name of add) ids.push((await this.#ownLabel(org, name)).id)\n await gi.addLabels(issue.id, ids, this.#o)\n issue.labels.push(...add)\n }\n if (off.length > 0) {\n const ids: string[] = []\n for (const name of off) ids.push((await this.#ownLabel(org, name)).id)\n await gi.removeLabels(issue.id, ids, this.#o)\n issue.labels = issue.labels.filter(\n (l) => !off.some((o) => o.toLowerCase() === l.toLowerCase())\n )\n }\n }\n\n /** Path first — an issue on the board without it is the team's — then the fields, each only when it differs. */\n async #values(board: Board, id: string, want: Desired): Promise<void> {\n const values = (await this.#known(board, id)).values\n const fields = await this.#fields(board)\n // A select with no option yet has no field yet: nothing to write.\n const declared = Object.entries(want.values).filter(([name]) =>\n fields.some((f) => f.name === name || FORMERLY[name] === f.name)\n )\n const [where, rest] = [\n declared.filter(([name]) => name === COLLECTION_FIELD),\n declared.filter(([name]) => name !== COLLECTION_FIELD),\n ]\n const wanted: [string, string | null][] = [\n [PATH_FIELD, want.path],\n ...where,\n [STATUS_FIELD, want.status],\n ...(want.statusField === null\n ? []\n : ([[want.statusField, want.status]] as [string, string | null][])),\n ...rest,\n ]\n for (const [name, value] of wanted)\n if (valueOf(values, name) !== value)\n await this.#set(board, id, name, value)\n }\n\n async #known(board: Board, id: string): Promise<gh.RawItem> {\n const cache = await this.#cacheOf(board)\n if (!cache.known.has(id)) await this.items(board)\n const known = cache.known.get(id)\n if (known === undefined) throw new Error(`the board has no item ${id}`)\n return known\n }\n\n #issueOf(known: gh.RawItem): gh.RawIssue {\n if (known.issue === null)\n throw new Error(`the board's item ${known.id} is no issue`)\n return known.issue\n }\n\n async #labelId(board: Board): Promise<string> {\n const id = (await this.#memory(board.org)).labelId\n if (id === null)\n throw new Error(\n `${board.org}/${MEMORY} has no label ${LABEL}: run rness board push`\n )\n return id\n }\n\n async mark(\n board: Board,\n itemIds: readonly string[],\n session: string | null,\n fields: MarkFields = { agent: 'Agent', session: WORKING_SESSION }\n ): Promise<void> {\n for (const id of itemIds) {\n await this.#set(\n board,\n id,\n fields.agent,\n session === null ? null : WORKING\n )\n if (fields.session !== null)\n await this.#set(board, id, fields.session, session)\n }\n }\n\n async describe(\n board: Board,\n text: { readme: string | null; description: string | null }\n ): Promise<string[]> {\n const cache = await this.#cacheOf(board)\n const now = await gh.projectText(cache.projectId, this.#o)\n const next: { readme?: string; shortDescription?: string } = {}\n // GitHub keeps a README's text as sent, up to its trailing blanks.\n if (text.readme !== null && now.readme.trimEnd() !== text.readme.trimEnd())\n next.readme = text.readme.trimEnd()\n if (text.description !== null && now.shortDescription !== text.description)\n next.shortDescription = text.description\n if (next.readme === undefined && next.shortDescription === undefined)\n return []\n await gh.updateProjectText(cache.projectId, next, this.#o)\n return [\n ...(next.readme === undefined ? [] : ['readme']),\n ...(next.shortDescription === undefined ? [] : ['short description']),\n ]\n }\n\n async postUpdates(\n board: Board,\n updates: readonly StatusUpdate[]\n ): Promise<string[]> {\n if (updates.length === 0) return []\n const cache = await this.#cacheOf(board)\n const there = await gh.statusUpdates(cache.projectId, this.#o)\n const written: string[] = []\n for (const u of updates) {\n const marker = markerOf(u.path)\n const input = {\n body: `${u.body.trimEnd()}\\n\\n${marker}`,\n status: u.health.toUpperCase().replace('-', '_'),\n startDate: u.startDate,\n targetDate: u.targetDate,\n }\n const posted = there.find((p) => p.body.includes(marker))\n if (posted === undefined) {\n await gh.createStatusUpdate(cache.projectId, input, this.#o)\n written.push(`posted ${u.path}`)\n } else if (\n posted.body.trimEnd() !== input.body ||\n posted.status !== input.status ||\n (posted.startDate ?? null) !== input.startDate ||\n (posted.targetDate ?? null) !== input.targetDate\n ) {\n await gh.updateStatusUpdate(posted.id, input, this.#o)\n written.push(`updated ${u.path}`)\n }\n }\n return written\n }\n}\n","import type { StatusUpdate } from '../board/collection.ts'\nimport type { Layout } from '../board/layout.ts'\nimport type { BoardItem, Placed, Step } from '../board/plan.ts'\nimport { type ResolvedToken, resolveToken } from './auth.ts'\nimport { approvalUrl } from './device-flow.ts'\nimport { GitHubBoards } from './github-board.ts'\nimport * as gj from './github-journal.ts'\nimport type { JournalIssue } from './github-journal.ts'\nimport {\n type ApiOptions,\n type CreateRepositoryResult,\n type RateWait,\n type RepositoryListing,\n createRepository,\n getOrgMembership,\n getScopes,\n getUser,\n listRepositories,\n listUserMemberships,\n} from './github.ts'\nimport type {\n Board,\n GitCredentials,\n MarkFields,\n Organization,\n OrganizationAccess,\n Provider,\n} from './provider.ts'\n\nconst GITHUB_HTTPS = 'https://github.com/'\n\n/**\n * GitHub as a user: the token of `GITHUB_TOKEN`, `GH_TOKEN` or `rness login`\n * — or none, and then it is GitHub seen anonymously (public repositories).\n */\nexport class GitHubOAuthProvider implements Provider {\n readonly #token: ResolvedToken | null\n readonly #apiBase: string | undefined\n readonly #wait: RateWait | undefined\n #login: Promise<{ login: string } | null> | undefined\n #boardClient: GitHubBoards | undefined\n\n get authenticated(): boolean {\n return this.#token !== null\n }\n\n constructor(options: {\n token: ResolvedToken | null\n apiBase?: string\n wait?: RateWait\n }) {\n this.#token = options.token\n this.#apiBase = options.apiBase\n this.#wait = options.wait\n }\n\n #api(token: string): ApiOptions {\n return {\n token,\n ...(this.#apiBase === undefined ? {} : { apiBase: this.#apiBase }),\n ...(this.#wait === undefined ? {} : { wait: this.#wait }),\n }\n }\n\n identity(): Promise<{ login: string } | null> {\n this.#login ??= (async () => {\n const t = this.#token\n if (t === null) return null\n // A stored login knows its name; an environment token has to be asked.\n if (t.login !== null) return { login: t.login }\n try {\n return await getUser(this.#api(t.token))\n } catch {\n return null\n }\n })()\n return this.#login\n }\n\n async listOrganizations(): Promise<Organization[]> {\n if (this.#token === null) return []\n const memberships = await listUserMemberships(this.#api(this.#token.token))\n return memberships.map((m) => ({\n login: m.login,\n approved: true,\n canGrant: m.role === 'admin',\n }))\n }\n\n approvalUrl(): string | null {\n // The page approves rness, the OAuth app of `rness login`. A token from\n // the environment belongs to some other app (gh, a PAT): approving rness\n // would not end a wait for it, so there is no page to offer.\n return this.#token?.source === 'login' ? approvalUrl() : null\n }\n\n async organizationAccess(org: string): Promise<OrganizationAccess> {\n if (this.#token === null) return 'unknown'\n try {\n return await getOrgMembership(org, this.#api(this.#token.token))\n } catch {\n return 'unknown'\n }\n }\n\n async listRepositories(owner: string): Promise<RepositoryListing> {\n return listRepositories(owner, {\n token: this.#token?.token,\n ...(this.#apiBase === undefined ? {} : { apiBase: this.#apiBase }),\n self: async () => (await this.identity())?.login ?? null,\n })\n }\n\n async createRepository(\n owner: string,\n name: string\n ): Promise<CreateRepositoryResult> {\n if (this.#token === null)\n return { kind: 'refused', reason: 'not logged in' }\n return createRepository(owner, name, {\n ...this.#api(this.#token.token),\n self: (await this.identity())?.login ?? null,\n })\n }\n\n async scopes(): Promise<string[] | null> {\n if (this.#token === null) return null\n return getScopes(this.#api(this.#token.token))\n }\n\n #boards(): GitHubBoards {\n if (this.#token === null)\n throw new Error('boards need a GitHub login: run rness login')\n this.#boardClient ??= new GitHubBoards(this.#api(this.#token.token))\n return this.#boardClient\n }\n\n // The board methods are async so that a missing login rejects, never throws.\n async checkIssues(org: string): Promise<void> {\n return this.#boards().checkIssues(org)\n }\n\n async createBoard(org: string, title?: string): Promise<Board> {\n return this.#boards().createBoard(org, title)\n }\n\n async board(org: string, number: number): Promise<Board | null> {\n return this.#boards().board(org, number)\n }\n\n async ensureLayout(board: Board, layout: Layout): Promise<string[]> {\n return this.#boards().ensureLayout(board, layout)\n }\n\n async items(\n board: Board,\n options?: { bodies?: boolean }\n ): Promise<BoardItem[]> {\n return this.#boards().items(board, options)\n }\n\n async apply(board: Board, step: Step): Promise<Placed | null> {\n return this.#boards().apply(board, step)\n }\n\n async mark(\n board: Board,\n itemIds: readonly string[],\n session: string | null,\n fields?: MarkFields\n ): Promise<void> {\n return this.#boards().mark(board, itemIds, session, fields)\n }\n\n async describe(\n board: Board,\n text: { readme: string | null; description: string | null }\n ): Promise<string[]> {\n return this.#boards().describe(board, text)\n }\n\n async postUpdates(\n board: Board,\n updates: readonly StatusUpdate[]\n ): Promise<string[]> {\n return this.#boards().postUpdates(board, updates)\n }\n\n #journalApi(): ApiOptions {\n if (this.#token === null)\n throw new Error('the journal needs a GitHub login: run rness login')\n return this.#api(this.#token.token)\n }\n\n // The journal's methods are async so that a missing login rejects, never throws.\n async journalIssue(\n owner: string,\n repo: string,\n planPath: string\n ): Promise<JournalIssue | null> {\n return gj.journalIssue(owner, repo, planPath, this.#journalApi())\n }\n\n async createJournalIssue(\n owner: string,\n repo: string,\n planPath: string,\n issue: { title: string; body: string }\n ): Promise<JournalIssue> {\n return gj.createJournalIssue(\n owner,\n repo,\n planPath,\n issue,\n this.#journalApi()\n )\n }\n\n async issueOf(\n owner: string,\n repo: string,\n number: number\n ): Promise<{ id: string; number: number; open: boolean } | null> {\n return gj.issueOf(owner, repo, number, this.#journalApi())\n }\n\n async addSubIssue(parentId: string, childId: string): Promise<void> {\n return gj.addSubIssue(parentId, childId, this.#journalApi())\n }\n\n async comment(issueId: string, body: string): Promise<void> {\n return gj.comment(issueId, body, this.#journalApi())\n }\n\n async pullRequestFor(\n owner: string,\n repo: string,\n branch: string\n ): Promise<{ number: number; state: string } | null> {\n return gj.pullRequestFor(owner, repo, branch, this.#journalApi())\n }\n\n credentialsFor(url: string): GitCredentials | null {\n if (this.#token === null || !url.startsWith(GITHUB_HTTPS)) return null\n return { username: 'x-access-token', password: this.#token.token }\n }\n}\n\n/** The CLI's provider: whatever token this machine has, against `apiBase`. */\nexport async function githubProvider(\n apiBase?: string,\n wait?: RateWait\n): Promise<Provider> {\n return new GitHubOAuthProvider({\n token: await resolveToken(),\n ...(apiBase === undefined ? {} : { apiBase }),\n ...(wait === undefined ? {} : { wait }),\n })\n}\n","import { glob, readFile, rm } from 'node:fs/promises'\nimport { isAbsolute, join, posix, relative, resolve, sep } from 'node:path'\n\nimport { exists } from './fs.ts'\nimport { clone, originUrl } from './git.ts'\nimport { NAME, NAME_RULE, parseRepoSpec, writeManifest } from './manifest.ts'\nimport type { GitCredentials } from './provider.ts'\nimport type { Manifest, ScopeEntry } from './types.ts'\n\nexport interface AddRepositoryInput {\n root: string\n rnessDir: string\n manifest: Manifest\n /** `<repo>`, `<owner>/<repo>`, or a clone URL. */\n spec: string\n /** The owner of a bare `<repo>`; null in a blank workspace, which refuses one. */\n org: string | null\n host: string\n /** Sub-scopes relative to the repository (`apps/web`); each becomes scope `<basename>` extending `<repo>`. */\n scopes: readonly string[]\n /** HTTPS credentials for the URL the spec resolves to, when there are any. */\n credentialsFor?: (url: string) => GitCredentials | null\n}\n\nexport interface AddRepositoryResult {\n manifest: Manifest\n name: string\n url: string\n action: 'cloned' | 'adopted'\n /** Scope names written to the manifest, repository scope first. */\n declared: string[]\n}\n\n/** Clone (or adopt) a repository under `org/` and declare it — manifest written last (spec 0003 §3). */\nexport async function addRepository(\n input: AddRepositoryInput\n): Promise<AddRepositoryResult> {\n const { name, url } = parseRepoSpec(input.spec, input.org, input.host)\n const dir = join(input.root, 'org', name)\n\n // Validate every scope before touching the filesystem: a malformed request\n // must never leave a clone behind that the manifest doesn't know about. Only\n // the per-sub directory-existence check needs the clone (or adoption) to have\n // happened, so it waits until after.\n const repoPath = `org/${name}`\n // The repository scope gets the same protection as a sub-scope: a name\n // already taken by another path is a collision, not something to overwrite.\n // At the same path the entry keeps its `extends` — a hand-added shared\n // parent scope survives every later `add` of the repository.\n const current = input.manifest.scopes[name]\n if (current !== undefined && current.path !== repoPath)\n throw new Error(`scope \"${name}\" already points at ${current.path}`)\n const scopes: Record<string, ScopeEntry> = {\n ...input.manifest.scopes,\n [name]: { path: repoPath, extends: current?.extends ?? [] },\n }\n const subs: { path: string; base: string }[] = []\n for (const sub of input.scopes) {\n const clean = sub.replace(/^\\/+|\\/+$/g, '')\n const segments = clean.split('/')\n if (segments.some((s) => s === '' || s === '.' || s === '..'))\n throw new Error(\n `sub-scope \"${clean}\" must be a relative path inside the repository`\n )\n const base = segments.at(-1) ?? ''\n const path = `org/${name}/${clean}`\n if (!NAME.test(base))\n throw new Error(\n `the last segment of sub-scope \"${clean}\" may only contain ${NAME_RULE}`\n )\n const existing = scopes[base]\n if (existing !== undefined && existing.path !== path)\n throw new Error(`scope \"${base}\" already points at ${existing.path}`)\n scopes[base] = { path, extends: [name] }\n subs.push({ path, base })\n }\n\n let action: AddRepositoryResult['action']\n if (await exists(dir)) {\n const origin = await originUrl(dir)\n if (origin === null)\n throw new Error(`org/${name} exists and is not a git clone`)\n if (origin !== url)\n throw new Error(`org/${name} is a clone of ${origin}, not ${url}`)\n action = 'adopted'\n } else {\n await clone(url, dir, input.credentialsFor?.(url) ?? null)\n action = 'cloned'\n }\n\n const declared = [name]\n for (const { path, base } of subs) {\n if (!(await exists(join(input.root, ...path.split('/'))))) {\n // Only a clone this call just made is ours to remove: it isn't in the\n // manifest yet, so nothing is lost. An adopted directory predates this\n // call and is left alone.\n if (action === 'cloned') await rm(dir, { recursive: true, force: true })\n throw new Error(`${path} does not exist`)\n }\n declared.push(base)\n }\n\n const manifest: Manifest = {\n ...input.manifest,\n repos: { ...input.manifest.repos, [name]: { url } },\n scopes,\n }\n await writeManifest(input.rnessDir, manifest)\n return { manifest, name, url, action, declared }\n}\n\n/** The clone of `repos` that holds `dir`: its name, directory and URL; null in `.rness/`, at the root, or outside. */\nexport function cloneHolding(\n root: string,\n repos: Manifest['repos'],\n dir: string\n): { name: string; dir: string; url: string } | null {\n for (const [name, repo] of Object.entries(repos)) {\n const clone = resolve(root, 'org', name)\n const r = relative(clone, resolve(dir))\n if (r === '' || (!r.startsWith('..') && !isAbsolute(r)))\n return { name, dir: clone, url: repo.url }\n }\n return null\n}\n\n/** Directories matched by `package.json#workspaces` that hold a `package.json`, POSIX-relative, sorted. */\nexport async function workspaceDirs(repoDir: string): Promise<string[]> {\n let patterns: string[] = []\n try {\n const pkg = JSON.parse(\n await readFile(join(repoDir, 'package.json'), 'utf8')\n ) as { workspaces?: unknown }\n const w = pkg.workspaces\n if (Array.isArray(w))\n patterns = w.filter((p): p is string => typeof p === 'string')\n else if (\n w !== null &&\n typeof w === 'object' &&\n Array.isArray((w as { packages?: unknown }).packages)\n ) {\n patterns = (w as { packages: unknown[] }).packages.filter(\n (p): p is string => typeof p === 'string'\n )\n }\n } catch {\n return []\n }\n const dirs = new Set<string>()\n for (const pattern of patterns) {\n for await (const match of glob(pattern, { cwd: repoDir })) {\n const rel = match.split(sep).join(posix.sep)\n if (await exists(join(repoDir, ...rel.split(posix.sep), 'package.json')))\n dirs.add(rel)\n }\n }\n return [...dirs].sort()\n}\n","import type {\n autocompleteMultiselect,\n cancel,\n confirm,\n intro,\n isCancel,\n log,\n multiselect,\n note,\n outro,\n select,\n spinner,\n text,\n} from '@clack/prompts'\n\n/** The `@clack/prompts` functions the interactive commands use. */\nexport interface Prompts {\n text: typeof text\n confirm: typeof confirm\n multiselect: typeof multiselect\n select: typeof select\n autocompleteMultiselect: typeof autocompleteMultiselect\n isCancel: typeof isCancel\n // The session look (spec 0007 §5b). Optional: a scripted terminal in a\n // test has prompts only, and gets the plain look.\n intro?: typeof intro\n outro?: typeof outro\n cancel?: typeof cancel\n note?: typeof note\n log?: typeof log\n spinner?: typeof spinner\n}\n\n/** What an interactive command needs from the terminal; tests replace it with scripted answers. */\nexport interface Terminal {\n isTty(): boolean\n prompts(): Promise<Prompts>\n}\n\nexport const defaultTerminal: Terminal = {\n isTty: () => process.stdin.isTTY === true && process.stdout.isTTY === true,\n // Lazy: the prompt library stays off every non-interactive path.\n prompts: () => import('@clack/prompts'),\n}\n","import { readdir } from 'node:fs/promises'\nimport { dirname, join, parse, resolve } from 'node:path'\n\nimport { exists } from './fs.ts'\nimport { isWorkspaceClone } from './manifest.ts'\nimport type { Workspace } from './types.ts'\n\n/** Walk up from `startDir`: a directory holding `.rness/rness.json` is the root. Only when none exists anywhere above does a directory that itself holds `rness.json` count — a standalone checkout of the context repository (CI): that directory is `.rness/`, its parent the root. */\nexport async function findWorkspace(startDir: string): Promise<Workspace> {\n const start = resolve(startDir)\n const { root: fsRoot } = parse(start)\n const ancestors: string[] = []\n for (let dir = start; ; dir = dirname(dir)) {\n ancestors.push(dir)\n if (dir === fsRoot) break\n }\n for (const dir of ancestors) {\n if (await exists(join(dir, '.rness', 'rness.json')))\n return { root: dir, rnessDir: join(dir, '.rness') }\n }\n for (const dir of ancestors) {\n if (await exists(join(dir, 'rness.json')))\n return { root: dirname(dir), rnessDir: dir }\n }\n throw new Error(`no rness workspace found above ${startDir}`)\n}\n\n/** The repositories cloned under `<root>/org`, by name (spec 0009 §3). */\nexport async function clonesIn(root: string): Promise<Set<string>> {\n try {\n const entries = await readdir(join(root, 'org'), { withFileTypes: true })\n return new Set(\n entries\n .filter((e) => e.isDirectory() && isWorkspaceClone(e.name))\n .map((e) => e.name)\n )\n } catch {\n return new Set()\n }\n}\n","import { styleText } from 'node:util'\n\n// The CLI's look (spec 0007). This module imports `node:util` only, so the\n// lean commands (`context`, `validate`) can use it. Whether a stream gets\n// colour is `util.styleText`'s decision: a terminal, unless NO_COLOR; any\n// stream with FORCE_COLOR. Off a terminal every function returns plain text —\n// the bytes scripts, CI and the tests have always read.\n\nexport type Tone = 'done' | 'idle' | 'info' | 'warn' | 'error'\n\ntype Format = Parameters<typeof styleText>[0]\n\nconst FORMAT: Record<Tone, Format> = {\n done: 'green',\n idle: 'dim',\n info: 'cyan',\n warn: 'yellow',\n error: 'red',\n}\n\n/** https://no-color.org: any non-empty value; FORCE_COLOR, being explicit, wins. */\nfunction noColor(): boolean {\n const off = process.env['NO_COLOR']\n return (\n off !== undefined && off !== '' && process.env['FORCE_COLOR'] === undefined\n )\n}\n\nexport function paint(\n tone: Tone,\n text: string,\n stream: NodeJS.WriteStream = process.stdout\n): string {\n if (noColor()) return text\n return styleText(FORMAT[tone], text, { stream, validateStream: true })\n}\n\nconst IDLE = new Set(['unchanged', 'skipped', 'not cloned', 'current'])\nconst DONE = new Set([\n 'created',\n 'cloned',\n 'adopted',\n 'declared',\n 'installed',\n 'committed',\n 'updated',\n 'upgraded',\n 'pulled',\n 'pushed',\n 'logged in',\n 'logged out',\n 'synced',\n 'listed',\n])\n\n/** What a status verb says about the step: it changed something, it did not, or it is progress. */\nexport function toneOf(verb: string): Tone {\n if (DONE.has(verb)) return 'done'\n if (IDLE.has(verb)) return 'idle'\n if (verb === 'stale') return 'warn'\n return 'info'\n}\n\n/** The width verbs are padded to; a longer verb (`unchanged`) takes its own. */\nconst COLUMN = 8\n\n/**\n * One status line: the verb painted by its tone and padded to the column,\n * then `rest`, untouched — a path stays readable on any background.\n */\nexport function status(\n verb: string,\n rest: string,\n stream: NodeJS.WriteStream = process.stdout\n): string {\n const pad = ' '.repeat(Math.max(0, COLUMN - verb.length))\n return `${paint(toneOf(verb), verb, stream)}${pad} ${rest}`\n}\n\nexport function bold(\n text: string,\n stream: NodeJS.WriteStream = process.stdout\n): string {\n if (noColor()) return text\n return styleText('bold', text, { stream, validateStream: true })\n}\n\n/**\n * Backgrounds for a badge. `intro` opens a session; the others close one, so\n * the verdict is legible at a glance without reading the words.\n */\nconst BACKGROUND: Record<BadgeTone, Format> = {\n intro: ['bgCyan', 'black', 'bold'],\n done: ['bgGreen', 'black', 'bold'],\n idle: ['bgCyan', 'black', 'bold'],\n info: ['bgCyan', 'black', 'bold'],\n warn: ['bgYellow', 'black', 'bold'],\n error: ['bgRed', 'white', 'bold'],\n}\n\nexport type BadgeTone = Tone | 'intro'\n\n/**\n * Text on a coloured background — the intro of a session, or its verdict.\n * Without colour it is the bare text: padding only makes sense around a\n * background.\n */\nexport function badge(\n text: string,\n tone: BadgeTone | NodeJS.WriteStream = 'intro',\n stream: NodeJS.WriteStream = process.stdout\n): string {\n // The stream used to be the second argument; callers that pass one still\n // get the intro badge they asked for before tones existed.\n const [t, s] =\n typeof tone === 'string'\n ? ([tone, stream] as const)\n : (['intro', tone] as const)\n if (noColor()) return text\n const padded = ` ${text} `\n const painted = styleText(BACKGROUND[t], padded, {\n stream: s,\n validateStream: true,\n })\n return painted === padded ? text : painted\n}\n\n/**\n * Reverse video, for what is selected: the active tab of `rness status`.\n * Without colour, brackets in place of the text's first and last characters\n * — spaces by convention — so the width is kept.\n */\nexport function inverse(\n text: string,\n stream: NodeJS.WriteStream = process.stdout\n): string {\n const plain = `[${text.slice(1, -1)}]`\n if (noColor()) return plain\n const painted = styleText('inverse', text, { stream, validateStream: true })\n return painted === text ? plain : painted\n}\n\n/** `1 repository`, `2 repositories`: the noun agrees with the number. */\nexport function count(n: number, [one, many]: [string, string]): string {\n return `${n} ${n === 1 ? one : many}`\n}\n\n/** Grey, for what is read after the rest: a box of next steps. */\nexport function grey(\n text: string,\n stream: NodeJS.WriteStream = process.stdout\n): string {\n if (noColor()) return text\n return styleText('gray', text, { stream, validateStream: true })\n}\n\n/**\n * Can this terminal draw characters beyond ASCII? The rule `@clack/prompts`\n * follows for its own symbols: everywhere but the Linux console and the\n * legacy Windows console.\n */\nexport function unicode(): boolean {\n if (process.platform !== 'win32') return process.env['TERM'] !== 'linux'\n return (\n process.env['WT_SESSION'] !== undefined ||\n process.env['TERM_PROGRAM'] === 'vscode'\n )\n}\n\n/** A private repository, said with a padlock; a public one says nothing. */\nexport const PRIVATE_MARK = '🔒'\n\n/** `warning: …` for stderr, the prefix painted. */\nexport function warn(text: string): string {\n return `${paint('warn', 'warning:', process.stderr)} ${text}`\n}\n\n// `rness`, rendered once with cfonts' \"tiny\" font and kept as a constant: one\n// fixed word does not need a font engine at run time.\nconst WORD = [' █▀█ █▄ █ █▀▀ █▀▀ █▀▀', ' █▀▄ █ ▀█ ██▄ ▄▄█ ▄▄█']\n\nconst FROM = [63, 185, 80] as const // green\nconst TO = [57, 197, 207] as const // cyan\n\n/**\n * The only hand-written escape sequences of the code base: `util.styleText`\n * has no 24-bit colour. A left-to-right gradient, one colour per column.\n */\nfunction gradient(line: string): string {\n const chars = [...line]\n const last = Math.max(1, chars.length - 1)\n const painted = chars.map((ch, i) => {\n if (ch === ' ') return ch\n const [r, g, b] = FROM.map((from, c) =>\n Math.round(from + (((TO[c] ?? from) - from) * i) / last)\n )\n return `\\x1b[38;2;${r};${g};${b}m${ch}`\n })\n return `${painted.join('')}\\x1b[39m`\n}\n\n/**\n * The banner, or `''` where it has no place: a pipe, a file, CI. Shown on a\n * terminal (and with FORCE_COLOR); the gradient only where the terminal says\n * it has true colour, plain green otherwise, no colour under NO_COLOR.\n */\nexport function banner(\n version: string,\n stream: NodeJS.WriteStream = process.stdout\n): string {\n const forced =\n process.env['FORCE_COLOR'] !== undefined &&\n process.env['FORCE_COLOR'] !== '0'\n if (stream.isTTY !== true && !forced) return ''\n const coloured = paint('done', 'x', stream) !== 'x'\n const trueColour =\n coloured &&\n typeof stream.hasColors === 'function' &&\n stream.hasColors(2 ** 24)\n const word = WORD.map((line) =>\n trueColour ? gradient(line) : paint('done', line, stream)\n )\n return [\n '',\n ...word,\n '',\n ` ${bold(`rness v${version}`, stream)}`,\n ` ${paint('idle', 'Context for AI coding agents, across an organization’s repositories', stream)}`,\n '',\n '',\n ].join('\\n')\n}\n","import { paint } from './core/style.ts'\n\n/**\n * Shared CLI error contract: one line on stderr, and — only under\n * `RNESS_DEBUG=1` — the stack trace instead of the plain message (the stack\n * already starts with `Error: <message>`, so printing both would repeat it).\n */\nexport function reportError(e: unknown): number {\n const debug = process.env['RNESS_DEBUG'] === '1'\n if (debug && e instanceof Error && e.stack) {\n process.stderr.write(`${e.stack}\\n`)\n } else {\n const message = e instanceof Error ? e.message : String(e)\n process.stderr.write(`${paint('error', message, process.stderr)}\\n`)\n }\n return 1\n}\n","import { realpath } from 'node:fs/promises'\n\nimport { envToken, readAuth, resolveToken, writeAuth } from '../core/auth.ts'\nimport { canOpenBrowser, openInBrowser } from '../core/browser.ts'\nimport {\n BOARD_SCOPE,\n LoginError,\n type PollDeps,\n SCOPES,\n pollForToken,\n requestDeviceCode,\n} from '../core/device-flow.ts'\nimport { DEFAULT_GITHUB_API, getUser } from '../core/github.ts'\nimport { loadManifest } from '../core/manifest.ts'\nimport { rnessCommand } from '../core/pm.ts'\nimport { PROVIDERS, unsupportedProviderMessage } from '../core/providers.ts'\nimport { isStableInstall, setupGit } from '../core/setup-git.ts'\nimport { type Terminal, defaultTerminal } from '../core/terminal.ts'\nimport type { Manifest } from '../core/types.ts'\nimport { type Ui, makeUi } from '../core/ui.ts'\nimport { findWorkspace } from '../core/workspace.ts'\nimport { reportError } from '../report.ts'\n\nexport interface LoginOptions {\n /** `--setup-git` / `--no-setup-git`; undefined asks in a terminal. */\n setupGit?: boolean\n /** Internal (tests): GitHub REST API base. */\n githubApi?: string\n /** Ask for the `project` scope even where no board is declared (`board push` creating one). */\n project?: boolean\n}\n\nexport interface LoginDeps extends PollDeps {\n terminal?: Terminal\n /** The caller's reporter: `create` logs in from inside its own session. */\n ui?: Ui\n /** Open a URL in the browser; failures are nobody's problem. */\n open?: (url: string) => void\n /** This rness's launcher, as git will have to find it. */\n bin?: string\n /** Where to look for the workspace; the current directory by default. */\n cwd?: string\n}\n\n/** The question of spec 0004 §5, or the line that replaces it under npx. */\nasync function offerSetupGit(\n opts: LoginOptions,\n terminal: Terminal,\n bin: string,\n ui: Ui\n): Promise<void> {\n if (opts.setupGit === false) return\n if (!isStableInstall(bin)) {\n ui.hint(\n 'install rness globally to let git use your login: npm i -g @rness/cli'\n )\n return\n }\n if (opts.setupGit !== true) {\n if (!terminal.isTty()) return\n const p = await terminal.prompts()\n const ok = await p.confirm({\n message: 'Use rness to authenticate git over HTTPS for github.com?',\n initialValue: true,\n })\n if (p.isCancel(ok) || ok !== true) return\n }\n const changed = await setupGit(process.execPath, bin)\n ui.line(\n changed ? 'updated' : 'unchanged',\n `git: rness answers for https://github.com (${rnessCommand()} logout undoes it)`,\n `git now asks rness for your github.com login over HTTPS (${rnessCommand()} logout undoes it)`\n )\n}\n\n/** The manifest of the workspace around `cwd`; null outside one (or when it is unreadable: login concerns the machine). */\nasync function manifestAround(cwd: string): Promise<Manifest | null> {\n try {\n return await loadManifest((await findWorkspace(cwd)).rnessDir)\n } catch {\n return null\n }\n}\n\n/** Scopes as GitHub words them: separated by commas, spaces, or both. */\nfunction splitScopes(scopes: string): string[] {\n return scopes.split(/[\\s,]+/).filter((s) => s !== '')\n}\n\n/**\n * `rness login`: GitHub's device flow (spec 0004 §2). Concerns the machine,\n * not a workspace: never delegated to a pinned copy.\n */\nexport async function loginCommand(\n opts: LoginOptions,\n deps: LoginDeps = {}\n): Promise<number> {\n const terminal = deps.terminal ?? defaultTerminal\n // On its own `login` is a session of its own; inside `create` it is a part.\n const own = deps.ui === undefined\n const ui = deps.ui ?? (await makeUi(terminal))\n if (own) ui.intro('Log in to GitHub')\n try {\n const manifest = await manifestAround(deps.cwd ?? process.cwd())\n if (manifest?.provider != null && !PROVIDERS[manifest.provider].available) {\n ui.error(unsupportedProviderMessage(manifest.provider))\n return 1\n }\n const needsProject = opts.project === true || manifest?.boards != null\n const bin =\n deps.bin ?? (await realpath(process.argv[1] ?? '').catch(() => ''))\n const env = envToken()\n if (env !== null)\n ui.hint(`${env.source} is set and wins over a stored login`)\n const stored = await readAuth()\n const resolved = stored === null ? null : await resolveToken()\n const lacksProject =\n needsProject &&\n resolved?.source === 'login' &&\n !splitScopes(stored?.tokens.scopes ?? '').includes(BOARD_SCOPE)\n if (stored !== null && resolved !== null && !lacksProject) {\n ui.line(\n 'logged in',\n `as ${stored.login} (github.com); ${rnessCommand()} logout to switch`\n )\n await offerSetupGit(opts, terminal, bin, ui)\n if (own) ui.outro('Nothing to do', 'idle')\n return 0\n }\n\n if (lacksProject) ui.line('login', 'logging in again for the project scope')\n const code = await requestDeviceCode(\n needsProject ? `${SCOPES} ${BOARD_SCOPE}` : SCOPES\n )\n if (ui.session)\n ui.line(\n 'open',\n code.verificationUri,\n `Open ${code.verificationUri} and enter the code ${code.userCode}`\n )\n else {\n ui.line('open', code.verificationUri)\n ui.line('code', code.userCode)\n }\n if (terminal.isTty() && canOpenBrowser())\n (deps.open ?? openInBrowser)(code.verificationUri)\n // The plain look says it is waiting, then who logged in; the session\n // look spins, and the spinner ends as that second line.\n if (!ui.session)\n ui.line('waiting', 'for you to approve rness on github.com…')\n const login = await ui.step(\n {\n doing: 'waiting for you to approve rness on github.com',\n sentence: 'Waiting for your approval on github.com',\n quiet: true,\n },\n async () => {\n const tokens = await pollForToken(code, deps)\n const user = await getUser({\n token: tokens.accessToken,\n apiBase: opts.githubApi ?? DEFAULT_GITHUB_API,\n })\n await writeAuth({ login: user.login, tokens })\n return user.login\n },\n (name) => ['logged in', `as ${name} (github.com)`]\n )\n if (!ui.session) ui.line('logged in', `as ${login} (github.com)`)\n await offerSetupGit(opts, terminal, bin, ui)\n if (own) ui.outro(`You are logged in as ${login}`)\n return 0\n } catch (e) {\n if (e instanceof LoginError) {\n ui.error(e.message)\n return 1\n }\n return reportError(e)\n }\n}\n","import { spawn } from 'node:child_process'\n\n/** Open a URL in the browser of this machine; failures are nobody's problem: the URL is on the screen. */\nexport function openInBrowser(url: string): void {\n const [command, args] =\n process.platform === 'darwin'\n ? ['open', [url]]\n : process.platform === 'win32'\n ? ['cmd', ['/c', 'start', '', url]]\n : ['xdg-open', [url]]\n try {\n const child = spawn(command, args, { stdio: 'ignore', detached: true })\n child.on('error', () => undefined)\n child.unref()\n } catch {\n // no browser here: the URL is on the screen\n }\n}\n\n/** Over SSH there is no browser on this end: the URL is printed and that is all (spec 0004 §2). */\nexport function canOpenBrowser(): boolean {\n return process.env['SSH_CONNECTION'] === undefined\n}\n","import { VERSION } from '../version.ts'\nimport { githubProvider } from './github-oauth-provider.ts'\nimport type { RateWait } from './github.ts'\nimport type { Provider } from './provider.ts'\nimport type { Manifest, ProviderName } from './types.ts'\n\nexport interface OpenOptions {\n apiBase?: string\n wait?: RateWait\n}\n\nexport interface ProviderEntry {\n name: ProviderName\n label: string\n available: boolean\n /** Only when `available`. */\n open?: (options: OpenOptions) => Promise<Provider>\n}\n\n/** The hosting providers rness knows by name, in the order it offers them. */\nexport const PROVIDERS: Readonly<Record<ProviderName, ProviderEntry>> = {\n github: {\n name: 'github',\n label: 'GitHub',\n available: true,\n open: ({ apiBase, wait }) => githubProvider(apiBase, wait),\n },\n gitlab: { name: 'gitlab', label: 'GitLab', available: false },\n atlassian: {\n name: 'atlassian',\n label: 'Atlassian (Bitbucket + Jira)',\n available: false,\n },\n}\n\nexport function isProviderName(value: string): value is ProviderName {\n return Object.hasOwn(PROVIDERS, value)\n}\n\nexport function unsupportedProviderMessage(name: ProviderName): string {\n const supported = Object.values(PROVIDERS)\n .filter((p) => p.available)\n .map((p) => p.name)\n return `rness.json: provider \"${name}\" is not supported by @rness/cli ${VERSION} (supported: ${supported.join(', ')})`\n}\n\n/**\n * The workspace's provider, opened — or throws the message above. Only a\n * provider written in `rness.json` is refused: a host detected from a\n * repository URL is git's business (spec 0017 §1), and opens GitHub, whose\n * credentials answer null for other hosts.\n */\nexport async function openProvider(\n manifest: Manifest | null,\n options: OpenOptions = {}\n): Promise<Provider> {\n const name = manifest?.provider ?? 'github'\n const entry = PROVIDERS[name]\n if (entry.open === undefined)\n throw new Error(unsupportedProviderMessage(name))\n return entry.open(options)\n}\n\n/**\n * For the commands that only clone and pull (`add`, `sync`): the provider as\n * `openProvider` opens it, or null when the written one is unavailable — git\n * then uses its own credentials instead of refusing.\n */\nexport async function openGitProvider(\n manifest: Manifest\n): Promise<Provider | null> {\n if (manifest.provider !== null && !PROVIDERS[manifest.provider].available)\n return null\n return openProvider(manifest)\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst execFileP = promisify(execFile)\n\n// Making rness git's credential helper for github.com (spec 0004 §5): what\n// `gh auth setup-git` does for gh. Two values under one key — an empty one,\n// which clears the helpers inherited from the system (osxkeychain would\n// otherwise answer first), then rness, by absolute path so git finds it\n// whatever PATH it runs with.\n\nconst KEY = 'credential.https://github.com.helper'\n\nexport function helperValue(node: string, bin: string): string {\n return `!'${node}' '${bin}' git-credential`\n}\n\n// The shape `helperValue` writes — not gh's `!gh auth git-credential`, nor\n// anyone else's helper that happens to end the same way.\nconst isOurs = (value: string): boolean =>\n /^!'[^']+' '[^']*rness[^']*' git-credential$/.test(value)\n\nasync function config(args: string[]): Promise<string> {\n const { stdout } = await execFileP('git', ['config', '--global', ...args])\n return stdout\n}\n\nasync function values(): Promise<string[]> {\n try {\n const out = await config(['--get-all', KEY])\n return out.replace(/\\n$/, '').split('\\n')\n } catch {\n return [] // the key is not set\n }\n}\n\n/** A copy run through npx lives in a cache that is cleared: not a path to give git. */\nexport function isStableInstall(bin: string): boolean {\n return !/[\\\\/]_npx[\\\\/]/.test(bin)\n}\n\n/** Register rness for github.com. False when it already was. */\nexport async function setupGit(node: string, bin: string): Promise<boolean> {\n const ours = helperValue(node, bin)\n if ((await values()).includes(ours)) return false\n // A stale rness entry (another install path) goes first.\n await removeGitSetup()\n await config(['--add', KEY, ''])\n await config(['--add', KEY, ours])\n return true\n}\n\n/**\n * Remove exactly what `setupGit` wrote: rness's entry and the empty one in\n * front of it. A helper someone else registered is left as it was. False\n * when there was nothing of rness's.\n */\nexport async function removeGitSetup(): Promise<boolean> {\n const current = await values()\n if (!current.some(isOurs)) return false\n const kept = current.filter(\n (value, i) =>\n !isOurs(value) && !(value === '' && isOurs(current[i + 1] ?? ''))\n )\n await config(['--unset-all', KEY])\n for (const value of kept) await config(['--add', KEY, value])\n return true\n}\n","import { paint } from './style.ts'\n\nconst FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']\nconst INTERVAL_MS = 80\n/** Back to column 0, erase the line. */\nconst CLEAR_LINE = '\\r\\x1b[2K'\n\nexport interface StepOptions {\n /** What is happening, as a status line in the making: `cloning org/api`. */\n label: string\n /**\n * Animate a spinner. Off for anything that runs git: over SSH, git's `ssh`\n * may ask for a passphrase on the terminal, and a line redrawn every 80 ms\n * would shred the question. The label is then written once and erased.\n */\n animate: boolean\n stream?: NodeJS.WriteStream\n}\n\nfunction isLive(stream: NodeJS.WriteStream): boolean {\n return (\n stream.isTTY === true &&\n process.env['TERM'] !== 'dumb' &&\n process.env['CI'] === undefined\n )\n}\n\n/**\n * Run `work` with a transient line saying what is going on (spec 0007 §5).\n * The line is erased when `work` settles, and the caller prints the step's\n * status line as it always did — so off a terminal, where nothing transient\n * is written, the output is byte for byte what it was.\n */\nexport async function step<T>(\n options: StepOptions,\n work: () => Promise<T>\n): Promise<T> {\n const stream = options.stream ?? process.stdout\n if (!isLive(stream)) return work()\n const draw = (frame: string): void => {\n rawWrite(\n `${CLEAR_LINE}${paint('info', frame, stream)} ${paint('idle', options.label, stream)}`\n )\n }\n let timer: NodeJS.Timeout | undefined\n let shown = true\n // Erase the label, once: when the work ends, or as soon as the work itself\n // writes — its first line must not land behind `… syncing the blocks`.\n const erase = (): void => {\n if (!shown) return\n shown = false\n if (timer !== undefined) clearInterval(timer)\n rawWrite(CLEAR_LINE)\n }\n // Both streams share the terminal's line, so a write to either erases it.\n const rawWrite = stream.write.bind(stream) as NodeJS.WriteStream['write']\n const rawErr = process.stderr.write.bind(\n process.stderr\n ) as NodeJS.WriteStream['write']\n type Write = NodeJS.WriteStream['write']\n // `write` is overloaded; the guard only forwards, whatever the overload.\n const guard = (raw: Write): Write =>\n ((...args: Parameters<Write>) => {\n erase()\n return raw(...args)\n }) as Write\n if (options.animate) {\n let i = 0\n draw(FRAMES[0] ?? '')\n timer = setInterval(() => {\n i = (i + 1) % FRAMES.length\n if (shown) draw(FRAMES[i] ?? '')\n }, INTERVAL_MS)\n // Never the reason the process stays alive.\n timer.unref()\n } else {\n draw('…')\n }\n stream.write = guard(rawWrite)\n if (process.stderr !== stream) process.stderr.write = guard(rawErr)\n try {\n return await work()\n } finally {\n stream.write = rawWrite\n if (process.stderr !== stream) process.stderr.write = rawErr\n erase()\n }\n}\n","import { step as transientStep } from './progress.ts'\nimport { type Tone, badge, grey, paint, status, toneOf, warn } from './style.ts'\nimport type { Prompts, Terminal } from './terminal.ts'\n\n// How an interactive command speaks (spec 0007 §5b). Two renderings of the\n// same calls: `plain` — the status column, the bytes scripts and tests read —\n// and `session`, clack's gutter from `intro` to `outro`, in a terminal.\n\n/** A status line: the verb of the column, what follows it. */\n/** `sentence` replaces `rest verb` in the session look, where that would not read. */\nexport type Line = readonly [verb: string, rest: string, sentence?: string]\n\nexport interface StepOptions {\n /** The transient label of the plain look: `cloning org/api`. */\n doing: string\n /** What the session look shows while it runs; defaults to `doing`, tidied. */\n sentence?: string\n /** The step runs git: it animates only when git is known not to prompt. */\n git?: boolean\n /**\n * The plain look has already said what it needs (`listing acme\n * repositories…`): only the session look prints the step's outcome.\n */\n quiet?: boolean\n}\n\nexport interface Ui {\n /** True for the session look. */\n readonly session: boolean\n /**\n * Set once rness knows git will not ask anything on the terminal (SSH works\n * unattended, or the clones are not over SSH): git steps may then animate.\n */\n gitIsSilent: boolean\n intro(title: string): void\n /** The last word of a session: green for a success, the tone given otherwise. */\n outro(message: string, tone?: Tone): void\n /** `sentence` replaces `verb rest` in the session look. */\n line(verb: string, rest: string, sentence?: string): void\n warn(text: string): void\n /** A block of commands or facts under a title. */\n note(title: string, lines: readonly string[]): void\n /** An aside: a plain line in the plain look, dimmed in the session one. */\n hint(text: string, stream?: 'stdout' | 'stderr'): void\n /** A handled error the command goes on after. */\n error(text: string): void\n cancelled(): void\n /** Run `work`; then print `done(result)` unless it answers null. */\n step<T>(\n options: StepOptions,\n work: () => Promise<T>,\n done?: (result: T) => Line | null\n ): Promise<T>\n}\n\nconst capitalise = (s: string): string =>\n s === '' ? s : `${s[0]?.toUpperCase() ?? ''}${s.slice(1)}`\n\n/** `cloning org/api` → `Cloning org/api`. */\nconst tidy = (label: string): string =>\n capitalise(label.replace(/\\s+/g, ' ').trim())\n\nexport const plainUi: Ui = {\n session: false,\n gitIsSilent: false,\n intro: () => undefined,\n outro: () => undefined,\n line: (verb, rest) => {\n process.stdout.write(`${status(verb, rest)}\\n`)\n },\n warn: (text) => {\n process.stderr.write(`${warn(text)}\\n`)\n },\n note: (title, lines) => {\n process.stdout.write(\n ['', `${title}:`, ...lines.map((l) => ` ${l}`), ''].join('\\n')\n )\n },\n hint: (text, stream = 'stdout') => {\n process[stream].write(`${text}\\n`)\n },\n error: (text) => {\n process.stderr.write(`${text}\\n`)\n },\n cancelled: () => {\n process.stderr.write('cancelled\\n')\n },\n async step(options, work, done) {\n // Animation is the install's; git steps write their label once.\n const result = await transientStep(\n { label: options.doing, animate: options.git !== true },\n work\n )\n const line = options.quiet === true ? null : (done?.(result) ?? null)\n if (line !== null) this.line(line[0], line[1])\n return result\n },\n}\n\nexport type Session = Required<\n Pick<Prompts, 'intro' | 'outro' | 'cancel' | 'note' | 'log' | 'spinner'>\n>\n\n/** The session look over clack's functions; exported for tests, which script them. */\n/** What a line says, once its tone has a symbol of its own to carry it. */\nconst IDLE_SYMBOL = '\\u00b7'\n\nexport function sessionUi(p: Session): Ui {\n // clack draws the gutter symbol, so it is the coloured column the plain\n // look puts first (spec 0007 §4): the text beside it stays neutral, which\n // is what lets a path lead and the paths of a list align (§5d).\n const say = (verb: string, text: string): void => {\n const tone = toneOf(verb)\n if (tone === 'done') p.log.success(text)\n else if (tone === 'warn') p.log.warn(text)\n else if (tone === 'error') p.log.error(text)\n else if (tone === 'idle')\n p.log.message(paint('idle', text), {\n symbol: paint('idle', IDLE_SYMBOL),\n })\n else p.log.info(text)\n }\n return {\n session: true,\n gitIsSilent: false,\n intro: (title) => {\n p.intro(badge(title))\n },\n outro: (message, tone = 'done') => {\n // The verdict closes a session the way the title opened it: on a\n // background, legible before the words are read (spec 0007 §5c).\n p.outro(badge(message, tone))\n },\n line: (verb, rest, sentence) => {\n // The path leads, the verb follows: in a list the paths align on the\n // left instead of starting at whatever width the verb happened to be.\n say(verb, sentence ?? `${rest} ${verb}`)\n },\n warn: (text) => {\n p.log.warn(text)\n },\n note: (title, lines) => {\n p.note(lines.join('\\n'), title, { format: (line) => grey(line) })\n },\n hint: (text) => {\n p.log.message(paint('idle', text))\n },\n error: (text) => {\n p.log.error(text)\n },\n cancelled: () => {\n p.cancel('Cancelled')\n },\n async step(options, work, done) {\n const label = options.sentence ?? tidy(options.doing)\n // The verb is kept beside its text: a finished step is said by `say`,\n // so its symbol is the one a plain line of the same tone would wear.\n const finish = (result: Awaited<ReturnType<typeof work>>): Line | null =>\n done?.(result) ?? null\n const label_ = (line: Line): string => line[2] ?? `${line[1]} ${line[0]}`\n // A spinner redraws its line: not while git's ssh may be asking for a\n // passphrase on the same terminal.\n if (options.git === true && !this.gitIsSilent) {\n p.log.message(paint('idle', `${label}…`))\n const result = await work()\n const line = finish(result)\n if (line !== null) say(line[0], label_(line))\n return result\n }\n const spin = p.spinner()\n spin.start(label)\n try {\n const result = await work()\n const line = finish(result)\n spin.stop(line === null ? label : label_(line))\n return result\n } catch (e) {\n spin.error(`${label}: failed`)\n throw e\n }\n },\n }\n}\n\n/** The session look needs a real terminal; everything else gets the plain one. */\nexport async function makeUi(terminal: Terminal): Promise<Ui> {\n const live =\n terminal.isTty() &&\n process.stdout.isTTY === true &&\n process.env['CI'] === undefined &&\n process.env['TERM'] !== 'dumb'\n if (!live) return { ...plainUi }\n const p = await terminal.prompts()\n if (\n p.intro === undefined ||\n p.outro === undefined ||\n p.cancel === undefined ||\n p.note === undefined ||\n p.log === undefined ||\n p.spinner === undefined\n )\n return { ...plainUi }\n return sessionUi({\n intro: p.intro,\n outro: p.outro,\n cancel: p.cancel,\n note: p.note,\n log: p.log,\n spinner: p.spinner,\n })\n}\n","import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\n\nimport { configDir } from '../core/auth.ts'\nimport { gitPath, headOf } from '../core/git.ts'\n\n/**\n * What the agent journal keeps on this machine (spec 0030 §4, §3.4): the\n * notes each session posted on each plan, in the `.rness` clone's git\n * directory (`rness/journal`, never pushed), as the issues the boards opened\n * are; each session's start, in the git directory of the clone it works\n * in (`rness/sessions/<id>`), for its summary; and the fallbacks the next\n * session start says once, beside the boards' failures in rness's\n * configuration directory.\n */\n\n/** A session's notes on a plan: how many, and the issues they went to, node id by reference. */\ninterface Noted {\n notes: number\n to: Record<string, string>\n}\n/** `rness/journal`: `{ \"<session id>\": { \"<plan path>\": Noted } }`. */\ntype Counts = Record<string, Record<string, unknown>>\n\n/** An issue a note went to: `acme/api#87`, and its node id. */\nexport interface NotedIssue {\n id: string\n reference: string\n}\n\nconst notedOf = (value: unknown): Noted => {\n const v = value as Partial<Noted> | null\n return typeof v?.notes === 'number'\n ? { notes: v.notes, to: { ...(v.to ?? {}) } }\n : { notes: 0, to: {} }\n}\n\nconst COUNTS = 'rness/journal'\n\n/**\n * A session's key: its id, `1a2b3c4d` of `claude · 1a2b3c4d`. The Bash\n * tool names a session without its agent type, the hooks with it: one key.\n */\nconst keyOf = (session: string): string =>\n session.split(' · ').at(-1)?.trim() ?? session\n\nasync function readJson(file: string): Promise<unknown> {\n try {\n return JSON.parse(await readFile(file, 'utf8'))\n } catch {\n return null\n }\n}\n\nasync function writeJson(file: string, value: unknown): Promise<void> {\n await mkdir(dirname(file), { recursive: true })\n const temporary = `${file}.${process.pid}`\n await writeFile(temporary, `${JSON.stringify(value, null, 2)}\\n`)\n await rename(temporary, file)\n}\n\n/** The notes `session` posted on `plan` from this clone; 0 when none, or no record. */\nexport async function notesPosted(\n rnessDir: string,\n session: string,\n plan: string\n): Promise<number> {\n const file = await gitPath(rnessDir, COUNTS)\n if (file === null) return 0\n const data = (await readJson(file)) as Counts | null\n return notedOf(data?.[keyOf(session)]?.[plan]).notes\n}\n\n/** One more note of `session` on `plan`, to the issue `to`, recorded; best effort. */\nexport async function notePosted(\n rnessDir: string,\n session: string,\n plan: string,\n to: NotedIssue\n): Promise<void> {\n const file = await gitPath(rnessDir, COUNTS)\n if (file === null) return\n try {\n const data = ((await readJson(file)) as Counts | null) ?? {}\n const key = keyOf(session)\n const of = data[key] ?? {}\n const noted = notedOf(of[plan])\n of[plan] = {\n notes: noted.notes + 1,\n to: { ...noted.to, [to.reference]: to.id },\n }\n data[key] = of\n await writeJson(file, data)\n } catch {\n // A note uncounted is one more allowed, nothing worse.\n }\n}\n\n/** The issues `session`'s notes went to, from this clone, each once. */\nexport async function issuesNoted(\n rnessDir: string,\n session: string\n): Promise<NotedIssue[]> {\n const file = await gitPath(rnessDir, COUNTS)\n if (file === null) return []\n const data = (await readJson(file)) as Counts | null\n const issues = new Map<string, string>()\n for (const value of Object.values(data?.[keyOf(session)] ?? {}))\n for (const [reference, id] of Object.entries(notedOf(value).to))\n issues.set(reference, id)\n return [...issues].map(([reference, id]) => ({ id, reference }))\n}\n\n/** `session`'s notes forgotten once it ended: its summary is posted or skipped. */\nexport async function forgetNotes(\n rnessDir: string,\n session: string\n): Promise<void> {\n const file = await gitPath(rnessDir, COUNTS)\n if (file === null) return\n try {\n const data = ((await readJson(file)) as Counts | null) ?? {}\n if (!Object.hasOwn(data, keyOf(session))) return\n delete data[keyOf(session)]\n await writeJson(file, data)\n } catch {\n // Kept: a few bytes, nothing worse.\n }\n}\n\n/** Where a session started: the clone's `HEAD`, and when (ms). */\nexport interface SessionStart {\n head: string\n at: number\n}\n\n/** The file of a session's start in `clone`'s git directory; null for an id that is not one. */\nasync function startFile(\n clone: string,\n session: string\n): Promise<string | null> {\n const id = keyOf(session)\n return /^[A-Za-z0-9-]{1,64}$/.test(id)\n ? gitPath(clone, `rness/sessions/${id}`)\n : null\n}\n\n/**\n * The session's start recorded in `clone`, once: a resumed or compacted\n * session keeps its first. Nothing outside a repository; best effort.\n */\nexport async function recordStart(\n clone: string,\n session: string,\n now: number = Date.now()\n): Promise<void> {\n try {\n const [file, head] = await Promise.all([\n startFile(clone, session),\n headOf(clone),\n ])\n if (file === null || head === null) return\n await mkdir(dirname(file), { recursive: true })\n await writeFile(file, `${JSON.stringify({ head, at: now })}\\n`, {\n flag: 'wx',\n })\n } catch {\n // Already recorded, or not writable: the summary goes without commits.\n }\n}\n\n/** The session's start recorded in `clone`; null when there is none. */\nexport async function startOf(\n clone: string,\n session: string\n): Promise<SessionStart | null> {\n const file = await startFile(clone, session)\n if (file === null) return null\n const data = (await readJson(file)) as Partial<SessionStart> | null\n return typeof data?.head === 'string' && typeof data.at === 'number'\n ? { head: data.head, at: data.at }\n : null\n}\n\n/** The session's start, removed once its summary is posted or skipped. */\nexport async function forgetStart(\n clone: string,\n session: string\n): Promise<void> {\n const file = await startFile(clone, session)\n if (file !== null) await rm(file, { force: true }).catch(() => {})\n}\n\nconst notices = (): string => join(configDir(), 'journal.json')\n\n/** A line for the next session start (`<repo> takes no issues, …`), kept until said; each once. */\nexport async function recordNotice(line: string): Promise<void> {\n try {\n const now = ((await readJson(notices())) as string[] | null) ?? []\n if (!now.includes(line)) await writeJson(notices(), [...now, line])\n } catch {\n // Said at the next fallback, then.\n }\n}\n\n/** The lines recorded since the last session start, taken: said once. */\nexport async function takeNotices(): Promise<string[]> {\n const now = await readJson(notices())\n await rm(notices(), { force: true }).catch(() => {})\n return Array.isArray(now)\n ? now.filter((l): l is string => typeof l === 'string')\n : []\n}\n","import { readFile, readdir } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { setTimeout as delay } from 'node:timers/promises'\n\nimport { issueBody } from '../board/body.ts'\nimport { type StatusUpdate, readUpdates } from '../board/collection.ts'\nimport { oneSyncAtATime, recordFailure } from '../board/detached.ts'\nimport {\n type BoardCollection,\n type Desired,\n type Layout,\n collectionsOf,\n desiredOf,\n layoutOf,\n readsFrontMatter,\n} from '../board/layout.ts'\nimport { onceSaid } from '../board/noted.ts'\nimport { openedFile, readOpened, writeOpened } from '../board/opened.ts'\nimport {\n type BoardItem,\n type BodyStep,\n type Placed,\n type Step,\n issuedAfter,\n planBodies,\n planSync,\n stillOpened,\n unwantedPaths,\n} from '../board/plan.ts'\nimport {\n type BoardAction,\n type BoardDeclaration,\n HOOK_EVENTS,\n parseBoard,\n presetFor,\n} from '../core/board-declaration.ts'\nimport {\n readmeDeclarations,\n withoutDeclarations,\n} from '../core/board-migration.ts'\nimport { collectMarkdown } from '../core/collect.ts'\nimport { containedPath } from '../core/contained.ts'\nimport type { CommandDeps } from '../core/deps.ts'\nimport { stripFrontMatter } from '../core/frontmatter.ts'\nimport { writeFileAtomic } from '../core/fs.ts'\nimport { seenPaths } from '../core/git.ts'\nimport {\n GitHubMessageError,\n RateLimitError,\n type RateWait,\n rateWait,\n} from '../core/github.ts'\nimport {\n PULSE,\n loadManifest,\n providerOf,\n writeManifest,\n} from '../core/manifest.ts'\nimport { declaredBoard, presetSource } from '../core/preset-board.ts'\nimport { labelOf } from '../core/presets.ts'\nimport type { Board, MarkFields, Provider } from '../core/provider.ts'\nimport { PROVIDERS, openProvider } from '../core/providers.ts'\nimport { type StatusTab, documentsIn, statusTabs } from '../core/status.ts'\nimport { type Terminal, defaultTerminal } from '../core/terminal.ts'\nimport type { Manifest } from '../core/types.ts'\nimport { type Ui, makeUi, plainUi } from '../core/ui.ts'\nimport { findWorkspace } from '../core/workspace.ts'\nimport { reportError } from '../report.ts'\nimport { loginCommand } from './login.ts'\n\nexport interface BoardOptions {\n /** Create the boards not created yet without asking (spec 0033 §4). */\n yes?: boolean\n /** Internal: the creation already answered — `rness pulse create` was typed. */\n confirmed?: boolean\n /** Internal (tests): directory to resolve from; default `process.cwd()`. */\n cwd?: string\n /** Internal (tests): GitHub API base. */\n githubApi?: string\n /** Internal (tests): how a rate-limit wait sleeps; default a timer. */\n sleep?: (ms: number) => Promise<void>\n}\n\nconst PROJECT_SCOPE = 'project'\nconst NEEDS_LOGIN = 'boards need a GitHub login: run rness login'\nconst NEEDS_SCOPE = 'boards need the project scope: run rness login'\n\n/**\n * GitHub's own words, named as GitHub's unless they already say so. rness's\n * own errors (`the board has no field Agent`) keep their words.\n */\nexport async function fromGithub<T>(work: Promise<T>): Promise<T> {\n try {\n return await work\n } catch (e) {\n if (e instanceof GitHubMessageError && !/github/i.test(e.message))\n throw new Error(`GitHub: ${e.message}`, { cause: e })\n throw e\n }\n}\n\nexport interface Context {\n root: string\n rnessDir: string\n manifest: Manifest\n org: string\n provider: Provider\n}\n\nconst apiOf = (opts: BoardOptions): { apiBase?: string } =>\n opts.githubApi === undefined ? {} : { apiBase: opts.githubApi }\n\nconst providerOptions = (\n opts: BoardOptions,\n wait?: RateWait\n): { apiBase?: string; wait?: RateWait } => ({\n ...apiOf(opts),\n ...(wait === undefined ? {} : { wait }),\n})\n\n/** The refusals every board command shares, in order; each throws one line. */\nexport async function context(\n opts: BoardOptions,\n wait?: RateWait\n): Promise<Context> {\n const ws = await findWorkspace(opts.cwd ?? process.cwd())\n const manifest = await loadManifest(ws.rnessDir)\n const provider = await openProvider(manifest, providerOptions(opts, wait))\n if (manifest.org === null)\n throw new Error('boards need an organization: rness.json has no \"org\"')\n return {\n root: ws.root,\n rnessDir: ws.rnessDir,\n manifest,\n org: manifest.org,\n provider,\n }\n}\n\n/** Rate-limit waits said as they begin: a pause of minutes must not look like a hang (spec 0018 §4). */\nconst waitSaid = (opts: BoardOptions, ui: Ui): RateWait =>\n rateWait(async (ms) => {\n ui.line('waiting', `${Math.round(ms / 1000)} s: GitHub's rate limit`)\n await (opts.sleep ?? ((n: number) => delay(n)))(ms)\n })\n\n/**\n * What the login lacks for boards — a login, or the project scope — or\n * null. Throws when GitHub cannot be asked: an offline machine or a rejected\n * token is never told that a scope is missing.\n */\nasync function missingAccess(provider: Provider): Promise<string | null> {\n if (!provider.authenticated) return NEEDS_LOGIN\n const scopes = await fromGithub(provider.scopes())\n return scopes?.includes(PROJECT_SCOPE) === true ? null : NEEDS_SCOPE\n}\n\n/** A board the provider has: its declaration names its project. */\nexport type Created = BoardDeclaration & { number: number }\n\nconst isCreated = (d: BoardDeclaration): d is Created => d.number !== null\n\n/** A declared project, opened: its name in `boards`, its declaration, its board. */\nexport interface Declared {\n name: string\n declaration: Created\n board: Board\n}\n\n/** A board that takes every collection no other board holds: `\"collections\": \"all\"`. */\nconst takesAll = (d: { declaration: BoardDeclaration }): boolean =>\n d.declaration.collections === 'all'\n\n/** The collections a board holds by name; none for one that takes all. */\nconst namedCollections = (d: BoardDeclaration): string[] =>\n d.collections === 'all' ? [] : Object.keys(d.collections)\n\n/** A board of `boards` the provider does not have yet: `board push` creates it (spec 0033 §4). */\ninterface NotCreated {\n name: string\n entry: string | BoardDeclaration\n declaration: BoardDeclaration\n}\n\n/**\n * Every declared board, read whole (a number or a preset's name is its\n * preset): those the provider has — those that name their collections\n * first, in the order of `boards`, one that takes all last, so a document\n * moving leaves it only once its own board holds it (spec 0025 §3) — and\n * those it does not have yet. A board `rness.json` refuses is said and\n * skipped.\n */\nasync function declarations(\n c: Context,\n ui?: Ui\n): Promise<{\n created: { name: string; declaration: Created }[]\n notCreated: NotCreated[]\n}> {\n const boards = c.manifest.boards ?? {}\n for (const r of c.manifest.refused ?? [])\n ui?.line('skipped', `${r.name}: ${r.reason}`)\n const all: { name: string; declaration: Created }[] = []\n const notCreated: NotCreated[] = []\n for (const [name, entry] of Object.entries(boards)) {\n const declaration = await declaredBoard(name, entry, c.rnessDir)\n // A README that still declares what rness.json declares now (spec 0031\n // §6): this board waits until `rness sync` moves it.\n const still: string[] = []\n if (typeof entry === 'object')\n for (const collection of namedCollections(declaration)) {\n const keys = Object.keys(\n await readmeDeclarations(c.rnessDir, collection)\n )\n if (keys.length > 0)\n still.push(`${collection}/README.md declares ${keys.join(', ')}`)\n }\n if (still.length > 0) {\n ui?.line(\n 'skipped',\n `${name}: ${still.join(', ')}, which rness.json declares now: rness sync moves it`\n )\n continue\n }\n if (isCreated(declaration)) all.push({ name, declaration })\n else if (typeof entry !== 'number')\n notCreated.push({ name, entry, declaration })\n }\n return {\n created: all.sort((a, b) => Number(takesAll(a)) - Number(takesAll(b))),\n notCreated,\n }\n}\n\n/** What `boards` holds, said when there is nothing to push. */\nfunction noBoard(c: Context): Error {\n return new Error(\n c.manifest.refused === undefined\n ? 'no board declared: declare one in .rness/rness.json, as \"boards\": { \"pulse\": \"agent-pulse\" }, then rness board push'\n : `no board rness.json declares is valid: ${c.manifest.refused.map((r) => r.reason).join('; ')}`\n )\n}\n\n/**\n * Every declared board the provider has, opened; `push` and `run` need\n * one. A board not created yet is left out: `push` creates it first.\n */\nexport async function declaredBoards(c: Context, ui?: Ui): Promise<Declared[]> {\n if (c.manifest.boards === null) throw noBoard(c)\n const { created } = await declarations(c, ui)\n if (created.length === 0) return []\n const missing = await missingAccess(c.provider)\n if (missing !== null) throw new Error(missing)\n const declared: Declared[] = []\n for (const { name, declaration } of created) {\n const board = await fromGithub(c.provider.board(c.org, declaration.number))\n if (board === null)\n throw new Error(`GitHub has no project ${declaration.number} in ${c.org}`)\n declared.push({ name, declaration, board })\n }\n return declared\n}\n\n/** What one project holds and how it looks, from the files of `.rness/`. */\ninterface Scope {\n /** How a sync names the project: `Agent Pulse`, `Marketing`. */\n label: string\n want: Desired[]\n layout: Layout\n /** A path on the board that another board holds, or none does: taken off, its issue kept. */\n elsewhere: (path: string) => boolean\n /** The paths whose opened issues this project's syncs record (spec 0018 §2). */\n mine: (path: string) => boolean\n /** Its README and short description, when declared. */\n text: { readme: string | null; description: string | null } | null\n updates: StatusUpdate[]\n /** Said after its sync's count: one board that takes all is said bare, as before. */\n on: string | undefined\n}\n\n/** The subdirectories of a collection, but `updates/`: the labels `labels: directory` makes. */\nasync function directoriesOf(dir: string): Promise<string[]> {\n try {\n return (await readdir(dir, { withFileTypes: true }))\n .filter(\n (e) =>\n e.isDirectory() && !e.name.startsWith('.') && e.name !== 'updates'\n )\n .map((e) => e.name)\n .sort()\n } catch {\n return []\n }\n}\n\n/** A file of `.rness/`, its front matter removed; null when it is not there; one leading out of `.rness`, refused. */\nasync function textOf(rnessDir: string, rel: string): Promise<string | null> {\n try {\n return stripFrontMatter(\n await readFile(await containedPath(rnessDir, rel), 'utf8')\n )\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') return null\n throw e\n }\n}\n\n/** A collection's README as written; null when it has none. */\nasync function readmeText(\n rnessDir: string,\n collection: string\n): Promise<string | null> {\n try {\n return await readFile(\n await containedPath(rnessDir, `${collection}/README.md`),\n 'utf8'\n )\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') return null\n throw e\n }\n}\n\n/** The collection of a path of `.rness/`: its first directory. */\nconst collectionOfPath = (path: string): string => path.split('/')[0] ?? ''\n\nasync function scopeOf(\n c: Context,\n name: string,\n declaration: BoardDeclaration,\n tabs: readonly StatusTab[],\n owners: readonly string[]\n): Promise<Scope> {\n const collections: BoardCollection[] = collectionsOf(\n declaration,\n tabs,\n (dir) => owners.includes(dir)\n )\n const held = (path: string): boolean =>\n collections.some((col) => col.name === collectionOfPath(path))\n // One that takes all holds what no other board holds; one that names its\n // collections, those alone: a card of any other leaves it, its issue kept.\n const elsewhere =\n declaration.collections === 'all'\n ? (path: string) => owners.includes(collectionOfPath(path))\n : (path: string) =>\n !namedCollections(declaration).includes(collectionOfPath(path))\n const fronts = new Map<string, Record<string, unknown>>()\n const directories = new Map<string, string[]>()\n if (readsFrontMatter(declaration))\n for (const col of collections) {\n const dir = join(c.rnessDir, col.name)\n for (const item of await collectMarkdown(dir))\n fronts.set(`${col.name}/${item.rel}`, item.fields ?? {})\n directories.set(col.name, await directoriesOf(dir))\n }\n const want = desiredOf(declaration, collections, c.org, fronts, directories)\n const text =\n declaration.readme === null && declaration.description === null\n ? null\n : {\n readme:\n declaration.readme === null\n ? null\n : await textOf(c.rnessDir, declaration.readme),\n description: declaration.description,\n }\n return {\n label: declaration.title ?? labelOf(name),\n want,\n layout: layoutOf(declaration, collections, want),\n elsewhere,\n mine: (path) => held(path) || !elsewhere(path),\n text,\n updates:\n declaration.updates === null\n ? []\n : await readUpdates(c.rnessDir, declaration.updates),\n on:\n declaration.collections === 'all'\n ? undefined\n : (declaration.title ?? labelOf(name)),\n }\n}\n\nconst plural = (n: number): string => `${n} item${n === 1 ? '' : 's'}`\n\n/** What the layout gained, as `sync` says it: `added view Plans`, a line each. */\ntype SayLayout = (ui: Ui, added: readonly string[], project: string) => void\n/** What a layout line says, by its first word: `renamed …`, `updated …`, `deleted …`, `note …`, else added. */\nconst VERBS = ['renamed', 'updated', 'deleted', 'note'] as const\nconst eachAdded: SayLayout = (ui, added) => {\n for (const a of added) {\n const verb = VERBS.find((v) => a.startsWith(`${v} `))\n if (verb === undefined) ui.line('added', a)\n else ui.line(verb, a.slice(verb.length + 1))\n }\n}\n/** As `create` says it: a line per kind, `created fields Collection, Agent`. */\nconst createdByKind: SayLayout = (ui, added, project) => {\n for (const kind of ['field', 'option', 'view']) {\n const names = added\n .filter((a) => a.startsWith(`${kind} `))\n .map((a) => a.slice(kind.length + 1))\n if (names.length > 0) ui.line('created', `${kind}s ${names.join(', ')}`)\n }\n for (const a of added) {\n if (a.startsWith('label ')) ui.line('created', a)\n else if (a.startsWith('link '))\n ui.line('linked', `${project} to ${a.slice('link '.length)}`)\n else if (a.startsWith('note ')) ui.line('note', a.slice('note '.length))\n }\n}\n\n/** `work` under a transient line when there is any work to show; nothing when there is none. */\nasync function working(\n ui: Ui,\n doing: string,\n count: number,\n work: () => Promise<void>\n): Promise<void> {\n if (count === 0) return work()\n await ui.step({ doing, quiet: true }, work, () => null)\n}\n\n/** Every file of `.rness/` by its path there, with `/`; not `.git` nor `node_modules` (spec 0018 §3.3). */\nasync function filesOf(rnessDir: string): Promise<Set<string>> {\n const files = new Set<string>()\n const walk = async (rel: string): Promise<void> => {\n const dir = rel === '' ? rnessDir : join(rnessDir, ...rel.split('/'))\n for (const e of await readdir(dir, { withFileTypes: true })) {\n const path = rel === '' ? e.name : `${rel}/${e.name}`\n if (e.isDirectory()) {\n if (e.name !== '.git' && e.name !== 'node_modules') await walk(path)\n } else if (e.isFile()) files.add(path)\n }\n }\n await walk('')\n return files\n}\n\nconst count = (n: number, word: string): string =>\n `${n} ${word}${n === 1 ? '' : 's'}`\n\n/**\n * What a sync did (spec 0018 §4): to `.rness`'s Issues first, then to every\n * item, as 0.12.0 said it; an item whose body alone was written is updated.\n * Each document has one step of create, convert, update or unchanged; an\n * item left alone for want of a document here is no document, not counted.\n */\nfunction sayDone(\n ui: Ui,\n org: string,\n documents: number,\n steps: readonly Step[],\n writes: readonly BodyStep[],\n adopted: number,\n on?: string\n): void {\n // An adopted issue was planned as a create: it is counted apart.\n const n = (kind: Step['kind']): number =>\n steps.filter((s) => s.kind === kind).length -\n (kind === 'create' ? adopted : 0)\n const reopened = steps.filter((s) => s.kind === 'update' && s.reopen).length\n if (n('create') > 0) ui.line('created', count(n('create'), 'issue'))\n if (adopted > 0)\n ui.line(\n 'adopted',\n `${count(adopted, 'issue')} already made for its document`\n )\n if (n('convert') > 0)\n ui.line(\n 'converted',\n `${count(n('convert'), 'draft')} into issues of ${org}/.rness`\n )\n if (reopened > 0) ui.line('reopened', count(reopened, 'issue'))\n if (n('remove') > 0)\n ui.line('moved', `${plural(n('remove'))} to their collection's project`)\n const written = new Set(writes.map((w) => w.id))\n const bodyOnly = steps.filter(\n (s) => s.kind === 'unchanged' && written.has(s.id)\n ).length\n const parts = (\n [\n ['created', n('create')],\n ['adopted', adopted],\n ['converted', n('convert')],\n ['updated', n('update') + bodyOnly],\n [\n 'unchanged',\n documents -\n n('create') -\n adopted -\n n('convert') -\n n('update') -\n bodyOnly,\n ],\n ['archived', n('close') + n('archive')],\n ] as const\n )\n .filter(([, k]) => k > 0)\n .map(([word, k]) => `${k} ${word}`)\n ui.line(\n 'synced',\n `${plural(documents)}${on === undefined ? '' : ` on ${on}`}${\n parts.length > 0 ? `: ${parts.join(', ')}` : ''\n }`\n )\n}\n\n/**\n * Issues first, then the layout, then the documents in two passes (spec\n * 0018 §4): each gets its issue, title, label and fields; then the bodies,\n * which link to one another's issues by number.\n */\nasync function syncBoard(\n c: Context,\n board: Board,\n ui: Ui,\n sayLayout: SayLayout,\n scope: Scope\n): Promise<void> {\n await fromGithub(c.provider.checkIssues(c.org))\n const { want } = scope\n // A note — a field or view no longer declared — is said once per clone.\n sayLayout(\n ui,\n await onceSaid(\n c.rnessDir,\n board.number,\n await fromGithub(c.provider.ensureLayout(board, scope.layout))\n ),\n scope.label\n )\n const have = await fromGithub(c.provider.items(board))\n // Gone is gone for this clone's git (spec 0018 §2): a path it never saw is\n // closed only on an issue this clone opened, as its record says. Git is\n // asked about every recorded path too: one it has seen is forgotten. The\n // record is the clone's: this project reads and rewrites its own paths only.\n const record = await openedFile(c.rnessDir)\n const all = await readOpened(record)\n const opened = new Map([...all].filter(([, path]) => scope.mine(path)))\n const others = [...all].filter(([, path]) => !scope.mine(path))\n const seen = await seenPaths(c.rnessDir, [\n ...unwantedPaths(want, have),\n ...opened.values(),\n ])\n const steps = planSync(want, have, seen, opened, scope.elsewhere)\n const changes = steps.filter((s) => s.kind !== 'unchanged').length\n let writes: BodyStep[] = []\n let made = 0\n let adopted = 0\n try {\n const placed = new Map<string, Placed>()\n // Recorded: the issues this sync opened — not a draft converted, synced\n // from a committed document — and forgotten: the ones it closed.\n const created = new Map<string, Placed>()\n const closed = new Set<string>()\n try {\n // Each change is a few requests, one at a time: a long pass shows it\n // is at work, and its line goes when it ends (spec 0007 §5).\n await working(\n ui,\n `writing ${plural(changes)} on ${scope.label}`,\n changes,\n async () => {\n for (const step of steps) {\n const p = await fromGithub(c.provider.apply(board, step))\n if (\n p !== null &&\n (step.kind === 'create' || step.kind === 'convert')\n )\n placed.set(step.want.path, p)\n // An adopted issue was opened by whichever sync made it, not this one.\n if (p?.adopted === true) adopted++\n else if (p !== null && step.kind === 'create')\n created.set(step.want.path, p)\n if (step.kind === 'close' || step.kind === 'archive')\n closed.add(step.id)\n if (step.kind !== 'unchanged') made++\n }\n }\n )\n } finally {\n // What pass 1 did, recorded before anything else can stop the sync.\n await writeOpened(\n record,\n new Map([\n ...others,\n ...stillOpened(opened, have, seen, closed, created),\n ])\n )\n }\n const issued = issuedAfter(steps, have, placed)\n const numbers = new Map([...issued].map(([path, i]) => [path, i.number]))\n const files = await filesOf(c.rnessDir)\n const bodies = new Map<string, string>()\n for (const w of want)\n bodies.set(\n w.path,\n issueBody({\n path: w.path,\n text: await readFile(join(c.rnessDir, ...w.path.split('/')), 'utf8'),\n org: c.org,\n numbers,\n files,\n })\n )\n writes = planBodies(bodies, issued)\n await working(\n ui,\n `writing ${plural(writes.length)} bodies on ${scope.label}`,\n writes.length,\n async () => {\n for (const step of writes) {\n await fromGithub(c.provider.apply(board, step))\n made++\n }\n }\n )\n } catch (e) {\n if (!(e instanceof RateLimitError)) throw e\n const total = changes + writes.length\n throw new Error(\n `${e.message}: ${total - made} of ${total} changes not made: the next rness board push makes them`,\n { cause: e }\n )\n }\n sayDone(ui, c.org, want.length, steps, writes, adopted, scope.on)\n if (scope.text !== null)\n for (const what of await fromGithub(c.provider.describe(board, scope.text)))\n ui.line('wrote', `${what} of ${scope.label}`)\n for (const line of await fromGithub(\n c.provider.postUpdates(board, scope.updates)\n )) {\n const [verb, ...rest] = line.split(' ')\n ui.line(verb ?? 'posted', rest.join(' '))\n }\n}\n\n/**\n * Every declared project, in turn (spec 0025 §3); `sayLayout` says what a\n * project's layout gained, by the board's name in `boards`.\n */\nasync function syncAll(\n c: Context,\n declared: readonly Declared[],\n ui: Ui,\n sayLayout: (name: string) => SayLayout\n): Promise<void> {\n const tabs = await statusTabs(c.rnessDir)\n for (const d of declared) {\n // The collections the other boards name: none of this board's.\n const owners = declared\n .filter((o) => o !== d)\n .flatMap((o) => namedCollections(o.declaration))\n await syncBoard(\n c,\n d.board,\n ui,\n sayLayout(d.name),\n await scopeOf(c, d.name, d.declaration, tabs, owners)\n )\n }\n}\n\n/**\n * Whether a board may be created under that name: `pulse`, or a collection\n * of `.rness/` — a directory whose documents carry a status (spec 0025 §3,\n * 0033 §4). Throws naming it, before the provider is asked anything.\n */\nexport async function checkBoardName(\n rnessDir: string,\n name: string\n): Promise<void> {\n if (name === PULSE) return\n const tabs = await statusTabs(rnessDir)\n if (!tabs.some((t) => t.name === name))\n throw new Error(\n `\"boards.${name}\": ${name} is no collection of .rness: none of its documents carries a status`\n )\n}\n\n/** The title a board not created yet gets on the provider: as declared, else its preset's. */\nconst titleOf = (b: NotCreated): string =>\n b.declaration.title ?? labelOf(b.name)\n\n/**\n * The boards not created yet, created (spec 0033 §4): asked once, unless\n * `--yes` or `rness pulse create` answered; the login and `.rness`'s Issues\n * checked; each project made, its number written into `rness.json` before\n * anything else can fail; a collection's README declarations moved. Says\n * which were made and which were left: off a terminal, or declined.\n */\nasync function createBoards(\n c: Context,\n boards: readonly NotCreated[],\n opts: BoardOptions,\n terminal: Terminal,\n ui: Ui,\n wait: RateWait\n): Promise<{ c: Context; made: string[]; left: string[] }> {\n for (const b of boards) await checkBoardName(c.rnessDir, b.name)\n // A written provider was already refused by `context`; a detected one is\n // what this writes, so it is refused here, before GitHub is asked\n // anything (spec 0017 §2.2).\n const detected = providerOf(c.manifest)\n if (!PROVIDERS[detected].available)\n throw new Error(\n `boards need a GitHub organization, and this workspace's repositories look like ${detected} (detected): write \"provider\": \"github\" in rness.json if the organization is on GitHub`\n )\n const names = boards.map((b) => b.name)\n if (opts.confirmed !== true && opts.yes !== true) {\n if (!terminal.isTty()) return { c, made: [], left: names }\n const p = await terminal.prompts()\n const ok = await p.confirm({\n message: `Create ${boards.map((b) => `${titleOf(b)} (${b.name})`).join(', ')} on GitHub, in ${c.org}?`,\n })\n if (p.isCancel(ok) || ok !== true) return { c, made: [], left: names }\n }\n const missing = await missingAccess(c.provider)\n if (missing !== null) {\n if (opts.yes === true || !terminal.isTty()) throw new Error(missing)\n const p = await terminal.prompts()\n const ok = await p.confirm({\n message:\n missing === NEEDS_LOGIN\n ? 'Boards need a GitHub login with the project scope. Log in now?'\n : 'Boards need the project scope of your GitHub login. Log in again to grant it?',\n })\n if (p.isCancel(ok) || ok !== true) throw new Error(missing)\n const code = await loginCommand(\n {\n project: true,\n // The git question is `rness login`'s own, not the board's to ask.\n setupGit: false,\n ...(opts.githubApi === undefined ? {} : { githubApi: opts.githubApi }),\n },\n { terminal, ui, ...(opts.cwd === undefined ? {} : { cwd: opts.cwd }) }\n )\n if (code !== 0) throw new Error(missing)\n c = {\n ...c,\n provider: await openProvider(c.manifest, providerOptions(opts, wait)),\n }\n const still = await missingAccess(c.provider)\n if (still !== null) throw new Error(still)\n }\n // Before anything is written: the items are issues of .rness (spec 0018 §2).\n await fromGithub(c.provider.checkIssues(c.org))\n const login = (await c.provider.identity())?.login ?? 'unknown'\n ui.line(\n 'checked',\n `${detected}, logged in as ${login}, scope ${PROJECT_SCOPE}`\n )\n const made: string[] = []\n for (const b of boards) {\n // A preset's name is written whole from that preset (spec 0031 §3, plan\n // 0045), what a collection's README declared in it (spec 0031 §6); a\n // declaration, as the team wrote it.\n const source =\n typeof b.entry === 'string'\n ? await presetSource(b.name, c.rnessDir, null, b.entry)\n : b.declaration.source\n const readme =\n typeof b.entry === 'string' && b.name !== PULSE\n ? await readmeText(c.rnessDir, b.name)\n : null\n const title = titleOf(b)\n const board = await fromGithub(c.provider.createBoard(c.org, title))\n // Declared as soon as the project exists, before its layout: whatever\n // fails after this leaves a declared project that the next push\n // completes, not one nobody knows about (spec 0017 §3).\n const manifest: Manifest = {\n ...c.manifest,\n provider: detected,\n boards: {\n ...c.manifest.boards,\n [b.name]: parseBoard(b.name, { number: board.number, ...source }),\n },\n }\n await writeManifest(c.rnessDir, manifest)\n if (readme !== null) {\n const cleaned = withoutDeclarations(readme)\n if (cleaned !== readme)\n await writeFileAtomic(join(c.rnessDir, b.name, 'README.md'), cleaned)\n }\n c = { ...c, manifest }\n made.push(b.name)\n ui.line('created', `${title} - ${board.url}`)\n }\n return { c, made, left: [] }\n}\n\n/**\n * `rness board push`: every board follows the documents of `.rness/`; one\n * not created yet is created first (spec 0033 §4).\n */\nexport async function boardPushCommand(\n opts: BoardOptions,\n deps: Partial<CommandDeps> = {}\n): Promise<number> {\n try {\n const terminal = deps.terminal ?? defaultTerminal\n const ui = deps.ui ?? (await makeUi(terminal))\n const wait = waitSaid(opts, ui)\n let c = await context(opts, wait)\n if (c.manifest.boards === null) throw noBoard(c)\n const { notCreated } = await declarations(c, ui)\n let made: string[] = []\n let left: string[] = []\n if (notCreated.length > 0)\n ({ c, made, left } = await createBoards(\n c,\n notCreated,\n opts,\n terminal,\n ui,\n wait\n ))\n try {\n // The lines of `declarations` were said above: not twice.\n const declared = await declaredBoards(c)\n await syncAll(c, declared, ui, (n) =>\n made.includes(n) ? createdByKind : eachAdded\n )\n } finally {\n if (made.length > 0)\n ui.line(\n 'declared',\n `${made.join(', ')} in .rness/rness.json - commit it: git -C .rness commit -am \"chore: board ${made.join(', ')}\"`\n )\n }\n if (left.length > 0)\n throw new Error(\n `not created: ${left.join(', ')} - rness board push in a terminal, or with --yes, creates ${left.length === 1 ? 'it' : 'them'}`\n )\n return 0\n } catch (e) {\n return reportError(e)\n }\n}\n\n/** The fields a board's marks write: its select from `$agent`, its text from `$session`. */\nfunction markFields(d: BoardDeclaration): MarkFields | null {\n const fields = Object.entries(d.fields)\n const agent = fields.find(\n ([, f]) => f.type === 'select' && f.from.includes('$agent')\n )?.[0]\n if (agent === undefined) return null\n return {\n agent,\n session: fields.find(([, f]) => f.from.includes('$session'))?.[0] ?? null,\n }\n}\n\n/** Whether a board holds a path's collection: one that takes all holds any. */\nexport const holds = (d: Declared, path: string): boolean =>\n takesAll(d) ||\n namedCollections(d.declaration).includes(collectionOfPath(path))\n\n/** The lock every write of these boards takes: one run at a time per workspace. */\nconst lockKey = (c: Context, declared: readonly Declared[]): string =>\n `${c.org}-${declared.map((d) => d.board.number).join('-')}`\n\n/**\n * Marks, on each board, the items of the paths `wanted` gives it, for\n * `session`. A document with no item yet, or whose status the board does\n * not show yet, is synced first (plan 0027 Task 6, spec 0020 §2).\n * `failed(d, e)` hears a board's own failure; one of all of them throws.\n */\nasync function markOn(\n c: Context,\n declared: readonly Declared[],\n wanted: ReadonlyMap<Declared, ReadonlySet<string>>,\n session: string,\n lock: { sleep?: (ms: number) => Promise<void> },\n failed: (d: Declared, e: unknown) => void = (_d, e) => {\n throw e\n }\n): Promise<void> {\n const key = lockKey(c, declared)\n const syncEvery = () => syncAll(c, declared, plainUi, () => eachAdded)\n // Marks need ids, `Path` and the session: every body, on every edit, is not\n // theirs to download. A sync lists what it needs itself.\n const listed = (board: Board) =>\n fromGithub(c.provider.items(board, { bodies: false }))\n const documents = new Map(\n (await statusTabs(c.rnessDir)).flatMap((t) =>\n t.rows.map((r) => [r.path, r.status] as const)\n )\n )\n let items = new Map<Declared, BoardItem[]>()\n const listAll = async () => {\n items = new Map()\n for (const d of declared) items.set(d, await listed(d.board))\n }\n await listAll()\n const onBoard = new Map(\n [...items.values()]\n .flat()\n .flatMap((i) => (i.path === null ? [] : [[i.path, i.status] as const]))\n )\n const stale = (path: string): boolean =>\n documents.has(path) &&\n (!onBoard.has(path) || onBoard.get(path) !== documents.get(path))\n const all = new Set([...wanted.values()].flatMap((w) => [...w]))\n if ([...all].some(stale)) {\n // Another hook's sync running gives it its item; the next edit marks it.\n if (await oneSyncAtATime(key, syncEvery, lock)) await listAll()\n }\n for (const d of declared) {\n const paths = wanted.get(d)\n if (paths === undefined) continue\n try {\n const ids = (items.get(d) ?? [])\n .filter((i) => i.path !== null && paths.has(i.path))\n .map((i) => i.id)\n if (ids.length > 0)\n await fromGithub(\n c.provider.mark(\n d.board,\n ids,\n session,\n markFields(d.declaration) ?? undefined\n )\n )\n } catch (e) {\n failed(d, e)\n }\n }\n}\n\n/**\n * Clears `session`'s marks on a board — a subagent's too, whose session\n * reads `claude · <type> · <id>` (spec 0025 §3). A board without a field\n * from `$session` cannot tell sessions apart: every mark of it goes.\n */\nasync function clearOn(\n c: Context,\n d: Declared,\n session: string\n): Promise<void> {\n const fields = markFields(d.declaration) ?? {\n agent: 'Agent',\n session: 'Working session',\n }\n const id = session.split(' · ').pop() ?? session\n const ids = (await fromGithub(c.provider.items(d.board, { bodies: false })))\n .filter((i) => {\n const of =\n fields.session === null\n ? null\n : (i.values[fields.session] ??\n (fields.session === 'Working session' ? i.session : null))\n return fields.session === null\n ? i.values[fields.agent] !== undefined\n : of === session || of?.endsWith(` · ${id}`) === true\n })\n .map((i) => i.id)\n await fromGithub(c.provider.mark(d.board, ids, null, fields))\n}\n\nexport interface RunOptions {\n cwd?: string\n githubApi?: string\n /** `session-start`, `edit` or `session-end` (spec 0032 §2). */\n event: string\n session: string\n /** `edit`: the document edited. */\n paths: string[]\n /** `session-start`, `session-end`: the session's scope; absent, the workspace's root. */\n scope?: string\n /** `session-end`: the clone the session worked in, a name of `repos`. */\n clone?: string\n /** Internal (tests): how the lock's poll sleeps. */\n sleep?: (ms: number) => Promise<void>\n}\n\n/**\n * Hidden, for the hooks (spec 0032 §4): the actions each board declares at\n * `event`, in the order of `boards`, under one lock per workspace. It\n * never prompts; a failure is recorded, naming each board and action that\n * failed, for the next session start to say. The exit is 0.\n */\nexport async function boardRunCommand(opts: RunOptions): Promise<number> {\n const failures: string[] = []\n try {\n await run(opts, failures)\n } catch (e) {\n failures.push(e instanceof Error ? e.message : String(e))\n }\n if (failures.length > 0) await recordFailure(failures.join('; '))\n return 0\n}\n\nasync function run(opts: RunOptions, failures: string[]): Promise<void> {\n const event = HOOK_EVENTS.find((e) => e === opts.event)\n if (event === undefined) throw new Error(`no such event: ${opts.event}`)\n const c = await context(opts)\n const declared = await declaredBoards(c)\n const lock = opts.sleep === undefined ? {} : { sleep: opts.sleep }\n const label = (d: Declared): string => d.declaration.title ?? labelOf(d.name)\n const acting = (name: BoardAction['action']) =>\n declared.filter((d) =>\n (d.declaration.hooks[event] ?? []).some((a) => a.action === name)\n )\n if (event === 'session-end') {\n for (const d of acting('journal-summary'))\n try {\n const { postSummary } = await import('../board/summary.ts')\n await postSummary({\n c,\n board: d,\n session: opts.session,\n scope: opts.scope ?? null,\n ...(opts.clone === undefined ? {} : { clone: opts.clone }),\n })\n } catch (e) {\n failures.push(\n `journal-summary on ${label(d)} failed: ${e instanceof Error ? e.message : String(e)}`\n )\n }\n const clearing = acting('clear-marks')\n for (const d of clearing)\n try {\n await clearOn(c, d, opts.session)\n } catch (e) {\n failures.push(\n `clear-marks on ${label(d)} failed: ${e instanceof Error ? e.message : String(e)}`\n )\n }\n if (clearing.length === 0) return\n // The session's last sync waits its turn behind an edit's.\n await oneSyncAtATime(\n lockKey(c, declared),\n () => syncAll(c, declared, plainUi, () => eachAdded),\n { ...lock, wait: true }\n )\n return\n }\n const wanted = new Map<Declared, Set<string>>()\n const action = event === 'edit' ? 'mark' : 'mark-in-progress'\n for (const d of acting(action)) {\n let paths = opts.paths\n if (event === 'session-start') {\n const a = (d.declaration.hooks['session-start'] ?? []).find(\n (x) => x.action === 'mark-in-progress'\n )\n paths =\n a?.action === 'mark-in-progress'\n ? await documentsIn(\n { root: c.root, rnessDir: c.rnessDir },\n c.manifest,\n opts.scope ?? null,\n a.collections,\n a.statuses\n )\n : []\n }\n const held = paths.filter((p) => holds(d, p))\n if (held.length > 0) wanted.set(d, new Set(held))\n }\n if (wanted.size === 0) return\n await markOn(c, declared, wanted, opts.session, lock, (d, e) =>\n failures.push(\n `${action} on ${label(d)} failed: ${e instanceof Error ? e.message : String(e)}`\n )\n )\n}\n\n/**\n * `rness pulse create [collection]`, a former command (spec 0033 §2): the\n * board declared by its preset's name when `boards` does not name it yet,\n * then pushed, its creation answered by the command typed.\n */\nexport async function pulseCreateCommand(\n collection: string | undefined,\n opts: BoardOptions,\n deps: Partial<CommandDeps> = {}\n): Promise<number> {\n try {\n const name = collection ?? PULSE\n const ws = await findWorkspace(opts.cwd ?? process.cwd())\n const manifest = await loadManifest(ws.rnessDir)\n if (manifest.org === null)\n throw new Error('boards need an organization: rness.json has no \"org\"')\n const refused = manifest.refused?.find((r) => r.name === name)\n if (refused !== undefined)\n throw new Error(`already declared, and refused: ${refused.reason}`)\n let said = 'rness pulse create is now rness board push'\n if (manifest.boards?.[name] === undefined) {\n await checkBoardName(ws.rnessDir, name)\n const preset = presetFor(name)\n await writeManifest(ws.rnessDir, {\n ...manifest,\n boards: { ...manifest.boards, [name]: preset },\n })\n said = `boards are declared in rness.json now: added \"${name}\": \"${preset}\", then rness board push`\n }\n process.stderr.write(`${said}\\n`)\n return await boardPushCommand({ ...opts, confirmed: true }, deps)\n } catch (e) {\n return reportError(e)\n }\n}\n","import { spawn as nodeSpawn } from 'node:child_process'\nimport { mkdir, open, readFile, rm, stat, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { setTimeout as delay } from 'node:timers/promises'\n\nimport { configDir } from '../core/auth.ts'\n\n/**\n * Runs `rness <args>` detached, from `cwd`: the hooks return at once and the\n * boards' GitHub calls finish on their own (spec 0017 §5).\n */\nexport type Spawn = (args: string[], cwd: string) => void\n\n/**\n * The hook already runs as the pinned copy's bin, so `process.argv[1]` is\n * the launcher to run again. `RNESS_NO_DELEGATE` keeps the child from\n * delegating or catching up.\n */\nexport const detached: Spawn = (args, cwd) => {\n const bin = process.argv[1]\n if (bin === undefined) return\n const child = nodeSpawn(process.execPath, [bin, ...args], {\n detached: true,\n stdio: 'ignore',\n cwd,\n env: { ...process.env, RNESS_NO_DELEGATE: '1' },\n })\n child.on('error', () => undefined)\n child.unref()\n}\n\nconst failureFile = (): string => join(configDir(), 'board.json')\n/** Where 0.21 and before recorded it: still read, once (plan 0048). */\nconst formerFailureFile = (): string => join(configDir(), 'pulse.json')\n\n/** What a detached `board run` could not do, for the next session start. */\nexport async function recordFailure(reason: string): Promise<void> {\n try {\n await mkdir(configDir(), { recursive: true, mode: 0o700 })\n await writeFile(\n failureFile(),\n `${JSON.stringify({ at: new Date().toISOString(), reason })}\\n`\n )\n } catch {\n // Nowhere to say it: the mark already failed, and nothing may throw here.\n }\n}\n\n/** The recorded failure's reason, once: reading it deletes it; a former record is read when there is no other. */\nexport async function takeFailure(): Promise<string | null> {\n return (\n (await takeFrom(failureFile())) ?? (await takeFrom(formerFailureFile()))\n )\n}\n\nasync function takeFrom(file: string): Promise<string | null> {\n try {\n const data: unknown = JSON.parse(await readFile(file, 'utf8'))\n await rm(file, { force: true })\n const reason =\n data !== null && typeof data === 'object'\n ? (data as Record<string, unknown>)['reason']\n : undefined\n return typeof reason === 'string' && reason !== '' ? reason : null\n } catch {\n return null\n }\n}\n\n/** A lock older than this is a crashed process's: a sync waits 10 minutes at most on GitHub. */\nconst LOCK_STALE_MS = 15 * 60_000\n\n/**\n * The hooks' syncs of one board, one at a time: two at once would each give\n * a new document an issue (plan 0027 Task 6). Runs `work` holding the lock\n * and says true. Held by another process, it says false at once — or, with\n * `wait`, polls each second until the lock is free or stale.\n */\nexport async function oneSyncAtATime(\n key: string,\n work: () => Promise<void>,\n options: { wait?: boolean; sleep?: (ms: number) => Promise<void> } = {}\n): Promise<boolean> {\n await mkdir(configDir(), { recursive: true, mode: 0o700 })\n const file = join(configDir(), `board-${key}.lock`)\n for (;;) {\n try {\n const handle = await open(file, 'wx')\n await handle.close()\n break\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== 'EEXIST') throw e\n const age = await stat(file).then(\n (s) => Date.now() - s.mtimeMs,\n () => 0\n )\n if (age > LOCK_STALE_MS) await rm(file, { force: true })\n else if (options.wait !== true) return false\n else await (options.sleep ?? ((ms: number) => delay(ms)))(1_000)\n }\n }\n try {\n await work()\n return true\n } finally {\n await rm(file, { force: true })\n }\n}\n","import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\n\nimport { gitPath } from '../core/git.ts'\n\n/**\n * What a sync has told this clone once (spec 0031 §4): a field or a view no\n * longer declared, views out of the declared order. Kept in the git\n * directory — per worktree, never pushed — as a JSON list of lines, each\n * prefixed with its board's number. Said again once it stops and returns.\n */\nconst NAME = 'rness/noted'\n\nexport function notedFile(rnessDir: string): Promise<string | null> {\n return gitPath(rnessDir, NAME)\n}\n\n/** The lines `file` records; missing or corrupt, none. Never throws. */\nexport async function readNoted(file: string | null): Promise<Set<string>> {\n if (file === null) return new Set()\n try {\n const data: unknown = JSON.parse(await readFile(file, 'utf8'))\n return new Set(\n Array.isArray(data)\n ? data.filter((l): l is string => typeof l === 'string')\n : []\n )\n } catch {\n return new Set()\n }\n}\n\n/** `noted` written whole, as `writeOpened` does; none, no file. Best effort. */\nexport async function writeNoted(\n file: string | null,\n noted: ReadonlySet<string>\n): Promise<void> {\n if (file === null) return\n try {\n if (noted.size === 0) {\n await rm(file, { force: true })\n return\n }\n await mkdir(dirname(file), { recursive: true })\n const temporary = `${file}.${process.pid}`\n await writeFile(\n temporary,\n `${JSON.stringify([...noted].sort(), null, 2)}\\n`\n )\n await rename(temporary, file)\n } catch {\n // A note said twice is the worst a lost record does.\n }\n}\n\n/**\n * The layout lines of one board to say: every line but a note already said\n * for it. The record keeps the notes that still hold, the others forgotten.\n */\nexport async function onceSaid(\n rnessDir: string,\n board: number,\n lines: readonly string[]\n): Promise<string[]> {\n const file = await notedFile(rnessDir)\n const noted = await readNoted(file)\n const prefix = `${board}: `\n const notes = lines.filter((l) => l.startsWith('note '))\n const now = new Set(notes.map((l) => `${prefix}${l}`))\n const said = lines.filter(\n (l) => !l.startsWith('note ') || !noted.has(`${prefix}${l}`)\n )\n const next = new Set([\n ...[...noted].filter((l) => !l.startsWith(prefix)),\n ...now,\n ])\n if (next.size !== noted.size || [...next].some((l) => !noted.has(l)))\n await writeNoted(file, next)\n return said\n}\n","import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\n\nimport { gitPath } from '../core/git.ts'\nimport type { Opened } from './plan.ts'\n\n/**\n * The issues this clone's syncs opened (spec 0018 §2), kept in its git\n * directory — per worktree, never pushed — as a JSON map from issue number\n * to path: `{ \"12\": \"specs/0019-x.md\" }`.\n */\nconst NAME = 'rness/opened'\n\n/** Where this clone keeps its record; null when `.rness` is no repository: nothing is recorded. */\nexport function openedFile(rnessDir: string): Promise<string | null> {\n return gitPath(rnessDir, NAME)\n}\n\n/** A positive issue number, as JSON keys write it: `12`, not `012` nor `1.5`. */\nconst NUMBER = /^[1-9][0-9]*$/\n\n/**\n * What `file` records. Missing, unreadable or corrupt, it records nothing;\n * an entry that is no number and path is skipped. Never throws.\n */\nexport async function readOpened(\n file: string | null\n): Promise<Map<number, string>> {\n const opened = new Map<number, string>()\n if (file === null) return opened\n let data: unknown\n try {\n data = JSON.parse(await readFile(file, 'utf8'))\n } catch {\n return opened\n }\n if (data === null || typeof data !== 'object' || Array.isArray(data))\n return opened\n for (const [key, path] of Object.entries(data))\n if (NUMBER.test(key) && typeof path === 'string' && path !== '')\n opened.set(Number(key), path)\n return opened\n}\n\n/**\n * `opened` written to `file` whole — a temporary file renamed over it, so a\n * reader never sees half of one; none left, no file. Best effort: a record\n * lost leaves at most a stale card, never a wrong close.\n */\nexport async function writeOpened(\n file: string | null,\n opened: Opened\n): Promise<void> {\n if (file === null) return\n try {\n if (opened.size === 0) {\n await rm(file, { force: true })\n return\n }\n const entries = [...opened].sort(([a], [b]) => a - b)\n await mkdir(dirname(file), { recursive: true })\n const temporary = `${file}.${process.pid}`\n await writeFile(\n temporary,\n `${JSON.stringify(Object.fromEntries(entries), null, 2)}\\n`\n )\n await rename(temporary, file)\n } catch {\n // See above.\n }\n}\n","import { readFile } from 'node:fs/promises'\n\nimport { parseDocument } from 'yaml'\n\nimport { BoardRefused, parseBoard } from './board-declaration.ts'\nimport { mergeBoard } from './board-merge.ts'\nimport { containedPath } from './contained.ts'\nimport { parseFrontMatter } from './frontmatter.ts'\nimport { presetSource } from './preset-board.ts'\nimport {\n type PresetName,\n currentPreset,\n isPresetRevision,\n presetNameOf,\n presetTemplate,\n} from './presets.ts'\nimport type { Boards, Manifest } from './types.ts'\n\n/**\n * What `sync` does to the boards of `rness.json` (plan 0045), in the copy\n * an upgrade runs: `projects`, or the older `pulse`, renamed `boards` (spec\n * 0033 §3); a board declared by its number (0.20 and before) written whole;\n * what a collection's `README.md` declared (spec 0025 §4) moved into its\n * board (spec 0031 §6); a newer revision of a preset merged into the boards\n * made from an older one. A preset not created yet is left as written:\n * `board push` writes it whole. `upgrade` commits the result.\n */\n\n/** The keys of a collection's README that `rness.json` declares now. */\nexport const README_KEYS = [\n 'description',\n 'statuses',\n 'fields',\n 'labels',\n] as const\ntype ReadmeKey = (typeof README_KEYS)[number]\n\n/** The presets as `sync` knows them: the bundled ones, or a test's. */\nexport interface Presets {\n current: (name: PresetName) => string\n template: (\n ref: string,\n vars: { collection: string }\n ) => Record<string, unknown>\n knows: (ref: string) => boolean\n}\nconst BUNDLED: Presets = {\n current: currentPreset,\n template: presetTemplate,\n knows: isPresetRevision,\n}\n\nconst README = (collection: string): string => `${collection}/README.md`\n\nasync function readmeOf(\n rnessDir: string,\n collection: string\n): Promise<string | null> {\n try {\n return await readFile(\n await containedPath(rnessDir, README(collection)),\n 'utf8'\n )\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') return null\n throw e\n }\n}\n\n/** What a collection's README still declares, by key; none when it has no README or no such key. */\nexport async function readmeDeclarations(\n rnessDir: string,\n collection: string\n): Promise<Partial<Record<ReadmeKey, unknown>>> {\n const text = await readmeOf(rnessDir, collection)\n if (text === null) return {}\n const front = parseFrontMatter(text) ?? {}\n return Object.fromEntries(\n README_KEYS.filter((k) => front[k] !== undefined).map((k) => [k, front[k]])\n )\n}\n\nconst FRONT = /^(\\uFEFF?)---\\r?\\n([\\s\\S]*?)\\r?\\n?---(\\r?\\n|$)/\n\n/** `text` without the keys rness.json declares now; a front matter left empty goes whole. */\nexport function withoutDeclarations(text: string): string {\n const match = FRONT.exec(text)\n if (match === null) return text\n const doc = parseDocument(match[2] ?? '')\n for (const key of README_KEYS) doc.delete(key)\n const rest = String(doc).trim()\n const after = text.slice(match[0].length)\n return rest === '' || rest === '{}'\n ? `${match[1] ?? ''}${after.replace(/^(?:[ \\t]*\\r?\\n)+/, '')}`\n : `${match[1] ?? ''}---\\n${rest}\\n---${match[3] ?? '\\n'}${after}`\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n v !== null && typeof v === 'object' && !Array.isArray(v)\n\nconst same = (a: unknown, b: unknown): boolean =>\n JSON.stringify(a) === JSON.stringify(b)\n\n/** A README's field as a board's: `from` a list, `options` only when it has some. */\nfunction asBoardField(value: unknown): unknown {\n if (!isRecord(value)) return value\n const from = value['from']\n const options = value['options']\n return {\n type: value['type'],\n from: typeof from === 'string' ? [from] : from,\n ...(Array.isArray(options) && options.length > 0 ? { options } : {}),\n }\n}\n\n/** A board's field compared as a README's: `from` a list, no empty options. */\nconst normalField = (value: unknown): unknown => asBoardField(value)\n\nexport interface Migration {\n /** Whether rness.json or a README is to be written. */\n changed: boolean\n boards: Boards | null\n /** The READMEs to write, by path of `.rness/`. */\n readmes: Map<string, string>\n /** What `sync` says, `[verb, rest]`. */\n lines: [string, string][]\n}\n\n/**\n * The README declarations of `collection` moved into `source`, a board's\n * JSON: a key the board lacks moved, one it declares alike dropped; one it\n * declares otherwise refused, naming both, the README left as it is.\n */\nfunction moveInto(\n name: string,\n collection: string,\n source: Record<string, unknown>,\n declared: Partial<Record<ReadmeKey, unknown>>\n): string | null {\n const collections = source['collections']\n const entry = isRecord(collections) ? collections[collection] : undefined\n const fields = isRecord(source['fields']) ? { ...source['fields'] } : {}\n const conflicts: string[] = []\n const take = (\n key: ReadmeKey,\n ours: unknown,\n theirs: unknown,\n set: () => void\n ) => {\n if (ours === undefined) set()\n else if (!same(ours, theirs)) conflicts.push(key)\n }\n if (declared.description !== undefined)\n take('description', source['description'], declared.description, () => {\n source['description'] = declared.description\n })\n if (declared.statuses !== undefined && isRecord(entry)) {\n const ours = entry['statuses']\n // \"found\" is no declaration of the board's: the README's list is.\n if (ours === undefined || ours === 'found')\n entry['statuses'] = declared.statuses\n else if (!same(ours, declared.statuses)) conflicts.push('statuses')\n }\n if (declared.labels !== undefined)\n take('labels', source['labels'], declared.labels, () => {\n source['labels'] = declared.labels\n })\n if (isRecord(declared.fields))\n for (const [field, value] of Object.entries(declared.fields)) {\n const ours = fields[field]\n if (ours === undefined) fields[field] = asBoardField(value)\n else if (!same(normalField(ours), asBoardField(value)))\n conflicts.push(`fields.${field}`)\n }\n if (conflicts.length > 0)\n return `${README(collection)} declares ${conflicts.join(', ')} otherwise than boards.${name}: keep one, in rness.json`\n source['fields'] = fields\n return null\n}\n\n/** The boards of `manifest` as `sync` leaves them; nothing written here. */\nexport async function migrateBoards(\n rnessDir: string,\n manifest: Manifest,\n presets: Presets = BUNDLED\n): Promise<Migration> {\n const migration: Migration = {\n changed: false,\n boards: manifest.boards,\n readmes: new Map(),\n lines: [],\n }\n if (manifest.formerKey !== undefined) {\n migration.lines.push([\n 'renamed',\n `${manifest.formerKey} to boards in .rness/rness.json`,\n ])\n migration.changed = true\n }\n if (manifest.boards === null) return migration\n const boards: Boards = {}\n for (const [name, entry] of Object.entries(manifest.boards)) {\n if (typeof entry === 'string') {\n boards[name] = entry\n continue\n }\n let source: Record<string, unknown>\n if (typeof entry === 'number') {\n // Today's board, from its preset and its README's declarations.\n source = await presetSource(name, rnessDir, entry)\n migration.lines.push([\n 'wrote',\n `${name} whole in .rness/rness.json, from ${String(source['preset'])}`,\n ])\n migration.changed = true\n } else source = structuredClone(entry.source) as Record<string, unknown>\n\n // A collection's README declarations: in the board now (spec 0031 §6).\n const collections = source['collections']\n for (const collection of isRecord(collections)\n ? Object.keys(collections)\n : []) {\n const declared = await readmeDeclarations(rnessDir, collection)\n const keys = Object.keys(declared)\n if (keys.length === 0) continue\n const refused =\n typeof entry === 'number'\n ? null\n : moveInto(name, collection, source, declared)\n if (refused !== null) {\n migration.lines.push(['refused', refused])\n continue\n }\n const text = await readmeOf(rnessDir, collection)\n if (text !== null)\n migration.readmes.set(README(collection), withoutDeclarations(text))\n migration.lines.push([\n 'moved',\n `${keys.join(', ')} of ${README(collection)} into rness.json`,\n ])\n migration.changed = true\n }\n\n // A newer revision of its preset, merged (plan 0045).\n const recorded = source['preset']\n if (typeof recorded === 'string') {\n const preset = presetNameOf(recorded) as PresetName\n const current = presets.current(preset)\n const revision = (ref: string) => Number(ref.split('/')[1])\n if (revision(recorded) < revision(current)) {\n const vars = { collection: name }\n const { board, kept } = mergeBoard(\n name,\n presets.template(recorded, vars),\n source,\n presets.template(current, vars),\n current\n )\n source = board\n migration.lines.push(['merged', `${name} to ${current}`])\n for (const k of kept) migration.lines.push(['kept', k])\n migration.changed = true\n }\n }\n\n try {\n boards[name] =\n typeof entry === 'number' || migration.changed\n ? parseBoard(name, source, presets.knows)\n : entry\n } catch (e) {\n if (!(e instanceof BoardRefused)) throw e\n // A merge or a move the declaration refuses: the board left as it was.\n migration.lines.push(['refused', e.message])\n boards[name] = entry\n }\n }\n migration.boards = boards\n return migration\n}\n","/**\n * A newer revision of a preset brought into a board made from an older one\n * (plan 0045): a three-way merge, value by value. The base is the revision\n * the board records, the team's value is the board's, the new value the\n * current revision's. A value the team never changed takes the new one; one\n * it changed is kept, and named when the revision changed it too. Pure: no\n * file, no network.\n */\n\ntype Json = unknown\n\nconst isObject = (v: Json): v is Record<string, Json> =>\n v !== null && typeof v === 'object' && !Array.isArray(v)\n\nfunction same(a: Json, b: Json): boolean {\n if (a === b) return true\n if (Array.isArray(a) && Array.isArray(b))\n return a.length === b.length && a.every((v, i) => same(v, b[i]))\n if (isObject(a) && isObject(b)) {\n const keys = Object.keys(a)\n return (\n keys.length === Object.keys(b).length &&\n keys.every((k) => Object.hasOwn(b, k) && same(a[k], b[k]))\n )\n }\n return false\n}\n\nconst shown = (v: Json): string =>\n typeof v === 'string' ? v : JSON.stringify(v)\n\n/** What the merge keeps against the revision, as `sync` says it. */\ntype Kept = string[]\n\n/**\n * One value: `undefined` is a value absent. Two changes alike are one;\n * objects changed on both sides merge key by key; any other pair keeps the\n * team's, named.\n */\nfunction mergeValue(\n at: string,\n base: Json,\n ours: Json,\n theirs: Json,\n ref: string,\n kept: Kept\n): Json {\n if (same(ours, theirs)) return ours\n if (same(ours, base)) return theirs\n if (same(theirs, base)) return ours\n if (\n isObject(ours) &&\n isObject(theirs) &&\n (base === undefined || isObject(base))\n )\n return mergeObject(at, isObject(base) ? base : {}, ours, theirs, ref, kept)\n kept.push(\n ours === undefined\n ? `${at}: kept none, ${ref} gives ${shown(theirs)}`\n : theirs === undefined\n ? `${at}: kept ${shown(ours)}, ${ref} removes it`\n : `${at}: kept ${shown(ours)}, ${ref} gives ${shown(theirs)}`\n )\n return ours\n}\n\nfunction mergeObject(\n at: string,\n base: Record<string, Json>,\n ours: Record<string, Json>,\n theirs: Record<string, Json>,\n ref: string,\n kept: Kept\n): Record<string, Json> {\n const merged: Record<string, Json> = {}\n const keys = [\n ...Object.keys(ours),\n ...Object.keys(theirs).filter((k) => !Object.hasOwn(ours, k)),\n ]\n for (const key of keys) {\n const value = mergeValue(\n `${at}.${key}`,\n base[key],\n ours[key],\n theirs[key],\n ref,\n kept\n )\n if (value !== undefined) merged[key] = value\n }\n return merged\n}\n\nconst nameOf = (v: Json): string | undefined =>\n isObject(v) && typeof v['name'] === 'string' ? v['name'] : undefined\n\nconst byName = (views: Json): Map<string, Json> =>\n new Map(\n (Array.isArray(views) ? views : []).flatMap((v) => {\n const name = nameOf(v)\n return name === undefined ? [] : [[name, v] as const]\n })\n )\n\n/**\n * Views by name: the team's in its order, each merged; one the revision\n * removed goes when the team never touched it; one it adds comes after.\n */\nfunction mergeViews(\n at: string,\n base: Json,\n ours: Json,\n theirs: Json,\n ref: string,\n kept: Kept\n): Json[] {\n const [b, t] = [byName(base), byName(theirs)]\n const merged: Json[] = []\n for (const view of Array.isArray(ours) ? ours : []) {\n const name = nameOf(view)\n if (name === undefined) {\n merged.push(view)\n continue\n }\n const value = mergeValue(\n `${at}.${name}`,\n b.get(name),\n view,\n t.get(name),\n ref,\n kept\n )\n if (value !== undefined) merged.push(value)\n }\n const there = byName(ours)\n for (const [name, view] of t)\n if (!there.has(name) && !b.has(name)) merged.push(view)\n return merged\n}\n\n/**\n * The board `name` made from `base` (its preset's revision), `ours` as\n * `rness.json` holds it, brought to `theirs` (revision `ref`): the merged\n * board, recording `ref`, and what was kept against it.\n */\nexport function mergeBoard(\n name: string,\n base: Record<string, Json>,\n ours: Record<string, Json>,\n theirs: Record<string, Json>,\n ref: string\n): { board: Record<string, Json>; kept: string[] } {\n const at = `boards.${name}`\n const kept: Kept = []\n const { number, preset: _, ...team } = ours\n const keys = [\n ...Object.keys(team),\n ...Object.keys(theirs).filter((k) => !Object.hasOwn(team, k)),\n ]\n const board: Record<string, Json> = {}\n if (number !== undefined) board['number'] = number\n board['preset'] = ref\n for (const key of keys) {\n const value =\n key === 'views'\n ? mergeViews(\n `${at}.views`,\n base[key],\n team[key],\n theirs[key],\n ref,\n kept\n )\n : mergeValue(\n `${at}.${key}`,\n base[key],\n team[key],\n theirs[key],\n ref,\n kept\n )\n if (value !== undefined) board[key] = value\n }\n return { board, kept }\n}\n","import { stat } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nimport { readShape } from '../board/collection.ts'\nimport {\n type BoardDeclaration,\n PULSE,\n parseBoard,\n presetFor,\n} from './board-declaration.ts'\nimport { loadManifest } from './manifest.ts'\nimport { currentPreset, presetTemplate } from './presets.ts'\nimport type { BoardEntry, Boards } from './types.ts'\n\n/**\n * A board as `board push` and the migration write it (plan 0045): the\n * current revision of its preset, made for this workspace — Agent Pulse\n * for `pulse`, a collection's own board for any other name — and, for a\n * collection, what its `README.md` declared before 0.21.0 (spec 0025 §4).\n */\n\n/** The keys of a board in the order spec 0031 §2.2 gives them. */\nconst ORDER = [\n 'number',\n 'preset',\n 'title',\n 'description',\n 'readme',\n 'updates',\n 'collections',\n 'colors',\n 'fields',\n 'labels',\n 'views',\n]\n\nconst ordered = (board: Record<string, unknown>): Record<string, unknown> =>\n Object.fromEntries(\n [\n ...ORDER.filter((k) => Object.hasOwn(board, k)),\n ...Object.keys(board).filter((k) => !ORDER.includes(k)),\n ].map((k) => [k, board[k]])\n )\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * The board `name` gets from its preset in this workspace, on project\n * `number` (none until `board push` creates it), as `rness.json` holds it:\n * from the revision `ref` names (`collection/1`), else the current one.\n */\nexport async function presetSource(\n name: string,\n rnessDir: string,\n number: number | null,\n ref?: string\n): Promise<Record<string, unknown>> {\n const kind = presetFor(name)\n const preset = ref?.includes('/') === true ? ref : currentPreset(kind)\n const numbered = number === null ? {} : { number }\n if (name === PULSE)\n return ordered({\n ...numbered,\n preset,\n ...presetTemplate(preset, { collection: name }),\n })\n const board: Record<string, unknown> = {\n ...numbered,\n preset,\n ...presetTemplate(preset, { collection: name }),\n }\n if (await exists(join(rnessDir, name, 'README.md')))\n board['readme'] = `${name}/README.md`\n if (await exists(join(rnessDir, name, 'updates')))\n board['updates'] = `${name}/updates`\n // What the README declared before 0.21.0 (spec 0025 §4), as the board's.\n const shape = await readShape(rnessDir, name)\n if (shape.description !== null) board['description'] = shape.description\n const collections = board['collections'] as Record<\n string,\n Record<string, unknown>\n >\n if (shape.statuses !== null && collections[name] !== undefined)\n collections[name]['statuses'] = [...shape.statuses]\n const fields = board['fields'] as Record<string, unknown>\n for (const f of shape.fields)\n fields[f.name] = {\n type: f.type,\n from: f.from.length === 1 ? f.from[0] : [...f.from],\n ...(f.options.length === 0 ? {} : { options: [...f.options] }),\n }\n if (shape.labels !== null)\n board['labels'] =\n shape.labels.kind === 'directory' ? 'directory' : shape.labels.key\n // A date declared: the calendar spec 0025's project had, after the board.\n const date = shape.fields.find((f) => f.type === 'date')\n if (date !== undefined) {\n const views = board['views'] as Record<string, unknown>[]\n const at = views.findIndex(\n (v) => v['collection'] === name && v['layout'] === 'board'\n )\n views.splice(at + 1, 0, {\n name: 'Calendar',\n layout: 'roadmap',\n collection: name,\n date: date.name,\n })\n }\n return ordered(board)\n}\n\n/**\n * A board of `boards` as a declaration: a number is its preset, as `sync`\n * would write it; a preset's name, as `board push` will write it.\n */\nexport async function declaredBoard(\n name: string,\n entry: BoardEntry,\n rnessDir: string\n): Promise<BoardDeclaration> {\n if (typeof entry === 'number')\n return parseBoard(name, await presetSource(name, rnessDir, entry))\n if (typeof entry === 'string')\n return parseBoard(name, await presetSource(name, rnessDir, null, entry))\n return entry\n}\n\n/** A board of `rness.json`, read whole (a number or a preset's name is its preset). */\nexport interface NamedBoard {\n name: string\n declaration: BoardDeclaration\n}\n\n/**\n * The boards `rness.json` declares and the provider has, for what reads\n * them on a session's path (the hooks, `rness mcp`): none when it cannot be\n * read; a board not created yet, left out until `board push` creates it;\n * one that cannot be read, left out — `validate` and the safety net say\n * why. Never throws.\n */\nexport async function readBoards(rnessDir: string): Promise<NamedBoard[]> {\n let declared: Boards\n try {\n declared = (await loadManifest(rnessDir)).boards ?? {}\n } catch {\n return []\n }\n const boards: NamedBoard[] = []\n for (const [name, entry] of Object.entries(declared))\n try {\n const declaration = await declaredBoard(name, entry, rnessDir)\n if (declaration.number !== null) boards.push({ name, declaration })\n } catch {\n // Refused: said elsewhere.\n }\n return boards\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,UAAU,SAAS,YAAY;AAExC,eAAsB,OAAO,GAA6B;AACxD,MAAI;AACF,UAAM,OAAO,CAAC;AACd,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOA,eAAsB,UAAU,GAA6B;AAC3D,MAAI;AACF,YAAQ,MAAM,MAAM,CAAC,GAAG,eAAe;AAAA,EACzC,SAAS,GAAG;AACV,QAAK,EAA4B,SAAS,SAAU,QAAO;AAC3D,UAAM;AAAA,EACR;AACF;AAGA,eAAsB,WAAW,GAAmC;AAClE,MAAI;AACF,WAAO,MAAM,SAAS,GAAG,MAAM;AAAA,EACjC,SAAS,GAAG;AACV,QAAK,EAA4B,SAAS,SAAU,QAAO;AAC3D,UAAM;AAAA,EACR;AACF;AAEA,IAAI,WAAW;AAGf,eAAsB,gBAAgB,GAAW,MAA6B;AAC5E,cAAY;AACZ,QAAM,MAAM,KAAK,QAAQ,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,IAAI,QAAQ,GAAG,IAAI,QAAQ,MAAM;AAC7E,QAAM,UAAU,KAAK,MAAM,MAAM;AACjC,MAAI;AACF,UAAM,OAAO,KAAK,CAAC;AAAA,EACrB,SAAS,GAAG;AACV,UAAM,GAAG,KAAK,EAAE,OAAO,KAAK,CAAC,EAAE,MAAM,MAAM,MAAS;AACpD,UAAM;AAAA,EACR;AACF;;;ACxDA,SAAS,aAAa;AAMtB,IAAM,eAAe;AAErB,SAAS,KAAK,SAAwB;AACpC,QAAM,IAAI,MAAM,iBAAiB,OAAO,EAAE;AAC5C;AAGA,SAAS,SAAS,QAAwB;AACxC,SAAO,OAAO,WAAW,QAAG,IAAI,OAAO,MAAM,CAAC,IAAI;AACpD;AAQO,SAAS,iBAAiB,QAA+B;AAC9D,QAAM,QAAQ,SAAS,MAAM,EAAE,MAAM,YAAY;AACjD,MAAI,UAAU,KAAM,QAAO;AAC3B,QAAM,QAAQ,MAAM,CAAC,KAAK;AAC1B,MAAI,MAAM,KAAK,MAAM,GAAI,QAAO,CAAC;AACjC,MAAI;AACJ,MAAI;AAGF,UAAM,MAAM,OAAO,EAAE,UAAU,QAAQ,CAAC;AAAA,EAC1C,SAAS,GAAG;AACV;AAAA,MACE,aAAa,SACR,EAAE,QAAQ,MAAM,IAAI,EAAE,CAAC,KAAK,gBAAgB,QAAQ,MAAM,EAAE,IAC7D;AAAA,IACN;AAAA,EACF;AACA,MAAI,QAAQ,QAAQ,QAAQ,OAAW,QAAO,CAAC;AAC/C,MAAI,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG;AAC9C,SAAK,2CAA2C;AAClD,SAAO;AACT;AASO,SAAS,iBAAiB,QAAwB;AACvD,QAAM,OAAO,SAAS,MAAM;AAC5B,QAAM,QAAQ,KAAK,MAAM,YAAY;AACrC,MAAI,UAAU,KAAM,QAAO;AAC3B,SAAO,KAAK,MAAM,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,qBAAqB,EAAE;AACpE;AAEO,SAAS,aAAa,QAA+B;AAC1D,SACE,SAAS,MAAM,EACZ,MAAM,WAAW,IAAI,CAAC,GACrB,KAAK,KAAK;AAElB;;;AClEA,SAAS,MAAM,YAAAA,iBAAgB;AAC/B,SAAS,QAAAC,OAAM,OAAO,WAAW;AASjC,SAAS,QAAQ,KAAqB;AACpC,SAAO,IAAI,MAAM,GAAG,EAAE,KAAK,MAAM,GAAG;AACtC;AAMO,SAAS,aACd,MACA,KACA,MACc;AACd,MAAIC,UAAiC;AACrC,MAAI,cAA6B;AACjC,MAAI;AACF,IAAAA,UAAS,iBAAiB,IAAI;AAAA,EAChC,SAAS,GAAG;AACV,kBAAc,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,EACzD;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAAA;AAAA,IACA;AAAA,IACA,OAAO,aAAa,IAAI;AAAA,IACxB;AAAA,IACA,SAAS,iBAAiB,IAAI;AAAA,EAChC;AACF;AAQA,eAAsB,gBAAgB,KAAsC;AAC1E,QAAM,OAAiB,CAAC;AACxB,mBAAiB,OAAO,KAAK,WAAW,EAAE,KAAK,IAAI,CAAC,EAAG,MAAK,KAAK,QAAQ,GAAG,CAAC;AAC7E,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B,KAAK,IAAI,OAAO,QAAQ;AACtB,YAAM,OAAOC,MAAK,KAAK,GAAG,IAAI,MAAM,MAAM,GAAG,CAAC;AAC9C,aAAO,aAAa,MAAM,KAAK,MAAMC,UAAS,MAAM,MAAM,CAAC;AAAA,IAC7D,CAAC;AAAA,EACH;AACA,SAAO,MAAM,KAAK,CAAC,GAAG,MAAO,EAAE,MAAM,EAAE,MAAM,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,CAAE;AAC1E;;;ACvDA,SAAS,SAAS,QAAgBC,SAAyB;AACzD,SAAO,WAAWA,WAAUA,QAAO,WAAW,GAAG,MAAM,GAAG;AAC5D;AAGO,SAAS,aACd,UACA,QACe;AACf,MAAI,OAAsB;AAC1B,MAAI,UAAU;AACd,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,SAAS,MAAM,GAAG;AAC3D,QAAI,SAAS,MAAM,MAAM,MAAM,KAAK,MAAM,KAAK,SAAS,SAAS;AAC/D,aAAO;AACP,gBAAU,MAAM,KAAK;AAAA,IACvB;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,WAAW,UAAoB,OAAgC;AAC7E,MAAI,UAAU,KAAM,QAAO,CAAC;AAC5B,QAAM,QAAkB,CAAC;AACzB,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,QAAQ,CAAC,MAAc,UAA6B;AACxD,QAAI,MAAM,IAAI,IAAI,EAAG,OAAM,IAAI,MAAM,2BAA2B,IAAI,GAAG;AACvE,QAAI,KAAK,IAAI,IAAI,EAAG;AACpB,SAAK,IAAI,IAAI;AACb,UAAM,KAAK,IAAI;AACf,UAAM,IAAI,IAAI;AACd,UAAM,QAAQ,OAAO,OAAO,SAAS,QAAQ,IAAI,IAC7C,SAAS,OAAO,IAAI,IACpB;AACJ,eAAWA,WAAU,OAAO,WAAW,CAAC,EAAG,OAAMA,SAAQ,KAAK;AAC9D,UAAM,OAAO,IAAI;AAAA,EACnB;AACA,QAAM,OAAO,oBAAI,IAAI,CAAC;AACtB,SAAO;AACT;;;ACzCA,SAAS,QAAAC,aAAY;AAad,IAAM,cAAyC;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,SAAS,WAAW,KAA4B;AACrD,QAAM,QAAQ,IAAI,QAAQ,GAAG;AAC7B,SAAO,UAAU,KAAK,OAAO,IAAI,MAAM,GAAG,KAAK;AACjD;AASA,eAAe,mBACb,KACA,MACA,OAC4B;AAC5B,QAAM,QAAQ,MAAM,gBAAgB,GAAG;AACvC,QAAM,SAAS,IAAI,IAAqB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjE,QAAM,YAAqB,CAAC;AAC5B,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,WAAW,KAAK,GAAG;AACjC,QAAI,UAAU,KAAM,WAAU,KAAK,EAAE,GAAG,MAAM,OAAO,KAAK,CAAC;AAAA,QACtD,QAAO,IAAI,KAAK,GAAG,KAAK,EAAE,GAAG,MAAM,OAAO,MAAM,CAAC;AAAA,EACxD;AACA,QAAM,QAAuB,CAAC;AAC9B,QAAM,OAAO,CAAC,MAAmB;AAC/B,UAAM,KAAK;AAAA,MACT,KAAK,EAAE;AAAA,MACP,OAAO,EAAE;AAAA,MACT,OAAO,EAAE;AAAA,MACT,MAAM,EAAE;AAAA,MACR,SAAS,EAAE;AAAA,IACb,CAAC;AAAA,EACH;AACA,aAAW,KAAK,MAAO,YAAW,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,EAAG,MAAK,CAAC;AAClE,aAAW,KAAK,UAAW,MAAK,CAAC;AACjC,SAAO,EAAE,MAAM,MAAM;AACvB;AASA,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF,GAAoC;AAClC,QAAM,QAAQ,WAAW,UAAU,KAAK;AACxC,QAAM,cAAc,MAAM,QAAQ;AAAA,IAChC,YAAY;AAAA,MAAI,CAAC,SACf,mBAAmBC,MAAK,UAAU,IAAI,GAAG,MAAM,KAAK;AAAA,IACtD;AAAA,EACF;AACA,SAAO,EAAE,OAAO,YAAY;AAC9B;;;ACjFA,SAAS,QAAAC,aAAY;;;ACArB,SAAS,SAAAC,cAAa;AAOf,SAAS,aAAa,KAA4B;AACvD,SACE,+DAA+D;AAAA,IAC7DA,OAAM,SAAS,GAAG;AAAA,EACpB,IAAI,CAAC,KAAK;AAEd;AAGO,SAAS,eAAe,KAA4B;AAEzD,MAAI,aAAa,GAAG,MAAM,KAAM,QAAO;AACvC,SAAO,YAAY,KAAKA,OAAM,SAAS,GAAG,CAAC,IAAI,CAAC,KAAK;AACvD;AAMO,SAAS,cAAc,SAAiB,QAA+B;AAC5E,MAAI,WAAW,KAAM,QAAO;AAC5B,QAAM,OAAO,IAAI,OAAO,IAAI,MAAM,+BAA+B,EAAE;AAAA,IACjE;AAAA,EACF,IAAI,CAAC;AACL,SAAO,QAAQ;AACjB;;;ADxBO,IAAM,WAA+D;AAAA,EAC1E,KAAK,CAAC,YAAY,YAAY,YAAY,YAAY;AAAA,EACtD,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,OAAO,CAAC,SAAS,SAAS,eAAe,WAAW,aAAa,WAAW;AAC9E;AACA,IAAM,OAAO,oBAAI,IAAI,CAAC,sBAAsB,CAAC;AAE7C,IAAM,iBAAiB,CAAC,UAAU,OAAO;AAazC,eAAe,QACb,UACA,MACA,UACA;AACA,QAAM,QAAQ,MAAM,gBAAgBC,MAAK,UAAU,IAAI,CAAC;AACxD,QAAM,SAAS,GAAG,IAAI;AACtB,MAAI,aAAa,UAAa,CAAC,SAAS,IAAI,WAAW,MAAM,EAAG,QAAO;AACvE,QAAM,MAAM,SAAS,IAAI,MAAM,OAAO,MAAM;AAC5C,QAAM,OAAO;AAAA,IACXA,MAAK,UAAU,GAAG,SAAS,IAAI,MAAM,GAAG,CAAC;AAAA,IACzC;AAAA,IACA,SAAS;AAAA,EACX;AACA,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,QAAQ,GAAG,GAAG,IAAI,EAAE;AAAA,IAAK,CAAC,GAAG,MAC5D,EAAE,MAAM,EAAE,MAAM,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI;AAAA,EAC3C;AACF;AAMA,eAAsB,cACpB,UACA,UACmB;AACnB,QAAM,WAAqB,CAAC;AAC5B,aAAW,QAAQ,aAAa;AAC9B,UAAM,UAAU,SAAS,IAAI;AAC7B,UAAM,QAAQ,MAAM,QAAQ,UAAU,MAAM,QAAQ;AAGpD,UAAM,WAAW,oBAAI,IAAsB;AAC3C,eAAW,QAAQ,OAAO;AACxB,YAAM,QAAQ,GAAG,IAAI,IAAI,KAAK,GAAG;AACjC,UAAI,KAAK,IAAI,KAAK,EAAG;AACrB,YAAM,SAAS,YAAY,SAAY,OAAO,eAAe,KAAK,GAAG;AACrE,UAAI,WAAW;AACb,iBAAS,IAAI,QAAQ,CAAC,GAAI,SAAS,IAAI,MAAM,KAAK,CAAC,GAAI,KAAK,CAAC;AAAA,IACjE;AACA,eAAW,CAAC,QAAQ,KAAK,KAAK,UAAU;AACtC,UAAI,MAAM,SAAS,EAAG;AACtB,iBAAW,SAAS;AAClB,iBAAS;AAAA,UACP,GAAG,KAAK,gBAAgB,MAAM,oBAAoB,MAC/C,OAAO,CAAC,MAAM,MAAM,KAAK,EACzB,KAAK,IAAI,CAAC;AAAA,QACf;AAAA,IACJ;AAGA,UAAM,OAAO;AAAA,MACX,KAAK,IAAI,GAAG,GAAG,CAAC,GAAG,SAAS,KAAK,CAAC,EAAE,IAAI,MAAM,CAAC,IAAI;AAAA,IACrD,EAAE,SAAS,GAAG,GAAG;AACjB,eAAW,QAAQ,OAAO;AACxB,YAAM,QAAQ,GAAG,IAAI,IAAI,KAAK,GAAG;AACjC,UAAI,KAAK,IAAI,KAAK,EAAG;AACrB,UAAI,YAAY,UAAa,eAAe,KAAK,GAAG,MAAM;AACxD,iBAAS;AAAA,UACP,GAAG,KAAK,2BAA2B,IAAI,kCAAkC,IAAI;AAAA,QAC/E;AACF,UAAI,KAAK,gBAAgB,MAAM;AAC7B,iBAAS,KAAK,GAAG,KAAK,2BAA2B,KAAK,WAAW,GAAG;AACpE;AAAA,MACF;AACA,UAAI,KAAK,WAAW,MAAM;AACxB,mBAAW,OAAO,gBAAgB;AAChC,cAAI,OAAO,OAAO,KAAK,QAAQ,GAAG,GAAG;AACnC,qBAAS;AAAA,cACP,GAAG,KAAK,mBAAmB,GAAG;AAAA,YAChC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,UAAI,YAAY,OAAW;AAC3B,UAAI,KAAK,WAAW,MAAM;AACxB,iBAAS,KAAK,GAAG,KAAK,gCAAgC;AACtD;AAAA,MACF;AACA,UAAI,KAAK,UAAU,KAAM,UAAS,KAAK,GAAG,KAAK,wBAAwB;AACvE,YAAMC,UAAS,KAAK,OAAO,QAAQ;AACnC,UAAIA,YAAW,UAAaA,YAAW,QAAQA,YAAW,IAAI;AAC5D,iBAAS,KAAK,GAAG,KAAK,oBAAoB;AAAA,MAC5C,WAAW,OAAOA,YAAW,YAAY,CAAC,QAAQ,SAASA,OAAM,GAAG;AAClE,iBAAS;AAAA,UACP,GAAG,KAAK,oBAAoB,KAAK,UAAUA,OAAM,CAAC,cAAc,QAAQ,KAAK,IAAI,CAAC;AAAA,QACpF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;AE/HA,SAAS,gBAAgB;AACzB,SAAS,YAAY,QAAAC,OAAM,gBAAgB;AAQpC,IAAM,aACX;AAMF,eAAsB,cACpB,MACA,KACiB;AACjB,MAAI,CAAC,WAAW,KAAK,GAAG;AACtB,UAAM,IAAI,MAAM,GAAG,GAAG,8BAA8B;AACtD,QAAM,OAAOA,MAAK,MAAM,GAAG,IAAI,MAAM,GAAG,CAAC;AACzC,QAAM,CAAC,UAAU,IAAI,IAAI,MAAM,QAAQ,IAAI,CAAC,SAAS,IAAI,GAAG,SAAS,IAAI,CAAC,CAAC;AAC3E,QAAM,SAAS,SAAS,UAAU,IAAI;AACtC,MAAI,WAAW,MAAM,OAAO,WAAW,IAAI,KAAK,WAAW,MAAM;AAC/D,UAAM,IAAI,MAAM,GAAG,GAAG,iDAAiD;AACzE,SAAO;AACT;;;AC5BA;AAAA,EACE,OAAS;AAAA,EACT,aAAe;AAAA,EACf,QAAU;AAAA,IACR,OAAS;AAAA,IACT,UAAY;AAAA,IACZ,OAAS;AAAA,IACT,UAAY;AAAA,IACZ,eAAe;AAAA,IACf,SAAW;AAAA,IACX,UAAY;AAAA,IACZ,aAAe;AAAA,IACf,WAAa;AAAA,IACb,UAAY;AAAA,IACZ,YAAc;AAAA,IACd,WAAa;AAAA,IACb,KAAO;AAAA,IACP,OAAS;AAAA,IACT,OAAS;AAAA,IACT,SAAW;AAAA,EACb;AAAA,EACA,QAAU;AAAA,IACR,YAAc;AAAA,MACZ,MAAQ;AAAA,MACR,MAAQ;AAAA,IACV;AAAA,IACA,OAAS;AAAA,MACP,MAAQ;AAAA,MACR,MAAQ;AAAA,MACR,SAAW,CAAC,SAAS;AAAA,IACvB;AAAA,IACA,mBAAmB;AAAA,MACjB,MAAQ;AAAA,MACR,MAAQ;AAAA,IACV;AAAA,IACA,mBAAmB;AAAA,MACjB,MAAQ;AAAA,MACR,MAAQ;AAAA,IACV;AAAA,EACF;AAAA,EACA,OAAS;AAAA,IACP;AAAA,MACE,MAAQ;AAAA,MACR,QAAU;AAAA,MACV,QAAU,CAAC,SAAS,cAAc,UAAU,iBAAiB;AAAA,IAC/D;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,QAAU;AAAA,MACV,YAAc;AAAA,MACd,SAAW;AAAA,IACb;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,QAAU;AAAA,MACV,YAAc;AAAA,MACd,SAAW;AAAA,IACb;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,QAAU;AAAA,MACV,YAAc;AAAA,MACd,SAAW;AAAA,IACb;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,QAAU;AAAA,MACV,QAAU;AAAA,MACV,QAAU,CAAC,SAAS,cAAc,UAAU,iBAAiB;AAAA,IAC/D;AAAA,EACF;AAAA,EACA,OAAS;AAAA,IACP,iBAAiB,CAAC,kBAAkB;AAAA,IACpC,MAAQ,CAAC,MAAM;AAAA,IACf,eAAe,CAAC,aAAa;AAAA,EAC/B;AACF;;;AC5EA;AAAA,EACE,OAAS;AAAA,EACT,aAAe;AAAA,IACb,gBAAgB,EAAE,OAAS,WAAW,UAAY,QAAQ;AAAA,EAC5D;AAAA,EACA,QAAU;AAAA,IACR,OAAS;AAAA,IACT,UAAY;AAAA,IACZ,OAAS;AAAA,IACT,UAAY;AAAA,IACZ,eAAe;AAAA,IACf,SAAW;AAAA,IACX,UAAY;AAAA,IACZ,aAAe;AAAA,IACf,WAAa;AAAA,IACb,UAAY;AAAA,IACZ,YAAc;AAAA,IACd,WAAa;AAAA,IACb,SAAW;AAAA,EACb;AAAA,EACA,QAAU;AAAA,IACR,YAAc,EAAE,MAAQ,UAAU,MAAQ,cAAc;AAAA,IACxD,OAAS,EAAE,MAAQ,UAAU,MAAQ,UAAU,SAAW,CAAC,SAAS,EAAE;AAAA,IACtE,mBAAmB,EAAE,MAAQ,QAAQ,MAAQ,WAAW;AAAA,IACxD,mBAAmB,EAAE,MAAQ,QAAQ,MAAQ,YAAY;AAAA,EAC3D;AAAA,EACA,OAAS;AAAA,IACP;AAAA,MACE,MAAQ;AAAA,MACR,QAAU;AAAA,MACV,QAAU,CAAC,SAAS,cAAc,UAAU,iBAAiB;AAAA,IAC/D;AAAA,IACA,EAAE,MAAQ,WAAW,QAAU,SAAS,YAAc,eAAe;AAAA,IACrE;AAAA,MACE,MAAQ;AAAA,MACR,QAAU;AAAA,MACV,QAAU;AAAA,MACV,QAAU,CAAC,SAAS,cAAc,UAAU,iBAAiB;AAAA,IAC/D;AAAA,EACF;AACF;;;AC3BA,IAAM,YAA8D;AAAA,EAClE,eAAe,CAAC,qBAAW;AAAA,EAC3B,YAAY,CAAC,oBAAW;AAC1B;AAEA,IAAM,MAAM;AAGL,IAAM,UAAU,CAAC,SACtB,GAAG,KAAK,OAAO,CAAC,EAAE,YAAY,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;AAG1C,IAAM,gBAAgB,CAAC,SAC5B,GAAG,IAAI,IAAI,UAAU,IAAI,EAAE,MAAM;AAEnC,SAAS,WAAW,KAAsB;AACxC,QAAM,CAAC,EAAE,MAAM,CAAC,IAAI,IAAI,KAAK,GAAG,KAAK,CAAC;AACtC,MAAI,SAAS,UAAa,MAAM,UAAa,CAAC,OAAO,OAAO,WAAW,IAAI;AACzE,WAAO;AACT,SAAO,UAAU,IAAkB,EAAE,OAAO,CAAC,IAAI,CAAC;AACpD;AAGO,IAAM,mBAAmB,CAAC,QAC/B,WAAW,GAAG,MAAM;AAGf,IAAM,eAAe,CAAC,QAAwB,IAAI,MAAM,GAAG,EAAE,CAAC,KAAK;AAG1E,SAAS,YAAY,OAAgB,YAA6B;AAChE,QAAM,OAAO,CAAC,MACZ,EACG,WAAW,gBAAgB,UAAU,EACrC,WAAW,WAAW,QAAQ,UAAU,CAAC;AAC9C,MAAI,OAAO,UAAU,SAAU,QAAO,KAAK,KAAK;AAChD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AAC5E,MAAI,UAAU,QAAQ,OAAO,UAAU;AACrC,WAAO,OAAO;AAAA,MACZ,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM;AAAA,QACpC,KAAK,CAAC;AAAA,QACN,YAAY,GAAG,UAAU;AAAA,MAC3B,CAAC;AAAA,IACH;AACF,SAAO;AACT;AAGO,SAAS,eACd,KACA,MACyB;AACzB,QAAM,WAAW,WAAW,GAAG;AAC/B,MAAI,aAAa,OAAW,OAAM,IAAI,MAAM,aAAa,GAAG,EAAE;AAC9D,SAAO,YAAY,UAAU,KAAK,UAAU;AAC9C;;;ACzDO,IAAM,gBAAgB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,cAAc,CAAC,QAAQ,QAAQ,UAAU,QAAQ;AAIvD,IAAM,UAAU;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,IAAM,UAAU;AAoBhB,IAAM,eAAe,CAAC,SAAS,SAAS,SAAS;AAqBjD,IAAM,cAAc,CAAC,iBAAiB,QAAQ,aAAa;AAc3D,IAAM,UAKT;AAAA,EACF,MAAM,EAAE,OAAO,QAAQ,YAAY,CAAC,EAAE;AAAA,EACtC,oBAAoB;AAAA,IAClB,OAAO;AAAA,IACP,YAAY,EAAE,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC,aAAa,EAAE;AAAA,EAClE;AAAA,EACA,eAAe,EAAE,OAAO,eAAe,YAAY,CAAC,EAAE;AAAA,EACtD,SAAS,EAAE,OAAO,iBAAiB,YAAY,EAAE,IAAI,QAAW,OAAO,EAAE,EAAE;AAAA,EAC3E,mBAAmB,EAAE,OAAO,eAAe,YAAY,CAAC,EAAE;AAC5D;AAGA,IAAM,UAAiC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF;AA4BO,IAAM,eAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,eAAkC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,kBAAkB,CAAC,SAAS,YAAY,OAAO;AACrD,IAAM,aAAa,CAAC,QAAQ,QAAQ,SAAS;AAC7C,IAAM,YAAY;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,aAAmD;AAAA,EACvD,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AACR;AAGA,IAAM,YAAY;AAClB,IAAM,SAAS;AAGR,IAAM,eAAN,cAA2B,MAAM;AAAA,EAC7B;AAAA,EACA;AAAA,EACT,YAAY,KAAaC,SAAgB;AACvC,UAAM,IAAI,GAAG,KAAKA,OAAM,EAAE;AAC1B,SAAK,MAAM;AACX,SAAK,SAASA;AAAA,EAChB;AAAA;AAAA,EAEA,YAA0B;AACxB,SAAK,UAAU,IAAI,KAAK,GAAG,MAAM,KAAK,MAAM;AAC5C,WAAO;AAAA,EACT;AACF;AAEA,IAAM,WAAW,CAAC,MAChB,MAAM,QAAQ,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC;AAEzD,IAAM,SAAS,CAAC,MACd,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM;AAExC,IAAM,UAAU,CAAC,MACf,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,KAAK,IAAI,IAAI,CAAC,EAAE,SAAS,EAAE;AAE/D,IAAM,QAAQ,CAAC,SACb,aAAa,KAAK,CAAC,MAAM,EAAE,YAAY,MAAM,KAAK,YAAY,CAAC;AAG1D,IAAM,aAAa,CAAC;AAAA;AAAA,EAEzB,OAAO,OAAO,UAAU,UAAU,IAC7B,SACC,UACF,IACA;AAAA;AAEN,SAAS,YACP,OACA,MACA,IACA,MACM;AACN,aAAW,KAAK,OAAO,KAAK,KAAK;AAC/B,QAAI,CAAC,KAAK,SAAS,CAAC;AAClB,YAAM,IAAI,aAAa,GAAG,EAAE,IAAI,CAAC,IAAI,mBAAmB,IAAI,EAAE;AACpE;AAEA,SAAS,aACP,OACA,KACA,IACe;AACf,QAAM,IAAI,MAAM,GAAG;AACnB,MAAI,MAAM,OAAW,QAAO;AAC5B,MAAI,CAAC,OAAO,CAAC,EAAG,OAAM,IAAI,aAAa,GAAG,EAAE,IAAI,GAAG,IAAI,cAAc;AACrE,SAAO;AACT;AAEA,SAAS,eACP,MACA,OACA,IACuB;AACvB,MAAI,CAAC,UAAU,KAAK,IAAI;AACtB,UAAM,IAAI,aAAa,IAAI,iCAAiC;AAC9D,MAAI,CAAC,SAAS,KAAK;AACjB,UAAM,IAAI,aAAa,IAAI,+CAA+C;AAC5E,cAAY,OAAO,iBAAiB,IAAI,cAAc;AACtD,QAAM,QAAQ,aAAa,OAAO,SAAS,EAAE,KAAK,QAAQ,IAAI;AAC9D,QAAM,MAAM,MAAM,UAAU;AAC5B,QAAM,WAAW,WAAW,IAAI;AAChC,MAAI;AACJ,MAAI,QAAQ,YAAY;AACtB,QAAI,aAAa;AACf,YAAM,IAAI;AAAA,QACR,GAAG,EAAE;AAAA,QACL;AAAA,MACF;AACF,eAAW;AAAA,EACb,WAAW,QAAQ,QAAS,YAAW;AAAA,WAC9B,QAAQ,GAAG,KAAK,IAAI,SAAS,GAAG;AAEvC,UAAM,WAAW,YAAY,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC;AAC/D,QAAI,QAAQ,SAAS;AACnB,YAAM,IAAI;AAAA,QACR,GAAG,EAAE;AAAA,QACL,2CAA2C,QAAQ,KAAK,IAAI,CAAC,IAC3D,QAAQ,WAAW,IAAI,OAAO,KAChC;AAAA,MACF;AACF,eAAW,CAAC,GAAG,GAAG;AAAA,EACpB;AACE,UAAM,IAAI;AAAA,MACR,GAAG,EAAE;AAAA,MACL;AAAA,IACF;AACF,QAAM,QAAQ,aAAa,OAAO,SAAS,EAAE;AAC7C,MAAI,UAAU,QAAQ,MAAM,KAAK;AAC/B,UAAM,IAAI;AAAA,MACR,GAAG,EAAE;AAAA,MACL;AAAA,IACF;AACF,SAAO,EAAE,OAAO,UAAU,MAAM;AAClC;AAEA,SAAS,UAAU,MAAc,OAAgB,IAA8B;AAC7E,MAAI,MAAM,IAAI;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACF,MAAI,CAAC,SAAS,KAAK;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACF,cAAY,OAAO,YAAY,IAAI,SAAS;AAC5C,QAAM,OAAO,YAAY,KAAK,CAAC,MAAM,MAAM,MAAM,MAAM,CAAC;AACxD,MAAI,SAAS;AACX,UAAM,IAAI;AAAA,MACR,GAAG,EAAE;AAAA,MACL,kBAAkB,YAAY,KAAK,IAAI,CAAC;AAAA,IAC1C;AACF,QAAM,MAAM,MAAM,MAAM;AACxB,QAAM,OAAO,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI;AACnC,MAAI,CAAC,QAAQ,IAAI,KAAK,KAAK,WAAW;AACpC,UAAM,IAAI;AAAA,MACR,GAAG,EAAE;AAAA,MACL;AAAA,IACF;AACF,aAAW,KAAK;AACd,QAAI,EAAE,WAAW,GAAG,KAAK,CAAE,QAA8B,SAAS,CAAC;AACjE,YAAM,IAAI;AAAA,QACR,GAAG,EAAE;AAAA,QACL,SAAS,CAAC,gCAAgC,QAAQ,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,OAAO,QAAQ,GAAG,EAAE,CAAC;AAAA,MAChG;AACJ,QAAM,aAAa,MAAM,SAAS,KAAK,CAAC;AACxC,MACE,EAAE,MAAM,QAAQ,UAAU,KAAK,WAAW,WAAW,MACrD,CAAC,QAAQ,UAAU;AAEnB,UAAM,IAAI,aAAa,GAAG,EAAE,YAAY,yBAAyB;AACnE,QAAM,UAAU,CAAC,GAAI,UAAuB;AAC5C,MACE,KAAK,SAAS,QAAQ,MACrB,SAAS,YAAY,CAAC,QAAQ,SAAS,OAAO;AAE/C,UAAM,IAAI;AAAA,MACR;AAAA,MACA,gDAAgD,OAAO;AAAA,IACzD;AACF,SAAO,EAAE,MAAM,MAAM,CAAC,GAAG,IAAI,GAAG,QAAQ;AAC1C;AAEA,SAAS,WAAW,OAAgB,IAAgC;AAClE,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,CAAC,OAAO,KAAK;AACf,UAAM,IAAI,aAAa,IAAI,yCAAyC;AACtE,SAAO,UAAU,cACb,EAAE,MAAM,YAAY,IACpB,EAAE,MAAM,OAAO,KAAK,MAAM;AAChC;AAQA,SAAS,SAAS,MAAc,GAAmB;AACjD,MAAI,SAAS,SAAU,QAAO;AAC9B,MAAI,EAAE,OAAO,IAAI,GAAG,SAAS,SAAU,QAAO;AAC9C,MAAI,EAAE,gBAAgB,MAAO,QAAO,KAAK,SAAS,SAAS;AAC3D,SAAO,OAAO,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI;AAClE;AAGA,SAAS,QAAQ,MAAc,GAAmB;AAChD,SACE,aAAa,SAAS,IAAI,KAC1B,OAAO,OAAO,EAAE,QAAQ,IAAI,MAC3B,EAAE,gBAAgB,QACf,KAAK,SAAS,SAAS,IACvB,OAAO,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI;AAEjE;AAEA,SAAS,SAAS,OAAgB,IAAY,GAA2B;AACvE,MAAI,CAAC,SAAS,KAAK;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACF,cAAY,OAAO,WAAW,IAAI,QAAQ;AAC1C,MAAI,CAAC,OAAO,MAAM,MAAM,CAAC;AACvB,UAAM,IAAI,aAAa,GAAG,EAAE,SAAS,cAAc;AACrD,QAAM,SAAS,aAAa,KAAK,CAAC,MAAM,MAAM,MAAM,QAAQ,CAAC;AAC7D,MAAI,WAAW;AACb,UAAM,IAAI;AAAA,MACR,GAAG,EAAE;AAAA,MACL,WAAW,aAAa,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,OAAO,aAAa,GAAG,EAAE,CAAC;AAAA,IAC3E;AACF,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,UAAU;AACjD,QAAI,MAAM,GAAG,MAAM,UAAa,SAAS;AACvC,YAAM,IAAI,aAAa,GAAG,EAAE,IAAI,GAAG,IAAI,iBAAiB,IAAI,YAAY;AAC5E,QAAM,aAAa,aAAa,OAAO,cAAc,EAAE;AACvD,MAAI,eAAe,MAAM;AACvB,QAAI,EAAE,gBAAgB,SAAS,CAAC,OAAO,OAAO,EAAE,aAAa,UAAU;AACrE,YAAM,IAAI;AAAA,QACR,GAAG,EAAE;AAAA,QACL,SAAS,UAAU;AAAA,MACrB;AACF,QACE,CAAC,OAAO,OAAO,EAAE,MAAM,EAAE;AAAA,MACvB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,KAAK,SAAS,aAAa;AAAA,IAC7D;AAEA,YAAM,IAAI;AAAA,QACR,GAAG,EAAE;AAAA,QACL;AAAA,MACF;AAAA,EACJ;AACA,QAAM,UAAU,aAAa,OAAO,WAAW,EAAE;AACjD,MAAI,YAAY,QAAQ,CAAC,SAAS,SAAS,CAAC;AAC1C,UAAM,IAAI;AAAA,MACR,GAAG,EAAE;AAAA,MACL;AAAA,IACF;AACF,MAAIC,UAA0B;AAC9B,MAAI,MAAM,QAAQ,MAAM,QAAW;AACjC,QAAI,CAAC,QAAQ,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,EAAE,WAAW;AAC1D,YAAM,IAAI,aAAa,GAAG,EAAE,WAAW,+BAA+B;AACxE,UAAM,UAAU,MAAM,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;AAC1D,QAAI,YAAY;AACd,YAAM,IAAI;AAAA,QACR,GAAG,EAAE;AAAA,QACL,SAAS,OAAO;AAAA,MAClB;AACF,IAAAA,UAAS,CAAC,GAAG,MAAM,QAAQ,CAAC;AAAA,EAC9B;AACA,QAAM,OAAO,aAAa,OAAO,QAAQ,EAAE;AAC3C,MACE,WAAW,cACV,SAAS,QAAQ,EAAE,OAAO,IAAI,GAAG,SAAS;AAE3C,UAAM,IAAI,aAAa,GAAG,EAAE,SAAS,wBAAwB;AAC/D,SAAO;AAAA,IACL,MAAM,MAAM,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,IACA,QAAQ,aAAa,OAAO,UAAU,EAAE;AAAA,IACxC;AAAA,IACA,QAAAA;AAAA,IACA;AAAA,EACF;AACF;AAGA,IAAM,QAAQ,CAACA,YACb,OAAO,OAAOA,OAAM,EAAE;AAAA,EACpB,CAAC,MACC,EAAE,SAAS,YACX,EAAE,KAAK,SAAS,QAAQ,KACxB,EAAE,QAAQ,SAAS,OAAO;AAC9B;AAGF,SAAS,UACP,OACA,IACAA,SACA,YACY;AACZ,MAAI,UAAU,OAAW,QAAO,CAAC;AACjC,MAAI,CAAC,SAAS,KAAK,EAAG,OAAM,IAAI,aAAa,IAAI,4BAA4B;AAC7E,QAAM,QAAoB,CAAC;AAC3B,aAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,UAAM,QAAQ,GAAG,EAAE,IAAI,KAAK;AAC5B,UAAM,QAAQ,YAAY,KAAK,CAAC,MAAM,MAAM,KAAK;AACjD,QAAI,UAAU;AACZ,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oBAAoB,YAAY,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,OAAO,YAAY,GAAG,EAAE,CAAC;AAAA,MAClF;AACF,QAAI,CAAC,MAAM,QAAQ,IAAI,EAAG,OAAM,IAAI,aAAa,OAAO,mBAAmB;AAC3E,UAAM,UAAyB,CAAC;AAChC,eAAW,CAAC,GAAG,IAAI,KAAK,KAAK,QAAQ,GAAG;AACtC,YAAM,MAAM,GAAG,KAAK,IAAI,CAAC;AACzB,YAAM,MACJ,OAAO,SAAS,WACZ,EAAE,QAAQ,KAAK,IACf,SAAS,IAAI,IACX,OACA;AACR,YAAM,OAAO,MAAM,QAAQ;AAC3B,YAAM,QAAQ,OAAO,KAAK,OAAO;AACjC,YAAM,SAAS,MAAM,KAAK,CAAC,MAAM,MAAM,IAAI;AAC3C,UAAI,QAAQ,QAAQ,WAAW;AAC7B,cAAM,IAAI;AAAA,UACR;AAAA,UACA,SAAS,OAAO,SAAS,WAAW,OAAO,KAAK,UAAU,IAAI,CAAC,yBAAyB,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,OAAO,MAAM,GAAG,EAAE,CAAC;AAAA,QAC1I;AACF,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,KAAK,UAAU;AACjB,cAAM,IAAI;AAAA,UACR;AAAA,UACA,GAAG,MAAM,oBAAoB,KAAK,KAAK,YAAY,KAAK;AAAA,QAC1D,EAAE,UAAU;AACd,iBAAW,KAAK,OAAO,KAAK,GAAG;AAC7B,YAAI,MAAM,YAAY,CAAC,OAAO,OAAO,KAAK,YAAY,CAAC;AACrD,gBAAM,IAAI;AAAA,YACR,GAAG,GAAG,IAAI,CAAC;AAAA,YACX,yBAAyB,MAAM;AAAA,UACjC;AACJ,UAAI,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM;AACzC,cAAM,IAAI,aAAa,KAAK,GAAG,MAAM,mBAAmB,EAAE,UAAU;AACtE,UAAI,QAAQ,SAAS,MAAM,KAAK,CAAC,MAAMA,OAAM;AAC3C,cAAM,IAAI;AAAA,UACR;AAAA,UACA,GAAG,MAAM,qDAAqD,OAAO;AAAA,QACvE,EAAE,UAAU;AACd,UAAI,WAAW,aAAa,CAAC;AAC3B,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF,EAAE,UAAU;AACd,UAAI,WAAW,oBAAoB;AACjC,cAAMC,QAAO,CAAC,MAAwB;AACpC,gBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC;AACrC,cAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW;AAC9B,kBAAM,IAAI,aAAa,GAAG,GAAG,IAAI,CAAC,IAAI,aAAa,CAAC,EAAE;AACxD,iBAAO,CAAC,GAAG,CAAC;AAAA,QACd;AACA,gBAAQ,KAAK;AAAA,UACX;AAAA,UACA,aAAaA,MAAK,aAAa;AAAA,UAC/B,UAAUA,MAAK,UAAU;AAAA,QAC3B,CAAC;AAAA,MACH,WAAW,WAAW,WAAW;AAC/B,cAAM,KAAK,IAAI,IAAI;AACnB,YAAI,OAAO,UAAU,OAAO;AAC1B,gBAAM,IAAI,aAAa,GAAG,GAAG,OAAO,sBAAsB;AAC5D,cAAM,QAAQ,IAAI,OAAO,KAAK,KAAK,WAAW,OAAO;AACrD,YAAI,OAAO,UAAU,YAAY,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ;AACnE,gBAAM,IAAI;AAAA,YACR,GAAG,GAAG;AAAA,YACN;AAAA,UACF;AACF,gBAAQ,KAAK,EAAE,QAAQ,IAAI,MAAM,CAAC;AAAA,MACpC,MAAO,SAAQ,KAAK,EAAE,OAAO,CAAC;AAAA,IAChC;AACA,UAAM,KAAK,IAAI;AAAA,EACjB;AAEA,QAAM,OAAO,MAAM,aAAa,KAAK,CAAC;AACtC,QAAM,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,WAAW,iBAAiB;AAChE,MACE,QAAQ,MACR,EAAE,MAAM,eAAe,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS;AAElE,UAAM,IAAI;AAAA,MACR,GAAG,EAAE,gBAAgB,GAAG;AAAA,MACxB;AAAA,IACF,EAAE,UAAU;AACd,SAAO;AACT;AAGO,IAAM,QAAQ;AAGd,IAAM,YAAY,CAAC,SACxB,SAAS,QAAQ,gBAAgB;AAEnC,IAAM,cAAc;AAOb,SAAS,gBACd,MACA,OACA,QAAkC,kBAC1B;AACR,QAAM,KAAK,UAAU,IAAI;AACzB,QAAM,SAAS,UAAU,IAAI;AAC7B,MAAI,CAAC,YAAY,KAAK,KAAK;AACzB,UAAM,IAAI,aAAa,IAAI,2BAA2B,MAAM,GAAG;AACjE,MAAI,aAAa,KAAK,MAAM;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,MACA,SAAS,QACL,SAAS,KAAK,KAAK,KAAK,iBAAiB,MAAM,KAC/C,SAAS,KAAK,uCAAuC,MAAM;AAAA,IACjE;AACF,MAAI,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,KAAK;AACrC,UAAM,IAAI,aAAa,IAAI,SAAS,KAAK,kCAAkC;AAC7E,SAAO;AACT;AAQO,SAAS,WACd,MACA,OACA,QAAkC,kBAChB;AAClB,QAAM,KAAK,UAAU,IAAI;AACzB,MAAI,CAAC,SAAS,KAAK;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACF,cAAY,OAAO,YAAY,IAAI,SAAS;AAC5C,QAAM,SAAS,MAAM,QAAQ,KAAK;AAClC,MACE,WAAW,SACV,OAAO,WAAW,YAAY,CAAC,OAAO,UAAU,MAAM,KAAK,SAAS;AAErE,UAAM,IAAI,aAAa,GAAG,EAAE,WAAW,0BAA0B;AACnE,QAAM,SAAS,MAAM,QAAQ;AAC7B,MACE,WAAW,WACV,OAAO,WAAW,YAAY,CAAC,OAAO,KAAK,MAAM;AAElD,UAAM,IAAI;AAAA,MACR,GAAG,EAAE;AAAA,MACL;AAAA,IACF;AACF,MAAI,OAAO,WAAW,YAAY,CAAC,MAAM,MAAM;AAC7C,UAAM,IAAI;AAAA,MACR,GAAG,EAAE;AAAA,MACL,SAAS,MAAM;AAAA,IACjB;AAEF,QAAM,iBAAiB,MAAM,aAAa;AAC1C,MAAI;AACJ,MAAI,mBAAmB,MAAO,eAAc;AAAA,WACnC,SAAS,cAAc,KAAK,OAAO,KAAK,cAAc,EAAE,SAAS;AACxE,kBAAc,OAAO;AAAA,MACnB,OAAO,QAAQ,cAAc,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM;AAAA,QAC7C;AAAA,QACA,eAAe,GAAG,GAAG,GAAG,EAAE,gBAAgB,CAAC,EAAE;AAAA,MAC/C,CAAC;AAAA,IACH;AAAA;AAEA,UAAM,IAAI;AAAA,MACR,GAAG,EAAE;AAAA,MACL;AAAA,IACF;AAEF,QAAM,YAAY,MAAM,QAAQ,KAAK,CAAC;AACtC,MAAI,CAAC,SAAS,SAAS;AACrB,UAAM,IAAI,aAAa,GAAG,EAAE,WAAW,6BAA6B;AACtE,QAAM,SAAsC,CAAC;AAC7C,aAAW,CAAC,QAAQ,CAAC,KAAK,OAAO,QAAQ,SAAS,GAAG;AACnD,UAAM,QAAQ,cAAc,KAAK,CAAC,MAAM,MAAM,CAAC;AAC/C,QAAI,UAAU;AACZ,YAAM,IAAI;AAAA,QACR,GAAG,EAAE,WAAW,MAAM;AAAA,QACtB,kBAAkB,cAAc,KAAK,IAAI,CAAC;AAAA,MAC5C;AACF,WAAO,MAAM,IAAI;AAAA,EACnB;AAEA,QAAM,YAAY,MAAM,QAAQ,KAAK,CAAC;AACtC,MAAI,CAAC,SAAS,SAAS;AACrB,UAAM,IAAI,aAAa,GAAG,EAAE,WAAW,0BAA0B;AACnE,QAAMD,UAAS,OAAO;AAAA,IACpB,OAAO,QAAQ,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM;AAAA,MACxC;AAAA,MACA,UAAU,GAAG,GAAG,GAAG,EAAE,WAAW,CAAC,EAAE;AAAA,IACrC,CAAC;AAAA,EACH;AACA,MAAI,gBAAgB;AAClB,eAAW,CAAC,GAAG,IAAI,KAAK,OAAO,QAAQ,WAAW;AAChD,UAAI,KAAK,UAAU,QAAQ,OAAO,OAAOA,SAAQ,KAAK,KAAK;AACzD,cAAM,IAAI;AAAA,UACR,GAAG,EAAE,gBAAgB,CAAC;AAAA,UACtB,SAAS,KAAK,KAAK;AAAA,QACrB;AAAA;AAEN,QAAM,QAAe,EAAE,aAAa,QAAAA,QAAO;AAC3C,QAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW;AAClD,UAAM,IAAI,aAAa,GAAG,EAAE,UAAU,6BAA6B;AACrE,QAAME,SAA2B,CAAC;AAClC,aAAW,CAAC,GAAG,CAAC,KAAK,SAAS,QAAQ,GAAG;AACvC,UAAM,OAAO,SAAS,GAAG,GAAG,EAAE,UAAU,CAAC,KAAK,KAAK;AACnD,QAAIA,OAAM,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI;AACxC,YAAM,IAAI;AAAA,QACR,GAAG,EAAE,UAAU,CAAC;AAAA,QAChB,MAAM,KAAK,IAAI;AAAA,MACjB;AACF,IAAAA,OAAM,KAAK,IAAI;AAAA,EACjB;AAIA,QAAM,SAAS,CAAC,QAA+B;AAC7C,UAAM,OAAO,aAAa,OAAO,KAAK,EAAE;AACxC,QAAI,SAAS,QAAQ,CAAC,WAAW,KAAK,IAAI;AACxC,YAAM,IAAI;AAAA,QACR,GAAG,EAAE,IAAI,GAAG;AAAA,QACZ,oCAAoC,QAAQ,WAAW,wBAAwB,mBAAmB;AAAA,MACpG;AACF,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL;AAAA,IACA,QAAS,UAAiC;AAAA,IAC1C,OAAO,aAAa,OAAO,SAAS,EAAE;AAAA,IACtC,aAAa,aAAa,OAAO,eAAe,EAAE;AAAA,IAClD,QAAQ,OAAO,QAAQ;AAAA,IACvB,SAAS,OAAO,SAAS;AAAA,IACzB;AAAA,IACA;AAAA,IACA,QAAAF;AAAA,IACA,QAAQ,WAAW,MAAM,QAAQ,GAAG,GAAG,EAAE,SAAS;AAAA,IAClD,OAAAE;AAAA,IACA,OAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,GAAG,EAAE;AAAA,MACLF;AAAA,MACA,gBAAgB,SAAS,OAAO,OAAO,aAAa,OAAO;AAAA,IAC7D;AAAA,IACA,QAAQ;AAAA,EACV;AACF;;;AChuBA,SAAS,gBAAgB;AACzB,SAAS,WAAAG,UAAS,eAAe;AACjC,SAAS,iBAAiB;AAI1B,IAAM,YAAY,UAAU,QAAQ;AAIpC,IAAM,aACJ;AAOK,SAAS,gBACd,aAIA;AACA,MAAI,gBAAgB,QAAQ,gBAAgB;AAC1C,WAAO,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,EAAE;AAC7B,SAAO;AAAA,IACL,MAAM,CAAC,MAAM,sBAAsB,MAAM,qBAAqB,UAAU,EAAE;AAAA,IAC1E,KAAK;AAAA,MACH,oBAAoB,YAAY;AAAA,MAChC,iBAAiB,YAAY;AAAA,IAC/B;AAAA,EACF;AACF;AAEA,eAAe,IACb,MACA,KACA,aACiB;AACjB,QAAM,OAAO,gBAAgB,WAAW;AACxC,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,UAAU,OAAO,CAAC,GAAG,KAAK,MAAM,GAAG,IAAI,GAAG;AAAA,MACjE,GAAI,QAAQ,SAAY,CAAC,IAAI,EAAE,IAAI;AAAA,MACnC,KAAK;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,GAAG,KAAK;AAAA,QACR,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA,QAKrB,GAAI,QAAQ,SACR,CAAC,IACD,EAAE,yBAAyBA,SAAQ,QAAQ,GAAG,CAAC,EAAE;AAAA,MACvD;AAAA,MACA,WAAW,KAAK,OAAO;AAAA,IACzB,CAAC;AACD,WAAO;AAAA,EACT,SAAS,GAAG;AACV,UAAM,MAAM;AACZ,UAAM,OACJ,IAAI,WAAW,UAAa,IAAI,WAAW,KACvC,IAAI,SACH,IAAI,WAAW;AACtB,UAAM,QACJ,KAAK,MAAM,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK;AACnD,UAAM,IAAI,MAAM,OAAO,KAAK,CAAC,KAAK,EAAE,YAAY,MAAM,KAAK,CAAC,IAAI;AAAA,MAC9D,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAGO,SAAS,WAAW,OAAe,MAAsB;AAC9D,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,IAAI,MAAM,uBAAuB,IAAI,KAAK,KAAK,EAAE;AACzD,SAAO;AACT;AAGA,eAAsB,MACpB,KACA,KACA,aACe;AACf,QAAM;AAAA,IACJ;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,KAAK,gBAAgB;AAAA,MAChC,WAAW,KAAK,WAAW;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAOA,eAAsB,QACpB,KACA,SAA4B,CAAC,GACX;AAClB,QAAM,WAAW,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AAC3C,UAEI,MAAM;AAAA,IACJ;AAAA,MACE;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA,MACA,GAAI,SAAS,SAAS,IAAI,CAAC,MAAM,GAAG,QAAQ,IAAI,CAAC;AAAA,IACnD;AAAA,IACA;AAAA,EACF,GACA,KAAK,MAAM;AAEjB;AAMA,eAAsB,aACpB,KACA,OACmB;AACnB,MAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAChC,QAAM,WACJ,MAAM;AAAA,IACJ,CAAC,UAAU,eAAe,MAAM,yBAAyB,MAAM,GAAG,KAAK;AAAA,IACvE;AAAA,EACF,GACA,MAAM,IAAI;AACZ,QAAM,UAAoB,CAAC;AAC3B,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,QAAQ,QAAQ,CAAC,KAAK;AAC5B,QAAI,MAAM,SAAS,EAAG;AACtB,YAAQ,KAAK,MAAM,MAAM,CAAC,CAAC;AAE3B,QAAI,MAAM,CAAC,MAAM,OAAO,MAAM,CAAC,MAAM,IAAK;AAAA,EAC5C;AACA,SAAO;AACT;AAWA,eAAsB,UACpB,KACA,OACsB;AACtB,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,QAAQ,IAAI,IAAI,KAAK,GAAG;AACjC,QAAI;AACF,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,aAAa,IAAI;AAAA,QACnB;AAAA,QACA;AAAA,MACF;AACA,UAAI,OAAO,KAAK,MAAM,GAAI,MAAK,IAAI,IAAI;AAAA,IACzC,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAOA,eAAsB,QACpB,KACA,MACwB;AACxB,MAAI;AACF,UAAM,QAAQ,MAAM,IAAI,CAAC,aAAa,cAAc,IAAI,GAAG,GAAG,GAAG,KAAK;AACtE,WAAO,SAAS,KAAK,OAAO,QAAQ,KAAK,IAAI;AAAA,EAC/C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,gBACpB,KACA,aACe;AACf,QAAM,IAAI,CAAC,QAAQ,aAAa,SAAS,GAAG,KAAK,WAAW;AAC9D;AAGA,eAAsB,QACpB,KACA,KACA,aACe;AACf,QAAM,IAAI,CAAC,UAAU,OAAO,UAAU,WAAW,KAAK,gBAAgB,CAAC,GAAG,GAAG;AAC7E,QAAM,IAAI,CAAC,QAAQ,WAAW,MAAM,UAAU,MAAM,GAAG,KAAK,WAAW;AACzE;AAGA,eAAsB,OAAO,KAAqC;AAChE,MAAI;AACF,YACG,MAAM,IAAI,CAAC,aAAa,YAAY,WAAW,MAAM,GAAG,GAAG,GAAG,KAAK,KACpE;AAAA,EAEJ,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,SAAS,KAAqC;AAClE,MAAI;AACF,YACG,MAAM,IAAI,CAAC,gBAAgB,WAAW,WAAW,MAAM,GAAG,GAAG,GAAG,KAAK,KACtE;AAAA,EAEJ,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,eACpB,KACA,MACA,KAAK,QACc;AACnB,QAAM,QAAQ,GAAG,WAAW,MAAM,UAAU,CAAC,KAAK,WAAW,IAAI,UAAU,CAAC;AAC5E,UAAQ,MAAM,IAAI,CAAC,YAAY,aAAa,mBAAmB,KAAK,GAAG,GAAG,GACvE,MAAM,IAAI,EACV,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,MAAM,EAAE;AAC3B;AAGA,eAAsB,UAAU,KAAqC;AACnE,MAAI;AACF,YAAQ,MAAM,IAAI,CAAC,UAAU,WAAW,QAAQ,GAAG,GAAG,GAAG,KAAK;AAAA,EAChE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,KAAK,KAA4B;AACrD,QAAM,IAAI,CAAC,QAAQ,MAAM,MAAM,MAAM,GAAG,GAAG;AAC7C;AAGA,eAAsB,UAAU,KAAa,SAAgC;AAC3E,QAAM,IAAI,CAAC,OAAO,IAAI,GAAG,GAAG;AAC5B,QAAM,IAAI,CAAC,UAAU,MAAM,MAAM,OAAO,GAAG,GAAG;AAChD;;;ACrRA,SAAS,aAAa;AAKf,IAAM,eAAe;AACrB,IAAM,WAAW;AAGjB,SAAS,QAAQ,MAAc,KAAa,MAAsB;AACvE,SAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI;AAC9B;AAKA,IAAM,OAAO;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,YAAY;AAAA,EAChB;AAAA,EACA;AACF;AAEA,SAAS,UAAU,MAAsB;AACvC,SACE,KACG,MAAM,IAAI,EACV,KAAK,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE,GAC1B,KAAK,KAAK;AAElB;AAQO,SAAS,cACd,KACA,UACA,QACO;AACP,MAAI,aAAa,KAAK,aAAa,EAAG,QAAO,EAAE,MAAM,QAAQ;AAC7D,MAAI,KAAK,KAAK,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AACjC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,iBAAiB,GAAG,KAAK,UAAU,MAAM,CAAC;AAAA,IACrD;AACF,MAAI,UAAU,KAAK,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC,EAAG,QAAO,EAAE,MAAM,YAAY;AACtE,SAAO,EAAE,MAAM,SAAS,SAAS,gBAAgB,GAAG,KAAK,UAAU,MAAM,CAAC,GAAG;AAC/E;AASA,IAAM,kBAAkB;AASxB,eAAsB,YACpB,KACA,YAAY,KACZ,aACgB;AAGhB,aAAW,KAAK,gBAAgB;AAChC,SAAO,IAAI,QAAe,CAACC,aAAY;AACrC,UAAM,OAAO,gBAAgB,WAAW;AACxC,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA,CAAC,GAAG,KAAK,MAAM,aAAa,eAAe,KAAK,MAAM;AAAA,MACtD;AAAA,QACE,OAAO,CAAC,UAAU,UAAU,MAAM;AAAA,QAClC,KAAK,EAAE,GAAG,QAAQ,KAAK,GAAG,KAAK,KAAK,qBAAqB,IAAI;AAAA,MAC/D;AAAA,IACF;AACA,UAAM,SAAmB,CAAC;AAC1B,UAAM,QAAQ,YAAY,MAAM;AAChC,UAAM,QAAQ,GAAG,QAAQ,CAAC,UAAkB,OAAO,KAAK,KAAK,CAAC;AAE9D,QAAI,UAAU;AACd,UAAM,SAAS,CAAC,UAAuB;AACrC,UAAI,QAAS;AACb,gBAAU;AACV,mBAAa,KAAK;AAGlB,YAAM,QAAQ,QAAQ;AACtB,MAAAA,SAAQ,KAAK;AAAA,IACf;AACA,UAAM,QAAQ,WAAW,MAAM;AAI7B,YAAM,KAAK,SAAS;AACpB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,gBAAgB,GAAG,qBAAqB,KAAK,MAAM,YAAY,GAAI,CAAC;AAAA,MAC/E,CAAC;AAAA,IACH,GAAG,SAAS;AAEZ,UAAM,GAAG,SAAS,CAAC,MAAa,OAAO,cAAc,KAAK,GAAG,EAAE,OAAO,CAAC,CAAC;AACxE,UAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,YAAM,SAAS,MACb,OAAO,cAAc,KAAK,QAAQ,GAAG,OAAO,KAAK,EAAE,CAAC,CAAC;AACvD,YAAM,SAAS,MAAM;AACrB,UAAI,WAAW,QAAQ,OAAO,iBAAiB,OAAO;AACpD,eAAO,OAAO;AAChB,YAAM,QAAQ,WAAW,QAAQ,eAAe;AAChD,YAAM,OAAO,MAAY;AACvB,qBAAa,KAAK;AAClB,eAAO;AAAA,MACT;AACA,aAAO,KAAK,OAAO,IAAI;AACvB,aAAO,KAAK,SAAS,IAAI;AAAA,IAC3B,CAAC;AAAA,EACH,CAAC;AACH;;;ACpIA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,YAAAC,WAAU,QAAAC,aAAY;AAyBxB,IAAM,OAAO;AAOb,IAAM,eAAe;AAcrB,IAAM,iBAAsC,oBAAI,IAAI;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASM,SAAS,aAAa,MAGjB;AACV,SAAO,CAAC,KAAK,YAAY,CAAC,eAAe,IAAI,KAAK,KAAK,YAAY,CAAC;AACtE;AAQO,SAAS,iBAAiB,MAAuB;AACtD,SAAO,KAAK,KAAK,IAAI,KAAK,CAAC,eAAe,IAAI,IAAI;AACpD;AAEO,IAAM,YACX;AAQK,IAAM,WAAW;AAGxB,IAAM,OAAO;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAASC,MAAK,SAAwB;AACpC,QAAM,IAAI,MAAM,eAAe,OAAO,EAAE;AAC1C;AAEA,SAASC,UAAS,OAAkD;AAClE,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,UAAU,OAAe,MAAuB;AACvD,MAAI,OAAO,SAAS,YAAY,SAAS;AACvC,IAAAD,MAAK,UAAU,KAAK,yBAAyB;AAC/C,MAAI,KAAK,WAAW,GAAG,EAAG,CAAAA,MAAK,UAAU,KAAK,yBAAyB;AACvE,MAAI,KAAK,MAAM,GAAG,EAAE,SAAS,IAAI;AAC/B,IAAAA,MAAK,UAAU,KAAK,8BAA8B;AACpD,MAAI,KAAK,MAAM,GAAG,EAAE,KAAK,CAAC,YAAY,YAAY,EAAE;AAClD,IAAAA,MAAK,UAAU,KAAK,wCAAwC;AAC9D,SAAO;AACT;AAEA,SAAS,QAAQ,OAA+B;AAC9C,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI,OAAO,UAAU,YAAY,CAAC,SAAS,KAAK,KAAK,GAAG;AACtD,IAAAA;AAAA,MACE,iDAAiD,KAAK,UAAU,KAAK,CAAC;AAAA,IACxE;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,cAAc,UAAoB,MAAsB;AACtE,SAAO,SAAS,OAAOE,UAAS,IAAI;AACtC;AAGA,IAAM,aAAa;AAGnB,SAAS,WAAW,OAAiC;AACnD,MAAI,UAAU,OAAW,QAAO;AAChC,MACE,CAAC,MAAM,QAAQ,KAAK,KACpB,CAAC,MAAM,MAAM,CAAC,MAAM,OAAO,MAAM,YAAY,WAAW,KAAK,CAAC,CAAC,KAC/D,IAAI,IAAI,KAAK,EAAE,SAAS,MAAM;AAE9B,IAAAF;AAAA,MACE,sDAAsD,KAAK,UAAU,KAAK,CAAC;AAAA,IAC7E;AACF,SAAO,CAAC,GAAI,KAAkB;AAChC;AAGO,IAAM,iBAA0C;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AACF;AAGA,SAAS,aAAa,OAAqC;AACzD,MAAI,UAAU,OAAW,QAAO;AAChC,QAAM,OAAO,eAAe,KAAK,CAAC,MAAM,MAAM,KAAK;AACnD,MAAI,SAAS;AACX,IAAAA;AAAA,MACE,6BAA6B,eAAe,KAAK,IAAI,CAAC,SAAS,KAAK,UAAU,KAAK,CAAC;AAAA,IACtF;AACF,SAAO;AACT;AAGA,SAAS,UAAU,OAAwB;AACzC,MACE,CAACC,UAAS,KAAK,KACf,OAAO,KAAK,KAAK,EAAE,WAAW,KAC9B,OAAO,MAAM,YAAY,YACzB,CAAC,OAAO,UAAU,MAAM,OAAO,KAC/B,MAAM,UAAU;AAEhB,IAAAD;AAAA,MACE,gDAAgD,KAAK,UAAU,KAAK,CAAC;AAAA,IACvE;AACF,SAAO,EAAE,CAAC,KAAK,GAAG,MAAM,QAAQ;AAClC;AAYA,IAAM,aAAa;AAEnB,IAAM,kBAAkB,CAAC,MACvB,OAAO,MAAM,YAAY,OAAO,UAAU,CAAC,KAAK,KAAK;AAQvD,SAAS,iBAAiB,OAGxB;AACA,QAAM,UAAUG,UAAS,KAAK,IAAI,OAAO,QAAQ,KAAK,IAAI,CAAC;AAC3D,QAAM,UAAU,QAAQ;AAAA,IAAQ,CAAC,CAAC,EAAE,CAAC,MACnCA,UAAS,CAAC,IAAK,gBAAgB,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAK,CAAC,CAAC;AAAA,EACxE;AACA,MACE,QAAQ,WAAW,KACnB,CAAC,QAAQ;AAAA,IACP,CAAC,CAAC,MAAM,CAAC,MACP,WAAW,KAAK,IAAI,MACnB,gBAAgB,CAAC,KAAK,OAAO,MAAM,YAAYA,UAAS,CAAC;AAAA,EAC9D,KACA,IAAI,IAAI,OAAO,EAAE,SAAS,QAAQ;AAElC,IAAAC;AAAA,MACE,8GAA8G,KAAK,UAAU,KAAK,CAAC;AAAA,IACrI;AACF,QAAM,SAAiB,CAAC;AACxB,QAAM,UAA0B,CAAC;AACjC,aAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACnC,QAAI,gBAAgB,KAAK,GAAG;AAC1B,aAAO,IAAI,IAAI;AACf;AAAA,IACF;AACA,QAAI;AACF,aAAO,IAAI,IACT,OAAO,UAAU,WACb,gBAAgB,MAAM,KAAK,IAC3B,WAAW,MAAM,KAAK;AAAA,IAC9B,SAAS,GAAG;AACV,UAAI,EAAE,aAAa,cAAe,OAAM;AACxC,cAAQ,KAAK,EAAE,MAAM,QAAQ,EAAE,SAAS,QAAQ,MAAM,CAAC;AAAA,IACzD;AAAA,EACF;AACA,SAAO;AAAA,IACL,QAAQ,OAAO,KAAK,MAAM,EAAE,WAAW,IAAI,OAAO;AAAA,IAClD;AAAA,EACF;AACF;AAGA,IAAM,UAAU,CAAC,UAAU,YAAY,OAAO;AAM9C,SAAS,mBAAmB,MAI1B;AACA,QAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,KAAK,CAAC,MAAM,MAAS;AAC3D,MAAI,QAAQ,SAAS;AACnB,IAAAA;AAAA,MACE,GAAG,QAAQ,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC;AAAA,IACxD;AACF,QAAM,MAAM,QAAQ,CAAC;AACrB,MAAI,QAAQ,OAAW,QAAO,EAAE,QAAQ,MAAM,SAAS,CAAC,EAAE;AAC1D,MAAI,QAAQ;AACV,WAAO,EAAE,QAAQ,UAAU,KAAK,KAAK,GAAG,SAAS,CAAC,GAAG,WAAW,IAAI;AACtE,QAAM,OAAO,iBAAiB,KAAK,GAAG,CAAC;AACvC,SAAO,QAAQ,WAAW,OAAO,EAAE,GAAG,MAAM,WAAW,IAAI;AAC7D;AAGO,SAAS,WAAW,UAAkC;AAC3D,MAAI,SAAS,aAAa,KAAM,QAAO,SAAS;AAChD,QAAM,MAAM,OAAO,OAAO,SAAS,KAAK,EAAE,CAAC,GAAG,OAAO;AACrD,QAAM,OAAO,iDAAiD,KAAK,GAAG,IAAI,CAAC;AAC3E,MAAI,MAAM,YAAY,EAAE,SAAS,QAAQ,EAAG,QAAO;AACnD,SAAO;AACT;AAEA,SAAS,UAAU,OAA2C;AAC5D,QAAM,MAAM,SAAS,CAAC;AACtB,MAAI,CAACD,UAAS,GAAG,EAAG,CAAAC,MAAK,2BAA2B;AACpD,QAAM,QAAmC,CAAC;AAC1C,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC/C,QAAI,CAAC,KAAK,KAAK,IAAI;AACjB,MAAAA,MAAK,cAAc,IAAI,sBAAsB,SAAS,EAAE;AAC1D,QAAI,CAACD,UAAS,KAAK,KAAK,OAAO,MAAM,QAAQ;AAC3C,MAAAC,MAAK,SAAS,IAAI,wBAAwB;AAC5C,UAAM,IAAI,IAAI,EAAE,KAAK,MAAM,IAAI;AAAA,EACjC;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAA4C;AAC9D,QAAM,MAAM,SAAS,CAAC;AACtB,MAAI,CAACD,UAAS,GAAG,EAAG,CAAAC,MAAK,4BAA4B;AACrD,QAAM,SAAqC,CAAC;AAC5C,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC/C,QAAI,CAAC,KAAK,KAAK,IAAI;AACjB,MAAAA,MAAK,eAAe,IAAI,sBAAsB,SAAS,EAAE;AAC3D,QAAI,CAACD,UAAS,KAAK,EAAG,CAAAC,MAAK,UAAU,IAAI,qBAAqB;AAC9D,UAAM,OAAO,UAAU,MAAM,MAAM,IAAI;AACvC,UAAM,MAAM,MAAM,WAAW,CAAC;AAC9B,QAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ,GAAG;AACnE,MAAAA,MAAK,UAAU,IAAI,2CAA2C;AAAA,IAChE;AACA,WAAO,IAAI,IAAI,EAAE,MAAM,SAAS,IAAgB;AAAA,EAClD;AACA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAClD,eAAWC,WAAU,MAAM,SAAS;AAClC,UAAI,CAAC,OAAO,OAAO,QAAQA,OAAM;AAC/B,QAAAD,MAAK,UAAU,IAAI,4BAA4BC,OAAM,GAAG;AAAA,IAC5D;AAAA,EACF;AACA,SAAO;AACT;AAGA,eAAsB,aAAa,UAAqC;AACtE,MAAI;AACJ,MAAI;AACF,UAAM,MAAMC,UAASC,MAAK,UAAU,YAAY,GAAG,MAAM;AAAA,EAC3D,QAAQ;AACN,IAAAH,MAAK,WAAW;AAAA,EAClB;AACA,SAAO,cAAc,GAAG;AAC1B;AAGO,SAAS,cAAc,KAAuB;AACnD,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,SAAS,GAAG;AACV,IAAAA,MAAK,iBAAiB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,GAAG;AAAA,EACrE;AACA,MAAI,CAACD,UAAS,IAAI,EAAG,CAAAC,MAAK,uBAAuB;AACjD,MAAI,KAAK,aAAa;AACpB,IAAAA,MAAK,yBAAyB,KAAK,UAAU,KAAK,QAAQ,CAAC,eAAe;AAG5E,aAAW,OAAO,OAAO,KAAK,IAAI,GAAG;AACnC,QAAI,CAAC,KAAK,SAAS,GAAG,EAAG,CAAAA,MAAK,eAAe,KAAK,UAAU,GAAG,CAAC,EAAE;AAAA,EACpE;AACA,QAAM,EAAE,QAAQ,SAAS,UAAU,IAAI,mBAAmB,IAAI;AAC9D,SAAO;AAAA,IACL,UAAU;AAAA,IACV,UAAU,aAAa,KAAK,QAAQ;AAAA,IACpC,KAAK,QAAQ,KAAK,GAAG;AAAA,IACrB,QAAQ,WAAW,KAAK,MAAM;AAAA,IAC9B;AAAA,IACA,GAAI,QAAQ,WAAW,IAAI,CAAC,IAAI,EAAE,QAAQ;AAAA,IAC1C,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU;AAAA,IAC/C,OAAO,UAAU,KAAK,KAAK;AAAA,IAC3B,QAAQ,WAAW,KAAK,MAAM;AAAA,EAChC;AACF;AAGA,IAAM,aAAa,CAAC,MAAc,UAChC,OAAO,KAAK,UAAU,IAAI,CAAC,KAAK,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,WAAW,MAAM,QAAQ,CAAC;AAE3F,IAAM,WAAW,CAAC,MAChB,OAAO,MAAM,YAAY,OAAO,MAAM;AAOxC,SAAS,YAAY,UAA8B;AACjD,QAAM,UAA0C;AAAA,IAC9C,GAAG,OAAO,QAAQ,SAAS,UAAU,CAAC,CAAC,EAAE;AAAA,MACvC,CAAC,CAAC,MAAM,CAAC,MACP,CAAC,MAAM,SAAS,CAAC,IAAI,IAAK,EAA0B,MAAM;AAAA,IAC9D;AAAA,IACA,IAAI,SAAS,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAU;AAAA,EACpE;AACA,MAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAClC,MAAI,QAAQ,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,SAAS,CAAC,CAAC;AACtC,WAAO;AAAA,MACL,iBAAiB,QACd,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,UAAU,IAAI,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,EAAE,EAClE,KAAK,IAAI,CAAC;AAAA,IACf;AACF,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,WAAW,MAAM,CAAC,CAAC,EAAE,KAAK,KAAK;AAAA,IAC1D;AAAA,EACF;AACF;AAGA,eAAsB,cACpB,UACA,UACe;AACf,QAAM,QAAQ,OAAO,QAAQ,SAAS,KAAK,EAAE;AAAA,IAC3C,CAAC,CAAC,MAAM,CAAC,MACP,OAAO,KAAK,UAAU,IAAI,CAAC,cAAc,KAAK,UAAU,EAAE,GAAG,CAAC;AAAA,EAClE;AACA,QAAM,SAAS,OAAO,QAAQ,SAAS,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM;AAChE,UAAM,MACJ,EAAE,QAAQ,WAAW,IACjB,KACA,iBAAiB,EAAE,QAAQ,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;AACzE,WAAO,OAAO,KAAK,UAAU,IAAI,CAAC,eAAe,KAAK,UAAU,EAAE,IAAI,CAAC,GAAG,GAAG;AAAA,EAC/E,CAAC;AACD,QAAM,QAAQ,CAAC,KAAK,kBAAkB;AACtC,MAAI,SAAS,aAAa;AACxB,UAAM,KAAK,iBAAiB,KAAK,UAAU,SAAS,QAAQ,CAAC,GAAG;AAClE,MAAI,SAAS,QAAQ;AACnB,UAAM,KAAK,YAAY,KAAK,UAAU,SAAS,GAAG,CAAC,GAAG;AACxD,MAAI,SAAS,WAAW;AACtB,UAAM;AAAA,MACJ,gBAAgB,SAAS,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,IAC1E;AACF,QAAM,KAAK,GAAG,YAAY,QAAQ,CAAC;AACnC,QAAM;AAAA,IACJ;AAAA,IACA,MAAM,KAAK,KAAK;AAAA,IAChB;AAAA,IACA;AAAA,IACA,OAAO,KAAK,KAAK;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACA,QAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,MAAM,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AACxD,QAAM,gBAAgBG,MAAK,UAAU,YAAY,GAAG,IAAI;AAC1D;AAEA,IAAM,WAAW;AAGV,SAAS,cACd,MACA,KACA,MAC+B;AAC/B,MAAI;AACJ,MAAI,SAAS,KAAK,IAAI,GAAG;AACvB,UAAM;AAAA,EACR,OAAO;AACL,UAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,QAAI,MAAM,WAAW,GAAG;AAEtB,UAAI,QAAQ;AACV,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AACF,YAAM,QAAQ,MAAM,KAAK,IAAI;AAAA,IAC/B,WACE,MAAM,WAAW,KACjB,MAAM,CAAC,MAAM,UACb,MAAM,CAAC,MAAM;AAEb,YAAM,QAAQ,MAAM,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAAA;AAEtC,YAAM,IAAI;AAAA,QACR,oBAAoB,IAAI;AAAA,MAC1B;AAAA,EACJ;AACA,QAAM,OAAO,IAAI,QAAQ,QAAQ,EAAE,EAAE,MAAM,MAAM,EAAE,GAAG,EAAE,KAAK;AAC7D,QAAM,OAAO,KAAK,SAAS,MAAM,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI;AACzD,MAAI,CAAC,KAAK,KAAK,IAAI;AACjB,UAAM,IAAI,MAAM,oBAAoB,IAAI,sBAAsB,SAAS,EAAE;AAC3E,SAAO,EAAE,MAAM,IAAI;AACrB;;;AC1dO,IAAM,UAAU;;;ACFvB,SAAS,YAAAC,iBAAgB;AACzB,SAAS,aAAAC,kBAAiB;AAE1B,IAAMC,aAAYD,WAAUD,SAAQ;AAG7B,IAAM,mBAA8C;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,iBAAiB,OAAwC;AACvE,SAAQ,iBAAuC,SAAS,KAAK;AAC/D;AAGO,SAAS,qBACd,YAAoB,QAAQ,IAAI,uBAAuB,KAAK,IAC5C;AAChB,QAAM,OAAO,UAAU,MAAM,GAAG,EAAE,CAAC,KAAK;AACxC,SAAO,iBAAiB,IAAI,IAAI,OAAO;AACzC;AAEA,SAASG,WAAU,MAAsB;AACvC,SACE,KACG,MAAM,IAAI,EACV,KAAK,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE,GAC1B,KAAK,KAAK;AAElB;AAEA,eAAsB,sBACpB,IACiB;AACjB,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMD,WAAU,IAAI,CAAC,WAAW,CAAC;AACpD,WAAO,OAAO,KAAK;AAAA,EACrB,SAAS,GAAG;AACV,UAAM,IAAI,MAAM,GAAG,EAAE,6BAA6B,EAAE,OAAO,EAAE,CAAC;AAAA,EAChE;AACF;AAQO,SAAS,YACd,IACA,SACQ;AACR,MAAI,OAAO,OAAQ,QAAO;AAC1B,MAAI,OAAO,MAAO,QAAO;AACzB,MAAI,OAAO,UAAU,OAAO,SAAS,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK;AACrD,WAAO;AACT,SAAO;AACT;AAOO,SAAS,YAAY,IAA4B;AACtD,MAAI,OAAO,OAAQ,QAAO;AAC1B,MAAI,OAAO,OAAQ,QAAO;AAC1B,MAAI,OAAO,MAAO,QAAO;AACzB,SAAO;AACT;AAQO,SAAS,aAAa,MAAyB,QAAQ,KAAa;AACzE,QAAM,QAAQ,IAAI,uBAAuB,KAAK;AAC9C,MAAI,UAAU,GAAI,QAAO;AACzB,QAAM,KAAK,qBAAqB,KAAK;AACrC,QAAM,CAAC,MAAM,OAAO,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,MAAM,GAAG;AAC7D,SAAO,YAAY,IAAI,SAAS,KAAM,WAAW,OAAQ,IAAI;AAC/D;AAEA,IAAM,gBAAgB;AAQf,SAAS,iBAAiB,QAAwB;AACvD,QAAM,QAAQ,OACX,MAAM,IAAI,EACV,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,MAAM,EAAE;AACzB,SAAO,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,KAAK,CAAC,CAAC,KAAKC,WAAU,MAAM;AACtE;AAEA,IAAM,SAAoD;AAAA,EACxD,KAAK,CAAC,IAAI;AAAA,EACV,MAAM,CAAC,WAAW,mBAAmB;AAAA,EACrC,MAAM,CAAC,WAAW,aAAa;AAAA,EAC/B,KAAK,CAAC,WAAW,mBAAmB;AACtC;AAGO,SAAS,WAAW,IAA8B;AACvD,SAAO,CAAC,GAAG,OAAO,EAAE,CAAC;AACvB;AAGA,eAAsB,oBACpB,IACA,KACA,OAA6B,CAAC,GACf;AACf,QAAM,OAAO,KAAK,WAAW,OAAO,WAAW,EAAE,IAAI,CAAC,SAAS;AAC/D,MAAI;AACF,UAAMD,WAAU,IAAI,MAAM,EAAE,KAAK,KAAK,WAAW,KAAK,OAAO,KAAK,CAAC;AAAA,EACrE,SAAS,GAAG;AACV,UAAM,MAAM;AACZ,UAAM,IAAI;AAAA,MACR,GAAG,EAAE,IAAI,KAAK,KAAK,GAAG,CAAC,cAAc,GAAG,KAAK,iBAAiB,IAAI,UAAU,IAAI,OAAO,CAAC;AAAA,MACxF,EAAE,OAAO,EAAE;AAAA,IACb;AAAA,EACF;AACF;;;ACpIA,SAAS,eAAe;AACxB,SAAS,QAAAE,OAAM,SAAAC,cAAa;AAsC5B,IAAM,QAAgD;AAAA,EACpD,CAAC,OAAO,KAAK;AAAA,EACb,CAAC,SAAS,OAAO;AAAA,EACjB,CAAC,SAAS,OAAO;AACnB;AAEA,IAAM,iBAAsC,oBAAI,IAAI;AAAA,EAClD,GAAG,MAAM,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,WAAW;AAEjB,SAAS,SAAS,MAAmC;AACnD,QAAMC,UAAS,KAAK,SAAS,QAAQ;AACrC,SAAO,OAAOA,YAAW,YAAYA,YAAW,KAAKA,UAAS;AAChE;AAOA,SAAS,WAAW,MAAoC;AACtD,QAAM,SAAS,KAAK,SAAS,UAAU;AACvC,MAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC;AACpC,QAAM,UAAU,oBAAI,IAA0B;AAC9C,aAAW,SAAS,QAAQ;AAC1B,UAAMC,UACJ,OAAO,UAAU,WACb,EAAE,IAAI,MAAM,IACZ,UAAU,QAAQ,OAAO,UAAU,WAChC,QACD,CAAC;AACT,UAAM,EAAE,IAAI,MAAM,IAAIA;AACtB,QAAI,OAAO,OAAO,YAAY,OAAO,MAAM,QAAQ,IAAI,EAAE,EAAG;AAC5D,YAAQ;AAAA,MACN;AAAA,MACA,OAAO,UAAU,YAAY,UAAU,KAAK,EAAE,IAAI,MAAM,IAAI,EAAE,GAAG;AAAA,IACnE;AAAA,EACF;AACA,SAAO,CAAC,GAAG,QAAQ,OAAO,CAAC;AAC7B;AAEA,SAAS,MAAM,KAAa,MAA+B;AACzD,QAAM,OAAOC,OAAM,SAAS,KAAK,KAAK,KAAK;AAC3C,QAAM,OAAO,aAAa,KAAK,GAAG;AAClC,QAAM,SAAS,eAAe,KAAK,GAAG;AACtC,QAAM,WAAW,WAAW,IAAI;AAChC,SAAO;AAAA,IACL,IAAI,QAAQ,UAAU;AAAA,IACtB,OAAO,cAAc,KAAK,SAAS,MAAM,MAAM;AAAA,IAC/C,QAAQ,SAAS,IAAI;AAAA,IACrB,MAAM,GAAG,GAAG,IAAI,KAAK,GAAG;AAAA,IACxB,GAAI,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;AAAA,EAC5C;AACF;AAGA,SAAS,YAAY,GAAc,GAAsB;AACvD,QAAM,CAAC,GAAG,CAAC,IAAI,CAACA,OAAM,SAAS,EAAE,IAAI,GAAGA,OAAM,SAAS,EAAE,IAAI,CAAC;AAC9D,MAAI,MAAM,EAAG,QAAO,IAAI,IAAI,IAAI;AAChC,SAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK;AACtD;AAOA,eAAsB,WAAW,UAAwC;AACvE,QAAM,OAAoB,CAAC;AAC3B,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO;AACjC,UAAM,QAAQ,MAAM,gBAAgBC,MAAK,UAAU,IAAI,CAAC,GACrD,IAAI,CAAC,SAAS,MAAM,MAAM,IAAI,CAAC,EAC/B,OAAO,CAAC,QAAQ,IAAI,SAAS,QAAQ;AACxC,SAAK,KAAK,EAAE,MAAM,OAAO,MAAM,KAAK,KAAK,WAAW,EAAE,CAAC;AAAA,EACzD;AACA,QAAM,UAAU,MAAM,QAAQ,UAAU,EAAE,eAAe,KAAK,CAAC,EAAE;AAAA,IAC/D,MAAM,CAAC;AAAA,EACT;AACA,QAAM,aAAa,QAChB;AAAA,IACC,CAAC,MACC,EAAE,YAAY,KACd,CAAC,EAAE,KAAK,WAAW,GAAG,KACtB,CAAC,eAAe,IAAI,EAAE,IAAI;AAAA,EAC9B,EACC,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK;AACR,aAAW,QAAQ,YAAY;AAC7B,UAAM,QAAQ,MAAM,gBAAgBA,MAAK,UAAU,IAAI,CAAC,GACrD,OAAO,CAAC,SAAS,SAAS,IAAI,MAAM,IAAI,EACxC,IAAI,CAAC,SAAS,MAAM,MAAM,IAAI,CAAC;AAClC,QAAI,KAAK,SAAS;AAChB,WAAK,KAAK;AAAA,QACR;AAAA,QACA,OAAO,GAAG,KAAK,OAAO,CAAC,EAAE,YAAY,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;AAAA,QACtD,MAAM,KAAK,KAAK,WAAW;AAAA,MAC7B,CAAC;AAAA,EACL;AACA,SAAO;AACT;AAGO,SAAS,QACd,MACA,QACuB;AACvB,QAAM,IAAI,OAAO,YAAY;AAC7B,SAAO,KAAK;AAAA,IACV,CAAC,QAAQ,IAAI,KAAK,YAAY,MAAM,KAAK,IAAI,MAAM,YAAY,MAAM;AAAA,EACvE;AACF;AAIA,IAAM,OAA4B,oBAAI,IAAI;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,UAA+B,oBAAI,IAAI;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,SAAS,WAAWH,SAAmC;AAC5D,MAAIA,YAAW,KAAM,QAAO;AAC5B,QAAM,IAAIA,QAAO,YAAY;AAC7B,MAAI,KAAK,IAAI,CAAC,EAAG,QAAO;AACxB,MAAI,QAAQ,IAAI,CAAC,EAAG,QAAO;AAC3B,SAAO;AACT;AAEA,IAAM,OAAO,CAAC,SAAyB,KAAK,WAAW,KAAK,KAAK;AAG1D,SAAS,eACd,WACA,MACQ;AACR,QAAM,MAAM,CAAC,GAAG,SAAS,gBAAa,EAAE;AACxC,aAAW,OAAO,MAAM;AACtB,QAAI,KAAK,MAAM,IAAI,KAAK,KAAK,IAAI,KAAK,MAAM,KAAK,EAAE;AACnD,QAAI,IAAI,KAAK,WAAW,GAAG;AACzB,UAAI,KAAK,kBAAkB,EAAE;AAC7B;AAAA,IACF;AACA,QAAI,KAAK,2BAA2B,qBAAqB;AACzD,eAAW,OAAO,IAAI;AACpB,UAAI;AAAA,QACF,KAAK,KAAK,IAAI,EAAE,CAAC,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,UAAU,GAAG,CAAC;AAAA,MACrE;AACF,QAAI,KAAK,EAAE;AAAA,EACb;AACA,SAAO,IAAI,KAAK,IAAI;AACtB;AAGA,eAAsB,gBACpB,IACA,UACA,OACmB;AACnB,SAAO,YAAY,IAAI,UAAU,OAAO,CAAC,OAAO,GAAG,CAAC,aAAa,CAAC;AACpE;AAQA,eAAsB,YACpB,IACA,UACA,OACA,aACA,UACmB;AACnB,QAAMI,WAAU,MAAM,gBAAgB;AAAA,IACpC,UAAU,GAAG;AAAA,IACb;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,QAAkB,CAAC;AACzB,QAAM,WAAWA,SAAQ,YAAY,IAAI,CAAC,MAAM,EAAE,IAAc;AAChE,aAAW,QAAQ,aAAa;AAC9B,UAAM,SAASA,SAAQ,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC9D,QAAI,WAAW,QAAW;AACxB,iBAAW,KAAK,OAAO;AACrB,YAAI;AACF,gBAAMJ,UAAS,iBAAiB,EAAE,IAAI,IAAI,QAAQ;AAClD,cAAI,OAAOA,YAAW,YAAY,SAAS,SAASA,OAAM;AACxD,kBAAM,KAAK,GAAG,IAAI,IAAI,EAAE,GAAG,EAAE;AAAA,QACjC,QAAQ;AAAA,QAER;AACF;AAAA,IACF;AACA,QAAI,SAAS,SAAS,IAAI,EAAG;AAC7B,UAAM,OAAO,MAAM,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACvE,eAAW,OAAO,KAAK,QAAQ,CAAC;AAC9B,UAAI,IAAI,WAAW,QAAQ,SAAS,SAAS,IAAI,MAAM;AACrD,cAAM,KAAK,IAAI,IAAI;AAAA,EACzB;AACA,SAAO;AACT;;;ACrPO,IAAM,WAAW,CAAC,KAAa,YACpC,2BAA2B,GAAG,aAAa,OAAO;AAM7C,IAAM,UAAU,CAAC,KAAa,SAAiB,SACpD,GAAG,SAAS,KAAK,OAAO,CAAC,gBAAgB,mBAAmB,SAAS,IAAI,GAAG,CAAC;AAExE,IAAM,UAAU,CAAC,KAAa,SACnC,sBAAsB,GAAG,qBAAqB,UAAU,IAAI,CAAC;AAExD,IAAM,WAAW,CAAC,KAAa,WACpC,sBAAsB,GAAG,kBAAkB,MAAM;;;ACpBnD,SAAS,cAAc,aAAa;AAK7B,IAAM,qBAAqB;AAG3B,IAAM,YAAY;AAClB,IAAM,WAAW;AAExB,IAAM,WAAW,MACf,iCAAiC,aAAa,CAAC;AAiCjD,IAAM,OAAO;AAEb,SAAS,aAAa,OAAwC;AAC5D,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,MAAM,MAAM,YACrB,OAAO,EAAE,SAAS,MAAM,aACxB,OAAO,EAAE,UAAU,MAAM;AAE7B;AAEA,SAAS,OAAO,GAAoB;AAGlC,MAAI,aAAa,SAAS,EAAE,iBAAiB,MAAO,QAAO,EAAE,MAAM;AACnE,SAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAClD;AAaO,IAAM,qBAAN,cAAiC,MAAM;AAAC;AAE/C,eAAe,QACb,KACA,SACA,WACAK,QAAgE,CAAC,GAClD;AACf,QAAM,EAAE,WAAW,GAAG,QAAQ,IAAIA;AAClC,QAAM,SAAS,YAAY,QAAQ,SAAS;AAC5C,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,KAAK,EAAE,SAAS,QAAQ,GAAG,QAAQ,CAAC;AAAA,EACxD,SAAS,GAAG;AACV,UAAM,IAAI,MAAM,gCAAgC,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;AAAA,EAC3E;AACA,MAAI,CAAC,IAAI,IAAI;AACX,QAAI,cAAc,MAAM;AACtB,YAAM,SAAkB,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,MAAS;AAC9D,aAAO,EAAE,QAAQ,IAAI,QAAQ,SAAS,IAAI,SAAS,MAAM,OAAO;AAAA,IAClE;AAEA,UAAM,IAAI,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AAC9C,WAAO,EAAE,QAAQ,IAAI,QAAQ,SAAS,IAAI,SAAS,MAAM,OAAU;AAAA,EACrE;AACA,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,IAAI,KAAK;AAAA,EACxB,SAAS,GAAG;AACV,UAAM,IAAI,MAAM,gCAAgC,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;AAAA,EAC3E;AACA,MAAI;AACF,WAAO,EAAE,QAAQ,IAAI,QAAQ,SAAS,IAAI,SAAS,MAAM,KAAK,MAAM,IAAI,EAAE;AAAA,EAC5E,SAAS,GAAG;AACV,UAAM,IAAI;AAAA,MACR,wCAAwC,IAAI,IAAI,GAAG,EAAE,QAAQ;AAAA,MAC7D,EAAE,OAAO,EAAE;AAAA,IACb;AAAA,EACF;AACF;AAEO,SAAS,UAAU,MAAY,MAAqB;AACzD,QAAM,QAAQ,EAAE,QAAQ,KAAK,QAAQ,KAAK;AAC1C,MAAI,KAAK,WAAW;AAClB,WAAO,IAAI,MAAM,mCAAmC,EAAE,MAAM,CAAC;AAG/D,MACE,KAAK,WAAW,OACf,KAAK,WAAW,QACd,KAAK,QAAQ,IAAI,uBAAuB,MAAM,OAC7C,KAAK,QAAQ,IAAI,aAAa,IAClC;AACA,WAAO,IAAI;AAAA,MACT,kFAAkF,aAAa,CAAC;AAAA,MAChG,EAAE,MAAM;AAAA,IACV;AAAA,EACF;AACA,SAAO,IAAI;AAAA,IACT,uBAAuB,KAAK,MAAM,QAAQ,IAAI,GAAG,SAAS,CAAC;AAAA,IAC3D,EAAE,MAAM;AAAA,EACV;AACF;AAQA,eAAsB,iBACpB,OACA,SAC4B;AAC5B,QAAM,QAAQ,QAAQ,WAAW,oBAAoB,QAAQ,QAAQ,EAAE;AACvE,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,UAAkC;AAAA,IACtC,QAAQ;AAAA,IACR,wBAAwB;AAAA,IACxB,cAAc;AAAA,EAChB;AACA,MAAI,QAAQ,UAAU,UAAa,QAAQ,UAAU;AACnD,YAAQ,eAAe,IAAI,UAAU,QAAQ,KAAK;AAEpD,QAAM,UAAU,mBAAmB,KAAK;AAMxC,QAAM,MAAY;AAAA,IAChB,MAAM,SAAS,OAAO;AAAA,IACtB,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACA,QAAM,OAAa;AAAA,IACjB,MAAM,UAAU,OAAO;AAAA,IACvB,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACA,QAAM,OAAa;AAAA,IACjB,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACA,QAAM,MAAM,CAAC,GAAS,MACpB,GAAG,IAAI,GAAG,EAAE,IAAI,IAAI,EAAE,KAAK,aAAa,QAAQ,SAAS,CAAC;AAC5D,MAAI,OAAa;AACjB,QAAM,eAAgC,CAAC;AACvC,WAAS,IAAI,GAAG,KAAK,WAAW,KAAK;AACnC,QAAI,OAAO,MAAM,QAAQ,IAAI,MAAM,CAAC,GAAG,SAAS,SAAS;AACzD,QAAI,MAAM,KAAK,KAAK,WAAW,KAAK;AAElC,YAAM,OAAQ,MAAM,QAAQ,OAAO,KAAM;AACzC,aAAO,MAAM,YAAY,MAAM,MAAM,YAAY,IAAI,OAAO;AAC5D,aAAO,MAAM,QAAQ,IAAI,MAAM,CAAC,GAAG,SAAS,SAAS;AACrD,UAAI,KAAK,WAAW,KAAK;AACvB,cAAM,IAAI;AAAA,UACR,6CAA6C,KAAK,kCAAkC,SAAS,CAAC;AAAA,UAC9F,EAAE,OAAO,EAAE,QAAQ,KAAK,MAAM,KAAK,KAAK,EAAE;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AACA,QAAI,KAAK,SAAS,OAAO,KAAK,UAAU;AACtC,YAAM,UAAU,MAAM,KAAK,IAAI;AACjC,QAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,YAAY,GAAG;AAC/D,YAAM,IAAI;AAAA,QACR,8CAA8C,KAAK,IAAI;AAAA,QACvD;AAAA,UACE,OAAO,KAAK;AAAA,QACd;AAAA,MACF;AAAA,IACF;AACA,eAAW,KAAK,KAAK;AACnB,mBAAa,KAAK;AAAA,QAChB,MAAM,EAAE;AAAA,QACR,SAAS,EAAE;AAAA,QACX,UAAU,EAAE;AAAA,MACd,CAAC;AACH,QAAI,CAAC,KAAK,KAAK,KAAK,QAAQ,IAAI,MAAM,KAAK,EAAE;AAC3C,aAAO;AAAA,QACL;AAAA,QACA,OAAO,KAAK;AAAA,QACZ,WAAW;AAAA,MACb;AAAA,EACJ;AACA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,KAAK;AAAA,IACZ,WAAW;AAAA,EACb;AACF;AAGO,IAAM,iBAAiB;AAE9B,IAAM,kBAAkB;AAExB,IAAM,cAAc;AACb,IAAM,uBACX;AASK,SAAS,SACd,QAAuC,CAAC,OAAO,MAAM,EAAE,GAC7C;AACV,SAAO,EAAE,MAAM,gBAAgB,KAAK,MAAM,KAAK,IAAI,GAAG,MAAM;AAC9D;AAGA,IAAM,eAAe,SAAS;AAGvB,IAAM,iBAAN,cAA6B,MAAM;AAAC;AAE3C,IAAM,YAAY,CAAC,SAA0B;AAC3C,QAAM,IACJ,SAAS,QAAQ,OAAO,SAAS,WAC5B,KAAiC,SAAS,IAC3C;AACN,SAAO,OAAO,MAAM,WAAW,IAAI;AACrC;AAUO,SAAS,UACd,MACA,KACA,UAAU,OACK;AACf,QAAM,IAAI,KAAK;AACf,QAAM,QAAQ,EAAE,IAAI,uBAAuB,MAAM;AACjD,QAAM,MACJ,WACA,KAAK,WAAW,OACf,KAAK,WAAW,QACd,EAAE,IAAI,aAAa,KAClB,SACA,cAAc,KAAK,UAAU,KAAK,IAAI,CAAC;AAC7C,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,SAAS,EAAE,IAAI,aAAa,KAAK,IAAI,KAAK;AAChD,MAAI,QAAQ,KAAK,KAAK,EAAG,QAAO,OAAO,KAAK,IAAI;AAChD,QAAM,SAAS,EAAE,IAAI,mBAAmB,KAAK,IAAI,KAAK;AACtD,MAAI,SAAS,QAAQ,KAAK,KAAK;AAC7B,WAAO,KAAK,IAAI,GAAG,OAAO,KAAK,IAAI,MAAO,GAAG;AAC/C,SAAO;AACT;AAGA,eAAsB,QAAQ,SAAqB,IAA2B;AAC5E,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,QAAQ,KAAK,IAAI,IAAI,WAAW;AACtC,MAAI,QAAQ,KAAK,KAAM,OAAM,IAAI,eAAe,oBAAoB;AACpE,OAAK,QAAQ;AACb,QAAM,KAAK,MAAM,KAAK;AACxB;AAUA,SAAS,WAAW,OAAuC;AACzD,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,eAAe,UAAU,KAAK;AAAA,EAChC;AACF;AAGA,eAAe,QACb,MACA,SAC4C;AAC5C,QAAM,QAAQ,QAAQ,WAAW,oBAAoB,QAAQ,QAAQ,EAAE;AACvE,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,IAAI;AAAA,MAClC,SAAS,WAAW,QAAQ,KAAK;AAAA,MACjC,QAAQ,YAAY,QAAQ,QAAQ,aAAa,IAAM;AAAA,IACzD,CAAC;AAAA,EACH,SAAS,GAAG;AACV,UAAM,IAAI,MAAM,gCAAgC,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;AAAA,EAC3E;AACA,QAAM,OAAgB,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,MAAS;AAC5D,SAAO,EAAE,QAAQ,IAAI,QAAQ,KAAK;AACpC;AAOA,eAAsB,SACpB,MACA,SACA,SAEA,UAAU,OAEV,UAAsC,MAAM,OAC1B;AAClB,QAAM,QAAQ,QAAQ,WAAW,oBAAoB,QAAQ,QAAQ,EAAE;AACvE,QAAM,QAAQ,QAAQ,QAAQ;AAC9B,aAAS;AACP,UAAM,OAAO,MAAM;AAAA,MACjB,GAAG,IAAI,GAAG,IAAI;AAAA,MACd,EAAE,GAAG,WAAW,QAAQ,KAAK,GAAG,gBAAgB,mBAAmB;AAAA,MACnE,QAAQ,aAAa;AAAA;AAAA;AAAA,MAGrB,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAU,OAAO,GAAG,WAAW,KAAK;AAAA,IACnE;AACA,UAAM,KAAK,KAAK,UAAU,OAAO,KAAK,SAAS;AAC/C,UAAM,OAAO,UAAU,MAAM,MAAM,IAAI,GAAG,MAAM,QAAQ,KAAK,IAAI,CAAC;AAClE,QAAI,SAAS,MAAM;AACjB,YAAM,QAAQ,SAAS,IAAI;AAC3B;AAAA,IACF;AACA,QAAI,CAAC,IAAI;AACP,YAAM,UACJ,WACA,KAAK,WAAW,OAChB,KAAK,WAAW,OAChB,KAAK,SAAS,QACd,OAAO,KAAK,SAAS,WAChB,KAAK,KAA+B,UACrC;AACN,UAAI,OAAO,YAAY,YAAY,YAAY;AAC7C,cAAM,IAAI,mBAAmB,SAAS;AAAA,UACpC,OAAO,EAAE,QAAQ,KAAK,QAAQ,KAAK;AAAA,QACrC,CAAC;AACH,YAAM,UAAU,MAAM,IAAI;AAAA,IAC5B;AACA,WAAO,KAAK;AAAA,EACd;AACF;AASA,eAAsB,UAAU,SAA+C;AAC7E,QAAM,QAAQ,QAAQ,WAAW,oBAAoB,QAAQ,QAAQ,EAAE;AACvE,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,GAAG,IAAI,SAAS;AAAA,MAChC,SAAS,WAAW,QAAQ,KAAK;AAAA,MACjC,QAAQ,YAAY,QAAQ,QAAQ,aAAa,IAAM;AAAA,IACzD,CAAC;AAAA,EACH,SAAS,GAAG;AACV,UAAM,IAAI,MAAM,wBAAwB,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;AAAA,EACnE;AACA,QAAM,OAAgB,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,MAAS;AAC5D,MAAI,IAAI,WAAW,KAAK;AACtB,UAAM,QAAQ,EAAE,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAClD,QAAI,IAAI,WAAW;AACjB,YAAM,IAAI,MAAM,mCAAmC,EAAE,MAAM,CAAC;AAC9D,UAAM,UACJ,SAAS,QAAQ,OAAO,SAAS,WAC5B,KAAiC,SAAS,IAC3C;AACN,QAAI,OAAO,YAAY,YAAY,YAAY;AAC7C,YAAM,IAAI,mBAAmB,SAAS,EAAE,MAAM,CAAC;AACjD,UAAM,IAAI,MAAM,uBAAuB,IAAI,MAAM,cAAc,EAAE,MAAM,CAAC;AAAA,EAC1E;AACA,QAAM,SAAS,IAAI,QAAQ,IAAI,gBAAgB;AAC/C,MAAI,WAAW,KAAM,QAAO;AAC5B,SAAO,OACJ,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,MAAM,EAAE;AAC3B;AAGA,eAAsB,QAAQ,SAAiD;AAC7E,QAAM,EAAE,QAAAC,SAAQ,KAAK,IAAI,MAAM,QAAQ,SAAS,OAAO;AACvD,MAAIA,YAAW,IAAK,OAAM,IAAI,MAAM,iCAAiC;AACrE,QAAM,QACJ,SAAS,QAAQ,OAAO,SAAS,WAC5B,KAAiC,OAAO,IACzC;AACN,MAAIA,YAAW,OAAO,OAAO,UAAU;AACrC,UAAM,IAAI,MAAM,uBAAuBA,OAAM,YAAY;AAC3D,SAAO,EAAE,MAAM;AACjB;AAaA,eAAsB,oBACpB,SAC2B;AAC3B,QAAM,EAAE,QAAAA,SAAQ,KAAK,IAAI,MAAM;AAAA,IAC7B,gDAAgD,QAAQ;AAAA,IACxD;AAAA,EACF;AACA,MAAIA,YAAW,OAAO,CAAC,MAAM,QAAQ,IAAI;AACvC,UAAM,IAAI,MAAM,uBAAuBA,OAAM,6BAA6B;AAC5E,QAAM,cAAgC,CAAC;AACvC,aAAW,KAAK,MAAmB;AACjC,QAAI,MAAM,QAAQ,OAAO,MAAM,SAAU;AACzC,UAAM,QAAQ;AACd,UAAM,MAAM,MAAM,cAAc;AAChC,UAAM,QACJ,QAAQ,QAAQ,OAAO,QAAQ,WAC1B,IAAgC,OAAO,IACxC;AACN,QAAI,OAAO,UAAU,YAAY,MAAM,OAAO,MAAM,SAAU;AAC9D,gBAAY,KAAK;AAAA,MACf;AAAA,MACA,MAAM,OAAO,MAAM,MAAM,MAAM,WAAW,MAAM,MAAM,IAAI;AAAA,IAC5D,CAAC;AAAA,EACH;AACA,SAAO;AACT;AASA,eAAsB,iBACpB,KACA,SACwB;AACxB,QAAM,EAAE,QAAAA,SAAQ,KAAK,IAAI,MAAM;AAAA,IAC7B,0BAA0B,mBAAmB,GAAG,CAAC;AAAA,IACjD;AAAA,EACF;AACA,MAAIA,YAAW,KAAK;AAClB,UAAM,QACJ,SAAS,QAAQ,OAAO,SAAS,WAC5B,KAAiC,OAAO,IACzC;AACN,WAAO,UAAU,WAAW,WAAW;AAAA,EACzC;AACA,MAAIA,YAAW,IAAK,QAAO;AAC3B,MAAIA,YAAW,KAAK;AAClB,UAAM,UACJ,SAAS,QAAQ,OAAO,SAAS,WAC7B,OAAQ,KAAiC,SAAS,KAAK,EAAE,IACzD;AACN,QAAI,iCAAiC,KAAK,OAAO,EAAG,QAAO;AAAA,EAC7D;AACA,SAAO;AACT;AAcA,eAAsB,iBACpB,OACA,MACA,SACiC;AACjC,QAAM,QAAQ,QAAQ,WAAW,oBAAoB,QAAQ,QAAQ,EAAE;AACvE,QAAMC,QAAO,OACX,SACiD;AACjD,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,IAAI;AAAA,QAClC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,GAAG,WAAW,QAAQ,KAAK;AAAA,UAC3B,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,MAAM,SAAS,KAAK,CAAC;AAAA,QAC5C,QAAQ,YAAY,QAAQ,QAAQ,aAAa,IAAM;AAAA,MACzD,CAAC;AAAA,IACH,SAAS,GAAG;AACV,YAAM,IAAI,MAAM,gCAAgC,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;AAAA,IAC3E;AACA,UAAM,OAAgB,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,MAAS;AAC5D,UAAM,UACJ,SAAS,QAAQ,OAAO,SAAS,WAC7B,OAAQ,KAAiC,SAAS,KAAK,EAAE,IACzD;AACN,WAAO,EAAE,QAAQ,IAAI,QAAQ,QAAQ;AAAA,EACvC;AACA,MAAI,SAAS,MAAMA,MAAK,SAAS,mBAAmB,KAAK,CAAC,QAAQ;AAClE,MACE,OAAO,WAAW,OAClB,QAAQ,SAAS,UACjB,QAAQ,SAAS,QACjB,QAAQ,KAAK,YAAY,MAAM,MAAM,YAAY;AAEjD,aAAS,MAAMA,MAAK,aAAa;AACnC,MAAI,OAAO,WAAW,IAAK,QAAO,EAAE,MAAM,UAAU;AACpD,MAAI,OAAO,WAAW,IAAK,QAAO,EAAE,MAAM,SAAS;AACnD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QACE,OAAO,YAAY,KACf,mBAAmB,OAAO,MAAM,KAChC,GAAG,OAAO,OAAO,KAAK,OAAO,MAAM;AAAA,EAC3C;AACF;;;AChjBA,SAASC,UAAS,GAA0C;AAC1D,SAAO,MAAM,QAAQ,OAAO,MAAM;AACpC;AAGA,IAAM,cAAc,CAAC,SACnBA,UAAS,IAAI,KACb,MAAM,QAAQ,KAAK,QAAQ,CAAC,KAC5B,KAAK,QAAQ,EAAE;AAAA,EACb,CAAC,MAAeA,UAAS,CAAC,KAAK,EAAE,MAAM,MAAM;AAC/C;AAEF,eAAe,WACb,OACA,WACA,SAC2B;AAC3B,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA,EAAE,OAAO,UAAU;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAOA,UAAS,IAAI,IAAK,OAA4B,CAAC;AACxD;AAEA,SAAS,WAAW,QAA8C;AAChE,QAAM,QAAQ,OAAO,SAAS,CAAC;AAC/B,SAAO,UAAU,SACb,OACA,IAAI,mBAAmB,MAAM,WAAW,sBAAsB;AACpE;AAEA,eAAsB,QACpB,OACA,WACA,SACY;AACZ,QAAM,SAAS,MAAM,WAAc,OAAO,WAAW,OAAO;AAC5D,QAAM,QAAQ,WAAW,MAAM;AAC/B,MAAI,UAAU,KAAM,OAAM;AAC1B,MAAI,OAAO,SAAS;AAClB,UAAM,IAAI,MAAM,sCAAsC;AACxD,SAAO,OAAO;AAChB;AAGA,eAAsB,aACpB,OACA,WACA,SACmB;AACnB,QAAM,SAAS,MAAM,WAAc,OAAO,WAAW,OAAO;AAC5D,QAAM,SAAS,OAAO,UAAU,CAAC;AACjC,MAAI,OAAO,SAAS,KAAK,OAAO,MAAM,CAAC,MAAM,EAAE,SAAS,WAAW;AACjE,WAAO;AACT,QAAM,QAAQ,WAAW,MAAM;AAC/B,MAAI,UAAU,KAAM,OAAM;AAC1B,SAAO,OAAO,QAAQ;AACxB;AAEA,eAAsB,MAAM,KAAa,GAAgC;AACvE,QAAM,IAAI,MAAM;AAAA,IACd;AAAA,IACA,EAAE,OAAO,IAAI;AAAA,IACb;AAAA,EACF;AACA,MAAI,EAAE,iBAAiB;AACrB,UAAM,IAAI,MAAM,gCAAgC,GAAG,EAAE;AACvD,SAAO,EAAE,aAAa;AACxB;AAEA,eAAsB,cACpB,SACA,OACA,GACsD;AACtD,QAAM,IAAI,MAAM;AAAA,IAGd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWA,EAAE,SAAS,MAAM;AAAA,IACjB;AAAA,EACF;AACA,SAAO,EAAE,gBAAgB;AAC3B;AAEA,eAAsB,YACpB,KACA,QACA,GAC6C;AAC7C,QAAM,SAAS,MAAM;AAAA,IAGnB;AAAA;AAAA;AAAA,IAGA,EAAE,OAAO,KAAK,OAAO;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,SAAS,OAAO,UAAU,CAAC;AACjC,MAAI,OAAO,SAAS,KAAK,OAAO,MAAM,CAAC,MAAM,EAAE,SAAS,WAAW;AACjE,WAAO;AACT,QAAM,QAAQ,WAAW,MAAM;AAC/B,MAAI,UAAU,KAAM,OAAM;AAC1B,SAAO,OAAO,MAAM,cAAc,aAAa;AACjD;AAoBA,SAAS,QAAQ,KAAsB;AACrC,QAAM,aAAa,IAAI;AAEvB,MAAI,OAAO,eAAe;AACxB,UAAM,IAAI;AAAA,MACR,8BAA8B,IAAI,QAAQ,IAAI,MAAM,EAAE;AAAA,IACxD;AACF,SAAO;AAAA,IACL,IAAI,IAAI,MAAM;AAAA,IACd;AAAA,IACA,MAAM,IAAI,QAAQ;AAAA,IAClB,UACE,IAAI,aACH,IAAI,YAAY,UAAa,IAAI,YAAY,OAC1C,SACA;AAAA,IACN,SAAS,IAAI,WAAW;AAAA,EAC1B;AACF;AAEA,eAAsB,OACpB,WACA,GACkB;AAClB,QAAM,IAAI,MAAM;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAMc,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO7B,EAAE,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO,EAAE,KAAK,OAAO,MAClB,OAAO,CAAC,MAAM,EAAE,OAAO,MAAS,EAChC,IAAI,CAAC,MAAM,QAAQ,CAAC,CAAC;AAC1B;AAQA,IAAM,cAAc,CAAC,GAAgB,QAAiB;AAAA,EACpD,GAAI,OAAO,SAAY,CAAC,IAAI,EAAE,GAAG;AAAA,EACjC,MAAM,EAAE;AAAA,EACR,OAAO,EAAE;AAAA,EACT,aAAa;AACf;AAEA,IAAM,kBAAkB;AAAA;AAGxB,eAAsB,YACpB,WACA,MACA,MACA,GACgB;AAChB,QAAM,SAAS,OAAO,SAAS;AAC/B,QAAM,IAAI,MAAM;AAAA,IAGd,iFACE,SAAS,yDAAyD,EACpE;AAAA;AAAA,iEAGM,SAAS,oCAAoC,EAC/C;AAAA,8BACsB,eAAe;AAAA;AAAA,IAEzC;AAAA,MACE;AAAA,MACA;AAAA,MACA,UAAU,SAAS,kBAAkB;AAAA,MACrC,GAAI,SAAS,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,IACvE;AAAA,IACA;AAAA,EACF;AACA,SAAO,QAAQ,EAAE,qBAAqB,cAAc;AACtD;AAGA,eAAsB,WACpB,OACA,SACA,GACgB;AAChB,QAAM,MAAM,IAAI,KAAK,MAAM,WAAW,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,IAAI,EAAE,CAAC,CAAC;AAC1E,QAAM,IAAI,MAAM;AAAA,IAGd;AAAA;AAAA,2BAEuB,eAAe;AAAA;AAAA;AAAA,IAGtC;AAAA,MACE,SAAS,MAAM;AAAA,MACf,SAAS,QAAQ,IAAI,CAAC,MAAM,YAAY,GAAG,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC;AAAA,IAC7D;AAAA,IACA;AAAA,EACF;AACA,SAAO,QAAQ,EAAE,qBAAqB,cAAc;AACtD;AAGA,eAAsB,YACpB,SACA,MACA,GACgB;AAChB,QAAM,IAAI,MAAM;AAAA,IAGd;AAAA;AAAA,2BAEuB,eAAe;AAAA;AAAA;AAAA,IAGtC,EAAE,SAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACA,SAAO,QAAQ,EAAE,qBAAqB,cAAc;AACtD;AAwDA,eAAsB,UACpB,WACA,GACA,EAAE,SAAS,KAAK,IAA0B,CAAC,GACvB;AACpB,QAAM,QAAmB,CAAC;AAC1B,MAAI,SAAwB;AAC5B,aAAS;AACP,UAAM,IAOF,MAAM;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAkBkB,SAAS,SAAS,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAyDtC,EAAE,WAAW,OAAO;AAAA,MACpB;AAAA,IACF;AACA,eAAW,KAAK,EAAE,KAAK,MAAM,OAAO;AAClC,YAAMC,UAAiC,CAAC;AACxC,iBAAW,KAAK,EAAE,aAAa,SAAS,CAAC,GAAG;AAC1C,cAAM,QAAQ,EAAE,OAAO;AACvB,cAAM,QACJ,EAAE,QACF,EAAE,QACF,EAAE,SACD,EAAE,WAAW,SAAY,SAAY,OAAO,EAAE,MAAM;AACvD,YAAI,UAAU,UAAa,UAAU,OAAW,CAAAA,QAAO,KAAK,IAAI;AAAA,MAClE;AACA,YAAM,IAAI,EAAE;AACZ,YAAM,QACJ,GAAG,OAAO,UAAa,EAAE,WAAW,SAChC;AAAA,QACE,IAAI,EAAE;AAAA,QACN,QAAQ,EAAE;AAAA,QACV,MAAM,EAAE,UAAU;AAAA,QAClB,YAAY,EAAE,YAAY,iBAAiB;AAAA,QAC3C,MAAM,SAAU,EAAE,QAAQ,KAAM;AAAA,QAChC,SAAS,EAAE,QAAQ,SAAS,CAAC,GAC1B,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EACvB,OAAO,CAAC,MAAM,MAAM,EAAE;AAAA,MAC3B,IACA;AACN,YAAM,KAAK;AAAA,QACT,IAAI,EAAE;AAAA,QACN,SAAS,UAAU,OAAQ,GAAG,MAAM,OAAQ;AAAA,QAC5C;AAAA,QACA,OAAO,GAAG,SAAS;AAAA,QACnB,UAAU,EAAE,eAAe;AAAA,QAC3B,QAAAA;AAAA,MACF,CAAC;AAAA,IACH;AACA,UAAM,EAAE,aAAa,UAAU,IAAI,EAAE,KAAK,MAAM;AAChD,QAAI,CAAC,eAAe,cAAc,KAAM,QAAO;AAC/C,aAAS;AAAA,EACX;AACF;AAEA,eAAsB,SACpB,WACA,QACA,SACA,OAMA,GACe;AACf,MAAI,UAAU,MAAM;AAClB,UAAM;AAAA,MACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,EAAE,WAAW,QAAQ,QAAQ;AAAA,MAC7B;AAAA,IACF;AACA;AAAA,EACF;AACA,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAqBA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,OACE,cAAc,QAAQ,EAAE,sBAAsB,MAAM,SAAS,IAAI;AAAA,IACrE;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,QACpB,WACA,QACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWA,EAAE,WAAW,OAAO;AAAA,IACpB;AAAA,EACF;AACF;AAGA,eAAsB,QACpB,WACA,WACA,GACiB;AACjB,QAAM,IAAI,MAAM;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWA,EAAE,WAAW,UAAU;AAAA,IACvB;AAAA,EACF;AACA,SAAO,EAAE,qBAAqB,KAAK;AACrC;AAGA,eAAsB,aACpB,QACA,cACA,GACyC;AACzC,QAAM,IAAI,MAAM;AAAA,IAKd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAiBA,EAAE,QAAQ,aAAa;AAAA,IACvB;AAAA,EACF;AACA,QAAM,UAAU,EAAE,sCAAsC,KAAK;AAC7D,QAAM,KAAK,SAAS;AACpB,QAAM,SAAS,SAAS;AACxB,MAAI,OAAO,UAAa,WAAW;AACjC,UAAM,IAAI,MAAM,6BAA6B,MAAM,mBAAmB;AACxE,SAAO,EAAE,IAAI,OAAO;AACtB;AAGA,eAAsB,mBACpB,WACA,GACmB;AACnB,QAAM,IAAI,MAAM;AAAA,IAGd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaA,EAAE,UAAU;AAAA,IACZ;AAAA,EACF;AACA,UAAQ,EAAE,MAAM,aAAa,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,aAAa;AACtE;AAGA,eAAsB,eACpB,WACA,cACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWA,EAAE,WAAW,aAAa;AAAA,IAC1B;AAAA,EACF;AACF;AAOA,eAAsB,WACpB,KACA,QACA,MASA,GACe;AACf,QAAM,OAAgC,EAAE,MAAM,KAAK,MAAM,QAAQ,KAAK,OAAO;AAC7E,MAAI,KAAK,WAAW,KAAM,MAAK,QAAQ,IAAI,KAAK;AAChD,MAAI,KAAK,YAAY,QAAW;AAC9B,QAAI,CAAC,OAAO,UAAU,KAAK,OAAO;AAChC,YAAM,IAAI;AAAA,QACR,+CAA+C,KAAK,OAAO;AAAA,MAC7D;AACF,SAAK,mBAAmB,IAAI,CAAC,KAAK,OAAO;AAAA,EAC3C;AACA,MAAI,KAAK,kBAAkB,QAAW;AACpC,QAAI,CAAC,KAAK,cAAc,MAAM,OAAO,SAAS;AAC5C,YAAM,IAAI,MAAM,2CAA2C;AAC7D,SAAK,gBAAgB,IAAI,KAAK;AAAA,EAChC;AACA,QAAM;AAAA,IACJ,SAAS,mBAAmB,GAAG,CAAC,eAAe,MAAM;AAAA,IACrD;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAgBA,eAAsB,MAAM,WAAmB,GAAgC;AAC7E,QAAM,IAAI,MAAM;AAAA,IAcd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IA8BA,EAAE,UAAU;AAAA,IACZ;AAAA,EACF;AACA,UAAQ,EAAE,MAAM,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,IAC7C,IAAI,EAAE;AAAA,IACN,MAAM,EAAE;AAAA,IACR,QAAQ,EAAE;AAAA,IACV,aAAa,EAAE,uBAAuB,MAAM,CAAC,GAAG,QAAQ;AAAA,IACxD,QAAQ,EAAE,WAAW,UAAa,EAAE,WAAW,KAAK,OAAO,EAAE;AAAA,IAC7D,SAAS,EAAE,QAAQ,SAAS,CAAC,GAAG;AAAA,MAAQ,CAAC,MACvC,EAAE,SAAS,SAAY,CAAC,IAAI,CAAC,EAAE,IAAI;AAAA,IACrC;AAAA,EACF,EAAE;AACJ;AAGA,eAAsB,WAAW,QAAgB,GAA8B;AAC7E,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,EAAE,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAGO,IAAM,UAAU;AAAA,EACrB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AACX;AAQA,eAAsB,WACpB,QACA,QAOA,GACe;AACf,QAAM,OAAgC,EAAE,OAAO;AAC/C,QAAM,UAAoB,CAAC,cAAc;AACzC,QAAM,QAAkB,CAAC,iBAAiB;AAC1C,MAAI,OAAO,SAAS,QAAW;AAC7B,SAAK,MAAM,IAAI,OAAO;AACtB,YAAQ,KAAK,eAAe;AAC5B,UAAM,KAAK,aAAa;AAAA,EAC1B;AACA,MAAI,OAAO,WAAW,QAAW;AAC/B,SAAK,QAAQ,IAAI,QAAQ,OAAO,MAAM;AACtC,YAAQ,KAAK,8BAA8B;AAC3C,UAAM,KAAK,iBAAiB;AAAA,EAC9B;AACA,MAAI,OAAO,WAAW,QAAW;AAC/B,SAAK,QAAQ,IAAI,OAAO;AACxB,YAAQ,KAAK,iBAAiB;AAC9B,UAAM,KAAK,iBAAiB;AAAA,EAC9B;AACA,MAAI,OAAO,oBAAoB,QAAW;AACxC,SAAK,iBAAiB,IAAI,OAAO;AACjC,YAAQ,KAAK,yBAAyB;AACtC,UAAM,KAAK,sDAAsD;AAAA,EACnE;AACA,QAAM;AAAA,IACJ,aAAa,QAAQ,KAAK,IAAI,CAAC;AAAA,qCACE,MAAM,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMjD;AAAA,IACA;AAAA,EACF;AACF;AAaA,eAAsB,WACpB,WACA,QACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,EAAE,WAAW,OAAO;AAAA,IACpB;AAAA,EACF;AACF;AAGA,eAAsB,YACpB,WACA,GACuD;AACvD,QAAM,IAAI,MAAM;AAAA,IAMd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUA,EAAE,UAAU;AAAA,IACZ;AAAA,EACF;AACA,SAAO;AAAA,IACL,QAAQ,EAAE,MAAM,iBAAiB;AAAA,IACjC,kBAAkB,EAAE,MAAM,sBAAsB;AAAA,EAClD;AACF;AAGA,eAAsB,kBACpB,WACA,MACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAeA,EAAE,WAAW,GAAG,KAAK;AAAA,IACrB;AAAA,EACF;AACF;AAYA,eAAsB,cACpB,WACA,GAC6B;AAC7B,QAAM,IAAI,MAAM;AAAA,IAGd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAiBA,EAAE,UAAU;AAAA,IACZ;AAAA,EACF;AACA,SAAO,EAAE,MAAM,cAAc,SAAS,CAAC;AACzC;AASA,eAAsB,mBACpB,WACA,QACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBA,EAAE,WAAW,GAAG,OAAO;AAAA,IACvB;AAAA,EACF;AACF;AAEA,eAAsB,mBACpB,gBACA,QACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBA,EAAE,gBAAgB,GAAG,OAAO;AAAA,IAC5B;AAAA,EACF;AACF;;;ACrhCA,eAAsB,WACpB,OACA,MACA,OACA,GAC4B;AAC5B,QAAM,IAAI,MAAM;AAAA,IAOd;AAAA;AAAA;AAAA,IAGA,EAAE,OAAO,MAAM,MAAM;AAAA,IACrB;AAAA,EACF;AACA,QAAM,IAAI,GAAG,cAAc;AAC3B,SAAO,MAAM,OACT,OACA,EAAE,IAAI,EAAE,IAAI,QAAQ,EAAE,kBAAkB,SAAS,EAAE,OAAO,MAAM,KAAK;AAC3E;AAeA,eAAsB,WACpB,OACA,MACA,OACA,GACsB;AACtB,QAAM,QAAqB,CAAC;AAC5B,MAAI,QAAuB;AAC3B,aAAS;AACP,UAAM,IAOF,MAAM;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAuBA,EAAE,OAAO,MAAM,OAAO,MAAM;AAAA,MAC5B;AAAA,IACF;AACA,UAAM,OAAO,EAAE,YAAY;AAC3B,QAAI,SAAS,OAAW,QAAO;AAC/B,UAAM,KAAK,GAAG,KAAK,KAAK;AACxB,QAAI,CAAC,KAAK,SAAS,eAAe,KAAK,SAAS,cAAc;AAC5D,aAAO;AACT,YAAQ,KAAK,SAAS;AAAA,EACxB;AACF;AAGA,eAAsB,YACpB,OACA,MACA,OACA,GACiB;AACjB,QAAM,OAAO,MAAM;AAAA,IACjB,UAAU,mBAAmB,KAAK,CAAC,IAAI,mBAAmB,IAAI,CAAC;AAAA,IAC/D;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,KACJ,SAAS,QAAQ,OAAO,SAAS,WAC5B,KAAiC,SAAS,IAC3C;AACN,MAAI,OAAO,OAAO;AAChB,UAAM,IAAI,MAAM,4BAA4B,MAAM,IAAI,oBAAoB;AAC5E,SAAO;AACT;AAEA,eAAsB,YACpB,cACA,OACA,GACyC;AACzC,QAAM,IAAI,MAAM;AAAA,IAGd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAsBA,EAAE,cAAc,GAAG,MAAM;AAAA,IACzB;AAAA,EACF;AACA,SAAO,EAAE,YAAY;AACvB;AAGA,eAAsB,YACpB,IACA,QACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,EAAE,IAAI,GAAG,OAAO;AAAA,IAChB;AAAA,EACF;AACF;AAGA,eAAsB,WAAW,IAAY,GAA8B;AACzE,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,EAAE,GAAG;AAAA,IACL;AAAA,EACF;AACF;AAEA,eAAsB,YAAY,IAAY,GAA8B;AAC1E,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,EAAE,GAAG;AAAA,IACL;AAAA,EACF;AACF;AAEA,eAAsB,UACpB,IACAC,WACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,EAAE,IAAI,UAAAA,UAAS;AAAA,IACf;AAAA,EACF;AACF;AAGA,eAAsB,SACpB,OACA,MACA,GAC8B;AAC9B,QAAM,MAAM,oBAAI,IAAoB;AACpC,MAAI,QAAuB;AAC3B,aAAS;AACP,UAAM,IAOF,MAAM;AAAA,MACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAgBA,EAAE,OAAO,MAAM,MAAM;AAAA,MACrB;AAAA,IACF;AACA,UAAM,OAAO,EAAE,YAAY;AAC3B,eAAW,KAAK,MAAM,SAAS,CAAC,EAAG,KAAI,IAAI,EAAE,MAAM,EAAE,EAAE;AACvD,QAAI,MAAM,SAAS,gBAAgB,QAAQ,KAAK,SAAS,cAAc;AACrE,aAAO;AACT,YAAQ,KAAK,SAAS;AAAA,EACxB;AACF;AAEA,eAAsB,aACpB,IACAA,WACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,EAAE,IAAI,UAAAA,UAAS;AAAA,IACf;AAAA,EACF;AACF;;;ACjSO,IAAM,gBAAgB;AAC7B,IAAM,sBAAsB;AAC5B,IAAM,4BAA4B;AAG3B,IAAM,gBAAgB,CAAC,aAC5B,sBAAsB,QAAQ;AAUzB,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAC/B;AAAA,EACT,YAAY,KAA2B,SAAiB;AACtD,UAAM,OAAO;AACb,SAAK,MAAM;AAAA,EACb;AACF;AAEA,IAAM,WAAW,CAAC,SAChB,KACG,QAAQ,EACR,MAAM,UAAU,EAChB,GAAG,EAAE,GACJ,KAAK,KAAK;AAGhB,eAAsB,aACpB,OACA,MACA,UACA,GAC8B;AAC9B,QAAM,SAAS,cAAc,QAAQ;AACrC,QAAM,SAAS,MAAS,WAAW,OAAO,MAAM,eAAe,CAAC,GAAG;AAAA,IACjE,CAAC,MAAM,SAAS,EAAE,IAAI,MAAM;AAAA,EAC9B;AACA,SAAO,UAAU,SACb,OACA,EAAE,IAAI,MAAM,IAAI,QAAQ,MAAM,QAAQ,YAAY,GAAG,KAAK,IAAI,IAAI,GAAG;AAC3E;AAQA,eAAsB,mBACpB,OACA,MACA,UACA,OACA,GACuB;AACvB,QAAM,OAAO,MAAS,WAAW,OAAO,MAAM,eAAe,CAAC;AAC9D,MAAI,SAAS;AACX,UAAM,IAAI;AAAA,MACR;AAAA,MACA,GAAG,KAAK,IAAI,IAAI;AAAA,IAClB;AACF,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,eAAe,UAAU,GAAG,KAAK,IAAI,IAAI,kBAAkB;AACvE,QAAM,UACJ,KAAK,WACJ,MAAS;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,IACf;AAAA,IACA;AAAA,EACF;AACF,QAAM,OAAO,MAAS;AAAA,IACpB,KAAK;AAAA,IACL;AAAA,MACE,OAAO,MAAM;AAAA,MACb,MAAM,GAAG,MAAM,KAAK,QAAQ,CAAC;AAAA;AAAA,EAAO,cAAc,QAAQ,CAAC;AAAA;AAAA,MAC3D,UAAU,CAAC,OAAO;AAAA,IACpB;AAAA,IACA;AAAA,EACF;AACA,SAAO,EAAE,GAAG,MAAM,YAAY,GAAG,KAAK,IAAI,IAAI,GAAG;AACnD;AAGA,eAAsB,QACpB,OACA,MACA,QACA,GAC+D;AAC/D,QAAM,IAAI,MAAM;AAAA,IAGd;AAAA;AAAA;AAAA,IAGA,EAAE,OAAO,MAAM,OAAO;AAAA,IACtB;AAAA,EACF;AACA,QAAM,IAAI,GAAG,WAAW,SAAS;AACjC,SAAO,MAAM,OACT,OACA,EAAE,IAAI,EAAE,IAAI,QAAQ,EAAE,QAAQ,MAAM,EAAE,UAAU,OAAO;AAC7D;AAGA,eAAsB,YACpB,UACA,SACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASA,EAAE,SAAS,UAAU,YAAY,QAAQ;AAAA,IACzC;AAAA,EACF;AACF;AAGA,eAAsB,QACpB,SACA,MACA,GACe;AACf,QAAM;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWA,EAAE,WAAW,SAAS,KAAK;AAAA,IAC3B;AAAA,EACF;AACF;AAGA,eAAsB,eACpB,OACA,MACA,QACA,GACmD;AACnD,QAAM,IAAI,MAAM;AAAA,IAKd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,EAAE,OAAO,MAAM,OAAO;AAAA,IACtB;AAAA,EACF;AACA,QAAM,KAAK,GAAG,WAAW,aAAa,MAAM,CAAC;AAC7C,SAAO,OAAO,SAAY,OAAO,EAAE,QAAQ,GAAG,QAAQ,OAAO,GAAG,MAAM;AACxE;;;ACjMA,SAAS,OAAO,OAAO,MAAM,YAAAC,WAAU,MAAAC,KAAI,YAAY;AACvD,SAAS,eAAe;AACxB,SAAS,QAAAC,aAAY;;;ACGrB,IAAM,mBAAmB;AACzB,IAAM,aAAa;AACZ,IAAM,SAAS;AAEf,IAAM,cAAc;AAEpB,SAAS,WAAmB;AACjC,SAAO,QAAQ,IAAI,wBAAwB,KAAK;AAClD;AAQO,SAAS,cAAsB;AACpC,SAAO,wDAAwD,SAAS,CAAC;AAC3E;AAGO,SAAS,UAAkB;AAChC,UAAQ,QAAQ,IAAI,kBAAkB,KAAK,YAAY,QAAQ,QAAQ,EAAE;AAC3E;AAqBO,IAAM,aAAN,cAAyB,MAAM;AAAC;AAEhC,IAAM,kBAAN,cAA8B,MAAM;AAAC;AAE5C,SAASC,QAAO,GAAoB;AAClC,MAAI,aAAa,OAAO;AACtB,WAAO,EAAE,SAAS,iBAAiB,cAAc,EAAE;AAAA,EACrD;AACA,SAAO,OAAO,CAAC;AACjB;AAEA,eAAe,KACb,MACA,QACkC;AAClC,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,IAAI,IAAI;AAAA,MACvC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,gBAAgB;AAAA,QAChB,cAAc;AAAA,MAChB;AAAA,MACA,MAAM,IAAI,gBAAgB,MAAM,EAAE,SAAS;AAAA,MAC3C,QAAQ,YAAY,QAAQ,IAAM;AAAA,IACpC,CAAC;AAAA,EACH,SAAS,GAAG;AACV,UAAM,IAAI,MAAM,4BAA4BA,QAAO,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;AAAA,EACvE;AACA,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,IAAI,KAAK;AAAA,EACxB,SAAS,GAAG;AACV,UAAM,IAAI,MAAM,uBAAuB,IAAI,MAAM,QAAQ,IAAI,IAAI;AAAA,MAC/D,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,MAAI,SAAS,QAAQ,OAAO,SAAS;AACnC,UAAM,IAAI,MAAM,8CAA8C,IAAI,EAAE;AACtE,SAAO;AACT;AAEA,IAAM,MAAM,CAAC,MAA+B,OAAO,MAAM,WAAW,IAAI;AACxE,IAAM,MAAM,CAAC,MACX,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IAAI,IAAI;AAEpD,SAAS,SAAS,MAA+B,KAA8B;AAC7E,QAAM,cAAc,IAAI,KAAK,cAAc,CAAC;AAC5C,MAAI,gBAAgB,KAAM,QAAO;AACjC,QAAM,YAAY,IAAI,KAAK,YAAY,CAAC;AACxC,QAAM,YAAY,IAAI,KAAK,0BAA0B,CAAC;AACtD,SAAO;AAAA,IACL;AAAA,IACA,WAAW,cAAc,OAAO,OAAO,MAAM,YAAY;AAAA,IACzD,cAAc,IAAI,KAAK,eAAe,CAAC;AAAA,IACvC,kBAAkB,cAAc,OAAO,OAAO,MAAM,YAAY;AAAA,IAChE,QAAQ,IAAI,KAAK,OAAO,CAAC,KAAK;AAAA,EAChC;AACF;AAEA,eAAsB,kBACpB,SAAiB,QACI;AACrB,QAAM,KAAK,SAAS;AACpB,MAAI,OAAO;AACT,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,QAAM,OAAO,MAAM,KAAK,sBAAsB;AAAA,IAC5C,WAAW;AAAA,IACX,OAAO;AAAA,EACT,CAAC;AACD,QAAM,aAAa,IAAI,KAAK,aAAa,CAAC;AAC1C,QAAM,WAAW,IAAI,KAAK,WAAW,CAAC;AACtC,QAAM,kBAAkB,IAAI,KAAK,kBAAkB,CAAC;AACpD,MAAI,eAAe,QAAQ,aAAa,QAAQ,oBAAoB,MAAM;AACxE,UAAM,QAAQ,IAAI,KAAK,OAAO,CAAC;AAC/B,UAAM,IAAI;AAAA,MACR,UAAU,yBACN,2DACA,wCAAwC,UAAU,OAAO,KAAK,KAAK,KAAK,GAAG;AAAA,IACjF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,IAAI,KAAK,YAAY,CAAC,KAAK;AAAA,IACtC,UAAU,IAAI,KAAK,UAAU,CAAC,KAAK;AAAA,EACrC;AACF;AAQA,eAAsB,aACpB,MACA,OAAiB,CAAC,GACC;AACnB,QAAM,QACJ,KAAK,UAAU,CAAC,OAAe,IAAI,QAAc,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC3E,QAAM,MAAM,KAAK,OAAO,KAAK;AAC7B,QAAM,WAAW,IAAI,IAAI,KAAK,YAAY;AAC1C,MAAI,WAAW,KAAK;AACpB,aAAS;AACP,UAAM,MAAM,WAAW,GAAI;AAC3B,UAAM,OAAO,MAAM,KAAK,6BAA6B;AAAA,MACnD,WAAW,SAAS;AAAA,MACpB,aAAa,KAAK;AAAA,MAClB,YAAY;AAAA,IACd,CAAC;AACD,UAAM,SAAS,SAAS,MAAM,IAAI,CAAC;AACnC,QAAI,WAAW,KAAM,QAAO;AAC5B,UAAM,QAAQ,IAAI,KAAK,OAAO,CAAC;AAC/B,QAAI,UAAU,yBAAyB;AACrC,UAAI,IAAI,IAAI;AACV,cAAM,IAAI,WAAW,yCAAyC;AAChE;AAAA,IACF;AACA,QAAI,UAAU,aAAa;AACzB,kBAAY,IAAI,KAAK,UAAU,CAAC,KAAK,YAAY;AACjD;AAAA,IACF;AACA,QAAI,UAAU;AACZ,YAAM,IAAI,WAAW,yCAAyC;AAChE,QAAI,UAAU;AACZ,YAAM,IAAI,WAAW,uCAAuC;AAC9D,UAAM,IAAI,WAAW,iCAAiC,SAAS,SAAS,GAAG;AAAA,EAC7E;AACF;AAGA,eAAsB,gBACpB,cACA,MAAoB,KAAK,KACN;AACnB,QAAM,OAAO,MAAM,KAAK,6BAA6B;AAAA,IACnD,WAAW,SAAS;AAAA,IACpB,YAAY;AAAA,IACZ,eAAe;AAAA,EACjB,CAAC;AACD,QAAM,SAAS,SAAS,MAAM,IAAI,CAAC;AACnC,MAAI,WAAW,KAAM,QAAO;AAC5B,QAAM,IAAI,gBAAgB,IAAI,KAAK,OAAO,CAAC,KAAK,SAAS;AAC3D;;;ADhLO,SAAS,YAAoB;AAClC,QAAM,MAAM,QAAQ,IAAI,iBAAiB;AACzC,MAAI,QAAQ,UAAa,QAAQ,GAAI,QAAOC,MAAK,KAAK,OAAO;AAC7D,QAAM,UAAU,QAAQ,IAAI,SAAS;AACrC,MAAI,QAAQ,aAAa,WAAW,YAAY,UAAa,YAAY;AACvE,WAAOA,MAAK,SAAS,OAAO;AAC9B,SAAOA,MAAK,QAAQ,GAAG,WAAW,OAAO;AAC3C;AAEA,IAAM,WAAW,MAAcA,MAAK,UAAU,GAAG,WAAW;AAC5D,IAAM,WAAW,MAAcA,MAAK,UAAU,GAAG,WAAW;AAE5D,SAAS,WAAW,GAA2B;AAC7C,MAAI,MAAM,QAAQ,OAAO,MAAM,SAAU,QAAO;AAChD,QAAM,IAAI;AACV,SAAO,OAAO,EAAE,aAAa,MAAM,YAAY,EAAE,aAAa,MAAM;AACtE;AAEA,eAAsB,WAAwC;AAC5D,MAAI;AACF,UAAM,SAAkB,KAAK,MAAM,MAAMC,UAAS,SAAS,GAAG,MAAM,CAAC;AACrE,UAAM,QACJ,WAAW,QAAQ,OAAO,WAAW,WAChC,OAAmC,YAAY,IAChD;AACN,QAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,UAAM,EAAE,OAAO,OAAO,IAAI;AAC1B,QAAI,OAAO,UAAU,YAAY,CAAC,WAAW,MAAM,EAAG,QAAO;AAC7D,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,QACN,aAAa,OAAO;AAAA,QACpB,WAAW,OAAO,aAAa;AAAA,QAC/B,cAAc,OAAO,gBAAgB;AAAA,QACrC,kBAAkB,OAAO,oBAAoB;AAAA,QAC7C,QAAQ,OAAO,UAAU;AAAA,MAC3B;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,UAAU,OAAmC;AACjE,QAAM,MAAM,UAAU;AACtB,QAAM,MAAM,KAAK,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACjD,QAAM,OAAO,SAAS;AACtB,QAAM;AAAA,IACJ;AAAA,IACA,GAAG,KAAK,UAAU,EAAE,cAAc,MAAM,GAAG,MAAM,CAAC,CAAC;AAAA;AAAA,EACrD;AACA,QAAM,MAAM,MAAM,GAAK;AACzB;AAEA,eAAsB,YAA2B;AAC/C,QAAMC,IAAG,SAAS,GAAG,EAAE,OAAO,KAAK,CAAC;AACtC;AAYO,SAAS,WAAiC;AAC/C,aAAW,UAAU,CAAC,gBAAgB,UAAU,GAAY;AAC1D,UAAM,QAAQ,QAAQ,IAAI,MAAM;AAChC,QAAI,UAAU,UAAa,UAAU;AACnC,aAAO,EAAE,OAAO,QAAQ,OAAO,KAAK;AAAA,EACxC;AACA,SAAO;AACT;AAGA,IAAM,oBAAoB,IAAI;AAC9B,IAAM,eAAe;AACrB,IAAM,gBAAgB;AAQtB,IAAM,QAAQ,CAAC,QAAkB,QAC/B,OAAO,cAAc,QAAQ,OAAO,YAAY,MAAM;AAOxD,eAAe,SAAY,MAA2C;AACpE,QAAM,MAAM,UAAU,GAAG,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACzD,QAAM,OAAO,SAAS;AACtB,QAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,aAAS;AACP,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,MAAM,IAAI;AACpC,YAAM,OAAO,MAAM;AACnB;AAAA,IACF,SAAS,GAAG;AACV,UAAK,EAA4B,SAAS,SAAU,OAAM;AAC1D,YAAM,MAAM,MAAM,KAAK,IAAI,EAAE;AAAA,QAC3B,CAAC,MAAM,KAAK,IAAI,IAAI,EAAE;AAAA,QACtB,MAAM;AAAA,MACR;AACA,UAAI,MAAM,cAAe,OAAMA,IAAG,MAAM,EAAE,OAAO,KAAK,CAAC;AAAA,eAC9C,KAAK,IAAI,IAAI,SAAU,QAAO;AAAA,UAClC,OAAM,IAAI,QAAc,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAAA,IACvD;AAAA,EACF;AACA,MAAI;AACF,WAAO,MAAM,KAAK;AAAA,EACpB,UAAE;AACA,UAAMA,IAAG,MAAM,EAAE,OAAO,KAAK,CAAC;AAAA,EAChC;AACF;AAQA,eAAsB,aACpB,OAAoB,CAAC,GACU;AAC/B,QAAM,MAAM,SAAS;AACrB,MAAI,QAAQ,KAAM,QAAO;AACzB,QAAM,MAAM,KAAK,OAAO,KAAK;AAC7B,QAAM,SAAS,MAAM,SAAS;AAC9B,MAAI,WAAW,KAAM,QAAO;AAC5B,QAAM,SAAS,CAAC,OAAmC;AAAA,IACjD,OAAO,EAAE,OAAO;AAAA,IAChB,QAAQ;AAAA,IACR,OAAO,EAAE;AAAA,EACX;AACA,MAAI,MAAM,OAAO,QAAQ,IAAI,CAAC,EAAG,QAAO,OAAO,MAAM;AAErD,QAAM,YAAY,MAAM,SAAS,YAAyC;AAExE,UAAM,UAAU,MAAM,SAAS;AAC/B,QAAI,YAAY,KAAM,QAAO;AAC7B,QAAI,MAAM,QAAQ,QAAQ,IAAI,CAAC,EAAG,QAAO;AACzC,QAAI,QAAQ,OAAO,iBAAiB,KAAM,QAAO;AACjD,QAAI;AACF,YAAM,SAAS,MAAM,gBAAgB,QAAQ,OAAO,cAAc,GAAG;AACrE,YAAM,OAAO,EAAE,OAAO,QAAQ,OAAO,OAAO;AAC5C,YAAM,UAAU,IAAI;AACpB,aAAO;AAAA,IACT,SAAS,GAAG;AACV,UAAI,aAAa,iBAAiB;AAChC,cAAM,UAAU;AACf,SAAC,KAAK,WAAW,CAAC,MAAM,QAAQ,OAAO,MAAM,GAAG,CAAC;AAAA,CAAI;AAAA,UACpD,kCAAkC,aAAa,CAAC;AAAA,QAClD;AACA,eAAO;AAAA,MACT;AAEA,YAAM,YAAY,QAAQ,OAAO;AACjC,aAAO,cAAc,QAAQ,YAAY,IAAI,IAAI,UAAU;AAAA,IAC7D;AAAA,EACF,CAAC;AACD,SAAO,cAAc,OAAO,OAAO,OAAO,SAAS;AACrD;;;AE9LA,SAAS,kBAAkB;AAC3B,SAAS,SAAAC,cAAa;AAYf,IAAM,aAAa;AAenB,SAAS,SAAS,MAAc,KAAqB;AAC1D,SAAO,KAAK,IAAI,uBAAoB,QAAQ,KAAK,IAAI,CAAC;AACxD;AAEA,IAAM,SAAS,CAAC,SACd,WAAW,QAAQ,EAAE,OAAO,MAAM,MAAM,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AACrE,IAAMC,WAAU,CAAC,MAAsB,cAAc,CAAC;AAEtD,IAAM,OAAO;AAAA;AAAA,EAAOA,SAAQ,IAAI,OAAO,EAAE,CAAC,CAAC,GAAG;AAC9C,IAAM,YAAY;AAOX,SAAS,SAAS,MAA6B;AACpD,QAAM,OAAO,KAAK,QAAQ,UAAU,IAAI;AACxC,QAAM,IAAI,UAAU,KAAK,IAAI;AAC7B,QAAM,IAAI,IAAI,CAAC;AACf,MAAI,MAAM,QAAQ,MAAM,OAAW,QAAO;AAC1C,SAAO,OAAO,KAAK,MAAM,GAAG,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;AACpD;AAEA,IAAM,SAAS;AACf,IAAM,SAAS;AAGf,SAAS,OAAO,OAAqC;AACnD,QAAM,OAAkB,CAAC;AACzB,MAAIC,OAAqB;AACzB,aAAW,QAAQ,OAAO;AACxB,QAAIA,SAAQ,MAAM;AAChB,YAAM,IAAI,OAAO,KAAK,IAAI;AAC1B,YAAMC,SAAQ,IAAI,CAAC;AAEnB,UACEA,WAAU,UACV,EAAEA,OAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,IAAI,SAAS,GAAG;AAEtD,QAAAD,OAAMC;AACR,WAAK,KAAKD,SAAQ,IAAI;AACtB;AAAA,IACF;AACA,SAAK,KAAK,IAAI;AACd,UAAM,QAAQ,OAAO,KAAK,IAAI,IAAI,CAAC;AACnC,QACE,UAAU,UACV,MAAM,CAAC,MAAMA,KAAI,CAAC,KAClB,MAAM,UAAUA,KAAI;AAEpB,MAAAA,OAAM;AAAA,EACV;AACA,SAAO;AACT;AAEA,IAAM,QAAQ;AAGd,SAAS,aAAa,OAAoC;AACxD,QAAM,OAAO,OAAO,KAAK;AACzB,QAAM,KAAK,MAAM,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,MAAM,QAAQ,MAAM,KAAK,IAAI,CAAC;AAC5E,MAAI,KAAK,EAAG,QAAO,CAAC,GAAG,KAAK;AAC5B,MAAI,MAAM,KAAK;AACf,SAAO,MAAM,MAAM,WAAW,MAAM,GAAG,KAAK,IAAI,KAAK,MAAM,GAAI;AAC/D,SAAO,CAAC,GAAG,MAAM,MAAM,GAAG,EAAE,GAAG,GAAG,MAAM,MAAM,GAAG,CAAC;AACpD;AAEA,IAAM,SAAS;AACf,IAAM,QAAQ;AAEd,IAAM,UAAU,CAAC,SAAyB;AACxC,MAAI;AACF,WAAO,UAAU,IAAI;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,OAAO,MAAc,GAAuB;AACnD,QAAM,MAAM,KAAK,WAAW,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI;AACvD,MACE,QAAQ,MACR,OAAO,KAAK,GAAG,KACf,IAAI,WAAW,IAAI,KACnB,IAAI,WAAW,GAAG;AAElB,WAAO;AACT,QAAM,OAAO,IAAI,QAAQ,GAAG;AAC5B,QAAM,WAAW,OAAO,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI;AACnD,QAAM,SAAS,OAAO,IAAI,KAAK,IAAI,MAAM,IAAI;AAC7C,QAAM,OAAO;AAAA,IACXE,OAAM;AAAA,MACJ,SAAS,WAAW,GAAG,IACnB,SAAS,MAAM,CAAC,IAChBA,OAAM,KAAKA,OAAM,QAAQ,EAAE,IAAI,GAAG,QAAQ;AAAA,IAChD;AAAA,EACF;AACA,QAAM,SAAS,EAAE,QAAQ,IAAI,IAAI;AACjC,MAAI,WAAW,OAAW,QAAO,SAAS,EAAE,KAAK,MAAM;AACvD,MAAI,CAAC,EAAE,MAAM,IAAI,IAAI,EAAG,QAAO;AAC/B,SAAO,GAAG,QAAQ,EAAE,KAAK,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,IAAI,cAAc,EAAE,GAAG,MAAM;AAC/E;AAOA,IAAM,YAAY,IAAI;AAAA,EACpB;AAAA,IACE,uCAAuC;AAAA,IACvC,kBAAkB;AAAA,IAClB,qCAAqC;AAAA,IACrC,4DAA4D;AAAA,IAC5D,wCAAwC;AAAA,IACxC,kDAAkD;AAAA,EACpD,EAAE,KAAK,GAAG;AAAA,EACV;AACF;AAEA,IAAM,UAAU;AAChB,IAAM,YAAY;AAClB,IAAM,OAAO;AAGb,IAAM,UAAU,CAAC,SACf,KAAK,QAAQ,SAAS,SAAS,EAAE,QAAQ,WAAW,MAAM,IAAI,IAAI;AAEpE,SAAS,OAAO,MAAc,GAAuB;AACnD,MAAI,MAAM;AACV,MAAI,OAAO;AACX,aAAW,KAAK,KAAK,SAAS,SAAS,GAAG;AACxC,UAAM,KAAK,EAAE,SAAS;AACtB,WAAO,QAAQ,KAAK,MAAM,MAAM,EAAE,CAAC;AACnC,UAAM,OAAO,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,KAAK;AACnD,WACE,SAAS,SACL,EAAE,CAAC,IACH,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EAAE,SAAS,KAAK,MAAM,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC;AACnE,WAAO,KAAK,EAAE,CAAC,EAAE;AAAA,EACnB;AACA,SAAO,MAAM,QAAQ,KAAK,MAAM,IAAI,CAAC;AACvC;AAGA,SAAS,QAAQ,OAA0B,GAAyB;AAClE,QAAM,OAAO,OAAO,KAAK;AACzB,QAAM,MAAgB,CAAC;AACvB,MAAI,YAAsB,CAAC;AAC3B,QAAM,QAAQ,MAAY;AACxB,QAAI,UAAU,SAAS,EAAG,KAAI,KAAK,OAAO,UAAU,KAAK,IAAI,GAAG,CAAC,CAAC;AAClE,gBAAY,CAAC;AAAA,EACf;AACA,QAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,QAAI,KAAK,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,IAAI;AAC1C,YAAM;AACN,UAAI,KAAK,IAAI;AAAA,IACf,MAAO,WAAU,KAAK,IAAI;AAAA,EAC5B,CAAC;AACD,QAAM;AACN,SAAO;AACT;AAOA,SAAS,IAAI,MAAc,MAAsB;AAC/C,QAAM,OAAO,aAAa,OAAO,IAAI,KAAK;AAC1C,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,OAAO,OAAO,KAAK;AACzB,MAAI,SAAS;AACb,MAAI,KAAK;AACT,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAU,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI;AACnC,QAAI,SAAS,KAAM;AACnB,QAAI,KAAK,CAAC,MAAM,SAAS,MAAM,CAAC,KAAK,IAAI,KAAK,MAAM,GAAI,MAAK;AAAA,EAC/D;AACA,SAAO,GAAG,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,EAAE,QAAQ,CAAC;AAAA;AAAA,EAAO,IAAI;AAC9D;AAEO,SAAS,UAAU,GAAuB;AAC/C,QAAM,QAAQ;AAAA,IACZ,iBAAiB,EAAE,KAAK,QAAQ,UAAU,IAAI,CAAC,EAAE,MAAM,IAAI;AAAA,EAC7D;AACA,QAAM,UAAU,QAAQ,OAAO,CAAC,EAC7B,KAAK,IAAI,EACT,QAAQ,kBAAkB,EAAE,EAC5B,QAAQ;AACX,QAAM,SAAS,SAAS,EAAE,MAAM,EAAE,GAAG;AACrC,QAAM,QAAQ,YAAY,KAAK,SAAS,GAAG,MAAM;AAAA;AAAA,EAAO,OAAO;AAC/D,QAAM,OACJ,MAAM,SAAS,QAAQ,aACnB,QACA,IAAI,OAAO,aAAa,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE;AACtD,SAAO,GAAG,IAAI;AAAA;AAAA,EAAOH,SAAQ,OAAO,IAAI,CAAC,CAAC;AAC5C;;;ACnOA,SAAS,YAAAI,WAAU,WAAAC,gBAAe;AAClC,SAAS,QAAAC,aAAY;AAcrB,IAAMC,eAAoC,CAAC,QAAQ,QAAQ,UAAU,QAAQ;AA4B7E,IAAM,QAAQ,IAAI;AAAA,EAChB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAC9B;AAEA,IAAMC,YAAW,CAAC,MAChB,MAAM,QAAQ,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC;AAEzD,IAAMC,WAAU,CAAC,MACf,MAAM,QAAQ,CAAC,KACf,EAAE,MAAM,CAAC,MAAM,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,EAAE,KACvD,IAAI,IAAI,CAAC,EAAE,SAAS,EAAE;AAExB,eAAe,SAAS,MAAsC;AAC5D,MAAI;AACF,WAAO,MAAMC,UAAS,MAAM,MAAM;AAAA,EACpC,SAAS,GAAG;AACV,QAAK,EAA4B,SAAS,SAAU,QAAO;AAC3D,UAAM;AAAA,EACR;AACF;AAEA,SAASC,WAAU,OAAe,MAAc,OAA+B;AAC7E,QAAM,MAAM,UAAU,IAAI;AAC1B,MAAI,MAAM,IAAI,KAAK,YAAY,CAAC;AAC9B,UAAM,IAAI,MAAM,GAAG,KAAK,MAAM,GAAG,0CAA0C;AAC7E,MAAI,CAACH,UAAS,KAAK;AACjB,UAAM,IAAI,MAAM,GAAG,KAAK,6CAA6C;AACvE,QAAM,OAAOD,aAAY,KAAK,CAAC,MAAM,MAAM,MAAM,MAAM,CAAC;AACxD,MAAI,SAAS;AACX,UAAM,IAAI;AAAA,MACR,GAAG,KAAK,MAAM,GAAG,yBAAyBA,aAAY,KAAK,IAAI,CAAC;AAAA,IAClE;AACF,QAAM,MAAM,MAAM,MAAM;AACxB,QAAM,OAAO,OAAO,QAAQ,YAAY,QAAQ,KAAK,CAAC,GAAG,IAAI;AAC7D,MAAI,CAACE,SAAQ,IAAI,KAAK,KAAK,WAAW;AACpC,UAAM,IAAI;AAAA,MACR,GAAG,KAAK,MAAM,GAAG;AAAA,IACnB;AACF,QAAM,UAAU,MAAM,SAAS,KAAK,CAAC;AACrC,MAAI,CAACA,SAAQ,OAAO,KAAK,EAAE,MAAM,QAAQ,OAAO,KAAK,QAAQ,WAAW;AACtE,UAAM,IAAI,MAAM,GAAG,KAAK,MAAM,GAAG,mCAAmC;AACtE,SAAO,EAAE,MAAM,MAAM,MAAM,SAAS,CAAC,GAAI,OAAoB,EAAE;AACjE;AAEA,SAASG,YAAW,OAAe,OAAoC;AACrE,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM;AAChD,UAAM,IAAI;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AACF,SAAO,UAAU,cACb,EAAE,MAAM,YAAY,IACpB,EAAE,MAAM,OAAO,KAAK,MAAM;AAChC;AAGA,eAAsB,UACpB,UACA,YAC0B;AAC1B,QAAM,QAAQ,GAAG,UAAU;AAC3B,QAAM,OAAO,MAAM,SAASC,MAAK,UAAU,YAAY,WAAW,CAAC;AACnE,MAAI,SAAS;AACX,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,UAAU;AAAA,MACV,QAAQ,CAAC;AAAA,MACT,QAAQ;AAAA,IACV;AACF,MAAI;AACJ,MAAI;AACF,YAAQ,iBAAiB,IAAI;AAAA,EAC/B,SAAS,GAAG;AACV,UAAM,IAAI,MAAM,GAAG,KAAK,KAAK,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,IAAI;AAAA,MACzE,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,QAAM,IAAI,SAAS,CAAC;AACpB,QAAM,cAAc,EAAE,aAAa,KAAK;AACxC,MAAI,gBAAgB,QAAQ,OAAO,gBAAgB;AACjD,UAAM,IAAI,MAAM,GAAG,KAAK,8BAA8B;AACxD,QAAM,WAAW,EAAE,UAAU,KAAK;AAClC,MAAI,aAAa,QAAQ,CAACJ,SAAQ,QAAQ;AACxC,UAAM,IAAI,MAAM,GAAG,KAAK,sCAAsC;AAChE,QAAMK,UAAS,EAAE,QAAQ,KAAK,CAAC;AAC/B,MAAI,CAACN,UAASM,OAAM;AAClB,UAAM,IAAI,MAAM,GAAG,KAAK,6CAA6C;AACvE,SAAO;AAAA,IACL,QAAQ,iBAAiB,IAAI;AAAA,IAC7B,aAAa,gBAAgB,OAAO,OAAO,YAAY,KAAK;AAAA,IAC5D,UAAU,aAAa,OAAO,OAAO,CAAC,GAAG,QAAQ;AAAA,IACjD,QAAQ,OAAO,QAAQA,OAAM,EAAE;AAAA,MAAI,CAAC,CAAC,MAAM,CAAC,MAC1CH,WAAU,OAAO,MAAM,CAAC;AAAA,IAC1B;AAAA,IACA,QAAQC,YAAW,OAAO,EAAE,QAAQ,CAAC;AAAA,EACvC;AACF;AAGA,SAAS,MAAM,OAA+B;AAC5C,MAAI,iBAAiB,QAAQ,CAAC,OAAO,MAAM,MAAM,QAAQ,CAAC;AACxD,WAAO,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AACxC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,MAAM,iCAAiC,KAAK,MAAM,KAAK,CAAC,IAAI,CAAC;AACnE,SAAO,OAAO;AAChB;AAEA,SAAS,QAAQ,OAAsBE,SAA+B;AACpE,QAAM,MAAM,MAAM,KAAK;AAAA,IACrB,CAAC,MAAMA,QAAO,CAAC,MAAM,UAAaA,QAAO,CAAC,MAAM,QAAQA,QAAO,CAAC,MAAM;AAAA,EACxE;AACA,MAAI,QAAQ,OAAW,QAAO;AAC9B,QAAM,MAAMA,QAAO,GAAG;AACtB,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO,MAAM,GAAG;AAAA,IAClB,KAAK,UAAU;AACb,YAAM,IAAI,OAAO,QAAQ,WAAW,MAAM,OAAO,GAAG;AACpD,aAAO,OAAO,QAAQ,aAAa,OAAO,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI;AAAA,IACtE;AAAA,IACA;AACE,UAAI,MAAM,QAAQ,GAAG,EAAG,QAAO,IAAI,IAAI,MAAM,EAAE,KAAK,IAAI;AACxD,aAAO,OAAO,QAAQ,WAAW,OAAO,OAAO,GAAG;AAAA,EACtD;AACF;AAOO,SAAS,SACd,OACAA,SACA,KAC6D;AAC7D,QAAMC,UAAS,OAAO;AAAA,IACpB,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,QAAQ,GAAGD,OAAM,CAAC,CAAC;AAAA,EACtD;AACA,QAAM,SAAmB,CAAC;AAC1B,MAAI,MAAM,QAAQ,SAAS,aAAa;AACtC,UAAM,QAAQ,IAAI,QAAQ,GAAG;AAC7B,QAAI,QAAQ,EAAG,QAAO,KAAK,IAAI,MAAM,GAAG,KAAK,CAAC;AAAA,EAChD,WAAW,MAAM,QAAQ,SAAS,OAAO;AACvC,UAAM,MAAMA,QAAO,MAAM,OAAO,GAAG;AACnC,eAAW,KAAK,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG;AAC7C,UAAI,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,MAAM,CAAC,OAAO,SAAS,CAAC;AAChE,eAAO,KAAK,EAAE,KAAK,CAAC;AAAA,EAC1B;AACA,SAAO,EAAE,QAAAC,SAAQ,OAAO;AAC1B;AAIA,IAAM,UAA6B;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAaA,eAAsB,YACpB,UACA,KACyB;AACzB,MAAI;AACJ,MAAI;AACJ,MAAI;AAGF,SAAK,MAAM,cAAc,UAAU,GAAG;AACtC,aACE,MAAMC,SAAQ,IAAI;AAAA,MAChB,eAAe;AAAA,IACjB,CAAC,GAEA,OAAO,CAAC,MAAM,EAAE,OAAO,KAAK,EAAE,KAAK,SAAS,KAAK,CAAC,EAClD,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK;AAAA,EACV,SAAS,GAAG;AACV,QAAK,EAA4B,SAAS,SAAU,QAAO,CAAC;AAC5D,UAAM;AAAA,EACR;AACA,QAAM,UAA0B,CAAC;AACjC,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,GAAG,GAAG,IAAI,IAAI;AAC3B,UAAM,OAAQ,MAAM,SAASH,MAAK,IAAI,IAAI,CAAC,KAAM;AACjD,QAAI;AACJ,QAAI;AACF,cAAQ,iBAAiB,IAAI;AAAA,IAC/B,SAAS,GAAG;AACV,YAAM,IAAI;AAAA,QACR,GAAG,IAAI,KAAK,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,QACtD;AAAA,UACE,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,MAAM,QAAQ,QAAQ,CAAC;AAC1D,QAAI,WAAW;AACb,YAAM,IAAI,MAAM,GAAG,IAAI,6BAA6B,QAAQ,KAAK,IAAI,CAAC,EAAE;AAC1E,YAAQ,KAAK;AAAA,MACX;AAAA,MACA;AAAA,MACA,WAAW,MAAM,QAAQ,YAAY,CAAC;AAAA,MACtC,YAAY,MAAM,QAAQ,aAAa,CAAC;AAAA,MACxC,MAAM,iBAAiB,IAAI;AAAA,IAC7B,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;AChMA,IAAMI,YAAW,CAACC,YAChBA,YAAW,QAAQA,YAAW,MAAM,OAAOA;AAG7C,IAAM,YAAY;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,cAAc;AAAA,EAClB,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AACV;AAOO,SAAS,YACd,QACA,MACA,MACoB;AACpB,QAAM,WAAW,OAAO,IAAI;AAC5B,MAAI,aAAa,OAAW,QAAO;AACnC,MAAI,SAAS,aAAc,QAAO;AAClC,MAAI,SAAS,WAAY,QAAO;AAChC,QAAM,OAAO,WAAW,IAAI;AAC5B,SAAO,SAAS,YAAY,SAAS,YAAY,IAAI;AACvD;AAGO,IAAM,kBAAkB,CAAC,UAA0B,GAAG,KAAK;AAGlE,IAAM,mBAAmB,CAAC,UAAsC;AAC9D,QAAM,MAAM,IAAI,IAAI,KAAK;AACzB,SAAO;AAAA,IACL,GAAG,UAAU,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;AAAA,IACrC,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,SAAS,CAAC,CAAC;AAAA,EAClD;AACF;AAGA,IAAM,OAAO,CAACC,YAAuC,CAAC,GAAG,IAAI,IAAIA,OAAM,CAAC;AAExE,IAAM,UAAU,CAAC,QACf,IAAI,KACD,IAAI,CAAC,QAAQF,UAAS,IAAI,MAAM,CAAC,EACjC,OAAO,CAAC,MAAmB,MAAM,IAAI;AAG1C,IAAM,QAAQ,CAAC,MAA4B,SACzC,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK,EAAE,MAAM,OAAO,QAAQ,IAAI,GAAG,MAAM,CAAC,EAAE;AAQvE,SAAS,cACd,OACA,MACA,QAAyC,MAAM,OAC5B;AACnB,MAAI,MAAM,gBAAgB;AACxB,WAAO,KACJ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC5B,IAAI,CAAC,QAAQ;AACZ,YAAM,WAAW,iBAAiB;AAAA,QAChC,GAAI,WAAW,IAAI,IAAI,KAAK,CAAC;AAAA,QAC7B,GAAG,QAAQ,GAAG;AAAA,MAChB,CAAC;AAED,aAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,OAAO,IAAI;AAAA,QACX;AAAA,QACA,OAAO,SAAS,SAAS,IAAI,gBAAgB,IAAI,KAAK,IAAI;AAAA,QAC1D;AAAA,MACF;AAAA,IACF,CAAC;AACL,SAAO,OAAO,QAAQ,MAAM,WAAW,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM;AAC1D,UAAM,MAAM,MAAM,MAAM,IAAI;AAC5B,UAAM,QAAQ,QAAQ,GAAG;AACzB,WAAO;AAAA,MACL;AAAA,MACA,OAAO,EAAE;AAAA,MACT,UACE,EAAE,aAAa,aACX,iBAAiB,CAAC,GAAI,WAAW,IAAI,KAAK,CAAC,GAAI,GAAG,KAAK,CAAC,IACxD,EAAE,aAAa,UACb,iBAAiB,KAAK,IACtB,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,KAAK,CAAC;AAAA,MACtC,OAAO,EAAE;AAAA,MACT,KAAK,EAAE,GAAG,KAAK,OAAO,EAAE,MAAM;AAAA,IAChC;AAAA,EACF,CAAC;AACH;AAGA,IAAM,kBAAkB,CAAC,UACvB,OAAO,QAAQ,MAAM,MAAM,EAAE;AAAA,EAC3B,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,KAAK,SAAS,aAAa;AACjE,IAAI,CAAC,KAAK;AAGL,IAAM,mBAAmB,CAAC,OAAe,UAC9C,GAAG,MAAM,YAAY,CAAC,KAAK,KAAK;AAOlC,SAAS,QACP,OACA,aACc;AACd,QAAM,QAAQ,gBAAgB,KAAK;AACnC,QAAM,oBAAoB,CAAC,SACzB,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,GAAG,SAAS,QAAQ,IAAI;AACjE,QAAMG,SAAsB,MAAM,MAAM,IAAI,CAAC,OAAO;AAAA,IAClD,MAAM,EAAE;AAAA,IACR,QAAQ,EAAE;AAAA,IACV,QACE;AAAA,MACE,EAAE,eAAe,QAAQ,UAAU,OAC/B,OACA,iBAAiB,OAAO,kBAAkB,EAAE,UAAU,CAAC;AAAA,MAC3D,EAAE;AAAA,IACJ,EACG,OAAO,CAAC,MAAmB,MAAM,IAAI,EACrC,KAAK,GAAG,KAAK;AAAA,IAClB,SAAS,EAAE,WAAW,UAAW,EAAE,WAAW,WAAY;AAAA,IAC1D,QAAQ,EAAE;AAAA,EACZ,EAAE;AACF,MAAI,MAAM,gBAAgB,SAAS,UAAU,KAAM,QAAOA;AAC1D,QAAM,QAAQ,IAAI;AAAA,IAChB,MAAM,MAAM,QAAQ,CAAC,MAAO,EAAE,eAAe,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,CAAE;AAAA,EAC1E;AACA,QAAM,QAAQ,YACX,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,IAAI,CAAC,EAChC,IAAI,CAAC,OAAO;AAAA,IACX,MAAM,EAAE;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ,iBAAiB,OAAO,EAAE,KAAK;AAAA,IACvC,SAAS,EAAE,SAAS;AAAA,IACpB,QAAQ;AAAA,EACV,EAAE;AACJ,QAAM,OAAO,MAAM,MAAM,cAAc,CAAC,MAAM,EAAE,eAAe,IAAI;AACnE,EAAAA,OAAM,OAAO,OAAO,GAAG,GAAG,GAAG,KAAK;AAClC,SAAOA;AACT;AAEA,IAAM,WAAW,CAAC,SAA0B,KAAK,WAAW,GAAG;AAG/D,IAAM,aAAa,CAAC,MAAc,OAAwC;AAAA,EACxE;AAAA,EACA,MAAM,EAAE;AAAA,EACR,MAAM,EAAE;AAAA,EACR,SAAS,EAAE;AACb;AAGO,SAAS,SACd,OACA,aACA,MACQ;AACR,QAAM,WACJ,YAAY,WAAW,IAClB,YAAY,CAAC,GAAG,YAAY,CAAC,IAC9B,iBAAiB,YAAY,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;AAC7D,QAAMC,UAAwB,CAAC;AAC/B,QAAM,WAAW,OAAO,QAAQ,MAAM,MAAM;AAE5C,aAAW,CAAC,MAAM,CAAC,KAAK;AACtB,QAAI,EAAE,SAAS,YAAY,EAAE,KAAK,CAAC,MAAM;AACvC,MAAAA,QAAO,KAAK;AAAA,QACV;AAAA,QACA,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,YAAY,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,QACvC,SAAS;AAAA,MACX,CAAC;AACL,aAAW,KAAK;AACd,QAAI,EAAE,UAAU,QAAQ,EAAE,SAAS,SAAS;AAC1C,MAAAA,QAAO,KAAK;AAAA,QACV,MAAM,EAAE;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,EAAE;AAAA,QACX,SAAS;AAAA,MACX,CAAC;AACL,aAAW,CAAC,MAAM,CAAC,KAAK,UAAU;AAChC,QAAI,EAAE,SAAS,YAAY,EAAE,KAAK,CAAC,MAAM,cAAe;AACxD,QAAI,EAAE,SAAS,UAAU;AACvB,MAAAA,QAAO,KAAK,EAAE,MAAM,MAAM,EAAE,KAAK,CAAC;AAClC;AAAA,IACF;AACA,UAAMH,UAAS,EAAE,KAAK,CAAC,MAAM;AAC7B,IAAAG,QAAO,KAAK;AAAA,MACV;AAAA,MACA,MAAM;AAAA,MACN,MAAMH,UAAS,WAAW;AAAA,MAC1B,SAASA,UACL,WACA,KAAK;AAAA,QACH,GAAG,EAAE;AAAA,QACL,GAAG,KACA,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,EACzB,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAAA,MACrD,CAAC;AAAA,MACL,SAAS,CAAC,EAAE,KAAK,MAAM,QAAQ;AAAA,IACjC,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL;AAAA,IACA,QAAAG;AAAA,IACA,OAAO,QAAQ,OAAO,WAAW;AAAA;AAAA;AAAA,IAGjC,QAAQ,KAAK,KAAK,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;AAAA,IAC1C,QAAQ,MAAM;AAAA,EAChB;AACF;AAEA,IAAMC,cAAa,CAAC,QAClB,IAAI,UACA,IAAI,CAAC,MAAO,EAAE,UAAU,SAAY,EAAE,KAAK,GAAG,EAAE,KAAK,SAAM,EAAE,EAAE,EAAG,EACnE,KAAK,IAAI,KAAK;AAGZ,IAAM,mBAAmB,CAAC,UAC/B,MAAM,WAAW,QACjB,OAAO,OAAO,MAAM,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAQnE,SAAS,UACd,OACA,aACA,KACA,SAAsC,oBAAI,IAAI,GAC9C,cAAsD,oBAAI,IAAI,GACnD;AACX,QAAM,UAAU,OAAO,QAAQ,MAAM,MAAM,EAAE;AAAA,IAC3C,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,SAAS,QAAQ,KAAK,CAAC,EAAE,KAAK,SAAS,UAAU;AAAA,EACtE;AACA,QAAM,QAAQ;AAAA,IACZ,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,UAAU;AAAA,IACV,QAAQ,QACL,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,MAAM,QAAQ,CAAC,EACzC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,WAAW,MAAM,CAAC,CAAC;AAAA,IACzC,QAAQ,MAAM;AAAA,EAChB;AACA,QAAM,SAAS,YAAY;AAAA,IAAQ,CAAC,MAClC,EAAE,IAAI,KAAK,IAAI,CAAC,QAAQ;AACtB,YAAM,QAAQ,OAAO,IAAI,IAAI,IAAI,KAAK,CAAC;AACvC,YAAM,OAAO,SAAS,OAAO,OAAO,IAAI,KAAK,MAAM,EAAE,KAAK,SAAS,CAAC,CAAC;AACrE,YAAMJ,UAASD,UAAS,IAAI,MAAM;AAClC,YAAM,UAAyC;AAAA,QAC7C,aAAa,EAAE;AAAA,QACf,SAASC;AAAA,QACT,WAAWI,YAAW,GAAG;AAAA,QACzB,KAAK,IAAI;AAAA,MACX;AACA,YAAMH,UAAwC,CAAC;AAC/C,iBAAW,CAAC,MAAM,CAAC,KAAK,SAAS;AAC/B,YAAI,QAAuB;AAC3B,mBAAW,QAAQ,EAAE,MAAM;AACzB,kBAAQ,SAAS,IAAI,IAChB,QAAQ,IAAI,KAAK,OACjB;AAAA,YACC;AAAA,cACE,GAAG;AAAA,cACH,QAAQ,CAAC,WAAW,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,YACnD;AAAA,YACA;AAAA,YACA;AAAA,UACF,EAAE,OAAO,IAAI,KAAK;AACtB,cAAI,UAAU,KAAM;AAAA,QACtB;AACA,QAAAA,QAAO,IAAI,IAAI;AAAA,MACjB;AACA,aAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,OAAO,GAAG,IAAI,EAAE,MAAM,IAAI,KAAK;AAAA,QAC/B,MAAM,SAAS,IAAI,MAAM,GAAG;AAAA,QAC5B,QAAAD;AAAA,QACA,aAAa,EAAE;AAAA,QACf,QAAAC;AAAA,QACA,QAAQ,KAAK;AAAA,QACb,UAAU,CAAC;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AACA,MAAI,MAAM,WAAW,KAAM,QAAO;AAGlC,QAAM,OAAO,KAAK;AAAA,IAChB,GAAG,OAAO,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,IACjC,GAAI,MAAM,OAAO,SAAS,cACtB,YAAY,QAAQ,CAAC,MAAM,YAAY,IAAI,EAAE,IAAI,KAAK,CAAC,CAAC,IACxD,CAAC;AAAA,EACP,CAAC;AACD,SAAO,OAAO,IAAI,CAAC,OAAO;AAAA,IACxB,GAAG;AAAA,IACH,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,SAAS,CAAC,CAAC;AAAA,EACpD,EAAE;AACJ;;;AChWA,IAAM,QAAQ,CAAC,WACb,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAG5C,SAAS,aAAa,MAAiB,GAAqB;AAC1D,MAAI,EAAE,OAAO,WAAW,KAAK,EAAE,SAAS,WAAW,EAAG,QAAO;AAC7D,QAAM,UAAU,MAAM,KAAK,OAAO,UAAU,CAAC,CAAC;AAC9C,SACE,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,YAAY,CAAC,CAAC,KAClD,EAAE,SAAS,KAAK,CAAC,MAAM,QAAQ,IAAI,EAAE,YAAY,CAAC,CAAC;AAEvD;AAEA,IAAM,UAAU,CAAC,MAAiB,MAChC,KAAK,UAAU,EAAE,SACjB,KAAK,WAAW,EAAE,UACjB,EAAE,gBAAgB,SAChB,KAAK,OAAO,EAAE,WAAW,KAAK,UAAU,EAAE,UAC7C,OAAO,QAAQ,EAAE,MAAM,EAAE;AAAA,EACvB,CAAC,CAAC,MAAM,KAAK,OAAO,KAAK,OAAO,IAAI,KAAK,UAAU;AACrD,KACA,aAAa,MAAM,CAAC;AAGtB,IAAM,OAAO,CAAC,MACZ,EAAE,UAAU,OAAO,IAAI,EAAE,MAAM,OAAO,IAAI;AAC5C,IAAM,YAAY,CAAC,GAAc,MAC/B,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,MAAM,EAAE,OAAO,UAAU;AAEpE,IAAM,OAAO,CAAC,SACZ,KAAK,UAAU,OACX,EAAE,MAAM,WAAW,IAAI,KAAK,GAAG,IAC/B,EAAE,MAAM,SAAS,IAAI,KAAK,GAAG;AAG5B,IAAMI,aAAY,CAAC,SACxB,KAAK,MAAM,YAAY,CAAC,EAAE,CAAC,KAAK;AAQlC,SAAS,OAAO,MAAsD;AACpE,QAAM,SAAS,oBAAI,IAAyB;AAC5C,aAAW,QAAQ,MAAM;AACvB,QACE,KAAK,SAAS,QACd,KAAK,UAAU,QACf,KAAK,MAAM,SAAS,QACpB,CAAC,KAAK,MAAM;AAEZ;AACF,UAAM,OAAOA,WAAU,KAAK,MAAM,IAAI;AACtC,WAAO,IAAI,MAAM,CAAC,GAAI,OAAO,IAAI,IAAI,KAAK,CAAC,GAAI,IAAI,CAAC;AAAA,EACtD;AACA,aAAW,SAAS,OAAO,OAAO,EAAG,OAAM,KAAK,SAAS;AACzD,SAAO;AACT;AAOO,SAAS,cACd,MACA,MACU;AACV,QAAM,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC9C,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,QAAQ;AACjB,QAAI,KAAK,SAAS,QAAQ,CAAC,OAAO,IAAI,KAAK,IAAI,EAAG,OAAM,IAAI,KAAK,IAAI;AACvE,SAAO,CAAC,GAAG,KAAK;AAClB;AAaA,SAAS,OACP,MACA,MACA,MACA,QACS;AACT,SACE,KAAK,IAAI,IAAI,KACZ,KAAK,UAAU,QAAQ,OAAO,IAAI,KAAK,MAAM,MAAM,MAAM;AAE9D;AAWO,SAAS,SACd,MACA,MACA,OAA4B,oBAAI,IAAI,GACpC,SAAiB,oBAAI,IAAI,GACzB,YAAuC,MAAM,OACrC;AACR,QAAM,SAAS,oBAAI,IAAyB;AAC5C,aAAW,QAAQ;AACjB,QAAI,KAAK,SAAS;AAChB,aAAO,IAAI,KAAK,MAAM,CAAC,GAAI,OAAO,IAAI,KAAK,IAAI,KAAK,CAAC,GAAI,IAAI,CAAC;AAClE,QAAM,OAAO,oBAAI,IAAuB;AACxC,QAAM,UAAkB,CAAC;AACzB,aAAW,CAAC,MAAM,KAAK,KAAK,QAAQ;AAClC,UAAM,CAAC,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,KAAK,EAAE,KAAK,SAAS;AACjD,QAAI,SAAS,OAAW,MAAK,IAAI,MAAM,IAAI;AAC3C,YAAQ,KAAK,GAAG,KAAK,IAAI,IAAI,CAAC;AAAA,EAChC;AACA,QAAM,OAAO,OAAO,IAAI;AACxB,QAAM,QAAgB,CAAC;AACvB,QAAM,SAAS,oBAAI,IAAY;AAC/B,aAAW,KAAK,MAAM;AACpB,WAAO,IAAI,EAAE,IAAI;AACjB,UAAM,OAAO,KAAK,IAAI,EAAE,IAAI,KAAK,KAAK,IAAI,EAAE,IAAI,IAAI,CAAC;AACrD,QAAI,SAAS,OAAW,OAAM,KAAK,EAAE,MAAM,UAAU,MAAM,EAAE,CAAC;AAAA,aACrD,KAAK,UAAU;AACtB,YAAM,KAAK,EAAE,MAAM,WAAW,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;AAAA,aAEpD,KAAK,SAAS,QACd,CAAC,KAAK,MAAM,QACZ,CAAC,KAAK,MAAM,YACZ,QAAQ,MAAM,CAAC;AAEf,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN,IAAI,KAAK;AAAA,QACT,MAAM;AAAA,QACN,QAAQ,CAAC,KAAK,MAAM;AAAA,MACtB,CAAC;AAAA,QACE,OAAM,KAAK,EAAE,MAAM,aAAa,IAAI,KAAK,GAAG,CAAC;AAAA,EACpD;AACA,aAAW,CAAC,MAAM,IAAI,KAAK;AACzB,QAAI,CAAC,OAAO,IAAI,IAAI;AAClB,YAAM;AAAA;AAAA,QAEJ,UAAU,IAAI,IACV,EAAE,MAAM,UAAU,IAAI,KAAK,GAAG,IAC9B,OAAO,MAAM,MAAM,MAAM,MAAM,IAC7B,KAAK,IAAI,IACT,EAAE,MAAM,aAAa,IAAI,KAAK,GAAG;AAAA,MACzC;AACJ,SAAO,CAAC,GAAG,OAAO,GAAG,OAAO;AAC9B;AAQO,SAAS,YACd,QACA,MACA,MACA,QACA,SACqB;AACrB,QAAM,QAAQ,oBAAI,IAAoB;AACtC,aAAW,QAAQ;AACjB,QAAI,KAAK,UAAU,KAAM,OAAM,IAAI,KAAK,MAAM,QAAQ,KAAK,EAAE;AAC/D,QAAM,OAAO,oBAAI,IAAoB;AACrC,aAAW,CAAC,QAAQ,IAAI,KAAK,QAAQ;AACnC,UAAM,KAAK,MAAM,IAAI,MAAM;AAC3B,QAAI,OAAO,UAAa,CAAC,OAAO,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI;AACvD,WAAK,IAAI,QAAQ,IAAI;AAAA,EACzB;AACA,aAAW,CAAC,MAAM,MAAM,KAAK,QAAS,MAAK,IAAI,OAAO,QAAQ,IAAI;AAClE,SAAO;AACT;AAUO,SAAS,YACd,OACA,MACA,QACqB;AACrB,QAAM,OAAO,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC/C,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAWC,SAAQ,OAAO;AACxB,QAAIA,MAAK,SAAS,YAAYA,MAAK,SAAS,WAAW;AACrD,YAAM,IAAI,OAAO,IAAIA,MAAK,KAAK,IAAI;AACnC,UAAI,MAAM,OAAW,QAAO,IAAIA,MAAK,KAAK,MAAM,EAAE,GAAG,GAAG,MAAM,KAAK,CAAC;AAAA,IACtE,WAAWA,MAAK,SAAS,YAAYA,MAAK,SAAS,aAAa;AAC9D,YAAM,OAAO,KAAK,IAAIA,MAAK,EAAE;AAE7B,YAAM,OAAOA,MAAK,SAAS,WAAWA,MAAK,KAAK,OAAO,MAAM;AAC7D,UAAI,SAAS,UAAa,QAAQ,QAAQ,KAAK,UAAU,KAAM;AAC/D,aAAO,IAAI,MAAM;AAAA,QACf,IAAI,KAAK;AAAA,QACT,QAAQ,KAAK,MAAM;AAAA,QACnB,MAAM,KAAK,MAAM;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,WACd,QACA,QACY;AACZ,QAAM,QAAoB,CAAC;AAC3B,aAAW,CAAC,MAAM,IAAI,KAAK,QAAQ;AACjC,UAAM,IAAI,OAAO,IAAI,IAAI;AACzB,QAAI,MAAM,OAAW;AACrB,QAAI,EAAE,SAAS,QAAQ,SAAS,EAAE,IAAI,MAAM,SAAS,IAAI;AACvD,YAAM,KAAK,EAAE,MAAM,QAAQ,IAAI,EAAE,IAAI,KAAK,CAAC;AAAA,EAC/C;AACA,SAAO;AACT;;;AC7RO,IAAM,gBAAgB;AAC7B,IAAMC,WAAU;AAChB,IAAM,eAAe;AAErB,IAAM,aAAa;AAEnB,IAAM,SAAS;AAER,IAAM,QAAQ;AAErB,IAAM,kBAAkB;AAExB,IAAM,kBAAkB;AAExB,IAAM,WAA6C;AAAA,EACjD,CAAC,eAAe,GAAG;AAAA,EACnB,CAAC,eAAe,GAAG;AACrB;AAEA,IAAMC,WAAU,CAACC,SAAgC,SAC/CA,QAAO,IAAI,KAAKA,QAAO,SAAS,IAAI,KAAK,EAAE,KAAK;AAClD,IAAM,cAAc;AACpB,IAAM,oBAAoB;AAE1B,IAAM,kBAAkB;AACxB,IAAM,wBACJ;AAEF,IAAM,gBAAgB;AAEtB,IAAM,WAAW,CAAC,SAAyB,eAAe,IAAI;AAE9D,IAAM,YAAY;AAAA,EAChB,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AACV;AAEA,IAAM,gBAAkD;AAAA,EACtD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,eAAe;AACjB;AAEA,IAAM,gBAAgB,IAAI;AAAA,EACxB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAC9B;AAMA,IAAM,WAAW,CAAC,MACf,EAAE,WAAW,QACZ,EAAE,WAAW,iBAAiB,kBAAkB,EAAE,IAAI,KACvD,EAAE,SAAS,gBAAgB,EAAE,WAAW,kBACxC,EAAE,SAAS,YAAY,EAAE,WAAW,QAAQ,EAAE,WAAW,kBACzD,EAAE,SAAS,iBAAiB,EAAE,WAAW;AAE5C,IAAM,WAAW,CAAC,WAChB,OAAO,KAAK,CAAC,MAAM,EAAE,YAAY,MAAM,MAAM,YAAY,CAAC;AAWrD,IAAM,eAAe;AAE5B,IAAM,WAAW;AACjB,IAAM,eAAe;AACd,IAAM,mBAAmB;AAQzB,SAAS,YAAYC,SAAuC;AACjE,QAAM,QAAQA,QAAO,KAAK,CAAC,MAAM,EAAE,SAAS,YAAY;AACxD,MAAI,UAAU,UAAa,MAAM,YAAY;AAC3C,UAAM,IAAI;AAAA,MACR,iDAAiD,YAAY;AAAA,IAC/D;AACF,SAAO;AACT;AASO,IAAM,iBAAiB;AAmB9B,IAAM,UAAU,CAAC,WACd,MAAM,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI;AAGzC,IAAM,eAAe,CACnB,QACA,QACa;AACb,QAAM,QAAQ,OAAO,OAAO,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;AAClD,SAAO,CAAC,GAAG,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC;AAC5D;AAGO,IAAM,eAAN,MASL;AAAA,EACS;AAAA,EACA,SAAS,oBAAI,IAAmB;AAAA;AAAA,EAEhC,YAAY,oBAAI,IAA2B;AAAA;AAAA,EAE3C,UAAU,oBAAI,IAAiC;AAAA,EAExD,YAAY,SAAqB;AAC/B,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,OAAO,CAAC,MAA+C,GAAG,EAAE,GAAG,IAAI,EAAE,MAAM;AAAA,EAE3E,MAAM,SAAS,OAA8B;AAC3C,UAAM,SAAS,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,CAAC;AAC/C,QAAI,WAAW,OAAW,QAAO;AACjC,UAAM,UAAU,MAAS,YAAY,MAAM,KAAK,MAAM,QAAQ,KAAK,EAAE;AACrE,QAAI,YAAY;AACd,YAAM,IAAI,MAAM,yBAAyB,MAAM,MAAM,OAAO,MAAM,GAAG,EAAE;AACzE,WAAO,KAAK,UAAU,OAAO,QAAQ,EAAE;AAAA,EACzC;AAAA,EAEA,UAAU,OAAc,WAA0B;AAChD,UAAM,QAAe,EAAE,WAAW,OAAO,oBAAI,IAAI,EAAE;AACnD,SAAK,OAAO,IAAI,KAAK,KAAK,KAAK,GAAG,KAAK;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,OAAmC;AAC/C,UAAM,QAAQ,MAAM,KAAK,SAAS,KAAK;AACvC,UAAM,WAAW,MAAS,OAAO,MAAM,WAAW,KAAK,EAAE;AACzD,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,QAAQ,KAAqC;AACjD,UAAM,QAAQ,KAAK,UAAU,IAAI,GAAG;AACpC,QAAI,UAAU,OAAW,QAAO;AAChC,UAAM,QAAQ,MAAS,WAAW,KAAK,QAAQ,OAAO,KAAK,EAAE;AAC7D,QAAI,UAAU;AACZ,YAAM,IAAI;AAAA,QACR,eAAe,GAAG,IAAI,MAAM;AAAA,MAC9B;AACF,SAAK,UAAU,IAAI,KAAK,KAAK;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,KAA4B;AAC5C,QAAI,EAAE,MAAM,KAAK,QAAQ,GAAG,GAAG;AAC7B,YAAM,IAAI;AAAA,QACR,yBAAyB,GAAG,IAAI,MAAM;AAAA,MACxC;AAAA,EACJ;AAAA;AAAA,EAGA,MAAM,YAAY,KAAa,QAAQ,eAA+B;AACpE,UAAM,UAAU,MAAS;AAAA,MACvB,MAAS,MAAM,KAAK,KAAK,EAAE;AAAA,MAC3B;AAAA,MACA,KAAK;AAAA,IACP;AACA,UAAM,QAAQ,EAAE,KAAK,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,IAAI;AAC9D,SAAK,UAAU,OAAO,QAAQ,EAAE,EAAE,QAAQ;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,MAAM,KAAa,QAAuC;AAC9D,UAAM,UAAU,MAAS,YAAY,KAAK,QAAQ,KAAK,EAAE;AACzD,QAAI,YAAY,KAAM,QAAO;AAC7B,UAAM,QAAQ,EAAE,KAAK,QAAQ,KAAK,QAAQ,IAAI;AAG9C,QAAI,CAAC,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,CAAC,EAAG,MAAK,UAAU,OAAO,QAAQ,EAAE;AACxE,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aAAa,OAAc,QAAmC;AAClE,UAAM,QAAQ,MAAM,KAAK,SAAS,KAAK;AACvC,UAAMC,UAAS,MAAS,OAAO,MAAM,WAAW,KAAK,EAAE;AACvD,UAAM,QAAkB,CAAC;AAEzB,UAAM,SAAS,CAAC,MAA2B,EAAE,YAAY;AACzD,UAAM,UAAU,CAAC,MAAkB,SAAgC;AACjE,YAAM,IAAI,YAAY,OAAO,QAAQ,MAAM,IAAI;AAC/C,aAAO,MAAM,OAAO,OAAO,OAAO,CAAC;AAAA,IACrC;AACA,UAAM,SAAS,CACb,UACA,MACAC,SACA,UAEA,MAAM,IAAI,CAAC,SAAS;AAClB,YAAM,MAAM,UAAU,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,GAAG;AAEpD,YAAM,QAAQA,QAAO,SAAS,IAAI,IAAI,QAAQ,MAAM,IAAI,IAAI;AAC5D,aAAO,EAAE,MAAM,OAAO,SAAS,OAAO,OAAO;AAAA,IAC/C,CAAC;AACH,UAAM,cAAc,OAClB,OACA,MACAA,SACA,YACsB;AACtB,YAAM,MAAM,QAAQ,KAAK;AACzB,YAAM,UAAUA,QAAO,OAAO,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC;AAErD,YAAM,QAAQ,CAAC,GAAG,KAAK,GAAG,OAAO;AACjC,YAAM,OAAO,UAAU,aAAaA,SAAQ,KAAK,IAAI;AACrD,YAAMC,WAAU,CAAC,KAAK,MAAM,CAAC,GAAG,MAAM,MAAM,IAAI,CAAC,CAAC;AAClD,YAAM,cAAc,MAAM,WAAW,CAAC,GAAG,KAAK,CAAC,MAAM;AACnD,cAAM,QAAQD,QAAO,SAAS,EAAE,IAAI,IAAI,QAAQ,MAAM,EAAE,IAAI,IAAI;AAChE,eAAO,UAAU,QAAQ,EAAE,UAAU,UAAa,EAAE,UAAU;AAAA,MAChE,CAAC;AACD,UAAI,CAACC,YAAW,CAAC,WAAY,QAAO;AACpC,YAAM,KAAK,GAAG,QAAQ,IAAI,CAAC,MAAM,UAAU,CAAC,EAAE,CAAC;AAC/C,UAAI,QAAQ,WAAW,KAAKA,SAAS,OAAM,KAAK,iBAAiB;AACjE,UAAI,cAAc,CAAC,MAAM,SAAS,kBAAkB;AAClD,cAAM,KAAK,kBAAkB;AAE/B,aAAU;AAAA,QACR;AAAA,QACA,OAAO,MAAM,SAAS,MAAMD,SAAQ,IAAI;AAAA,QACxC,KAAK;AAAA,MACP;AAAA,IACF;AACA,UAAM,QAAQ,CAAC,MAAc,SAAuC;AAClE,YAAM,QAAQD,QAAO,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAChD,UAAI,UAAU,UAAa,MAAM,aAAa;AAC5C,cAAM,IAAI;AAAA,UACR,uBAAuB,IAAI,aAAa,cAAc,IAAI,KAAK,IAAI;AAAA,QACrE;AACF,aAAO;AAAA,IACT;AACA,UAAM,SAAS,OACb,MACA,MACAC,SACA,YAC6B;AAC7B,YAAM,QAAQ,MAAM,MAAM,eAAe;AACzC,UAAI,UAAU,OAAW,QAAO,YAAY,OAAO,MAAMA,SAAQ,OAAO;AAExE,UAAIA,QAAO,WAAW,EAAG,QAAO;AAChC,YAAM,KAAK,SAAS,IAAI,EAAE;AAC1B,aAAU;AAAA,QACR,MAAM;AAAA,QACN;AAAA,QACA,EAAE,SAAS,OAAO,MAAM,MAAMA,SAAQA,OAAM,EAAE;AAAA,QAC9C,KAAK;AAAA,MACP;AAAA,IACF;AACA,UAAM,QAAQ,OACZ,MACA,SACsB;AACtB,YAAM,QAAQ,MAAM,MAAM,UAAU,IAAI,CAAC;AACzC,UAAI,UAAU,OAAW,QAAO;AAGhC,YAAM,MAAMD,QAAO,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS,IAAI,CAAC;AACxD,UAAI,SAAS,UAAU,QAAQ,QAAW;AACxC,cAAM,KAAK,iBAAiB,IAAI,IAAI,WAAM,IAAI,EAAE;AAChD,eAAU,YAAY,IAAI,IAAI,MAAM,KAAK,EAAE;AAAA,MAC7C;AACA,YAAM,KAAK,SAAS,IAAI,EAAE;AAC1B,aAAU,YAAY,MAAM,WAAW,MAAM,UAAU,IAAI,GAAG,KAAK,EAAE;AAAA,IACvE;AAIA,UAAMG,SAAQ,MAAM,UAAU,QAAQ,OAAO,SAAS,SAAS;AAC/D,UAAM,QAAQ;AACd,QAAIA,OAAO,OAAM,KAAK,GAAG,OAAO,SAAS,IAAI,CAAC,MAAM,UAAU,CAAC,EAAE,CAAC;AAClE,UAAMC,UAASD,SACX,MAAS;AAAA,MACP,YAAYH,OAAM;AAAA,MAClB,OAAO,MAAM,UAAU,OAAO,UAAU,OAAO,QAAQ;AAAA,MACvD,KAAK;AAAA,IACP,IACA,MAAM,YAAY,YAAYA,OAAM,GAAG,UAAU,OAAO,UAAU,IAAI;AAE1E,UAAM,OAAO,MAAM,MAAM,YAAY,MAAM;AAC3C,UAAM,OAAmB,CAAC;AAC1B,eAAW,KAAK,OAAO,QAAQ;AAC7B,YAAM,QACJ,EAAE,SAAS,WACP,MAAM,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,IACjD,MAAM,MAAM,EAAE,MAAM,EAAE,IAAI;AAChC,UAAI,UAAU,KAAM,MAAK,KAAK,KAAK;AAAA,IACrC;AACA,UAAM,MAAM,CAACI,SAAQ,MAAM,GAAG,IAAI;AAElC,UAAM,WAAW,oBAAI,IAAI;AAAA,MACvB,GAAG,OAAO,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,MAClC,GAAG,OAAO,OAAO,QAAQ;AAAA,IAC3B,CAAC;AACD,eAAW,KAAKJ;AACd,UACE,EAAE,SAAS,gBACX,EAAE,SAAS,cACX,CAAC,cAAc,IAAI,EAAE,KAAK,YAAY,CAAC,KACvC,CAAC,SAAS,IAAI,EAAE,IAAI;AAEpB,cAAM;AAAA,UACJ,cAAc,EAAE,IAAI;AAAA,QACtB;AAEJ,UAAMK,UAAS,CAAC,SACd,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAKL,QAAO,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAExE,UAAMM,SAAQ,CAAC,UACb,UAAU,OACN,OACA,MAAM,QAAQ,CAAC,MAAM;AACnB,YAAM,IAAID,QAAO,CAAC;AAClB,aAAO,MAAM,SAAY,CAAC,IAAI,CAAC,CAAC;AAAA,IAClC,CAAC;AACP,UAAM,UAAU,MAAS,MAAM,MAAM,WAAW,KAAK,EAAE;AAGvD,UAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI;AACvC,UAAME,QAAO,CAAC,SAAiB,MAAM,OAAO,MAAM,QAAQ,IAAI,GAAG,CAAC;AAGlE,UAAM,QAAQ,QAAQ,CAAC;AACvB,UAAM,OAAO,OAAO,MAAM,CAAC;AAC3B,QAAI,UAAyB;AAC7B,QACE,UAAU,UACV,SAAS,UACT,MAAM,SAAS,gBACf,KAAK,WAAW,WAChB,CAAC,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,GACzC;AACA,YAAM,KAAK,QAAQ,KAAK,IAAI,EAAE;AAC9B,YAAM,UAAUD,OAAM,KAAK,MAAM;AACjC,YAAS;AAAA,QACP,MAAM;AAAA,QACN;AAAA,UACE,MAAM,KAAK;AAAA,UACX,GAAI,KAAK,WAAW,OAAO,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO;AAAA,UACtD,GAAI,YAAY,OACZ,CAAC,IACD,EAAE,iBAAiB,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE;AAAA,QAClD;AAAA,QACA,KAAK;AAAA,MACP;AACA,gBAAU,MAAM;AAChB,YAAM,CAAC,IAAI,KAAK;AAAA,IAClB;AACA,UAAM,SAAS,OAAO,SAAoC;AACxD,YAAM,SAAS,KAAK,YAAY,OAAO,OAAOD,QAAO,KAAK,OAAO;AACjE,UAAI,KAAK,YAAY,QAAQ,WAAW;AACtC,cAAM,IAAI,MAAM,4BAA4B,KAAK,OAAO,eAAe;AACzE,YAAS;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,UACE,MAAM,KAAK;AAAA,UACX,QAAQ,KAAK;AAAA,UACb,QAAQ,KAAK;AAAA,UACb,GAAI,WAAW,QAAQ,WAAW,SAC9B,CAAC,IACD,EAAE,SAAS,OAAO,WAAW;AAAA,UACjC,GAAI,KAAK,WAAW,OAChB,CAAC,IACD;AAAA,YACE,gBAAgBC,OAAM,KAAK,MAAM,KAAK,CAAC,GAAG;AAAA,cACxC,CAAC,MAAM,EAAE;AAAA,YACX;AAAA,UACF;AAAA,QACN;AAAA,QACA,KAAK;AAAA,MACP;AAAA,IACF;AACA,eAAW,QAAQ,OAAO,OAAO;AAC/B,UAAI,YAAY,QAAQ,SAAS,KAAM;AACvC,YAAM,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI;AACtD,UAAI,UAAU,QAAW;AACvB,cAAM,KAAK,QAAQ,KAAK,IAAI,EAAE;AAC9B,cAAM,OAAO,IAAI;AACjB,cAAM,KAAK,KAAK,IAAI;AACpB;AAAA,MACF;AAGA,UACE,MAAM,WAAc,QAAQ,KAAK,MAAM,KACtC,KAAK,WAAW,WAAW,MAAM,gBAAgB,KAAK,SACvD;AACA,cAAS,WAAW,MAAM,IAAI,KAAK,EAAE;AACrC,cAAM;AAAA,UACJ,QAAQ,KAAK,IAAI,UACf,KAAK,WAAW,UAAU,aAAa,KAAK,OAAO,KAAK,EAC1D;AAAA,QACF;AACA,cAAM,OAAO,IAAI;AACjB,QAAAC,MAAK,KAAK,IAAI;AACd,cAAM,KAAK,KAAK,IAAI;AACpB;AAAA,MACF;AAGA,YAAM,SAAS,MAAM,WAAW,KAAK;AACrC,YAAM,UAAUD,OAAM,KAAK,MAAM;AACjC,YAAM,eACJ,YAAY,SACX,QAAQ,WAAW,MAAM,OAAO,UAC/B,QAAQ,KAAK,CAAC,MAAM,CAAC,MAAM,OAAO,SAAS,EAAE,IAAI,CAAC;AACtD,UAAI,UAAU,cAAc;AAC1B,cAAM,KAAK,gBAAgB,KAAK,IAAI,EAAE;AACtC,cAAS;AAAA,UACP,MAAM;AAAA,UACN;AAAA,YACE,GAAI,SAAS,EAAE,QAAQ,KAAK,UAAU,GAAG,IAAI,CAAC;AAAA,YAC9C,GAAI,gBAAgB,YAAY,OAC5B,EAAE,iBAAiB,QAAQ,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,IAC5C,CAAC;AAAA,UACP;AAAA,UACA,KAAK;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,IAAI,IAAI,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AACtD,eAAW,KAAK,SAAS;AACvB,UAAI,EAAE,OAAO,WAAW,OAAO,IAAI,EAAE,IAAI,EAAG;AAC5C,UAAI,SAAS,CAAC,GAAG;AACf,cAAS,WAAW,EAAE,IAAI,KAAK,EAAE;AACjC,cAAM,KAAK,gBAAgB,EAAE,IAAI,EAAE;AACnC,QAAAC,MAAK,EAAE,IAAI;AAAA,MACb;AACE,cAAM;AAAA,UACJ,aAAa,EAAE,IAAI;AAAA,QACrB;AAAA,IACJ;AACA,UAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,OAAO,IAAI,CAAC,CAAC;AAC/C,UAAM,gBAAgB,OAAO,MAC1B,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,OAAO,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC;AAClC,QAAI,MAAM,KAAK,CAAC,GAAG,MAAM,MAAM,cAAc,CAAC,CAAC;AAC7C,YAAM;AAAA,QACJ;AAAA,MACF;AAIF,UAAM,SAAS,MAAM,KAAK,QAAQ,MAAM,GAAG;AAC3C,QAAI,OAAO,YAAY,MAAM;AAC3B,aAAO,UAAU,MAAS;AAAA,QACxB,MAAM;AAAA,QACN;AAAA,QACA,EAAE,MAAM,OAAO,OAAO,aAAa,aAAa,kBAAkB;AAAA,QAClE,KAAK;AAAA,MACP;AACA,YAAM,KAAK,SAAS,KAAK,EAAE;AAAA,IAC7B;AACA,eAAW,QAAQ,OAAO;AACxB,WAAK,MAAM,KAAK,UAAU,MAAM,KAAK,IAAI,GAAG;AAC1C,cAAM,KAAK,SAAS,IAAI,EAAE;AAC9B,UAAMC,cAAa,GAAG,MAAM,GAAG,IAAI,MAAM;AACzC,UAAM,SAAS,MAAS,mBAAmB,MAAM,WAAW,KAAK,EAAE;AACnE,QAAI,CAAC,OAAO,KAAK,CAAC,MAAM,EAAE,YAAY,MAAMA,YAAW,YAAY,CAAC,GAAG;AACrE,YAAS,eAAe,MAAM,WAAW,OAAO,IAAI,KAAK,EAAE;AAC3D,YAAM,KAAK,QAAQA,WAAU,EAAE;AAAA,IACjC;AACA,UAAM,SAAS;AAAA,MACb,GAAG;AAAA,MACH,GAAGR,QAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC;AAAA,IACzD;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,UACJ,KACA,MACwC;AACxC,QAAI,MAAM,KAAK,QAAQ,IAAI,GAAG;AAC9B,QAAI,QAAQ,QAAW;AACrB,YAAM,MAAS,SAAS,KAAK,QAAQ,KAAK,EAAE;AAC5C,WAAK,QAAQ,IAAI,KAAK,GAAG;AAAA,IAC3B;AAEA,UAAM,QAAQ,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,YAAY,MAAM,KAAK,YAAY,CAAC;AAC3E,QAAI,UAAU,OAAW,QAAO,EAAE,IAAI,MAAM,CAAC,GAAG,MAAM,MAAM;AAC5D,UAAM,KAAK,MAAS;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,QACE;AAAA,QACA,OAAO;AAAA,QACP,aAAa;AAAA,MACf;AAAA,MACA,KAAK;AAAA,IACP;AACA,QAAI,IAAI,MAAM,EAAE;AAChB,WAAO,EAAE,IAAI,MAAM,KAAK;AAAA,EAC1B;AAAA,EAEA,MAAM,MACJ,OACA,UAAgC,CAAC,GACX;AACtB,UAAM,QAAQ,MAAM,KAAK,SAAS,KAAK;AACvC,UAAM,MAAM,MAAS,UAAU,MAAM,WAAW,KAAK,IAAI,OAAO;AAChE,UAAM,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC/C,UAAM,SAAS,GAAG,MAAM,GAAG,IAAI,MAAM,GAAG,YAAY;AACpD,WAAO,IACJ,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EACzB,IAAI,CAAC,MAAM;AACV,YAAM,QACJ,EAAE,UAAU,QAAQ,EAAE,MAAM,WAAW,YAAY,MAAM,SACrD,EAAE,QACF;AAGN,YAAM,OAAO,EAAE,YAAY,QAAQ,UAAU;AAC7C,aAAO;AAAA,QACL,IAAI,EAAE;AAAA,QACN,MAAM,OAAQ,EAAE,OAAO,MAAM,KAAK,OAAQ;AAAA,QAC1C,OACE,UAAU,OACN,OACA;AAAA,UACE,QAAQ,MAAM;AAAA,UACd,MAAM,MAAM;AAAA,UACZ,UAAU,SAAS,MAAM,MAAM;AAAA,UAC/B,MAAM,MAAM;AAAA,UACZ,QAAQ,CAAC,GAAG,MAAM,MAAM;AAAA,QAC1B;AAAA,QACN,OAAO,EAAE;AAAA,QACT,QAAQ,EAAE,OAAO,YAAY,KAAK;AAAA,QAClC,kBACE,EAAE,OAAO,GAAG,EAAE,OAAO,gBAAgB,KAAK,EAAE,SAAS,KAAK;AAAA,QAC5D,MAAM,EAAE,OAAO,gBAAgB,KAAK;AAAA,QACpC,OAAO,EAAE,OAAO,OAAO,KAAK;AAAA,QAC5B,SAASS,SAAQ,EAAE,QAAQ,eAAe;AAAA,QAC1C,UAAUA,SAAQ,EAAE,QAAQ,eAAe;AAAA,QAC3C,QAAQ,EAAE,GAAG,EAAE,OAAO;AAAA,MACxB;AAAA,IACF,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,KACJ,OACA,QACA,MACA,OACe;AACf,UAAM,QAAQ,MAAM,KAAK,SAAS,KAAK;AACvC,UAAMT,UAAS,MAAM,KAAK,QAAQ,KAAK;AACvC,UAAM,QACJA,QAAO,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAClCA,QAAO,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS,IAAI,CAAC;AAC9C,QAAI,UAAU,OAAW,OAAM,IAAI,MAAM,0BAA0B,IAAI,EAAE;AACzE,QAAI,OAKO;AACX,QAAI,UAAU,QAAQ,MAAM,aAAa,OAAQ,QAAO,EAAE,MAAM,MAAM;AAAA,aAC7D,UAAU,QAAQ,MAAM,aAAa;AAC5C,aAAO,EAAE,QAAQ,OAAO,KAAK,EAAE;AAAA,aACxB,UAAU,QAAQ,MAAM,YAAY,KAAM,QAAO,EAAE,MAAM,MAAM;AAAA,aAC/D,UAAU,MAAM;AACvB,YAAM,SAAS,MAAM,SAAS,KAAK,CAAC,QAAQ,IAAI,SAAS,KAAK;AAC9D,UAAI,WAAW;AACb,cAAM,IAAI,MAAM,aAAa,IAAI,kBAAkB,KAAK,EAAE;AAC5D,aAAO,EAAE,UAAU,OAAO,GAAG;AAAA,IAC/B;AACA,UAAS,SAAS,MAAM,WAAW,QAAQ,MAAM,IAAI,MAAM,KAAK,EAAE;AAClE,UAAM,QAAQ,MAAM,MAAM,IAAI,MAAM;AACpC,QAAI,UAAU,OAAW;AACzB,QAAI,UAAU,KAAM,QAAO,MAAM,OAAO,MAAM,IAAI;AAAA,QAC7C,OAAM,OAAO,MAAM,IAAI,IAAI;AAAA,EAClC;AAAA,EAEA,MAAM,MAAM,OAAcU,OAAoC;AAC5D,QAAIA,MAAK,SAAS,YAAa,QAAO;AACtC,UAAM,QAAQ,MAAM,KAAK,SAAS,KAAK;AACvC,QAAIA,MAAK,SAAS,SAAU,QAAO,KAAK,QAAQ,OAAO,OAAOA,MAAK,IAAI;AACvE,QAAIA,MAAK,SAAS,UAAU;AAE1B,YAAS,WAAW,MAAM,WAAWA,MAAK,IAAI,KAAK,EAAE;AACrD,YAAM,MAAM,OAAOA,MAAK,EAAE;AAC1B,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,MAAM,KAAK,OAAO,OAAOA,MAAK,EAAE;AAC9C,QAAIA,MAAK,SAAS,aAAaA,MAAK,SAAS,SAAS;AAEpD,UAAIA,MAAK,SAAS,WAAW,MAAM,OAAO,SAAS;AACjD,cAAS,WAAW,MAAM,MAAM,IAAI,KAAK,EAAE;AAC7C,YAAS,QAAQ,MAAM,WAAWA,MAAK,IAAI,KAAK,EAAE;AAClD,YAAM,MAAM,OAAOA,MAAK,EAAE;AAC1B,aAAO;AAAA,IACT;AACA,QAAIA,MAAK,SAAS,QAAQ;AACxB,YAAMC,SAAQ,KAAK,SAAS,KAAK;AACjC,YAAS,YAAYA,OAAM,IAAI,EAAE,MAAMD,MAAK,KAAK,GAAG,KAAK,EAAE;AAC3D,MAAAC,OAAM,OAAOD,MAAK;AAClB,aAAO;AAAA,IACT;AACA,UAAM,UAAU,MAAM,KAAK,SAAS,KAAK;AACzC,QAAIA,MAAK,SAAS,WAAW;AAC3B,YAAM,OAAO,MAAS;AAAA,QACpBA,MAAK;AAAA,SACJ,MAAM,KAAK,QAAQ,MAAM,GAAG,GAAG;AAAA,QAChC,KAAK;AAAA,MACP;AACA,YAAM,UAAU;AAChB,YAAM,QAAQ;AAAA,QACZ,GAAG;AAAA,QACH,MAAM;AAAA,QACN,YAAY,GAAG,MAAM,GAAG,IAAI,MAAM;AAAA,QAClC,MAAM;AAAA,QACN,QAAQ,CAAC;AAAA,MACX;AACA,YAAM,KAAK,OAAO,OAAOA,MAAK,MAAM,OAAO;AAC3C,YAAM,KAAK,WAAW,MAAM,KAAK,OAAOA,MAAK,IAAI;AACjD,YAAM,KAAK,QAAQ,OAAOA,MAAK,IAAIA,MAAK,IAAI;AAC5C,aAAO,EAAE,IAAIA,MAAK,IAAI,QAAQ,KAAK,OAAO;AAAA,IAC5C;AACA,UAAM,QAAQ,KAAK,SAAS,KAAK;AACjC,QAAIA,MAAK,QAAQ;AACf,YAAS,YAAY,MAAM,IAAI,KAAK,EAAE;AACtC,YAAM,OAAO;AAAA,IACf;AACA,UAAM,KAAK,OAAO,OAAOA,MAAK,MAAM,OAAO;AAC3C,UAAM,KAAK,WAAW,MAAM,KAAK,OAAOA,MAAK,IAAI;AACjD,UAAM,KAAK,QAAQ,OAAOA,MAAK,IAAIA,MAAK,IAAI;AAC5C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WACJ,OACA,OACA,MAC8B;AAC9B,UAAM,SAAS,MAAS,WAAW,MAAM,KAAK,QAAQ,OAAO,KAAK,EAAE;AACpE,UAAM,KAAK,MAAM,KAAK,UAAU,CAAC,MAAME,WAAU,EAAE,IAAI,MAAM,KAAK,IAAI;AACtE,QAAI,OAAO,GAAI,QAAO;AACtB,WAAO,MAAM,KAAK,OAAO,IAAI,CAAC,EAAE,CAAC,KAAK;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QAAQ,OAAc,OAAc,MAAgC;AACxE,UAAM,SAAS,MAAM,KAAK,QAAQ,MAAM,GAAG;AAC3C,UAAM,UAAU,MAAM,KAAK,SAAS,KAAK;AACzC,UAAM,QAAQ,MAAM,KAAK,WAAW,OAAO,OAAO,IAAI;AACtD,QAAI,UAAU,MAAM;AAClB,YAAMC,MAAK,MAAS,QAAQ,MAAM,WAAW,MAAM,IAAI,KAAK,EAAE;AAC9D,YAAM,QAAoB,MAAM,MAAM,IAAIA,GAAE,KAAK;AAAA,QAC/C,IAAAA;AAAA,QACA,SAAS;AAAA,QACT,OAAO;AAAA,UACL,IAAI,MAAM;AAAA,UACV,QAAQ,MAAM;AAAA,UACd,MAAM;AAAA,UACN,YAAY,GAAG,MAAM,GAAG,IAAI,MAAM;AAAA,UAClC,MAAM,MAAM;AAAA,UACZ,QAAQ,CAAC,KAAK;AAAA,QAChB;AAAA,QACA,OAAO,MAAM;AAAA,QACb,UAAU;AAAA,QACV,QAAQ,CAAC;AAAA,MACX;AACA,YAAM,MAAM,IAAIA,KAAI,KAAK;AACzB,YAAM,KAAK,OAAO,OAAO,MAAM,OAAO;AACtC,YAAM,KAAK,WAAW,MAAM,KAAK,OAAO,IAAI;AAC5C,YAAM,KAAK,QAAQ,OAAOA,KAAI,IAAI;AAClC,aAAO,EAAE,IAAAA,KAAI,QAAQ,MAAM,QAAQ,SAAS,KAAK;AAAA,IACnD;AACA,UAAM,OAAO,MAAS;AAAA,MACpB,OAAO;AAAA,MACP,EAAE,OAAO,KAAK,OAAO,MAAM,KAAK,MAAM,UAAU,CAAC,OAAO,EAAE;AAAA,MAC1D,KAAK;AAAA,IACP;AACA,UAAM,KAAK,MAAS,QAAQ,MAAM,WAAW,KAAK,IAAI,KAAK,EAAE;AAC7D,UAAM,MAAM,IAAI,IAAI;AAAA,MAClB;AAAA,MACA,SAAS;AAAA,MACT,OAAO;AAAA,QACL,GAAG;AAAA,QACH,MAAM;AAAA,QACN,YAAY,GAAG,MAAM,GAAG,IAAI,MAAM;AAAA,QAClC,MAAM,KAAK;AAAA,QACX,QAAQ,CAAC,KAAK;AAAA,MAChB;AAAA,MACA,OAAO,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,QAAQ,CAAC;AAAA,IACX,CAAC;AACD,UAAM,KAAK,WAAW,MAAM,KAAK,MAAM,MAAM,IAAI,EAAE,GAAI,IAAI;AAC3D,UAAM,KAAK,QAAQ,OAAO,IAAI,IAAI;AAClC,WAAO,EAAE,IAAI,QAAQ,KAAK,OAAO;AAAA,EACnC;AAAA;AAAA,EAGA,MAAM,OACJ,OACA,MACA,SACe;AACf,UAAM,QAAQ,KAAK,SAAS,KAAK;AACjC,QAAI,CAAC,SAAS,MAAM,MAAM,GAAG;AAC3B,YAAS,UAAU,MAAM,IAAI,CAAC,OAAO,GAAG,KAAK,EAAE;AAC/C,YAAM,OAAO,KAAK,KAAK;AAAA,IACzB;AACA,QAAI,MAAM,UAAU,KAAK,OAAO;AAC9B,YAAS,YAAY,MAAM,IAAI,EAAE,OAAO,KAAK,MAAM,GAAG,KAAK,EAAE;AAC7D,YAAM,QAAQ,KAAK;AAAA,IACrB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,WACJ,KACA,OACA,MACe;AACf,QAAI,KAAK,OAAO,WAAW,KAAK,KAAK,SAAS,WAAW,EAAG;AAC5D,UAAM,QAAQ,KAAK,SAAS,KAAK;AACjC,UAAM,UAAU,CAAC,SACf,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,YAAY,MAAM,KAAK,YAAY,CAAC;AACjE,UAAM,MAAM,KAAK,OAAO,OAAO,CAAC,MAAM,QAAQ,CAAC,MAAM,MAAS;AAC9D,UAAM,MAAM,KAAK,SAAS,OAAO,CAAC,MAAM,QAAQ,CAAC,MAAM,MAAS;AAChE,QAAI,IAAI,SAAS,GAAG;AAClB,YAAM,MAAgB,CAAC;AACvB,iBAAW,QAAQ,IAAK,KAAI,MAAM,MAAM,KAAK,UAAU,KAAK,IAAI,GAAG,EAAE;AACrE,YAAS,UAAU,MAAM,IAAI,KAAK,KAAK,EAAE;AACzC,YAAM,OAAO,KAAK,GAAG,GAAG;AAAA,IAC1B;AACA,QAAI,IAAI,SAAS,GAAG;AAClB,YAAM,MAAgB,CAAC;AACvB,iBAAW,QAAQ,IAAK,KAAI,MAAM,MAAM,KAAK,UAAU,KAAK,IAAI,GAAG,EAAE;AACrE,YAAS,aAAa,MAAM,IAAI,KAAK,KAAK,EAAE;AAC5C,YAAM,SAAS,MAAM,OAAO;AAAA,QAC1B,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,YAAY,MAAM,EAAE,YAAY,CAAC;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,QAAQ,OAAc,IAAY,MAA8B;AACpE,UAAMC,WAAU,MAAM,KAAK,OAAO,OAAO,EAAE,GAAG;AAC9C,UAAMd,UAAS,MAAM,KAAK,QAAQ,KAAK;AAEvC,UAAM,WAAW,OAAO,QAAQ,KAAK,MAAM,EAAE;AAAA,MAAO,CAAC,CAAC,IAAI,MACxDA,QAAO,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ,SAAS,IAAI,MAAM,EAAE,IAAI;AAAA,IACjE;AACA,UAAM,CAAC,OAAO,IAAI,IAAI;AAAA,MACpB,SAAS,OAAO,CAAC,CAAC,IAAI,MAAM,SAAS,gBAAgB;AAAA,MACrD,SAAS,OAAO,CAAC,CAAC,IAAI,MAAM,SAAS,gBAAgB;AAAA,IACvD;AACA,UAAM,SAAoC;AAAA,MACxC,CAAC,YAAY,KAAK,IAAI;AAAA,MACtB,GAAG;AAAA,MACH,CAAC,cAAc,KAAK,MAAM;AAAA,MAC1B,GAAI,KAAK,gBAAgB,OACrB,CAAC,IACA,CAAC,CAAC,KAAK,aAAa,KAAK,MAAM,CAAC;AAAA,MACrC,GAAG;AAAA,IACL;AACA,eAAW,CAAC,MAAM,KAAK,KAAK;AAC1B,UAAIS,SAAQK,SAAQ,IAAI,MAAM;AAC5B,cAAM,KAAK,KAAK,OAAO,IAAI,MAAM,KAAK;AAAA,EAC5C;AAAA,EAEA,MAAM,OAAO,OAAc,IAAiC;AAC1D,UAAM,QAAQ,MAAM,KAAK,SAAS,KAAK;AACvC,QAAI,CAAC,MAAM,MAAM,IAAI,EAAE,EAAG,OAAM,KAAK,MAAM,KAAK;AAChD,UAAM,QAAQ,MAAM,MAAM,IAAI,EAAE;AAChC,QAAI,UAAU,OAAW,OAAM,IAAI,MAAM,yBAAyB,EAAE,EAAE;AACtE,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAAgC;AACvC,QAAI,MAAM,UAAU;AAClB,YAAM,IAAI,MAAM,oBAAoB,MAAM,EAAE,cAAc;AAC5D,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,SAAS,OAA+B;AAC5C,UAAM,MAAM,MAAM,KAAK,QAAQ,MAAM,GAAG,GAAG;AAC3C,QAAI,OAAO;AACT,YAAM,IAAI;AAAA,QACR,GAAG,MAAM,GAAG,IAAI,MAAM,iBAAiB,KAAK;AAAA,MAC9C;AACF,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KACJ,OACA,SACA,SACAd,UAAqB,EAAE,OAAO,SAAS,SAAS,gBAAgB,GACjD;AACf,eAAW,MAAM,SAAS;AACxB,YAAM,KAAK;AAAA,QACT;AAAA,QACA;AAAA,QACAA,QAAO;AAAA,QACP,YAAY,OAAO,OAAOe;AAAA,MAC5B;AACA,UAAIf,QAAO,YAAY;AACrB,cAAM,KAAK,KAAK,OAAO,IAAIA,QAAO,SAAS,OAAO;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,MAAM,SACJ,OACA,MACmB;AACnB,UAAM,QAAQ,MAAM,KAAK,SAAS,KAAK;AACvC,UAAM,MAAM,MAAS,YAAY,MAAM,WAAW,KAAK,EAAE;AACzD,UAAM,OAAuD,CAAC;AAE9D,QAAI,KAAK,WAAW,QAAQ,IAAI,OAAO,QAAQ,MAAM,KAAK,OAAO,QAAQ;AACvE,WAAK,SAAS,KAAK,OAAO,QAAQ;AACpC,QAAI,KAAK,gBAAgB,QAAQ,IAAI,qBAAqB,KAAK;AAC7D,WAAK,mBAAmB,KAAK;AAC/B,QAAI,KAAK,WAAW,UAAa,KAAK,qBAAqB;AACzD,aAAO,CAAC;AACV,UAAS,kBAAkB,MAAM,WAAW,MAAM,KAAK,EAAE;AACzD,WAAO;AAAA,MACL,GAAI,KAAK,WAAW,SAAY,CAAC,IAAI,CAAC,QAAQ;AAAA,MAC9C,GAAI,KAAK,qBAAqB,SAAY,CAAC,IAAI,CAAC,mBAAmB;AAAA,IACrE;AAAA,EACF;AAAA,EAEA,MAAM,YACJ,OACA,SACmB;AACnB,QAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAClC,UAAM,QAAQ,MAAM,KAAK,SAAS,KAAK;AACvC,UAAM,QAAQ,MAAS,cAAc,MAAM,WAAW,KAAK,EAAE;AAC7D,UAAM,UAAoB,CAAC;AAC3B,eAAW,KAAK,SAAS;AACvB,YAAM,SAAS,SAAS,EAAE,IAAI;AAC9B,YAAM,QAAQ;AAAA,QACZ,MAAM,GAAG,EAAE,KAAK,QAAQ,CAAC;AAAA;AAAA,EAAO,MAAM;AAAA,QACtC,QAAQ,EAAE,OAAO,YAAY,EAAE,QAAQ,KAAK,GAAG;AAAA,QAC/C,WAAW,EAAE;AAAA,QACb,YAAY,EAAE;AAAA,MAChB;AACA,YAAM,SAAS,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK,SAAS,MAAM,CAAC;AACxD,UAAI,WAAW,QAAW;AACxB,cAAS,mBAAmB,MAAM,WAAW,OAAO,KAAK,EAAE;AAC3D,gBAAQ,KAAK,UAAU,EAAE,IAAI,EAAE;AAAA,MACjC,WACE,OAAO,KAAK,QAAQ,MAAM,MAAM,QAChC,OAAO,WAAW,MAAM,WACvB,OAAO,aAAa,UAAU,MAAM,cACpC,OAAO,cAAc,UAAU,MAAM,YACtC;AACA,cAAS,mBAAmB,OAAO,IAAI,OAAO,KAAK,EAAE;AACrD,gBAAQ,KAAK,WAAW,EAAE,IAAI,EAAE;AAAA,MAClC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;AC15BA,IAAM,eAAe;AAMd,IAAM,sBAAN,MAA8C;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EACA;AAAA,EAEA,IAAI,gBAAyB;AAC3B,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,YAAY,SAIT;AACD,SAAK,SAAS,QAAQ;AACtB,SAAK,WAAW,QAAQ;AACxB,SAAK,QAAQ,QAAQ;AAAA,EACvB;AAAA,EAEA,KAAK,OAA2B;AAC9B,WAAO;AAAA,MACL;AAAA,MACA,GAAI,KAAK,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS,KAAK,SAAS;AAAA,MAChE,GAAI,KAAK,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,WAA8C;AAC5C,SAAK,YAAY,YAAY;AAC3B,YAAM,IAAI,KAAK;AACf,UAAI,MAAM,KAAM,QAAO;AAEvB,UAAI,EAAE,UAAU,KAAM,QAAO,EAAE,OAAO,EAAE,MAAM;AAC9C,UAAI;AACF,eAAO,MAAM,QAAQ,KAAK,KAAK,EAAE,KAAK,CAAC;AAAA,MACzC,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,GAAG;AACH,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,oBAA6C;AACjD,QAAI,KAAK,WAAW,KAAM,QAAO,CAAC;AAClC,UAAM,cAAc,MAAM,oBAAoB,KAAK,KAAK,KAAK,OAAO,KAAK,CAAC;AAC1E,WAAO,YAAY,IAAI,CAAC,OAAO;AAAA,MAC7B,OAAO,EAAE;AAAA,MACT,UAAU;AAAA,MACV,UAAU,EAAE,SAAS;AAAA,IACvB,EAAE;AAAA,EACJ;AAAA,EAEA,cAA6B;AAI3B,WAAO,KAAK,QAAQ,WAAW,UAAU,YAAY,IAAI;AAAA,EAC3D;AAAA,EAEA,MAAM,mBAAmB,KAA0C;AACjE,QAAI,KAAK,WAAW,KAAM,QAAO;AACjC,QAAI;AACF,aAAO,MAAM,iBAAiB,KAAK,KAAK,KAAK,KAAK,OAAO,KAAK,CAAC;AAAA,IACjE,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,OAA2C;AAChE,WAAO,iBAAiB,OAAO;AAAA,MAC7B,OAAO,KAAK,QAAQ;AAAA,MACpB,GAAI,KAAK,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS,KAAK,SAAS;AAAA,MAChE,MAAM,aAAa,MAAM,KAAK,SAAS,IAAI,SAAS;AAAA,IACtD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBACJ,OACA,MACiC;AACjC,QAAI,KAAK,WAAW;AAClB,aAAO,EAAE,MAAM,WAAW,QAAQ,gBAAgB;AACpD,WAAO,iBAAiB,OAAO,MAAM;AAAA,MACnC,GAAG,KAAK,KAAK,KAAK,OAAO,KAAK;AAAA,MAC9B,OAAO,MAAM,KAAK,SAAS,IAAI,SAAS;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,SAAmC;AACvC,QAAI,KAAK,WAAW,KAAM,QAAO;AACjC,WAAO,UAAU,KAAK,KAAK,KAAK,OAAO,KAAK,CAAC;AAAA,EAC/C;AAAA,EAEA,UAAwB;AACtB,QAAI,KAAK,WAAW;AAClB,YAAM,IAAI,MAAM,6CAA6C;AAC/D,SAAK,iBAAiB,IAAI,aAAa,KAAK,KAAK,KAAK,OAAO,KAAK,CAAC;AACnE,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,MAAM,YAAY,KAA4B;AAC5C,WAAO,KAAK,QAAQ,EAAE,YAAY,GAAG;AAAA,EACvC;AAAA,EAEA,MAAM,YAAY,KAAa,OAAgC;AAC7D,WAAO,KAAK,QAAQ,EAAE,YAAY,KAAK,KAAK;AAAA,EAC9C;AAAA,EAEA,MAAM,MAAM,KAAa,QAAuC;AAC9D,WAAO,KAAK,QAAQ,EAAE,MAAM,KAAK,MAAM;AAAA,EACzC;AAAA,EAEA,MAAM,aAAa,OAAc,QAAmC;AAClE,WAAO,KAAK,QAAQ,EAAE,aAAa,OAAO,MAAM;AAAA,EAClD;AAAA,EAEA,MAAM,MACJ,OACA,SACsB;AACtB,WAAO,KAAK,QAAQ,EAAE,MAAM,OAAO,OAAO;AAAA,EAC5C;AAAA,EAEA,MAAM,MAAM,OAAcgB,OAAoC;AAC5D,WAAO,KAAK,QAAQ,EAAE,MAAM,OAAOA,KAAI;AAAA,EACzC;AAAA,EAEA,MAAM,KACJ,OACA,SACA,SACAC,SACe;AACf,WAAO,KAAK,QAAQ,EAAE,KAAK,OAAO,SAAS,SAASA,OAAM;AAAA,EAC5D;AAAA,EAEA,MAAM,SACJ,OACA,MACmB;AACnB,WAAO,KAAK,QAAQ,EAAE,SAAS,OAAO,IAAI;AAAA,EAC5C;AAAA,EAEA,MAAM,YACJ,OACA,SACmB;AACnB,WAAO,KAAK,QAAQ,EAAE,YAAY,OAAO,OAAO;AAAA,EAClD;AAAA,EAEA,cAA0B;AACxB,QAAI,KAAK,WAAW;AAClB,YAAM,IAAI,MAAM,mDAAmD;AACrE,WAAO,KAAK,KAAK,KAAK,OAAO,KAAK;AAAA,EACpC;AAAA;AAAA,EAGA,MAAM,aACJ,OACA,MACA,UAC8B;AAC9B,WAAU,aAAa,OAAO,MAAM,UAAU,KAAK,YAAY,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,mBACJ,OACA,MACA,UACA,OACuB;AACvB,WAAU;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,QACJ,OACA,MACA,QAC+D;AAC/D,WAAU,QAAQ,OAAO,MAAM,QAAQ,KAAK,YAAY,CAAC;AAAA,EAC3D;AAAA,EAEA,MAAM,YAAY,UAAkB,SAAgC;AAClE,WAAU,YAAY,UAAU,SAAS,KAAK,YAAY,CAAC;AAAA,EAC7D;AAAA,EAEA,MAAM,QAAQ,SAAiB,MAA6B;AAC1D,WAAU,QAAQ,SAAS,MAAM,KAAK,YAAY,CAAC;AAAA,EACrD;AAAA,EAEA,MAAM,eACJ,OACA,MACA,QACmD;AACnD,WAAU,eAAe,OAAO,MAAM,QAAQ,KAAK,YAAY,CAAC;AAAA,EAClE;AAAA,EAEA,eAAe,KAAoC;AACjD,QAAI,KAAK,WAAW,QAAQ,CAAC,IAAI,WAAW,YAAY,EAAG,QAAO;AAClE,WAAO,EAAE,UAAU,kBAAkB,UAAU,KAAK,OAAO,MAAM;AAAA,EACnE;AACF;AAGA,eAAsB,eACpB,SACA,MACmB;AACnB,SAAO,IAAI,oBAAoB;AAAA,IAC7B,OAAO,MAAM,aAAa;AAAA,IAC1B,GAAI,YAAY,SAAY,CAAC,IAAI,EAAE,QAAQ;AAAA,IAC3C,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,KAAK;AAAA,EACvC,CAAC;AACH;;;AClQA,SAAS,QAAAC,OAAM,YAAAC,WAAU,MAAAC,WAAU;AACnC,SAAS,cAAAC,aAAY,QAAAC,QAAM,SAAAC,QAAO,YAAAC,WAAU,WAAAC,UAAS,OAAAC,YAAW;AAiChE,eAAsB,cACpB,OAC8B;AAC9B,QAAM,EAAE,MAAM,IAAI,IAAI,cAAc,MAAM,MAAM,MAAM,KAAK,MAAM,IAAI;AACrE,QAAM,MAAMC,OAAK,MAAM,MAAM,OAAO,IAAI;AAMxC,QAAM,WAAW,OAAO,IAAI;AAK5B,QAAM,UAAU,MAAM,SAAS,OAAO,IAAI;AAC1C,MAAI,YAAY,UAAa,QAAQ,SAAS;AAC5C,UAAM,IAAI,MAAM,UAAU,IAAI,uBAAuB,QAAQ,IAAI,EAAE;AACrE,QAAM,SAAqC;AAAA,IACzC,GAAG,MAAM,SAAS;AAAA,IAClB,CAAC,IAAI,GAAG,EAAE,MAAM,UAAU,SAAS,SAAS,WAAW,CAAC,EAAE;AAAA,EAC5D;AACA,QAAM,OAAyC,CAAC;AAChD,aAAW,OAAO,MAAM,QAAQ;AAC9B,UAAM,QAAQ,IAAI,QAAQ,cAAc,EAAE;AAC1C,UAAM,WAAW,MAAM,MAAM,GAAG;AAChC,QAAI,SAAS,KAAK,CAAC,MAAM,MAAM,MAAM,MAAM,OAAO,MAAM,IAAI;AAC1D,YAAM,IAAI;AAAA,QACR,cAAc,KAAK;AAAA,MACrB;AACF,UAAM,OAAO,SAAS,GAAG,EAAE,KAAK;AAChC,UAAM,OAAO,OAAO,IAAI,IAAI,KAAK;AACjC,QAAI,CAAC,KAAK,KAAK,IAAI;AACjB,YAAM,IAAI;AAAA,QACR,kCAAkC,KAAK,sBAAsB,SAAS;AAAA,MACxE;AACF,UAAM,WAAW,OAAO,IAAI;AAC5B,QAAI,aAAa,UAAa,SAAS,SAAS;AAC9C,YAAM,IAAI,MAAM,UAAU,IAAI,uBAAuB,SAAS,IAAI,EAAE;AACtE,WAAO,IAAI,IAAI,EAAE,MAAM,SAAS,CAAC,IAAI,EAAE;AACvC,SAAK,KAAK,EAAE,MAAM,KAAK,CAAC;AAAA,EAC1B;AAEA,MAAI;AACJ,MAAI,MAAM,OAAO,GAAG,GAAG;AACrB,UAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAI,WAAW;AACb,YAAM,IAAI,MAAM,OAAO,IAAI,gCAAgC;AAC7D,QAAI,WAAW;AACb,YAAM,IAAI,MAAM,OAAO,IAAI,kBAAkB,MAAM,SAAS,GAAG,EAAE;AACnE,aAAS;AAAA,EACX,OAAO;AACL,UAAM,MAAM,KAAK,KAAK,MAAM,iBAAiB,GAAG,KAAK,IAAI;AACzD,aAAS;AAAA,EACX;AAEA,QAAM,WAAW,CAAC,IAAI;AACtB,aAAW,EAAE,MAAM,KAAK,KAAK,MAAM;AACjC,QAAI,CAAE,MAAM,OAAOA,OAAK,MAAM,MAAM,GAAG,KAAK,MAAM,GAAG,CAAC,CAAC,GAAI;AAIzD,UAAI,WAAW,SAAU,OAAMC,IAAG,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACvE,YAAM,IAAI,MAAM,GAAG,IAAI,iBAAiB;AAAA,IAC1C;AACA,aAAS,KAAK,IAAI;AAAA,EACpB;AAEA,QAAM,WAAqB;AAAA,IACzB,GAAG,MAAM;AAAA,IACT,OAAO,EAAE,GAAG,MAAM,SAAS,OAAO,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE;AAAA,IAClD;AAAA,EACF;AACA,QAAM,cAAc,MAAM,UAAU,QAAQ;AAC5C,SAAO,EAAE,UAAU,MAAM,KAAK,QAAQ,SAAS;AACjD;AAGO,SAAS,aACd,MACA,OACA,KACmD;AACnD,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,UAAMC,SAAQC,SAAQ,MAAM,OAAO,IAAI;AACvC,UAAM,IAAIC,UAASF,QAAOC,SAAQ,GAAG,CAAC;AACtC,QAAI,MAAM,MAAO,CAAC,EAAE,WAAW,IAAI,KAAK,CAACE,YAAW,CAAC;AACnD,aAAO,EAAE,MAAM,KAAKH,QAAO,KAAK,KAAK,IAAI;AAAA,EAC7C;AACA,SAAO;AACT;AAGA,eAAsB,cAAc,SAAoC;AACtE,MAAI,WAAqB,CAAC;AAC1B,MAAI;AACF,UAAM,MAAM,KAAK;AAAA,MACf,MAAMI,UAASN,OAAK,SAAS,cAAc,GAAG,MAAM;AAAA,IACtD;AACA,UAAM,IAAI,IAAI;AACd,QAAI,MAAM,QAAQ,CAAC;AACjB,iBAAW,EAAE,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAAA,aAE7D,MAAM,QACN,OAAO,MAAM,YACb,MAAM,QAAS,EAA6B,QAAQ,GACpD;AACA,iBAAY,EAA8B,SAAS;AAAA,QACjD,CAAC,MAAmB,OAAO,MAAM;AAAA,MACnC;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,WAAW,UAAU;AAC9B,qBAAiB,SAASO,MAAK,SAAS,EAAE,KAAK,QAAQ,CAAC,GAAG;AACzD,YAAM,MAAM,MAAM,MAAMC,IAAG,EAAE,KAAKC,OAAM,GAAG;AAC3C,UAAI,MAAM,OAAOT,OAAK,SAAS,GAAG,IAAI,MAAMS,OAAM,GAAG,GAAG,cAAc,CAAC;AACrE,aAAK,IAAI,GAAG;AAAA,IAChB;AAAA,EACF;AACA,SAAO,CAAC,GAAG,IAAI,EAAE,KAAK;AACxB;;;ACtHO,IAAM,kBAA4B;AAAA,EACvC,OAAO,MAAM,QAAQ,MAAM,UAAU,QAAQ,QAAQ,OAAO,UAAU;AAAA;AAAA,EAEtE,SAAS,MAAM,OAAO,gBAAgB;AACxC;;;AC3CA,SAAS,WAAAC,gBAAe;AACxB,SAAS,WAAAC,UAAS,QAAAC,QAAM,SAAAC,QAAO,WAAAC,gBAAe;AAO9C,eAAsB,cAAc,UAAsC;AACxE,QAAM,QAAQC,SAAQ,QAAQ;AAC9B,QAAM,EAAE,MAAM,OAAO,IAAIC,OAAM,KAAK;AACpC,QAAM,YAAsB,CAAC;AAC7B,WAAS,MAAM,SAAS,MAAMC,SAAQ,GAAG,GAAG;AAC1C,cAAU,KAAK,GAAG;AAClB,QAAI,QAAQ,OAAQ;AAAA,EACtB;AACA,aAAW,OAAO,WAAW;AAC3B,QAAI,MAAM,OAAOC,OAAK,KAAK,UAAU,YAAY,CAAC;AAChD,aAAO,EAAE,MAAM,KAAK,UAAUA,OAAK,KAAK,QAAQ,EAAE;AAAA,EACtD;AACA,aAAW,OAAO,WAAW;AAC3B,QAAI,MAAM,OAAOA,OAAK,KAAK,YAAY,CAAC;AACtC,aAAO,EAAE,MAAMD,SAAQ,GAAG,GAAG,UAAU,IAAI;AAAA,EAC/C;AACA,QAAM,IAAI,MAAM,kCAAkC,QAAQ,EAAE;AAC9D;AAGA,eAAsB,SAAS,MAAoC;AACjE,MAAI;AACF,UAAM,UAAU,MAAME,SAAQD,OAAK,MAAM,KAAK,GAAG,EAAE,eAAe,KAAK,CAAC;AACxE,WAAO,IAAI;AAAA,MACT,QACG,OAAO,CAAC,MAAM,EAAE,YAAY,KAAK,iBAAiB,EAAE,IAAI,CAAC,EACzD,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,IACtB;AAAA,EACF,QAAQ;AACN,WAAO,oBAAI,IAAI;AAAA,EACjB;AACF;;;ACvCA,SAAS,iBAAiB;AAY1B,IAAM,SAA+B;AAAA,EACnC,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT;AAGA,SAAS,UAAmB;AAC1B,QAAM,MAAM,QAAQ,IAAI,UAAU;AAClC,SACE,QAAQ,UAAa,QAAQ,MAAM,QAAQ,IAAI,aAAa,MAAM;AAEtE;AAEO,SAAS,MACd,MACA,MACA,SAA6B,QAAQ,QAC7B;AACR,MAAI,QAAQ,EAAG,QAAO;AACtB,SAAO,UAAU,OAAO,IAAI,GAAG,MAAM,EAAE,QAAQ,gBAAgB,KAAK,CAAC;AACvE;AAEA,IAAM,OAAO,oBAAI,IAAI,CAAC,aAAa,WAAW,cAAc,SAAS,CAAC;AACtE,IAAME,QAAO,oBAAI,IAAI;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,SAAS,OAAO,MAAoB;AACzC,MAAIA,MAAK,IAAI,IAAI,EAAG,QAAO;AAC3B,MAAI,KAAK,IAAI,IAAI,EAAG,QAAO;AAC3B,MAAI,SAAS,QAAS,QAAO;AAC7B,SAAO;AACT;AAGA,IAAM,SAAS;AAMR,SAAS,OACd,MACA,MACA,SAA6B,QAAQ,QAC7B;AACR,QAAM,MAAM,IAAI,OAAO,KAAK,IAAI,GAAG,SAAS,KAAK,MAAM,CAAC;AACxD,SAAO,GAAG,MAAM,OAAO,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,GAAG,IAAI,IAAI;AAC3D;AAEO,SAAS,KACd,MACA,SAA6B,QAAQ,QAC7B;AACR,MAAI,QAAQ,EAAG,QAAO;AACtB,SAAO,UAAU,QAAQ,MAAM,EAAE,QAAQ,gBAAgB,KAAK,CAAC;AACjE;AAMA,IAAM,aAAwC;AAAA,EAC5C,OAAO,CAAC,UAAU,SAAS,MAAM;AAAA,EACjC,MAAM,CAAC,WAAW,SAAS,MAAM;AAAA,EACjC,MAAM,CAAC,UAAU,SAAS,MAAM;AAAA,EAChC,MAAM,CAAC,UAAU,SAAS,MAAM;AAAA,EAChC,MAAM,CAAC,YAAY,SAAS,MAAM;AAAA,EAClC,OAAO,CAAC,SAAS,SAAS,MAAM;AAClC;AASO,SAAS,MACd,MACA,OAAuC,SACvC,SAA6B,QAAQ,QAC7B;AAGR,QAAM,CAAC,GAAG,CAAC,IACT,OAAO,SAAS,WACX,CAAC,MAAM,MAAM,IACb,CAAC,SAAS,IAAI;AACrB,MAAI,QAAQ,EAAG,QAAO;AACtB,QAAM,SAAS,IAAI,IAAI;AACvB,QAAM,UAAU,UAAU,WAAW,CAAC,GAAG,QAAQ;AAAA,IAC/C,QAAQ;AAAA,IACR,gBAAgB;AAAA,EAClB,CAAC;AACD,SAAO,YAAY,SAAS,OAAO;AACrC;AAOO,SAAS,QACd,MACA,SAA6B,QAAQ,QAC7B;AACR,QAAM,QAAQ,IAAI,KAAK,MAAM,GAAG,EAAE,CAAC;AACnC,MAAI,QAAQ,EAAG,QAAO;AACtB,QAAM,UAAU,UAAU,WAAW,MAAM,EAAE,QAAQ,gBAAgB,KAAK,CAAC;AAC3E,SAAO,YAAY,OAAO,QAAQ;AACpC;AAGO,SAAS,MAAM,GAAW,CAAC,KAAK,IAAI,GAA6B;AACtE,SAAO,GAAG,CAAC,IAAI,MAAM,IAAI,MAAM,IAAI;AACrC;AAGO,SAAS,KACd,MACA,SAA6B,QAAQ,QAC7B;AACR,MAAI,QAAQ,EAAG,QAAO;AACtB,SAAO,UAAU,QAAQ,MAAM,EAAE,QAAQ,gBAAgB,KAAK,CAAC;AACjE;AAOO,SAAS,UAAmB;AACjC,MAAI,QAAQ,aAAa,QAAS,QAAO,QAAQ,IAAI,MAAM,MAAM;AACjE,SACE,QAAQ,IAAI,YAAY,MAAM,UAC9B,QAAQ,IAAI,cAAc,MAAM;AAEpC;AAGO,IAAM,eAAe;AAGrB,SAAS,KAAK,MAAsB;AACzC,SAAO,GAAG,MAAM,QAAQ,YAAY,QAAQ,MAAM,CAAC,IAAI,IAAI;AAC7D;AAIA,IAAM,OAAO,CAAC,oGAAyB,kGAAuB;AAE9D,IAAM,OAAO,CAAC,IAAI,KAAK,EAAE;AACzB,IAAM,KAAK,CAAC,IAAI,KAAK,GAAG;AAMxB,SAAS,SAAS,MAAsB;AACtC,QAAM,QAAQ,CAAC,GAAG,IAAI;AACtB,QAAM,OAAO,KAAK,IAAI,GAAG,MAAM,SAAS,CAAC;AACzC,QAAM,UAAU,MAAM,IAAI,CAAC,IAAI,MAAM;AACnC,QAAI,OAAO,IAAK,QAAO;AACvB,UAAM,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK;AAAA,MAAI,CAAC,MAAM,MAChC,KAAK,MAAM,SAAU,GAAG,CAAC,KAAK,QAAQ,QAAQ,IAAK,IAAI;AAAA,IACzD;AACA,WAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;AAAA,EACvC,CAAC;AACD,SAAO,GAAG,QAAQ,KAAK,EAAE,CAAC;AAC5B;AAOO,SAAS,OACd,SACA,SAA6B,QAAQ,QAC7B;AACR,QAAM,SACJ,QAAQ,IAAI,aAAa,MAAM,UAC/B,QAAQ,IAAI,aAAa,MAAM;AACjC,MAAI,OAAO,UAAU,QAAQ,CAAC,OAAQ,QAAO;AAC7C,QAAM,WAAW,MAAM,QAAQ,KAAK,MAAM,MAAM;AAChD,QAAM,aACJ,YACA,OAAO,OAAO,cAAc,cAC5B,OAAO,UAAU,KAAK,EAAE;AAC1B,QAAM,OAAO,KAAK;AAAA,IAAI,CAAC,SACrB,aAAa,SAAS,IAAI,IAAI,MAAM,QAAQ,MAAM,MAAM;AAAA,EAC1D;AACA,SAAO;AAAA,IACL;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA,IAAI,KAAK,UAAU,OAAO,IAAI,MAAM,CAAC;AAAA,IACrC,IAAI,MAAM,QAAQ,4EAAuE,MAAM,CAAC;AAAA,IAChG;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;;;AChOO,SAAS,YAAY,GAAoB;AAC9C,QAAM,QAAQ,QAAQ,IAAI,aAAa,MAAM;AAC7C,MAAI,SAAS,aAAa,SAAS,EAAE,OAAO;AAC1C,YAAQ,OAAO,MAAM,GAAG,EAAE,KAAK;AAAA,CAAI;AAAA,EACrC,OAAO;AACL,UAAM,UAAU,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACzD,YAAQ,OAAO,MAAM,GAAG,MAAM,SAAS,SAAS,QAAQ,MAAM,CAAC;AAAA,CAAI;AAAA,EACrE;AACA,SAAO;AACT;;;AChBA,SAAS,YAAAC,iBAAgB;;;ACAzB,SAAS,SAAAC,cAAa;AAGf,SAAS,cAAc,KAAmB;AAC/C,QAAM,CAAC,SAAS,IAAI,IAClB,QAAQ,aAAa,WACjB,CAAC,QAAQ,CAAC,GAAG,CAAC,IACd,QAAQ,aAAa,UACnB,CAAC,OAAO,CAAC,MAAM,SAAS,IAAI,GAAG,CAAC,IAChC,CAAC,YAAY,CAAC,GAAG,CAAC;AAC1B,MAAI;AACF,UAAM,QAAQA,OAAM,SAAS,MAAM,EAAE,OAAO,UAAU,UAAU,KAAK,CAAC;AACtE,UAAM,GAAG,SAAS,MAAM,MAAS;AACjC,UAAM,MAAM;AAAA,EACd,QAAQ;AAAA,EAER;AACF;AAGO,SAAS,iBAA0B;AACxC,SAAO,QAAQ,IAAI,gBAAgB,MAAM;AAC3C;;;ACFO,IAAM,YAA2D;AAAA,EACtE,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,WAAW;AAAA,IACX,MAAM,CAAC,EAAE,SAAS,KAAK,MAAM,eAAe,SAAS,IAAI;AAAA,EAC3D;AAAA,EACA,QAAQ,EAAE,MAAM,UAAU,OAAO,UAAU,WAAW,MAAM;AAAA,EAC5D,WAAW;AAAA,IACT,MAAM;AAAA,IACN,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AACF;AAEO,SAAS,eAAe,OAAsC;AACnE,SAAO,OAAO,OAAO,WAAW,KAAK;AACvC;AAEO,SAAS,2BAA2B,MAA4B;AACrE,QAAM,YAAY,OAAO,OAAO,SAAS,EACtC,OAAO,CAAC,MAAM,EAAE,SAAS,EACzB,IAAI,CAAC,MAAM,EAAE,IAAI;AACpB,SAAO,yBAAyB,IAAI,oCAAoC,OAAO,gBAAgB,UAAU,KAAK,IAAI,CAAC;AACrH;AAQA,eAAsB,aACpB,UACA,UAAuB,CAAC,GACL;AACnB,QAAM,OAAO,UAAU,YAAY;AACnC,QAAM,QAAQ,UAAU,IAAI;AAC5B,MAAI,MAAM,SAAS;AACjB,UAAM,IAAI,MAAM,2BAA2B,IAAI,CAAC;AAClD,SAAO,MAAM,KAAK,OAAO;AAC3B;AAOA,eAAsB,gBACpB,UAC0B;AAC1B,MAAI,SAAS,aAAa,QAAQ,CAAC,UAAU,SAAS,QAAQ,EAAE;AAC9D,WAAO;AACT,SAAO,aAAa,QAAQ;AAC9B;;;AC1EA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,aAAAC,kBAAiB;AAE1B,IAAMC,aAAYD,WAAUD,SAAQ;AAQpC,IAAM,MAAM;AAEL,SAAS,YAAY,MAAc,KAAqB;AAC7D,SAAO,KAAK,IAAI,MAAM,GAAG;AAC3B;AAIA,IAAM,SAAS,CAAC,UACd,8CAA8C,KAAK,KAAK;AAE1D,eAAe,OAAO,MAAiC;AACrD,QAAM,EAAE,OAAO,IAAI,MAAME,WAAU,OAAO,CAAC,UAAU,YAAY,GAAG,IAAI,CAAC;AACzE,SAAO;AACT;AAEA,eAAe,SAA4B;AACzC,MAAI;AACF,UAAM,MAAM,MAAM,OAAO,CAAC,aAAa,GAAG,CAAC;AAC3C,WAAO,IAAI,QAAQ,OAAO,EAAE,EAAE,MAAM,IAAI;AAAA,EAC1C,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAGO,SAAS,gBAAgB,KAAsB;AACpD,SAAO,CAAC,iBAAiB,KAAK,GAAG;AACnC;AAGA,eAAsB,SAAS,MAAc,KAA+B;AAC1E,QAAM,OAAO,YAAY,MAAM,GAAG;AAClC,OAAK,MAAM,OAAO,GAAG,SAAS,IAAI,EAAG,QAAO;AAE5C,QAAM,eAAe;AACrB,QAAM,OAAO,CAAC,SAAS,KAAK,EAAE,CAAC;AAC/B,QAAM,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC;AACjC,SAAO;AACT;AAOA,eAAsB,iBAAmC;AACvD,QAAM,UAAU,MAAM,OAAO;AAC7B,MAAI,CAAC,QAAQ,KAAK,MAAM,EAAG,QAAO;AAClC,QAAM,OAAO,QAAQ;AAAA,IACnB,CAAC,OAAO,MACN,CAAC,OAAO,KAAK,KAAK,EAAE,UAAU,MAAM,OAAO,QAAQ,IAAI,CAAC,KAAK,EAAE;AAAA,EACnE;AACA,QAAM,OAAO,CAAC,eAAe,GAAG,CAAC;AACjC,aAAW,SAAS,KAAM,OAAM,OAAO,CAAC,SAAS,KAAK,KAAK,CAAC;AAC5D,SAAO;AACT;;;ACjEA,IAAM,SAAS,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAChE,IAAM,cAAc;AAEpB,IAAM,aAAa;AAcnB,SAAS,OAAO,QAAqC;AACnD,SACE,OAAO,UAAU,QACjB,QAAQ,IAAI,MAAM,MAAM,UACxB,QAAQ,IAAI,IAAI,MAAM;AAE1B;AAQA,eAAsB,KACpB,SACA,MACY;AACZ,QAAM,SAAS,QAAQ,UAAU,QAAQ;AACzC,MAAI,CAAC,OAAO,MAAM,EAAG,QAAO,KAAK;AACjC,QAAM,OAAO,CAAC,UAAwB;AACpC;AAAA,MACE,GAAG,UAAU,GAAG,MAAM,QAAQ,OAAO,MAAM,CAAC,IAAI,MAAM,QAAQ,QAAQ,OAAO,MAAM,CAAC;AAAA,IACtF;AAAA,EACF;AACA,MAAI;AACJ,MAAIC,SAAQ;AAGZ,QAAM,QAAQ,MAAY;AACxB,QAAI,CAACA,OAAO;AACZ,IAAAA,SAAQ;AACR,QAAI,UAAU,OAAW,eAAc,KAAK;AAC5C,aAAS,UAAU;AAAA,EACrB;AAEA,QAAM,WAAW,OAAO,MAAM,KAAK,MAAM;AACzC,QAAM,SAAS,QAAQ,OAAO,MAAM;AAAA,IAClC,QAAQ;AAAA,EACV;AAGA,QAAM,QAAQ,CAAC,SACZ,IAAI,SAA4B;AAC/B,UAAM;AACN,WAAO,IAAI,GAAG,IAAI;AAAA,EACpB;AACF,MAAI,QAAQ,SAAS;AACnB,QAAI,IAAI;AACR,SAAK,OAAO,CAAC,KAAK,EAAE;AACpB,YAAQ,YAAY,MAAM;AACxB,WAAK,IAAI,KAAK,OAAO;AACrB,UAAIA,OAAO,MAAK,OAAO,CAAC,KAAK,EAAE;AAAA,IACjC,GAAG,WAAW;AAEd,UAAM,MAAM;AAAA,EACd,OAAO;AACL,SAAK,QAAG;AAAA,EACV;AACA,SAAO,QAAQ,MAAM,QAAQ;AAC7B,MAAI,QAAQ,WAAW,OAAQ,SAAQ,OAAO,QAAQ,MAAM,MAAM;AAClE,MAAI;AACF,WAAO,MAAM,KAAK;AAAA,EACpB,UAAE;AACA,WAAO,QAAQ;AACf,QAAI,QAAQ,WAAW,OAAQ,SAAQ,OAAO,QAAQ;AACtD,UAAM;AAAA,EACR;AACF;;;AChCA,IAAM,aAAa,CAAC,MAClB,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC,GAAG,YAAY,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAG1D,IAAM,OAAO,CAAC,UACZ,WAAW,MAAM,QAAQ,QAAQ,GAAG,EAAE,KAAK,CAAC;AAEvC,IAAM,UAAc;AAAA,EACzB,SAAS;AAAA,EACT,aAAa;AAAA,EACb,OAAO,MAAM;AAAA,EACb,OAAO,MAAM;AAAA,EACb,MAAM,CAAC,MAAM,SAAS;AACpB,YAAQ,OAAO,MAAM,GAAG,OAAO,MAAM,IAAI,CAAC;AAAA,CAAI;AAAA,EAChD;AAAA,EACA,MAAM,CAAC,SAAS;AACd,YAAQ,OAAO,MAAM,GAAG,KAAK,IAAI,CAAC;AAAA,CAAI;AAAA,EACxC;AAAA,EACA,MAAM,CAAC,OAAO,UAAU;AACtB,YAAQ,OAAO;AAAA,MACb,CAAC,IAAI,GAAG,KAAK,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,IAAI;AAAA,IAChE;AAAA,EACF;AAAA,EACA,MAAM,CAAC,MAAM,SAAS,aAAa;AACjC,YAAQ,MAAM,EAAE,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,EACnC;AAAA,EACA,OAAO,CAAC,SAAS;AACf,YAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,EAClC;AAAA,EACA,WAAW,MAAM;AACf,YAAQ,OAAO,MAAM,aAAa;AAAA,EACpC;AAAA,EACA,MAAM,KAAK,SAAS,MAAM,MAAM;AAE9B,UAAM,SAAS,MAAM;AAAA,MACnB,EAAE,OAAO,QAAQ,OAAO,SAAS,QAAQ,QAAQ,KAAK;AAAA,MACtD;AAAA,IACF;AACA,UAAM,OAAO,QAAQ,UAAU,OAAO,OAAQ,OAAO,MAAM,KAAK;AAChE,QAAI,SAAS,KAAM,MAAK,KAAK,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;AAC7C,WAAO;AAAA,EACT;AACF;AAQA,IAAM,cAAc;AAEb,SAAS,UAAU,GAAgB;AAIxC,QAAM,MAAM,CAAC,MAAc,SAAuB;AAChD,UAAM,OAAO,OAAO,IAAI;AACxB,QAAI,SAAS,OAAQ,GAAE,IAAI,QAAQ,IAAI;AAAA,aAC9B,SAAS,OAAQ,GAAE,IAAI,KAAK,IAAI;AAAA,aAChC,SAAS,QAAS,GAAE,IAAI,MAAM,IAAI;AAAA,aAClC,SAAS;AAChB,QAAE,IAAI,QAAQ,MAAM,QAAQ,IAAI,GAAG;AAAA,QACjC,QAAQ,MAAM,QAAQ,WAAW;AAAA,MACnC,CAAC;AAAA,QACE,GAAE,IAAI,KAAK,IAAI;AAAA,EACtB;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,aAAa;AAAA,IACb,OAAO,CAAC,UAAU;AAChB,QAAE,MAAM,MAAM,KAAK,CAAC;AAAA,IACtB;AAAA,IACA,OAAO,CAAC,SAAS,OAAO,WAAW;AAGjC,QAAE,MAAM,MAAM,SAAS,IAAI,CAAC;AAAA,IAC9B;AAAA,IACA,MAAM,CAAC,MAAM,MAAM,aAAa;AAG9B,UAAI,MAAM,YAAY,GAAG,IAAI,IAAI,IAAI,EAAE;AAAA,IACzC;AAAA,IACA,MAAM,CAAC,SAAS;AACd,QAAE,IAAI,KAAK,IAAI;AAAA,IACjB;AAAA,IACA,MAAM,CAAC,OAAO,UAAU;AACtB,QAAE,KAAK,MAAM,KAAK,IAAI,GAAG,OAAO,EAAE,QAAQ,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;AAAA,IAClE;AAAA,IACA,MAAM,CAAC,SAAS;AACd,QAAE,IAAI,QAAQ,MAAM,QAAQ,IAAI,CAAC;AAAA,IACnC;AAAA,IACA,OAAO,CAAC,SAAS;AACf,QAAE,IAAI,MAAM,IAAI;AAAA,IAClB;AAAA,IACA,WAAW,MAAM;AACf,QAAE,OAAO,WAAW;AAAA,IACtB;AAAA,IACA,MAAM,KAAK,SAAS,MAAM,MAAM;AAC9B,YAAM,QAAQ,QAAQ,YAAY,KAAK,QAAQ,KAAK;AAGpD,YAAM,SAAS,CAAC,WACd,OAAO,MAAM,KAAK;AACpB,YAAM,SAAS,CAAC,SAAuB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC;AAGvE,UAAI,QAAQ,QAAQ,QAAQ,CAAC,KAAK,aAAa;AAC7C,UAAE,IAAI,QAAQ,MAAM,QAAQ,GAAG,KAAK,QAAG,CAAC;AACxC,cAAM,SAAS,MAAM,KAAK;AAC1B,cAAM,OAAO,OAAO,MAAM;AAC1B,YAAI,SAAS,KAAM,KAAI,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC;AAC5C,eAAO;AAAA,MACT;AACA,YAAM,OAAO,EAAE,QAAQ;AACvB,WAAK,MAAM,KAAK;AAChB,UAAI;AACF,cAAM,SAAS,MAAM,KAAK;AAC1B,cAAM,OAAO,OAAO,MAAM;AAC1B,aAAK,KAAK,SAAS,OAAO,QAAQ,OAAO,IAAI,CAAC;AAC9C,eAAO;AAAA,MACT,SAAS,GAAG;AACV,aAAK,MAAM,GAAG,KAAK,UAAU;AAC7B,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAGA,eAAsB,OAAO,UAAiC;AAC5D,QAAM,OACJ,SAAS,MAAM,KACf,QAAQ,OAAO,UAAU,QACzB,QAAQ,IAAI,IAAI,MAAM,UACtB,QAAQ,IAAI,MAAM,MAAM;AAC1B,MAAI,CAAC,KAAM,QAAO,EAAE,GAAG,QAAQ;AAC/B,QAAM,IAAI,MAAM,SAAS,QAAQ;AACjC,MACE,EAAE,UAAU,UACZ,EAAE,UAAU,UACZ,EAAE,WAAW,UACb,EAAE,SAAS,UACX,EAAE,QAAQ,UACV,EAAE,YAAY;AAEd,WAAO,EAAE,GAAG,QAAQ;AACtB,SAAO,UAAU;AAAA,IACf,OAAO,EAAE;AAAA,IACT,OAAO,EAAE;AAAA,IACT,QAAQ,EAAE;AAAA,IACV,MAAM,EAAE;AAAA,IACR,KAAK,EAAE;AAAA,IACP,SAAS,EAAE;AAAA,EACb,CAAC;AACH;;;ALrKA,eAAe,cACb,MACA,UACA,KACA,IACe;AACf,MAAI,KAAK,aAAa,MAAO;AAC7B,MAAI,CAAC,gBAAgB,GAAG,GAAG;AACzB,OAAG;AAAA,MACD;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,KAAK,aAAa,MAAM;AAC1B,QAAI,CAAC,SAAS,MAAM,EAAG;AACvB,UAAM,IAAI,MAAM,SAAS,QAAQ;AACjC,UAAM,KAAK,MAAM,EAAE,QAAQ;AAAA,MACzB,SAAS;AAAA,MACT,cAAc;AAAA,IAChB,CAAC;AACD,QAAI,EAAE,SAAS,EAAE,KAAK,OAAO,KAAM;AAAA,EACrC;AACA,QAAM,UAAU,MAAM,SAAS,QAAQ,UAAU,GAAG;AACpD,KAAG;AAAA,IACD,UAAU,YAAY;AAAA,IACtB,8CAA8C,aAAa,CAAC;AAAA,IAC5D,4DAA4D,aAAa,CAAC;AAAA,EAC5E;AACF;AAGA,eAAe,eAAe,KAAuC;AACnE,MAAI;AACF,WAAO,MAAM,cAAc,MAAM,cAAc,GAAG,GAAG,QAAQ;AAAA,EAC/D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,YAAY,QAA0B;AAC7C,SAAO,OAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AACtD;AAMA,eAAsB,aACpB,MACA,OAAkB,CAAC,GACF;AACjB,QAAM,WAAW,KAAK,YAAY;AAElC,QAAM,MAAM,KAAK,OAAO;AACxB,QAAM,KAAK,KAAK,MAAO,MAAM,OAAO,QAAQ;AAC5C,MAAI,IAAK,IAAG,MAAM,kBAAkB;AACpC,MAAI;AACF,UAAM,WAAW,MAAM,eAAe,KAAK,OAAO,QAAQ,IAAI,CAAC;AAC/D,QAAI,UAAU,YAAY,QAAQ,CAAC,UAAU,SAAS,QAAQ,EAAE,WAAW;AACzE,SAAG,MAAM,2BAA2B,SAAS,QAAQ,CAAC;AACtD,aAAO;AAAA,IACT;AACA,UAAM,eAAe,KAAK,YAAY,QAAQ,UAAU,UAAU;AAClE,UAAM,MACJ,KAAK,OAAQ,MAAMC,UAAS,QAAQ,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,MAAM,EAAE;AACnE,UAAM,MAAM,SAAS;AACrB,QAAI,QAAQ;AACV,SAAG,KAAK,GAAG,IAAI,MAAM,sCAAsC;AAC7D,UAAM,SAAS,MAAM,SAAS;AAC9B,UAAM,WAAW,WAAW,OAAO,OAAO,MAAM,aAAa;AAC7D,UAAM,eACJ,gBACA,UAAU,WAAW,WACrB,CAAC,YAAY,QAAQ,OAAO,UAAU,EAAE,EAAE,SAAS,WAAW;AAChE,QAAI,WAAW,QAAQ,aAAa,QAAQ,CAAC,cAAc;AACzD,SAAG;AAAA,QACD;AAAA,QACA,MAAM,OAAO,KAAK,kBAAkB,aAAa,CAAC;AAAA,MACpD;AACA,YAAM,cAAc,MAAM,UAAU,KAAK,EAAE;AAC3C,UAAI,IAAK,IAAG,MAAM,iBAAiB,MAAM;AACzC,aAAO;AAAA,IACT;AAEA,QAAI,aAAc,IAAG,KAAK,SAAS,wCAAwC;AAC3E,UAAM,OAAO,MAAM;AAAA,MACjB,eAAe,GAAG,MAAM,IAAI,WAAW,KAAK;AAAA,IAC9C;AACA,QAAI,GAAG;AACL,SAAG;AAAA,QACD;AAAA,QACA,KAAK;AAAA,QACL,QAAQ,KAAK,eAAe,uBAAuB,KAAK,QAAQ;AAAA,MAClE;AAAA,SACG;AACH,SAAG,KAAK,QAAQ,KAAK,eAAe;AACpC,SAAG,KAAK,QAAQ,KAAK,QAAQ;AAAA,IAC/B;AACA,QAAI,SAAS,MAAM,KAAK,eAAe;AACrC,OAAC,KAAK,QAAQ,eAAe,KAAK,eAAe;AAGnD,QAAI,CAAC,GAAG;AACN,SAAG,KAAK,WAAW,8CAAyC;AAC9D,UAAM,QAAQ,MAAM,GAAG;AAAA,MACrB;AAAA,QACE,OAAO;AAAA,QACP,UAAU;AAAA,QACV,OAAO;AAAA,MACT;AAAA,MACA,YAAY;AACV,cAAM,SAAS,MAAM,aAAa,MAAM,IAAI;AAC5C,cAAM,OAAO,MAAM,QAAQ;AAAA,UACzB,OAAO,OAAO;AAAA,UACd,SAAS,KAAK,aAAa;AAAA,QAC7B,CAAC;AACD,cAAM,UAAU,EAAE,OAAO,KAAK,OAAO,OAAO,CAAC;AAC7C,eAAO,KAAK;AAAA,MACd;AAAA,MACA,CAAC,SAAS,CAAC,aAAa,MAAM,IAAI,eAAe;AAAA,IACnD;AACA,QAAI,CAAC,GAAG,QAAS,IAAG,KAAK,aAAa,MAAM,KAAK,eAAe;AAChE,UAAM,cAAc,MAAM,UAAU,KAAK,EAAE;AAC3C,QAAI,IAAK,IAAG,MAAM,wBAAwB,KAAK,EAAE;AACjD,WAAO;AAAA,EACT,SAAS,GAAG;AACV,QAAI,aAAa,YAAY;AAC3B,SAAG,MAAM,EAAE,OAAO;AAClB,aAAO;AAAA,IACT;AACA,WAAO,YAAY,CAAC;AAAA,EACtB;AACF;;;AMlLA,SAAS,SAAAC,QAAO,YAAAC,WAAU,UAAAC,SAAQ,MAAAC,KAAI,aAAAC,kBAAiB;AACvD,SAAS,WAAAC,UAAS,QAAAC,cAAY;AA6B9B,IAAM,UAAU,CAAC,UAA0B;AACzC,QAAM,IAAI;AACV,SAAO,OAAO,GAAG,UAAU,WACvB,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,GAAI,EAAE,MAAM,CAAC,EAAG,EAAE,IAC1C,EAAE,OAAO,GAAG,IAAI,CAAC,EAAE;AACzB;AAEA,IAAM,SAAS;AAMf,IAAM,QAAQ,CAAC,YACb,QAAQ,MAAM,QAAK,EAAE,GAAG,EAAE,GAAG,KAAK,KAAK;AAEzC,eAAe,SAAS,MAAgC;AACtD,MAAI;AACF,WAAO,KAAK,MAAM,MAAMC,UAAS,MAAM,MAAM,CAAC;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,UAAU,MAAc,OAA+B;AACpE,QAAMC,OAAMC,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,QAAM,YAAY,GAAG,IAAI,IAAI,QAAQ,GAAG;AACxC,QAAMC,WAAU,WAAW,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,CAAI;AAChE,QAAMC,QAAO,WAAW,IAAI;AAC9B;AAGA,eAAsB,YACpB,UACA,SACA,MACiB;AACjB,QAAM,OAAO,MAAM,QAAQ,UAAU,MAAM;AAC3C,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,OAAQ,MAAM,SAAS,IAAI;AACjC,SAAO,QAAQ,OAAO,MAAM,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE;AACjD;AAGA,eAAsB,WACpB,UACA,SACA,MACA,IACe;AACf,QAAM,OAAO,MAAM,QAAQ,UAAU,MAAM;AAC3C,MAAI,SAAS,KAAM;AACnB,MAAI;AACF,UAAM,OAAS,MAAM,SAAS,IAAI,KAAwB,CAAC;AAC3D,UAAM,MAAM,MAAM,OAAO;AACzB,UAAM,KAAK,KAAK,GAAG,KAAK,CAAC;AACzB,UAAM,QAAQ,QAAQ,GAAG,IAAI,CAAC;AAC9B,OAAG,IAAI,IAAI;AAAA,MACT,OAAO,MAAM,QAAQ;AAAA,MACrB,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,SAAS,GAAG,GAAG,GAAG;AAAA,IAC3C;AACA,SAAK,GAAG,IAAI;AACZ,UAAM,UAAU,MAAM,IAAI;AAAA,EAC5B,QAAQ;AAAA,EAER;AACF;AAGA,eAAsB,YACpB,UACA,SACuB;AACvB,QAAM,OAAO,MAAM,QAAQ,UAAU,MAAM;AAC3C,MAAI,SAAS,KAAM,QAAO,CAAC;AAC3B,QAAM,OAAQ,MAAM,SAAS,IAAI;AACjC,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,SAAS,OAAO,OAAO,OAAO,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;AAC5D,eAAW,CAAC,WAAW,EAAE,KAAK,OAAO,QAAQ,QAAQ,KAAK,EAAE,EAAE;AAC5D,aAAO,IAAI,WAAW,EAAE;AAC5B,SAAO,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,UAAU,EAAE;AACjE;AAGA,eAAsB,YACpB,UACA,SACe;AACf,QAAM,OAAO,MAAM,QAAQ,UAAU,MAAM;AAC3C,MAAI,SAAS,KAAM;AACnB,MAAI;AACF,UAAM,OAAS,MAAM,SAAS,IAAI,KAAwB,CAAC;AAC3D,QAAI,CAAC,OAAO,OAAO,MAAM,MAAM,OAAO,CAAC,EAAG;AAC1C,WAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,UAAM,UAAU,MAAM,IAAI;AAAA,EAC5B,QAAQ;AAAA,EAER;AACF;AASA,eAAe,UACbC,QACA,SACwB;AACxB,QAAM,KAAK,MAAM,OAAO;AACxB,SAAO,uBAAuB,KAAK,EAAE,IACjC,QAAQA,QAAO,kBAAkB,EAAE,EAAE,IACrC;AACN;AAMA,eAAsB,YACpBA,QACA,SACA,MAAc,KAAK,IAAI,GACR;AACf,MAAI;AACF,UAAM,CAAC,MAAM,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,MACrC,UAAUA,QAAO,OAAO;AAAA,MACxB,OAAOA,MAAK;AAAA,IACd,CAAC;AACD,QAAI,SAAS,QAAQ,SAAS,KAAM;AACpC,UAAMJ,OAAMC,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAMC,WAAU,MAAM,GAAG,KAAK,UAAU,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC;AAAA,GAAM;AAAA,MAC9D,MAAM;AAAA,IACR,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;AAGA,eAAsB,QACpBE,QACA,SAC8B;AAC9B,QAAM,OAAO,MAAM,UAAUA,QAAO,OAAO;AAC3C,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,OAAQ,MAAM,SAAS,IAAI;AACjC,SAAO,OAAO,MAAM,SAAS,YAAY,OAAO,KAAK,OAAO,WACxD,EAAE,MAAM,KAAK,MAAM,IAAI,KAAK,GAAG,IAC/B;AACN;AAGA,eAAsB,YACpBA,QACA,SACe;AACf,QAAM,OAAO,MAAM,UAAUA,QAAO,OAAO;AAC3C,MAAI,SAAS,KAAM,OAAMC,IAAG,MAAM,EAAE,OAAO,KAAK,CAAC,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AACnE;AAEA,IAAM,UAAU,MAAcC,OAAK,UAAU,GAAG,cAAc;AAG9D,eAAsB,aAAa,MAA6B;AAC9D,MAAI;AACF,UAAM,MAAQ,MAAM,SAAS,QAAQ,CAAC,KAA0B,CAAC;AACjE,QAAI,CAAC,IAAI,SAAS,IAAI,EAAG,OAAM,UAAU,QAAQ,GAAG,CAAC,GAAG,KAAK,IAAI,CAAC;AAAA,EACpE,QAAQ;AAAA,EAER;AACF;AAGA,eAAsB,cAAiC;AACrD,QAAM,MAAM,MAAM,SAAS,QAAQ,CAAC;AACpC,QAAMD,IAAG,QAAQ,GAAG,EAAE,OAAO,KAAK,CAAC,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AACnD,SAAO,MAAM,QAAQ,GAAG,IACpB,IAAI,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IACpD,CAAC;AACP;;;ACpNA,SAAS,YAAAE,YAAU,WAAAC,gBAAe;AAClC,SAAS,QAAAC,cAAY;AACrB,SAAS,cAAcC,cAAa;;;ACFpC,SAAS,SAAS,iBAAiB;AACnC,SAAS,SAAAC,QAAO,QAAAC,OAAM,YAAAC,WAAU,MAAAC,KAAI,QAAAC,OAAM,aAAAC,kBAAiB;AAC3D,SAAS,QAAAC,cAAY;AACrB,SAAS,cAAcC,cAAa;AAe7B,IAAM,WAAkB,CAAC,MAAM,QAAQ;AAC5C,QAAM,MAAM,QAAQ,KAAK,CAAC;AAC1B,MAAI,QAAQ,OAAW;AACvB,QAAM,QAAQ,UAAU,QAAQ,UAAU,CAAC,KAAK,GAAG,IAAI,GAAG;AAAA,IACxD,UAAU;AAAA,IACV,OAAO;AAAA,IACP;AAAA,IACA,KAAK,EAAE,GAAG,QAAQ,KAAK,mBAAmB,IAAI;AAAA,EAChD,CAAC;AACD,QAAM,GAAG,SAAS,MAAM,MAAS;AACjC,QAAM,MAAM;AACd;AAEA,IAAM,cAAc,MAAcC,OAAK,UAAU,GAAG,YAAY;AAEhE,IAAM,oBAAoB,MAAcA,OAAK,UAAU,GAAG,YAAY;AAGtE,eAAsB,cAAcC,SAA+B;AACjE,MAAI;AACF,UAAMC,OAAM,UAAU,GAAG,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACzD,UAAMC;AAAA,MACJ,YAAY;AAAA,MACZ,GAAG,KAAK,UAAU,EAAE,KAAI,oBAAI,KAAK,GAAE,YAAY,GAAG,QAAAF,QAAO,CAAC,CAAC;AAAA;AAAA,IAC7D;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAGA,eAAsB,cAAsC;AAC1D,SACG,MAAM,SAAS,YAAY,CAAC,KAAO,MAAM,SAAS,kBAAkB,CAAC;AAE1E;AAEA,eAAe,SAAS,MAAsC;AAC5D,MAAI;AACF,UAAM,OAAgB,KAAK,MAAM,MAAMG,UAAS,MAAM,MAAM,CAAC;AAC7D,UAAMC,IAAG,MAAM,EAAE,OAAO,KAAK,CAAC;AAC9B,UAAMJ,UACJ,SAAS,QAAQ,OAAO,SAAS,WAC5B,KAAiC,QAAQ,IAC1C;AACN,WAAO,OAAOA,YAAW,YAAYA,YAAW,KAAKA,UAAS;AAAA,EAChE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,IAAMK,iBAAgB,KAAK;AAQ3B,eAAsB,eACpB,KACA,MACA,UAAqE,CAAC,GACpD;AAClB,QAAMJ,OAAM,UAAU,GAAG,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACzD,QAAM,OAAOF,OAAK,UAAU,GAAG,SAAS,GAAG,OAAO;AAClD,aAAS;AACP,QAAI;AACF,YAAM,SAAS,MAAMO,MAAK,MAAM,IAAI;AACpC,YAAM,OAAO,MAAM;AACnB;AAAA,IACF,SAAS,GAAG;AACV,UAAK,EAA4B,SAAS,SAAU,OAAM;AAC1D,YAAM,MAAM,MAAMC,MAAK,IAAI,EAAE;AAAA,QAC3B,CAAC,MAAM,KAAK,IAAI,IAAI,EAAE;AAAA,QACtB,MAAM;AAAA,MACR;AACA,UAAI,MAAMF,eAAe,OAAMD,IAAG,MAAM,EAAE,OAAO,KAAK,CAAC;AAAA,eAC9C,QAAQ,SAAS,KAAM,QAAO;AAAA,UAClC,QAAO,QAAQ,UAAU,CAAC,OAAeI,OAAM,EAAE,IAAI,GAAK;AAAA,IACjE;AAAA,EACF;AACA,MAAI;AACF,UAAM,KAAK;AACX,WAAO;AAAA,EACT,UAAE;AACA,UAAMJ,IAAG,MAAM,EAAE,OAAO,KAAK,CAAC;AAAA,EAChC;AACF;;;AC3GA,SAAS,SAAAK,QAAO,YAAAC,WAAU,UAAAC,SAAQ,MAAAC,KAAI,aAAAC,kBAAiB;AACvD,SAAS,WAAAC,gBAAe;AAUxB,IAAMC,QAAO;AAEN,SAAS,UAAU,UAA0C;AAClE,SAAO,QAAQ,UAAUA,KAAI;AAC/B;AAGA,eAAsB,UAAU,MAA2C;AACzE,MAAI,SAAS,KAAM,QAAO,oBAAI,IAAI;AAClC,MAAI;AACF,UAAM,OAAgB,KAAK,MAAM,MAAMC,UAAS,MAAM,MAAM,CAAC;AAC7D,WAAO,IAAI;AAAA,MACT,MAAM,QAAQ,IAAI,IACd,KAAK,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IACrD,CAAC;AAAA,IACP;AAAA,EACF,QAAQ;AACN,WAAO,oBAAI,IAAI;AAAA,EACjB;AACF;AAGA,eAAsB,WACpB,MACA,OACe;AACf,MAAI,SAAS,KAAM;AACnB,MAAI;AACF,QAAI,MAAM,SAAS,GAAG;AACpB,YAAMC,IAAG,MAAM,EAAE,OAAO,KAAK,CAAC;AAC9B;AAAA,IACF;AACA,UAAMC,OAAMC,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,YAAY,GAAG,IAAI,IAAI,QAAQ,GAAG;AACxC,UAAMC;AAAA,MACJ;AAAA,MACA,GAAG,KAAK,UAAU,CAAC,GAAG,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC;AAAA;AAAA,IAC/C;AACA,UAAMC,QAAO,WAAW,IAAI;AAAA,EAC9B,QAAQ;AAAA,EAER;AACF;AAMA,eAAsB,SACpB,UACA,OACA,OACmB;AACnB,QAAM,OAAO,MAAM,UAAU,QAAQ;AACrC,QAAM,QAAQ,MAAM,UAAU,IAAI;AAClC,QAAM,SAAS,GAAG,KAAK;AACvB,QAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,CAAC;AACvD,QAAM,MAAM,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC;AACrD,QAAM,OAAO,MAAM;AAAA,IACjB,CAAC,MAAM,CAAC,EAAE,WAAW,OAAO,KAAK,CAAC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,EAAE;AAAA,EAC7D;AACA,QAAM,OAAO,oBAAI,IAAI;AAAA,IACnB,GAAG,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,MAAM,CAAC;AAAA,IACjD,GAAG;AAAA,EACL,CAAC;AACD,MAAI,KAAK,SAAS,MAAM,QAAQ,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;AACjE,UAAM,WAAW,MAAM,IAAI;AAC7B,SAAO;AACT;;;AC/EA,SAAS,SAAAC,QAAO,YAAAC,YAAU,UAAAC,SAAQ,MAAAC,KAAI,aAAAC,kBAAiB;AACvD,SAAS,WAAAC,gBAAe;AAUxB,IAAMC,QAAO;AAGN,SAAS,WAAW,UAA0C;AACnE,SAAO,QAAQ,UAAUA,KAAI;AAC/B;AAGA,IAAM,SAAS;AAMf,eAAsB,WACpB,MAC8B;AAC9B,QAAM,SAAS,oBAAI,IAAoB;AACvC,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,MAAMC,WAAS,MAAM,MAAM,CAAC;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI;AACjE,WAAO;AACT,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,IAAI;AAC3C,QAAI,OAAO,KAAK,GAAG,KAAK,OAAO,SAAS,YAAY,SAAS;AAC3D,aAAO,IAAI,OAAO,GAAG,GAAG,IAAI;AAChC,SAAO;AACT;AAOA,eAAsB,YACpB,MACA,QACe;AACf,MAAI,SAAS,KAAM;AACnB,MAAI;AACF,QAAI,OAAO,SAAS,GAAG;AACrB,YAAMC,IAAG,MAAM,EAAE,OAAO,KAAK,CAAC;AAC9B;AAAA,IACF;AACA,UAAM,UAAU,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC;AACpD,UAAMC,OAAMC,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAM,YAAY,GAAG,IAAI,IAAI,QAAQ,GAAG;AACxC,UAAMC;AAAA,MACJ;AAAA,MACA,GAAG,KAAK,UAAU,OAAO,YAAY,OAAO,GAAG,MAAM,CAAC,CAAC;AAAA;AAAA,IACzD;AACA,UAAMC,QAAO,WAAW,IAAI;AAAA,EAC9B,QAAQ;AAAA,EAER;AACF;;;ACtEA,SAAS,YAAAC,kBAAgB;AAEzB,SAAS,qBAAqB;;;ACS9B,IAAM,WAAW,CAAC,MAChB,MAAM,QAAQ,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC;AAEzD,SAAS,KAAK,GAAS,GAAkB;AACvC,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC;AACrC,WAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;AACjE,MAAI,SAAS,CAAC,KAAK,SAAS,CAAC,GAAG;AAC9B,UAAM,OAAO,OAAO,KAAK,CAAC;AAC1B,WACE,KAAK,WAAW,OAAO,KAAK,CAAC,EAAE,UAC/B,KAAK,MAAM,CAAC,MAAM,OAAO,OAAO,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAAA,EAE7D;AACA,SAAO;AACT;AAEA,IAAM,QAAQ,CAAC,MACb,OAAO,MAAM,WAAW,IAAI,KAAK,UAAU,CAAC;AAU9C,SAAS,WACP,IACA,MACA,MACA,QACA,KACA,MACM;AACN,MAAI,KAAK,MAAM,MAAM,EAAG,QAAO;AAC/B,MAAI,KAAK,MAAM,IAAI,EAAG,QAAO;AAC7B,MAAI,KAAK,QAAQ,IAAI,EAAG,QAAO;AAC/B,MACE,SAAS,IAAI,KACb,SAAS,MAAM,MACd,SAAS,UAAa,SAAS,IAAI;AAEpC,WAAO,YAAY,IAAI,SAAS,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,QAAQ,KAAK,IAAI;AAC5E,OAAK;AAAA,IACH,SAAS,SACL,GAAG,EAAE,gBAAgB,GAAG,UAAU,MAAM,MAAM,CAAC,KAC/C,WAAW,SACT,GAAG,EAAE,UAAU,MAAM,IAAI,CAAC,KAAK,GAAG,gBAClC,GAAG,EAAE,UAAU,MAAM,IAAI,CAAC,KAAK,GAAG,UAAU,MAAM,MAAM,CAAC;AAAA,EACjE;AACA,SAAO;AACT;AAEA,SAAS,YACP,IACA,MACA,MACA,QACA,KACA,MACsB;AACtB,QAAM,SAA+B,CAAC;AACtC,QAAM,OAAO;AAAA,IACX,GAAG,OAAO,KAAK,IAAI;AAAA,IACnB,GAAG,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,EAC9D;AACA,aAAW,OAAO,MAAM;AACtB,UAAM,QAAQ;AAAA,MACZ,GAAG,EAAE,IAAI,GAAG;AAAA,MACZ,KAAK,GAAG;AAAA,MACR,KAAK,GAAG;AAAA,MACR,OAAO,GAAG;AAAA,MACV;AAAA,MACA;AAAA,IACF;AACA,QAAI,UAAU,OAAW,QAAO,GAAG,IAAI;AAAA,EACzC;AACA,SAAO;AACT;AAEA,IAAM,SAAS,CAAC,MACd,SAAS,CAAC,KAAK,OAAO,EAAE,MAAM,MAAM,WAAW,EAAE,MAAM,IAAI;AAE7D,IAAM,SAAS,CAACC,WACd,IAAI;AAAA,GACD,MAAM,QAAQA,MAAK,IAAIA,SAAQ,CAAC,GAAG,QAAQ,CAAC,MAAM;AACjD,UAAM,OAAO,OAAO,CAAC;AACrB,WAAO,SAAS,SAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAU;AAAA,EACtD,CAAC;AACH;AAMF,SAAS,WACP,IACA,MACA,MACA,QACA,KACA,MACQ;AACR,QAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,GAAG,OAAO,MAAM,CAAC;AAC5C,QAAM,SAAiB,CAAC;AACxB,aAAW,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG;AAClD,UAAM,OAAO,OAAO,IAAI;AACxB,QAAI,SAAS,QAAW;AACtB,aAAO,KAAK,IAAI;AAChB;AAAA,IACF;AACA,UAAM,QAAQ;AAAA,MACZ,GAAG,EAAE,IAAI,IAAI;AAAA,MACb,EAAE,IAAI,IAAI;AAAA,MACV;AAAA,MACA,EAAE,IAAI,IAAI;AAAA,MACV;AAAA,MACA;AAAA,IACF;AACA,QAAI,UAAU,OAAW,QAAO,KAAK,KAAK;AAAA,EAC5C;AACA,QAAM,QAAQ,OAAO,IAAI;AACzB,aAAW,CAAC,MAAM,IAAI,KAAK;AACzB,QAAI,CAAC,MAAM,IAAI,IAAI,KAAK,CAAC,EAAE,IAAI,IAAI,EAAG,QAAO,KAAK,IAAI;AACxD,SAAO;AACT;AAOO,SAAS,WACd,MACA,MACA,MACA,QACA,KACiD;AACjD,QAAM,KAAK,UAAU,IAAI;AACzB,QAAM,OAAa,CAAC;AACpB,QAAM,EAAE,QAAQ,QAAQ,GAAG,GAAG,KAAK,IAAI;AACvC,QAAM,OAAO;AAAA,IACX,GAAG,OAAO,KAAK,IAAI;AAAA,IACnB,GAAG,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,EAC9D;AACA,QAAM,QAA8B,CAAC;AACrC,MAAI,WAAW,OAAW,OAAM,QAAQ,IAAI;AAC5C,QAAM,QAAQ,IAAI;AAClB,aAAW,OAAO,MAAM;AACtB,UAAM,QACJ,QAAQ,UACJ;AAAA,MACE,GAAG,EAAE;AAAA,MACL,KAAK,GAAG;AAAA,MACR,KAAK,GAAG;AAAA,MACR,OAAO,GAAG;AAAA,MACV;AAAA,MACA;AAAA,IACF,IACA;AAAA,MACE,GAAG,EAAE,IAAI,GAAG;AAAA,MACZ,KAAK,GAAG;AAAA,MACR,KAAK,GAAG;AAAA,MACR,OAAO,GAAG;AAAA,MACV;AAAA,MACA;AAAA,IACF;AACN,QAAI,UAAU,OAAW,OAAM,GAAG,IAAI;AAAA,EACxC;AACA,SAAO,EAAE,OAAO,KAAK;AACvB;;;ACxLA,SAAS,QAAAC,aAAY;AACrB,SAAS,QAAAC,cAAY;AAqBrB,IAAM,QAAQ;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,UAAU,CAAC,UACf,OAAO;AAAA,EACL;AAAA,IACE,GAAG,MAAM,OAAO,CAAC,MAAM,OAAO,OAAO,OAAO,CAAC,CAAC;AAAA,IAC9C,GAAG,OAAO,KAAK,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;AAAA,EACxD,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AAC5B;AAEF,eAAeC,QAAO,MAAgC;AACpD,MAAI;AACF,UAAMC,MAAK,IAAI;AACf,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOA,eAAsB,aACpB,MACA,UACA,QACA,KACkC;AAClC,QAAM,OAAO,UAAU,IAAI;AAC3B,QAAM,SAAS,KAAK,SAAS,GAAG,MAAM,OAAO,MAAM,cAAc,IAAI;AACrE,QAAM,WAAW,WAAW,OAAO,CAAC,IAAI,EAAE,OAAO;AACjD,MAAI,SAAS;AACX,WAAO,QAAQ;AAAA,MACb,GAAG;AAAA,MACH;AAAA,MACA,GAAG,eAAe,QAAQ,EAAE,YAAY,KAAK,CAAC;AAAA,IAChD,CAAC;AACH,QAAM,QAAiC;AAAA,IACrC,GAAG;AAAA,IACH;AAAA,IACA,GAAG,eAAe,QAAQ,EAAE,YAAY,KAAK,CAAC;AAAA,EAChD;AACA,MAAI,MAAMD,QAAOE,OAAK,UAAU,MAAM,WAAW,CAAC;AAChD,UAAM,QAAQ,IAAI,GAAG,IAAI;AAC3B,MAAI,MAAMF,QAAOE,OAAK,UAAU,MAAM,SAAS,CAAC;AAC9C,UAAM,SAAS,IAAI,GAAG,IAAI;AAE5B,QAAM,QAAQ,MAAM,UAAU,UAAU,IAAI;AAC5C,MAAI,MAAM,gBAAgB,KAAM,OAAM,aAAa,IAAI,MAAM;AAC7D,QAAM,cAAc,MAAM,aAAa;AAIvC,MAAI,MAAM,aAAa,QAAQ,YAAY,IAAI,MAAM;AACnD,gBAAY,IAAI,EAAE,UAAU,IAAI,CAAC,GAAG,MAAM,QAAQ;AACpD,QAAMC,UAAS,MAAM,QAAQ;AAC7B,aAAW,KAAK,MAAM;AACpB,IAAAA,QAAO,EAAE,IAAI,IAAI;AAAA,MACf,MAAM,EAAE;AAAA,MACR,MAAM,EAAE,KAAK,WAAW,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI;AAAA,MAClD,GAAI,EAAE,QAAQ,WAAW,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE;AAAA,IAC9D;AACF,MAAI,MAAM,WAAW;AACnB,UAAM,QAAQ,IACZ,MAAM,OAAO,SAAS,cAAc,cAAc,MAAM,OAAO;AAEnE,QAAM,OAAO,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AACvD,MAAI,SAAS,QAAW;AACtB,UAAMC,SAAQ,MAAM,OAAO;AAC3B,UAAM,KAAKA,OAAM;AAAA,MACf,CAAC,MAAM,EAAE,YAAY,MAAM,QAAQ,EAAE,QAAQ,MAAM;AAAA,IACrD;AACA,IAAAA,OAAM,OAAO,KAAK,GAAG,GAAG;AAAA,MACtB,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,MAAM,KAAK;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO,QAAQ,KAAK;AACtB;AAMA,eAAsB,cACpB,MACA,OACA,UAC2B;AAC3B,MAAI,OAAO,UAAU;AACnB,WAAO,WAAW,MAAM,MAAM,aAAa,MAAM,UAAU,KAAK,CAAC;AACnE,MAAI,OAAO,UAAU;AACnB,WAAO,WAAW,MAAM,MAAM,aAAa,MAAM,UAAU,MAAM,KAAK,CAAC;AACzE,SAAO;AACT;AAeA,eAAsB,WAAW,UAAyC;AACxE,MAAI;AACJ,MAAI;AACF,gBAAY,MAAM,aAAa,QAAQ,GAAG,UAAU,CAAC;AAAA,EACvD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,SAAuB,CAAC;AAC9B,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,QAAQ;AACjD,QAAI;AACF,YAAM,cAAc,MAAM,cAAc,MAAM,OAAO,QAAQ;AAC7D,UAAI,YAAY,WAAW,KAAM,QAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAAA,IACpE,QAAQ;AAAA,IAER;AACF,SAAO;AACT;;;AFtIO,IAAM,cAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAYA,IAAM,UAAmB;AAAA,EACvB,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AACT;AAEA,IAAM,SAAS,CAAC,eAA+B,GAAG,UAAU;AAE5D,eAAe,SACb,UACA,YACwB;AACxB,MAAI;AACF,WAAO,MAAMC;AAAA,MACX,MAAM,cAAc,UAAU,OAAO,UAAU,CAAC;AAAA,MAChD;AAAA,IACF;AAAA,EACF,SAAS,GAAG;AACV,QAAK,EAA4B,SAAS,SAAU,QAAO;AAC3D,UAAM;AAAA,EACR;AACF;AAGA,eAAsB,mBACpB,UACA,YAC8C;AAC9C,QAAM,OAAO,MAAM,SAAS,UAAU,UAAU;AAChD,MAAI,SAAS,KAAM,QAAO,CAAC;AAC3B,QAAM,QAAQ,iBAAiB,IAAI,KAAK,CAAC;AACzC,SAAO,OAAO;AAAA,IACZ,YAAY,OAAO,CAAC,MAAM,MAAM,CAAC,MAAM,MAAS,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AAAA,EAC5E;AACF;AAEA,IAAM,QAAQ;AAGP,SAAS,oBAAoB,MAAsB;AACxD,QAAM,QAAQ,MAAM,KAAK,IAAI;AAC7B,MAAI,UAAU,KAAM,QAAO;AAC3B,QAAM,MAAM,cAAc,MAAM,CAAC,KAAK,EAAE;AACxC,aAAW,OAAO,YAAa,KAAI,OAAO,GAAG;AAC7C,QAAM,OAAO,OAAO,GAAG,EAAE,KAAK;AAC9B,QAAM,QAAQ,KAAK,MAAM,MAAM,CAAC,EAAE,MAAM;AACxC,SAAO,SAAS,MAAM,SAAS,OAC3B,GAAG,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,QAAQ,qBAAqB,EAAE,CAAC,KAC1D,GAAG,MAAM,CAAC,KAAK,EAAE;AAAA,EAAQ,IAAI;AAAA,KAAQ,MAAM,CAAC,KAAK,IAAI,GAAG,KAAK;AACnE;AAEA,IAAMC,YAAW,CAAC,MAChB,MAAM,QAAQ,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC;AAEzD,IAAMC,QAAO,CAAC,GAAY,MACxB,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC;AAGxC,SAAS,aAAa,OAAyB;AAC7C,MAAI,CAACD,UAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,OAAO,MAAM,MAAM;AACzB,QAAM,UAAU,MAAM,SAAS;AAC/B,SAAO;AAAA,IACL,MAAM,MAAM,MAAM;AAAA,IAClB,MAAM,OAAO,SAAS,WAAW,CAAC,IAAI,IAAI;AAAA,IAC1C,GAAI,MAAM,QAAQ,OAAO,KAAK,QAAQ,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,EACpE;AACF;AAGA,IAAM,cAAc,CAAC,UAA4B,aAAa,KAAK;AAiBnE,SAAS,SACP,MACA,YACA,QACA,UACe;AACf,QAAM,cAAc,OAAO,aAAa;AACxC,QAAM,QAAQA,UAAS,WAAW,IAAI,YAAY,UAAU,IAAI;AAChE,QAAME,UAASF,UAAS,OAAO,QAAQ,CAAC,IAAI,EAAE,GAAG,OAAO,QAAQ,EAAE,IAAI,CAAC;AACvE,QAAM,YAAsB,CAAC;AAC7B,QAAM,OAAO,CACX,KACA,MACA,QACA,QACG;AACH,QAAI,SAAS,OAAW,KAAI;AAAA,aACnB,CAACC,MAAK,MAAM,MAAM,EAAG,WAAU,KAAK,GAAG;AAAA,EAClD;AACA,MAAI,SAAS,gBAAgB;AAC3B,SAAK,eAAe,OAAO,aAAa,GAAG,SAAS,aAAa,MAAM;AACrE,aAAO,aAAa,IAAI,SAAS;AAAA,IACnC,CAAC;AACH,MAAI,SAAS,aAAa,UAAaD,UAAS,KAAK,GAAG;AACtD,UAAM,OAAO,MAAM,UAAU;AAE7B,QAAI,SAAS,UAAa,SAAS;AACjC,YAAM,UAAU,IAAI,SAAS;AAAA,aACtB,CAACC,MAAK,MAAM,SAAS,QAAQ,EAAG,WAAU,KAAK,UAAU;AAAA,EACpE;AACA,MAAI,SAAS,WAAW;AACtB,SAAK,UAAU,OAAO,QAAQ,GAAG,SAAS,QAAQ,MAAM;AACtD,aAAO,QAAQ,IAAI,SAAS;AAAA,IAC9B,CAAC;AACH,MAAID,UAAS,SAAS,MAAM;AAC1B,eAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,SAAS,MAAM,GAAG;AAC5D,YAAM,OAAOE,QAAO,KAAK;AACzB,UAAI,SAAS,OAAW,CAAAA,QAAO,KAAK,IAAI,aAAa,KAAK;AAAA,eACjD,CAACD,MAAK,YAAY,IAAI,GAAG,aAAa,KAAK,CAAC;AACnD,kBAAU,KAAK,UAAU,KAAK,EAAE;AAAA,IACpC;AACF,MAAI,UAAU,SAAS;AACrB,WAAO,GAAG,OAAO,UAAU,CAAC,aAAa,UAAU,KAAK,IAAI,CAAC,0BAA0B,IAAI;AAC7F,SAAO,QAAQ,IAAIC;AACnB,SAAO;AACT;AAGA,eAAsB,cACpB,UACA,UACA,UAAmB,SACC;AACpB,QAAM,YAAuB;AAAA,IAC3B,SAAS;AAAA,IACT,QAAQ,SAAS;AAAA,IACjB,SAAS,oBAAI,IAAI;AAAA,IACjB,OAAO,CAAC;AAAA,EACV;AACA,MAAI,SAAS,cAAc,QAAW;AACpC,cAAU,MAAM,KAAK;AAAA,MACnB;AAAA,MACA,GAAG,SAAS,SAAS;AAAA,IACvB,CAAC;AACD,cAAU,UAAU;AAAA,EACtB;AACA,MAAI,SAAS,WAAW,KAAM,QAAO;AACrC,QAAM,SAAiB,CAAC;AACxB,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,SAAS,MAAM,GAAG;AAC3D,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO,IAAI,IAAI;AACf;AAAA,IACF;AACA,QAAI;AACJ,QAAI,OAAO,UAAU,UAAU;AAE7B,eAAS,MAAM,aAAa,MAAM,UAAU,KAAK;AACjD,gBAAU,MAAM,KAAK;AAAA,QACnB;AAAA,QACA,GAAG,IAAI,qCAAqC,OAAO,OAAO,QAAQ,CAAC,CAAC;AAAA,MACtE,CAAC;AACD,gBAAU,UAAU;AAAA,IACtB,MAAO,UAAS,gBAAgB,MAAM,MAAM;AAG5C,UAAM,cAAc,OAAO,aAAa;AACxC,eAAW,cAAcF,UAAS,WAAW,IACzC,OAAO,KAAK,WAAW,IACvB,CAAC,GAAG;AACN,YAAM,WAAW,MAAM,mBAAmB,UAAU,UAAU;AAC9D,YAAM,OAAO,OAAO,KAAK,QAAQ;AACjC,UAAI,KAAK,WAAW,EAAG;AACvB,YAAM,UACJ,OAAO,UAAU,WACb,OACA,SAAS,MAAM,YAAY,QAAQ,QAAQ;AACjD,UAAI,YAAY,MAAM;AACpB,kBAAU,MAAM,KAAK,CAAC,WAAW,OAAO,CAAC;AACzC;AAAA,MACF;AACA,YAAM,OAAO,MAAM,SAAS,UAAU,UAAU;AAChD,UAAI,SAAS;AACX,kBAAU,QAAQ,IAAI,OAAO,UAAU,GAAG,oBAAoB,IAAI,CAAC;AACrE,gBAAU,MAAM,KAAK;AAAA,QACnB;AAAA,QACA,GAAG,KAAK,KAAK,IAAI,CAAC,OAAO,OAAO,UAAU,CAAC;AAAA,MAC7C,CAAC;AACD,gBAAU,UAAU;AAAA,IACtB;AAGA,UAAM,WAAW,OAAO,QAAQ;AAChC,QAAI,OAAO,aAAa,UAAU;AAChC,YAAM,SAAS,aAAa,QAAQ;AACpC,YAAM,UAAU,QAAQ,QAAQ,MAAM;AACtC,YAAM,WAAW,CAAC,QAAgB,OAAO,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC;AAC1D,UAAI,SAAS,QAAQ,IAAI,SAAS,OAAO,GAAG;AAC1C,cAAM,OAAO,EAAE,YAAY,KAAK;AAChC,cAAM,EAAE,OAAO,KAAK,IAAI;AAAA,UACtB;AAAA,UACA,QAAQ,SAAS,UAAU,IAAI;AAAA,UAC/B;AAAA,UACA,QAAQ,SAAS,SAAS,IAAI;AAAA,UAC9B;AAAA,QACF;AACA,iBAAS;AACT,kBAAU,MAAM,KAAK,CAAC,UAAU,GAAG,IAAI,OAAO,OAAO,EAAE,CAAC;AACxD,mBAAW,KAAK,KAAM,WAAU,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;AACtD,kBAAU,UAAU;AAAA,MACtB;AAAA,IACF;AAEA,QAAI;AACF,aAAO,IAAI,IACT,OAAO,UAAU,YAAY,UAAU,UACnC,WAAW,MAAM,QAAQ,QAAQ,KAAK,IACtC;AAAA,IACR,SAAS,GAAG;AACV,UAAI,EAAE,aAAa,cAAe,OAAM;AAExC,gBAAU,MAAM,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC;AAC3C,aAAO,IAAI,IAAI;AAAA,IACjB;AAAA,EACF;AACA,YAAU,SAAS;AACnB,SAAO;AACT;;;AJpMA,IAAM,gBAAgB;AACtB,IAAM,cAAc;AACpB,IAAM,cAAc;AAMpB,eAAsB,WAAc,MAA8B;AAChE,MAAI;AACF,WAAO,MAAM;AAAA,EACf,SAAS,GAAG;AACV,QAAI,aAAa,sBAAsB,CAAC,UAAU,KAAK,EAAE,OAAO;AAC9D,YAAM,IAAI,MAAM,WAAW,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;AACtD,UAAM;AAAA,EACR;AACF;AAUA,IAAM,QAAQ,CAAC,SACb,KAAK,cAAc,SAAY,CAAC,IAAI,EAAE,SAAS,KAAK,UAAU;AAEhE,IAAM,kBAAkB,CACtB,MACA,UAC2C;AAAA,EAC3C,GAAG,MAAM,IAAI;AAAA,EACb,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,KAAK;AACvC;AAGA,eAAsB,QACpB,MACA,MACkB;AAClB,QAAM,KAAK,MAAM,cAAc,KAAK,OAAO,QAAQ,IAAI,CAAC;AACxD,QAAM,WAAW,MAAM,aAAa,GAAG,QAAQ;AAC/C,QAAM,WAAW,MAAM,aAAa,UAAU,gBAAgB,MAAM,IAAI,CAAC;AACzE,MAAI,SAAS,QAAQ;AACnB,UAAM,IAAI,MAAM,sDAAsD;AACxE,SAAO;AAAA,IACL,MAAM,GAAG;AAAA,IACT,UAAU,GAAG;AAAA,IACb;AAAA,IACA,KAAK,SAAS;AAAA,IACd;AAAA,EACF;AACF;AAGA,IAAM,WAAW,CAAC,MAAoB,OACpC,SAAS,OAAO,OAAO;AACrB,KAAG,KAAK,WAAW,GAAG,KAAK,MAAM,KAAK,GAAI,CAAC,yBAAyB;AACpE,SAAO,KAAK,UAAU,CAAC,MAAcG,OAAM,CAAC,IAAI,EAAE;AACpD,CAAC;AAOH,eAAe,cAAc,UAA4C;AACvE,MAAI,CAAC,SAAS,cAAe,QAAO;AACpC,QAAM,SAAS,MAAM,WAAW,SAAS,OAAO,CAAC;AACjD,SAAO,QAAQ,SAAS,aAAa,MAAM,OAAO,OAAO;AAC3D;AAKA,IAAM,YAAY,CAAC,MAAsC,EAAE,WAAW;AAUtE,IAAM,WAAW,CAAC,MAChB,EAAE,YAAY,gBAAgB;AAGhC,IAAM,mBAAmB,CAAC,MACxB,EAAE,gBAAgB,QAAQ,CAAC,IAAI,OAAO,KAAK,EAAE,WAAW;AAiB1D,eAAe,aACb,GACA,IAIC;AACD,QAAM,SAAS,EAAE,SAAS,UAAU,CAAC;AACrC,aAAW,KAAK,EAAE,SAAS,WAAW,CAAC;AACrC,QAAI,KAAK,WAAW,GAAG,EAAE,IAAI,KAAK,EAAE,MAAM,EAAE;AAC9C,QAAM,MAAgD,CAAC;AACvD,QAAM,aAA2B,CAAC;AAClC,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAClD,UAAM,cAAc,MAAM,cAAc,MAAM,OAAO,EAAE,QAAQ;AAG/D,UAAM,QAAkB,CAAC;AACzB,QAAI,OAAO,UAAU;AACnB,iBAAW,cAAc,iBAAiB,WAAW,GAAG;AACtD,cAAM,OAAO,OAAO;AAAA,UAClB,MAAM,mBAAmB,EAAE,UAAU,UAAU;AAAA,QACjD;AACA,YAAI,KAAK,SAAS;AAChB,gBAAM,KAAK,GAAG,UAAU,uBAAuB,KAAK,KAAK,IAAI,CAAC,EAAE;AAAA,MACpE;AACF,QAAI,MAAM,SAAS,GAAG;AACpB,UAAI;AAAA,QACF;AAAA,QACA,GAAG,IAAI,KAAK,MAAM,KAAK,IAAI,CAAC;AAAA,MAC9B;AACA;AAAA,IACF;AACA,QAAI,UAAU,WAAW,EAAG,KAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAAA,aACjD,OAAO,UAAU;AACxB,iBAAW,KAAK,EAAE,MAAM,OAAO,YAAY,CAAC;AAAA,EAChD;AACA,SAAO;AAAA,IACL,SAAS,IAAI,KAAK,CAAC,GAAG,MAAM,OAAO,SAAS,CAAC,CAAC,IAAI,OAAO,SAAS,CAAC,CAAC,CAAC;AAAA,IACrE;AAAA,EACF;AACF;AAGA,SAAS,QAAQ,GAAmB;AAClC,SAAO,IAAI;AAAA,IACT,EAAE,SAAS,YAAY,SACnB,wHACA,0CAA0C,EAAE,SAAS,QAAQ,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAAA,EAClG;AACF;AAMA,eAAsB,eAAe,GAAY,IAA8B;AAC7E,MAAI,EAAE,SAAS,WAAW,KAAM,OAAM,QAAQ,CAAC;AAC/C,QAAM,EAAE,QAAQ,IAAI,MAAM,aAAa,GAAG,EAAE;AAC5C,MAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAClC,QAAM,UAAU,MAAM,cAAc,EAAE,QAAQ;AAC9C,MAAI,YAAY,KAAM,OAAM,IAAI,MAAM,OAAO;AAC7C,QAAM,WAAuB,CAAC;AAC9B,aAAW,EAAE,MAAM,YAAY,KAAK,SAAS;AAC3C,UAAM,QAAQ,MAAM,WAAW,EAAE,SAAS,MAAM,EAAE,KAAK,YAAY,MAAM,CAAC;AAC1E,QAAI,UAAU;AACZ,YAAM,IAAI,MAAM,yBAAyB,YAAY,MAAM,OAAO,EAAE,GAAG,EAAE;AAC3E,aAAS,KAAK,EAAE,MAAM,aAAa,MAAM,CAAC;AAAA,EAC5C;AACA,SAAO;AACT;AAoBA,eAAe,cAAc,KAAgC;AAC3D,MAAI;AACF,YAAQ,MAAMC,SAAQ,KAAK,EAAE,eAAe,KAAK,CAAC,GAC/C;AAAA,MACC,CAAC,MACC,EAAE,YAAY,KAAK,CAAC,EAAE,KAAK,WAAW,GAAG,KAAK,EAAE,SAAS;AAAA,IAC7D,EACC,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK;AAAA,EACV,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAGA,eAAe,OAAO,UAAkB,KAAqC;AAC3E,MAAI;AACF,WAAO;AAAA,MACL,MAAMC,WAAS,MAAM,cAAc,UAAU,GAAG,GAAG,MAAM;AAAA,IAC3D;AAAA,EACF,SAAS,GAAG;AACV,QAAK,EAA4B,SAAS,SAAU,QAAO;AAC3D,UAAM;AAAA,EACR;AACF;AAGA,eAAe,WACb,UACA,YACwB;AACxB,MAAI;AACF,WAAO,MAAMA;AAAA,MACX,MAAM,cAAc,UAAU,GAAG,UAAU,YAAY;AAAA,MACvD;AAAA,IACF;AAAA,EACF,SAAS,GAAG;AACV,QAAK,EAA4B,SAAS,SAAU,QAAO;AAC3D,UAAM;AAAA,EACR;AACF;AAGA,IAAM,mBAAmB,CAAC,SAAyB,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK;AAEzE,eAAe,QACb,GACA,MACA,aACA,MACA,QACgB;AAChB,QAAM,cAAiC;AAAA,IACrC;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,OAAO,SAAS,GAAG;AAAA,EAC9B;AACA,QAAM,OAAO,CAAC,SACZ,YAAY,KAAK,CAAC,QAAQ,IAAI,SAAS,iBAAiB,IAAI,CAAC;AAG/D,QAAM,YACJ,YAAY,gBAAgB,QACxB,CAAC,SAAiB,OAAO,SAAS,iBAAiB,IAAI,CAAC,IACxD,CAAC,SACC,CAAC,iBAAiB,WAAW,EAAE,SAAS,iBAAiB,IAAI,CAAC;AACtE,QAAM,SAAS,oBAAI,IAAqC;AACxD,QAAM,cAAc,oBAAI,IAAsB;AAC9C,MAAI,iBAAiB,WAAW;AAC9B,eAAW,OAAO,aAAa;AAC7B,YAAM,MAAMC,OAAK,EAAE,UAAU,IAAI,IAAI;AACrC,iBAAW,QAAQ,MAAM,gBAAgB,GAAG;AAC1C,eAAO,IAAI,GAAG,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,UAAU,CAAC,CAAC;AACzD,kBAAY,IAAI,IAAI,MAAM,MAAM,cAAc,GAAG,CAAC;AAAA,IACpD;AACF,QAAM,OAAO,UAAU,aAAa,aAAa,EAAE,KAAK,QAAQ,WAAW;AAC3E,QAAM,OACJ,YAAY,WAAW,QAAQ,YAAY,gBAAgB,OACvD,OACA;AAAA,IACE,QACE,YAAY,WAAW,OACnB,OACA,MAAM,OAAO,EAAE,UAAU,YAAY,MAAM;AAAA,IACjD,aAAa,YAAY;AAAA,EAC3B;AACN,SAAO;AAAA,IACL,OAAO,YAAY,SAAS,QAAQ,IAAI;AAAA,IACxC;AAAA,IACA,QAAQ,SAAS,aAAa,aAAa,IAAI;AAAA,IAC/C;AAAA,IACA,MAAM,CAAC,SAAS,KAAK,IAAI,KAAK,CAAC,UAAU,IAAI;AAAA,IAC7C;AAAA,IACA,SACE,YAAY,YAAY,OACpB,CAAC,IACD,MAAM,YAAY,EAAE,UAAU,YAAY,OAAO;AAAA,IACvD,IACE,YAAY,gBAAgB,QACxB,SACC,YAAY,SAAS,QAAQ,IAAI;AAAA,EAC1C;AACF;AAEA,IAAM,SAAS,CAAC,MAAsB,GAAG,CAAC,QAAQ,MAAM,IAAI,KAAK,GAAG;AAKpE,IAAM,QAAQ,CAAC,WAAW,WAAW,WAAW,MAAM;AACtD,IAAM,YAAuB,CAAC,IAAI,UAAU;AAC1C,aAAW,KAAK,OAAO;AACrB,UAAM,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,GAAG,CAAC;AACpD,QAAI,SAAS,OAAW,IAAG,KAAK,SAAS,CAAC;AAAA,QACrC,IAAG,KAAK,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC;AAAA,EAC7C;AACF;AAEA,IAAM,gBAA2B,CAAC,IAAI,OAAO,YAAY;AACvD,aAAW,QAAQ,CAAC,SAAS,UAAU,MAAM,GAAG;AAC9C,UAAM,QAAQ,MACX,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,CAAC,EACtC,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC;AACtC,QAAI,MAAM,SAAS,EAAG,IAAG,KAAK,WAAW,GAAG,IAAI,KAAK,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,EACzE;AACA,aAAW,KAAK,OAAO;AACrB,QAAI,EAAE,WAAW,QAAQ,EAAG,IAAG,KAAK,WAAW,CAAC;AAAA,aACvC,EAAE,WAAW,OAAO;AAC3B,SAAG,KAAK,UAAU,GAAG,OAAO,OAAO,EAAE,MAAM,QAAQ,MAAM,CAAC,EAAE;AAAA,aACrD,EAAE,WAAW,OAAO,EAAG,IAAG,KAAK,QAAQ,EAAE,MAAM,QAAQ,MAAM,CAAC;AAAA,EACzE;AACF;AAGA,eAAe,QACb,IACA,OACAC,QACA,MACe;AACf,MAAIA,WAAU,EAAG,QAAO,KAAK;AAC7B,QAAM,GAAG,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,MAAM,MAAM,IAAI;AACxD;AAGA,eAAe,QAAQ,UAAwC;AAC7D,QAAM,QAAQ,oBAAI,IAAY;AAC9B,QAAM,OAAO,OAAO,QAA+B;AACjD,UAAM,MAAM,QAAQ,KAAK,WAAWD,OAAK,UAAU,GAAG,IAAI,MAAM,GAAG,CAAC;AACpE,eAAW,KAAK,MAAMF,SAAQ,KAAK,EAAE,eAAe,KAAK,CAAC,GAAG;AAC3D,YAAM,OAAO,QAAQ,KAAK,EAAE,OAAO,GAAG,GAAG,IAAI,EAAE,IAAI;AACnD,UAAI,EAAE,YAAY,GAAG;AACnB,YAAI,EAAE,SAAS,UAAU,EAAE,SAAS,eAAgB,OAAM,KAAK,IAAI;AAAA,MACrE,WAAW,EAAE,OAAO,EAAG,OAAM,IAAI,IAAI;AAAA,IACvC;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AACb,SAAO;AACT;AAEA,IAAMG,SAAQ,CAAC,GAAW,SACxB,GAAG,CAAC,IAAI,IAAI,GAAG,MAAM,IAAI,KAAK,GAAG;AAQnC,SAAS,QACP,IACA,KACA,WACA,OACA,QACA,SACA,IACM;AAEN,QAAM,IAAI,CAAC,SACT,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,UACpC,SAAS,WAAW,UAAU;AACjC,QAAM,WAAW,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,MAAM,EAAE;AACtE,MAAI,EAAE,QAAQ,IAAI,EAAG,IAAG,KAAK,WAAWA,OAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;AACnE,MAAI,UAAU;AACZ,OAAG;AAAA,MACD;AAAA,MACA,GAAGA,OAAM,SAAS,OAAO,CAAC;AAAA,IAC5B;AACF,MAAI,EAAE,SAAS,IAAI;AACjB,OAAG;AAAA,MACD;AAAA,MACA,GAAGA,OAAM,EAAE,SAAS,GAAG,OAAO,CAAC,mBAAmB,GAAG;AAAA,IACvD;AACF,MAAI,WAAW,EAAG,IAAG,KAAK,YAAYA,OAAM,UAAU,OAAO,CAAC;AAC9D,MAAI,EAAE,QAAQ,IAAI;AAChB,OAAG,KAAK,SAAS,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,gCAAgC;AACzE,QAAM,UAAU,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC/C,QAAM,WAAW,MAAM;AAAA,IACrB,CAAC,MAAM,EAAE,SAAS,eAAe,QAAQ,IAAI,EAAE,EAAE;AAAA,EACnD,EAAE;AACF,QAAM,QACJ;AAAA,IACE,CAAC,WAAW,EAAE,QAAQ,CAAC;AAAA,IACvB,CAAC,WAAW,OAAO;AAAA,IACnB,CAAC,aAAa,EAAE,SAAS,CAAC;AAAA,IAC1B,CAAC,WAAW,EAAE,QAAQ,IAAI,QAAQ;AAAA,IAClC;AAAA,MACE;AAAA,MACA,YACE,EAAE,QAAQ,IACV,UACA,EAAE,SAAS,IACX,EAAE,QAAQ,IACV;AAAA,IACJ;AAAA,IACA,CAAC,YAAY,EAAE,OAAO,IAAI,EAAE,SAAS,CAAC;AAAA,EACxC,EAEC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,EACvB,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,EAAE;AACpC,KAAG;AAAA,IACD;AAAA,IACA,GAAG,OAAO,SAAS,CAAC,GAAG,OAAO,SAAY,KAAK,OAAO,EAAE,EAAE,GACxD,MAAM,SAAS,IAAI,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,EAC/C;AAAA,EACF;AACF;AAOA,eAAe,UACb,GACA,OACA,IACA,WACA,OACe;AACf,QAAM,WAAW,EAAE,SAAS,YAAY,EAAE,GAAG,CAAC;AAC9C,QAAM,EAAE,KAAK,IAAI;AAEjB;AAAA,IACE;AAAA,IACA,MAAM;AAAA,MACJ,EAAE;AAAA,MACF,MAAM;AAAA,MACN,MAAM,WAAW,EAAE,SAAS,aAAa,OAAO,MAAM,MAAM,CAAC;AAAA,IAC/D;AAAA,IACA,MAAM;AAAA,EACR;AACA,QAAM,OAAO,MAAM,WAAW,EAAE,SAAS,MAAM,KAAK,CAAC;AAKrD,QAAM,SAAS,MAAM,WAAW,EAAE,QAAQ;AAC1C,QAAM,MAAM,MAAM,WAAW,MAAM;AACnC,QAAM,SAAS,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,MAAM,KAAK,IAAI,CAAC,CAAC;AACtE,QAAM,SAAS,CAAC,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC;AAC9D,QAAM,OAAO,MAAM,UAAU,EAAE,UAAU;AAAA,IACvC,GAAG,cAAc,MAAM,IAAI;AAAA,IAC3B,GAAG,OAAO,OAAO;AAAA,EACnB,CAAC;AACD,QAAM,QAAQ,SAAS,MAAM,MAAM,MAAM,QAAQ,MAAM,SAAS;AAChE,QAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE;AAC5D,MAAI,SAAqB,CAAC;AAC1B,MAAI,OAAO;AACX,MAAI,UAAU;AACd,MAAI;AACF,UAAM,SAAS,oBAAI,IAAoB;AAGvC,UAAM,UAAU,oBAAI,IAAoB;AACxC,UAAM,SAAS,oBAAI,IAAY;AAC/B,QAAI;AAGF,YAAM;AAAA,QACJ;AAAA,QACA,YAAY,OAAO,OAAO,CAAC,OAAO,MAAM,KAAK;AAAA,QAC7C;AAAA,QACA,YAAY;AACV,qBAAWC,SAAQ,OAAO;AACxB,kBAAM,IAAI,MAAM,WAAW,EAAE,SAAS,MAAM,OAAOA,KAAI,CAAC;AACxD,gBACE,MAAM,SACLA,MAAK,SAAS,YAAYA,MAAK,SAAS;AAEzC,qBAAO,IAAIA,MAAK,KAAK,MAAM,CAAC;AAE9B,gBAAI,GAAG,YAAY,KAAM;AAAA,qBAChB,MAAM,QAAQA,MAAK,SAAS;AACnC,sBAAQ,IAAIA,MAAK,KAAK,MAAM,CAAC;AAC/B,gBAAIA,MAAK,SAAS,WAAWA,MAAK,SAAS;AACzC,qBAAO,IAAIA,MAAK,EAAE;AACpB,gBAAIA,MAAK,SAAS,YAAa;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAAA,IACF,UAAE;AAEA,YAAM;AAAA,QACJ;AAAA,QACA,IAAI,IAAI;AAAA,UACN,GAAG;AAAA,UACH,GAAG,YAAY,QAAQ,MAAM,MAAM,QAAQ,OAAO;AAAA,QACpD,CAAC;AAAA,MACH;AAAA,IACF;AACA,UAAM,SAAS,YAAY,OAAO,MAAM,MAAM;AAC9C,UAAM,UAAU,IAAI,IAAI,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACxE,UAAM,QAAQ,MAAM,QAAQ,EAAE,QAAQ;AACtC,UAAM,SAAS,oBAAI,IAAoB;AACvC,eAAW,KAAK;AACd,aAAO;AAAA,QACL,EAAE;AAAA,QACF,UAAU;AAAA,UACR,MAAM,EAAE;AAAA,UACR,MAAM,MAAMH,WAASC,OAAK,EAAE,UAAU,GAAG,EAAE,KAAK,MAAM,GAAG,CAAC,GAAG,MAAM;AAAA,UACnE,KAAK,EAAE;AAAA,UACP;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AACF,aAAS,WAAW,QAAQ,MAAM;AAClC,UAAM;AAAA,MACJ;AAAA,MACA,YAAY,OAAO,OAAO,MAAM,CAAC,cAAc,MAAM,KAAK;AAAA,MAC1D,OAAO;AAAA,MACP,YAAY;AACV,mBAAWE,SAAQ,QAAQ;AACzB,gBAAM,WAAW,EAAE,SAAS,MAAM,OAAOA,KAAI,CAAC;AAC9C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,GAAG;AACV,QAAI,EAAE,aAAa,gBAAiB,OAAM;AAC1C,UAAM,QAAQ,UAAU,OAAO;AAC/B,UAAM,IAAI;AAAA,MACR,GAAG,EAAE,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK;AAAA,MACzC,EAAE,OAAO,EAAE;AAAA,IACb;AAAA,EACF;AACA,UAAQ,IAAI,EAAE,KAAK,KAAK,QAAQ,OAAO,QAAQ,SAAS,MAAM,EAAE;AAChE,MAAI,MAAM,SAAS;AACjB,eAAW,QAAQ,MAAM,WAAW,EAAE,SAAS,SAAS,OAAO,MAAM,IAAI,CAAC;AACxE,SAAG,KAAK,SAAS,GAAG,IAAI,OAAO,MAAM,KAAK,EAAE;AAChD,aAAW,QAAQ,MAAM;AAAA,IACvB,EAAE,SAAS,YAAY,OAAO,MAAM,OAAO;AAAA,EAC7C,GAAG;AACD,UAAM,CAAC,MAAM,GAAG,IAAI,IAAI,KAAK,MAAM,GAAG;AACtC,OAAG,KAAK,QAAQ,UAAU,KAAK,KAAK,GAAG,CAAC;AAAA,EAC1C;AACF;AAMA,eAAe,QACb,GACA,UACA,IACA,WACe;AACf,QAAM,OAAO,MAAM,WAAW,EAAE,QAAQ;AACxC,aAAW,KAAK,UAAU;AAExB,UAAM,SAAS,SACZ,OAAO,CAAC,MAAM,MAAM,CAAC,EACrB,QAAQ,CAAC,MAAM,iBAAiB,EAAE,WAAW,CAAC;AACjD,UAAM;AAAA,MACJ;AAAA,MACA,EAAE;AAAA,MACF;AAAA,MACA,UAAU,EAAE,IAAI;AAAA,MAChB,MAAM,QAAQ,GAAG,EAAE,MAAM,EAAE,aAAa,MAAM,MAAM;AAAA,IACtD;AAAA,EACF;AACF;AAOA,eAAsB,eACpB,UACA,MACe;AACf,MAAI,SAAS,MAAO;AACpB,QAAM,OAAO,MAAM,WAAW,QAAQ;AACtC,MAAI,CAAC,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACnC,UAAM,IAAI;AAAA,MACR,WAAW,IAAI,MAAM,IAAI;AAAA,IAC3B;AACJ;AAGA,IAAM,UAAU,CAAC,MACf,EAAE,YAAY,SAAS,QAAQ,EAAE,IAAI;AASvC,eAAe,aACb,GACA,QACA,MACA,UACA,IACA,MACyD;AACzD,aAAW,KAAK,OAAQ,OAAM,eAAe,EAAE,UAAU,EAAE,IAAI;AAI/D,QAAM,WAAW,WAAW,EAAE,QAAQ;AACtC,MAAI,CAAC,UAAU,QAAQ,EAAE;AACvB,UAAM,IAAI;AAAA,MACR,kFAAkF,QAAQ;AAAA,IAC5F;AACF,QAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AACtC,MAAI,KAAK,cAAc,QAAQ,KAAK,QAAQ,MAAM;AAChD,QAAI,CAAC,SAAS,MAAM,EAAG,QAAO,EAAE,GAAG,MAAM,CAAC,GAAG,MAAM,MAAM;AACzD,UAAM,IAAI,MAAM,SAAS,QAAQ;AACjC,UAAM,KAAK,MAAM,EAAE,QAAQ;AAAA,MACzB,SAAS,UAAU,OAAO,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC,kBAAkB,EAAE,GAAG;AAAA,IACrG,CAAC;AACD,QAAI,EAAE,SAAS,EAAE,KAAK,OAAO,KAAM,QAAO,EAAE,GAAG,MAAM,CAAC,GAAG,MAAM,MAAM;AAAA,EACvE;AACA,QAAM,UAAU,MAAM,cAAc,EAAE,QAAQ;AAC9C,MAAI,YAAY,MAAM;AACpB,QAAI,KAAK,QAAQ,QAAQ,CAAC,SAAS,MAAM,EAAG,OAAM,IAAI,MAAM,OAAO;AACnE,UAAM,IAAI,MAAM,SAAS,QAAQ;AACjC,UAAM,KAAK,MAAM,EAAE,QAAQ;AAAA,MACzB,SACE,YAAY,cACR,mEACA;AAAA,IACR,CAAC;AACD,QAAI,EAAE,SAAS,EAAE,KAAK,OAAO,KAAM,OAAM,IAAI,MAAM,OAAO;AAC1D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,QACE,SAAS;AAAA;AAAA,QAET,UAAU;AAAA,QACV,GAAI,KAAK,cAAc,SAAY,CAAC,IAAI,EAAE,WAAW,KAAK,UAAU;AAAA,MACtE;AAAA,MACA,EAAE,UAAU,IAAI,GAAI,KAAK,QAAQ,SAAY,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,EAAG;AAAA,IACvE;AACA,QAAI,SAAS,EAAG,OAAM,IAAI,MAAM,OAAO;AACvC,QAAI;AAAA,MACF,GAAG;AAAA,MACH,UAAU,MAAM,aAAa,EAAE,UAAU,gBAAgB,MAAM,IAAI,CAAC;AAAA,IACtE;AACA,UAAM,QAAQ,MAAM,cAAc,EAAE,QAAQ;AAC5C,QAAI,UAAU,KAAM,OAAM,IAAI,MAAM,KAAK;AAAA,EAC3C;AAEA,QAAM,WAAW,EAAE,SAAS,YAAY,EAAE,GAAG,CAAC;AAC9C,QAAM,SAAS,MAAM,EAAE,SAAS,SAAS,IAAI,SAAS;AACtD,KAAG;AAAA,IACD;AAAA,IACA,GAAG,QAAQ,kBAAkB,KAAK,WAAW,aAAa;AAAA,EAC5D;AACA,QAAM,OAAiB,CAAC;AACxB,aAAW,KAAK,QAAQ;AAItB,UAAM,SACJ,OAAO,EAAE,UAAU,WACf,MAAM,aAAa,EAAE,MAAM,EAAE,UAAU,MAAM,EAAE,KAAK,IACpD,EAAE,YAAY;AACpB,UAAM,SACJ,OAAO,EAAE,UAAU,YAAY,EAAE,SAAS,QACtC,MAAM,WAAW,EAAE,UAAU,EAAE,IAAI,IACnC;AACN,UAAM,QAAQ,QAAQ,CAAC;AACvB,UAAM,QAAQ,MAAM,WAAW,EAAE,SAAS,YAAY,EAAE,KAAK,KAAK,CAAC;AAInE,UAAM,WAAqB;AAAA,MACzB,GAAG,EAAE;AAAA,MACL,UAAU;AAAA,MACV,QAAQ;AAAA,QACN,GAAG,EAAE,SAAS;AAAA,QACd,CAAC,EAAE,IAAI,GAAG,WAAW,EAAE,MAAM,EAAE,QAAQ,MAAM,QAAQ,GAAG,OAAO,CAAC;AAAA,MAClE;AAAA,IACF;AACA,UAAM,cAAc,EAAE,UAAU,QAAQ;AACxC,QAAI,WAAW,MAAM;AACnB,YAAM,UAAU,oBAAoB,MAAM;AAC1C,UAAI,YAAY;AACd,cAAM,gBAAgBF,OAAK,EAAE,UAAU,EAAE,MAAM,WAAW,GAAG,OAAO;AAAA,IACxE;AACA,QAAI,EAAE,GAAG,GAAG,SAAS;AACrB,SAAK,KAAK,EAAE,IAAI;AAChB,OAAG,KAAK,WAAW,GAAG,KAAK,MAAM,MAAM,GAAG,EAAE;AAAA,EAC9C;AACA,SAAO,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE;AAC7B;AAMA,eAAsB,iBACpB,MACA,OAA6B,CAAC,GACb;AACjB,MAAI;AACF,UAAM,WAAW,KAAK,YAAY;AAClC,UAAM,KAAK,KAAK,MAAO,MAAM,OAAO,QAAQ;AAC5C,UAAM,OAAO,SAAS,MAAM,EAAE;AAC9B,QAAI,IAAI,MAAM,QAAQ,MAAM,IAAI;AAChC,QAAI,EAAE,SAAS,WAAW,KAAM,OAAM,QAAQ,CAAC;AAC/C,UAAM,EAAE,WAAW,IAAI,MAAM,aAAa,GAAG,EAAE;AAC/C,QAAI,OAAiB,CAAC;AACtB,QAAI,OAAiB,CAAC;AACtB,QAAI,WAAW,SAAS;AACtB,OAAC,EAAE,GAAG,MAAM,KAAK,IAAI,MAAM;AAAA,QACzB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACF,QAAI;AAEF,YAAM,WAAW,MAAM,eAAe,CAAC;AACvC,YAAM;AAAA,QAAQ;AAAA,QAAG;AAAA,QAAU;AAAA,QAAI,CAAC,MAC9B,KAAK,SAAS,CAAC,IAAI,gBAAgB;AAAA,MACrC;AAAA,IACF,UAAE;AACA,UAAI,KAAK,SAAS;AAChB,WAAG;AAAA,UACD;AAAA,UACA,GAAG,KAAK,KAAK,IAAI,CAAC,6EAA6E,KAAK,KAAK,IAAI,CAAC;AAAA,QAChH;AAAA,IACJ;AACA,QAAI,KAAK,SAAS;AAChB,YAAM,IAAI;AAAA,QACR,gBAAgB,KAAK,KAAK,IAAI,CAAC,6DAA6D,KAAK,WAAW,IAAI,OAAO,MAAM;AAAA,MAC/H;AACF,WAAO;AAAA,EACT,SAAS,GAAG;AACV,WAAO,YAAY,CAAC;AAAA,EACtB;AACF;AAGA,SAAS,WAAW,GAAwC;AAC1D,QAAMG,UAAS,OAAO,QAAQ,EAAE,MAAM;AACtC,QAAM,QAAQA,QAAO;AAAA,IACnB,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,KAAK,SAAS,QAAQ;AAAA,EAC5D,IAAI,CAAC;AACL,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO;AAAA,IACL;AAAA,IACA,SAASA,QAAO,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,SAAS,UAAU,CAAC,IAAI,CAAC,KAAK;AAAA,EACvE;AACF;AAGO,IAAM,QAAQ,CAAC,GAAa,SACjC,SAAS,CAAC,KACV,iBAAiB,EAAE,WAAW,EAAE,SAAS,iBAAiB,IAAI,CAAC;AAGjE,IAAM,UAAU,CAAC,GAAY,aAC3B,GAAG,EAAE,GAAG,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,MAAM,MAAM,EAAE,KAAK,GAAG,CAAC;AAQ3D,eAAe,OACb,GACA,UACA,QACA,SACA,MACA,SAA4C,CAAC,IAAI,MAAM;AACrD,QAAM;AACR,GACe;AACf,QAAM,MAAM,QAAQ,GAAG,QAAQ;AAC/B,QAAM,YAAY,MAAM,QAAQ,GAAG,UAAU,SAAS,MAAM,SAAS;AAGrE,QAAM,SAAS,CAAC,UACd,WAAW,EAAE,SAAS,MAAM,OAAO,EAAE,QAAQ,MAAM,CAAC,CAAC;AACvD,QAAM,YAAY,IAAI;AAAA,KACnB,MAAM,WAAW,EAAE,QAAQ,GAAG;AAAA,MAAQ,CAAC,MACtC,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAU;AAAA,IAC/C;AAAA,EACF;AACA,MAAI,QAAQ,oBAAI,IAA2B;AAC3C,QAAM,UAAU,YAAY;AAC1B,YAAQ,oBAAI,IAAI;AAChB,eAAW,KAAK,SAAU,OAAM,IAAI,GAAG,MAAM,OAAO,EAAE,KAAK,CAAC;AAAA,EAC9D;AACA,QAAM,QAAQ;AACd,QAAM,UAAU,IAAI;AAAA,IAClB,CAAC,GAAG,MAAM,OAAO,CAAC,EACf,KAAK,EACL,QAAQ,CAAC,MAAO,EAAE,SAAS,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAU,CAAE;AAAA,EAC1E;AACA,QAAM,QAAQ,CAAC,SACb,UAAU,IAAI,IAAI,MACjB,CAAC,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,MAAM,UAAU,IAAI,IAAI;AACjE,QAAM,MAAM,IAAI,IAAI,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAI,CAAC,GAAG,GAAG,EAAE,KAAK,KAAK,GAAG;AAExB,QAAI,MAAM,eAAe,KAAK,WAAW,IAAI,EAAG,OAAM,QAAQ;AAAA,EAChE;AACA,aAAW,KAAK,UAAU;AACxB,UAAM,QAAQ,OAAO,IAAI,CAAC;AAC1B,QAAI,UAAU,OAAW;AACzB,QAAI;AACF,YAAM,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,GAC3B,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,MAAM,IAAI,EAAE,IAAI,CAAC,EAClD,IAAI,CAAC,MAAM,EAAE,EAAE;AAClB,UAAI,IAAI,SAAS;AACf,cAAM;AAAA,UACJ,EAAE,SAAS;AAAA,YACT,EAAE;AAAA,YACF;AAAA,YACA;AAAA,YACA,WAAW,EAAE,WAAW,KAAK;AAAA,UAC/B;AAAA,QACF;AAAA,IACJ,SAAS,GAAG;AACV,aAAO,GAAG,CAAC;AAAA,IACb;AAAA,EACF;AACF;AAOA,eAAe,QACb,GACA,GACA,SACe;AACf,QAAMA,UAAS,WAAW,EAAE,WAAW,KAAK;AAAA,IAC1C,OAAO;AAAA,IACP,SAAS;AAAA,EACX;AACA,QAAM,KAAK,QAAQ,MAAM,QAAK,EAAE,IAAI,KAAK;AACzC,QAAM,OAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EAAE,OAAO,EAAE,QAAQ,MAAM,CAAC,CAAC,GACvE,OAAO,CAAC,MAAM;AACb,UAAM,KACJA,QAAO,YAAY,OACf,OACC,EAAE,OAAOA,QAAO,OAAO,MACvBA,QAAO,YAAY,oBAAoB,EAAE,UAAU;AAC1D,WAAOA,QAAO,YAAY,OACtB,EAAE,OAAOA,QAAO,KAAK,MAAM,SAC3B,OAAO,WAAW,IAAI,SAAS,SAAM,EAAE,EAAE,MAAM;AAAA,EACrD,CAAC,EACA,IAAI,CAAC,MAAM,EAAE,EAAE;AAClB,QAAM,WAAW,EAAE,SAAS,KAAK,EAAE,OAAO,KAAK,MAAMA,OAAM,CAAC;AAC9D;AAwBA,eAAsB,gBAAgB,MAAmC;AACvE,QAAM,WAAqB,CAAC;AAC5B,MAAI;AACF,UAAM,IAAI,MAAM,QAAQ;AAAA,EAC1B,SAAS,GAAG;AACV,aAAS,KAAK,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,EAC1D;AACA,MAAI,SAAS,SAAS,EAAG,OAAM,cAAc,SAAS,KAAK,IAAI,CAAC;AAChE,SAAO;AACT;AAEA,eAAe,IAAI,MAAkB,UAAmC;AACtE,QAAM,QAAQ,YAAY,KAAK,CAAC,MAAM,MAAM,KAAK,KAAK;AACtD,MAAI,UAAU,OAAW,OAAM,IAAI,MAAM,kBAAkB,KAAK,KAAK,EAAE;AACvE,QAAM,IAAI,MAAM,QAAQ,IAAI;AAC5B,QAAM,WAAW,MAAM,eAAe,CAAC;AACvC,QAAM,OAAO,KAAK,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;AACjE,QAAM,QAAQ,CAAC,MAAwB,EAAE,YAAY,SAAS,QAAQ,EAAE,IAAI;AAC5E,QAAM,SAAS,CAAC,SACd,SAAS;AAAA,IAAO,CAAC,OACd,EAAE,YAAY,MAAM,KAAK,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,WAAW,IAAI;AAAA,EAClE;AACF,MAAI,UAAU,eAAe;AAC3B,eAAW,KAAK,OAAO,iBAAiB;AACtC,UAAI;AACF,cAAM,EAAE,YAAY,IAAI,MAAM,OAAO,uBAAqB;AAC1D,cAAM,YAAY;AAAA,UAChB;AAAA,UACA,OAAO;AAAA,UACP,SAAS,KAAK;AAAA,UACd,OAAO,KAAK,SAAS;AAAA,UACrB,GAAI,KAAK,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;AAAA,QAC1D,CAAC;AAAA,MACH,SAAS,GAAG;AACV,iBAAS;AAAA,UACP,sBAAsB,MAAM,CAAC,CAAC,YAAY,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,QACtF;AAAA,MACF;AACF,UAAM,WAAW,OAAO,aAAa;AACrC,eAAW,KAAK;AACd,UAAI;AACF,cAAM,QAAQ,GAAG,GAAG,KAAK,OAAO;AAAA,MAClC,SAAS,GAAG;AACV,iBAAS;AAAA,UACP,kBAAkB,MAAM,CAAC,CAAC,YAAY,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,QAClF;AAAA,MACF;AACF,QAAI,SAAS,WAAW,EAAG;AAE3B,UAAM;AAAA,MACJ,QAAQ,GAAG,QAAQ;AAAA,MACnB,MAAM,QAAQ,GAAG,UAAU,SAAS,MAAM,SAAS;AAAA,MACnD,EAAE,GAAG,MAAM,MAAM,KAAK;AAAA,IACxB;AACA;AAAA,EACF;AACA,QAAM,SAAS,oBAAI,IAA2B;AAC9C,QAAM,SAAS,UAAU,SAAS,SAAS;AAC3C,aAAW,KAAK,OAAO,MAAM,GAAG;AAC9B,QAAI,QAAQ,KAAK;AACjB,QAAI,UAAU,iBAAiB;AAC7B,YAAM,KAAK,EAAE,YAAY,MAAM,eAAe,KAAK,CAAC,GAAG;AAAA,QACrD,CAAC,MAAM,EAAE,WAAW;AAAA,MACtB;AACA,cACE,GAAG,WAAW,qBACV,MAAM;AAAA,QACJ,EAAE,MAAM,EAAE,MAAM,UAAU,EAAE,SAAS;AAAA,QACrC,EAAE;AAAA,QACF,KAAK,SAAS;AAAA,QACd,EAAE;AAAA,QACF,EAAE;AAAA,MACJ,IACA,CAAC;AAAA,IACT;AACA,UAAM,OAAO,MAAM,OAAO,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC;AAC5C,QAAI,KAAK,SAAS,EAAG,QAAO,IAAI,GAAG,IAAI,IAAI,IAAI,CAAC;AAAA,EAClD;AACA,MAAI,OAAO,SAAS,EAAG;AACvB,QAAM;AAAA,IAAO;AAAA,IAAG;AAAA,IAAU;AAAA,IAAQ,KAAK;AAAA,IAAS;AAAA,IAAM,CAAC,GAAG,MACxD,SAAS;AAAA,MACP,GAAG,MAAM,OAAO,MAAM,CAAC,CAAC,YAAY,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,IAChF;AAAA,EACF;AACF;AAOA,eAAsB,mBACpB,YACA,MACA,OAA6B,CAAC,GACb;AACjB,MAAI;AACF,UAAM,OAAO,cAAc;AAC3B,UAAM,KAAK,MAAM,cAAc,KAAK,OAAO,QAAQ,IAAI,CAAC;AACxD,UAAM,WAAW,MAAM,aAAa,GAAG,QAAQ;AAC/C,QAAI,SAAS,QAAQ;AACnB,YAAM,IAAI,MAAM,sDAAsD;AACxE,UAAM,UAAU,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC7D,QAAI,YAAY;AACd,YAAM,IAAI,MAAM,kCAAkC,QAAQ,MAAM,EAAE;AACpE,QAAI,OAAO;AACX,QAAI,SAAS,SAAS,IAAI,MAAM,QAAW;AACzC,YAAM,eAAe,GAAG,UAAU,IAAI;AACtC,YAAM,SAAS,UAAU,IAAI;AAC7B,YAAM,cAAc,GAAG,UAAU;AAAA,QAC/B,GAAG;AAAA,QACH,QAAQ,EAAE,GAAG,SAAS,QAAQ,CAAC,IAAI,GAAG,OAAO;AAAA,MAC/C,CAAC;AACD,aAAO,iDAAiD,IAAI,OAAO,MAAM;AAAA,IAC3E;AACA,YAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAChC,WAAO,MAAM,iBAAiB,EAAE,GAAG,MAAM,WAAW,KAAK,GAAG,IAAI;AAAA,EAClE,SAAS,GAAG;AACV,WAAO,YAAY,CAAC;AAAA,EACtB;AACF;","names":["readFile","join","fields","join","readFile","target","join","join","join","posix","join","status","join","reason","fields","list","views","dirname","resolve","readFile","basename","join","fail","isRecord","basename","isRecord","fail","target","readFile","join","execFile","promisify","execFileP","firstLine","join","posix","status","fields","posix","join","context","init","status","post","isRecord","values","labelIds","readFile","rm","join","reason","join","readFile","rm","posix","comment","run","fence","posix","readFile","readdir","join","FIELD_TYPES","isRecord","isNames","readFile","readField","readLabels","join","fields","values","readdir","statusOf","status","values","views","fields","sessionsOf","firstLine","step","WORKING","valueOf","values","fields","fields","wanted","ordered","fresh","status","byName","shown","gone","repository","valueOf","step","issue","firstLine","id","values","WORKING","step","fields","glob","readFile","rm","isAbsolute","join","posix","relative","resolve","sep","join","rm","clone","resolve","relative","isAbsolute","readFile","glob","sep","posix","readdir","dirname","join","parse","resolve","resolve","parse","dirname","join","readdir","DONE","realpath","spawn","execFile","promisify","execFileP","shown","realpath","mkdir","readFile","rename","rm","writeFile","dirname","join","readFile","mkdir","dirname","writeFile","rename","clone","rm","join","readFile","readdir","join","delay","mkdir","open","readFile","rm","stat","writeFile","join","delay","join","reason","mkdir","writeFile","readFile","rm","LOCK_STALE_MS","open","stat","delay","mkdir","readFile","rename","rm","writeFile","dirname","NAME","readFile","rm","mkdir","dirname","writeFile","rename","mkdir","readFile","rename","rm","writeFile","dirname","NAME","readFile","rm","mkdir","dirname","writeFile","rename","readFile","views","stat","join","exists","stat","join","fields","views","readFile","isRecord","same","fields","delay","readdir","readFile","join","count","step","fields"]}