driftdetect-core 0.1.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/dist/analyzers/ast-analyzer.d.ts +251 -0
- package/dist/analyzers/ast-analyzer.d.ts.map +1 -0
- package/dist/analyzers/ast-analyzer.js +548 -0
- package/dist/analyzers/ast-analyzer.js.map +1 -0
- package/dist/analyzers/flow-analyzer.d.ts +241 -0
- package/dist/analyzers/flow-analyzer.d.ts.map +1 -0
- package/dist/analyzers/flow-analyzer.js +1219 -0
- package/dist/analyzers/flow-analyzer.js.map +1 -0
- package/dist/analyzers/index.d.ts +18 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +19 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/semantic-analyzer.d.ts +252 -0
- package/dist/analyzers/semantic-analyzer.d.ts.map +1 -0
- package/dist/analyzers/semantic-analyzer.js +1182 -0
- package/dist/analyzers/semantic-analyzer.js.map +1 -0
- package/dist/analyzers/type-analyzer.d.ts +289 -0
- package/dist/analyzers/type-analyzer.d.ts.map +1 -0
- package/dist/analyzers/type-analyzer.js +1269 -0
- package/dist/analyzers/type-analyzer.js.map +1 -0
- package/dist/analyzers/types.d.ts +537 -0
- package/dist/analyzers/types.d.ts.map +1 -0
- package/dist/analyzers/types.js +11 -0
- package/dist/analyzers/types.js.map +1 -0
- package/dist/config/config-loader.d.ts +166 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +429 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config/config-validator.d.ts +204 -0
- package/dist/config/config-validator.d.ts.map +1 -0
- package/dist/config/config-validator.js +632 -0
- package/dist/config/config-validator.js.map +1 -0
- package/dist/config/defaults.d.ts +8 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +26 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +10 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +10 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +47 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +7 -0
- package/dist/config/types.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest/exporter.d.ts +21 -0
- package/dist/manifest/exporter.d.ts.map +1 -0
- package/dist/manifest/exporter.js +339 -0
- package/dist/manifest/exporter.js.map +1 -0
- package/dist/manifest/index.d.ts +14 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +15 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/manifest-store.d.ts +111 -0
- package/dist/manifest/manifest-store.d.ts.map +1 -0
- package/dist/manifest/manifest-store.js +418 -0
- package/dist/manifest/manifest-store.js.map +1 -0
- package/dist/manifest/types.d.ts +238 -0
- package/dist/manifest/types.d.ts.map +1 -0
- package/dist/manifest/types.js +11 -0
- package/dist/manifest/types.js.map +1 -0
- package/dist/matcher/confidence-scorer.d.ts +188 -0
- package/dist/matcher/confidence-scorer.d.ts.map +1 -0
- package/dist/matcher/confidence-scorer.js +302 -0
- package/dist/matcher/confidence-scorer.js.map +1 -0
- package/dist/matcher/index.d.ts +24 -0
- package/dist/matcher/index.d.ts.map +1 -0
- package/dist/matcher/index.js +26 -0
- package/dist/matcher/index.js.map +1 -0
- package/dist/matcher/outlier-detector.d.ts +252 -0
- package/dist/matcher/outlier-detector.d.ts.map +1 -0
- package/dist/matcher/outlier-detector.js +544 -0
- package/dist/matcher/outlier-detector.js.map +1 -0
- package/dist/matcher/pattern-matcher.d.ts +169 -0
- package/dist/matcher/pattern-matcher.d.ts.map +1 -0
- package/dist/matcher/pattern-matcher.js +692 -0
- package/dist/matcher/pattern-matcher.js.map +1 -0
- package/dist/matcher/types.d.ts +476 -0
- package/dist/matcher/types.d.ts.map +1 -0
- package/dist/matcher/types.js +36 -0
- package/dist/matcher/types.js.map +1 -0
- package/dist/parsers/base-parser.d.ts +282 -0
- package/dist/parsers/base-parser.d.ts.map +1 -0
- package/dist/parsers/base-parser.js +421 -0
- package/dist/parsers/base-parser.js.map +1 -0
- package/dist/parsers/css-parser.d.ts +225 -0
- package/dist/parsers/css-parser.d.ts.map +1 -0
- package/dist/parsers/css-parser.js +477 -0
- package/dist/parsers/css-parser.js.map +1 -0
- package/dist/parsers/index.d.ts +15 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +15 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/json-parser.d.ts +219 -0
- package/dist/parsers/json-parser.d.ts.map +1 -0
- package/dist/parsers/json-parser.js +602 -0
- package/dist/parsers/json-parser.js.map +1 -0
- package/dist/parsers/markdown-parser.d.ts +276 -0
- package/dist/parsers/markdown-parser.d.ts.map +1 -0
- package/dist/parsers/markdown-parser.js +731 -0
- package/dist/parsers/markdown-parser.js.map +1 -0
- package/dist/parsers/parser-manager.d.ts +294 -0
- package/dist/parsers/parser-manager.d.ts.map +1 -0
- package/dist/parsers/parser-manager.js +738 -0
- package/dist/parsers/parser-manager.js.map +1 -0
- package/dist/parsers/python-parser.d.ts +204 -0
- package/dist/parsers/python-parser.d.ts.map +1 -0
- package/dist/parsers/python-parser.js +517 -0
- package/dist/parsers/python-parser.js.map +1 -0
- package/dist/parsers/types.d.ts +43 -0
- package/dist/parsers/types.d.ts.map +1 -0
- package/dist/parsers/types.js +7 -0
- package/dist/parsers/types.js.map +1 -0
- package/dist/parsers/typescript-parser.d.ts +264 -0
- package/dist/parsers/typescript-parser.d.ts.map +1 -0
- package/dist/parsers/typescript-parser.js +658 -0
- package/dist/parsers/typescript-parser.js.map +1 -0
- package/dist/rules/evaluator.d.ts +305 -0
- package/dist/rules/evaluator.d.ts.map +1 -0
- package/dist/rules/evaluator.js +579 -0
- package/dist/rules/evaluator.js.map +1 -0
- package/dist/rules/index.d.ts +13 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +13 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/quick-fix-generator.d.ts +334 -0
- package/dist/rules/quick-fix-generator.d.ts.map +1 -0
- package/dist/rules/quick-fix-generator.js +1075 -0
- package/dist/rules/quick-fix-generator.js.map +1 -0
- package/dist/rules/rule-engine.d.ts +241 -0
- package/dist/rules/rule-engine.d.ts.map +1 -0
- package/dist/rules/rule-engine.js +585 -0
- package/dist/rules/rule-engine.js.map +1 -0
- package/dist/rules/severity-manager.d.ts +394 -0
- package/dist/rules/severity-manager.d.ts.map +1 -0
- package/dist/rules/severity-manager.js +619 -0
- package/dist/rules/severity-manager.js.map +1 -0
- package/dist/rules/types.d.ts +370 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +133 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/rules/variant-manager.d.ts +388 -0
- package/dist/rules/variant-manager.d.ts.map +1 -0
- package/dist/rules/variant-manager.js +777 -0
- package/dist/rules/variant-manager.js.map +1 -0
- package/dist/scanner/change-detector.d.ts +164 -0
- package/dist/scanner/change-detector.d.ts.map +1 -0
- package/dist/scanner/change-detector.js +263 -0
- package/dist/scanner/change-detector.js.map +1 -0
- package/dist/scanner/dependency-graph.d.ts +270 -0
- package/dist/scanner/dependency-graph.d.ts.map +1 -0
- package/dist/scanner/dependency-graph.js +436 -0
- package/dist/scanner/dependency-graph.js.map +1 -0
- package/dist/scanner/file-walker.d.ts +127 -0
- package/dist/scanner/file-walker.d.ts.map +1 -0
- package/dist/scanner/file-walker.js +526 -0
- package/dist/scanner/file-walker.js.map +1 -0
- package/dist/scanner/index.d.ts +12 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +12 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/types.d.ts +218 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +10 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/scanner/worker-pool.d.ts +317 -0
- package/dist/scanner/worker-pool.d.ts.map +1 -0
- package/dist/scanner/worker-pool.js +571 -0
- package/dist/scanner/worker-pool.js.map +1 -0
- package/dist/store/cache-manager.d.ts +179 -0
- package/dist/store/cache-manager.d.ts.map +1 -0
- package/dist/store/cache-manager.js +391 -0
- package/dist/store/cache-manager.js.map +1 -0
- package/dist/store/history-store.d.ts +314 -0
- package/dist/store/history-store.d.ts.map +1 -0
- package/dist/store/history-store.js +707 -0
- package/dist/store/history-store.js.map +1 -0
- package/dist/store/index.d.ts +20 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +26 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/lock-file-manager.d.ts +202 -0
- package/dist/store/lock-file-manager.d.ts.map +1 -0
- package/dist/store/lock-file-manager.js +475 -0
- package/dist/store/lock-file-manager.js.map +1 -0
- package/dist/store/pattern-store.d.ts +289 -0
- package/dist/store/pattern-store.d.ts.map +1 -0
- package/dist/store/pattern-store.js +936 -0
- package/dist/store/pattern-store.js.map +1 -0
- package/dist/store/schema-validator.d.ts +159 -0
- package/dist/store/schema-validator.d.ts.map +1 -0
- package/dist/store/schema-validator.js +1096 -0
- package/dist/store/schema-validator.js.map +1 -0
- package/dist/store/types.d.ts +585 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +82 -0
- package/dist/store/types.js.map +1 -0
- package/dist/types/analysis.d.ts +19 -0
- package/dist/types/analysis.d.ts.map +1 -0
- package/dist/types/analysis.js +5 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/types/common.d.ts +7 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +5 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +10 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/patterns.d.ts +40 -0
- package/dist/types/patterns.d.ts.map +1 -0
- package/dist/types/patterns.js +7 -0
- package/dist/types/patterns.js.map +1 -0
- package/dist/types/violations.d.ts +7 -0
- package/dist/types/violations.d.ts.map +1 -0
- package/dist/types/violations.js +7 -0
- package/dist/types/violations.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker Pool - Parallel file processing with configurable concurrency
|
|
3
|
+
*
|
|
4
|
+
* Provides a task queue-based worker pool for parallel file processing,
|
|
5
|
+
* with support for configurable worker count, task distribution,
|
|
6
|
+
* error handling, and graceful shutdown.
|
|
7
|
+
*
|
|
8
|
+
* @requirements 2.6 - THE Scanner SHALL process files in parallel using worker threads
|
|
9
|
+
*/
|
|
10
|
+
import { EventEmitter } from 'node:events';
|
|
11
|
+
/**
|
|
12
|
+
* Default options for the worker pool
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_CPU_COUNT = 4;
|
|
15
|
+
/**
|
|
16
|
+
* Get default options synchronously
|
|
17
|
+
*/
|
|
18
|
+
function getDefaultOptions() {
|
|
19
|
+
let cpuCount = DEFAULT_CPU_COUNT;
|
|
20
|
+
try {
|
|
21
|
+
// Dynamic import for Node.js os module
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
23
|
+
const os = require('node:os');
|
|
24
|
+
cpuCount = os.cpus().length || DEFAULT_CPU_COUNT;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Fallback for non-Node environments
|
|
28
|
+
cpuCount = DEFAULT_CPU_COUNT;
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
minWorkers: 1,
|
|
32
|
+
maxWorkers: cpuCount,
|
|
33
|
+
taskTimeout: 30000,
|
|
34
|
+
maxRetries: 2,
|
|
35
|
+
enableCaching: false,
|
|
36
|
+
maxQueueSize: 0,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* WorkerPool class for parallel task processing
|
|
41
|
+
*
|
|
42
|
+
* Implements a configurable worker pool that processes tasks in parallel
|
|
43
|
+
* with support for task queuing, retries, timeouts, and graceful shutdown.
|
|
44
|
+
*
|
|
45
|
+
* @requirements 2.6 - Parallel file processing with configurable worker count
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const pool = new WorkerPool<string, ParseResult>({
|
|
50
|
+
* maxWorkers: 4,
|
|
51
|
+
* taskTimeout: 10000,
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* pool.setProcessor(async (filePath) => {
|
|
55
|
+
* return await parseFile(filePath);
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* const results = await pool.processBatch(['file1.ts', 'file2.ts']);
|
|
59
|
+
* await pool.shutdown();
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export class WorkerPool extends EventEmitter {
|
|
63
|
+
options;
|
|
64
|
+
taskQueue = [];
|
|
65
|
+
activeTasks = new Map();
|
|
66
|
+
completedTasks = new Map();
|
|
67
|
+
processor = null;
|
|
68
|
+
taskIdCounter = 0;
|
|
69
|
+
isShuttingDown = false;
|
|
70
|
+
isPaused = false;
|
|
71
|
+
totalDuration = 0;
|
|
72
|
+
completedCount = 0;
|
|
73
|
+
failedCount = 0;
|
|
74
|
+
cancelledCount = 0;
|
|
75
|
+
timedOutCount = 0;
|
|
76
|
+
taskTimeouts = new Map();
|
|
77
|
+
cache = new Map();
|
|
78
|
+
constructor(options = {}) {
|
|
79
|
+
super();
|
|
80
|
+
const defaults = getDefaultOptions();
|
|
81
|
+
this.options = { ...defaults, ...options };
|
|
82
|
+
// Validate options
|
|
83
|
+
if (this.options.minWorkers < 1) {
|
|
84
|
+
this.options.minWorkers = 1;
|
|
85
|
+
}
|
|
86
|
+
if (this.options.maxWorkers < this.options.minWorkers) {
|
|
87
|
+
this.options.maxWorkers = this.options.minWorkers;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Set the task processor function
|
|
92
|
+
*
|
|
93
|
+
* @param processor - Function that processes a single task input
|
|
94
|
+
*/
|
|
95
|
+
setProcessor(processor) {
|
|
96
|
+
this.processor = processor;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Add a single task to the queue
|
|
100
|
+
*
|
|
101
|
+
* @param input - Input data for the task
|
|
102
|
+
* @param priority - Task priority (higher = processed first)
|
|
103
|
+
* @returns The created task
|
|
104
|
+
*/
|
|
105
|
+
addTask(input, priority = 0) {
|
|
106
|
+
if (this.isShuttingDown) {
|
|
107
|
+
throw new Error('Cannot add tasks while shutting down');
|
|
108
|
+
}
|
|
109
|
+
if (this.options.maxQueueSize > 0 && this.taskQueue.length >= this.options.maxQueueSize) {
|
|
110
|
+
throw new Error(`Task queue is full (max: ${this.options.maxQueueSize})`);
|
|
111
|
+
}
|
|
112
|
+
const task = {
|
|
113
|
+
id: this.generateTaskId(),
|
|
114
|
+
input,
|
|
115
|
+
status: 'pending',
|
|
116
|
+
retries: 0,
|
|
117
|
+
createdAt: new Date(),
|
|
118
|
+
priority,
|
|
119
|
+
};
|
|
120
|
+
// Insert task in priority order (higher priority first)
|
|
121
|
+
const insertIndex = this.taskQueue.findIndex((t) => t.priority < priority);
|
|
122
|
+
if (insertIndex === -1) {
|
|
123
|
+
this.taskQueue.push(task);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.taskQueue.splice(insertIndex, 0, task);
|
|
127
|
+
}
|
|
128
|
+
this.emit('taskQueued', task);
|
|
129
|
+
this.processQueue();
|
|
130
|
+
return task;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Add multiple tasks to the queue
|
|
134
|
+
*
|
|
135
|
+
* @param inputs - Array of input data for tasks
|
|
136
|
+
* @param priority - Priority for all tasks
|
|
137
|
+
* @returns Array of created tasks
|
|
138
|
+
*/
|
|
139
|
+
addTasks(inputs, priority = 0) {
|
|
140
|
+
return inputs.map((input) => this.addTask(input, priority));
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Process a batch of inputs and wait for all results
|
|
144
|
+
*
|
|
145
|
+
* @param inputs - Array of input data to process
|
|
146
|
+
* @param priority - Priority for all tasks
|
|
147
|
+
* @returns Promise resolving to array of task results
|
|
148
|
+
*/
|
|
149
|
+
async processBatch(inputs, priority = 0) {
|
|
150
|
+
if (!this.processor) {
|
|
151
|
+
throw new Error('No processor set. Call setProcessor() first.');
|
|
152
|
+
}
|
|
153
|
+
const tasks = this.addTasks(inputs, priority);
|
|
154
|
+
const taskIds = new Set(tasks.map((t) => t.id));
|
|
155
|
+
return new Promise((resolve) => {
|
|
156
|
+
const results = [];
|
|
157
|
+
const checkComplete = () => {
|
|
158
|
+
// Collect results for our tasks
|
|
159
|
+
for (const taskId of taskIds) {
|
|
160
|
+
const task = this.completedTasks.get(taskId);
|
|
161
|
+
if (task && !results.some((r) => r.taskId === taskId)) {
|
|
162
|
+
results.push(this.taskToResult(task));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Check if all tasks are complete
|
|
166
|
+
if (results.length === tasks.length) {
|
|
167
|
+
// Clean up listeners
|
|
168
|
+
this.off('taskCompleted', onTaskComplete);
|
|
169
|
+
this.off('taskFailed', onTaskFailed);
|
|
170
|
+
this.off('taskTimeout', onTaskTimeout);
|
|
171
|
+
resolve(results);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const onTaskComplete = (task) => {
|
|
175
|
+
if (taskIds.has(task.id)) {
|
|
176
|
+
checkComplete();
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
const onTaskFailed = (task) => {
|
|
180
|
+
if (taskIds.has(task.id)) {
|
|
181
|
+
checkComplete();
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
const onTaskTimeout = (task) => {
|
|
185
|
+
if (taskIds.has(task.id)) {
|
|
186
|
+
checkComplete();
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
this.on('taskCompleted', onTaskComplete);
|
|
190
|
+
this.on('taskFailed', onTaskFailed);
|
|
191
|
+
this.on('taskTimeout', onTaskTimeout);
|
|
192
|
+
// Check if any tasks are already complete
|
|
193
|
+
checkComplete();
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Cancel a specific task
|
|
198
|
+
*
|
|
199
|
+
* @param taskId - ID of the task to cancel
|
|
200
|
+
* @returns True if the task was cancelled
|
|
201
|
+
*/
|
|
202
|
+
cancelTask(taskId) {
|
|
203
|
+
// Check if task is in queue
|
|
204
|
+
const queueIndex = this.taskQueue.findIndex((t) => t.id === taskId);
|
|
205
|
+
if (queueIndex !== -1) {
|
|
206
|
+
const task = this.taskQueue[queueIndex];
|
|
207
|
+
if (task) {
|
|
208
|
+
task.status = 'cancelled';
|
|
209
|
+
task.completedAt = new Date();
|
|
210
|
+
this.taskQueue.splice(queueIndex, 1);
|
|
211
|
+
this.completedTasks.set(taskId, task);
|
|
212
|
+
this.cancelledCount++;
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Check if task is active (cannot cancel running tasks)
|
|
217
|
+
if (this.activeTasks.has(taskId)) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Cancel all pending tasks
|
|
224
|
+
*
|
|
225
|
+
* @returns Number of tasks cancelled
|
|
226
|
+
*/
|
|
227
|
+
cancelAllPending() {
|
|
228
|
+
let cancelled = 0;
|
|
229
|
+
while (this.taskQueue.length > 0) {
|
|
230
|
+
const task = this.taskQueue.shift();
|
|
231
|
+
if (task) {
|
|
232
|
+
task.status = 'cancelled';
|
|
233
|
+
task.completedAt = new Date();
|
|
234
|
+
this.completedTasks.set(task.id, task);
|
|
235
|
+
this.cancelledCount++;
|
|
236
|
+
cancelled++;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return cancelled;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Pause task processing
|
|
243
|
+
*/
|
|
244
|
+
pause() {
|
|
245
|
+
this.isPaused = true;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Resume task processing
|
|
249
|
+
*/
|
|
250
|
+
resume() {
|
|
251
|
+
this.isPaused = false;
|
|
252
|
+
this.processQueue();
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get the current status of a task
|
|
256
|
+
*
|
|
257
|
+
* @param taskId - ID of the task
|
|
258
|
+
* @returns Task or undefined if not found
|
|
259
|
+
*/
|
|
260
|
+
getTask(taskId) {
|
|
261
|
+
// Check active tasks
|
|
262
|
+
const active = this.activeTasks.get(taskId);
|
|
263
|
+
if (active)
|
|
264
|
+
return active;
|
|
265
|
+
// Check completed tasks
|
|
266
|
+
const completed = this.completedTasks.get(taskId);
|
|
267
|
+
if (completed)
|
|
268
|
+
return completed;
|
|
269
|
+
// Check queue
|
|
270
|
+
return this.taskQueue.find((t) => t.id === taskId);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Get current worker pool statistics
|
|
274
|
+
*
|
|
275
|
+
* @returns WorkerPoolStats object
|
|
276
|
+
*/
|
|
277
|
+
getStats() {
|
|
278
|
+
return {
|
|
279
|
+
queuedTasks: this.taskQueue.length,
|
|
280
|
+
activeTasks: this.activeTasks.size,
|
|
281
|
+
completedTasks: this.completedCount,
|
|
282
|
+
failedTasks: this.failedCount,
|
|
283
|
+
cancelledTasks: this.cancelledCount,
|
|
284
|
+
timedOutTasks: this.timedOutCount,
|
|
285
|
+
averageDuration: this.completedCount > 0 ? this.totalDuration / this.completedCount : 0,
|
|
286
|
+
activeWorkers: this.activeTasks.size,
|
|
287
|
+
maxWorkers: this.options.maxWorkers,
|
|
288
|
+
isShuttingDown: this.isShuttingDown,
|
|
289
|
+
isPaused: this.isPaused,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Wait for all current tasks to complete
|
|
294
|
+
*
|
|
295
|
+
* @returns Promise that resolves when all tasks are done
|
|
296
|
+
*/
|
|
297
|
+
async drain() {
|
|
298
|
+
if (this.taskQueue.length === 0 && this.activeTasks.size === 0) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
return new Promise((resolve) => {
|
|
302
|
+
const checkDrained = () => {
|
|
303
|
+
if (this.taskQueue.length === 0 && this.activeTasks.size === 0) {
|
|
304
|
+
this.off('taskCompleted', checkDrained);
|
|
305
|
+
this.off('taskFailed', checkDrained);
|
|
306
|
+
this.off('taskTimeout', checkDrained);
|
|
307
|
+
this.emit('drained');
|
|
308
|
+
resolve();
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
this.on('taskCompleted', checkDrained);
|
|
312
|
+
this.on('taskFailed', checkDrained);
|
|
313
|
+
this.on('taskTimeout', checkDrained);
|
|
314
|
+
checkDrained();
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Gracefully shutdown the worker pool
|
|
319
|
+
*
|
|
320
|
+
* Waits for active tasks to complete, cancels pending tasks,
|
|
321
|
+
* and cleans up resources.
|
|
322
|
+
*
|
|
323
|
+
* @param timeout - Maximum time to wait for active tasks (ms)
|
|
324
|
+
* @returns Promise that resolves when shutdown is complete
|
|
325
|
+
*/
|
|
326
|
+
async shutdown(timeout = 30000) {
|
|
327
|
+
if (this.isShuttingDown) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
this.isShuttingDown = true;
|
|
331
|
+
// Cancel all pending tasks
|
|
332
|
+
this.cancelAllPending();
|
|
333
|
+
// Wait for active tasks to complete (with timeout)
|
|
334
|
+
if (this.activeTasks.size > 0) {
|
|
335
|
+
const shutdownPromise = new Promise((resolve) => {
|
|
336
|
+
const checkComplete = () => {
|
|
337
|
+
if (this.activeTasks.size === 0) {
|
|
338
|
+
this.off('taskCompleted', checkComplete);
|
|
339
|
+
this.off('taskFailed', checkComplete);
|
|
340
|
+
this.off('taskTimeout', checkComplete);
|
|
341
|
+
resolve();
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
this.on('taskCompleted', checkComplete);
|
|
345
|
+
this.on('taskFailed', checkComplete);
|
|
346
|
+
this.on('taskTimeout', checkComplete);
|
|
347
|
+
});
|
|
348
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
349
|
+
setTimeout(() => {
|
|
350
|
+
// Force cancel remaining active tasks
|
|
351
|
+
for (const [taskId, task] of this.activeTasks) {
|
|
352
|
+
task.status = 'cancelled';
|
|
353
|
+
task.completedAt = new Date();
|
|
354
|
+
this.completedTasks.set(taskId, task);
|
|
355
|
+
this.cancelledCount++;
|
|
356
|
+
// Clear timeout
|
|
357
|
+
const timeoutId = this.taskTimeouts.get(taskId);
|
|
358
|
+
if (timeoutId) {
|
|
359
|
+
clearTimeout(timeoutId);
|
|
360
|
+
this.taskTimeouts.delete(taskId);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
this.activeTasks.clear();
|
|
364
|
+
resolve();
|
|
365
|
+
}, timeout);
|
|
366
|
+
});
|
|
367
|
+
await Promise.race([shutdownPromise, timeoutPromise]);
|
|
368
|
+
}
|
|
369
|
+
// Clear all timeouts
|
|
370
|
+
for (const timeoutId of this.taskTimeouts.values()) {
|
|
371
|
+
clearTimeout(timeoutId);
|
|
372
|
+
}
|
|
373
|
+
this.taskTimeouts.clear();
|
|
374
|
+
// Clear cache
|
|
375
|
+
this.cache.clear();
|
|
376
|
+
// Emit idle event
|
|
377
|
+
this.emit('idle');
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Clear the result cache
|
|
381
|
+
*/
|
|
382
|
+
clearCache() {
|
|
383
|
+
this.cache.clear();
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Get the number of items in the cache
|
|
387
|
+
*/
|
|
388
|
+
getCacheSize() {
|
|
389
|
+
return this.cache.size;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Process tasks from the queue
|
|
393
|
+
*/
|
|
394
|
+
processQueue() {
|
|
395
|
+
if (this.isPaused || this.isShuttingDown || !this.processor) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
// Process tasks up to maxWorkers limit
|
|
399
|
+
while (this.taskQueue.length > 0 &&
|
|
400
|
+
this.activeTasks.size < this.options.maxWorkers) {
|
|
401
|
+
const task = this.taskQueue.shift();
|
|
402
|
+
if (task) {
|
|
403
|
+
this.processTask(task);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
// Check if idle
|
|
407
|
+
if (this.taskQueue.length === 0 && this.activeTasks.size === 0) {
|
|
408
|
+
this.emit('idle');
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Process a single task
|
|
413
|
+
*/
|
|
414
|
+
async processTask(task) {
|
|
415
|
+
if (!this.processor) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
task.status = 'running';
|
|
419
|
+
task.startedAt = new Date();
|
|
420
|
+
this.activeTasks.set(task.id, task);
|
|
421
|
+
this.emit('taskStarted', task);
|
|
422
|
+
// Check cache
|
|
423
|
+
if (this.options.enableCaching) {
|
|
424
|
+
const cacheKey = this.getCacheKey(task.input);
|
|
425
|
+
const cached = this.cache.get(cacheKey);
|
|
426
|
+
if (cached !== undefined) {
|
|
427
|
+
this.completeTask(task, cached);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
// Set up timeout
|
|
432
|
+
const timeoutId = setTimeout(() => {
|
|
433
|
+
this.handleTaskTimeout(task);
|
|
434
|
+
}, this.options.taskTimeout);
|
|
435
|
+
this.taskTimeouts.set(task.id, timeoutId);
|
|
436
|
+
try {
|
|
437
|
+
const result = await this.processor(task.input);
|
|
438
|
+
// Clear timeout
|
|
439
|
+
clearTimeout(timeoutId);
|
|
440
|
+
this.taskTimeouts.delete(task.id);
|
|
441
|
+
// Check if task was cancelled or timed out while processing
|
|
442
|
+
if (task.status !== 'running') {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
this.completeTask(task, result);
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
// Clear timeout
|
|
449
|
+
clearTimeout(timeoutId);
|
|
450
|
+
this.taskTimeouts.delete(task.id);
|
|
451
|
+
// Check if task was cancelled or timed out while processing
|
|
452
|
+
if (task.status !== 'running') {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
this.handleTaskError(task, error);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Complete a task successfully
|
|
460
|
+
*/
|
|
461
|
+
completeTask(task, result) {
|
|
462
|
+
task.status = 'completed';
|
|
463
|
+
task.completedAt = new Date();
|
|
464
|
+
task.result = result;
|
|
465
|
+
const duration = task.completedAt.getTime() - (task.startedAt?.getTime() || task.createdAt.getTime());
|
|
466
|
+
this.totalDuration += duration;
|
|
467
|
+
this.completedCount++;
|
|
468
|
+
// Cache result
|
|
469
|
+
if (this.options.enableCaching) {
|
|
470
|
+
const cacheKey = this.getCacheKey(task.input);
|
|
471
|
+
this.cache.set(cacheKey, result);
|
|
472
|
+
}
|
|
473
|
+
this.activeTasks.delete(task.id);
|
|
474
|
+
this.completedTasks.set(task.id, task);
|
|
475
|
+
this.emit('taskCompleted', task, result);
|
|
476
|
+
this.processQueue();
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Handle a task error
|
|
480
|
+
*/
|
|
481
|
+
handleTaskError(task, error) {
|
|
482
|
+
task.retries++;
|
|
483
|
+
// Check if we should retry
|
|
484
|
+
if (task.retries <= this.options.maxRetries) {
|
|
485
|
+
task.status = 'pending';
|
|
486
|
+
this.activeTasks.delete(task.id);
|
|
487
|
+
// Re-add to front of queue for retry
|
|
488
|
+
this.taskQueue.unshift(task);
|
|
489
|
+
this.emit('taskRetried', task, task.retries);
|
|
490
|
+
// Use setImmediate to avoid stack overflow on rapid retries
|
|
491
|
+
setImmediate(() => this.processQueue());
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
// Task failed after all retries
|
|
495
|
+
task.status = 'failed';
|
|
496
|
+
task.completedAt = new Date();
|
|
497
|
+
task.error = error.message;
|
|
498
|
+
this.failedCount++;
|
|
499
|
+
this.activeTasks.delete(task.id);
|
|
500
|
+
this.completedTasks.set(task.id, task);
|
|
501
|
+
this.emit('taskFailed', task, error);
|
|
502
|
+
// Use setImmediate to process queue after error handling
|
|
503
|
+
setImmediate(() => this.processQueue());
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Handle a task timeout
|
|
507
|
+
*/
|
|
508
|
+
handleTaskTimeout(task) {
|
|
509
|
+
// Only handle if task is still running
|
|
510
|
+
if (task.status !== 'running') {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
task.status = 'timeout';
|
|
514
|
+
task.completedAt = new Date();
|
|
515
|
+
task.error = `Task timed out after ${this.options.taskTimeout}ms`;
|
|
516
|
+
this.timedOutCount++;
|
|
517
|
+
this.taskTimeouts.delete(task.id);
|
|
518
|
+
this.activeTasks.delete(task.id);
|
|
519
|
+
this.completedTasks.set(task.id, task);
|
|
520
|
+
this.emit('taskTimeout', task);
|
|
521
|
+
this.processQueue();
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Generate a unique task ID
|
|
525
|
+
*/
|
|
526
|
+
generateTaskId() {
|
|
527
|
+
return `task-${++this.taskIdCounter}-${Date.now()}`;
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Generate a cache key for an input
|
|
531
|
+
*/
|
|
532
|
+
getCacheKey(input) {
|
|
533
|
+
return JSON.stringify(input);
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Convert a task to a TaskResult
|
|
537
|
+
*/
|
|
538
|
+
taskToResult(task) {
|
|
539
|
+
const duration = task.completedAt && task.startedAt
|
|
540
|
+
? task.completedAt.getTime() - task.startedAt.getTime()
|
|
541
|
+
: 0;
|
|
542
|
+
const result = {
|
|
543
|
+
taskId: task.id,
|
|
544
|
+
success: task.status === 'completed',
|
|
545
|
+
duration,
|
|
546
|
+
retries: task.retries,
|
|
547
|
+
};
|
|
548
|
+
if (task.result !== undefined) {
|
|
549
|
+
result.result = task.result;
|
|
550
|
+
}
|
|
551
|
+
if (task.error !== undefined) {
|
|
552
|
+
result.error = task.error;
|
|
553
|
+
}
|
|
554
|
+
return result;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Create a worker pool for file processing
|
|
559
|
+
*
|
|
560
|
+
* Convenience function to create a worker pool configured for file processing.
|
|
561
|
+
*
|
|
562
|
+
* @param processor - Function to process each file
|
|
563
|
+
* @param options - Worker pool options
|
|
564
|
+
* @returns Configured WorkerPool instance
|
|
565
|
+
*/
|
|
566
|
+
export function createFileProcessorPool(processor, options = {}) {
|
|
567
|
+
const pool = new WorkerPool(options);
|
|
568
|
+
pool.setProcessor(processor);
|
|
569
|
+
return pool;
|
|
570
|
+
}
|
|
571
|
+
//# sourceMappingURL=worker-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-pool.js","sourceRoot":"","sources":["../../src/scanner/worker-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqL3C;;GAEG;AACH,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAE5B;;GAEG;AACH,SAAS,iBAAiB;IACxB,IAAI,QAAQ,GAAG,iBAAiB,CAAC;IACjC,IAAI,CAAC;QACH,uCAAuC;QACvC,iEAAiE;QACjE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAC9B,QAAQ,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,iBAAiB,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;QACrC,QAAQ,GAAG,iBAAiB,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,KAAK;QAClB,UAAU,EAAE,CAAC;QACb,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,CAAC;KAChB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,UAA4B,SAAQ,YAAY;IACnD,OAAO,CAA8B;IACrC,SAAS,GAA4B,EAAE,CAAC;IACxC,WAAW,GAAuC,IAAI,GAAG,EAAE,CAAC;IAC5D,cAAc,GAAuC,IAAI,GAAG,EAAE,CAAC;IAC/D,SAAS,GAA0C,IAAI,CAAC;IACxD,aAAa,GAAG,CAAC,CAAC;IAClB,cAAc,GAAG,KAAK,CAAC;IACvB,QAAQ,GAAG,KAAK,CAAC;IACjB,aAAa,GAAG,CAAC,CAAC;IAClB,cAAc,GAAG,CAAC,CAAC;IACnB,WAAW,GAAG,CAAC,CAAC;IAChB,cAAc,GAAG,CAAC,CAAC;IACnB,aAAa,GAAG,CAAC,CAAC;IAClB,YAAY,GAAgC,IAAI,GAAG,EAAE,CAAC;IACtD,KAAK,GAAyB,IAAI,GAAG,EAAE,CAAC;IAEhD,YAAY,UAA6B,EAAE;QACzC,KAAK,EAAE,CAAC;QACR,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;QAE3C,mBAAmB;QACnB,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YACtD,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QACpD,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,SAAyC;QACpD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,KAAa,EAAE,WAAmB,CAAC;QACzC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YACxF,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC;QAC5E,CAAC;QAED,MAAM,IAAI,GAA0B;YAClC,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE;YACzB,KAAK;YACL,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,QAAQ;SACT,CAAC;QAEF,wDAAwD;QACxD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAC;QAC3E,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,MAAgB,EAAE,WAAmB,CAAC;QAC7C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,YAAY,CAAC,MAAgB,EAAE,WAAmB,CAAC;QACvD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEhD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,OAAO,GAA0B,EAAE,CAAC;YAC1C,MAAM,aAAa,GAAG,GAAS,EAAE;gBAC/B,gCAAgC;gBAChC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;oBAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBAC7C,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;oBACxC,CAAC;gBACH,CAAC;gBAED,kCAAkC;gBAClC,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;oBACpC,qBAAqB;oBACrB,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;oBAC1C,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;oBACrC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;oBACvC,OAAO,CAAC,OAAO,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,cAAc,GAAG,CAAC,IAA2B,EAAQ,EAAE;gBAC3D,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;oBACzB,aAAa,EAAE,CAAC;gBAClB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,YAAY,GAAG,CAAC,IAA2B,EAAQ,EAAE;gBACzD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;oBACzB,aAAa,EAAE,CAAC;gBAClB,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,aAAa,GAAG,CAAC,IAA2B,EAAQ,EAAE;gBAC1D,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;oBACzB,aAAa,EAAE,CAAC;gBAClB,CAAC;YACH,CAAC,CAAC;YAEF,IAAI,CAAC,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;YACzC,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;YACpC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;YAEtC,0CAA0C;YAC1C,aAAa,EAAE,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,MAAc;QACvB,4BAA4B;QAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QACpE,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACxC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;gBAC1B,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;gBAC9B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;gBACrC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACtC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,wDAAwD;QACxD,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;OAIG;IACH,gBAAgB;QACd,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;gBAC1B,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;gBAC9B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBACvC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,SAAS,EAAE,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,MAAc;QACpB,qBAAqB;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,wBAAwB;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;QAEhC,cAAc;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM;YAClC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;YAClC,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,eAAe,EAAE,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;YACvF,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;YACpC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;YACnC,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC/D,OAAO;QACT,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,YAAY,GAAG,GAAS,EAAE;gBAC9B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;oBAC/D,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;oBACxC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;oBACrC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;oBACtC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACrB,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC,CAAC;YAEF,IAAI,CAAC,EAAE,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;YACvC,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;YACpC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;YACrC,YAAY,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,QAAQ,CAAC,UAAkB,KAAK;QACpC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAE3B,2BAA2B;QAC3B,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,mDAAmD;QACnD,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,eAAe,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBACpD,MAAM,aAAa,GAAG,GAAS,EAAE;oBAC/B,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;wBAChC,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;wBACzC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;wBACtC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;wBACvC,OAAO,EAAE,CAAC;oBACZ,CAAC;gBACH,CAAC,CAAC;gBAEF,IAAI,CAAC,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;gBACxC,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;gBACrC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;YAEH,MAAM,cAAc,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBACnD,UAAU,CAAC,GAAG,EAAE;oBACd,sCAAsC;oBACtC,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBAC9C,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;wBAC1B,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;wBAC9B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;wBACtC,IAAI,CAAC,cAAc,EAAE,CAAC;wBAEtB,gBAAgB;wBAChB,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;wBAChD,IAAI,SAAS,EAAE,CAAC;4BACd,YAAY,CAAC,SAAS,CAAC,CAAC;4BACxB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;wBACnC,CAAC;oBACH,CAAC;oBACD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;oBACzB,OAAO,EAAE,CAAC;gBACZ,CAAC,EAAE,OAAO,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC,CAAC;QACxD,CAAC;QAED,qBAAqB;QACrB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;YACnD,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAE1B,cAAc;QACd,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAEnB,kBAAkB;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;;OAEG;IACK,YAAY;QAClB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5D,OAAO;QACT,CAAC;QAED,uCAAuC;QACvC,OACE,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;YACzB,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAC/C,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,gBAAgB;QAChB,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,WAAW,CAAC,IAA2B;QACnD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QAE/B,cAAc;QACd,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAChC,OAAO;YACT,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC7B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAEhD,gBAAgB;YAChB,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAElC,4DAA4D;YAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9B,OAAO;YACT,CAAC;YAED,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAgB;YAChB,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAElC,4DAA4D;YAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9B,OAAO;YACT,CAAC;YAED,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,KAAc,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,IAA2B,EAAE,MAAe;QAC/D,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;QAC1B,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;QACtG,IAAI,CAAC,aAAa,IAAI,QAAQ,CAAC;QAC/B,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtB,eAAe;QACf,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAEvC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,IAA2B,EAAE,KAAY;QAC/D,IAAI,CAAC,OAAO,EAAE,CAAC;QAEf,2BAA2B;QAC3B,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;YACxB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEjC,qCAAqC;YACrC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,4DAA4D;YAC5D,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QAED,gCAAgC;QAChC,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;QACvB,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAEvC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAErC,yDAAyD;QACzD,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,IAA2B;QACnD,uCAAuC;QACvC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,wBAAwB,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC;QAClE,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAEvC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,cAAc;QACpB,OAAO,QAAQ,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACtD,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,KAAa;QAC/B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,IAA2B;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,SAAS;YACjD,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;YACvD,CAAC,CAAC,CAAC,CAAC;QAEN,MAAM,MAAM,GAAwB;YAClC,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,OAAO,EAAE,IAAI,CAAC,MAAM,KAAK,WAAW;YACpC,QAAQ;YACR,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;QAEF,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC9B,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5B,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,SAAyC,EACzC,UAA6B,EAAE;IAE/B,MAAM,IAAI,GAAG,IAAI,UAAU,CAAkB,OAAO,CAAC,CAAC;IACtD,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAC7B,OAAO,IAAI,CAAC;AACd,CAAC"}
|