@cdoing/cli 0.1.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/.cdoing/permissions.json +8 -0
- package/dist/callbacks.d.ts +17 -0
- package/dist/callbacks.d.ts.map +1 -0
- package/dist/callbacks.js +265 -0
- package/dist/callbacks.js.map +1 -0
- package/dist/chat.d.ts +27 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +57 -0
- package/dist/chat.js.map +1 -0
- package/dist/commands.d.ts +22 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +452 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +84 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +427 -0
- package/dist/config.js.map +1 -0
- package/dist/help.d.ts +9 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/help.js +167 -0
- package/dist/help.js.map +1 -0
- package/dist/history.d.ts +51 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +207 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +220 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth.d.ts +13 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +182 -0
- package/dist/oauth.js.map +1 -0
- package/dist/review.d.ts +26 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +198 -0
- package/dist/review.js.map +1 -0
- package/dist/serve.d.ts +23 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +293 -0
- package/dist/serve.js.map +1 -0
- package/dist/tools.d.ts +14 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +57 -0
- package/dist/tools.js.map +1 -0
- package/dist/ui/App.d.ts +24 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +321 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/MessageList.d.ts +14 -0
- package/dist/ui/MessageList.d.ts.map +1 -0
- package/dist/ui/MessageList.js +147 -0
- package/dist/ui/MessageList.js.map +1 -0
- package/dist/ui/SessionBrowser.d.ts +18 -0
- package/dist/ui/SessionBrowser.d.ts.map +1 -0
- package/dist/ui/SessionBrowser.js +149 -0
- package/dist/ui/SessionBrowser.js.map +1 -0
- package/dist/ui/SetupWizard.d.ts +23 -0
- package/dist/ui/SetupWizard.d.ts.map +1 -0
- package/dist/ui/SetupWizard.js +402 -0
- package/dist/ui/SetupWizard.js.map +1 -0
- package/dist/ui/Spinner.d.ts +15 -0
- package/dist/ui/Spinner.d.ts.map +1 -0
- package/dist/ui/Spinner.js +111 -0
- package/dist/ui/Spinner.js.map +1 -0
- package/dist/ui/StatusBar.d.ts +16 -0
- package/dist/ui/StatusBar.d.ts.map +1 -0
- package/dist/ui/StatusBar.js +56 -0
- package/dist/ui/StatusBar.js.map +1 -0
- package/dist/ui/UserInput.d.ts +13 -0
- package/dist/ui/UserInput.d.ts.map +1 -0
- package/dist/ui/UserInput.js +872 -0
- package/dist/ui/UserInput.js.map +1 -0
- package/dist/ui/hooks/helpers.d.ts +55 -0
- package/dist/ui/hooks/helpers.d.ts.map +1 -0
- package/dist/ui/hooks/helpers.js +304 -0
- package/dist/ui/hooks/helpers.js.map +1 -0
- package/dist/ui/hooks/useAgent.d.ts +60 -0
- package/dist/ui/hooks/useAgent.d.ts.map +1 -0
- package/dist/ui/hooks/useAgent.js +213 -0
- package/dist/ui/hooks/useAgent.js.map +1 -0
- package/dist/ui/hooks/useChat.d.ts +74 -0
- package/dist/ui/hooks/useChat.d.ts.map +1 -0
- package/dist/ui/hooks/useChat.js +819 -0
- package/dist/ui/hooks/useChat.js.map +1 -0
- package/dist/ui/theme.d.ts +73 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +214 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/ui/types.d.ts +37 -0
- package/dist/ui/types.d.ts.map +1 -0
- package/dist/ui/types.js +3 -0
- package/dist/ui/types.js.map +1 -0
- package/package.json +33 -0
- package/src/callbacks.ts +294 -0
- package/src/chat.ts +72 -0
- package/src/commands.ts +425 -0
- package/src/config.ts +462 -0
- package/src/help.ts +182 -0
- package/src/history.ts +205 -0
- package/src/index.ts +248 -0
- package/src/oauth.ts +164 -0
- package/src/review.ts +233 -0
- package/src/serve.ts +290 -0
- package/src/tools.ts +104 -0
- package/src/ui/App.tsx +426 -0
- package/src/ui/MessageList.tsx +222 -0
- package/src/ui/SessionBrowser.tsx +161 -0
- package/src/ui/SetupWizard.tsx +412 -0
- package/src/ui/Spinner.tsx +103 -0
- package/src/ui/StatusBar.tsx +106 -0
- package/src/ui/UserInput.tsx +954 -0
- package/src/ui/hooks/helpers.ts +271 -0
- package/src/ui/hooks/useAgent.ts +270 -0
- package/src/ui/hooks/useChat.ts +943 -0
- package/src/ui/theme.ts +326 -0
- package/src/ui/types.ts +41 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* useAgent.ts — React hook that owns the AgentRunner lifecycle.
|
|
4
|
+
*
|
|
5
|
+
* Single responsibility: build, rebuild, and run the AI agent.
|
|
6
|
+
* It knows nothing about conversations, sessions, slash commands, or UI
|
|
7
|
+
* messages — those live in useChat.ts.
|
|
8
|
+
*
|
|
9
|
+
* Why a separate hook?
|
|
10
|
+
* - The agent can be rebuilt (e.g. when the user changes the model) without
|
|
11
|
+
* touching any message or session state.
|
|
12
|
+
* - The streaming callbacks (onToken, onToolCall…) are pure side-effects of
|
|
13
|
+
* the agent run. Keeping them here makes them easy to read end-to-end.
|
|
14
|
+
* - useChat.ts can stay focused on slash commands and message history.
|
|
15
|
+
*
|
|
16
|
+
* What this hook exposes:
|
|
17
|
+
* - agentRef — the live AgentRunner instance
|
|
18
|
+
* - modelConfigRef — mutable model settings (mutated by /model, /provider)
|
|
19
|
+
* - toolRegistryRef — mutable tool list (mutated by /dir)
|
|
20
|
+
* - workingDirRef — current working directory as a ref
|
|
21
|
+
* - planManagerRef — manages plan-mode state
|
|
22
|
+
* - rulesManagerRef — loads .cdoing/rules.md
|
|
23
|
+
* - effortManagerRef — tracks effort level
|
|
24
|
+
* - mcpManagerRef — MCP server configuration
|
|
25
|
+
* - contextProvidersRef — @mention context providers
|
|
26
|
+
* - rebuildAgent() — recreate the agent after config changes
|
|
27
|
+
* - resolveContextProviders() — expand @mentions in a message
|
|
28
|
+
*/
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.useAgent = useAgent;
|
|
31
|
+
const react_1 = require("react");
|
|
32
|
+
const ai_1 = require("@cdoing/ai");
|
|
33
|
+
const core_1 = require("@cdoing/core");
|
|
34
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
35
|
+
// Hook
|
|
36
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Manages the AgentRunner and all mutable config references.
|
|
39
|
+
*
|
|
40
|
+
* All returned refs are intentionally mutable — slash commands in useChat.ts
|
|
41
|
+
* mutate them (e.g. modelConfigRef.current.model = "gpt-4o") and then call
|
|
42
|
+
* rebuildAgent() to create a fresh AgentRunner with the new settings.
|
|
43
|
+
*/
|
|
44
|
+
function useAgent(opts) {
|
|
45
|
+
// ── Mutable config refs ───────────────────────────────────────────────────
|
|
46
|
+
// These use useRef (not useState) because changing them should NOT trigger
|
|
47
|
+
// a re-render. Re-renders are triggered by state variables in useChat.ts.
|
|
48
|
+
/** Current working directory — changes when the user runs /dir */
|
|
49
|
+
const workingDirRef = (0, react_1.useRef)(process.cwd());
|
|
50
|
+
/** Model + provider + API key settings — changes on /model, /provider, /config set */
|
|
51
|
+
const modelConfigRef = (0, react_1.useRef)({ ...opts.modelConfig });
|
|
52
|
+
/** The set of tools available to the agent — swapped on /dir to match the new cwd */
|
|
53
|
+
const toolRegistryRef = (0, react_1.useRef)(opts.toolRegistry);
|
|
54
|
+
// ── Feature-manager refs ─────────────────────────────────────────────────
|
|
55
|
+
// Each manager encapsulates one feature. They are ref-stored so the agent
|
|
56
|
+
// can query them synchronously inside buildAgent() without going through state.
|
|
57
|
+
/** Plan mode: the agent proposes a plan before executing */
|
|
58
|
+
const planManagerRef = (0, react_1.useRef)(new core_1.PlanManager());
|
|
59
|
+
/** Project-specific rules loaded from .cdoing/rules.md */
|
|
60
|
+
const rulesManagerRef = (0, react_1.useRef)(new core_1.RulesManager(process.cwd()));
|
|
61
|
+
/** Effort level — low / medium / high / max — affects the system prompt */
|
|
62
|
+
const effortManagerRef = (0, react_1.useRef)(new core_1.EffortManager());
|
|
63
|
+
/** MCP (Model Context Protocol) server configuration */
|
|
64
|
+
const mcpManagerRef = (0, react_1.useRef)(new core_1.McpManager(process.cwd()));
|
|
65
|
+
/**
|
|
66
|
+
* Registry of @mention context providers.
|
|
67
|
+
* Each provider has a trigger (e.g. "@file") and a resolve() function that
|
|
68
|
+
* returns context to inject into the user's message before it reaches the LLM.
|
|
69
|
+
*/
|
|
70
|
+
const contextProvidersRef = (0, react_1.useRef)(buildContextProviders());
|
|
71
|
+
// ── Agent ref ────────────────────────────────────────────────────────────
|
|
72
|
+
/**
|
|
73
|
+
* The live AgentRunner instance. Wrapped in a ref so the same object is
|
|
74
|
+
* accessible inside async callbacks without capturing a stale closure.
|
|
75
|
+
*
|
|
76
|
+
* Initialized with buildAgentInternal() immediately, then replaced via
|
|
77
|
+
* rebuildAgent() whenever settings change.
|
|
78
|
+
*/
|
|
79
|
+
const agentRef = (0, react_1.useRef)((() => {
|
|
80
|
+
try {
|
|
81
|
+
return buildAgentInternal();
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
})());
|
|
87
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
88
|
+
// Agent builder
|
|
89
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
90
|
+
/**
|
|
91
|
+
* Construct a new AgentRunner from the current refs.
|
|
92
|
+
*
|
|
93
|
+
* Called once on mount and again via rebuildAgent() after any config change.
|
|
94
|
+
* Combines project config, rules, and effort hints into a single system prompt.
|
|
95
|
+
*/
|
|
96
|
+
function buildAgentInternal() {
|
|
97
|
+
const dir = workingDirRef.current;
|
|
98
|
+
const projectConfig = (0, core_1.loadProjectConfig)(dir); // .cdoing/config.md
|
|
99
|
+
const rulesText = rulesManagerRef.current?.formatForPrompt() || "";
|
|
100
|
+
const effortHint = effortManagerRef.current?.getSystemPromptAddition() || "";
|
|
101
|
+
// Merge all system-prompt additions, filtering out empty strings
|
|
102
|
+
const systemPrompt = [projectConfig || "", rulesText, effortHint]
|
|
103
|
+
.filter(Boolean)
|
|
104
|
+
.join("\n\n");
|
|
105
|
+
return new ai_1.AgentRunner(modelConfigRef.current, toolRegistryRef.current, opts.permissionManager, opts.hookManager, {
|
|
106
|
+
workingDir: dir,
|
|
107
|
+
projectConfig: systemPrompt || undefined,
|
|
108
|
+
memory: opts.memoryStore.formatForPrompt() || undefined,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Replace the live agent with a freshly built one.
|
|
113
|
+
* Call this any time you mutate modelConfigRef, toolRegistryRef, or workingDirRef.
|
|
114
|
+
*/
|
|
115
|
+
function rebuildAgent() {
|
|
116
|
+
try {
|
|
117
|
+
agentRef.current = buildAgentInternal();
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
// Don't crash — agentRef keeps the previous agent (or null).
|
|
121
|
+
// The error will surface as a friendly message on the next send.
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
125
|
+
// Context provider resolver
|
|
126
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
127
|
+
/**
|
|
128
|
+
* Expand any @mention triggers in the user's message.
|
|
129
|
+
*
|
|
130
|
+
* Example: "@file src/main.ts tell me what this does"
|
|
131
|
+
* → strips "@file src/main.ts"
|
|
132
|
+
* → reads the file
|
|
133
|
+
* → returns "tell me what this does\n\n---\n\n<file path="src/main.ts">…</file>"
|
|
134
|
+
*
|
|
135
|
+
* @param message Raw message as typed by the user
|
|
136
|
+
* @param workingDir Current working directory (for relative file paths)
|
|
137
|
+
* @param lastTerminalOutput Last captured terminal output (for @terminal)
|
|
138
|
+
*/
|
|
139
|
+
async function resolveContextProviders(message, workingDir, lastTerminalOutput) {
|
|
140
|
+
const providers = contextProvidersRef.current.getAll();
|
|
141
|
+
if (!providers.length)
|
|
142
|
+
return message;
|
|
143
|
+
const injected = [];
|
|
144
|
+
let clean = message;
|
|
145
|
+
for (const provider of providers) {
|
|
146
|
+
const idx = message.indexOf(provider.trigger);
|
|
147
|
+
if (idx < 0)
|
|
148
|
+
continue; // trigger not present
|
|
149
|
+
// Extract the argument (text after the trigger on the same line)
|
|
150
|
+
const after = message.substring(idx + provider.trigger.length);
|
|
151
|
+
let arg;
|
|
152
|
+
if (provider.requiresArg) {
|
|
153
|
+
const end = after.indexOf("\n");
|
|
154
|
+
arg = (end >= 0 ? after.substring(0, end) : after).trim();
|
|
155
|
+
}
|
|
156
|
+
// Remove the trigger (+ optional arg) from the clean message
|
|
157
|
+
const fullTrigger = provider.requiresArg && arg
|
|
158
|
+
? `${provider.trigger} ${arg}`
|
|
159
|
+
: provider.trigger;
|
|
160
|
+
clean = clean.replace(fullTrigger, "").trim();
|
|
161
|
+
try {
|
|
162
|
+
const result = await provider.resolve(arg, { workingDir, terminalOutput: lastTerminalOutput });
|
|
163
|
+
if (result.content)
|
|
164
|
+
injected.push(result.content);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// If a provider fails, skip it silently — the message still goes through
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Append all injected context blocks separated by a horizontal rule
|
|
171
|
+
return injected.length
|
|
172
|
+
? `${clean}\n\n---\n\n${injected.join("\n\n---\n\n")}`
|
|
173
|
+
: clean;
|
|
174
|
+
}
|
|
175
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
176
|
+
// Public API
|
|
177
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
178
|
+
return {
|
|
179
|
+
// Refs exposed so slash commands in useChat.ts can mutate them
|
|
180
|
+
agentRef,
|
|
181
|
+
modelConfigRef,
|
|
182
|
+
toolRegistryRef,
|
|
183
|
+
workingDirRef,
|
|
184
|
+
planManagerRef,
|
|
185
|
+
rulesManagerRef,
|
|
186
|
+
effortManagerRef,
|
|
187
|
+
mcpManagerRef,
|
|
188
|
+
contextProvidersRef,
|
|
189
|
+
// Actions
|
|
190
|
+
rebuildAgent,
|
|
191
|
+
resolveContextProviders,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
195
|
+
// Private helpers (module-level, not exported)
|
|
196
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
197
|
+
/**
|
|
198
|
+
* Register all built-in @mention context providers.
|
|
199
|
+
*
|
|
200
|
+
* The Strategy pattern: each provider is interchangeable and can be added or
|
|
201
|
+
* removed without changing the chat hook.
|
|
202
|
+
*/
|
|
203
|
+
function buildContextProviders() {
|
|
204
|
+
const reg = new core_1.ContextProviderRegistry();
|
|
205
|
+
reg.register(new core_1.TerminalContextProvider()); // @terminal — recent shell output
|
|
206
|
+
reg.register(new core_1.UrlContextProvider()); // @url <link> — fetch a webpage
|
|
207
|
+
reg.register(new core_1.TreeContextProvider()); // @tree — project file tree
|
|
208
|
+
reg.register(new core_1.CodebaseContextProvider()); // @codebase — full codebase
|
|
209
|
+
reg.register(new core_1.ClipboardContextProvider()); // @clip — clipboard content
|
|
210
|
+
reg.register(new core_1.FileIncludeContextProvider()); // @file <path> — include a file
|
|
211
|
+
return reg;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=useAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAgent.js","sourceRoot":"","sources":["../../../src/ui/hooks/useAgent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useChat.ts — Main chat state hook.
|
|
3
|
+
*
|
|
4
|
+
* This is the top-level hook consumed by App.tsx. It wires together three
|
|
5
|
+
* concerns that intentionally live in separate modules:
|
|
6
|
+
*
|
|
7
|
+
* 1. Agent lifecycle → ./useAgent.ts
|
|
8
|
+
* Build / rebuild the AgentRunner when settings change.
|
|
9
|
+
*
|
|
10
|
+
* 2. Pure utilities → ./helpers.ts
|
|
11
|
+
* Terminal output, diff printing, help text — no React.
|
|
12
|
+
*
|
|
13
|
+
* 3. This file (useChat.ts)
|
|
14
|
+
* - Message history (what's displayed in the chat window)
|
|
15
|
+
* - Session / conversation persistence
|
|
16
|
+
* - Background jobs (/bg, /jobs)
|
|
17
|
+
* - Slash command dispatch (/model, /dir, /clear, …)
|
|
18
|
+
* - The sendMessage() function that runs the agent and streams tokens
|
|
19
|
+
*
|
|
20
|
+
* Learning note — why split at all?
|
|
21
|
+
* A single 1000-line file works but becomes hard to navigate. Splitting by
|
|
22
|
+
* responsibility means you can read useAgent.ts to understand "how is the
|
|
23
|
+
* AI agent built?" without wading through session management, and vice versa.
|
|
24
|
+
*
|
|
25
|
+
* Data flow:
|
|
26
|
+
* User types → UserInput.tsx → onSubmit → App.tsx → sendMessage()
|
|
27
|
+
* ↓
|
|
28
|
+
* agentRef.current.run()
|
|
29
|
+
* ↓
|
|
30
|
+
* onToken / onToolCall / onComplete
|
|
31
|
+
* ↓
|
|
32
|
+
* setStreamingContent / setMessages
|
|
33
|
+
*/
|
|
34
|
+
import type { ModelConfig } from "@cdoing/ai";
|
|
35
|
+
import type { ToolRegistry, PermissionManager, HookManager, MemoryStore, TodoStore } from "@cdoing/core";
|
|
36
|
+
import { listConversations } from "../../history";
|
|
37
|
+
import type { ChatMessage, ToolActivity, UsageInfo, ContextUsage, BackgroundJob } from "../types";
|
|
38
|
+
/** Props passed by the parent component (App.tsx → chat.ts → here) */
|
|
39
|
+
export interface UseChatOptions {
|
|
40
|
+
modelConfig: Partial<ModelConfig>;
|
|
41
|
+
toolRegistry: ToolRegistry;
|
|
42
|
+
permissionManager: PermissionManager;
|
|
43
|
+
hookManager: HookManager;
|
|
44
|
+
memoryStore: MemoryStore;
|
|
45
|
+
todoStore?: TodoStore;
|
|
46
|
+
}
|
|
47
|
+
export declare function useChat(opts: UseChatOptions): {
|
|
48
|
+
messages: ChatMessage[];
|
|
49
|
+
setMessages: import("react").Dispatch<import("react").SetStateAction<ChatMessage[]>>;
|
|
50
|
+
streamingContent: string;
|
|
51
|
+
isProcessing: boolean;
|
|
52
|
+
toolActivity: ToolActivity | null;
|
|
53
|
+
lastUsage: UsageInfo | null;
|
|
54
|
+
contextUsage: ContextUsage | null;
|
|
55
|
+
workingDir: string;
|
|
56
|
+
backgroundJobs: BackgroundJob[];
|
|
57
|
+
showSessionBrowser: boolean;
|
|
58
|
+
setShowSessionBrowser: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
59
|
+
conversations: typeof listConversations;
|
|
60
|
+
modelConfig: {
|
|
61
|
+
provider?: string | undefined;
|
|
62
|
+
model?: string | undefined;
|
|
63
|
+
apiKey?: string | undefined;
|
|
64
|
+
oauthToken?: string | undefined;
|
|
65
|
+
temperature?: number | undefined;
|
|
66
|
+
maxTokens?: number | undefined;
|
|
67
|
+
baseURL?: string | undefined;
|
|
68
|
+
};
|
|
69
|
+
sendMessage: (text: string) => Promise<void>;
|
|
70
|
+
handleSlashCommand: (command: string) => Promise<string | null>;
|
|
71
|
+
cancelCurrent: () => void;
|
|
72
|
+
addSystemMessage: (content: string) => void;
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=useChat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../../src/ui/hooks/useChat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EAEjB,WAAW,EACX,WAAW,EACX,SAAS,EACV,MAAM,cAAc,CAAC;AAItB,OAAO,EAIL,iBAAiB,EAKlB,MAAM,eAAe,CAAC;AAsBvB,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAiBlG,sEAAsE;AACtE,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAQ,OAAO,CAAC,WAAW,CAAC,CAAC;IACxC,YAAY,EAAO,YAAY,CAAC;IAChC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,WAAW,EAAQ,WAAW,CAAC;IAC/B,WAAW,EAAQ,WAAW,CAAC;IAC/B,SAAS,CAAC,EAAS,SAAS,CAAC;CAC9B;AAMD,wBAAgB,OAAO,CAAC,IAAI,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;wBAwL3B,MAAM;kCA2JH,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;;gCA/Od,MAAM,KAAG,IAAI;EAytBjD"}
|