@exaudeus/workrail 0.0.12 → 0.0.13
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/dist/infrastructure/storage/git-workflow-storage.d.ts +65 -0
- package/dist/infrastructure/storage/git-workflow-storage.d.ts.map +1 -0
- package/dist/infrastructure/storage/git-workflow-storage.js +284 -0
- package/dist/infrastructure/storage/git-workflow-storage.js.map +1 -0
- package/dist/infrastructure/storage/plugin-workflow-storage.d.ts +102 -0
- package/dist/infrastructure/storage/plugin-workflow-storage.d.ts.map +1 -0
- package/dist/infrastructure/storage/plugin-workflow-storage.js +319 -0
- package/dist/infrastructure/storage/plugin-workflow-storage.js.map +1 -0
- package/dist/infrastructure/storage/remote-workflow-storage.d.ts +44 -0
- package/dist/infrastructure/storage/remote-workflow-storage.d.ts.map +1 -0
- package/dist/infrastructure/storage/remote-workflow-storage.js +321 -0
- package/dist/infrastructure/storage/remote-workflow-storage.js.map +1 -0
- package/dist/tools/mcp_initialize.js +1 -1
- package/dist/utils/storage-security.d.ts +74 -0
- package/dist/utils/storage-security.d.ts.map +1 -0
- package/dist/utils/storage-security.js +134 -0
- package/dist/utils/storage-security.js.map +1 -0
- package/package.json +1 -1
- package/workflows/coding-task-workflow.json +59 -15
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PLUGIN_WORKFLOW_CONFIGS = exports.PluginWorkflowStorage = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
6
|
+
const promises_1 = tslib_1.__importDefault(require("fs/promises"));
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const storage_security_1 = require("../../utils/storage-security");
|
|
9
|
+
const error_handler_1 = require("../../core/error-handler");
|
|
10
|
+
/**
|
|
11
|
+
* Plugin-based workflow storage that loads workflows from npm packages
|
|
12
|
+
* Workflows are distributed as npm packages with a specific structure
|
|
13
|
+
*
|
|
14
|
+
* Security features:
|
|
15
|
+
* - Path traversal prevention
|
|
16
|
+
* - File size limits
|
|
17
|
+
* - Plugin count limits
|
|
18
|
+
* - Safe package.json parsing
|
|
19
|
+
*
|
|
20
|
+
* Example package structure:
|
|
21
|
+
* ```
|
|
22
|
+
* my-workflow-pack/
|
|
23
|
+
* ├── package.json
|
|
24
|
+
* ├── index.js
|
|
25
|
+
* └── workflows/
|
|
26
|
+
* ├── my-workflow-1.json
|
|
27
|
+
* └── my-workflow-2.json
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
class PluginWorkflowStorage {
|
|
31
|
+
config;
|
|
32
|
+
pluginCache = new Map();
|
|
33
|
+
lastScan = 0;
|
|
34
|
+
constructor(config = {}) {
|
|
35
|
+
this.config = this.validateAndNormalizeConfig(config);
|
|
36
|
+
}
|
|
37
|
+
validateAndNormalizeConfig(config) {
|
|
38
|
+
const securityOptions = (0, storage_security_1.validateSecurityOptions)({
|
|
39
|
+
maxFileSizeBytes: config.maxFileSize || 1024 * 1024 // 1MB default
|
|
40
|
+
});
|
|
41
|
+
const pluginPaths = (config.pluginPaths && config.pluginPaths.length > 0)
|
|
42
|
+
? config.pluginPaths
|
|
43
|
+
: this.getDefaultPluginPaths();
|
|
44
|
+
// Validate all plugin paths are safe
|
|
45
|
+
for (const pluginPath of pluginPaths) {
|
|
46
|
+
try {
|
|
47
|
+
// Ensure plugin paths are within reasonable bounds
|
|
48
|
+
if (path_1.default.isAbsolute(pluginPath)) {
|
|
49
|
+
(0, storage_security_1.assertWithinBase)(pluginPath, '/'); // Basic sanity check for absolute paths
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
throw new error_handler_1.SecurityError(`Unsafe plugin path: ${pluginPath}: ${error.message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
pluginPaths,
|
|
58
|
+
scanInterval: Math.max(30000, config.scanInterval || 300000), // minimum 30 seconds
|
|
59
|
+
maxFileSize: securityOptions.maxFileSizeBytes,
|
|
60
|
+
maxFiles: Math.max(1, config.maxFiles || 50), // minimum 1 file
|
|
61
|
+
maxPlugins: Math.max(1, config.maxPlugins || 20) // maximum 20 plugins
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
getDefaultPluginPaths() {
|
|
65
|
+
const paths = [];
|
|
66
|
+
// Global npm modules
|
|
67
|
+
try {
|
|
68
|
+
const globalPath = require.resolve('npm').replace(/\/npm\/.*$/, '');
|
|
69
|
+
const globalNodeModules = path_1.default.join(globalPath, 'node_modules');
|
|
70
|
+
if ((0, fs_1.existsSync)(globalNodeModules)) {
|
|
71
|
+
paths.push(globalNodeModules);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Fallback: try common global paths
|
|
76
|
+
const commonPaths = [
|
|
77
|
+
'/usr/local/lib/node_modules',
|
|
78
|
+
'/usr/lib/node_modules'
|
|
79
|
+
];
|
|
80
|
+
for (const commonPath of commonPaths) {
|
|
81
|
+
if ((0, fs_1.existsSync)(commonPath)) {
|
|
82
|
+
paths.push(commonPath);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Local project
|
|
87
|
+
const localNodeModules = path_1.default.join(process.cwd(), 'node_modules');
|
|
88
|
+
if ((0, fs_1.existsSync)(localNodeModules)) {
|
|
89
|
+
paths.push(localNodeModules);
|
|
90
|
+
}
|
|
91
|
+
return paths;
|
|
92
|
+
}
|
|
93
|
+
async loadAllWorkflows() {
|
|
94
|
+
try {
|
|
95
|
+
await this.scanPlugins();
|
|
96
|
+
const workflows = [];
|
|
97
|
+
for (const plugin of this.pluginCache.values()) {
|
|
98
|
+
workflows.push(...plugin.workflows);
|
|
99
|
+
}
|
|
100
|
+
return workflows;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error instanceof error_handler_1.StorageError || error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
throw new error_handler_1.StorageError(`Failed to load plugin workflows: ${error.message}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async getWorkflowById(id) {
|
|
110
|
+
const sanitizedId = (0, storage_security_1.sanitizeId)(id);
|
|
111
|
+
const workflows = await this.loadAllWorkflows();
|
|
112
|
+
return workflows.find(w => w.id === sanitizedId) || null;
|
|
113
|
+
}
|
|
114
|
+
async listWorkflowSummaries() {
|
|
115
|
+
const workflows = await this.loadAllWorkflows();
|
|
116
|
+
return workflows.map(workflow => ({
|
|
117
|
+
id: workflow.id,
|
|
118
|
+
name: workflow.name,
|
|
119
|
+
description: workflow.description,
|
|
120
|
+
category: 'plugin',
|
|
121
|
+
version: workflow.version
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
async save() {
|
|
125
|
+
throw new error_handler_1.StorageError('Plugin-based storage is read-only. Publish workflows as npm packages instead.');
|
|
126
|
+
}
|
|
127
|
+
async scanPlugins() {
|
|
128
|
+
const now = Date.now();
|
|
129
|
+
if (now - this.lastScan < this.config.scanInterval) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
this.pluginCache.clear();
|
|
133
|
+
let pluginCount = 0;
|
|
134
|
+
for (const pluginPath of this.config.pluginPaths) {
|
|
135
|
+
if (!(0, fs_1.existsSync)(pluginPath)) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
// Security: Ensure we're scanning within expected directory
|
|
140
|
+
(0, storage_security_1.assertWithinBase)(pluginPath, pluginPath);
|
|
141
|
+
const entries = await promises_1.default.readdir(pluginPath);
|
|
142
|
+
for (const entry of entries) {
|
|
143
|
+
// Check plugin count limit
|
|
144
|
+
if (pluginCount >= this.config.maxPlugins) {
|
|
145
|
+
throw new error_handler_1.StorageError(`Too many plugins found (${pluginCount}), maximum allowed: ${this.config.maxPlugins}`);
|
|
146
|
+
}
|
|
147
|
+
if (this.isWorkflowPlugin(entry)) {
|
|
148
|
+
const fullPath = path_1.default.join(pluginPath, entry);
|
|
149
|
+
// Security: Ensure plugin path is within scan directory
|
|
150
|
+
(0, storage_security_1.assertWithinBase)(fullPath, pluginPath);
|
|
151
|
+
const plugin = await this.loadPlugin(fullPath);
|
|
152
|
+
if (plugin) {
|
|
153
|
+
this.pluginCache.set(plugin.name, plugin);
|
|
154
|
+
pluginCount++;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
if (error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.StorageError) {
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
throw new error_handler_1.StorageError(`Failed to scan plugin directory ${pluginPath}: ${error.message}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
this.lastScan = now;
|
|
167
|
+
}
|
|
168
|
+
isWorkflowPlugin(entry) {
|
|
169
|
+
return entry.startsWith('workrail-workflows-') || entry.startsWith('@workrail/workflows-');
|
|
170
|
+
}
|
|
171
|
+
async loadPlugin(pluginPath) {
|
|
172
|
+
try {
|
|
173
|
+
// Security: Ensure plugin path is safe
|
|
174
|
+
(0, storage_security_1.assertWithinBase)(pluginPath, path_1.default.dirname(pluginPath));
|
|
175
|
+
const packageJsonPath = path_1.default.join(pluginPath, 'package.json');
|
|
176
|
+
if (!(0, fs_1.existsSync)(packageJsonPath)) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
// Security: Ensure package.json is within plugin directory
|
|
180
|
+
(0, storage_security_1.assertWithinBase)(packageJsonPath, pluginPath);
|
|
181
|
+
// Validate package.json size
|
|
182
|
+
const packageStats = await promises_1.default.stat(packageJsonPath);
|
|
183
|
+
(0, storage_security_1.validateFileSize)(packageStats.size, Math.min(this.config.maxFileSize, 64 * 1024), 'package.json'); // Max 64KB for package.json
|
|
184
|
+
const packageContent = await promises_1.default.readFile(packageJsonPath, 'utf-8');
|
|
185
|
+
let packageJson;
|
|
186
|
+
try {
|
|
187
|
+
packageJson = JSON.parse(packageContent);
|
|
188
|
+
}
|
|
189
|
+
catch (parseError) {
|
|
190
|
+
throw new error_handler_1.InvalidWorkflowError(pluginPath, `Invalid package.json: ${parseError.message}`);
|
|
191
|
+
}
|
|
192
|
+
// Validate it's a workflow plugin
|
|
193
|
+
if (!packageJson.workrail || !packageJson.workrail.workflows) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
// Validate package name
|
|
197
|
+
if (!packageJson.name || typeof packageJson.name !== 'string') {
|
|
198
|
+
throw new error_handler_1.InvalidWorkflowError(pluginPath, `Invalid package name`);
|
|
199
|
+
}
|
|
200
|
+
const workflowsPath = path_1.default.join(pluginPath, 'workflows');
|
|
201
|
+
if (!(0, fs_1.existsSync)(workflowsPath)) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
// Security: Ensure workflows directory is within plugin
|
|
205
|
+
(0, storage_security_1.assertWithinBase)(workflowsPath, pluginPath);
|
|
206
|
+
const workflows = await this.loadWorkflowsFromDirectory(workflowsPath);
|
|
207
|
+
return {
|
|
208
|
+
name: packageJson.name,
|
|
209
|
+
version: packageJson.version || '0.0.0',
|
|
210
|
+
workflows,
|
|
211
|
+
metadata: {
|
|
212
|
+
author: packageJson.author,
|
|
213
|
+
description: packageJson.description,
|
|
214
|
+
homepage: packageJson.homepage,
|
|
215
|
+
repository: packageJson.repository?.url || packageJson.repository
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
if (error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
throw new error_handler_1.StorageError(`Failed to load plugin from ${pluginPath}: ${error.message}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
async loadWorkflowsFromDirectory(workflowsPath) {
|
|
227
|
+
const workflows = [];
|
|
228
|
+
try {
|
|
229
|
+
const files = await promises_1.default.readdir(workflowsPath);
|
|
230
|
+
const jsonFiles = files.filter(f => f.endsWith('.json'));
|
|
231
|
+
if (jsonFiles.length > this.config.maxFiles) {
|
|
232
|
+
throw new error_handler_1.StorageError(`Too many workflow files in ${workflowsPath} (${jsonFiles.length}), maximum allowed: ${this.config.maxFiles}`);
|
|
233
|
+
}
|
|
234
|
+
for (const file of jsonFiles) {
|
|
235
|
+
try {
|
|
236
|
+
const filePath = path_1.default.join(workflowsPath, file);
|
|
237
|
+
// Security: Ensure file is within workflows directory
|
|
238
|
+
(0, storage_security_1.assertWithinBase)(filePath, workflowsPath);
|
|
239
|
+
// Validate file size
|
|
240
|
+
const stats = await promises_1.default.stat(filePath);
|
|
241
|
+
(0, storage_security_1.validateFileSize)(stats.size, this.config.maxFileSize, file);
|
|
242
|
+
const content = await promises_1.default.readFile(filePath, 'utf-8');
|
|
243
|
+
let workflow;
|
|
244
|
+
try {
|
|
245
|
+
workflow = JSON.parse(content);
|
|
246
|
+
}
|
|
247
|
+
catch (parseError) {
|
|
248
|
+
throw new error_handler_1.InvalidWorkflowError(file, `Invalid JSON in workflow file: ${parseError.message}`);
|
|
249
|
+
}
|
|
250
|
+
// Validate workflow ID
|
|
251
|
+
const sanitizedId = (0, storage_security_1.sanitizeId)(workflow.id);
|
|
252
|
+
if (workflow.id !== sanitizedId) {
|
|
253
|
+
throw new error_handler_1.InvalidWorkflowError(workflow.id, `Invalid workflow ID in file ${file}`);
|
|
254
|
+
}
|
|
255
|
+
workflows.push(workflow);
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
if (error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
throw new error_handler_1.StorageError(`Failed to load workflow from ${file}: ${error.message}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
if (error instanceof error_handler_1.StorageError || error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
throw new error_handler_1.StorageError(`Failed to read workflows directory ${workflowsPath}: ${error.message}`);
|
|
270
|
+
}
|
|
271
|
+
return workflows;
|
|
272
|
+
}
|
|
273
|
+
getLoadedPlugins() {
|
|
274
|
+
return Array.from(this.pluginCache.values());
|
|
275
|
+
}
|
|
276
|
+
getConfig() {
|
|
277
|
+
return { ...this.config };
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
exports.PluginWorkflowStorage = PluginWorkflowStorage;
|
|
281
|
+
/**
|
|
282
|
+
* Example package.json for a workflow plugin:
|
|
283
|
+
*
|
|
284
|
+
* ```json
|
|
285
|
+
* {
|
|
286
|
+
* "name": "workrail-workflows-ai-coding",
|
|
287
|
+
* "version": "1.0.0",
|
|
288
|
+
* "description": "AI-powered coding workflows for Workrail",
|
|
289
|
+
* "main": "index.js",
|
|
290
|
+
* "workrail": {
|
|
291
|
+
* "workflows": true,
|
|
292
|
+
* "category": "coding"
|
|
293
|
+
* },
|
|
294
|
+
* "keywords": ["workrail", "workflow", "ai", "coding"],
|
|
295
|
+
* "author": "Your Name",
|
|
296
|
+
* "license": "MIT"
|
|
297
|
+
* }
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
/**
|
|
301
|
+
* Example configuration for different environments
|
|
302
|
+
*/
|
|
303
|
+
exports.PLUGIN_WORKFLOW_CONFIGS = {
|
|
304
|
+
// Development environment with relaxed limits
|
|
305
|
+
development: {
|
|
306
|
+
scanInterval: 60000, // 1 minute
|
|
307
|
+
maxFileSize: 2 * 1024 * 1024, // 2MB
|
|
308
|
+
maxFiles: 100,
|
|
309
|
+
maxPlugins: 50
|
|
310
|
+
},
|
|
311
|
+
// Production environment with strict limits
|
|
312
|
+
production: {
|
|
313
|
+
scanInterval: 300000, // 5 minutes
|
|
314
|
+
maxFileSize: 1024 * 1024, // 1MB
|
|
315
|
+
maxFiles: 50,
|
|
316
|
+
maxPlugins: 20
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
//# sourceMappingURL=plugin-workflow-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-workflow-storage.js","sourceRoot":"","sources":["../../../src/infrastructure/storage/plugin-workflow-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { IWorkflowStorage } from '../../types/storage';
|
|
2
|
+
import { Workflow, WorkflowSummary } from '../../types/mcp-types';
|
|
3
|
+
import { StorageSecurityOptions } from '../../utils/storage-security';
|
|
4
|
+
export interface RemoteWorkflowRegistryConfig extends StorageSecurityOptions {
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
apiKey?: string;
|
|
7
|
+
timeout?: number;
|
|
8
|
+
retryAttempts?: number;
|
|
9
|
+
userAgent?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Remote workflow storage that fetches workflows from a community registry.
|
|
13
|
+
* Implements security best practices and proper error handling.
|
|
14
|
+
* Similar to npm registry but for workflows.
|
|
15
|
+
*/
|
|
16
|
+
export declare class RemoteWorkflowStorage implements IWorkflowStorage {
|
|
17
|
+
private readonly config;
|
|
18
|
+
private readonly securityOptions;
|
|
19
|
+
constructor(config: RemoteWorkflowRegistryConfig);
|
|
20
|
+
private validateConfig;
|
|
21
|
+
loadAllWorkflows(): Promise<Workflow[]>;
|
|
22
|
+
getWorkflowById(id: string): Promise<Workflow | null>;
|
|
23
|
+
listWorkflowSummaries(): Promise<WorkflowSummary[]>;
|
|
24
|
+
save(workflow: Workflow): Promise<void>;
|
|
25
|
+
private fetchWithRetry;
|
|
26
|
+
private parseResponse;
|
|
27
|
+
private validateWorkflows;
|
|
28
|
+
private validateSummaries;
|
|
29
|
+
private validateWorkflowForSave;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Multi-source workflow storage that combines bundled, local, and remote workflows.
|
|
33
|
+
* Uses composition to cleanly separate concerns.
|
|
34
|
+
*/
|
|
35
|
+
export declare class CommunityWorkflowStorage implements IWorkflowStorage {
|
|
36
|
+
private readonly sources;
|
|
37
|
+
private readonly remoteStorage;
|
|
38
|
+
constructor(bundledStorage: IWorkflowStorage, localStorage: IWorkflowStorage, remoteConfig: RemoteWorkflowRegistryConfig);
|
|
39
|
+
loadAllWorkflows(): Promise<Workflow[]>;
|
|
40
|
+
getWorkflowById(id: string): Promise<Workflow | null>;
|
|
41
|
+
listWorkflowSummaries(): Promise<WorkflowSummary[]>;
|
|
42
|
+
save(workflow: Workflow): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=remote-workflow-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-workflow-storage.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/storage/remote-workflow-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAIL,sBAAsB,EACvB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,4BAA6B,SAAQ,sBAAsB;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;gBAEvD,MAAM,EAAE,4BAA4B;IAehD,OAAO,CAAC,cAAc;IAkBhB,gBAAgB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAqBvC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAwCrD,qBAAqB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAmBnD,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;YAkC/B,cAAc;YAwCd,aAAa;IAqB3B,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,iBAAiB;IAyBzB,OAAO,CAAC,uBAAuB;CAoBhC;AAED;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,gBAAgB;IAC/D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwB;gBAGpD,cAAc,EAAE,gBAAgB,EAChC,YAAY,EAAE,gBAAgB,EAC9B,YAAY,EAAE,4BAA4B;IAMtC,gBAAgB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAmCvC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAkCrD,qBAAqB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAYnD,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAI9C"}
|