@quarri/claude-data-tools 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.
- package/.claude-plugin/plugin.json +19 -0
- package/README.md +165 -0
- package/dist/api/client.d.ts +103 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +166 -0
- package/dist/api/client.js.map +1 -0
- package/dist/auth/cli-auth.d.ts +15 -0
- package/dist/auth/cli-auth.d.ts.map +1 -0
- package/dist/auth/cli-auth.js +170 -0
- package/dist/auth/cli-auth.js.map +1 -0
- package/dist/auth/token-store.d.ts +45 -0
- package/dist/auth/token-store.d.ts.map +1 -0
- package/dist/auth/token-store.js +154 -0
- package/dist/auth/token-store.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +157 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/definitions.d.ts +34 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +968 -0
- package/dist/tools/definitions.js.map +1 -0
- package/package.json +52 -0
- package/skills/quarri-guide/SKILL.md +102 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token storage for Quarri CLI credentials
|
|
3
|
+
* Stores tokens in ~/.quarri/credentials with secure permissions
|
|
4
|
+
*/
|
|
5
|
+
export interface StoredCredentials {
|
|
6
|
+
token: string;
|
|
7
|
+
email: string;
|
|
8
|
+
role: string;
|
|
9
|
+
databases: Array<{
|
|
10
|
+
database_name: string;
|
|
11
|
+
display_name: string;
|
|
12
|
+
access_level: string;
|
|
13
|
+
}>;
|
|
14
|
+
selectedDatabase?: string;
|
|
15
|
+
expiresAt: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Load stored credentials from disk
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadCredentials(): StoredCredentials | null;
|
|
21
|
+
/**
|
|
22
|
+
* Save credentials to disk with secure permissions
|
|
23
|
+
*/
|
|
24
|
+
export declare function saveCredentials(credentials: StoredCredentials): void;
|
|
25
|
+
/**
|
|
26
|
+
* Clear stored credentials
|
|
27
|
+
*/
|
|
28
|
+
export declare function clearCredentials(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get the currently selected database
|
|
31
|
+
*/
|
|
32
|
+
export declare function getSelectedDatabase(): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Set the selected database
|
|
35
|
+
*/
|
|
36
|
+
export declare function setSelectedDatabase(databaseName: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Get the stored API token
|
|
39
|
+
*/
|
|
40
|
+
export declare function getToken(): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Check if user is authenticated
|
|
43
|
+
*/
|
|
44
|
+
export declare function isAuthenticated(): boolean;
|
|
45
|
+
//# sourceMappingURL=token-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/auth/token-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,KAAK,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAcD;;GAEG;AACH,wBAAgB,eAAe,IAAI,iBAAiB,GAAG,IAAI,CAwB1D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAKpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAQvC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAgBnD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAkBjE;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CAGxC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Token storage for Quarri CLI credentials
|
|
4
|
+
* Stores tokens in ~/.quarri/credentials with secure permissions
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.loadCredentials = loadCredentials;
|
|
41
|
+
exports.saveCredentials = saveCredentials;
|
|
42
|
+
exports.clearCredentials = clearCredentials;
|
|
43
|
+
exports.getSelectedDatabase = getSelectedDatabase;
|
|
44
|
+
exports.setSelectedDatabase = setSelectedDatabase;
|
|
45
|
+
exports.getToken = getToken;
|
|
46
|
+
exports.isAuthenticated = isAuthenticated;
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const os = __importStar(require("os"));
|
|
50
|
+
const QUARRI_DIR = path.join(os.homedir(), '.quarri');
|
|
51
|
+
const CREDENTIALS_FILE = path.join(QUARRI_DIR, 'credentials');
|
|
52
|
+
/**
|
|
53
|
+
* Ensure the ~/.quarri directory exists with secure permissions
|
|
54
|
+
*/
|
|
55
|
+
function ensureQuarriDir() {
|
|
56
|
+
if (!fs.existsSync(QUARRI_DIR)) {
|
|
57
|
+
fs.mkdirSync(QUARRI_DIR, { mode: 0o700 });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Load stored credentials from disk
|
|
62
|
+
*/
|
|
63
|
+
function loadCredentials() {
|
|
64
|
+
try {
|
|
65
|
+
if (!fs.existsSync(CREDENTIALS_FILE)) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const content = fs.readFileSync(CREDENTIALS_FILE, 'utf-8');
|
|
69
|
+
const credentials = JSON.parse(content);
|
|
70
|
+
// Check if token is expired
|
|
71
|
+
if (credentials.expiresAt) {
|
|
72
|
+
const expiresAt = new Date(credentials.expiresAt);
|
|
73
|
+
if (expiresAt < new Date()) {
|
|
74
|
+
// Token expired, remove credentials
|
|
75
|
+
clearCredentials();
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return credentials;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
console.error('Failed to load credentials:', error);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Save credentials to disk with secure permissions
|
|
88
|
+
*/
|
|
89
|
+
function saveCredentials(credentials) {
|
|
90
|
+
ensureQuarriDir();
|
|
91
|
+
const content = JSON.stringify(credentials, null, 2);
|
|
92
|
+
fs.writeFileSync(CREDENTIALS_FILE, content, { mode: 0o600 });
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Clear stored credentials
|
|
96
|
+
*/
|
|
97
|
+
function clearCredentials() {
|
|
98
|
+
try {
|
|
99
|
+
if (fs.existsSync(CREDENTIALS_FILE)) {
|
|
100
|
+
fs.unlinkSync(CREDENTIALS_FILE);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error('Failed to clear credentials:', error);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the currently selected database
|
|
109
|
+
*/
|
|
110
|
+
function getSelectedDatabase() {
|
|
111
|
+
const credentials = loadCredentials();
|
|
112
|
+
if (!credentials) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
// Return selected database or first available database
|
|
116
|
+
if (credentials.selectedDatabase) {
|
|
117
|
+
return credentials.selectedDatabase;
|
|
118
|
+
}
|
|
119
|
+
if (credentials.databases && credentials.databases.length > 0) {
|
|
120
|
+
return credentials.databases[0].database_name;
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Set the selected database
|
|
126
|
+
*/
|
|
127
|
+
function setSelectedDatabase(databaseName) {
|
|
128
|
+
const credentials = loadCredentials();
|
|
129
|
+
if (!credentials) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
// Verify database is in user's list
|
|
133
|
+
const hasAccess = credentials.databases.some((db) => db.database_name === databaseName);
|
|
134
|
+
if (!hasAccess && credentials.role !== 'super_admin') {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
credentials.selectedDatabase = databaseName;
|
|
138
|
+
saveCredentials(credentials);
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get the stored API token
|
|
143
|
+
*/
|
|
144
|
+
function getToken() {
|
|
145
|
+
const credentials = loadCredentials();
|
|
146
|
+
return credentials?.token ?? null;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if user is authenticated
|
|
150
|
+
*/
|
|
151
|
+
function isAuthenticated() {
|
|
152
|
+
return loadCredentials() !== null;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=token-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.js","sourceRoot":"","sources":["../../src/auth/token-store.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Quarri MCP Server
|
|
5
|
+
*
|
|
6
|
+
* Model Context Protocol server for the Quarri Data Assistant.
|
|
7
|
+
* Provides 47 tools for natural language data analysis.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
11
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
12
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
13
|
+
const client_js_1 = require("./api/client.js");
|
|
14
|
+
const token_store_js_1 = require("./auth/token-store.js");
|
|
15
|
+
const cli_auth_js_1 = require("./auth/cli-auth.js");
|
|
16
|
+
const definitions_js_1 = require("./tools/definitions.js");
|
|
17
|
+
// Initialize API client
|
|
18
|
+
const client = new client_js_1.QuarriApiClient();
|
|
19
|
+
// Initialize MCP server
|
|
20
|
+
const server = new index_js_1.Server({
|
|
21
|
+
name: 'quarri',
|
|
22
|
+
version: '1.0.0',
|
|
23
|
+
}, {
|
|
24
|
+
capabilities: {
|
|
25
|
+
tools: {},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Ensure user is authenticated before tool execution
|
|
30
|
+
*/
|
|
31
|
+
async function ensureAuthenticated() {
|
|
32
|
+
const credentials = (0, token_store_js_1.loadCredentials)();
|
|
33
|
+
if (credentials) {
|
|
34
|
+
client.setToken(credentials.token);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
// Run interactive auth flow
|
|
38
|
+
const result = await (0, cli_auth_js_1.runAuthFlow)(client);
|
|
39
|
+
if (result) {
|
|
40
|
+
client.setToken(result.token);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Handle list tools request
|
|
47
|
+
*/
|
|
48
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
49
|
+
return {
|
|
50
|
+
tools: definitions_js_1.TOOL_DEFINITIONS.map((tool) => ({
|
|
51
|
+
name: tool.name,
|
|
52
|
+
description: tool.description,
|
|
53
|
+
inputSchema: tool.inputSchema,
|
|
54
|
+
})),
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* Handle tool execution request
|
|
59
|
+
*/
|
|
60
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
61
|
+
const { name, arguments: args } = request.params;
|
|
62
|
+
// Ensure authenticated
|
|
63
|
+
const authenticated = await ensureAuthenticated();
|
|
64
|
+
if (!authenticated) {
|
|
65
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidRequest, 'Authentication required. Please run the auth flow.');
|
|
66
|
+
}
|
|
67
|
+
// Handle special session management tools
|
|
68
|
+
if (name === 'quarri_list_databases') {
|
|
69
|
+
const credentials = (0, token_store_js_1.loadCredentials)();
|
|
70
|
+
if (!credentials) {
|
|
71
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidRequest, 'Not authenticated');
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
content: [
|
|
75
|
+
{
|
|
76
|
+
type: 'text',
|
|
77
|
+
text: JSON.stringify({
|
|
78
|
+
success: true,
|
|
79
|
+
databases: credentials.databases,
|
|
80
|
+
selected: (0, token_store_js_1.getSelectedDatabase)(),
|
|
81
|
+
}, null, 2),
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (name === 'quarri_select_database') {
|
|
87
|
+
const databaseName = args.database_name;
|
|
88
|
+
const success = (0, token_store_js_1.setSelectedDatabase)(databaseName);
|
|
89
|
+
if (!success) {
|
|
90
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidRequest, `Database '${databaseName}' not found or access denied`);
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
content: [
|
|
94
|
+
{
|
|
95
|
+
type: 'text',
|
|
96
|
+
text: JSON.stringify({
|
|
97
|
+
success: true,
|
|
98
|
+
message: `Selected database: ${databaseName}`,
|
|
99
|
+
}, null, 2),
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Map MCP tool name to backend tool name
|
|
105
|
+
const backendToolName = (0, definitions_js_1.getBackendToolName)(name);
|
|
106
|
+
if (!backendToolName) {
|
|
107
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
108
|
+
}
|
|
109
|
+
// Get selected database
|
|
110
|
+
const databaseName = (0, token_store_js_1.getSelectedDatabase)();
|
|
111
|
+
// Execute tool via API
|
|
112
|
+
const result = await client.executeTool(backendToolName, args, databaseName ?? undefined);
|
|
113
|
+
// Format response
|
|
114
|
+
if (!result.success) {
|
|
115
|
+
return {
|
|
116
|
+
content: [
|
|
117
|
+
{
|
|
118
|
+
type: 'text',
|
|
119
|
+
text: JSON.stringify({
|
|
120
|
+
success: false,
|
|
121
|
+
error: result.error,
|
|
122
|
+
}, null, 2),
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
isError: true,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
content: [
|
|
130
|
+
{
|
|
131
|
+
type: 'text',
|
|
132
|
+
text: JSON.stringify(result, null, 2),
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
/**
|
|
138
|
+
* Main entry point
|
|
139
|
+
*/
|
|
140
|
+
async function main() {
|
|
141
|
+
// Check for initial health check
|
|
142
|
+
const health = await client.healthCheck();
|
|
143
|
+
if (!health.success) {
|
|
144
|
+
console.error('Warning: Could not connect to Quarri API');
|
|
145
|
+
}
|
|
146
|
+
// Create transport
|
|
147
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
148
|
+
// Connect server to transport
|
|
149
|
+
await server.connect(transport);
|
|
150
|
+
console.error('Quarri MCP server started');
|
|
151
|
+
}
|
|
152
|
+
// Run the server
|
|
153
|
+
main().catch((error) => {
|
|
154
|
+
console.error('Failed to start server:', error);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quarri Tool Definitions for MCP Server
|
|
3
|
+
* All tools are prefixed with 'quarri_' to avoid conflicts with other MCP servers
|
|
4
|
+
*/
|
|
5
|
+
export interface ToolParameter {
|
|
6
|
+
type: string;
|
|
7
|
+
description: string;
|
|
8
|
+
enum?: string[];
|
|
9
|
+
items?: {
|
|
10
|
+
type: string;
|
|
11
|
+
};
|
|
12
|
+
default?: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface ToolDefinition {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
category: string;
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: 'object';
|
|
20
|
+
properties: Record<string, ToolParameter>;
|
|
21
|
+
required: string[];
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare const TOOL_NAME_MAP: Record<string, string>;
|
|
25
|
+
export declare const TOOL_DEFINITIONS: ToolDefinition[];
|
|
26
|
+
/**
|
|
27
|
+
* Get backend tool name from MCP tool name
|
|
28
|
+
*/
|
|
29
|
+
export declare function getBackendToolName(mcpToolName: string): string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Get tool definition by name
|
|
32
|
+
*/
|
|
33
|
+
export declare function getToolDefinition(name: string): ToolDefinition | undefined;
|
|
34
|
+
//# sourceMappingURL=definitions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAC1C,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;CACH;AAGD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsDhD,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,cAAc,EA04B5C,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAErE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE1E"}
|