@memclaw/memclaw 0.9.9

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/README.md ADDED
@@ -0,0 +1,276 @@
1
+ # MemClaw
2
+
3
+ Layered semantic memory plugin for OpenClaw with L0/L1/L2 tiered retrieval, automatic service management, and migration support from OpenClaw native memory.
4
+
5
+ ## Overview
6
+
7
+ MemClaw is an OpenClaw plugin that provides advanced semantic memory capabilities using Cortex Memory's tiered memory architecture. It stores, searches, and recalls memories with intelligent layer-based retrieval that balances speed and context.
8
+
9
+ ## Features
10
+
11
+ - **Three-Layer Memory Architecture**: L0 (abstract), L1 (overview), and L2 (full) layers for intelligent retrieval
12
+ - **Automatic Service Management**: Auto-starts Qdrant vector database and cortex-mem-service
13
+ - **Semantic Search**: Vector-based similarity search across all memory layers
14
+ - **Session Management**: Create, list, and close memory sessions
15
+ - **Migration Support**: One-click migration from OpenClaw native memory
16
+ - **Cross-Platform**: Supports Windows x64 and macOS Apple Silicon
17
+
18
+ ## Architecture
19
+
20
+ ### Memory Layers
21
+
22
+ | Layer | Tokens | Content | Role |
23
+ |-------|--------|---------|------|
24
+ | **L0 (Abstract)** | ~100 | High-level summary | Quick filtering |
25
+ | **L1 (Overview)** | ~2000 | Key points + context | Context refinement |
26
+ | **L2 (Full)** | Complete | Original content | Precise matching |
27
+
28
+ The search engine queries all three layers internally and returns unified results with `snippet` and `content`.
29
+
30
+ ### System Components
31
+
32
+ ```
33
+ OpenClaw + MemClaw Plugin
34
+
35
+ ├── cortex_search → Search memories
36
+ ├── cortex_recall → Recall with context
37
+ ├── cortex_add_memory → Store memories
38
+ ├── cortex_list_sessions → List sessions
39
+ ├── cortex_close_session → Close & extract
40
+ └── cortex_migrate → Migrate existing memory
41
+
42
+
43
+ cortex-mem-service (port 8085)
44
+
45
+
46
+ Qdrant (port 6334)
47
+ ```
48
+
49
+ ## Installation
50
+
51
+ ### Requirements
52
+
53
+ | Requirement | Details |
54
+ |-------------|---------|
55
+ | **Platforms** | Windows x64, macOS Apple Silicon |
56
+ | **Node.js** | ≥ 22.0.0 |
57
+ | **OpenClaw** | Installed and configured |
58
+
59
+ ### Install Plugin
60
+
61
+ ```bash
62
+ openclaw plugins install @memclaw/memclaw
63
+ ```
64
+
65
+ ### Local Development Installation
66
+
67
+ For developers who want to use a local version of memclaw or develop the plugin:
68
+
69
+ ```bash
70
+ # Clone the repository
71
+ git clone https://github.com/sopaco/cortex-mem.git
72
+ cd cortex-mem/examples/@memclaw/plugin
73
+
74
+ # Install dependencies
75
+ bun install
76
+
77
+ # Build the plugin
78
+ bun run build
79
+ ```
80
+
81
+ **Option A: Use plugins.load.paths**
82
+
83
+ ```json
84
+ {
85
+ "plugins": {
86
+ "load": {
87
+ "paths": ["/path/to/cortex-mem/examples/@memclaw/plugin"]
88
+ },
89
+ "entries": {
90
+ "memclaw": { "enabled": true }
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ **Option B: Symlink to extensions directory**
97
+
98
+ ```bash
99
+ mkdir -p ~/.openclaw/extensions
100
+ ln -sf "$(pwd)" ~/.openclaw/extensions/memclaw
101
+ ```
102
+
103
+ Then enable in `openclaw.json`:
104
+
105
+ ```json
106
+ {
107
+ "plugins": {
108
+ "entries": {
109
+ "memclaw": { "enabled": true }
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ After making code changes, rebuild with `bun run build` and restart OpenClaw.
116
+
117
+ ### Configure OpenClaw
118
+
119
+ Edit your `openclaw.json`:
120
+
121
+ ```json
122
+ {
123
+ "plugins": {
124
+ "entries": {
125
+ "memclaw": {
126
+ "enabled": true,
127
+ "config": {
128
+ "serviceUrl": "http://localhost:8085",
129
+ "tenantId": "tenant_claw",
130
+ "autoStartServices": true
131
+ }
132
+ }
133
+ }
134
+ },
135
+ "agents": {
136
+ "defaults": {
137
+ "memorySearch": { "enabled": false }
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+ > **Note**: Set `memorySearch.enabled: false` to disable OpenClaw's built-in memory search and use MemClaw instead.
144
+
145
+ ### Configure LLM
146
+
147
+ On first run, MemClaw creates a configuration file:
148
+
149
+ | Platform | Path |
150
+ |----------|------|
151
+ | Windows | `%APPDATA%\memclaw\config.toml` |
152
+ | macOS | `~/Library/Application Support/memclaw/config.toml` |
153
+
154
+ Edit the configuration file and fill in required fields:
155
+
156
+ ```toml
157
+ [llm]
158
+ api_key = "xxx" # REQUIRED: Your LLM API key
159
+
160
+ [embedding]
161
+ api_key = "xxx" # REQUIRED: Your embedding API key (can be same as llm.api_key)
162
+ ```
163
+
164
+ Then restart OpenClaw.
165
+
166
+ ## Available Tools
167
+
168
+ ### cortex_search
169
+
170
+ Semantic search across all memories using L0/L1/L2 tiered retrieval.
171
+
172
+ ```json
173
+ {
174
+ "query": "database architecture decisions",
175
+ "limit": 5,
176
+ "min_score": 0.6
177
+ }
178
+ ```
179
+
180
+ ### cortex_recall
181
+
182
+ Recall memories with more context (snippet + full content).
183
+
184
+ ```json
185
+ {
186
+ "query": "user preferences for code style",
187
+ "limit": 10
188
+ }
189
+ ```
190
+
191
+ ### cortex_add_memory
192
+
193
+ Store a message for future retrieval.
194
+
195
+ ```json
196
+ {
197
+ "content": "User prefers TypeScript with strict mode",
198
+ "role": "assistant",
199
+ "session_id": "default"
200
+ }
201
+ ```
202
+
203
+ ### cortex_list_sessions
204
+
205
+ List all memory sessions with status and message count.
206
+
207
+ ### cortex_close_session
208
+
209
+ Close a session and trigger memory extraction pipeline (takes 30-60 seconds).
210
+
211
+ ```json
212
+ {
213
+ "session_id": "default"
214
+ }
215
+ ```
216
+
217
+ ### cortex_migrate
218
+
219
+ Migrate from OpenClaw native memory to MemClaw. Run once during initial setup.
220
+
221
+ ## Configuration Options
222
+
223
+ | Option | Type | Default | Description |
224
+ |--------|------|---------|-------------|
225
+ | `serviceUrl` | string | `http://localhost:8085` | Cortex Memory service URL |
226
+ | `tenantId` | string | `tenant_claw` | Tenant ID for data isolation |
227
+ | `autoStartServices` | boolean | `true` | Auto-start Qdrant and service |
228
+ | `defaultSessionId` | string | `default` | Default session for memory operations |
229
+ | `searchLimit` | number | `10` | Default number of search results |
230
+ | `minScore` | number | `0.6` | Minimum relevance score (0-1) |
231
+
232
+ ## Quick Decision Flow
233
+
234
+ 1. **Need to find something** → `cortex_search`
235
+ 2. **Need more context** → `cortex_recall`
236
+ 3. **Save important information** → `cortex_add_memory`
237
+ 4. **Conversation complete** → `cortex_close_session`
238
+ 5. **First time setup** → `cortex_migrate`
239
+
240
+ ## Troubleshooting
241
+
242
+ ### Services Won't Start
243
+
244
+ 1. Check that ports 6333, 6334, 8085 are available
245
+ 2. Verify `api_key` fields are filled in config.toml
246
+ 3. Run `openclaw skills` to check plugin status
247
+
248
+ ### Search Returns No Results
249
+
250
+ 1. Run `cortex_list_sessions` to verify sessions exist
251
+ 2. Lower `min_score` threshold (default: 0.6)
252
+ 3. Check service health with `cortex-mem-cli stats`
253
+
254
+ ### Migration Fails
255
+
256
+ 1. Ensure OpenClaw workspace exists at `~/.openclaw/workspace`
257
+ 2. Verify memory files exist in `~/.openclaw/workspace/memory/`
258
+
259
+ ## CLI Reference
260
+
261
+ For advanced users, use the cortex-mem-cli directly:
262
+
263
+ ```bash
264
+ # List sessions
265
+ cortex-mem-cli --config config.toml --tenant tenant_claw session list
266
+
267
+ # Ensure all layers are generated
268
+ cortex-mem-cli --config config.toml --tenant tenant_claw layers ensure-all
269
+
270
+ # Rebuild vector index
271
+ cortex-mem-cli --config config.toml --tenant tenant_claw vector reindex
272
+ ```
273
+
274
+ ## License
275
+
276
+ MIT
@@ -0,0 +1,100 @@
1
+ /**
2
+ * MemClaw - Layered Semantic Memory for OpenClaw
3
+ *
4
+ * Provides:
5
+ * - L0/L1/L2 tiered memory retrieval
6
+ * - Automatic service startup (Qdrant + cortex-mem-service)
7
+ * - Migration from OpenClaw native memory
8
+ *
9
+ * Installation:
10
+ * openclaw plugins install memclaw
11
+ *
12
+ * Configuration (in openclaw.json):
13
+ * {
14
+ * "plugins": {
15
+ * "entries": {
16
+ * "memclaw": {
17
+ * "enabled": true,
18
+ * "config": {
19
+ * "serviceUrl": "http://localhost:8085",
20
+ * "tenantId": "tenant_claw",
21
+ * "autoStartServices": true
22
+ * }
23
+ * }
24
+ * }
25
+ * }
26
+ * }
27
+ */
28
+ export type { CortexMemClient } from './src/client.js';
29
+ export type { MemClawConfig } from './src/config.js';
30
+ interface PluginLogger {
31
+ debug?: (msg: string, ...args: unknown[]) => void;
32
+ info: (msg: string, ...args: unknown[]) => void;
33
+ warn: (msg: string, ...args: unknown[]) => void;
34
+ error: (msg: string, ...args: unknown[]) => void;
35
+ }
36
+ interface ToolDefinition {
37
+ name: string;
38
+ description: string;
39
+ parameters: object;
40
+ execute: (_id: string, params: Record<string, unknown>) => Promise<unknown>;
41
+ optional?: boolean;
42
+ }
43
+ interface PluginAPI {
44
+ pluginConfig?: Record<string, unknown>;
45
+ registerTool(tool: ToolDefinition, opts?: {
46
+ optional?: boolean;
47
+ }): void;
48
+ registerService(service: {
49
+ id: string;
50
+ start: () => Promise<void>;
51
+ stop: () => Promise<void>;
52
+ }): void;
53
+ logger: PluginLogger;
54
+ }
55
+ export default function memclawPlugin(api: PluginAPI): {
56
+ id: string;
57
+ name: string;
58
+ version: string;
59
+ };
60
+ export declare const plugin: {
61
+ id: string;
62
+ name: string;
63
+ version: string;
64
+ configSchema: {
65
+ type: string;
66
+ properties: {
67
+ serviceUrl: {
68
+ type: string;
69
+ default: string;
70
+ };
71
+ defaultSessionId: {
72
+ type: string;
73
+ default: string;
74
+ };
75
+ searchLimit: {
76
+ type: string;
77
+ default: number;
78
+ };
79
+ minScore: {
80
+ type: string;
81
+ default: number;
82
+ };
83
+ tenantId: {
84
+ type: string;
85
+ default: string;
86
+ };
87
+ autoStartServices: {
88
+ type: string;
89
+ default: boolean;
90
+ };
91
+ };
92
+ required: never[];
93
+ };
94
+ register(api: PluginAPI): {
95
+ id: string;
96
+ name: string;
97
+ version: string;
98
+ };
99
+ };
100
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD,UAAU,YAAY;IACrB,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClD,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAChD,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAChD,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACjD;AAED,UAAU,cAAc;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,SAAS;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACxE,eAAe,CAAC,OAAO,EAAE;QACxB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,MAAM,EAAE,YAAY,CAAC;CACrB;AAGD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,GAAG,EAAE,SAAS;;;;EAEnD;AAGD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgBJ,SAAS;;;;;CAGvB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+ /**
3
+ * MemClaw - Layered Semantic Memory for OpenClaw
4
+ *
5
+ * Provides:
6
+ * - L0/L1/L2 tiered memory retrieval
7
+ * - Automatic service startup (Qdrant + cortex-mem-service)
8
+ * - Migration from OpenClaw native memory
9
+ *
10
+ * Installation:
11
+ * openclaw plugins install memclaw
12
+ *
13
+ * Configuration (in openclaw.json):
14
+ * {
15
+ * "plugins": {
16
+ * "entries": {
17
+ * "memclaw": {
18
+ * "enabled": true,
19
+ * "config": {
20
+ * "serviceUrl": "http://localhost:8085",
21
+ * "tenantId": "tenant_claw",
22
+ * "autoStartServices": true
23
+ * }
24
+ * }
25
+ * }
26
+ * }
27
+ * }
28
+ */
29
+ Object.defineProperty(exports, '__esModule', { value: true });
30
+ exports.plugin = void 0;
31
+ exports.default = memclawPlugin;
32
+ const plugin_impl_js_1 = require('./plugin-impl.js');
33
+ // Default export - main plugin function
34
+ function memclawPlugin(api) {
35
+ return (0, plugin_impl_js_1.createPlugin)(api);
36
+ }
37
+ // Named export - object style registration
38
+ exports.plugin = {
39
+ id: 'memclaw',
40
+ name: 'MemClaw',
41
+ version: '0.9.9',
42
+ configSchema: {
43
+ type: 'object',
44
+ properties: {
45
+ serviceUrl: { type: 'string', default: 'http://localhost:8085' },
46
+ defaultSessionId: { type: 'string', default: 'default' },
47
+ searchLimit: { type: 'integer', default: 10 },
48
+ minScore: { type: 'number', default: 0.6 },
49
+ tenantId: { type: 'string', default: 'tenant_claw' },
50
+ autoStartServices: { type: 'boolean', default: true }
51
+ },
52
+ required: []
53
+ },
54
+ register(api) {
55
+ return (0, plugin_impl_js_1.createPlugin)(api);
56
+ }
57
+ };
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;AAoCH,gCAEC;AApCD,qDAAgD;AAiChD,wCAAwC;AACxC,SAAwB,aAAa,CAAC,GAAc;IACnD,OAAO,IAAA,6BAAY,EAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,2CAA2C;AAC9B,QAAA,MAAM,GAAG;IACrB,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,OAAO;IAChB,YAAY,EAAE;QACb,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACX,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,uBAAuB,EAAE;YAChE,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE;YACxD,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE;YAC7C,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE;YAC1C,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE;YACpD,iBAAiB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE;SACrD;QACD,QAAQ,EAAE,EAAE;KACZ;IACD,QAAQ,CAAC,GAAc;QACtB,OAAO,IAAA,6BAAY,EAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;CACD,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * MemClaw Plugin Implementation
3
+ *
4
+ * Provides layered semantic memory for OpenClaw with:
5
+ * - Automatic service startup
6
+ * - Memory tools (search, recall, add, list, close)
7
+ * - Migration from OpenClaw native memory
8
+ */
9
+ interface PluginLogger {
10
+ debug?: (msg: string, ...args: unknown[]) => void;
11
+ info: (msg: string, ...args: unknown[]) => void;
12
+ warn: (msg: string, ...args: unknown[]) => void;
13
+ error: (msg: string, ...args: unknown[]) => void;
14
+ }
15
+ interface CronAPI {
16
+ call(params: {
17
+ method: "add" | "remove" | "list";
18
+ params?: {
19
+ name?: string;
20
+ schedule?: {
21
+ kind: string;
22
+ expr: string;
23
+ };
24
+ sessionTarget?: string;
25
+ payload?: {
26
+ kind: string;
27
+ message: string;
28
+ };
29
+ delivery?: {
30
+ mode: string;
31
+ };
32
+ };
33
+ }): Promise<unknown>;
34
+ }
35
+ interface RuntimeAPI {
36
+ tools: {
37
+ get(name: "cron"): CronAPI;
38
+ };
39
+ }
40
+ interface ToolDefinition {
41
+ name: string;
42
+ description: string;
43
+ parameters: object;
44
+ execute: (_id: string, params: Record<string, unknown>) => Promise<unknown>;
45
+ optional?: boolean;
46
+ }
47
+ interface PluginAPI {
48
+ pluginConfig?: Record<string, unknown>;
49
+ registerTool(tool: ToolDefinition, opts?: {
50
+ optional?: boolean;
51
+ }): void;
52
+ registerService(service: {
53
+ id: string;
54
+ start: () => Promise<void>;
55
+ stop: () => Promise<void>;
56
+ }): void;
57
+ logger: PluginLogger;
58
+ runtime?: RuntimeAPI;
59
+ }
60
+ export declare function createPlugin(api: PluginAPI): {
61
+ id: string;
62
+ name: string;
63
+ version: string;
64
+ };
65
+ export {};
66
+ //# sourceMappingURL=plugin-impl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-impl.d.ts","sourceRoot":"","sources":["../plugin-impl.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA0CH,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClD,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAChD,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAChD,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CAClD;AAED,UAAU,OAAO;IACf,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;QAClC,MAAM,CAAC,EAAE;YACP,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC;YAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;YACvB,OAAO,CAAC,EAAE;gBACR,IAAI,EAAE,MAAM,CAAC;gBACb,OAAO,EAAE,MAAM,CAAC;aACjB,CAAC;YACF,QAAQ,CAAC,EAAE;gBAAE,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC;SAC7B,CAAC;KACH,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtB;AAED,UAAU,UAAU;IAClB,KAAK,EAAE;QACL,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;KAC5B,CAAC;CACH;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,SAAS;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACxE,eAAe,CAAC,OAAO,EAAE;QACvB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;KAC3B,GAAG,IAAI,CAAC;IACT,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAqPD,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS;;;;EAwc1C"}