@objectstack/core 0.9.1 → 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.
Files changed (94) hide show
  1. package/{ENHANCED_FEATURES.md → ADVANCED_FEATURES.md} +13 -13
  2. package/CHANGELOG.md +21 -0
  3. package/PHASE2_IMPLEMENTATION.md +388 -0
  4. package/README.md +12 -341
  5. package/REFACTORING_SUMMARY.md +40 -0
  6. package/dist/api-registry-plugin.test.js +23 -21
  7. package/dist/api-registry.test.js +2 -2
  8. package/dist/dependency-resolver.d.ts +62 -0
  9. package/dist/dependency-resolver.d.ts.map +1 -0
  10. package/dist/dependency-resolver.js +317 -0
  11. package/dist/dependency-resolver.test.d.ts +2 -0
  12. package/dist/dependency-resolver.test.d.ts.map +1 -0
  13. package/dist/dependency-resolver.test.js +241 -0
  14. package/dist/health-monitor.d.ts +65 -0
  15. package/dist/health-monitor.d.ts.map +1 -0
  16. package/dist/health-monitor.js +269 -0
  17. package/dist/health-monitor.test.d.ts +2 -0
  18. package/dist/health-monitor.test.d.ts.map +1 -0
  19. package/dist/health-monitor.test.js +68 -0
  20. package/dist/hot-reload.d.ts +79 -0
  21. package/dist/hot-reload.d.ts.map +1 -0
  22. package/dist/hot-reload.js +313 -0
  23. package/dist/index.d.ts +4 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +5 -1
  26. package/dist/kernel-base.d.ts +2 -2
  27. package/dist/kernel-base.js +2 -2
  28. package/dist/kernel.d.ts +89 -31
  29. package/dist/kernel.d.ts.map +1 -1
  30. package/dist/kernel.js +430 -73
  31. package/dist/kernel.test.js +375 -122
  32. package/dist/lite-kernel.d.ts +55 -0
  33. package/dist/lite-kernel.d.ts.map +1 -0
  34. package/dist/lite-kernel.js +112 -0
  35. package/dist/lite-kernel.test.d.ts +2 -0
  36. package/dist/lite-kernel.test.d.ts.map +1 -0
  37. package/dist/lite-kernel.test.js +161 -0
  38. package/dist/logger.d.ts +2 -2
  39. package/dist/logger.d.ts.map +1 -1
  40. package/dist/logger.js +26 -7
  41. package/dist/plugin-loader.d.ts +15 -0
  42. package/dist/plugin-loader.d.ts.map +1 -1
  43. package/dist/plugin-loader.js +40 -10
  44. package/dist/plugin-loader.test.js +9 -0
  45. package/dist/security/index.d.ts +3 -0
  46. package/dist/security/index.d.ts.map +1 -1
  47. package/dist/security/index.js +4 -0
  48. package/dist/security/permission-manager.d.ts +96 -0
  49. package/dist/security/permission-manager.d.ts.map +1 -0
  50. package/dist/security/permission-manager.js +235 -0
  51. package/dist/security/permission-manager.test.d.ts +2 -0
  52. package/dist/security/permission-manager.test.d.ts.map +1 -0
  53. package/dist/security/permission-manager.test.js +220 -0
  54. package/dist/security/plugin-permission-enforcer.d.ts +1 -1
  55. package/dist/security/sandbox-runtime.d.ts +115 -0
  56. package/dist/security/sandbox-runtime.d.ts.map +1 -0
  57. package/dist/security/sandbox-runtime.js +310 -0
  58. package/dist/security/security-scanner.d.ts +92 -0
  59. package/dist/security/security-scanner.d.ts.map +1 -0
  60. package/dist/security/security-scanner.js +273 -0
  61. package/examples/{enhanced-kernel-example.ts → kernel-features-example.ts} +6 -6
  62. package/examples/phase2-integration.ts +355 -0
  63. package/package.json +3 -2
  64. package/src/api-registry-plugin.test.ts +23 -21
  65. package/src/api-registry.test.ts +2 -2
  66. package/src/dependency-resolver.test.ts +287 -0
  67. package/src/dependency-resolver.ts +388 -0
  68. package/src/health-monitor.test.ts +81 -0
  69. package/src/health-monitor.ts +316 -0
  70. package/src/hot-reload.ts +388 -0
  71. package/src/index.ts +6 -1
  72. package/src/kernel-base.ts +2 -2
  73. package/src/kernel.test.ts +471 -134
  74. package/src/kernel.ts +518 -76
  75. package/src/lite-kernel.test.ts +200 -0
  76. package/src/lite-kernel.ts +135 -0
  77. package/src/logger.ts +28 -7
  78. package/src/plugin-loader.test.ts +10 -1
  79. package/src/plugin-loader.ts +49 -13
  80. package/src/security/index.ts +19 -0
  81. package/src/security/permission-manager.test.ts +256 -0
  82. package/src/security/permission-manager.ts +336 -0
  83. package/src/security/plugin-permission-enforcer.test.ts +1 -1
  84. package/src/security/plugin-permission-enforcer.ts +1 -1
  85. package/src/security/sandbox-runtime.ts +432 -0
  86. package/src/security/security-scanner.ts +365 -0
  87. package/dist/enhanced-kernel.d.ts +0 -103
  88. package/dist/enhanced-kernel.d.ts.map +0 -1
  89. package/dist/enhanced-kernel.js +0 -403
  90. package/dist/enhanced-kernel.test.d.ts +0 -2
  91. package/dist/enhanced-kernel.test.d.ts.map +0 -1
  92. package/dist/enhanced-kernel.test.js +0 -412
  93. package/src/enhanced-kernel.test.ts +0 -535
  94. package/src/enhanced-kernel.ts +0 -496
@@ -0,0 +1,365 @@
1
+ import type {
2
+ SecurityVulnerability,
3
+ SecurityScanResult
4
+ } from '@objectstack/spec/kernel';
5
+ import type { ObjectLogger } from '../logger.js';
6
+
7
+ /**
8
+ * Scan Target
9
+ */
10
+ export interface ScanTarget {
11
+ pluginId: string;
12
+ version: string;
13
+ files?: string[];
14
+ dependencies?: Record<string, string>;
15
+ }
16
+
17
+ /**
18
+ * Security Issue
19
+ */
20
+ export interface SecurityIssue {
21
+ id: string;
22
+ severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
23
+ category: 'vulnerability' | 'malware' | 'license' | 'code-quality' | 'configuration';
24
+ title: string;
25
+ description: string;
26
+ location?: {
27
+ file?: string;
28
+ line?: number;
29
+ column?: number;
30
+ };
31
+ remediation?: string;
32
+ cve?: string;
33
+ cvss?: number;
34
+ }
35
+
36
+ /**
37
+ * Plugin Security Scanner
38
+ *
39
+ * Scans plugins for security vulnerabilities, malware, and license issues
40
+ */
41
+ export class PluginSecurityScanner {
42
+ private logger: ObjectLogger;
43
+
44
+ // Known vulnerabilities database (CVE cache)
45
+ private vulnerabilityDb = new Map<string, SecurityVulnerability>();
46
+
47
+ // Scan results cache
48
+ private scanResults = new Map<string, SecurityScanResult>();
49
+
50
+ private passThreshold: number = 70;
51
+
52
+ constructor(logger: ObjectLogger, config?: { passThreshold?: number }) {
53
+ this.logger = logger.child({ component: 'SecurityScanner' });
54
+ if (config?.passThreshold !== undefined) {
55
+ this.passThreshold = config.passThreshold;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Perform a comprehensive security scan on a plugin
61
+ */
62
+ async scan(target: ScanTarget): Promise<SecurityScanResult> {
63
+ this.logger.info('Starting security scan', {
64
+ pluginId: target.pluginId,
65
+ version: target.version
66
+ });
67
+
68
+ const issues: SecurityIssue[] = [];
69
+
70
+ try {
71
+ // 1. Scan for code vulnerabilities
72
+ const codeIssues = await this.scanCode(target);
73
+ issues.push(...codeIssues);
74
+
75
+ // 2. Scan dependencies for known vulnerabilities
76
+ const depIssues = await this.scanDependencies(target);
77
+ issues.push(...depIssues);
78
+
79
+ // 3. Scan for malware patterns
80
+ const malwareIssues = await this.scanMalware(target);
81
+ issues.push(...malwareIssues);
82
+
83
+ // 4. Check license compliance
84
+ const licenseIssues = await this.scanLicenses(target);
85
+ issues.push(...licenseIssues);
86
+
87
+ // 5. Check configuration security
88
+ const configIssues = await this.scanConfiguration(target);
89
+ issues.push(...configIssues);
90
+
91
+ // Calculate security score (0-100, higher is better)
92
+ const score = this.calculateSecurityScore(issues);
93
+
94
+ const result: SecurityScanResult = {
95
+ timestamp: new Date().toISOString(),
96
+ scanner: { name: 'ObjectStack Security Scanner', version: '1.0.0' },
97
+ status: score >= this.passThreshold ? 'passed' : 'failed',
98
+ vulnerabilities: issues.map(issue => ({
99
+ id: issue.id,
100
+ severity: issue.severity,
101
+ category: issue.category,
102
+ title: issue.title,
103
+ description: issue.description,
104
+ location: issue.location ? `${issue.location.file}:${issue.location.line}` : undefined,
105
+ remediation: issue.remediation,
106
+ affectedVersions: [],
107
+ exploitAvailable: false,
108
+ patchAvailable: false,
109
+ })),
110
+ summary: {
111
+ totalVulnerabilities: issues.length,
112
+ criticalCount: issues.filter(i => i.severity === 'critical').length,
113
+ highCount: issues.filter(i => i.severity === 'high').length,
114
+ mediumCount: issues.filter(i => i.severity === 'medium').length,
115
+ lowCount: issues.filter(i => i.severity === 'low').length,
116
+ infoCount: issues.filter(i => i.severity === 'info').length,
117
+ },
118
+ };
119
+
120
+ this.scanResults.set(`${target.pluginId}:${target.version}`, result);
121
+
122
+ this.logger.info('Security scan complete', {
123
+ pluginId: target.pluginId,
124
+ score,
125
+ status: result.status,
126
+ summary: result.summary
127
+ });
128
+
129
+ return result;
130
+ } catch (error) {
131
+ this.logger.error('Security scan failed', {
132
+ pluginId: target.pluginId,
133
+ error
134
+ });
135
+
136
+ throw error;
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Scan code for vulnerabilities
142
+ */
143
+ private async scanCode(target: ScanTarget): Promise<SecurityIssue[]> {
144
+ const issues: SecurityIssue[] = [];
145
+
146
+ // In a real implementation, this would:
147
+ // - Parse code with AST (e.g., using @typescript-eslint/parser)
148
+ // - Check for dangerous patterns (eval, Function constructor, etc.)
149
+ // - Check for XSS vulnerabilities
150
+ // - Check for SQL injection patterns
151
+ // - Check for insecure crypto usage
152
+ // - Check for path traversal vulnerabilities
153
+
154
+ this.logger.debug('Code scan complete', {
155
+ pluginId: target.pluginId,
156
+ issuesFound: issues.length
157
+ });
158
+
159
+ return issues;
160
+ }
161
+
162
+ /**
163
+ * Scan dependencies for known vulnerabilities
164
+ */
165
+ private async scanDependencies(target: ScanTarget): Promise<SecurityIssue[]> {
166
+ const issues: SecurityIssue[] = [];
167
+
168
+ if (!target.dependencies) {
169
+ return issues;
170
+ }
171
+
172
+ // In a real implementation, this would:
173
+ // - Query npm audit API
174
+ // - Check GitHub Advisory Database
175
+ // - Check Snyk vulnerability database
176
+ // - Check OSV (Open Source Vulnerabilities)
177
+
178
+ for (const [depName, version] of Object.entries(target.dependencies)) {
179
+ const vulnKey = `${depName}@${version}`;
180
+ const vulnerability = this.vulnerabilityDb.get(vulnKey);
181
+
182
+ if (vulnerability) {
183
+ issues.push({
184
+ id: `vuln-${vulnerability.cve || depName}`,
185
+ severity: vulnerability.severity,
186
+ category: 'vulnerability',
187
+ title: `Vulnerable dependency: ${depName}`,
188
+ description: `${depName}@${version} has known security vulnerabilities`,
189
+ remediation: vulnerability.fixedIn
190
+ ? `Upgrade to ${vulnerability.fixedIn.join(' or ')}`
191
+ : 'No fix available',
192
+ cve: vulnerability.cve,
193
+ });
194
+ }
195
+ }
196
+
197
+ this.logger.debug('Dependency scan complete', {
198
+ pluginId: target.pluginId,
199
+ dependencies: Object.keys(target.dependencies).length,
200
+ vulnerabilities: issues.length
201
+ });
202
+
203
+ return issues;
204
+ }
205
+
206
+ /**
207
+ * Scan for malware patterns
208
+ */
209
+ private async scanMalware(target: ScanTarget): Promise<SecurityIssue[]> {
210
+ const issues: SecurityIssue[] = [];
211
+
212
+ // In a real implementation, this would:
213
+ // - Check for obfuscated code
214
+ // - Check for suspicious network activity patterns
215
+ // - Check for crypto mining patterns
216
+ // - Check for data exfiltration patterns
217
+ // - Use ML-based malware detection
218
+ // - Check file hashes against known malware databases
219
+
220
+ this.logger.debug('Malware scan complete', {
221
+ pluginId: target.pluginId,
222
+ issuesFound: issues.length
223
+ });
224
+
225
+ return issues;
226
+ }
227
+
228
+ /**
229
+ * Check license compliance
230
+ */
231
+ private async scanLicenses(target: ScanTarget): Promise<SecurityIssue[]> {
232
+ const issues: SecurityIssue[] = [];
233
+
234
+ if (!target.dependencies) {
235
+ return issues;
236
+ }
237
+
238
+ // In a real implementation, this would:
239
+ // - Check license compatibility
240
+ // - Detect GPL contamination
241
+ // - Flag proprietary dependencies
242
+ // - Check for missing licenses
243
+ // - Verify SPDX identifiers
244
+
245
+ this.logger.debug('License scan complete', {
246
+ pluginId: target.pluginId,
247
+ issuesFound: issues.length
248
+ });
249
+
250
+ return issues;
251
+ }
252
+
253
+ /**
254
+ * Check configuration security
255
+ */
256
+ private async scanConfiguration(target: ScanTarget): Promise<SecurityIssue[]> {
257
+ const issues: SecurityIssue[] = [];
258
+
259
+ // In a real implementation, this would:
260
+ // - Check for hardcoded secrets
261
+ // - Check for weak permissions
262
+ // - Check for insecure defaults
263
+ // - Check for missing security headers
264
+ // - Check CSP policies
265
+
266
+ this.logger.debug('Configuration scan complete', {
267
+ pluginId: target.pluginId,
268
+ issuesFound: issues.length
269
+ });
270
+
271
+ return issues;
272
+ }
273
+
274
+ /**
275
+ * Calculate security score based on issues
276
+ */
277
+ private calculateSecurityScore(issues: SecurityIssue[]): number {
278
+ // Start with perfect score
279
+ let score = 100;
280
+
281
+ // Deduct points based on severity
282
+ for (const issue of issues) {
283
+ switch (issue.severity) {
284
+ case 'critical':
285
+ score -= 20;
286
+ break;
287
+ case 'high':
288
+ score -= 10;
289
+ break;
290
+ case 'medium':
291
+ score -= 5;
292
+ break;
293
+ case 'low':
294
+ score -= 2;
295
+ break;
296
+ case 'info':
297
+ score -= 0;
298
+ break;
299
+ }
300
+ }
301
+
302
+ // Ensure score doesn't go below 0
303
+ return Math.max(0, score);
304
+ }
305
+
306
+ /**
307
+ * Add a vulnerability to the database
308
+ */
309
+ addVulnerability(
310
+ packageName: string,
311
+ version: string,
312
+ vulnerability: SecurityVulnerability
313
+ ): void {
314
+ const key = `${packageName}@${version}`;
315
+ this.vulnerabilityDb.set(key, vulnerability);
316
+
317
+ this.logger.debug('Vulnerability added to database', {
318
+ package: packageName,
319
+ version,
320
+ cve: vulnerability.cve
321
+ });
322
+ }
323
+
324
+ /**
325
+ * Get scan result from cache
326
+ */
327
+ getScanResult(pluginId: string, version: string): SecurityScanResult | undefined {
328
+ return this.scanResults.get(`${pluginId}:${version}`);
329
+ }
330
+
331
+ /**
332
+ * Clear scan results cache
333
+ */
334
+ clearCache(): void {
335
+ this.scanResults.clear();
336
+ this.logger.debug('Scan results cache cleared');
337
+ }
338
+
339
+ /**
340
+ * Update vulnerability database from external source
341
+ */
342
+ async updateVulnerabilityDatabase(): Promise<void> {
343
+ this.logger.info('Updating vulnerability database');
344
+
345
+ // In a real implementation, this would:
346
+ // - Fetch from GitHub Advisory Database
347
+ // - Fetch from npm audit
348
+ // - Fetch from NVD (National Vulnerability Database)
349
+ // - Parse and cache vulnerability data
350
+
351
+ this.logger.info('Vulnerability database updated', {
352
+ entries: this.vulnerabilityDb.size
353
+ });
354
+ }
355
+
356
+ /**
357
+ * Shutdown security scanner
358
+ */
359
+ shutdown(): void {
360
+ this.vulnerabilityDb.clear();
361
+ this.scanResults.clear();
362
+
363
+ this.logger.info('Security scanner shutdown complete');
364
+ }
365
+ }
@@ -1,103 +0,0 @@
1
- import { Plugin } from './types.js';
2
- import type { LoggerConfig } from '@objectstack/spec/system';
3
- import { ServiceLifecycle, ServiceFactory } from './plugin-loader.js';
4
- /**
5
- * Enhanced Kernel Configuration
6
- */
7
- export interface EnhancedKernelConfig {
8
- logger?: Partial<LoggerConfig>;
9
- /** Default plugin startup timeout in milliseconds */
10
- defaultStartupTimeout?: number;
11
- /** Whether to enable graceful shutdown */
12
- gracefulShutdown?: boolean;
13
- /** Graceful shutdown timeout in milliseconds */
14
- shutdownTimeout?: number;
15
- /** Whether to rollback on startup failure */
16
- rollbackOnFailure?: boolean;
17
- }
18
- /**
19
- * Enhanced ObjectKernel with Advanced Plugin Management
20
- *
21
- * Extends the basic ObjectKernel with:
22
- * - Async plugin loading with validation
23
- * - Version compatibility checking
24
- * - Plugin signature verification
25
- * - Configuration validation (Zod)
26
- * - Factory-based dependency injection
27
- * - Service lifecycle management (singleton/transient/scoped)
28
- * - Circular dependency detection
29
- * - Lazy loading services
30
- * - Graceful shutdown
31
- * - Plugin startup timeout control
32
- * - Startup failure rollback
33
- * - Plugin health checks
34
- */
35
- export declare class EnhancedObjectKernel {
36
- private plugins;
37
- private services;
38
- private hooks;
39
- private state;
40
- private logger;
41
- private context;
42
- private pluginLoader;
43
- private config;
44
- private startedPlugins;
45
- private pluginStartTimes;
46
- private shutdownHandlers;
47
- constructor(config?: EnhancedKernelConfig);
48
- /**
49
- * Register a plugin with enhanced validation
50
- */
51
- use(plugin: Plugin): Promise<this>;
52
- /**
53
- * Register a service factory with lifecycle management
54
- */
55
- registerServiceFactory<T>(name: string, factory: ServiceFactory<T>, lifecycle?: ServiceLifecycle, dependencies?: string[]): this;
56
- /**
57
- * Bootstrap the kernel with enhanced features
58
- */
59
- bootstrap(): Promise<void>;
60
- /**
61
- * Graceful shutdown with timeout
62
- */
63
- shutdown(): Promise<void>;
64
- /**
65
- * Check health of a specific plugin
66
- */
67
- checkPluginHealth(pluginName: string): Promise<any>;
68
- /**
69
- * Check health of all plugins
70
- */
71
- checkAllPluginsHealth(): Promise<Map<string, any>>;
72
- /**
73
- * Get plugin startup metrics
74
- */
75
- getPluginMetrics(): Map<string, number>;
76
- /**
77
- * Get a service (sync helper)
78
- */
79
- getService<T>(name: string): T;
80
- /**
81
- * Get a service asynchronously (supports factories)
82
- */
83
- getServiceAsync<T>(name: string, scopeId?: string): Promise<T>;
84
- /**
85
- * Check if kernel is running
86
- */
87
- isRunning(): boolean;
88
- /**
89
- * Get kernel state
90
- */
91
- getState(): string;
92
- private initPluginWithTimeout;
93
- private startPluginWithTimeout;
94
- private rollbackStartedPlugins;
95
- private performShutdown;
96
- private resolveDependencies;
97
- private registerShutdownSignals;
98
- /**
99
- * Register a custom shutdown handler
100
- */
101
- onShutdown(handler: () => Promise<void>): void;
102
- }
103
- //# sourceMappingURL=enhanced-kernel.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"enhanced-kernel.d.ts","sourceRoot":"","sources":["../src/enhanced-kernel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAgC,gBAAgB,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAEzH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAE/B,qDAAqD;IACrD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,oBAAoB;IAC7B,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAA2E;IACxF,OAAO,CAAC,KAAK,CAAwE;IACrF,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,gBAAgB,CAAkC;gBAE9C,MAAM,GAAE,oBAAyB;IAgE7C;;OAEG;IACG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBxC;;OAEG;IACH,sBAAsB,CAAC,CAAC,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAC1B,SAAS,GAAE,gBAA6C,EACxD,YAAY,CAAC,EAAE,MAAM,EAAE,GACxB,IAAI;IAUP;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAqDhC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAqC/B;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzD;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAWxD;;OAEG;IACH,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAIvC;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC;IAI9B;;OAEG;IACG,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,QAAQ,IAAI,MAAM;YAMJ,qBAAqB;YAerB,sBAAsB;YA6CtB,sBAAsB;YAkBtB,eAAe;IA2B7B,OAAO,CAAC,mBAAmB;IAyC3B,OAAO,CAAC,uBAAuB;IA2B/B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;CAGjD"}