workmatic 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js ADDED
@@ -0,0 +1,505 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Workmatic CLI
4
+ *
5
+ * Commands:
6
+ * stats <db> Show job statistics
7
+ * export <db> [output] Export jobs to CSV
8
+ * import <db> <input> Import jobs from CSV
9
+ * purge <db> [--status=done] Delete jobs by status
10
+ * retry <db> [--status=dead] Retry failed/dead jobs
11
+ * pause <db> <queue> Pause a queue (workers stop claiming)
12
+ * resume <db> <queue> Resume a paused queue
13
+ */
14
+ import Database from 'better-sqlite3';
15
+ import { createReadStream, createWriteStream } from 'fs';
16
+ import { createInterface } from 'readline';
17
+ // Parse command line arguments
18
+ const args = process.argv.slice(2);
19
+ const command = args[0];
20
+ function printUsage() {
21
+ console.log(`
22
+ Workmatic CLI - Job Queue Management
23
+
24
+ Usage:
25
+ workmatic <command> [options]
26
+
27
+ Commands:
28
+ stats <db> Show job statistics
29
+ queues <db> List all queues with status
30
+ list <db> [--status=<status>] List jobs (optionally filter by status)
31
+ export <db> [output.csv] Export jobs to CSV (default: stdout)
32
+ import <db> <input.csv> Import jobs from CSV
33
+ purge <db> --status=<status> Delete jobs by status
34
+ retry <db> [--status=dead] Retry dead/failed jobs (reset to ready)
35
+ pause <db> <queue> Pause a queue (running workers stop claiming)
36
+ resume <db> <queue> Resume a paused queue
37
+
38
+ Options:
39
+ --status=<status> Filter by status (ready|running|done|failed|dead)
40
+ --queue=<queue> Filter by queue name
41
+ --limit=<n> Limit number of results (default: 100)
42
+
43
+ Examples:
44
+ workmatic stats ./jobs.db
45
+ workmatic list ./jobs.db --status=dead --limit=10
46
+ workmatic export ./jobs.db backup.csv
47
+ workmatic export ./jobs.db --status=failed > failed-jobs.csv
48
+ workmatic import ./jobs.db backup.csv
49
+ workmatic purge ./jobs.db --status=done
50
+ workmatic retry ./jobs.db --status=dead
51
+ workmatic pause ./jobs.db emails
52
+ workmatic resume ./jobs.db emails
53
+ `);
54
+ }
55
+ function parseOptions(args) {
56
+ const options = {};
57
+ for (const arg of args) {
58
+ if (arg.startsWith('--')) {
59
+ const [key, value] = arg.slice(2).split('=');
60
+ options[key] = value ?? 'true';
61
+ }
62
+ }
63
+ return options;
64
+ }
65
+ function getPositionalArgs(args) {
66
+ return args.filter(arg => !arg.startsWith('--'));
67
+ }
68
+ // CSV helpers
69
+ function escapeCSV(value) {
70
+ if (value === null)
71
+ return '';
72
+ const str = String(value);
73
+ if (str.includes(',') || str.includes('"') || str.includes('\n')) {
74
+ return `"${str.replace(/"/g, '""')}"`;
75
+ }
76
+ return str;
77
+ }
78
+ function parseCSVLine(line) {
79
+ const result = [];
80
+ let current = '';
81
+ let inQuotes = false;
82
+ for (let i = 0; i < line.length; i++) {
83
+ const char = line[i];
84
+ if (inQuotes) {
85
+ if (char === '"') {
86
+ if (line[i + 1] === '"') {
87
+ current += '"';
88
+ i++;
89
+ }
90
+ else {
91
+ inQuotes = false;
92
+ }
93
+ }
94
+ else {
95
+ current += char;
96
+ }
97
+ }
98
+ else {
99
+ if (char === '"') {
100
+ inQuotes = true;
101
+ }
102
+ else if (char === ',') {
103
+ result.push(current);
104
+ current = '';
105
+ }
106
+ else {
107
+ current += char;
108
+ }
109
+ }
110
+ }
111
+ result.push(current);
112
+ return result;
113
+ }
114
+ // Commands
115
+ async function cmdStats(dbPath) {
116
+ const db = new Database(dbPath, { readonly: true });
117
+ try {
118
+ const stats = db.prepare(`
119
+ SELECT status, COUNT(*) as count
120
+ FROM workmatic_jobs
121
+ GROUP BY status
122
+ `).all();
123
+ const queues = db.prepare(`
124
+ SELECT queue, COUNT(*) as count
125
+ FROM workmatic_jobs
126
+ GROUP BY queue
127
+ `).all();
128
+ const total = stats.reduce((sum, s) => sum + s.count, 0);
129
+ console.log('\n📊 Job Statistics\n');
130
+ console.log('By Status:');
131
+ console.log('─'.repeat(30));
132
+ const statusOrder = ['ready', 'running', 'done', 'failed', 'dead'];
133
+ const statusEmoji = {
134
+ ready: '⏳',
135
+ running: '▶️ ',
136
+ done: '✅',
137
+ failed: '⚠️ ',
138
+ dead: '💀',
139
+ };
140
+ for (const status of statusOrder) {
141
+ const stat = stats.find(s => s.status === status);
142
+ const count = stat?.count ?? 0;
143
+ const emoji = statusEmoji[status] || ' ';
144
+ console.log(` ${emoji} ${status.padEnd(10)} ${count.toLocaleString().padStart(8)}`);
145
+ }
146
+ console.log('─'.repeat(30));
147
+ console.log(` Total: ${total.toLocaleString().padStart(8)}`);
148
+ if (queues.length > 0) {
149
+ console.log('\nBy Queue:');
150
+ console.log('─'.repeat(30));
151
+ for (const q of queues) {
152
+ console.log(` ${q.queue.padEnd(15)} ${q.count.toLocaleString().padStart(8)}`);
153
+ }
154
+ }
155
+ console.log();
156
+ }
157
+ finally {
158
+ db.close();
159
+ }
160
+ }
161
+ async function cmdList(dbPath, options) {
162
+ const db = new Database(dbPath, { readonly: true });
163
+ try {
164
+ let query = 'SELECT public_id, queue, status, priority, attempts, max_attempts, created_at, last_error FROM workmatic_jobs WHERE 1=1';
165
+ const params = [];
166
+ if (options.status) {
167
+ query += ' AND status = ?';
168
+ params.push(options.status);
169
+ }
170
+ if (options.queue) {
171
+ query += ' AND queue = ?';
172
+ params.push(options.queue);
173
+ }
174
+ query += ' ORDER BY created_at DESC LIMIT ?';
175
+ params.push(parseInt(options.limit || '100', 10));
176
+ const jobs = db.prepare(query).all(...params);
177
+ if (jobs.length === 0) {
178
+ console.log('No jobs found.');
179
+ return;
180
+ }
181
+ console.log('\nID Queue Status Pri Attempts Created');
182
+ console.log('─'.repeat(85));
183
+ for (const job of jobs) {
184
+ const id = job.public_id.slice(0, 21);
185
+ const queue = job.queue.slice(0, 15).padEnd(15);
186
+ const status = job.status.padEnd(9);
187
+ const pri = String(job.priority).padStart(3);
188
+ const attempts = `${job.attempts}/${job.max_attempts}`.padStart(8);
189
+ const created = new Date(job.created_at).toISOString().slice(0, 19);
190
+ console.log(`${id} ${queue} ${status} ${pri} ${attempts} ${created}`);
191
+ }
192
+ console.log(`\nShowing ${jobs.length} jobs\n`);
193
+ }
194
+ finally {
195
+ db.close();
196
+ }
197
+ }
198
+ async function cmdExport(dbPath, outputPath, options) {
199
+ const db = new Database(dbPath, { readonly: true });
200
+ try {
201
+ let query = 'SELECT * FROM workmatic_jobs WHERE 1=1';
202
+ const params = [];
203
+ if (options.status) {
204
+ query += ' AND status = ?';
205
+ params.push(options.status);
206
+ }
207
+ if (options.queue) {
208
+ query += ' AND queue = ?';
209
+ params.push(options.queue);
210
+ }
211
+ query += ' ORDER BY id';
212
+ const jobs = db.prepare(query).all(...params);
213
+ const output = outputPath ? createWriteStream(outputPath) : process.stdout;
214
+ // Header
215
+ const columns = [
216
+ 'public_id', 'queue', 'payload', 'status', 'priority',
217
+ 'run_at', 'attempts', 'max_attempts', 'lease_until',
218
+ 'created_at', 'updated_at', 'last_error'
219
+ ];
220
+ if (outputPath) {
221
+ output.write(columns.join(',') + '\n');
222
+ }
223
+ else {
224
+ console.log(columns.join(','));
225
+ }
226
+ // Rows
227
+ for (const job of jobs) {
228
+ const row = columns.map(col => escapeCSV(job[col]));
229
+ if (outputPath) {
230
+ output.write(row.join(',') + '\n');
231
+ }
232
+ else {
233
+ console.log(row.join(','));
234
+ }
235
+ }
236
+ if (outputPath) {
237
+ output.end();
238
+ console.error(`✅ Exported ${jobs.length} jobs to ${outputPath}`);
239
+ }
240
+ }
241
+ finally {
242
+ db.close();
243
+ }
244
+ }
245
+ async function cmdImport(dbPath, inputPath) {
246
+ const db = new Database(dbPath);
247
+ // Ensure schema exists
248
+ db.exec(`
249
+ CREATE TABLE IF NOT EXISTS workmatic_jobs (
250
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
251
+ public_id TEXT UNIQUE NOT NULL,
252
+ queue TEXT NOT NULL,
253
+ payload TEXT NOT NULL,
254
+ status TEXT NOT NULL DEFAULT 'ready',
255
+ priority INTEGER NOT NULL DEFAULT 0,
256
+ run_at INTEGER NOT NULL,
257
+ attempts INTEGER NOT NULL DEFAULT 0,
258
+ max_attempts INTEGER NOT NULL DEFAULT 3,
259
+ lease_until INTEGER NOT NULL DEFAULT 0,
260
+ created_at INTEGER NOT NULL,
261
+ updated_at INTEGER NOT NULL,
262
+ last_error TEXT
263
+ )
264
+ `);
265
+ const insert = db.prepare(`
266
+ INSERT OR REPLACE INTO workmatic_jobs
267
+ (public_id, queue, payload, status, priority, run_at, attempts, max_attempts, lease_until, created_at, updated_at, last_error)
268
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
269
+ `);
270
+ const rl = createInterface({
271
+ input: createReadStream(inputPath),
272
+ crlfDelay: Infinity,
273
+ });
274
+ let lineNum = 0;
275
+ let imported = 0;
276
+ let columns = [];
277
+ try {
278
+ const insertMany = db.transaction((rows) => {
279
+ for (const row of rows) {
280
+ insert.run(row.public_id, row.queue, row.payload, row.status, parseInt(row.priority, 10) || 0, parseInt(row.run_at, 10) || Date.now(), parseInt(row.attempts, 10) || 0, parseInt(row.max_attempts, 10) || 3, parseInt(row.lease_until, 10) || 0, parseInt(row.created_at, 10) || Date.now(), parseInt(row.updated_at, 10) || Date.now(), row.last_error || null);
281
+ imported++;
282
+ }
283
+ });
284
+ const batch = [];
285
+ for await (const line of rl) {
286
+ lineNum++;
287
+ if (lineNum === 1) {
288
+ // Header row
289
+ columns = parseCSVLine(line);
290
+ continue;
291
+ }
292
+ if (!line.trim())
293
+ continue;
294
+ const values = parseCSVLine(line);
295
+ const row = {};
296
+ for (let i = 0; i < columns.length; i++) {
297
+ row[columns[i]] = values[i] ?? '';
298
+ }
299
+ batch.push(row);
300
+ // Batch insert every 1000 rows
301
+ if (batch.length >= 1000) {
302
+ insertMany(batch);
303
+ batch.length = 0;
304
+ process.stderr.write(`\rImported ${imported} jobs...`);
305
+ }
306
+ }
307
+ // Insert remaining
308
+ if (batch.length > 0) {
309
+ insertMany(batch);
310
+ }
311
+ console.log(`\n✅ Imported ${imported} jobs from ${inputPath}`);
312
+ }
313
+ finally {
314
+ db.close();
315
+ }
316
+ }
317
+ async function cmdPurge(dbPath, options) {
318
+ if (!options.status) {
319
+ console.error('Error: --status is required for purge command');
320
+ console.error('Example: workmatic purge ./jobs.db --status=done');
321
+ process.exit(1);
322
+ }
323
+ const db = new Database(dbPath);
324
+ try {
325
+ const result = db.prepare('DELETE FROM workmatic_jobs WHERE status = ?').run(options.status);
326
+ console.log(`🗑️ Deleted ${result.changes} jobs with status '${options.status}'`);
327
+ }
328
+ finally {
329
+ db.close();
330
+ }
331
+ }
332
+ async function cmdRetry(dbPath, options) {
333
+ const status = options.status || 'dead';
334
+ const db = new Database(dbPath);
335
+ try {
336
+ const now = Date.now();
337
+ const result = db.prepare(`
338
+ UPDATE workmatic_jobs
339
+ SET status = 'ready',
340
+ attempts = 0,
341
+ run_at = ?,
342
+ lease_until = 0,
343
+ updated_at = ?
344
+ WHERE status = ?
345
+ `).run(now, now, status);
346
+ console.log(`🔄 Reset ${result.changes} jobs from '${status}' to 'ready'`);
347
+ }
348
+ finally {
349
+ db.close();
350
+ }
351
+ }
352
+ async function cmdPause(dbPath, queueName) {
353
+ const db = new Database(dbPath);
354
+ try {
355
+ // Ensure settings table exists
356
+ db.exec(`
357
+ CREATE TABLE IF NOT EXISTS workmatic_settings (
358
+ queue TEXT PRIMARY KEY,
359
+ paused INTEGER NOT NULL DEFAULT 0,
360
+ updated_at INTEGER NOT NULL
361
+ )
362
+ `);
363
+ const now = Date.now();
364
+ db.prepare(`
365
+ INSERT INTO workmatic_settings (queue, paused, updated_at)
366
+ VALUES (?, 1, ?)
367
+ ON CONFLICT(queue) DO UPDATE SET paused = 1, updated_at = ?
368
+ `).run(queueName, now, now);
369
+ console.log(`⏸️ Paused queue '${queueName}'`);
370
+ console.log(` Running workers will stop claiming new jobs.`);
371
+ }
372
+ finally {
373
+ db.close();
374
+ }
375
+ }
376
+ async function cmdResume(dbPath, queueName) {
377
+ const db = new Database(dbPath);
378
+ try {
379
+ // Ensure settings table exists
380
+ db.exec(`
381
+ CREATE TABLE IF NOT EXISTS workmatic_settings (
382
+ queue TEXT PRIMARY KEY,
383
+ paused INTEGER NOT NULL DEFAULT 0,
384
+ updated_at INTEGER NOT NULL
385
+ )
386
+ `);
387
+ const now = Date.now();
388
+ db.prepare(`
389
+ INSERT INTO workmatic_settings (queue, paused, updated_at)
390
+ VALUES (?, 0, ?)
391
+ ON CONFLICT(queue) DO UPDATE SET paused = 0, updated_at = ?
392
+ `).run(queueName, now, now);
393
+ console.log(`▶️ Resumed queue '${queueName}'`);
394
+ console.log(` Workers will start claiming jobs again.`);
395
+ }
396
+ finally {
397
+ db.close();
398
+ }
399
+ }
400
+ async function cmdQueues(dbPath) {
401
+ const db = new Database(dbPath, { readonly: true });
402
+ try {
403
+ // Get all queues with their job counts and pause state
404
+ const queues = db.prepare(`
405
+ SELECT
406
+ j.queue,
407
+ COUNT(*) as total,
408
+ SUM(CASE WHEN j.status = 'ready' THEN 1 ELSE 0 END) as ready,
409
+ SUM(CASE WHEN j.status = 'running' THEN 1 ELSE 0 END) as running,
410
+ COALESCE(s.paused, 0) as paused
411
+ FROM workmatic_jobs j
412
+ LEFT JOIN workmatic_settings s ON j.queue = s.queue
413
+ GROUP BY j.queue
414
+ `).all();
415
+ if (queues.length === 0) {
416
+ console.log('No queues found.');
417
+ return;
418
+ }
419
+ console.log('\n📋 Queues\n');
420
+ console.log('Queue Status Ready Running Total');
421
+ console.log('─'.repeat(55));
422
+ for (const q of queues) {
423
+ const name = q.queue.padEnd(16);
424
+ const status = q.paused ? '⏸️ PAUSED' : '▶️ ACTIVE';
425
+ const ready = String(q.ready).padStart(5);
426
+ const running = String(q.running).padStart(8);
427
+ const total = String(q.total).padStart(6);
428
+ console.log(`${name} ${status} ${ready} ${running} ${total}`);
429
+ }
430
+ console.log();
431
+ }
432
+ finally {
433
+ db.close();
434
+ }
435
+ }
436
+ // Main
437
+ async function main() {
438
+ if (!command || command === '--help' || command === '-h') {
439
+ printUsage();
440
+ process.exit(0);
441
+ }
442
+ const positionalArgs = getPositionalArgs(args.slice(1));
443
+ const options = parseOptions(args);
444
+ const dbPath = positionalArgs[0];
445
+ if (!dbPath) {
446
+ console.error('Error: Database path is required');
447
+ printUsage();
448
+ process.exit(1);
449
+ }
450
+ try {
451
+ switch (command) {
452
+ case 'stats':
453
+ await cmdStats(dbPath);
454
+ break;
455
+ case 'list':
456
+ await cmdList(dbPath, options);
457
+ break;
458
+ case 'export':
459
+ await cmdExport(dbPath, positionalArgs[1], options);
460
+ break;
461
+ case 'import':
462
+ if (!positionalArgs[1]) {
463
+ console.error('Error: Input CSV file is required');
464
+ process.exit(1);
465
+ }
466
+ await cmdImport(dbPath, positionalArgs[1]);
467
+ break;
468
+ case 'purge':
469
+ await cmdPurge(dbPath, options);
470
+ break;
471
+ case 'retry':
472
+ await cmdRetry(dbPath, options);
473
+ break;
474
+ case 'pause':
475
+ if (!positionalArgs[1]) {
476
+ console.error('Error: Queue name is required');
477
+ console.error('Example: workmatic pause ./jobs.db emails');
478
+ process.exit(1);
479
+ }
480
+ await cmdPause(dbPath, positionalArgs[1]);
481
+ break;
482
+ case 'resume':
483
+ if (!positionalArgs[1]) {
484
+ console.error('Error: Queue name is required');
485
+ console.error('Example: workmatic resume ./jobs.db emails');
486
+ process.exit(1);
487
+ }
488
+ await cmdResume(dbPath, positionalArgs[1]);
489
+ break;
490
+ case 'queues':
491
+ await cmdQueues(dbPath);
492
+ break;
493
+ default:
494
+ console.error(`Unknown command: ${command}`);
495
+ printUsage();
496
+ process.exit(1);
497
+ }
498
+ }
499
+ catch (error) {
500
+ console.error('Error:', error instanceof Error ? error.message : error);
501
+ process.exit(1);
502
+ }
503
+ }
504
+ main();
505
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { ClientOptions, WorkmaticClient } from './types.js';
2
+ /**
3
+ * Create a job queue client for adding jobs
4
+ *
5
+ * @param options - Client options
6
+ * @returns Client instance
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * const client = createClient({ db });
11
+ *
12
+ * // Add a simple job
13
+ * const result = await client.add({ email: 'user@example.com' });
14
+ * console.log(result.id); // Job public ID
15
+ *
16
+ * // Add a job with options
17
+ * await client.add(
18
+ * { userId: 123 },
19
+ * { priority: 1, delayMs: 5000, maxAttempts: 5 }
20
+ * );
21
+ *
22
+ * // Get queue statistics
23
+ * const stats = await client.stats();
24
+ * console.log(stats); // { ready: 5, running: 2, done: 100, ... }
25
+ * ```
26
+ */
27
+ export declare function createClient(options: ClientOptions): WorkmaticClient;
28
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,aAAa,EACb,eAAe,EAKhB,MAAM,YAAY,CAAC;AAGpB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,eAAe,CAuFpE"}
package/dist/client.js ADDED
@@ -0,0 +1,99 @@
1
+ import { nanoid } from 'nanoid';
2
+ import { sql } from 'kysely';
3
+ import { validatePayload, now } from './utils.js';
4
+ /**
5
+ * Create a job queue client for adding jobs
6
+ *
7
+ * @param options - Client options
8
+ * @returns Client instance
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const client = createClient({ db });
13
+ *
14
+ * // Add a simple job
15
+ * const result = await client.add({ email: 'user@example.com' });
16
+ * console.log(result.id); // Job public ID
17
+ *
18
+ * // Add a job with options
19
+ * await client.add(
20
+ * { userId: 123 },
21
+ * { priority: 1, delayMs: 5000, maxAttempts: 5 }
22
+ * );
23
+ *
24
+ * // Get queue statistics
25
+ * const stats = await client.stats();
26
+ * console.log(stats); // { ready: 5, running: 2, done: 100, ... }
27
+ * ```
28
+ */
29
+ export function createClient(options) {
30
+ const { db, queue = 'default' } = options;
31
+ if (!db) {
32
+ throw new Error('Database instance is required');
33
+ }
34
+ return {
35
+ /**
36
+ * Add a job to the queue
37
+ */
38
+ async add(payload, opts = {}) {
39
+ const { priority = 0, delayMs = 0, maxAttempts = 3, } = opts;
40
+ // Validate and serialize payload
41
+ const payloadJson = validatePayload(payload);
42
+ // Generate unique public ID
43
+ const publicId = nanoid();
44
+ const timestamp = now();
45
+ const runAt = timestamp + delayMs;
46
+ // Insert job
47
+ await db
48
+ .insertInto('workmatic_jobs')
49
+ .values({
50
+ public_id: publicId,
51
+ queue,
52
+ payload: payloadJson,
53
+ status: 'ready',
54
+ priority,
55
+ run_at: runAt,
56
+ attempts: 0,
57
+ max_attempts: maxAttempts,
58
+ lease_until: 0,
59
+ created_at: timestamp,
60
+ updated_at: timestamp,
61
+ last_error: null,
62
+ })
63
+ .execute();
64
+ return { ok: true, id: publicId };
65
+ },
66
+ /**
67
+ * Get job statistics for the queue
68
+ */
69
+ async stats() {
70
+ const result = await db
71
+ .selectFrom('workmatic_jobs')
72
+ .select([
73
+ 'status',
74
+ sql `count(*)`.as('count'),
75
+ ])
76
+ .where('queue', '=', queue)
77
+ .groupBy('status')
78
+ .execute();
79
+ const stats = {
80
+ ready: 0,
81
+ running: 0,
82
+ done: 0,
83
+ failed: 0,
84
+ dead: 0,
85
+ total: 0,
86
+ };
87
+ for (const row of result) {
88
+ const status = row.status;
89
+ const count = Number(row.count);
90
+ if (status in stats) {
91
+ stats[status] = count;
92
+ }
93
+ stats.total += count;
94
+ }
95
+ return stats;
96
+ },
97
+ };
98
+ }
99
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAU7B,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,MAAM,EAAE,EAAE,EAAE,KAAK,GAAG,SAAS,EAAE,GAAG,OAAO,CAAC;IAE1C,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,OAAO;QACL;;WAEG;QACH,KAAK,CAAC,GAAG,CACP,OAAiB,EACjB,OAAsB,EAAE;YAExB,MAAM,EACJ,QAAQ,GAAG,CAAC,EACZ,OAAO,GAAG,CAAC,EACX,WAAW,GAAG,CAAC,GAChB,GAAG,IAAI,CAAC;YAET,iCAAiC;YACjC,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;YAE7C,4BAA4B;YAC5B,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC;YAE1B,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,SAAS,GAAG,OAAO,CAAC;YAElC,aAAa;YACb,MAAM,EAAE;iBACL,UAAU,CAAC,gBAAgB,CAAC;iBAC5B,MAAM,CAAC;gBACN,SAAS,EAAE,QAAQ;gBACnB,KAAK;gBACL,OAAO,EAAE,WAAW;gBACpB,MAAM,EAAE,OAAO;gBACf,QAAQ;gBACR,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,CAAC;gBACX,YAAY,EAAE,WAAW;gBACzB,WAAW,EAAE,CAAC;gBACd,UAAU,EAAE,SAAS;gBACrB,UAAU,EAAE,SAAS;gBACrB,UAAU,EAAE,IAAI;aACjB,CAAC;iBACD,OAAO,EAAE,CAAC;YAEb,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;QACpC,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,KAAK;YACT,MAAM,MAAM,GAAG,MAAM,EAAE;iBACpB,UAAU,CAAC,gBAAgB,CAAC;iBAC5B,MAAM,CAAC;gBACN,QAAQ;gBACR,GAAG,CAAQ,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC;aAClC,CAAC;iBACD,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC;iBAC1B,OAAO,CAAC,QAAQ,CAAC;iBACjB,OAAO,EAAE,CAAC;YAEb,MAAM,KAAK,GAAa;gBACtB,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,CAAC;gBACV,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,CAAC;gBACT,IAAI,EAAE,CAAC;gBACP,KAAK,EAAE,CAAC;aACT,CAAC;YAEF,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;gBACzB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAmB,CAAC;gBACvC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAChC,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;oBACpB,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;gBACxB,CAAC;gBACD,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC;YACvB,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}