claude-code-memory 1.0.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.
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * install.ts - Set up memory-mcp for a project or globally.
5
+ *
6
+ * Usage:
7
+ * node dist/install.js <project-dir> # Per-project install
8
+ * node dist/install.js --global # Global install (all projects)
9
+ * node dist/install.js --api-key <key> # Store API key globally
10
+ * node dist/install.js --global --api-key <key> # Both
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const args = process.argv.slice(2);
49
+ const isGlobal = args.includes("--global");
50
+ const apiKeyIdx = args.indexOf("--api-key");
51
+ const apiKey = apiKeyIdx !== -1 ? args[apiKeyIdx + 1] : null;
52
+ const projectDir = args.find((a) => !a.startsWith("--") && a !== apiKey);
53
+ const memoryMcpDir = path.resolve(__dirname, "..");
54
+ const extractorPath = path.join(memoryMcpDir, "dist", "extractor.js");
55
+ const serverPath = path.join(memoryMcpDir, "dist", "index.js");
56
+ const homeDir = process.env.HOME || "";
57
+ if (!isGlobal && !projectDir && !apiKey) {
58
+ console.error(`Usage:
59
+ memory-mcp-install <project-dir> Per-project install
60
+ memory-mcp-install --global Global install (all projects)
61
+ memory-mcp-install --api-key <key> Store API key
62
+ memory-mcp-install --global --api-key <key> Both`);
63
+ process.exit(1);
64
+ }
65
+ // --- Store API Key ---
66
+ if (apiKey) {
67
+ const configDir = path.join(homeDir, ".memory-mcp");
68
+ if (!fs.existsSync(configDir)) {
69
+ fs.mkdirSync(configDir, { recursive: true });
70
+ }
71
+ const configPath = path.join(configDir, "config.json");
72
+ let config = {};
73
+ if (fs.existsSync(configPath)) {
74
+ config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
75
+ }
76
+ config.apiKey = apiKey;
77
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
78
+ console.log(` ✓ API key stored in ~/.memory-mcp/config.json`);
79
+ }
80
+ // --- Hook Config ---
81
+ const hookCommand = `node ${extractorPath}`;
82
+ const hookEntry = {
83
+ hooks: [{ type: "command", command: hookCommand, timeout: 30 }],
84
+ };
85
+ function installHooks(settingsPath) {
86
+ const dir = path.dirname(settingsPath);
87
+ if (!fs.existsSync(dir)) {
88
+ fs.mkdirSync(dir, { recursive: true });
89
+ }
90
+ let settings = {};
91
+ if (fs.existsSync(settingsPath)) {
92
+ settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
93
+ }
94
+ if (!settings.hooks)
95
+ settings.hooks = {};
96
+ for (const event of ["Stop", "PreCompact", "SessionEnd"]) {
97
+ if (!settings.hooks[event]) {
98
+ settings.hooks[event] = [];
99
+ }
100
+ const alreadyInstalled = settings.hooks[event].some((h) => h.hooks?.some((hh) => hh.command?.includes("memory-mcp")));
101
+ if (!alreadyInstalled) {
102
+ settings.hooks[event].push(hookEntry);
103
+ console.log(` ✓ Added ${event} hook`);
104
+ }
105
+ else {
106
+ console.log(` · ${event} hook already exists`);
107
+ }
108
+ }
109
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
110
+ }
111
+ // --- Global Install ---
112
+ if (isGlobal) {
113
+ console.log(`\nInstalling memory-mcp globally\n`);
114
+ // Hooks in ~/.claude/settings.json
115
+ const globalSettingsPath = path.join(homeDir, ".claude", "settings.json");
116
+ installHooks(globalSettingsPath);
117
+ console.log(`
118
+ Done! memory-mcp hooks installed globally.
119
+
120
+ How it works:
121
+ 1. Claude works normally in any project — no commands needed
122
+ 2. After each response, a hook silently reads the transcript
123
+ 3. A fast LLM extracts important memories to .memory/ in the project
124
+ 4. Memories sync to CLAUDE.md automatically
125
+ 5. New sessions read CLAUDE.md → instant context recovery
126
+
127
+ To also add the MCP server (for search/ask tools), add to each project's .mcp.json:
128
+ {
129
+ "mcpServers": {
130
+ "memory": {
131
+ "command": "node",
132
+ "args": ["${serverPath}"]
133
+ }
134
+ }
135
+ }
136
+
137
+ Or run: memory-mcp-install <project-dir> (for per-project MCP)
138
+ `);
139
+ }
140
+ // --- Per-Project Install ---
141
+ if (projectDir) {
142
+ const absProjectDir = path.resolve(projectDir);
143
+ console.log(`\nInstalling memory-mcp for: ${absProjectDir}\n`);
144
+ // 1. Create .memory directory
145
+ const memDir = path.join(absProjectDir, ".memory");
146
+ if (!fs.existsSync(memDir)) {
147
+ fs.mkdirSync(memDir, { recursive: true });
148
+ console.log(" ✓ Created .memory/");
149
+ }
150
+ else {
151
+ console.log(" · .memory/ already exists");
152
+ }
153
+ // 2. Hooks (project-level)
154
+ const settingsPath = path.join(absProjectDir, ".claude", "settings.json");
155
+ installHooks(settingsPath);
156
+ // 3. MCP server config
157
+ const mcpPath = path.join(absProjectDir, ".mcp.json");
158
+ let mcpConfig = {};
159
+ if (fs.existsSync(mcpPath)) {
160
+ mcpConfig = JSON.parse(fs.readFileSync(mcpPath, "utf-8"));
161
+ }
162
+ if (!mcpConfig.mcpServers)
163
+ mcpConfig.mcpServers = {};
164
+ if (!mcpConfig.mcpServers.memory) {
165
+ mcpConfig.mcpServers.memory = {
166
+ command: "node",
167
+ args: [serverPath, absProjectDir],
168
+ };
169
+ console.log(" ✓ Added MCP server to .mcp.json");
170
+ }
171
+ else {
172
+ console.log(" · MCP server already in .mcp.json");
173
+ }
174
+ fs.writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2));
175
+ // 4. .gitignore
176
+ const gitignorePath = path.join(absProjectDir, ".gitignore");
177
+ if (fs.existsSync(gitignorePath)) {
178
+ const gitignore = fs.readFileSync(gitignorePath, "utf-8");
179
+ if (!gitignore.includes(".memory")) {
180
+ fs.appendFileSync(gitignorePath, "\n# Memory MCP\n.memory/\n");
181
+ console.log(" ✓ Added .memory/ to .gitignore");
182
+ }
183
+ else {
184
+ console.log(" · .memory/ already in .gitignore");
185
+ }
186
+ }
187
+ else {
188
+ fs.writeFileSync(gitignorePath, "# Memory MCP\n.memory/\n");
189
+ console.log(" ✓ Created .gitignore with .memory/");
190
+ }
191
+ console.log(`
192
+ Done! memory-mcp installed for ${absProjectDir}.
193
+
194
+ MCP Tools available:
195
+ memory_search — keyword search across all memories
196
+ memory_related — get memories by tag/area
197
+ memory_ask — ask a question, get synthesized answer
198
+ memory_save — manually save a memory
199
+ memory_recall — list all memories
200
+ memory_stats — show memory statistics
201
+ memory_consolidate — merge/prune memories
202
+ `);
203
+ }
204
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
package/dist/llm.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { Memory } from "./types";
2
+ /**
3
+ * Shared LLM utilities: API key resolution and Anthropic API calls.
4
+ */
5
+ export declare function resolveApiKey(): Promise<string | null>;
6
+ export declare function callHaiku(prompt: string, maxTokens?: number): Promise<string | null>;
7
+ export declare function buildExtractionPrompt(existingMemories: Memory[], transcript: string): string;
8
+ export declare function buildConsolidationPrompt(type: string, memories: {
9
+ id: string;
10
+ content: string;
11
+ }[]): string;
12
+ export declare function buildAskPrompt(question: string, memories: Memory[]): string;
13
+ //# sourceMappingURL=llm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC;;GAEG;AAEH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuB5D;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAa,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsBhG;AAED,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAuC5F;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,GAC1C,MAAM,CAsBR;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAW3E"}
package/dist/llm.js ADDED
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveApiKey = resolveApiKey;
37
+ exports.callHaiku = callHaiku;
38
+ exports.buildExtractionPrompt = buildExtractionPrompt;
39
+ exports.buildConsolidationPrompt = buildConsolidationPrompt;
40
+ exports.buildAskPrompt = buildAskPrompt;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ /**
44
+ * Shared LLM utilities: API key resolution and Anthropic API calls.
45
+ */
46
+ async function resolveApiKey() {
47
+ // 1. Explicit env var
48
+ if (process.env.ANTHROPIC_API_KEY)
49
+ return process.env.ANTHROPIC_API_KEY;
50
+ // 2. Global memory-mcp config
51
+ const globalConfig = path.join(process.env.HOME || "", ".memory-mcp", "config.json");
52
+ if (fs.existsSync(globalConfig)) {
53
+ try {
54
+ const cfg = JSON.parse(fs.readFileSync(globalConfig, "utf-8"));
55
+ if (cfg.apiKey)
56
+ return cfg.apiKey;
57
+ }
58
+ catch { }
59
+ }
60
+ // 3. Claude CLI config paths
61
+ const candidates = [
62
+ path.join(process.env.HOME || "", ".config", "anthropic", "api_key"),
63
+ path.join(process.env.HOME || "", ".anthropic", "api_key"),
64
+ ];
65
+ for (const p of candidates) {
66
+ if (fs.existsSync(p))
67
+ return fs.readFileSync(p, "utf-8").trim();
68
+ }
69
+ return null;
70
+ }
71
+ async function callHaiku(prompt, maxTokens = 1024) {
72
+ const key = await resolveApiKey();
73
+ if (!key)
74
+ return null;
75
+ const response = await fetch("https://api.anthropic.com/v1/messages", {
76
+ method: "POST",
77
+ headers: {
78
+ "Content-Type": "application/json",
79
+ "x-api-key": key,
80
+ "anthropic-version": "2023-06-01",
81
+ },
82
+ body: JSON.stringify({
83
+ model: "claude-3-5-haiku-20241022",
84
+ max_tokens: maxTokens,
85
+ messages: [{ role: "user", content: prompt }],
86
+ }),
87
+ });
88
+ if (!response.ok)
89
+ return null;
90
+ const data = (await response.json());
91
+ return data.content?.[0]?.text || null;
92
+ }
93
+ function buildExtractionPrompt(existingMemories, transcript) {
94
+ const existingSummary = existingMemories
95
+ .filter((m) => !m.tags.includes("superseded") && (m.confidence ?? 1) > 0.3)
96
+ .map((m) => ` [${m.type}] ${m.content}`)
97
+ .join("\n");
98
+ return `You are a memory extractor for a coding project. Analyze the conversation transcript and extract ONLY important new memories.
99
+
100
+ EXISTING MEMORIES (do NOT duplicate these — only add NEW info or UPDATES):
101
+ ${existingSummary || " (none yet)"}
102
+
103
+ Extract only memories that are:
104
+ - NEW information not covered above
105
+ - UPDATES to existing memories (something changed — include "supersedes_content" with the OLD text)
106
+ - CORRECTIONS to existing memories
107
+
108
+ Categories:
109
+ - architecture: System structure, components, tech stack
110
+ - decision: Why X was chosen over Y, trade-offs
111
+ - pattern: Codebase conventions (naming, structure, approach)
112
+ - gotcha: Non-obvious pitfalls, surprising bugs
113
+ - progress: Completed work, in-flight tasks, blockers
114
+ - context: Business context, deadlines, requirements, preferences
115
+
116
+ Rules:
117
+ - SKIP trivial operations (typo fixes, file reads, routine commands)
118
+ - SKIP things obvious from code itself
119
+ - Each memory: one clear, specific sentence with concrete details (file names, function names)
120
+ - If nothing new, return empty array
121
+ - Be VERY selective — 0-3 memories per extraction is typical
122
+ - Include relevant tags for categorization
123
+
124
+ Return JSON only:
125
+ [{"type": "decision", "content": "...", "tags": ["auth"], "supersedes_content": null}, ...]
126
+
127
+ Empty result: []
128
+
129
+ --- TRANSCRIPT ---
130
+ ${transcript}`;
131
+ }
132
+ function buildConsolidationPrompt(type, memories) {
133
+ const memList = memories.map((m) => ` ${m.id}: ${m.content}`).join("\n");
134
+ return `You are a memory consolidator. Below are ${memories.length} memories of type "${type}" from a coding project.
135
+
136
+ Merge memories that overlap or can be combined into one clearer memory.
137
+ Remove memories that are outdated or no longer relevant given later ones.
138
+ Keep memories that are unique and still valuable.
139
+
140
+ Return JSON only:
141
+ {
142
+ "keep": ["mem_id1", "mem_id2"],
143
+ "merge": [
144
+ {"content": "merged text here", "tags": ["tag1"], "sources": ["mem_id3", "mem_id4"]}
145
+ ],
146
+ "drop": ["mem_id5"]
147
+ }
148
+
149
+ Every input memory ID must appear in exactly one of: keep, merge.sources, or drop.
150
+
151
+ MEMORIES:
152
+ ${memList}`;
153
+ }
154
+ function buildAskPrompt(question, memories) {
155
+ const memList = memories
156
+ .map((m) => ` [${m.type}] ${m.content}`)
157
+ .join("\n");
158
+ return `You have access to project memories. Answer the question using ONLY the memories below. Be concise and specific. If the memories don't contain enough info, say so.
159
+
160
+ MEMORIES:
161
+ ${memList}
162
+
163
+ QUESTION: ${question}`;
164
+ }
165
+ //# sourceMappingURL=llm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.js","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { Memory, MemoryType, ProjectState } from "./types";
2
+ export declare function tokenize(s: string): Set<string>;
3
+ export declare function jaccard(a: Set<string>, b: Set<string>): number;
4
+ export declare class MemoryStore {
5
+ private storePath;
6
+ private memDir;
7
+ private state;
8
+ constructor(projectDir: string);
9
+ private load;
10
+ private save;
11
+ acquireLock(): boolean;
12
+ releaseLock(): void;
13
+ setProject(name: string, description: string): void;
14
+ incrementExtractionCount(): number;
15
+ getExtractionCount(): number;
16
+ addMemory(memory: Omit<Memory, "id" | "created" | "updated" | "confidence" | "accessCount">): Memory | null;
17
+ deleteMemory(id: string): boolean;
18
+ getActiveMemories(): Memory[];
19
+ getMemories(opts?: {
20
+ type?: string;
21
+ tags?: string[];
22
+ active?: boolean;
23
+ }): Memory[];
24
+ searchMemories(query: string, limit?: number): Memory[];
25
+ getRelated(tags: string[], type?: MemoryType): Memory[];
26
+ decayConfidence(): void;
27
+ needsConsolidation(): boolean;
28
+ /**
29
+ * Apply consolidation results from LLM.
30
+ * Called by extractor after getting LLM consolidation response.
31
+ */
32
+ applyConsolidation(results: {
33
+ keep: string[];
34
+ merge: {
35
+ content: string;
36
+ tags: string[];
37
+ sources: string[];
38
+ }[];
39
+ drop: string[];
40
+ }): void;
41
+ /**
42
+ * Get memories formatted for consolidation LLM prompt (grouped by type).
43
+ */
44
+ getMemoriesForConsolidation(): Record<string, {
45
+ id: string;
46
+ content: string;
47
+ }[]>;
48
+ getState(): ProjectState;
49
+ getAllMemoryCount(): {
50
+ active: number;
51
+ archived: number;
52
+ superseded: number;
53
+ total: number;
54
+ };
55
+ generateConsciousness(): string;
56
+ }
57
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAkC3D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAO/C;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAQ9D;AA+CD,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAe;gBAEhB,UAAU,EAAE,MAAM;IAS9B,OAAO,CAAC,IAAI;IAwBZ,OAAO,CAAC,IAAI;IAKZ,WAAW,IAAI,OAAO;IAItB,WAAW,IAAI,IAAI;IAInB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAMnD,wBAAwB,IAAI,MAAM;IAMlC,kBAAkB,IAAI,MAAM;IAM5B,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,aAAa,CAAC,GAAG,MAAM,GAAG,IAAI;IAyC3G,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAUjC,iBAAiB,IAAI,MAAM,EAAE;IAM7B,WAAW,CAAC,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,EAAE;IAclF,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,MAAM,EAAE;IAoB3D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,EAAE;IAkBvD,eAAe,IAAI,IAAI;IAkBvB,kBAAkB,IAAI,OAAO;IAK7B;;;OAGG;IACH,kBAAkB,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,EAAE,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI;IAsDtI;;OAEG;IACH,2BAA2B,IAAI,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAUhF,QAAQ,IAAI,YAAY;IAIxB,iBAAiB,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAW5F,qBAAqB,IAAI,MAAM;CAsFhC"}