@noir-ai/cli 1.11.2 → 1.13.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/bin.js +4052 -713
  2. package/dist/bin.js.map +1 -1
  3. package/dist/index.js +6755 -6
  4. package/dist/index.js.map +1 -1
  5. package/dist/{chunk-QIVHIKYD.js → tui/chunk-2RK6AFZQ.js} +37 -16
  6. package/dist/tui/chunk-2RK6AFZQ.js.map +1 -0
  7. package/dist/tui/{chunk-R5YX44UL.js → chunk-ESZTOQEC.js} +211 -2
  8. package/dist/tui/chunk-ESZTOQEC.js.map +1 -0
  9. package/dist/tui/chunk-KMLSJRYV.js +5618 -0
  10. package/dist/tui/chunk-KMLSJRYV.js.map +1 -0
  11. package/dist/{create-VK2QMXYS.js → tui/create-HYFBTBLR.js} +4 -4
  12. package/dist/tui/{create-WKFVM237.js.map → create-HYFBTBLR.js.map} +1 -1
  13. package/dist/tui/index.js +45 -3454
  14. package/dist/tui/index.js.map +1 -1
  15. package/dist/tui/{install-JR6ZXNYA.js → install-YGTUSLRO.js} +2 -3
  16. package/dist/{sync-VXZKODQA.js → tui/sync-QDOJ7INZ.js} +4 -4
  17. package/dist/tui/{sync-DUWJAF7Z.js.map → sync-QDOJ7INZ.js.map} +1 -1
  18. package/dist/tui/{update-PGAM6OVL.js → update-LET5BWOU.js} +3 -4
  19. package/package.json +12 -12
  20. package/dist/chunk-A5W2E3X2.js +0 -33
  21. package/dist/chunk-A5W2E3X2.js.map +0 -1
  22. package/dist/chunk-CT6TYLHN.js +0 -1105
  23. package/dist/chunk-CT6TYLHN.js.map +0 -1
  24. package/dist/chunk-I2R55ACD.js +0 -369
  25. package/dist/chunk-I2R55ACD.js.map +0 -1
  26. package/dist/chunk-QIVHIKYD.js.map +0 -1
  27. package/dist/chunk-RON2XESF.js +0 -210
  28. package/dist/chunk-RON2XESF.js.map +0 -1
  29. package/dist/create-VK2QMXYS.js.map +0 -1
  30. package/dist/install-4U4UDDNE.js +0 -13
  31. package/dist/sync-VXZKODQA.js.map +0 -1
  32. package/dist/tui/chunk-F6XRS72N.js +0 -1106
  33. package/dist/tui/chunk-F6XRS72N.js.map +0 -1
  34. package/dist/tui/chunk-NLK6UNIA.js +0 -223
  35. package/dist/tui/chunk-NLK6UNIA.js.map +0 -1
  36. package/dist/tui/chunk-QF6777NJ.js +0 -209
  37. package/dist/tui/chunk-QF6777NJ.js.map +0 -1
  38. package/dist/tui/chunk-R5YX44UL.js.map +0 -1
  39. package/dist/tui/create-WKFVM237.js +0 -79
  40. package/dist/tui/sync-DUWJAF7Z.js +0 -90
  41. package/dist/tui/update-PGAM6OVL.js.map +0 -1
  42. package/dist/update-ZDAVLOXB.js +0 -20
  43. package/dist/update-ZDAVLOXB.js.map +0 -1
  44. /package/dist/{install-4U4UDDNE.js.map → tui/install-YGTUSLRO.js.map} +0 -0
  45. /package/dist/tui/{install-JR6ZXNYA.js.map → update-LET5BWOU.js.map} +0 -0
@@ -1,13 +1,13 @@
1
- #!/usr/bin/env node
2
1
  import {
3
2
  assertTransportUrl,
4
3
  buildConflictOpts,
5
4
  checkWritePathDedup,
6
5
  reportPlannedWrites
7
- } from "./chunk-CT6TYLHN.js";
6
+ } from "./chunk-KMLSJRYV.js";
7
+ import "./chunk-2RK6AFZQ.js";
8
8
  import {
9
9
  resolveInteractive
10
- } from "./chunk-I2R55ACD.js";
10
+ } from "./chunk-ESZTOQEC.js";
11
11
 
12
12
  // src/commands/create.ts
13
13
  import { resolve } from "path";
@@ -77,4 +77,4 @@ async function create(dir, opts) {
77
77
  export {
78
78
  create
79
79
  };
80
- //# sourceMappingURL=create-VK2QMXYS.js.map
80
+ //# sourceMappingURL=create-HYFBTBLR.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/create.ts"],"sourcesContent":["// `noir create [dir]` — greenfield first-run for the AI layer only.\n//\n// Slice S — new command. Bootstraps Noir's AI layer (.noir/ store, host\n// pointers, skills) into `dir` (created if absent), with NO external\n// scaffolder chaining (S-OQ1 = AI-layer only; no `pnpm create` wrapping).\n//\n// Reuses init's transport/url handling (including the localhost security\n// gate) by calling into the same engine: `scaffold({mode:'create', root})`.\n// The only difference from `noir init` is the mode tag (which selects the\n// manifest's first-run subset + generates a fresh project id unconditionally)\n// and that the target dir is `resolve(dir ?? cwd)` rather than `process.cwd()`.\n//\n// S10 multi-host: gains `--host <id>` (default `'claude'`); the host drives\n// both scaffold emission + skills emission via `resolveAdapter(host)` —\n// shared with init through `emitHostSkills`. See `init.ts` for the matrix.\n//\n// Stream discipline matches init: diagnostics → stderr, nothing on stdout\n// (so `noir create --json` is safe by construction — there is no data payload).\n//\n// Exit codes: `assertTransportUrl` is called DIRECTLY (M2) so transport/url\n// errors propagate as plain `Error` → bin.ts's handleError → exit 1, EXACTLY\n// matching `noir init` for the same error class. (The S9 spec lists usage=2 for\n// a missing `--url`; neither `init` nor `create` implements that split today —\n// both report it as a plain error=1 — and the review asked for consistency\n// over a one-sided fix. Changing them together is a separate, contract-level\n// change.) The target dir is created by the engine's `create` mode (N1: the\n// duplicate mkdir that used to live here is gone — one attributable failure\n// point, in scaffold.ts).\n\nimport { resolve } from 'node:path';\nimport { type HostId, resolveAdapter } from '@noir-ai/adapters';\nimport { loadProjectInfo, type ProjectInfo } from '@noir-ai/core';\nimport { type ScaffoldResult, scaffold } from '@noir-ai/create';\nimport { type CompileTarget, emitSkillsToDir } from '@noir-ai/skills';\nimport { buildConflictOpts } from '../conflict.js';\nimport { checkWritePathDedup } from '../dedup-write.js';\nimport { assertTransportUrl, reportPlannedWrites } from '../init.js';\nimport { resolveInteractive } from '../output.js';\n\nexport interface CreateOptions {\n transport: 'stdio' | 'streamable-http';\n url?: string;\n /** S10 target host. Defaults to `'claude'`. */\n host?: HostId;\n /** SP-A: re-scaffold even if already initialized. */\n force?: boolean;\n /** F1: `--dry-run`/`--preview` — report the planned writes to stderr\n * without touching disk (incl. NOT creating the target dir). */\n dryRun?: boolean;\n /** F1: alias for `--dry-run`. Kept on the options bag so direct callers can\n * pass either spelling; the bin collapses both flags before dispatch. */\n preview?: boolean;\n}\n\n/**\n * Bootstrap Noir's AI layer in `dir`. Returns the {@link ScaffoldResult} (with\n * structured `conflicts[]` + any dedup records appended); the bin\n * emits it under `--json`. `undefined` when the already-initialized guard\n * short-circuited (a no-op).\n *\n * @param dir Target directory (created if absent). Defaults to `process.cwd()`.\n * @param opts Transport + URL + host (same semantics as `noir init`).\n */\nexport async function create(\n dir: string | undefined,\n opts: CreateOptions,\n): Promise<ScaffoldResult | undefined> {\n // M2: call assertTransportUrl directly so the SAME error class yields the SAME\n // exit code as `noir init` (plain Error → exit 1 for both missing-url and\n // non-localhost). The previous NoirCliError(EXIT.USAGE) wrapper made `create`\n // exit 2 where `init` exits 1.\n assertTransportUrl(opts);\n\n const root = resolve(dir ?? process.cwd());\n const host: HostId = opts.host ?? 'claude';\n // Derive interactive once (consistency with init/sync) so both scaffold\n // and skills emission see the same hermetic flag.\n const interactive = resolveInteractive();\n const conflictOpts = buildConflictOpts({ force: opts.force, interactive });\n // F1: --dry-run/--preview collapse to a single dryRun boolean. The engine\n // skips the target-dir mkdir + every write; skills emission + dedup are\n // skipped too (they would touch disk / load the embedder).\n const dryRun = opts.dryRun === true || opts.preview === true;\n\n const res = await scaffold({\n root,\n mode: 'create',\n host,\n transport: opts.transport,\n interactive,\n ...(opts.url !== undefined ? { url: opts.url } : {}),\n ...(opts.force === true ? { force: true } : {}),\n ...(dryRun ? { dryRun: true } : {}),\n ...conflictOpts,\n });\n // F1: dry-run reports the planned writes and stops BEFORE skills emission +\n // the \"created\" message — the target dir was NOT created, so nothing may\n // touch disk. (The engine's create-mode mkdir is gated on !dryRun.)\n if (dryRun) {\n reportPlannedWrites(res);\n return res;\n }\n // SP-A: a no-op (already-initialized guard) must not re-emit skills.\n if (res.noop) return res;\n\n // Skills are out-of-manifest by design — same composition as init.\n const adapter = resolveAdapter(host);\n const skillsDir = adapter.skillsDir?.({ root });\n if (skillsDir === undefined) {\n // N1: standardized wording — same phrase across init/sync/create so logs\n // grep uniformly. (Pre-N1 each command phrased this differently.)\n process.stderr.write(`host '${host}' has no skill emitter; skipping skills\\n`);\n } else {\n const target: CompileTarget = host;\n // Forward conflictOpts so an interactive `noir create` with a\n // conflicting skill emit consults the resolver (mirrors init/sync).\n type SkillEmitOpts = NonNullable<Parameters<typeof emitSkillsToDir>[1]>;\n const skillOpts: SkillEmitOpts = {\n includeIntegrations: true,\n target,\n conflictPolicy: conflictOpts.conflictPolicy,\n interactive,\n };\n if (conflictOpts.onConflict !== undefined) {\n skillOpts.onConflict = conflictOpts.onConflict as SkillEmitOpts['onConflict'];\n }\n const summary = await emitSkillsToDir(skillsDir, skillOpts);\n const relDir = skillsDir.replace(`${root}/`, '');\n process.stderr.write(\n `Emitted ${summary.emitted.length} Noir skills to ${relDir}/ (target: ${target}).\\n`,\n );\n }\n\n // Write-path semantic dedup. Greenfield create rarely has\n // existing host-context candidates (the target dir is fresh), so the fast\n // path fires; `--force` on a pre-existing Noir project reads the config and\n // runs the full dedup. Best-effort: a missing/corrupt config warn-skips.\n let projectInfo: ProjectInfo | undefined;\n try {\n projectInfo = loadProjectInfo(root);\n } catch {\n projectInfo = undefined;\n }\n const dedup = await checkWritePathDedup(root, res, { interactive, project: projectInfo });\n if (dedup.conflicts.length > 0) res.conflicts.push(...dedup.conflicts);\n\n process.stderr.write(`Noir created in ${root} (host: ${host}, transport: ${opts.transport}).\\n`);\n process.stderr.write('Next: cd into the new directory, then run `noir` to open the home menu.\\n');\n return res;\n}\n"],"mappings":";;;;;;;;;;;AA6BA,SAAS,eAAe;AACxB,SAAsB,sBAAsB;AAC5C,SAAS,uBAAyC;AAClD,SAA8B,gBAAgB;AAC9C,SAA6B,uBAAuB;AA8BpD,eAAsB,OACpB,KACA,MACqC;AAKrC,qBAAmB,IAAI;AAEvB,QAAM,OAAO,QAAQ,OAAO,QAAQ,IAAI,CAAC;AACzC,QAAM,OAAe,KAAK,QAAQ;AAGlC,QAAM,cAAc,mBAAmB;AACvC,QAAM,eAAe,kBAAkB,EAAE,OAAO,KAAK,OAAO,YAAY,CAAC;AAIzE,QAAM,SAAS,KAAK,WAAW,QAAQ,KAAK,YAAY;AAExD,QAAM,MAAM,MAAM,SAAS;AAAA,IACzB;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,WAAW,KAAK;AAAA,IAChB;AAAA,IACA,GAAI,KAAK,QAAQ,SAAY,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;AAAA,IAClD,GAAI,KAAK,UAAU,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;AAAA,IAC7C,GAAI,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;AAAA,IACjC,GAAG;AAAA,EACL,CAAC;AAID,MAAI,QAAQ;AACV,wBAAoB,GAAG;AACvB,WAAO;AAAA,EACT;AAEA,MAAI,IAAI,KAAM,QAAO;AAGrB,QAAM,UAAU,eAAe,IAAI;AACnC,QAAM,YAAY,QAAQ,YAAY,EAAE,KAAK,CAAC;AAC9C,MAAI,cAAc,QAAW;AAG3B,YAAQ,OAAO,MAAM,SAAS,IAAI;AAAA,CAA2C;AAAA,EAC/E,OAAO;AACL,UAAM,SAAwB;AAI9B,UAAM,YAA2B;AAAA,MAC/B,qBAAqB;AAAA,MACrB;AAAA,MACA,gBAAgB,aAAa;AAAA,MAC7B;AAAA,IACF;AACA,QAAI,aAAa,eAAe,QAAW;AACzC,gBAAU,aAAa,aAAa;AAAA,IACtC;AACA,UAAM,UAAU,MAAM,gBAAgB,WAAW,SAAS;AAC1D,UAAM,SAAS,UAAU,QAAQ,GAAG,IAAI,KAAK,EAAE;AAC/C,YAAQ,OAAO;AAAA,MACb,WAAW,QAAQ,QAAQ,MAAM,mBAAmB,MAAM,cAAc,MAAM;AAAA;AAAA,IAChF;AAAA,EACF;AAMA,MAAI;AACJ,MAAI;AACF,kBAAc,gBAAgB,IAAI;AAAA,EACpC,QAAQ;AACN,kBAAc;AAAA,EAChB;AACA,QAAM,QAAQ,MAAM,oBAAoB,MAAM,KAAK,EAAE,aAAa,SAAS,YAAY,CAAC;AACxF,MAAI,MAAM,UAAU,SAAS,EAAG,KAAI,UAAU,KAAK,GAAG,MAAM,SAAS;AAErE,UAAQ,OAAO,MAAM,mBAAmB,IAAI,WAAW,IAAI,gBAAgB,KAAK,SAAS;AAAA,CAAM;AAC/F,UAAQ,OAAO,MAAM,2EAA2E;AAChG,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/commands/create.ts"],"sourcesContent":["// `noir create [dir]` — greenfield first-run for the AI layer only.\n//\n// Slice S — new command. Bootstraps Noir's AI layer (.noir/ store, host\n// pointers, skills) into `dir` (created if absent), with NO external\n// scaffolder chaining (S-OQ1 = AI-layer only; no `pnpm create` wrapping).\n//\n// Reuses init's transport/url handling (including the localhost security\n// gate) by calling into the same engine: `scaffold({mode:'create', root})`.\n// The only difference from `noir init` is the mode tag (which selects the\n// manifest's first-run subset + generates a fresh project id unconditionally)\n// and that the target dir is `resolve(dir ?? cwd)` rather than `process.cwd()`.\n//\n// S10 multi-host: gains `--host <id>` (default `'claude'`); the host drives\n// both scaffold emission + skills emission via `resolveAdapter(host)` —\n// shared with init through `emitHostSkills`. See `init.ts` for the matrix.\n//\n// Stream discipline matches init: diagnostics → stderr, nothing on stdout\n// (so `noir create --json` is safe by construction — there is no data payload).\n//\n// Exit codes: `assertTransportUrl` is called DIRECTLY (M2) so transport/url\n// errors propagate as plain `Error` → bin.ts's handleError → exit 1, EXACTLY\n// matching `noir init` for the same error class. (The S9 spec lists usage=2 for\n// a missing `--url`; neither `init` nor `create` implements that split today —\n// both report it as a plain error=1 — and the review asked for consistency\n// over a one-sided fix. Changing them together is a separate, contract-level\n// change.) The target dir is created by the engine's `create` mode (N1: the\n// duplicate mkdir that used to live here is gone — one attributable failure\n// point, in scaffold.ts).\n\nimport { resolve } from 'node:path';\nimport { type HostId, resolveAdapter } from '@noir-ai/adapters';\nimport { loadProjectInfo, type ProjectInfo } from '@noir-ai/core';\nimport { type ScaffoldResult, scaffold } from '@noir-ai/create';\nimport { type CompileTarget, emitSkillsToDir } from '@noir-ai/skills';\nimport { buildConflictOpts } from '../conflict.js';\nimport { checkWritePathDedup } from '../dedup-write.js';\nimport { assertTransportUrl, reportPlannedWrites } from '../init.js';\nimport { resolveInteractive } from '../output.js';\n\nexport interface CreateOptions {\n transport: 'stdio' | 'streamable-http';\n url?: string;\n /** S10 target host. Defaults to `'claude'`. */\n host?: HostId;\n /** SP-A: re-scaffold even if already initialized. */\n force?: boolean;\n /** F1: `--dry-run`/`--preview` — report the planned writes to stderr\n * without touching disk (incl. NOT creating the target dir). */\n dryRun?: boolean;\n /** F1: alias for `--dry-run`. Kept on the options bag so direct callers can\n * pass either spelling; the bin collapses both flags before dispatch. */\n preview?: boolean;\n}\n\n/**\n * Bootstrap Noir's AI layer in `dir`. Returns the {@link ScaffoldResult} (with\n * structured `conflicts[]` + any dedup records appended); the bin\n * emits it under `--json`. `undefined` when the already-initialized guard\n * short-circuited (a no-op).\n *\n * @param dir Target directory (created if absent). Defaults to `process.cwd()`.\n * @param opts Transport + URL + host (same semantics as `noir init`).\n */\nexport async function create(\n dir: string | undefined,\n opts: CreateOptions,\n): Promise<ScaffoldResult | undefined> {\n // M2: call assertTransportUrl directly so the SAME error class yields the SAME\n // exit code as `noir init` (plain Error → exit 1 for both missing-url and\n // non-localhost). The previous NoirCliError(EXIT.USAGE) wrapper made `create`\n // exit 2 where `init` exits 1.\n assertTransportUrl(opts);\n\n const root = resolve(dir ?? process.cwd());\n const host: HostId = opts.host ?? 'claude';\n // Derive interactive once (consistency with init/sync) so both scaffold\n // and skills emission see the same hermetic flag.\n const interactive = resolveInteractive();\n const conflictOpts = buildConflictOpts({ force: opts.force, interactive });\n // F1: --dry-run/--preview collapse to a single dryRun boolean. The engine\n // skips the target-dir mkdir + every write; skills emission + dedup are\n // skipped too (they would touch disk / load the embedder).\n const dryRun = opts.dryRun === true || opts.preview === true;\n\n const res = await scaffold({\n root,\n mode: 'create',\n host,\n transport: opts.transport,\n interactive,\n ...(opts.url !== undefined ? { url: opts.url } : {}),\n ...(opts.force === true ? { force: true } : {}),\n ...(dryRun ? { dryRun: true } : {}),\n ...conflictOpts,\n });\n // F1: dry-run reports the planned writes and stops BEFORE skills emission +\n // the \"created\" message — the target dir was NOT created, so nothing may\n // touch disk. (The engine's create-mode mkdir is gated on !dryRun.)\n if (dryRun) {\n reportPlannedWrites(res);\n return res;\n }\n // SP-A: a no-op (already-initialized guard) must not re-emit skills.\n if (res.noop) return res;\n\n // Skills are out-of-manifest by design — same composition as init.\n const adapter = resolveAdapter(host);\n const skillsDir = adapter.skillsDir?.({ root });\n if (skillsDir === undefined) {\n // N1: standardized wording — same phrase across init/sync/create so logs\n // grep uniformly. (Pre-N1 each command phrased this differently.)\n process.stderr.write(`host '${host}' has no skill emitter; skipping skills\\n`);\n } else {\n const target: CompileTarget = host;\n // Forward conflictOpts so an interactive `noir create` with a\n // conflicting skill emit consults the resolver (mirrors init/sync).\n type SkillEmitOpts = NonNullable<Parameters<typeof emitSkillsToDir>[1]>;\n const skillOpts: SkillEmitOpts = {\n includeIntegrations: true,\n target,\n conflictPolicy: conflictOpts.conflictPolicy,\n interactive,\n };\n if (conflictOpts.onConflict !== undefined) {\n skillOpts.onConflict = conflictOpts.onConflict as SkillEmitOpts['onConflict'];\n }\n const summary = await emitSkillsToDir(skillsDir, skillOpts);\n const relDir = skillsDir.replace(`${root}/`, '');\n process.stderr.write(\n `Emitted ${summary.emitted.length} Noir skills to ${relDir}/ (target: ${target}).\\n`,\n );\n }\n\n // Write-path semantic dedup. Greenfield create rarely has\n // existing host-context candidates (the target dir is fresh), so the fast\n // path fires; `--force` on a pre-existing Noir project reads the config and\n // runs the full dedup. Best-effort: a missing/corrupt config warn-skips.\n let projectInfo: ProjectInfo | undefined;\n try {\n projectInfo = loadProjectInfo(root);\n } catch {\n projectInfo = undefined;\n }\n const dedup = await checkWritePathDedup(root, res, { interactive, project: projectInfo });\n if (dedup.conflicts.length > 0) res.conflicts.push(...dedup.conflicts);\n\n process.stderr.write(`Noir created in ${root} (host: ${host}, transport: ${opts.transport}).\\n`);\n process.stderr.write('Next: cd into the new directory, then run `noir` to open the home menu.\\n');\n return res;\n}\n"],"mappings":";;;;;;;;;;;;AA6BA,SAAS,eAAe;AACxB,SAAsB,sBAAsB;AAC5C,SAAS,uBAAyC;AAClD,SAA8B,gBAAgB;AAC9C,SAA6B,uBAAuB;AA8BpD,eAAsB,OACpB,KACA,MACqC;AAKrC,qBAAmB,IAAI;AAEvB,QAAM,OAAO,QAAQ,OAAO,QAAQ,IAAI,CAAC;AACzC,QAAM,OAAe,KAAK,QAAQ;AAGlC,QAAM,cAAc,mBAAmB;AACvC,QAAM,eAAe,kBAAkB,EAAE,OAAO,KAAK,OAAO,YAAY,CAAC;AAIzE,QAAM,SAAS,KAAK,WAAW,QAAQ,KAAK,YAAY;AAExD,QAAM,MAAM,MAAM,SAAS;AAAA,IACzB;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,WAAW,KAAK;AAAA,IAChB;AAAA,IACA,GAAI,KAAK,QAAQ,SAAY,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;AAAA,IAClD,GAAI,KAAK,UAAU,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;AAAA,IAC7C,GAAI,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;AAAA,IACjC,GAAG;AAAA,EACL,CAAC;AAID,MAAI,QAAQ;AACV,wBAAoB,GAAG;AACvB,WAAO;AAAA,EACT;AAEA,MAAI,IAAI,KAAM,QAAO;AAGrB,QAAM,UAAU,eAAe,IAAI;AACnC,QAAM,YAAY,QAAQ,YAAY,EAAE,KAAK,CAAC;AAC9C,MAAI,cAAc,QAAW;AAG3B,YAAQ,OAAO,MAAM,SAAS,IAAI;AAAA,CAA2C;AAAA,EAC/E,OAAO;AACL,UAAM,SAAwB;AAI9B,UAAM,YAA2B;AAAA,MAC/B,qBAAqB;AAAA,MACrB;AAAA,MACA,gBAAgB,aAAa;AAAA,MAC7B;AAAA,IACF;AACA,QAAI,aAAa,eAAe,QAAW;AACzC,gBAAU,aAAa,aAAa;AAAA,IACtC;AACA,UAAM,UAAU,MAAM,gBAAgB,WAAW,SAAS;AAC1D,UAAM,SAAS,UAAU,QAAQ,GAAG,IAAI,KAAK,EAAE;AAC/C,YAAQ,OAAO;AAAA,MACb,WAAW,QAAQ,QAAQ,MAAM,mBAAmB,MAAM,cAAc,MAAM;AAAA;AAAA,IAChF;AAAA,EACF;AAMA,MAAI;AACJ,MAAI;AACF,kBAAc,gBAAgB,IAAI;AAAA,EACpC,QAAQ;AACN,kBAAc;AAAA,EAChB;AACA,QAAM,QAAQ,MAAM,oBAAoB,MAAM,KAAK,EAAE,aAAa,SAAS,YAAY,CAAC;AACxF,MAAI,MAAM,UAAU,SAAS,EAAG,KAAI,UAAU,KAAK,GAAG,MAAM,SAAS;AAErE,UAAQ,OAAO,MAAM,mBAAmB,IAAI,WAAW,IAAI,gBAAgB,KAAK,SAAS;AAAA,CAAM;AAC/F,UAAQ,OAAO,MAAM,2EAA2E;AAChG,SAAO;AACT;","names":[]}