@exaudeus/workrail 0.0.12 → 0.0.14

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,65 @@
1
+ import { IWorkflowStorage } from '../../types/storage';
2
+ import { Workflow, WorkflowSummary } from '../../types/mcp-types';
3
+ export interface GitWorkflowConfig {
4
+ repositoryUrl: string;
5
+ branch?: string;
6
+ localPath?: string;
7
+ syncInterval?: number;
8
+ authToken?: string;
9
+ maxFileSize?: number;
10
+ maxFiles?: number;
11
+ }
12
+ export interface ValidatedGitWorkflowConfig extends Required<GitWorkflowConfig> {
13
+ maxFileSize: number;
14
+ maxFiles: number;
15
+ }
16
+ /**
17
+ * Git-based workflow storage that clones/pulls workflows from a Git repository
18
+ * Perfect for community-driven workflow contributions via GitHub/GitLab
19
+ *
20
+ * Security features:
21
+ * - Git command injection protection
22
+ * - Path traversal prevention
23
+ * - File size limits
24
+ * - Repository URL validation
25
+ */
26
+ export declare class GitWorkflowStorage implements IWorkflowStorage {
27
+ private readonly config;
28
+ private readonly localPath;
29
+ private lastSync;
30
+ private isCloning;
31
+ constructor(config: GitWorkflowConfig);
32
+ private validateAndNormalizeConfig;
33
+ private isValidGitUrl;
34
+ private sanitizeGitRef;
35
+ loadAllWorkflows(): Promise<Workflow[]>;
36
+ getWorkflowById(id: string): Promise<Workflow | null>;
37
+ listWorkflowSummaries(): Promise<WorkflowSummary[]>;
38
+ save(workflow: Workflow): Promise<void>;
39
+ private ensureRepository;
40
+ private cloneRepository;
41
+ private pullRepository;
42
+ private gitCommitAndPush;
43
+ private escapeShellArg;
44
+ }
45
+ /**
46
+ * Example usage and configuration
47
+ */
48
+ export declare const COMMUNITY_WORKFLOW_REPOS: {
49
+ official: {
50
+ repositoryUrl: string;
51
+ branch: string;
52
+ syncInterval: number;
53
+ maxFileSize: number;
54
+ maxFiles: number;
55
+ };
56
+ personal: {
57
+ repositoryUrl: string;
58
+ branch: string;
59
+ syncInterval: number;
60
+ authToken: string | undefined;
61
+ maxFileSize: number;
62
+ maxFiles: number;
63
+ };
64
+ };
65
+ //# sourceMappingURL=git-workflow-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-workflow-storage.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/storage/git-workflow-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAgBlE,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,0BAA2B,SAAQ,QAAQ,CAAC,iBAAiB,CAAC;IAC7E,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,YAAW,gBAAgB;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,SAAS,CAAkB;gBAEvB,MAAM,EAAE,iBAAiB;IAKrC,OAAO,CAAC,0BAA0B;IAmClC,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,cAAc;IAQhB,gBAAgB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IA6DvC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAMrD,qBAAqB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAWnD,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;YAoC/B,gBAAgB;YAyChB,eAAe;YAqBf,cAAc;YAcd,gBAAgB;IAsB9B,OAAO,CAAC,cAAc;CAIvB;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;CAmBpC,CAAC"}
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.COMMUNITY_WORKFLOW_REPOS = exports.GitWorkflowStorage = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const child_process_1 = require("child_process");
6
+ const util_1 = require("util");
7
+ const path_1 = tslib_1.__importDefault(require("path"));
8
+ const promises_1 = tslib_1.__importDefault(require("fs/promises"));
9
+ const fs_1 = require("fs");
10
+ const storage_security_1 = require("../../utils/storage-security");
11
+ const error_handler_1 = require("../../core/error-handler");
12
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
13
+ /**
14
+ * Git-based workflow storage that clones/pulls workflows from a Git repository
15
+ * Perfect for community-driven workflow contributions via GitHub/GitLab
16
+ *
17
+ * Security features:
18
+ * - Git command injection protection
19
+ * - Path traversal prevention
20
+ * - File size limits
21
+ * - Repository URL validation
22
+ */
23
+ class GitWorkflowStorage {
24
+ config;
25
+ localPath;
26
+ lastSync = 0;
27
+ isCloning = false;
28
+ constructor(config) {
29
+ this.config = this.validateAndNormalizeConfig(config);
30
+ this.localPath = this.config.localPath;
31
+ }
32
+ validateAndNormalizeConfig(config) {
33
+ if (!config.repositoryUrl?.trim()) {
34
+ throw new error_handler_1.StorageError('Repository URL is required for Git workflow storage');
35
+ }
36
+ // Validate repository URL format and security
37
+ if (!this.isValidGitUrl(config.repositoryUrl)) {
38
+ throw new error_handler_1.SecurityError('Invalid or potentially unsafe repository URL');
39
+ }
40
+ const securityOptions = (0, storage_security_1.validateSecurityOptions)({
41
+ maxFileSizeBytes: config.maxFileSize || 1024 * 1024 // 1MB default
42
+ });
43
+ const localPath = config.localPath ||
44
+ path_1.default.join(process.cwd(), '.workrail-cache', 'community-workflows');
45
+ // Ensure local path is within safe boundaries
46
+ try {
47
+ (0, storage_security_1.assertWithinBase)(localPath, process.cwd());
48
+ }
49
+ catch (error) {
50
+ throw new error_handler_1.SecurityError(`Local path outside safe boundaries: ${error.message}`);
51
+ }
52
+ return {
53
+ repositoryUrl: config.repositoryUrl.trim(),
54
+ branch: this.sanitizeGitRef(config.branch || 'main'),
55
+ localPath,
56
+ syncInterval: Math.max(1, config.syncInterval || 60), // minimum 1 minute
57
+ authToken: config.authToken || '',
58
+ maxFileSize: securityOptions.maxFileSizeBytes,
59
+ maxFiles: config.maxFiles || 100 // default 100 files
60
+ };
61
+ }
62
+ isValidGitUrl(url) {
63
+ try {
64
+ const parsed = new URL(url);
65
+ // Allow common Git hosting services
66
+ const allowedHosts = [
67
+ 'github.com', 'gitlab.com', 'bitbucket.org',
68
+ 'dev.azure.com', 'sourceforge.net'
69
+ ];
70
+ return allowedHosts.some(host => parsed.hostname === host || parsed.hostname.endsWith(`.${host}`)) && (parsed.protocol === 'https:' || parsed.protocol === 'git:');
71
+ }
72
+ catch {
73
+ return false;
74
+ }
75
+ }
76
+ sanitizeGitRef(ref) {
77
+ // Prevent Git injection by allowing only safe characters
78
+ if (!/^[a-zA-Z0-9/_.-]+$/.test(ref)) {
79
+ throw new error_handler_1.SecurityError('Git reference contains unsafe characters');
80
+ }
81
+ return ref;
82
+ }
83
+ async loadAllWorkflows() {
84
+ try {
85
+ await this.ensureRepository();
86
+ const workflowsPath = path_1.default.join(this.localPath, 'workflows');
87
+ if (!(0, fs_1.existsSync)(workflowsPath)) {
88
+ return [];
89
+ }
90
+ const files = await promises_1.default.readdir(workflowsPath);
91
+ const jsonFiles = files.filter(f => f.endsWith('.json'));
92
+ if (jsonFiles.length > this.config.maxFiles) {
93
+ throw new error_handler_1.StorageError(`Too many workflow files (${jsonFiles.length}), maximum allowed: ${this.config.maxFiles}`);
94
+ }
95
+ const workflows = [];
96
+ for (const file of jsonFiles) {
97
+ try {
98
+ const filePath = path_1.default.join(workflowsPath, file);
99
+ // Security: Ensure file is within expected directory
100
+ (0, storage_security_1.assertWithinBase)(filePath, workflowsPath);
101
+ // Validate file size
102
+ const stats = await promises_1.default.stat(filePath);
103
+ (0, storage_security_1.validateFileSize)(stats.size, this.config.maxFileSize, file);
104
+ const content = await promises_1.default.readFile(filePath, 'utf-8');
105
+ const workflow = JSON.parse(content);
106
+ // Validate workflow ID matches filename (security)
107
+ const expectedFilename = `${(0, storage_security_1.sanitizeId)(workflow.id)}.json`;
108
+ if (file !== expectedFilename) {
109
+ throw new error_handler_1.InvalidWorkflowError(workflow.id, `Workflow ID '${workflow.id}' doesn't match filename '${file}'`);
110
+ }
111
+ workflows.push(workflow);
112
+ }
113
+ catch (error) {
114
+ if (error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
115
+ throw error;
116
+ }
117
+ throw new error_handler_1.StorageError(`Failed to load workflow from ${file}: ${error.message}`);
118
+ }
119
+ }
120
+ return workflows;
121
+ }
122
+ catch (error) {
123
+ if (error instanceof error_handler_1.StorageError || error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
124
+ throw error;
125
+ }
126
+ throw new error_handler_1.StorageError(`Failed to load workflows from Git repository: ${error.message}`);
127
+ }
128
+ }
129
+ async getWorkflowById(id) {
130
+ const sanitizedId = (0, storage_security_1.sanitizeId)(id);
131
+ const workflows = await this.loadAllWorkflows();
132
+ return workflows.find(w => w.id === sanitizedId) || null;
133
+ }
134
+ async listWorkflowSummaries() {
135
+ const workflows = await this.loadAllWorkflows();
136
+ return workflows.map(workflow => ({
137
+ id: workflow.id,
138
+ name: workflow.name,
139
+ description: workflow.description,
140
+ category: 'community',
141
+ version: workflow.version
142
+ }));
143
+ }
144
+ async save(workflow) {
145
+ try {
146
+ // Validate workflow ID
147
+ const sanitizedId = (0, storage_security_1.sanitizeId)(workflow.id);
148
+ if (workflow.id !== sanitizedId) {
149
+ throw new error_handler_1.InvalidWorkflowError(workflow.id, `Invalid workflow ID: ${workflow.id}`);
150
+ }
151
+ await this.ensureRepository();
152
+ const workflowsPath = path_1.default.join(this.localPath, 'workflows');
153
+ await promises_1.default.mkdir(workflowsPath, { recursive: true });
154
+ const filename = `${sanitizedId}.json`;
155
+ const filePath = path_1.default.join(workflowsPath, filename);
156
+ // Security: Ensure we're writing within expected directory
157
+ (0, storage_security_1.assertWithinBase)(filePath, workflowsPath);
158
+ const content = JSON.stringify(workflow, null, 2);
159
+ // Validate content size
160
+ (0, storage_security_1.validateFileSize)(Buffer.byteLength(content, 'utf-8'), this.config.maxFileSize, workflow.id);
161
+ await promises_1.default.writeFile(filePath, content);
162
+ // Git commit and push
163
+ await this.gitCommitAndPush(workflow);
164
+ }
165
+ catch (error) {
166
+ if (error instanceof error_handler_1.SecurityError || error instanceof error_handler_1.InvalidWorkflowError) {
167
+ throw error;
168
+ }
169
+ throw new error_handler_1.StorageError(`Failed to save workflow to Git repository: ${error.message}`);
170
+ }
171
+ }
172
+ async ensureRepository() {
173
+ if (this.isCloning) {
174
+ // Wait for clone to complete
175
+ let attempts = 0;
176
+ const maxAttempts = 60; // 1 minute max wait
177
+ while (this.isCloning && attempts < maxAttempts) {
178
+ await new Promise(resolve => setTimeout(resolve, 1000));
179
+ attempts++;
180
+ }
181
+ if (this.isCloning) {
182
+ throw new error_handler_1.StorageError('Repository clone operation timed out');
183
+ }
184
+ return;
185
+ }
186
+ const shouldSync = !(0, fs_1.existsSync)(this.localPath) ||
187
+ (Date.now() - this.lastSync) > (this.config.syncInterval * 60 * 1000);
188
+ if (!shouldSync) {
189
+ return;
190
+ }
191
+ this.isCloning = true;
192
+ try {
193
+ if (!(0, fs_1.existsSync)(this.localPath)) {
194
+ await this.cloneRepository();
195
+ }
196
+ else {
197
+ await this.pullRepository();
198
+ }
199
+ this.lastSync = Date.now();
200
+ }
201
+ catch (error) {
202
+ throw new error_handler_1.StorageError(`Failed to ensure Git repository: ${error.message}`);
203
+ }
204
+ finally {
205
+ this.isCloning = false;
206
+ }
207
+ }
208
+ async cloneRepository() {
209
+ const parentDir = path_1.default.dirname(this.localPath);
210
+ await promises_1.default.mkdir(parentDir, { recursive: true });
211
+ // Security: Escape shell arguments to prevent injection
212
+ const escapedUrl = this.config.authToken
213
+ ? this.config.repositoryUrl.replace('https://', `https://${this.escapeShellArg(this.config.authToken)}@`)
214
+ : this.config.repositoryUrl;
215
+ const escapedBranch = this.escapeShellArg(this.config.branch);
216
+ const escapedPath = this.escapeShellArg(this.localPath);
217
+ const command = `git clone --branch ${escapedBranch} --depth 1 ${this.escapeShellArg(escapedUrl)} ${escapedPath}`;
218
+ try {
219
+ await execAsync(command, { timeout: 60000 }); // 1 minute timeout
220
+ }
221
+ catch (error) {
222
+ throw new error_handler_1.StorageError(`Failed to clone workflow repository: ${error.message}`);
223
+ }
224
+ }
225
+ async pullRepository() {
226
+ const escapedPath = this.escapeShellArg(this.localPath);
227
+ const escapedBranch = this.escapeShellArg(this.config.branch);
228
+ const command = `cd ${escapedPath} && git pull origin ${escapedBranch}`;
229
+ try {
230
+ await execAsync(command, { timeout: 30000 }); // 30 second timeout
231
+ }
232
+ catch (error) {
233
+ // Don't throw on pull failure - use cached version
234
+ // This is intentional behavior for offline scenarios
235
+ }
236
+ }
237
+ async gitCommitAndPush(workflow) {
238
+ const escapedPath = this.escapeShellArg(this.localPath);
239
+ const escapedFilename = this.escapeShellArg(`workflows/${workflow.id}.json`);
240
+ const escapedMessage = this.escapeShellArg(`Add/update workflow: ${workflow.name}`);
241
+ const escapedBranch = this.escapeShellArg(this.config.branch);
242
+ const commands = [
243
+ `cd ${escapedPath}`,
244
+ `git add ${escapedFilename}`,
245
+ `git commit -m ${escapedMessage}`,
246
+ `git push origin ${escapedBranch}`
247
+ ];
248
+ const command = commands.join(' && ');
249
+ try {
250
+ await execAsync(command, { timeout: 60000 }); // 1 minute timeout
251
+ }
252
+ catch (error) {
253
+ throw new error_handler_1.StorageError(`Failed to push workflow to repository: ${error.message}`);
254
+ }
255
+ }
256
+ escapeShellArg(arg) {
257
+ // Escape shell arguments to prevent injection attacks
258
+ return `'${arg.replace(/'/g, "'\"'\"'")}'`;
259
+ }
260
+ }
261
+ exports.GitWorkflowStorage = GitWorkflowStorage;
262
+ /**
263
+ * Example usage and configuration
264
+ */
265
+ exports.COMMUNITY_WORKFLOW_REPOS = {
266
+ // Official community repository
267
+ official: {
268
+ repositoryUrl: 'https://github.com/your-org/workrail-community-workflows.git',
269
+ branch: 'main',
270
+ syncInterval: 60, // 1 hour
271
+ maxFileSize: 1024 * 1024, // 1MB
272
+ maxFiles: 100
273
+ },
274
+ // User's personal workflow repository
275
+ personal: {
276
+ repositoryUrl: 'https://github.com/username/my-workflows.git',
277
+ branch: 'main',
278
+ syncInterval: 30, // 30 minutes
279
+ authToken: process.env['GITHUB_TOKEN'],
280
+ maxFileSize: 1024 * 1024, // 1MB
281
+ maxFiles: 50
282
+ }
283
+ };
284
+ //# sourceMappingURL=git-workflow-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-workflow-storage.js","sourceRoot":"","sources":["../../../src/infrastructure/storage/git-workflow-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ import { IWorkflowStorage } from '../../types/storage';
2
+ import { Workflow, WorkflowSummary } from '../../types/mcp-types';
3
+ export interface WorkflowPlugin {
4
+ name: string;
5
+ version: string;
6
+ workflows: Workflow[];
7
+ metadata?: {
8
+ author?: string;
9
+ description?: string;
10
+ homepage?: string;
11
+ repository?: string;
12
+ };
13
+ }
14
+ export interface PluginWorkflowConfig {
15
+ pluginPaths?: string[];
16
+ scanInterval?: number;
17
+ maxFileSize?: number;
18
+ maxFiles?: number;
19
+ maxPlugins?: number;
20
+ }
21
+ export interface ValidatedPluginWorkflowConfig extends Required<PluginWorkflowConfig> {
22
+ pluginPaths: string[];
23
+ scanInterval: number;
24
+ maxFileSize: number;
25
+ maxFiles: number;
26
+ maxPlugins: number;
27
+ }
28
+ /**
29
+ * Plugin-based workflow storage that loads workflows from npm packages
30
+ * Workflows are distributed as npm packages with a specific structure
31
+ *
32
+ * Security features:
33
+ * - Path traversal prevention
34
+ * - File size limits
35
+ * - Plugin count limits
36
+ * - Safe package.json parsing
37
+ *
38
+ * Example package structure:
39
+ * ```
40
+ * my-workflow-pack/
41
+ * ├── package.json
42
+ * ├── index.js
43
+ * └── workflows/
44
+ * ├── my-workflow-1.json
45
+ * └── my-workflow-2.json
46
+ * ```
47
+ */
48
+ export declare class PluginWorkflowStorage implements IWorkflowStorage {
49
+ private readonly config;
50
+ private pluginCache;
51
+ private lastScan;
52
+ constructor(config?: PluginWorkflowConfig);
53
+ private validateAndNormalizeConfig;
54
+ private getDefaultPluginPaths;
55
+ loadAllWorkflows(): Promise<Workflow[]>;
56
+ getWorkflowById(id: string): Promise<Workflow | null>;
57
+ listWorkflowSummaries(): Promise<WorkflowSummary[]>;
58
+ save(): Promise<void>;
59
+ private scanPlugins;
60
+ private isWorkflowPlugin;
61
+ private loadPlugin;
62
+ private loadWorkflowsFromDirectory;
63
+ getLoadedPlugins(): WorkflowPlugin[];
64
+ getConfig(): ValidatedPluginWorkflowConfig;
65
+ }
66
+ /**
67
+ * Example package.json for a workflow plugin:
68
+ *
69
+ * ```json
70
+ * {
71
+ * "name": "workrail-workflows-ai-coding",
72
+ * "version": "1.0.0",
73
+ * "description": "AI-powered coding workflows for Workrail",
74
+ * "main": "index.js",
75
+ * "workrail": {
76
+ * "workflows": true,
77
+ * "category": "coding"
78
+ * },
79
+ * "keywords": ["workrail", "workflow", "ai", "coding"],
80
+ * "author": "Your Name",
81
+ * "license": "MIT"
82
+ * }
83
+ * ```
84
+ */
85
+ /**
86
+ * Example configuration for different environments
87
+ */
88
+ export declare const PLUGIN_WORKFLOW_CONFIGS: {
89
+ development: {
90
+ scanInterval: number;
91
+ maxFileSize: number;
92
+ maxFiles: number;
93
+ maxPlugins: number;
94
+ };
95
+ production: {
96
+ scanInterval: number;
97
+ maxFileSize: number;
98
+ maxFiles: number;
99
+ maxPlugins: number;
100
+ };
101
+ };
102
+ //# sourceMappingURL=plugin-workflow-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-workflow-storage.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/storage/plugin-workflow-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAYlE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,6BAA8B,SAAQ,QAAQ,CAAC,oBAAoB,CAAC;IACnF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,WAAW,CAA0C;IAC7D,OAAO,CAAC,QAAQ,CAAa;gBAEjB,MAAM,GAAE,oBAAyB;IAI7C,OAAO,CAAC,0BAA0B;IA8BlC,OAAO,CAAC,qBAAqB;IAiCvB,gBAAgB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAmBvC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAMrD,qBAAqB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAWnD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAIb,WAAW;IAqDzB,OAAO,CAAC,gBAAgB;YAIV,UAAU;YAkEV,0BAA0B;IAyDjC,gBAAgB,IAAI,cAAc,EAAE;IAIpC,SAAS,IAAI,6BAA6B;CAGlD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;CAgBnC,CAAC"}