@andrewkimjoseph/celina 0.3.6 → 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 +4 -4
- package/build/clients/celo-client.d.ts +0 -1
- package/build/clients/celo-client.js +0 -19
- package/build/clients/celo-client.js.map +1 -1
- package/build/config/aave.d.ts +8 -2
- package/build/config/aave.js +51 -2
- package/build/config/aave.js.map +1 -1
- package/build/config/chains.js +7 -0
- package/build/config/chains.js.map +1 -1
- package/build/server/instructions.js +3 -3
- package/build/services/aave.service.d.ts +6 -6
- package/build/services/aave.service.js +38 -38
- package/build/services/aave.service.js.map +1 -1
- package/build/services/mento-fx.service.d.ts +1 -2
- package/build/services/mento-fx.service.js +3 -8
- package/build/services/mento-fx.service.js.map +1 -1
- package/build/services/self.service.d.ts +5 -8
- package/build/services/self.service.js +10 -14
- package/build/services/self.service.js.map +1 -1
- package/build/services/transaction.service.d.ts +3 -3
- package/build/services/transaction.service.js +5 -10
- package/build/services/transaction.service.js.map +1 -1
- package/build/tools/aave.tools.js +18 -19
- package/build/tools/aave.tools.js.map +1 -1
- package/build/tools/mento-fx.tools.js +2 -9
- package/build/tools/mento-fx.tools.js.map +1 -1
- package/build/tools/self.tools.js +11 -25
- package/build/tools/self.tools.js.map +1 -1
- package/build/tools/transaction.tools.js +4 -10
- package/build/tools/transaction.tools.js.map +1 -1
- package/package.json +2 -7
- package/build/crypto/wallet-key-crypto.d.ts +0 -11
- package/build/crypto/wallet-key-crypto.js +0 -57
- package/build/crypto/wallet-key-crypto.js.map +0 -1
- package/build/http.d.ts +0 -2
- package/build/http.js +0 -15
- package/build/http.js.map +0 -1
- package/build/server/create-http-app.d.ts +0 -1
- package/build/server/create-http-app.js +0 -147
- package/build/server/create-http-app.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrewkimjoseph/celina",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Celina — MCP server for Celo mainnet. Balances, transfers, Self Agent ID, and chain reads for LLM agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -22,11 +22,9 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "rm -rf build && tsc",
|
|
24
24
|
"start": "node build/index.js",
|
|
25
|
-
"start:http": "node build/http.js",
|
|
26
25
|
"dev": "tsc --watch",
|
|
27
26
|
"prepare": "npm run build",
|
|
28
|
-
"inspect": "npx @modelcontextprotocol/inspector node build/index.js"
|
|
29
|
-
"encrypt-key": "tsx scripts/encrypt-key.ts"
|
|
27
|
+
"inspect": "npx @modelcontextprotocol/inspector node build/index.js"
|
|
30
28
|
},
|
|
31
29
|
"engines": {
|
|
32
30
|
"node": ">=20.0.0"
|
|
@@ -47,14 +45,11 @@
|
|
|
47
45
|
"@modelcontextprotocol/sdk": "^1.22.0",
|
|
48
46
|
"@noble/ed25519": "^3.1.0",
|
|
49
47
|
"dotenv": "^17.4.2",
|
|
50
|
-
"express": "^5.2.1",
|
|
51
48
|
"viem": "^2.39.3",
|
|
52
49
|
"zod": "^3.24.3"
|
|
53
50
|
},
|
|
54
51
|
"devDependencies": {
|
|
55
|
-
"@types/express": "^5.0.6",
|
|
56
52
|
"@types/node": "^22.0.0",
|
|
57
|
-
"tsx": "^4.22.3",
|
|
58
53
|
"typescript": "^5.8.2"
|
|
59
54
|
}
|
|
60
55
|
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare function isWalletEncryptionConfigured(): boolean;
|
|
2
|
-
export declare function getPublicKeyPem(): string;
|
|
3
|
-
export declare function getEncryptionInfo(): {
|
|
4
|
-
algorithm: string;
|
|
5
|
-
hash: string;
|
|
6
|
-
encoding: string;
|
|
7
|
-
publicKey: string;
|
|
8
|
-
instructions: string;
|
|
9
|
-
};
|
|
10
|
-
export declare function encryptPrivateKey(publicKeyPem: string, privateKey: string): string;
|
|
11
|
-
export declare function decryptPrivateKey(encryptedBase64: string): `0x${string}`;
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { createPrivateKey, createPublicKey, privateDecrypt, publicEncrypt, } from "node:crypto";
|
|
2
|
-
const RSA_OAEP = {
|
|
3
|
-
oaepHash: "sha256",
|
|
4
|
-
padding: 4, // RSA_PKCS1_OAEP_PADDING
|
|
5
|
-
};
|
|
6
|
-
const PRIVATE_KEY_PATTERN = /^0x[0-9a-fA-F]{64}$/;
|
|
7
|
-
let cachedPrivateKey;
|
|
8
|
-
function loadPrivateKey() {
|
|
9
|
-
if (cachedPrivateKey) {
|
|
10
|
-
return cachedPrivateKey;
|
|
11
|
-
}
|
|
12
|
-
const pem = process.env.WALLET_ENCRYPTION_PRIVATE_KEY;
|
|
13
|
-
if (!pem) {
|
|
14
|
-
throw new Error("Wallet encryption is not configured. Set WALLET_ENCRYPTION_PRIVATE_KEY.");
|
|
15
|
-
}
|
|
16
|
-
cachedPrivateKey = createPrivateKey(pem);
|
|
17
|
-
return cachedPrivateKey;
|
|
18
|
-
}
|
|
19
|
-
export function isWalletEncryptionConfigured() {
|
|
20
|
-
return Boolean(process.env.WALLET_ENCRYPTION_PRIVATE_KEY);
|
|
21
|
-
}
|
|
22
|
-
export function getPublicKeyPem() {
|
|
23
|
-
const privateKey = loadPrivateKey();
|
|
24
|
-
return createPublicKey(privateKey).export({ type: "spki", format: "pem" });
|
|
25
|
-
}
|
|
26
|
-
export function getEncryptionInfo() {
|
|
27
|
-
return {
|
|
28
|
-
algorithm: "RSA-OAEP",
|
|
29
|
-
hash: "sha256",
|
|
30
|
-
encoding: "base64",
|
|
31
|
-
publicKey: getPublicKeyPem(),
|
|
32
|
-
instructions: "Encrypt your 0x-prefixed private key locally with this public key, then pass the base64 ciphertext as encryptedPrivateKey.",
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
export function encryptPrivateKey(publicKeyPem, privateKey) {
|
|
36
|
-
if (!PRIVATE_KEY_PATTERN.test(privateKey)) {
|
|
37
|
-
throw new Error("Invalid private key format. Expected 0x followed by 64 hex chars.");
|
|
38
|
-
}
|
|
39
|
-
const encrypted = publicEncrypt({ key: publicKeyPem, ...RSA_OAEP }, Buffer.from(privateKey, "utf8"));
|
|
40
|
-
return encrypted.toString("base64");
|
|
41
|
-
}
|
|
42
|
-
export function decryptPrivateKey(encryptedBase64) {
|
|
43
|
-
const privateKey = loadPrivateKey();
|
|
44
|
-
let decrypted;
|
|
45
|
-
try {
|
|
46
|
-
decrypted = privateDecrypt({ key: privateKey, ...RSA_OAEP }, Buffer.from(encryptedBase64, "base64"));
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
throw new Error("Failed to decrypt private key. Ensure it was encrypted with this server's public key.");
|
|
50
|
-
}
|
|
51
|
-
const value = decrypted.toString("utf8");
|
|
52
|
-
if (!PRIVATE_KEY_PATTERN.test(value)) {
|
|
53
|
-
throw new Error("Decrypted value is not a valid private key.");
|
|
54
|
-
}
|
|
55
|
-
return value;
|
|
56
|
-
}
|
|
57
|
-
//# sourceMappingURL=wallet-key-crypto.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wallet-key-crypto.js","sourceRoot":"","sources":["../../src/crypto/wallet-key-crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,GAEd,MAAM,aAAa,CAAC;AAErB,MAAM,QAAQ,GAAG;IACf,QAAQ,EAAE,QAAiB;IAC3B,OAAO,EAAE,CAAC,EAAE,yBAAyB;CACtC,CAAC;AAEF,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAElD,IAAI,gBAAuC,CAAC;AAE5C,SAAS,cAAc;IACrB,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;IACtD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IAED,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACzC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,OAAO,eAAe,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAW,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO;QACL,SAAS,EAAE,UAAU;QACrB,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,QAAQ;QAClB,SAAS,EAAE,eAAe,EAAE;QAC5B,YAAY,EACV,4HAA4H;KAC/H,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,YAAoB,EACpB,UAAkB;IAElB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,SAAS,GAAG,aAAa,CAC7B,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,QAAQ,EAAE,EAClC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAChC,CAAC;IAEF,OAAO,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,eAAuB;IACvD,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,IAAI,SAAiB,CAAC;IAEtB,IAAI,CAAC;QACH,SAAS,GAAG,cAAc,CACxB,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,QAAQ,EAAE,EAChC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,CACvC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,uFAAuF,CACxF,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,KAAsB,CAAC;AAChC,CAAC"}
|
package/build/http.d.ts
DELETED
package/build/http.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import "./config/load-env.js";
|
|
3
|
-
import { app } from "./server/create-http-app.js";
|
|
4
|
-
const PORT = parseInt(process.env.PORT || "10000", 10);
|
|
5
|
-
if (!process.env.WALLET_ENCRYPTION_PRIVATE_KEY) {
|
|
6
|
-
console.warn("WARNING: WALLET_ENCRYPTION_PRIVATE_KEY is not set. Write tools requiring encryptedPrivateKey will fail.");
|
|
7
|
-
}
|
|
8
|
-
app.listen(PORT, "0.0.0.0", () => {
|
|
9
|
-
console.log(`Celina HTTP server listening on port ${PORT}`);
|
|
10
|
-
});
|
|
11
|
-
process.on("SIGINT", () => {
|
|
12
|
-
console.log("Shutting down server...");
|
|
13
|
-
process.exit(0);
|
|
14
|
-
});
|
|
15
|
-
//# sourceMappingURL=http.js.map
|
package/build/http.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":";AACA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,MAAM,6BAA6B,CAAC;AAElD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,EAAE,CAAC,CAAC;AAEvD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,CAAC;IAC/C,OAAO,CAAC,IAAI,CACV,yGAAyG,CAC1G,CAAC;AACJ,CAAC;AAED,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE;IAC/B,OAAO,CAAC,GAAG,CAAC,wCAAwC,IAAI,EAAE,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const app: import("express").Express;
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
3
|
-
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
|
|
4
|
-
import { getEncryptionInfo, isWalletEncryptionConfigured, } from "../crypto/wallet-key-crypto.js";
|
|
5
|
-
import { createServer } from "./create-server.js";
|
|
6
|
-
function getAllowedHosts() {
|
|
7
|
-
const hosts = new Set();
|
|
8
|
-
if (process.env.RENDER_EXTERNAL_HOSTNAME) {
|
|
9
|
-
hosts.add(process.env.RENDER_EXTERNAL_HOSTNAME);
|
|
10
|
-
}
|
|
11
|
-
const extra = process.env.ALLOWED_HOSTS;
|
|
12
|
-
if (extra) {
|
|
13
|
-
for (const host of extra.split(",")) {
|
|
14
|
-
const trimmed = host.trim();
|
|
15
|
-
if (trimmed) {
|
|
16
|
-
hosts.add(trimmed);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return hosts.size > 0 ? [...hosts] : undefined;
|
|
21
|
-
}
|
|
22
|
-
export const app = createMcpExpressApp({
|
|
23
|
-
host: "0.0.0.0",
|
|
24
|
-
allowedHosts: getAllowedHosts(),
|
|
25
|
-
});
|
|
26
|
-
const transports = new Map();
|
|
27
|
-
function isInitializeRequest(body) {
|
|
28
|
-
if (Array.isArray(body)) {
|
|
29
|
-
return body.some(isInitializeRequest);
|
|
30
|
-
}
|
|
31
|
-
if (!body || typeof body !== "object") {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
return body.method === "initialize";
|
|
35
|
-
}
|
|
36
|
-
app.get("/health", (_req, res) => {
|
|
37
|
-
res.json({ status: "ok" });
|
|
38
|
-
});
|
|
39
|
-
app.get("/public-key", (_req, res) => {
|
|
40
|
-
if (!isWalletEncryptionConfigured()) {
|
|
41
|
-
res.status(503).json({
|
|
42
|
-
error: "Wallet encryption is not configured on this server.",
|
|
43
|
-
});
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
const { publicKey, algorithm, hash, encoding } = getEncryptionInfo();
|
|
47
|
-
res.json({ publicKey, algorithm, hash, encoding });
|
|
48
|
-
});
|
|
49
|
-
app.post("/mcp", async (req, res) => {
|
|
50
|
-
const sessionId = req.headers["mcp-session-id"];
|
|
51
|
-
try {
|
|
52
|
-
let transport;
|
|
53
|
-
if (sessionId && transports.has(sessionId)) {
|
|
54
|
-
transport = transports.get(sessionId);
|
|
55
|
-
}
|
|
56
|
-
else if (!sessionId && isInitializeRequest(req.body)) {
|
|
57
|
-
transport = new StreamableHTTPServerTransport({
|
|
58
|
-
sessionIdGenerator: () => randomUUID(),
|
|
59
|
-
onsessioninitialized: (id) => {
|
|
60
|
-
if (transport) {
|
|
61
|
-
transports.set(id, transport);
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
transport.onclose = () => {
|
|
66
|
-
const id = transport?.sessionId;
|
|
67
|
-
if (id) {
|
|
68
|
-
transports.delete(id);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
const server = createServer();
|
|
72
|
-
await server.connect(transport);
|
|
73
|
-
await transport.handleRequest(req, res, req.body);
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
else if (sessionId) {
|
|
77
|
-
res.status(404).json({
|
|
78
|
-
jsonrpc: "2.0",
|
|
79
|
-
error: { code: -32001, message: "Session not found" },
|
|
80
|
-
id: null,
|
|
81
|
-
});
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
res.status(400).json({
|
|
86
|
-
jsonrpc: "2.0",
|
|
87
|
-
error: { code: -32000, message: "Bad Request: Session ID required" },
|
|
88
|
-
id: null,
|
|
89
|
-
});
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
await transport.handleRequest(req, res, req.body);
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
console.error("Error handling MCP request:", error);
|
|
96
|
-
if (!res.headersSent) {
|
|
97
|
-
res.status(500).json({
|
|
98
|
-
jsonrpc: "2.0",
|
|
99
|
-
error: { code: -32603, message: "Internal server error" },
|
|
100
|
-
id: null,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
app.get("/mcp", async (req, res) => {
|
|
106
|
-
const sessionId = req.headers["mcp-session-id"];
|
|
107
|
-
if (!sessionId) {
|
|
108
|
-
res.status(400).send("Missing session ID");
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
const transport = transports.get(sessionId);
|
|
112
|
-
if (!transport) {
|
|
113
|
-
res.status(404).send("Session not found");
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
try {
|
|
117
|
-
await transport.handleRequest(req, res);
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
console.error("Error handling MCP SSE request:", error);
|
|
121
|
-
if (!res.headersSent) {
|
|
122
|
-
res.status(500).send("Error processing SSE stream");
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
app.delete("/mcp", async (req, res) => {
|
|
127
|
-
const sessionId = req.headers["mcp-session-id"];
|
|
128
|
-
if (!sessionId) {
|
|
129
|
-
res.status(400).send("Missing session ID");
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
const transport = transports.get(sessionId);
|
|
133
|
-
if (!transport) {
|
|
134
|
-
res.status(404).send("Session not found");
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
try {
|
|
138
|
-
await transport.handleRequest(req, res);
|
|
139
|
-
}
|
|
140
|
-
catch (error) {
|
|
141
|
-
console.error("Error handling MCP session termination:", error);
|
|
142
|
-
if (!res.headersSent) {
|
|
143
|
-
res.status(500).send("Error processing session termination");
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
//# sourceMappingURL=create-http-app.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-http-app.js","sourceRoot":"","sources":["../../src/server/create-http-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAElF,OAAO,EACL,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,SAAS,eAAe;IACtB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAEhC,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;QACzC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IACxC,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,OAAO,EAAE,CAAC;gBACZ,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,mBAAmB,CAAC;IACrC,IAAI,EAAE,SAAS;IACf,YAAY,EAAE,eAAe,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,IAAI,GAAG,EAAyC,CAAC;AAEpE,SAAS,mBAAmB,CAAC,IAAa;IACxC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAQ,IAA4B,CAAC,MAAM,KAAK,YAAY,CAAC;AAC/D,CAAC;AAED,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;IAClD,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;IACtD,IAAI,CAAC,4BAA4B,EAAE,EAAE,CAAC;QACpC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,qDAAqD;SAC7D,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,iBAAiB,EAAE,CAAC;IACrE,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IACrD,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;IAEtE,IAAI,CAAC;QACH,IAAI,SAAoD,CAAC;QAEzD,IAAI,SAAS,IAAI,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3C,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxC,CAAC;aAAM,IAAI,CAAC,SAAS,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,SAAS,GAAG,IAAI,6BAA6B,CAAC;gBAC5C,kBAAkB,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;gBACtC,oBAAoB,EAAE,CAAC,EAAE,EAAE,EAAE;oBAC3B,IAAI,SAAS,EAAE,CAAC;wBACd,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;oBAChC,CAAC;gBACH,CAAC;aACF,CAAC,CAAC;YAEH,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;gBACvB,MAAM,EAAE,GAAG,SAAS,EAAE,SAAS,CAAC;gBAChC,IAAI,EAAE,EAAE,CAAC;oBACP,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;YAC9B,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAChC,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YAClD,OAAO;QACT,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE;gBACrD,EAAE,EAAE,IAAI;aACT,CAAC,CAAC;YACH,OAAO;QACT,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,kCAAkC,EAAE;gBACpE,EAAE,EAAE,IAAI;aACT,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,SAAU,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACpD,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,uBAAuB,EAAE;gBACzD,EAAE,EAAE,IAAI;aACT,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IACpD,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;IACtE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IACvD,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;IACtE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;QAChE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC"}
|