zidane 5.1.22 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as ExecutionHandle, i as ExecutionContext, n as ContextType, o as SpawnConfig, r as ExecResult, t as ContextCapabilities } from "./types-Ce78ds4h.js";
2
2
  import { t as SandboxProvider } from "./index-BiO_5Hm4.js";
3
3
  import { A as SessionStore, At as SpawnHookContext, Bt as toolOutputByteLength, C as SkillResource, Ct as PromptTextPart, D as Session, Dt as SessionHookContext, E as CreateSessionOptions, Et as SessionEndStatus, Ft as ToolResultContent, G as ProviderCapabilities, Gt as AgentToolNotAllowedError, Ht as AgentAbortedError, It as ToolResultImageContent, J as ToolCall, Jt as ClassifiedErrorKind, K as StreamCallbacks, Kt as CONTEXT_EXCEEDED_MESSAGE_PATTERNS, Lt as ToolResultTextContent, Mt as ThinkingLevel, N as RemoteStoreOptions, Nt as ToolExecutionMode, O as SessionData, Ot as SessionMessage, Pt as ToolHookContext, Q as OpenRouterParams, Rt as TurnFinishReason, St as PromptPart, T as SkillsConfig, Tt as SessionContentBlock, Ut as AgentContextExceededError, Vt as toolResultToText, W as Provider, Wt as AgentProviderError, X as ToolSpec, Xt as matchesContextExceeded, Y as ToolResult, Z as TurnResult, _t as McpToolHookContext, b as ToolMap, bt as PromptDocumentPart, ct as CerebrasParams, ft as AgentBehavior, gt as McpServerConfig, ht as ChildRunStats, i as AgentOptions, jt as StreamHookContext, k as SessionRun, kt as SessionTurn, mt as AgentStats, ot as OpenAIParams, p as McpConnection, pt as AgentRunOptions, q as StreamOptions, qt as ClassifiedError, r as AgentHooks, t as Agent, ut as AnthropicParams, v as ToolContext, wt as RunHookMap, x as SkillConfig, xt as PromptImagePart, y as ToolDef, yt as OAuthRefreshHookContext, zt as TurnUsage } from "./agent-CYpPKn5Z.js";
4
- import { I as ModelUsage, L as flattenTurns, R as statsByModel, _ as ChildAgent, f as ValidationResult, j as InteractionToolOptions, t as Preset, v as SpawnToolOptions, y as SpawnToolState } from "./index-D-cTScN3.js";
4
+ import { I as ModelUsage, L as flattenTurns, R as statsByModel, _ as ChildAgent, f as ValidationResult, j as InteractionToolOptions, t as Preset, v as SpawnToolOptions, y as SpawnToolState } from "./index-BRTRan3z.js";
5
5
  export { type Agent, AgentAbortedError, type AgentBehavior, AgentContextExceededError, type AgentHooks, type AgentOptions, AgentProviderError, type AgentRunOptions, type AgentStats, AgentToolNotAllowedError, type AnthropicParams, CONTEXT_EXCEEDED_MESSAGE_PATTERNS, type CerebrasParams, type ChildAgent, type ChildRunStats, type ClassifiedError, type ClassifiedErrorKind, type ContextCapabilities, type ContextType, type CreateSessionOptions, type ExecResult, type ExecutionContext, type ExecutionHandle, type InteractionToolOptions, type McpConnection, type McpServerConfig, type McpToolHookContext, type ModelUsage, type OAuthRefreshHookContext, type OpenAIParams, type OpenRouterParams, type Preset, type PromptDocumentPart, type PromptImagePart, type PromptPart, type PromptTextPart, type Provider, type ProviderCapabilities, type RemoteStoreOptions, type RunHookMap, type SandboxProvider, type Session, type SessionContentBlock, type SessionData, type SessionEndStatus, type SessionHookContext, type SessionMessage, type SessionRun, type SessionStore, type SessionTurn, type SkillConfig, type SkillResource, type SkillsConfig, type SpawnConfig, type SpawnHookContext, type SpawnToolOptions, type SpawnToolState, type StreamCallbacks, type StreamHookContext, type StreamOptions, type ThinkingLevel, type ToolCall, type ToolContext, type ToolDef, type ToolExecutionMode, type ToolHookContext, type ToolMap, type ToolResult, type ToolResultContent, type ToolResultImageContent, type ToolResultTextContent, type ToolSpec, type TurnFinishReason, type TurnResult, type TurnUsage, type ValidationResult, flattenTurns, matchesContextExceeded, statsByModel, toolOutputByteLength, toolResultToText };
package/docs/CHAT.md CHANGED
@@ -154,6 +154,7 @@ The table below indexes every named export; sections further down dive into the
154
154
  | `store` | Session reconstruction + persisted UI state + transcript view rules — `eventsFromTurns`, `lastContextSizeFromTurns`, `listSessionMeta`, `deriveSessionTitle`, `titleFromTurns`, `selectableTurnIds`, `stripSpawnTokensLine`, `toolCallPreview`, `toolResultText`, `createStateStore`, `loadState`, `saveState`, `isVisible`, `marginTopFor`, `isEditErrorResult`, `isTurnHighlighted`, `sumRunCosts`, `turnSelectionOwnership`, `TuiState`, `StateStoreApi`. |
155
155
  | `streaming` | `useStreamBuffer`, `finalizeStreamingMarkdown`, `finalizeStreamingMarkdownForOwner`, `turnContextSize`. Per-owner finalize handles concurrent parent + child streams. |
156
156
  | `theme` + `theme-context` | `Theme`, `BUILTIN_THEMES`, `resolveTheme`, `resolveChipColor`, `DEFAULT_THEME`, themes (`CATPPUCCIN_*`, `VAPORWAVE_THEME`), hooks (`useTheme`, `useColors`, `useSelectStyle`, `useSurfaces`, `useSyntaxStyles`). See **Theme**. |
157
+ | `todos` | `todowrite` / `todoread` tool factory — `createTodoTools` (returns a `Preset`), `isTodoTool`, `getTodosForRun`, `setTodosForRun`, `pruneTodosByRun`, `TODOWRITE_TOOL`, `TODOREAD_TOOL`, `TODOS_METADATA_KEY`, `TODO_WRITE_COUNTS_METADATA_KEY`, `TodoItem`, `TodoStatus`, `CreateTodoToolsOptions`. Run-scoped checkpointing keyed on `session.metadata.todosByRun[runId]`; dedup hasher + per-run write budget plumb through the existing `behavior.dedupTools` / `behavior.toolBudgets` primitives — compose with `composePresets` or spread. See **Todos** below. |
157
158
  | `tool-formatters` | Per-tool display verbs + curated input formatters — `TOOL_DISPLAY`, `displayNameFor`, `formatToolCall`, `ToolDisplayMeta`, `ToolFormatLine`. Powers the `'formatted'` `toolCallDisplay` view. See **Tool call display**. |
158
159
  | `transcript-anchors` | `computeTurnAnchors(items)` → `TranscriptItem[]` — assigns `turn-anchor-<turnId>` ids consumers wire into their renderer's scroll-into-view (TUI: `ScrollBoxRenderable.scrollChildIntoView`; GUI: DOM `element.scrollIntoView`). |
159
160
  | `turn-operations` | `deleteTurnSafely`, `truncateTurnsAt`, `turnAsText`, `countNeighbors`. Fork / delete with orphan tool-pair cleanup. |
@@ -271,8 +272,8 @@ interface AgentProfile {
271
272
 
272
273
  Built-ins (`BUILTIN_AGENTS`):
273
274
 
274
- - **`BUILD_AGENT`** (`build`) — full tool access: `shell`, `readFile`, `writeFile`, `listFiles`, `edit`, `multiEdit`, `glob`, `grep`, plus `spawn` (with `persist: true` so reloads can reconstruct the subagent tree).
275
- - **`PLAN_AGENT`** (`plan`) — read-only: `readFile`, `listFiles`, `glob`, `grep`. System prompt is `PLAN_MODE_DOCTRINE`.
275
+ - **`BUILD_AGENT`** (`build`) — full tool access: `shell`, `readFile`, `writeFile`, `listFiles`, `edit`, `multiEdit`, `glob`, `grep`, plus `spawn` (with `persist: true` so reloads can reconstruct the subagent tree) and `todowrite` / `todoread` layered in via `composePresets(..., createTodoTools())` (see **Todos**).
276
+ - **`PLAN_AGENT`** (`plan`) — read-only: `readFile`, `listFiles`, `glob`, `grep`. System prompt is `PLAN_MODE_DOCTRINE`. No todos — a read-only exploration session has nothing to checkpoint.
276
277
 
277
278
  Both share `SHARED_BEHAVIOR`:
278
279
 
@@ -289,7 +290,7 @@ Both share `SHARED_BEHAVIOR`:
289
290
  }
290
291
  ```
291
292
 
292
- `DEFAULT_PERSIST_EXCLUDE_TOOLS` = `['read_file', 'tool_search', 'skills_use', 'skills_read', 'present_plan', 'ask_user', 'spawn']`. SDK consumers building custom profiles can extend this for any host-defined tool whose output should stay inline regardless of size.
293
+ `DEFAULT_PERSIST_EXCLUDE_TOOLS` = `['read_file', 'tool_search', 'skills_use', 'skills_read', 'present_plan', 'ask_user', 'spawn', 'todowrite', 'todoread']`. SDK consumers building custom profiles can extend this for any host-defined tool whose output should stay inline regardless of size.
293
294
 
294
295
  `resolveAgentId(registry, requestedId, defaultId)` picks the next active profile with fallbacks: requested id > defaultId > first registry key > `null`. `singleAgentRegistry(preset)` wraps a legacy `preset` into a one-entry registry — used internally when the host passed `preset` without `agents`.
295
296
 
@@ -473,6 +474,63 @@ const pending = queue[0] ?? null
473
474
 
474
475
  **Parallel-call deny semantics**: each pending approval resolves on its own. A single `deny` does **not** cascade through the queue — the gate handler sets `ctx.block = true` + `ctx.reason = 'User denied this tool call'` for THAT call and returns, so the model receives `Blocked: User denied this tool call` as that one tool's result and the turn continues; other parallel approvals stay queued and prompt independently. The user's explicit "stop everything" gesture is the host-level `esc abort run` shortcut, which calls `cancelRunOnDenial()` → `denyAll()` + `agent.abort()` in one shot.
475
476
 
477
+ ## Todos
478
+
479
+ `todowrite` and `todoread` give the model a place to plan multi-step work and stream progress as it executes. Monolithic-replacement semantics — every `todowrite` overwrites the active run's list in full. State lives at `session.metadata.todosByRun: Record<runId, TodoItem[]>`; runs are isolated by `runId`, so subagent writes never bleed into the parent's slot. Resume is transparent — the latest `tool_result` block in `session.turns` carries the same snapshot the persisted metadata bag does.
480
+
481
+ Public API (re-exported from `zidane/chat`):
482
+
483
+ - **Factory** — `createTodoTools(options?)` returns a `Preset` carrying `{ tools, behavior }` (tools + dedup hasher + per-run write budget). Compose with `composePresets` or spread it into your agent setup like any other preset.
484
+ - **Identities** — `TODOWRITE_TOOL`, `TODOREAD_TOOL`, `isTodoTool(name)`.
485
+ - **Metadata accessors** — `getTodosForRun(session, runId)`, `setTodosForRun(session, runId, items)`, `pruneTodosByRun(session)`, `TODOS_METADATA_KEY`, `TODO_WRITE_COUNTS_METADATA_KEY`.
486
+ - **Types** — `TodoItem`, `TodoStatus` (`'pending' | 'in_progress' | 'completed' | 'cancelled'`), `CreateTodoToolsOptions`.
487
+
488
+ `CreateTodoToolsOptions`:
489
+
490
+ | Option | Default | Notes |
491
+ |---|---|---|
492
+ | `maxItems` | `100` | Per-call item cap. Excess items are truncated by the recursive validator and reported in the tool_result. |
493
+ | `maxWritesPerRun` | `6` | Per-run write cap. Plumbs into `behavior.toolBudgets.todowrite`. Set to `0` to opt out (factory omits the entry; caller-supplied budget wins). |
494
+ | `onMaxWrites` | `'steer'` | `'steer'` or `'block'`. |
495
+ | `remindAfter` | `3` | Append a "you've checkpointed N times — slow down" nudge to the tool_result once the run-cumulative count reaches this. Set to `0` to opt out. Counts executed dispatches only (dedup hits skip the body); use `maxWritesPerRun` for a hard limit covering both. |
496
+ | `reminderText` | built-in | `(count, items) => string \| undefined`. Return `undefined` / `''` to suppress for this call. |
497
+ | `dedupIdentical` | `true` | Plumbs into `behavior.dedupTools.todowrite`. Set `false` to opt out. |
498
+ | `writeDescription` / `readDescription` | built-in | Override the JSON-schema-level descriptions. |
499
+
500
+ `BUILD_AGENT` opts in via `composePresets`; `PLAN_AGENT` doesn't (read-only mode has nothing to checkpoint). Hosts building custom profiles use the same primitive:
501
+
502
+ ```ts
503
+ import { composePresets, definePreset } from 'zidane/presets'
504
+ import { createTodoTools } from 'zidane/chat'
505
+
506
+ const myPreset = composePresets(
507
+ definePreset({
508
+ name: 'mine',
509
+ tools: { ...basicTools },
510
+ behavior: { ...SHARED_BEHAVIOR },
511
+ }),
512
+ createTodoTools({ maxWritesPerRun: 6, remindAfter: 3 }),
513
+ )
514
+ ```
515
+
516
+ `composePresets` deep-merges `behavior.dedupTools` and `behavior.toolBudgets` per tool name, so layering order is forgiving: a downstream preset overriding `dedupTools.todowrite` keeps the rest of the factory's wiring intact. For the simplest case ("just add the tools to an existing config"), plain spread is also valid since the factory returns a `Preset`:
517
+
518
+ ```ts
519
+ createAgent({ ...basicPreset, ...createTodoTools(), provider })
520
+ ```
521
+
522
+ Spread is shallow-merge, so two presets that both touch `dedupTools` / `toolBudgets` should go through `composePresets` instead.
523
+
524
+ Hygiene is layered across the lifecycle:
525
+
526
+ - **Input time** — schema validation drops malformed items; per-call ID dedup keeps last-wins semantics; empty initial writes don't create a slot.
527
+ - **Per-call reminder** — rides on the tool's own `tool_result`, so the model sees the nudge in the result it just received (no `system:transform` plumbing).
528
+ - **Per-run budget + dedup** — composed through the existing `behavior.dedupTools` / `behavior.toolBudgets` primitives; same gates, same `tool-budget:exceeded` event.
529
+ - **Session-level reconciliation** — `pruneTodosByRun(session)` drops orphan keys (and the parallel counter bag) after a `setRuns()` fork or any out-of-band run-list mutation; not automatic on `save()`.
530
+ - **Subagent isolation** — falls out of `runId`-keyed state; each child run owns its own slot.
531
+
532
+ Renderer integration: the `TOOL_DISPLAY` registry ships entries for both tools (`Todos N items · …` line shape that matches the tool's result summary), and `DEFAULT_PERSIST_EXCLUDE_TOOLS` skips them from disk-persistence (the latest snapshot is the only state of interest).
533
+
476
534
  ## Interactions
477
535
 
478
536
  `present_plan` and `ask_user` let the agent pause for explicit user input. **The call IS the persisted state** — both tools land in `session.turns` as regular `tool_call` blocks, and pending entries are derived from disk via `pendingInteractionsFromTurns(turns)`.
@@ -820,6 +878,7 @@ Write src/foo.ts · 2.4 KB
820
878
  Spawn research the foo bar baz
821
879
  Activate skill design-eng
822
880
  Ask user 3 questions
881
+ Todos 5 items · 2 done · 1 in progress · 2 pending
823
882
  ```
824
883
 
825
884
  Renderer-agnostic helpers:
package/docs/SKILL.md CHANGED
@@ -246,6 +246,8 @@ Returns `string` (common) or `ToolResultContent[]` (images / mixed content). Rou
246
246
 
247
247
  `validateToolArgs(input, schema)` runs between `tool:gate` and `tool:before`. Missing/null required fields fail. Top-level coercions normalize the common OSS-model mistakes (`"true"`/`"yes"`/`"1"` → `true`, numeric strings → numbers, JSON strings → arrays/objects). `execute` always receives the **coerced** input. `validation:reject` fires only when no type reconciles — distinct from `tool:error`.
248
248
 
249
+ Array recursion: properties declared `{ type: 'array', items: { ... }, maxItems?, minItems? }` walk each item against `items` (one level of nesting — required-field check + per-property coercion + enum). Items that can't be coerced are **dropped** rather than failing the whole call; the original indexes surface on `ValidationResult.droppedItems[fieldName]`. `maxItems` truncates and reports the discarded tail. The tool's `execute` receives the post-recursion array.
250
+
249
251
  ```ts
250
252
  import { validateToolArgs } from 'zidane'
251
253
  const { valid, coercedInput, coercions } = validateToolArgs(
@@ -667,7 +669,7 @@ createSandboxContext(myProvider) // implement SandboxProvider (E2B, Rivet, …)
667
669
  | `FileMapAdapter` | `{ get, save, delete }` — host-SDK seam for `createFileMapStore`. |
668
670
  | `TracingHooksOptions` | `createTracingHooks` config (`startSpan`, `namespace?`). |
669
671
  | `OpenAICompatParams` | `openaiCompat()` config (apiKey, baseURL, authHeader, extraHeaders, capabilities, cacheBreakpoints). |
670
- | `ValidationResult` | `{ valid, error?, coercedInput?, coercions? }` — `validateToolArgs` output. |
672
+ | `ValidationResult` | `{ valid, error?, coercedInput?, coercions?, droppedItems? }` — `validateToolArgs` output. `droppedItems` is keyed by field name and reports the original indexes of items dropped during recursive array validation. |
671
673
  | `AgentHookMap` | `{ [event]: handler \| handler[] }` — agent-lifetime hooks on `AgentOptions.hooks`. |
672
674
  | `RunHookMap` | Same shape, per-run scope (`agent.run({ hooks })`); handlers auto-detach. |
673
675
  | `toolOutputByteLength(content)` | Reproduces the loop's `outputBytes` formula. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zidane",
3
- "version": "5.1.22",
3
+ "version": "5.2.0",
4
4
  "description": "an agent that goes straight to the goal",
5
5
  "type": "module",
6
6
  "private": false,
@@ -1 +0,0 @@
1
- {"version":3,"file":"presets-tvD28pCu.js","names":[],"sources":["../src/presets/basic.ts","../src/presets/index.ts"],"sourcesContent":["import { definePreset } from '.'\nimport { edit, listFiles, multiEdit, readFile, shell, writeFile } from '../tools'\nimport { createSpawnTool } from '../tools/spawn'\n\n/**\n * Core tools available in every basic preset (without spawn).\n *\n * `edit` and `multi_edit` ship in the basic set because surgical edits are the\n * default modality for production agents — `write_file` is for full overwrites.\n * `glob` and `grep` are exported but opt-in: not every agent needs codebase\n * search, and shipping them by default would force `tool:gate` work onto\n * consumers that prefer the model to use `shell` + classic Unix tools.\n */\nexport const basicTools = { shell, readFile, writeFile, listFiles, edit, multiEdit }\n\nexport default definePreset({\n name: 'basic',\n system: 'You are a helpful assistant with access to shell, file reading, file writing, surgical and multi-edit tools, directory listing, and sub-agent spawning. Prefer `edit` / `multi_edit` for in-place changes and `write_file` for full file overwrites. Use them to accomplish tasks in the project directory.',\n // `persist: true` shares the parent's session with every child agent — child\n // turns land in `session.turns` tagged with their own `runId`, and the run\n // itself is recorded in `session.runs` with `parentRunId` + `depth`. That's\n // what lets a reloaded TUI session reconstruct the full subagent tree (see\n // `eventsFromTurns` in `tui/store.ts`). Hosts that want children in-memory\n // only can construct their own preset with `createSpawnTool()`.\n tools: { ...basicTools, spawn: createSpawnTool({ persist: true }) },\n})\n","import type { AgentHooks, AgentOptions } from '../agent'\n\nexport type { AgentHookMap } from '../agent'\n\n/**\n * A preset is a reusable slice of `AgentOptions` — spread it into `createAgent()`\n * to configure tools, a default system prompt, aliases, behavior defaults, and\n * agent-lifetime hooks.\n *\n * `provider`, `execution`, `session`, and internal fields are excluded so presets\n * remain shareable and composable.\n *\n * ```ts\n * import { basic } from 'zidane/presets'\n * createAgent({ ...basic, provider })\n * ```\n *\n * ### Composing multiple presets\n *\n * Bare `...spread` is shallow — `{ ...a, ...b }` overwrites every key `b`\n * defines, including `hooks`. Use {@link composePresets} when you want\n * field-aware merging (per-event hook concat, tools shallow-merge, etc.):\n *\n * ```ts\n * createAgent({ ...composePresets(basic, telemetry, mine), provider })\n * ```\n */\nexport type Preset = Omit<Partial<AgentOptions>, 'provider' | 'execution' | 'session' | 'mcpConnector'>\n\n/**\n * Identity helper for type inference when defining a preset.\n */\nexport function definePreset(config: Preset): Preset {\n return config\n}\n\n/**\n * Field-aware composition of presets. Right-most preset wins for scalar fields;\n * objects shallow-merge; arrays and hook handler lists concatenate. Designed so\n * stacking presets does the obvious thing without the spread-collision footgun:\n *\n * - `name`, `system`, `eager`, `skills` → last-defined wins\n * - `tools`, `toolAliases`, `behavior` → shallow-merge (later keys override)\n * - `mcpServers` → concat with last-wins on `name` collision\n * - `hooks` → per-event concat; every handler fires\n *\n * `hooks` always emerges as `event → handler[]` so downstream registration\n * (in `createAgent`) sees a uniform shape. Order of handlers within an event\n * follows preset order: earlier presets register first.\n *\n * `mcpServers` is deduped by `name` because shipping two servers with the same\n * name would trip the connector at runtime — a later preset overriding an\n * earlier preset's `github` server is the practical intent.\n */\nexport function composePresets(...presets: Preset[]): Preset {\n const out: Preset = {}\n const hooksByEvent: { [K in keyof AgentHooks]?: AgentHooks[K][] } = {}\n // Keep mcpServers in source-order on first sight, but allow later\n // declarations to override earlier ones with the same `name`. A `Map`\n // keyed by name gives O(1) override + stable iteration.\n const mcpByName = new Map<string, NonNullable<Preset['mcpServers']>[number]>()\n\n for (const p of presets) {\n if (p.name !== undefined)\n out.name = p.name\n if (p.system !== undefined)\n out.system = p.system\n if (p.eager !== undefined)\n out.eager = p.eager\n if (p.skills !== undefined)\n out.skills = p.skills\n if (p.tools)\n out.tools = { ...out.tools, ...p.tools }\n if (p.toolAliases)\n out.toolAliases = { ...out.toolAliases, ...p.toolAliases }\n if (p.behavior)\n out.behavior = { ...out.behavior, ...p.behavior }\n if (p.mcpServers) {\n for (const server of p.mcpServers)\n mcpByName.set(server.name, server)\n }\n if (p.hooks) {\n for (const [event, handler] of Object.entries(p.hooks)) {\n if (handler === undefined)\n continue\n const list = Array.isArray(handler) ? handler : [handler]\n const key = event as keyof AgentHooks\n // Safe cast: we read the loose `AgentHookMap` shape (handler-or-array)\n // and re-emit only as arrays. Each `list` element matches the event's\n // handler signature by construction (the input was typed `AgentHookMap`).\n const bucket = (hooksByEvent[key] ??= []) as unknown[]\n bucket.push(...(list as unknown[]))\n }\n }\n }\n\n if (mcpByName.size > 0)\n out.mcpServers = [...mcpByName.values()]\n\n if (Object.keys(hooksByEvent).length > 0)\n out.hooks = hooksByEvent\n\n return out\n}\n\nexport { default as basic, basicTools } from './basic'\n"],"mappings":";;;;;;;;;;;AAaA,MAAa,aAAa;CAAE;CAAO;CAAU;CAAW;CAAW;CAAM;CAAW;AAEpF,IAAA,gBAAe,aAAa;CAC1B,MAAM;CACN,QAAQ;CAOR,OAAO;EAAE,GAAG;EAAY,OAAO,gBAAgB,EAAE,SAAS,MAAM,CAAC;EAAE;CACpE,CAAC;;;;;;ACOF,SAAgB,aAAa,QAAwB;CACnD,OAAO;;;;;;;;;;;;;;;;;;;;AAqBT,SAAgB,eAAe,GAAG,SAA2B;CAC3D,MAAM,MAAc,EAAE;CACtB,MAAM,eAA8D,EAAE;CAItE,MAAM,4BAAY,IAAI,KAAwD;CAE9E,KAAK,MAAM,KAAK,SAAS;EACvB,IAAI,EAAE,SAAS,KAAA,GACb,IAAI,OAAO,EAAE;EACf,IAAI,EAAE,WAAW,KAAA,GACf,IAAI,SAAS,EAAE;EACjB,IAAI,EAAE,UAAU,KAAA,GACd,IAAI,QAAQ,EAAE;EAChB,IAAI,EAAE,WAAW,KAAA,GACf,IAAI,SAAS,EAAE;EACjB,IAAI,EAAE,OACJ,IAAI,QAAQ;GAAE,GAAG,IAAI;GAAO,GAAG,EAAE;GAAO;EAC1C,IAAI,EAAE,aACJ,IAAI,cAAc;GAAE,GAAG,IAAI;GAAa,GAAG,EAAE;GAAa;EAC5D,IAAI,EAAE,UACJ,IAAI,WAAW;GAAE,GAAG,IAAI;GAAU,GAAG,EAAE;GAAU;EACnD,IAAI,EAAE,YACJ,KAAK,MAAM,UAAU,EAAE,YACrB,UAAU,IAAI,OAAO,MAAM,OAAO;EAEtC,IAAI,EAAE,OACJ,KAAK,MAAM,CAAC,OAAO,YAAY,OAAO,QAAQ,EAAE,MAAM,EAAE;GACtD,IAAI,YAAY,KAAA,GACd;GACF,MAAM,OAAO,MAAM,QAAQ,QAAQ,GAAG,UAAU,CAAC,QAAQ;GACzD,MAAM,MAAM;GAKZ,CADgB,aAAa,SAAS,EAAE,EACjC,KAAK,GAAI,KAAmB;;;CAKzC,IAAI,UAAU,OAAO,GACnB,IAAI,aAAa,CAAC,GAAG,UAAU,QAAQ,CAAC;CAE1C,IAAI,OAAO,KAAK,aAAa,CAAC,SAAS,GACrC,IAAI,QAAQ;CAEd,OAAO"}