squads-cli 0.2.0 → 0.4.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/README.md +470 -75
- package/dist/chunk-7OCVIDC7.js +12 -0
- package/dist/chunk-7OCVIDC7.js.map +1 -0
- package/dist/chunk-FUHBEL3L.js +203 -0
- package/dist/chunk-FUHBEL3L.js.map +1 -0
- package/dist/chunk-G63RBKDH.js +980 -0
- package/dist/chunk-G63RBKDH.js.map +1 -0
- package/dist/cli.js +4174 -1962
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -4
- package/dist/index.js +1 -11
- package/dist/index.js.map +1 -1
- package/dist/memory-4PVUKIDK.js +19 -0
- package/dist/memory-4PVUKIDK.js.map +1 -0
- package/dist/sessions-JCQ34BEU.js +15 -0
- package/dist/sessions-JCQ34BEU.js.map +1 -0
- package/docker/.env.example +17 -0
- package/docker/README.md +92 -0
- package/docker/docker-compose.engram.yml +289 -0
- package/docker/docker-compose.yml +194 -0
- package/docker/init-db.sql +399 -0
- package/docker/init-engram-db.sql +148 -0
- package/docker/init-langfuse-db.sh +10 -0
- package/docker/otel-collector.yaml +34 -0
- package/docker/squads-bridge/Dockerfile +14 -0
- package/docker/squads-bridge/Dockerfile.proxy +14 -0
- package/docker/squads-bridge/anthropic_proxy.py +313 -0
- package/docker/squads-bridge/requirements.txt +7 -0
- package/docker/squads-bridge/squads_bridge.py +1610 -0
- package/docker/telemetry-ping/Dockerfile +10 -0
- package/docker/telemetry-ping/deploy.sh +69 -0
- package/docker/telemetry-ping/main.py +136 -0
- package/docker/telemetry-ping/requirements.txt +3 -0
- package/package.json +15 -2
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
__require
|
|
4
|
+
} from "./chunk-7OCVIDC7.js";
|
|
5
|
+
|
|
6
|
+
// src/lib/memory.ts
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from "fs";
|
|
8
|
+
import { join, dirname } from "path";
|
|
9
|
+
function findMemoryDir() {
|
|
10
|
+
let dir = process.cwd();
|
|
11
|
+
for (let i = 0; i < 5; i++) {
|
|
12
|
+
const memoryPath = join(dir, ".agents", "memory");
|
|
13
|
+
if (existsSync(memoryPath)) {
|
|
14
|
+
return memoryPath;
|
|
15
|
+
}
|
|
16
|
+
const parent = join(dir, "..");
|
|
17
|
+
if (parent === dir) break;
|
|
18
|
+
dir = parent;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
function listMemoryEntries(memoryDir) {
|
|
23
|
+
const entries = [];
|
|
24
|
+
const squads = readdirSync(memoryDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
25
|
+
for (const squad of squads) {
|
|
26
|
+
const squadPath = join(memoryDir, squad);
|
|
27
|
+
const agents = readdirSync(squadPath, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
28
|
+
for (const agent of agents) {
|
|
29
|
+
const agentPath = join(squadPath, agent);
|
|
30
|
+
const files = readdirSync(agentPath).filter((f) => f.endsWith(".md"));
|
|
31
|
+
for (const file of files) {
|
|
32
|
+
const filePath = join(agentPath, file);
|
|
33
|
+
const type = file.replace(".md", "");
|
|
34
|
+
entries.push({
|
|
35
|
+
squad,
|
|
36
|
+
agent,
|
|
37
|
+
type,
|
|
38
|
+
content: readFileSync(filePath, "utf-8"),
|
|
39
|
+
path: filePath
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return entries;
|
|
45
|
+
}
|
|
46
|
+
var SEMANTIC_EXPANSIONS = {
|
|
47
|
+
"pricing": ["price", "cost", "$", "revenue", "fee", "rate"],
|
|
48
|
+
"price": ["pricing", "cost", "$", "fee"],
|
|
49
|
+
"revenue": ["income", "sales", "mrr", "arr", "$"],
|
|
50
|
+
"cost": ["expense", "spend", "budget", "$", "price"],
|
|
51
|
+
"customer": ["client", "lead", "prospect", "user"],
|
|
52
|
+
"client": ["customer", "lead", "prospect"],
|
|
53
|
+
"lead": ["prospect", "customer", "client", "pipeline"],
|
|
54
|
+
"agent": ["squad", "bot", "ai"],
|
|
55
|
+
"squad": ["team", "agent", "group"],
|
|
56
|
+
"status": ["state", "progress", "health"],
|
|
57
|
+
"bug": ["issue", "error", "problem", "fix"],
|
|
58
|
+
"feature": ["capability", "function", "ability"]
|
|
59
|
+
};
|
|
60
|
+
function expandQuery(query) {
|
|
61
|
+
const words = query.toLowerCase().split(/\s+/);
|
|
62
|
+
const expanded = new Set(words);
|
|
63
|
+
for (const word of words) {
|
|
64
|
+
if (SEMANTIC_EXPANSIONS[word]) {
|
|
65
|
+
SEMANTIC_EXPANSIONS[word].forEach((syn) => expanded.add(syn));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return Array.from(expanded);
|
|
69
|
+
}
|
|
70
|
+
function getFileAge(filePath) {
|
|
71
|
+
try {
|
|
72
|
+
const { statSync } = __require("fs");
|
|
73
|
+
const stats = statSync(filePath);
|
|
74
|
+
const ageMs = Date.now() - stats.mtimeMs;
|
|
75
|
+
const ageDays = ageMs / (1e3 * 60 * 60 * 24);
|
|
76
|
+
return ageDays;
|
|
77
|
+
} catch {
|
|
78
|
+
return 999;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function searchMemory(query, memoryDir) {
|
|
82
|
+
const dir = memoryDir || findMemoryDir();
|
|
83
|
+
if (!dir) return [];
|
|
84
|
+
const entries = listMemoryEntries(dir);
|
|
85
|
+
const results = [];
|
|
86
|
+
const queryLower = query.toLowerCase();
|
|
87
|
+
const expandedTerms = expandQuery(queryLower);
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
const contentLower = entry.content.toLowerCase();
|
|
90
|
+
const lines = entry.content.split("\n");
|
|
91
|
+
const matches = [];
|
|
92
|
+
let score = 0;
|
|
93
|
+
let directHits = 0;
|
|
94
|
+
let expandedHits = 0;
|
|
95
|
+
const directWords = queryLower.split(/\s+/);
|
|
96
|
+
for (const word of directWords) {
|
|
97
|
+
if (contentLower.includes(word)) {
|
|
98
|
+
directHits += 1;
|
|
99
|
+
score += 2;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
for (const term of expandedTerms) {
|
|
103
|
+
if (contentLower.includes(term)) {
|
|
104
|
+
expandedHits += 1;
|
|
105
|
+
score += 0.5;
|
|
106
|
+
for (let i = 0; i < lines.length; i++) {
|
|
107
|
+
const line = lines[i];
|
|
108
|
+
if (line.toLowerCase().includes(term) && line.trim() && !matches.includes(line.trim())) {
|
|
109
|
+
matches.push(line.trim());
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (contentLower.includes(queryLower)) {
|
|
115
|
+
score += 5;
|
|
116
|
+
}
|
|
117
|
+
const ageDays = getFileAge(entry.path);
|
|
118
|
+
if (ageDays < 1) {
|
|
119
|
+
score *= 1.5;
|
|
120
|
+
} else if (ageDays < 7) {
|
|
121
|
+
score *= 1.2;
|
|
122
|
+
} else if (ageDays > 30) {
|
|
123
|
+
score *= 0.8;
|
|
124
|
+
}
|
|
125
|
+
const typeWeights = {
|
|
126
|
+
"state": 1.2,
|
|
127
|
+
// Current state slightly preferred
|
|
128
|
+
"learnings": 1.1,
|
|
129
|
+
// Learnings are valuable
|
|
130
|
+
"output": 1,
|
|
131
|
+
// Recent outputs
|
|
132
|
+
"feedback": 0.9
|
|
133
|
+
// Feedback less commonly needed
|
|
134
|
+
};
|
|
135
|
+
score *= typeWeights[entry.type] || 1;
|
|
136
|
+
if (score > 0 && (directHits > 0 || expandedHits > 1)) {
|
|
137
|
+
results.push({ entry, matches: matches.slice(0, 7), score });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return results.sort((a, b) => b.score - a.score);
|
|
141
|
+
}
|
|
142
|
+
function getSquadState(squadName) {
|
|
143
|
+
const memoryDir = findMemoryDir();
|
|
144
|
+
if (!memoryDir) return [];
|
|
145
|
+
const squadPath = join(memoryDir, squadName);
|
|
146
|
+
if (!existsSync(squadPath)) return [];
|
|
147
|
+
const entries = [];
|
|
148
|
+
const agents = readdirSync(squadPath, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
149
|
+
for (const agent of agents) {
|
|
150
|
+
const statePath = join(squadPath, agent, "state.md");
|
|
151
|
+
if (existsSync(statePath)) {
|
|
152
|
+
entries.push({
|
|
153
|
+
squad: squadName,
|
|
154
|
+
agent,
|
|
155
|
+
type: "state",
|
|
156
|
+
content: readFileSync(statePath, "utf-8"),
|
|
157
|
+
path: statePath
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return entries;
|
|
162
|
+
}
|
|
163
|
+
function updateMemory(squadName, agentName, type, content) {
|
|
164
|
+
const memoryDir = findMemoryDir();
|
|
165
|
+
if (!memoryDir) {
|
|
166
|
+
throw new Error("No .agents/memory directory found");
|
|
167
|
+
}
|
|
168
|
+
const filePath = join(memoryDir, squadName, agentName, `${type}.md`);
|
|
169
|
+
const dir = dirname(filePath);
|
|
170
|
+
if (!existsSync(dir)) {
|
|
171
|
+
mkdirSync(dir, { recursive: true });
|
|
172
|
+
}
|
|
173
|
+
writeFileSync(filePath, content);
|
|
174
|
+
}
|
|
175
|
+
function appendToMemory(squadName, agentName, type, addition) {
|
|
176
|
+
const memoryDir = findMemoryDir();
|
|
177
|
+
if (!memoryDir) {
|
|
178
|
+
throw new Error("No .agents/memory directory found");
|
|
179
|
+
}
|
|
180
|
+
const filePath = join(memoryDir, squadName, agentName, `${type}.md`);
|
|
181
|
+
let existing = "";
|
|
182
|
+
if (existsSync(filePath)) {
|
|
183
|
+
existing = readFileSync(filePath, "utf-8");
|
|
184
|
+
}
|
|
185
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
186
|
+
const newContent = existing + `
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
_Added: ${timestamp}_
|
|
190
|
+
|
|
191
|
+
${addition}`;
|
|
192
|
+
updateMemory(squadName, agentName, type, newContent.trim());
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export {
|
|
196
|
+
findMemoryDir,
|
|
197
|
+
listMemoryEntries,
|
|
198
|
+
searchMemory,
|
|
199
|
+
getSquadState,
|
|
200
|
+
updateMemory,
|
|
201
|
+
appendToMemory
|
|
202
|
+
};
|
|
203
|
+
//# sourceMappingURL=chunk-FUHBEL3L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/memory.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\n\nexport interface MemoryEntry {\n squad: string;\n agent: string;\n type: 'state' | 'output' | 'learnings' | 'feedback';\n content: string;\n path: string;\n lastUpdated?: string;\n}\n\nexport interface SearchResult {\n entry: MemoryEntry;\n matches: string[];\n score: number;\n}\n\nexport function findMemoryDir(): string | null {\n let dir = process.cwd();\n\n for (let i = 0; i < 5; i++) {\n const memoryPath = join(dir, '.agents', 'memory');\n if (existsSync(memoryPath)) {\n return memoryPath;\n }\n const parent = join(dir, '..');\n if (parent === dir) break;\n dir = parent;\n }\n\n return null;\n}\n\nexport function listMemoryEntries(memoryDir: string): MemoryEntry[] {\n const entries: MemoryEntry[] = [];\n\n const squads = readdirSync(memoryDir, { withFileTypes: true })\n .filter(e => e.isDirectory())\n .map(e => e.name);\n\n for (const squad of squads) {\n const squadPath = join(memoryDir, squad);\n const agents = readdirSync(squadPath, { withFileTypes: true })\n .filter(e => e.isDirectory())\n .map(e => e.name);\n\n for (const agent of agents) {\n const agentPath = join(squadPath, agent);\n const files = readdirSync(agentPath).filter(f => f.endsWith('.md'));\n\n for (const file of files) {\n const filePath = join(agentPath, file);\n const type = file.replace('.md', '') as MemoryEntry['type'];\n\n entries.push({\n squad,\n agent,\n type,\n content: readFileSync(filePath, 'utf-8'),\n path: filePath\n });\n }\n }\n }\n\n return entries;\n}\n\n// Semantic expansions for common business terms\nconst SEMANTIC_EXPANSIONS: Record<string, string[]> = {\n 'pricing': ['price', 'cost', '$', 'revenue', 'fee', 'rate'],\n 'price': ['pricing', 'cost', '$', 'fee'],\n 'revenue': ['income', 'sales', 'mrr', 'arr', '$'],\n 'cost': ['expense', 'spend', 'budget', '$', 'price'],\n 'customer': ['client', 'lead', 'prospect', 'user'],\n 'client': ['customer', 'lead', 'prospect'],\n 'lead': ['prospect', 'customer', 'client', 'pipeline'],\n 'agent': ['squad', 'bot', 'ai'],\n 'squad': ['team', 'agent', 'group'],\n 'status': ['state', 'progress', 'health'],\n 'bug': ['issue', 'error', 'problem', 'fix'],\n 'feature': ['capability', 'function', 'ability'],\n};\n\nfunction expandQuery(query: string): string[] {\n const words = query.toLowerCase().split(/\\s+/);\n const expanded = new Set(words);\n\n for (const word of words) {\n if (SEMANTIC_EXPANSIONS[word]) {\n SEMANTIC_EXPANSIONS[word].forEach(syn => expanded.add(syn));\n }\n }\n\n return Array.from(expanded);\n}\n\nfunction getFileAge(filePath: string): number {\n try {\n const { statSync } = require('fs');\n const stats = statSync(filePath);\n const ageMs = Date.now() - stats.mtimeMs;\n const ageDays = ageMs / (1000 * 60 * 60 * 24);\n return ageDays;\n } catch {\n return 999;\n }\n}\n\nexport function searchMemory(query: string, memoryDir?: string): SearchResult[] {\n const dir = memoryDir || findMemoryDir();\n if (!dir) return [];\n\n const entries = listMemoryEntries(dir);\n const results: SearchResult[] = [];\n const queryLower = query.toLowerCase();\n const expandedTerms = expandQuery(queryLower);\n\n for (const entry of entries) {\n const contentLower = entry.content.toLowerCase();\n const lines = entry.content.split('\\n');\n const matches: string[] = [];\n let score = 0;\n let directHits = 0;\n let expandedHits = 0;\n\n // Check direct query words first\n const directWords = queryLower.split(/\\s+/);\n for (const word of directWords) {\n if (contentLower.includes(word)) {\n directHits += 1;\n score += 2; // Direct matches worth more\n }\n }\n\n // Check expanded terms\n for (const term of expandedTerms) {\n if (contentLower.includes(term)) {\n expandedHits += 1;\n score += 0.5; // Expanded matches worth less but still count\n\n // Find matching lines with context\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.toLowerCase().includes(term) && line.trim() && !matches.includes(line.trim())) {\n matches.push(line.trim());\n }\n }\n }\n }\n\n // Boost score for exact phrase match\n if (contentLower.includes(queryLower)) {\n score += 5;\n }\n\n // Recency boost - files updated recently are more relevant\n const ageDays = getFileAge(entry.path);\n if (ageDays < 1) {\n score *= 1.5; // Updated today\n } else if (ageDays < 7) {\n score *= 1.2; // Updated this week\n } else if (ageDays > 30) {\n score *= 0.8; // Stale data penalty\n }\n\n // Type weighting - balanced across types\n const typeWeights: Record<string, number> = {\n 'state': 1.2, // Current state slightly preferred\n 'learnings': 1.1, // Learnings are valuable\n 'output': 1.0, // Recent outputs\n 'feedback': 0.9, // Feedback less commonly needed\n };\n score *= typeWeights[entry.type] || 1.0;\n\n if (score > 0 && (directHits > 0 || expandedHits > 1)) {\n results.push({ entry, matches: matches.slice(0, 7), score });\n }\n }\n\n // Sort by score descending\n return results.sort((a, b) => b.score - a.score);\n}\n\nexport function getSquadState(squadName: string): MemoryEntry[] {\n const memoryDir = findMemoryDir();\n if (!memoryDir) return [];\n\n const squadPath = join(memoryDir, squadName);\n if (!existsSync(squadPath)) return [];\n\n const entries: MemoryEntry[] = [];\n const agents = readdirSync(squadPath, { withFileTypes: true })\n .filter(e => e.isDirectory())\n .map(e => e.name);\n\n for (const agent of agents) {\n const statePath = join(squadPath, agent, 'state.md');\n if (existsSync(statePath)) {\n entries.push({\n squad: squadName,\n agent,\n type: 'state',\n content: readFileSync(statePath, 'utf-8'),\n path: statePath\n });\n }\n }\n\n return entries;\n}\n\nexport function updateMemory(\n squadName: string,\n agentName: string,\n type: MemoryEntry['type'],\n content: string\n): void {\n const memoryDir = findMemoryDir();\n if (!memoryDir) {\n throw new Error('No .agents/memory directory found');\n }\n\n const filePath = join(memoryDir, squadName, agentName, `${type}.md`);\n const dir = dirname(filePath);\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n writeFileSync(filePath, content);\n}\n\nexport function appendToMemory(\n squadName: string,\n agentName: string,\n type: MemoryEntry['type'],\n addition: string\n): void {\n const memoryDir = findMemoryDir();\n if (!memoryDir) {\n throw new Error('No .agents/memory directory found');\n }\n\n const filePath = join(memoryDir, squadName, agentName, `${type}.md`);\n\n let existing = '';\n if (existsSync(filePath)) {\n existing = readFileSync(filePath, 'utf-8');\n }\n\n const timestamp = new Date().toISOString().split('T')[0];\n const newContent = existing + `\\n\\n---\\n_Added: ${timestamp}_\\n\\n${addition}`;\n\n updateMemory(squadName, agentName, type, newContent.trim());\n}\n"],"mappings":";;;;;;AAAA,SAAS,cAAc,eAAe,YAAY,aAAa,iBAAiB;AAChF,SAAS,MAAM,eAAe;AAiBvB,SAAS,gBAA+B;AAC7C,MAAI,MAAM,QAAQ,IAAI;AAEtB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,aAAa,KAAK,KAAK,WAAW,QAAQ;AAChD,QAAI,WAAW,UAAU,GAAG;AAC1B,aAAO;AAAA,IACT;AACA,UAAM,SAAS,KAAK,KAAK,IAAI;AAC7B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AAEA,SAAO;AACT;AAEO,SAAS,kBAAkB,WAAkC;AAClE,QAAM,UAAyB,CAAC;AAEhC,QAAM,SAAS,YAAY,WAAW,EAAE,eAAe,KAAK,CAAC,EAC1D,OAAO,OAAK,EAAE,YAAY,CAAC,EAC3B,IAAI,OAAK,EAAE,IAAI;AAElB,aAAW,SAAS,QAAQ;AAC1B,UAAM,YAAY,KAAK,WAAW,KAAK;AACvC,UAAM,SAAS,YAAY,WAAW,EAAE,eAAe,KAAK,CAAC,EAC1D,OAAO,OAAK,EAAE,YAAY,CAAC,EAC3B,IAAI,OAAK,EAAE,IAAI;AAElB,eAAW,SAAS,QAAQ;AAC1B,YAAM,YAAY,KAAK,WAAW,KAAK;AACvC,YAAM,QAAQ,YAAY,SAAS,EAAE,OAAO,OAAK,EAAE,SAAS,KAAK,CAAC;AAElE,iBAAW,QAAQ,OAAO;AACxB,cAAM,WAAW,KAAK,WAAW,IAAI;AACrC,cAAM,OAAO,KAAK,QAAQ,OAAO,EAAE;AAEnC,gBAAQ,KAAK;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA,SAAS,aAAa,UAAU,OAAO;AAAA,UACvC,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAGA,IAAM,sBAAgD;AAAA,EACpD,WAAW,CAAC,SAAS,QAAQ,KAAK,WAAW,OAAO,MAAM;AAAA,EAC1D,SAAS,CAAC,WAAW,QAAQ,KAAK,KAAK;AAAA,EACvC,WAAW,CAAC,UAAU,SAAS,OAAO,OAAO,GAAG;AAAA,EAChD,QAAQ,CAAC,WAAW,SAAS,UAAU,KAAK,OAAO;AAAA,EACnD,YAAY,CAAC,UAAU,QAAQ,YAAY,MAAM;AAAA,EACjD,UAAU,CAAC,YAAY,QAAQ,UAAU;AAAA,EACzC,QAAQ,CAAC,YAAY,YAAY,UAAU,UAAU;AAAA,EACrD,SAAS,CAAC,SAAS,OAAO,IAAI;AAAA,EAC9B,SAAS,CAAC,QAAQ,SAAS,OAAO;AAAA,EAClC,UAAU,CAAC,SAAS,YAAY,QAAQ;AAAA,EACxC,OAAO,CAAC,SAAS,SAAS,WAAW,KAAK;AAAA,EAC1C,WAAW,CAAC,cAAc,YAAY,SAAS;AACjD;AAEA,SAAS,YAAY,OAAyB;AAC5C,QAAM,QAAQ,MAAM,YAAY,EAAE,MAAM,KAAK;AAC7C,QAAM,WAAW,IAAI,IAAI,KAAK;AAE9B,aAAW,QAAQ,OAAO;AACxB,QAAI,oBAAoB,IAAI,GAAG;AAC7B,0BAAoB,IAAI,EAAE,QAAQ,SAAO,SAAS,IAAI,GAAG,CAAC;AAAA,IAC5D;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,QAAQ;AAC5B;AAEA,SAAS,WAAW,UAA0B;AAC5C,MAAI;AACF,UAAM,EAAE,SAAS,IAAI,UAAQ,IAAI;AACjC,UAAM,QAAQ,SAAS,QAAQ;AAC/B,UAAM,QAAQ,KAAK,IAAI,IAAI,MAAM;AACjC,UAAM,UAAU,SAAS,MAAO,KAAK,KAAK;AAC1C,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,aAAa,OAAe,WAAoC;AAC9E,QAAM,MAAM,aAAa,cAAc;AACvC,MAAI,CAAC,IAAK,QAAO,CAAC;AAElB,QAAM,UAAU,kBAAkB,GAAG;AACrC,QAAM,UAA0B,CAAC;AACjC,QAAM,aAAa,MAAM,YAAY;AACrC,QAAM,gBAAgB,YAAY,UAAU;AAE5C,aAAW,SAAS,SAAS;AAC3B,UAAM,eAAe,MAAM,QAAQ,YAAY;AAC/C,UAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI;AACtC,UAAM,UAAoB,CAAC;AAC3B,QAAI,QAAQ;AACZ,QAAI,aAAa;AACjB,QAAI,eAAe;AAGnB,UAAM,cAAc,WAAW,MAAM,KAAK;AAC1C,eAAW,QAAQ,aAAa;AAC9B,UAAI,aAAa,SAAS,IAAI,GAAG;AAC/B,sBAAc;AACd,iBAAS;AAAA,MACX;AAAA,IACF;AAGA,eAAW,QAAQ,eAAe;AAChC,UAAI,aAAa,SAAS,IAAI,GAAG;AAC/B,wBAAgB;AAChB,iBAAS;AAGT,iBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,gBAAM,OAAO,MAAM,CAAC;AACpB,cAAI,KAAK,YAAY,EAAE,SAAS,IAAI,KAAK,KAAK,KAAK,KAAK,CAAC,QAAQ,SAAS,KAAK,KAAK,CAAC,GAAG;AACtF,oBAAQ,KAAK,KAAK,KAAK,CAAC;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,aAAa,SAAS,UAAU,GAAG;AACrC,eAAS;AAAA,IACX;AAGA,UAAM,UAAU,WAAW,MAAM,IAAI;AACrC,QAAI,UAAU,GAAG;AACf,eAAS;AAAA,IACX,WAAW,UAAU,GAAG;AACtB,eAAS;AAAA,IACX,WAAW,UAAU,IAAI;AACvB,eAAS;AAAA,IACX;AAGA,UAAM,cAAsC;AAAA,MAC1C,SAAS;AAAA;AAAA,MACT,aAAa;AAAA;AAAA,MACb,UAAU;AAAA;AAAA,MACV,YAAY;AAAA;AAAA,IACd;AACA,aAAS,YAAY,MAAM,IAAI,KAAK;AAEpC,QAAI,QAAQ,MAAM,aAAa,KAAK,eAAe,IAAI;AACrD,cAAQ,KAAK,EAAE,OAAO,SAAS,QAAQ,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC;AAAA,IAC7D;AAAA,EACF;AAGA,SAAO,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACjD;AAEO,SAAS,cAAc,WAAkC;AAC9D,QAAM,YAAY,cAAc;AAChC,MAAI,CAAC,UAAW,QAAO,CAAC;AAExB,QAAM,YAAY,KAAK,WAAW,SAAS;AAC3C,MAAI,CAAC,WAAW,SAAS,EAAG,QAAO,CAAC;AAEpC,QAAM,UAAyB,CAAC;AAChC,QAAM,SAAS,YAAY,WAAW,EAAE,eAAe,KAAK,CAAC,EAC1D,OAAO,OAAK,EAAE,YAAY,CAAC,EAC3B,IAAI,OAAK,EAAE,IAAI;AAElB,aAAW,SAAS,QAAQ;AAC1B,UAAM,YAAY,KAAK,WAAW,OAAO,UAAU;AACnD,QAAI,WAAW,SAAS,GAAG;AACzB,cAAQ,KAAK;AAAA,QACX,OAAO;AAAA,QACP;AAAA,QACA,MAAM;AAAA,QACN,SAAS,aAAa,WAAW,OAAO;AAAA,QACxC,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,aACd,WACA,WACA,MACA,SACM;AACN,QAAM,YAAY,cAAc;AAChC,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,QAAM,WAAW,KAAK,WAAW,WAAW,WAAW,GAAG,IAAI,KAAK;AACnE,QAAM,MAAM,QAAQ,QAAQ;AAE5B,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,EACpC;AAEA,gBAAc,UAAU,OAAO;AACjC;AAEO,SAAS,eACd,WACA,WACA,MACA,UACM;AACN,QAAM,YAAY,cAAc;AAChC,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,QAAM,WAAW,KAAK,WAAW,WAAW,WAAW,GAAG,IAAI,KAAK;AAEnE,MAAI,WAAW;AACf,MAAI,WAAW,QAAQ,GAAG;AACxB,eAAW,aAAa,UAAU,OAAO;AAAA,EAC3C;AAEA,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AACvD,QAAM,aAAa,WAAW;AAAA;AAAA;AAAA,UAAoB,SAAS;AAAA;AAAA,EAAQ,QAAQ;AAE3E,eAAa,WAAW,WAAW,MAAM,WAAW,KAAK,CAAC;AAC5D;","names":[]}
|