@shardworks/nexus 0.1.270 → 0.1.272

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,652 @@
1
+ /**
2
+ * nsg clock — operator-facing Clockworks CLI.
3
+ *
4
+ * Three subcommands under `nsg clock` that compose on top of
5
+ * `ClockworksApi.processEvents` and a direct read of the
6
+ * `clockworks/events` book:
7
+ *
8
+ * - `nsg clock list` — print pending events (or, with
9
+ * `--include-processed`, every event), one event per two-line
10
+ * block (or a single line when payload is null), in id-ascending
11
+ * order. `--limit N` caps output at N entries.
12
+ * - `nsg clock tick [id]` — process a single event. Without `id`,
13
+ * the next pending event in id order; with `id`, exactly that
14
+ * event after a CLI-side pre-check that it exists and is still
15
+ * pending. Prints per-dispatch summary lines via the
16
+ * `processEvents({ onDispatch })` observer.
17
+ * - `nsg clock run` — loop `processEvents()` until the dispatcher
18
+ * reports zero processed events for an iteration. No sleep, no
19
+ * daemon — finite drain. Mid-sweep arrivals are picked up on the
20
+ * next iteration.
21
+ *
22
+ * The CLI package deliberately does not depend on the clockworks or
23
+ * stacks plugin packages — apparatus interfaces are declared inline
24
+ * and resolved at runtime via `guild().apparatus<T>(name)`. This
25
+ * mirrors the discipline practiced by `signal` and `start`.
26
+ *
27
+ * Hand-written rather than auto-built because:
28
+ * - `tick [id]` is an optional positional, which the auto-builder
29
+ * cannot express.
30
+ * - `--include-processed` and `--limit <N>` need locally-validated
31
+ * parsing.
32
+ * - Exit-code semantics are nontrivial: nonzero only when at least
33
+ * one dispatch recorded `status: error`, plus the
34
+ * missing-event-id and already-processed-event branches.
35
+ *
36
+ * See commission c-mody57g7 decisions D1–D20.
37
+ */
38
+ import { Command } from 'commander';
39
+ import { guild } from '@shardworks/nexus-core';
40
+ import { clockStart, clockStatus, clockStop, runForegroundDaemonFromGuild, } from '@shardworks/clockworks-apparatus';
41
+ import { getStartedGuild } from "../started-guild.js";
42
+ // ── Constants (D9, D10, D13, D14, D15, D19) ──────────────────────────
43
+ /** Maximum payload-preview length for `list` (D19). */
44
+ const PAYLOAD_PREVIEW_MAX = 120;
45
+ /** Empty-queue messages — one per command (D13). */
46
+ const EMPTY_LIST = 'No pending events.';
47
+ const EMPTY_TICK = 'Queue is empty; nothing to process.';
48
+ const EMPTY_RUN = 'Queue is empty; processed 0 events.';
49
+ // ── Helpers ──────────────────────────────────────────────────────────
50
+ /**
51
+ * Resolve the loaded guild or throw the canonical no-guild error so
52
+ * the action wrapper can convert it to an `Error: …` exit-1 line.
53
+ */
54
+ function requireGuild() {
55
+ try {
56
+ return guild();
57
+ }
58
+ catch {
59
+ throw new Error('Not inside a guild. Run `nsg init` to create one first.');
60
+ }
61
+ }
62
+ /**
63
+ * Build the daemon-coexistence warning when the Clockworks daemon is
64
+ * already running. Returns `null` when the daemon is not running so
65
+ * callers can append it conditionally.
66
+ *
67
+ * The warning is non-fatal: `nsg clock tick` and `nsg clock run` keep
68
+ * working even when the daemon is up. The dispatch sweep
69
+ * (read-pending → invoke → patch-processed) is not atomic across
70
+ * processes, so a daemon and a manual invocation that overlap may
71
+ * each invoke the same relay for the same event. Operators rely on
72
+ * relay-author idempotency (see `RelayHandler` in
73
+ * `packages/plugins/clockworks/src/relay.ts`); this warning exists so
74
+ * they understand the contract is engaged whenever they tick or run
75
+ * alongside the daemon.
76
+ */
77
+ function daemonCoexistenceWarning(home) {
78
+ const status = clockStatus(home);
79
+ if (!status.running)
80
+ return null;
81
+ return (`Warning: clockworks daemon is running (pid ${status.pid}); ` +
82
+ `this manual invocation will run concurrently — relays may be ` +
83
+ `invoked more than once for overlapping events.`);
84
+ }
85
+ /**
86
+ * Render the payload preview for `list`. Returns null when the
87
+ * payload is exactly null (D19 — payload line omitted entirely);
88
+ * otherwise returns a truncated JSON string.
89
+ */
90
+ export function renderPayloadPreview(payload) {
91
+ if (payload === null)
92
+ return null;
93
+ let json;
94
+ try {
95
+ json = JSON.stringify(payload);
96
+ }
97
+ catch {
98
+ json = '<unserializable>';
99
+ }
100
+ if (json === undefined)
101
+ return null;
102
+ if (json.length <= PAYLOAD_PREVIEW_MAX)
103
+ return json;
104
+ // Reserve one char for the trailing ellipsis.
105
+ return json.slice(0, PAYLOAD_PREVIEW_MAX - 1) + '…';
106
+ }
107
+ /**
108
+ * Format a single event for `nsg clock list`. Two lines when payload
109
+ * is non-null; single line otherwise.
110
+ */
111
+ export function formatEventBlock(event) {
112
+ const head = `${event.id} ${event.name} ${event.emitter} ${event.firedAt}`;
113
+ const preview = renderPayloadPreview(event.payload);
114
+ if (preview === null)
115
+ return head;
116
+ return `${head}\n payload: ${preview}`;
117
+ }
118
+ /**
119
+ * Format a single dispatch observation for the per-dispatch summary
120
+ * line emitted by `tick` and `run`. Per D10:
121
+ * `[<handlerName>] <status> <durationMs>ms`
122
+ * With `: <error>` appended on the same line when `status` is error.
123
+ *
124
+ * Loop-guard `'skipped'` rows render as
125
+ * `[<handlerName>] skipped: <loop-guard reason>`
126
+ * — the same colon-then-message convention as the error arm so output
127
+ * stays parseable. Skipped lines do NOT include a duration (the
128
+ * dispatcher never invoked the relay; surfacing `0ms` would only
129
+ * mislead operators).
130
+ */
131
+ export function formatDispatchLine(obs) {
132
+ if (obs.status === 'skipped') {
133
+ const head = `[${obs.handlerName}] skipped`;
134
+ return obs.error ? `${head}: ${obs.error}` : head;
135
+ }
136
+ const head = `[${obs.handlerName}] ${obs.status} ${obs.durationMs}ms`;
137
+ if (obs.status === 'error' && obs.error) {
138
+ return `${head}: ${obs.error}`;
139
+ }
140
+ return head;
141
+ }
142
+ /**
143
+ * Read events for `nsg clock list` and render them.
144
+ *
145
+ * The book read uses `find` with a `where` filter when only pending
146
+ * events are wanted (the common case); otherwise `list` with no
147
+ * filter (the `--include-processed` path).
148
+ */
149
+ export async function runList(input) {
150
+ const g = requireGuild();
151
+ const stacks = g.apparatus('stacks');
152
+ const events = stacks.book('clockworks', 'events');
153
+ const orderBy = [['id', 'asc']];
154
+ let rows;
155
+ if (input.includeProcessed) {
156
+ const opts = { orderBy };
157
+ if (input.limit !== undefined)
158
+ opts.limit = input.limit;
159
+ rows = await events.list(opts);
160
+ }
161
+ else {
162
+ const query = {
163
+ where: [['processed', '=', false]],
164
+ orderBy,
165
+ };
166
+ if (input.limit !== undefined)
167
+ query.limit = input.limit;
168
+ rows = await events.find(query);
169
+ }
170
+ if (rows.length === 0) {
171
+ return { lines: [EMPTY_LIST], count: 0, empty: true };
172
+ }
173
+ const lines = [];
174
+ for (const row of rows) {
175
+ lines.push(formatEventBlock(row));
176
+ }
177
+ return { lines, count: rows.length, empty: false };
178
+ }
179
+ /**
180
+ * Process a single event via `processEvents({ eventId })` or
181
+ * `processEvents({ max: 1 })` and capture the per-dispatch summary
182
+ * lines via the observer.
183
+ *
184
+ * The `events.get(id)` pre-check happens here per D4: missing-id and
185
+ * already-processed cases never reach the dispatcher.
186
+ */
187
+ export async function runTick(input) {
188
+ const g = requireGuild();
189
+ const clockworks = g.apparatus('clockworks');
190
+ const stacks = g.apparatus('stacks');
191
+ const events = stacks.book('clockworks', 'events');
192
+ // Daemon-coexistence warning — emitted independently of the
193
+ // dispatch outcome so operators always see whether they're racing
194
+ // the daemon. Best-effort: a thrown clockStatus must not block tick.
195
+ const warnings = [];
196
+ try {
197
+ const w = daemonCoexistenceWarning(g.home);
198
+ if (w)
199
+ warnings.push(w);
200
+ }
201
+ catch {
202
+ // ignore — diagnostic warning, not load-bearing
203
+ }
204
+ const lines = [];
205
+ // Capture the targeted event row (or the next-pending one) so we can
206
+ // surface the no-match line per D16 without re-reading the book
207
+ // after the sweep.
208
+ let targetEvent;
209
+ if (input.eventId !== undefined) {
210
+ targetEvent = await events.get(input.eventId);
211
+ if (!targetEvent) {
212
+ return {
213
+ lines: [`Error: clockworks: event "${input.eventId}" not found in events book.`],
214
+ hadError: true,
215
+ empty: false,
216
+ notFound: true,
217
+ alreadyProcessed: false,
218
+ warnings,
219
+ };
220
+ }
221
+ if (targetEvent.processed) {
222
+ return {
223
+ lines: [
224
+ `Warning: clockworks: event "${input.eventId}" has already been processed.`,
225
+ ],
226
+ hadError: true,
227
+ empty: false,
228
+ notFound: false,
229
+ alreadyProcessed: true,
230
+ warnings,
231
+ };
232
+ }
233
+ }
234
+ else {
235
+ // Next-pending mode: peek ahead so we know which event the
236
+ // dispatcher will pick up. Using the same id-ascending order as
237
+ // the dispatcher's own find call so the peek matches.
238
+ const peek = await events.find({
239
+ where: [['processed', '=', false]],
240
+ orderBy: [['id', 'asc']],
241
+ limit: 1,
242
+ });
243
+ targetEvent = peek[0] ?? null;
244
+ if (!targetEvent) {
245
+ return {
246
+ lines: [EMPTY_TICK],
247
+ hadError: false,
248
+ empty: true,
249
+ notFound: false,
250
+ alreadyProcessed: false,
251
+ warnings,
252
+ };
253
+ }
254
+ }
255
+ const observedEventIds = new Set();
256
+ const opts = {
257
+ onDispatch: (obs) => {
258
+ observedEventIds.add(obs.eventId);
259
+ lines.push(formatDispatchLine(obs));
260
+ },
261
+ };
262
+ if (input.eventId !== undefined) {
263
+ opts.eventId = input.eventId;
264
+ }
265
+ else {
266
+ opts.max = 1;
267
+ }
268
+ const summary = await clockworks.processEvents(opts);
269
+ // The empty-queue branch is handled above for the next-pending mode.
270
+ // For the explicit-id mode, summary.processedEvents will be 1 — the
271
+ // pre-check already eliminated the missing/already-processed cases.
272
+ // Defensive fall-through: if somehow nothing was processed, treat
273
+ // it like an empty queue.
274
+ if (summary.processedEvents === 0) {
275
+ return {
276
+ lines: [EMPTY_TICK],
277
+ hadError: false,
278
+ empty: true,
279
+ notFound: false,
280
+ alreadyProcessed: false,
281
+ warnings,
282
+ };
283
+ }
284
+ // D16: a processed event with zero dispatch observations means
285
+ // there were no matching standing orders. Surface a single visibility
286
+ // line so operators don't see silence.
287
+ if (targetEvent && !observedEventIds.has(targetEvent.id)) {
288
+ lines.push(`${targetEvent.id} ${targetEvent.name} (no matching standing orders)`);
289
+ }
290
+ // D20: zero matching standing orders → exit 0.
291
+ return {
292
+ lines,
293
+ hadError: summary.errors > 0,
294
+ empty: false,
295
+ notFound: false,
296
+ alreadyProcessed: false,
297
+ warnings,
298
+ };
299
+ }
300
+ /**
301
+ * Drain the queue. Loop `processEvents()` until it reports zero
302
+ * processed events for an iteration. No sleep, no daemon. Per-dispatch
303
+ * summary lines emit as they happen via the observer; the final
304
+ * `processed N events` line goes out at the end.
305
+ */
306
+ export async function runRun() {
307
+ const g = requireGuild();
308
+ const clockworks = g.apparatus('clockworks');
309
+ const stacks = g.apparatus('stacks');
310
+ const events = stacks.book('clockworks', 'events');
311
+ // Daemon-coexistence warning — emitted independently of the drain
312
+ // outcome.
313
+ const warnings = [];
314
+ try {
315
+ const w = daemonCoexistenceWarning(g.home);
316
+ if (w)
317
+ warnings.push(w);
318
+ }
319
+ catch {
320
+ // ignore — diagnostic warning, not load-bearing
321
+ }
322
+ const lines = [];
323
+ let totalProcessed = 0;
324
+ let totalErrors = 0;
325
+ let firstIterationEmpty = false;
326
+ // Track which event ids produced at least one dispatch row this
327
+ // process so we can surface "(no matching standing orders)" for the
328
+ // ones that didn't.
329
+ const seenDispatchEventIds = new Set();
330
+ for (;;) {
331
+ // D16: capture the set of events the dispatcher will see this
332
+ // sweep so we can surface "(no matching standing orders)" lines
333
+ // for events that produced zero dispatch observations. `run` has
334
+ // no max cap, so every event in this snapshot will be flipped
335
+ // before the sweep returns.
336
+ const pendingBefore = await events.find({
337
+ where: [['processed', '=', false]],
338
+ orderBy: [['id', 'asc']],
339
+ });
340
+ const summary = await clockworks.processEvents({
341
+ onDispatch: (obs) => {
342
+ seenDispatchEventIds.add(obs.eventId);
343
+ lines.push(formatDispatchLine(obs));
344
+ },
345
+ });
346
+ if (summary.processedEvents === 0) {
347
+ if (totalProcessed === 0)
348
+ firstIterationEmpty = true;
349
+ break;
350
+ }
351
+ for (const ev of pendingBefore) {
352
+ if (!seenDispatchEventIds.has(ev.id)) {
353
+ lines.push(`${ev.id} ${ev.name} (no matching standing orders)`);
354
+ // Defensive: prevent re-emission if a later sweep would see
355
+ // the same id (it shouldn't — the row is now processed —
356
+ // but the guard keeps the line idempotent).
357
+ seenDispatchEventIds.add(ev.id);
358
+ }
359
+ }
360
+ totalProcessed += summary.processedEvents;
361
+ totalErrors += summary.errors;
362
+ }
363
+ if (firstIterationEmpty) {
364
+ return {
365
+ lines: [EMPTY_RUN],
366
+ hadError: false,
367
+ totalProcessed: 0,
368
+ empty: true,
369
+ warnings,
370
+ };
371
+ }
372
+ lines.push(`processed ${totalProcessed} events`);
373
+ return {
374
+ lines,
375
+ hadError: totalErrors > 0,
376
+ totalProcessed,
377
+ empty: false,
378
+ warnings,
379
+ };
380
+ }
381
+ /**
382
+ * Handle `nsg clock start`. Without `--foreground`, calls
383
+ * `clockStart(home)`, which spawns a detached child and blocks until
384
+ * the daemon is verified running. With `--foreground`, calls
385
+ * `runForegroundDaemonFromGuild` — the inline daemon body that the
386
+ * detached spawn re-execs into. The function returns only when the
387
+ * daemon shuts down (under SIGTERM or SIGINT).
388
+ */
389
+ export async function runStart(input) {
390
+ const g = requireGuild();
391
+ if (input.foreground) {
392
+ // Inline foreground daemon body. `runForegroundDaemonFromGuild`
393
+ // installs SIGTERM/SIGINT handlers and returns once shutdown is
394
+ // signaled. Once it returns we exit cleanly.
395
+ //
396
+ // Pass the StartedGuild deposited by program.ts so the daemon's
397
+ // shutdown path runs `guildInstance.shutdown()` — and therefore
398
+ // every started apparatus's optional `stop()` — before
399
+ // process.exit(0).
400
+ const startedGuild = getStartedGuild();
401
+ const opts = {
402
+ onShutdown: () => process.exit(0),
403
+ };
404
+ if (input.interval !== undefined)
405
+ opts.intervalMs = input.interval;
406
+ if (startedGuild)
407
+ opts.startedGuild = startedGuild;
408
+ await runForegroundDaemonFromGuild(opts);
409
+ // Unreachable — onShutdown exits the process.
410
+ return { lines: [] };
411
+ }
412
+ const startOpts = {};
413
+ if (input.interval !== undefined)
414
+ startOpts.interval = input.interval;
415
+ const result = await clockStart(g.home, startOpts);
416
+ return {
417
+ lines: [
418
+ `Clockworks daemon started (pid: ${result.pid})`,
419
+ ` Log file: ${result.logFile}`,
420
+ ],
421
+ };
422
+ }
423
+ /**
424
+ * Handle `nsg clock stop`. Thin wrapper around `clockStop`.
425
+ *
426
+ * Per spec: missing-pidfile and stale-pidfile cases exit zero with a
427
+ * message — they are not errors. The success-path message comes from
428
+ * the core API result so the three branches (`'signaled'`,
429
+ * `'no-pidfile'`, `'stale'`) stay aligned across CLI / programmatic
430
+ * consumers.
431
+ */
432
+ export async function runStop() {
433
+ const g = requireGuild();
434
+ const result = await clockStop(g.home);
435
+ return { lines: [result.message] };
436
+ }
437
+ /**
438
+ * Handle `nsg clock status`. Defaults to multi-line plain text;
439
+ * `--json` emits the structured shape verbatim. The output mirrors
440
+ * the `clock-status` MCP tool's payload so the surfaces stay aligned.
441
+ */
442
+ export function runStatus(input) {
443
+ const g = requireGuild();
444
+ const status = clockStatus(g.home);
445
+ if (input.json) {
446
+ return { lines: [JSON.stringify(status, null, 2)], status };
447
+ }
448
+ if (!status.running) {
449
+ if (status.stalePidfile) {
450
+ return {
451
+ lines: [
452
+ 'Clockworks daemon: not running.',
453
+ ' (Stale pidfile detected and removed.)',
454
+ ],
455
+ status,
456
+ };
457
+ }
458
+ return { lines: ['Clockworks daemon: not running.'], status };
459
+ }
460
+ const lines = [
461
+ 'Clockworks daemon: running',
462
+ ` PID: ${status.pid}`,
463
+ ` Log file: ${status.logFile}`,
464
+ ` Uptime: ${formatUptime(status.uptime ?? 0)}`,
465
+ ];
466
+ return { lines, status };
467
+ }
468
+ /** Format a millisecond uptime as a short human-readable string. */
469
+ function formatUptime(ms) {
470
+ if (ms < 1000)
471
+ return `${ms}ms`;
472
+ const seconds = Math.floor(ms / 1000);
473
+ if (seconds < 60)
474
+ return `${seconds}s`;
475
+ const minutes = Math.floor(seconds / 60);
476
+ const remSeconds = seconds % 60;
477
+ if (minutes < 60)
478
+ return `${minutes}m${remSeconds}s`;
479
+ const hours = Math.floor(minutes / 60);
480
+ const remMinutes = minutes % 60;
481
+ return `${hours}h${remMinutes}m${remSeconds}s`;
482
+ }
483
+ // ── Commander Command ────────────────────────────────────────────────
484
+ /**
485
+ * Parse and validate the `--limit <N>` flag for `list`. Commander
486
+ * surfaces flag values as strings; we want a positive integer.
487
+ */
488
+ function parseLimitOption(raw) {
489
+ const n = Number(raw);
490
+ if (!Number.isInteger(n) || n <= 0) {
491
+ throw new Error(`clock list: --limit must be a positive integer, got "${raw}".`);
492
+ }
493
+ return n;
494
+ }
495
+ /**
496
+ * Parse and validate the `--interval <ms>` flag for `start`. Mirrors
497
+ * the fail-loud pattern of `parseLimitOption`.
498
+ */
499
+ function parseIntervalOption(raw) {
500
+ const n = Number(raw);
501
+ if (!Number.isInteger(n) || n <= 0) {
502
+ throw new Error(`clock start: --interval must be a positive integer (ms), got "${raw}".`);
503
+ }
504
+ return n;
505
+ }
506
+ /**
507
+ * Build the `nsg clock` Commander Command — the parent group plus the
508
+ * three subcommands. Each subcommand's action wrapper translates the
509
+ * structured handler output to printed lines and `process.exit(N)` per
510
+ * commission decision D8.
511
+ */
512
+ export function buildClockCommand() {
513
+ const cmd = new Command('clock').description('Clockworks operator commands');
514
+ // ── list ──────────────────────────────────────────────────────────
515
+ const list = new Command('list')
516
+ .description('List events in the Clockworks events book.')
517
+ .option('--include-processed', 'Include processed events in addition to pending ones.')
518
+ .option('--limit <n>', 'Cap output at N entries. Without this flag, every matching event prints.', parseLimitOption)
519
+ .action(async (opts) => {
520
+ try {
521
+ const out = await runList({
522
+ includeProcessed: opts.includeProcessed,
523
+ limit: opts.limit,
524
+ });
525
+ for (const line of out.lines)
526
+ console.log(line);
527
+ }
528
+ catch (err) {
529
+ const message = err instanceof Error ? err.message : String(err);
530
+ console.error(`Error: ${message}`);
531
+ process.exit(1);
532
+ }
533
+ });
534
+ // ── tick ──────────────────────────────────────────────────────────
535
+ const tick = new Command('tick')
536
+ .description('Process a single event (next pending, or the supplied id).')
537
+ .argument('[id]', 'Event id to process. Omit to take the next pending event.')
538
+ .action(async (id) => {
539
+ try {
540
+ const out = await runTick({ eventId: id });
541
+ // Daemon-coexistence warning(s) go to stderr first so the
542
+ // operator notices them ahead of the dispatch summary.
543
+ for (const w of out.warnings)
544
+ console.error(w);
545
+ // D8: print first, then explicitly exit non-zero — keeps the
546
+ // structured summary intact ahead of any "Error: …" prefix.
547
+ for (const line of out.lines) {
548
+ if (line.startsWith('Error:') || line.startsWith('Warning:')) {
549
+ console.error(line);
550
+ }
551
+ else {
552
+ console.log(line);
553
+ }
554
+ }
555
+ if (out.notFound || out.alreadyProcessed) {
556
+ process.exit(1);
557
+ }
558
+ if (out.hadError) {
559
+ process.exit(1);
560
+ }
561
+ }
562
+ catch (err) {
563
+ const message = err instanceof Error ? err.message : String(err);
564
+ console.error(`Error: ${message}`);
565
+ process.exit(1);
566
+ }
567
+ });
568
+ // ── run ───────────────────────────────────────────────────────────
569
+ const run = new Command('run')
570
+ .description('Drain the queue. Loops processEvents() until zero events are processed.')
571
+ .action(async () => {
572
+ try {
573
+ const out = await runRun();
574
+ for (const w of out.warnings)
575
+ console.error(w);
576
+ for (const line of out.lines)
577
+ console.log(line);
578
+ if (out.hadError) {
579
+ process.exit(1);
580
+ }
581
+ }
582
+ catch (err) {
583
+ const message = err instanceof Error ? err.message : String(err);
584
+ console.error(`Error: ${message}`);
585
+ process.exit(1);
586
+ }
587
+ });
588
+ // ── start ─────────────────────────────────────────────────────────
589
+ const start = new Command('start')
590
+ .description('Start the Clockworks daemon (detached background process).')
591
+ .option('--interval <ms>', 'Polling interval in milliseconds (default 2000).', parseIntervalOption)
592
+ .option('-f, --foreground', 'Run the daemon body inline in this process (used by the detached re-exec).')
593
+ .action(async (opts) => {
594
+ try {
595
+ const input = {};
596
+ if (opts.interval !== undefined)
597
+ input.interval = opts.interval;
598
+ if (opts.foreground)
599
+ input.foreground = true;
600
+ const out = await runStart(input);
601
+ for (const line of out.lines)
602
+ console.log(line);
603
+ }
604
+ catch (err) {
605
+ const message = err instanceof Error ? err.message : String(err);
606
+ console.error(`Error: ${message}`);
607
+ process.exit(1);
608
+ }
609
+ });
610
+ // ── stop ──────────────────────────────────────────────────────────
611
+ const stop = new Command('stop')
612
+ .description('Stop the Clockworks daemon (graceful SIGTERM with SIGKILL escalation).')
613
+ .action(async () => {
614
+ try {
615
+ const out = await runStop();
616
+ for (const line of out.lines)
617
+ console.log(line);
618
+ }
619
+ catch (err) {
620
+ const message = err instanceof Error ? err.message : String(err);
621
+ console.error(`Error: ${message}`);
622
+ process.exit(1);
623
+ }
624
+ });
625
+ // ── status ────────────────────────────────────────────────────────
626
+ const status = new Command('status')
627
+ .description('Show whether the Clockworks daemon is running.')
628
+ .option('--json', 'Output the structured status as JSON.')
629
+ .action((opts) => {
630
+ try {
631
+ const input = {};
632
+ if (opts.json)
633
+ input.json = true;
634
+ const out = runStatus(input);
635
+ for (const line of out.lines)
636
+ console.log(line);
637
+ }
638
+ catch (err) {
639
+ const message = err instanceof Error ? err.message : String(err);
640
+ console.error(`Error: ${message}`);
641
+ process.exit(1);
642
+ }
643
+ });
644
+ cmd.addCommand(list);
645
+ cmd.addCommand(tick);
646
+ cmd.addCommand(run);
647
+ cmd.addCommand(start);
648
+ cmd.addCommand(stop);
649
+ cmd.addCommand(status);
650
+ return cmd;
651
+ }
652
+ //# sourceMappingURL=clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.js","sourceRoot":"","sources":["../../src/commands/clock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,WAAW,EACX,SAAS,EACT,4BAA4B,GAE7B,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAwEtD,wEAAwE;AAExE,uDAAuD;AACvD,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,oDAAoD;AACpD,MAAM,UAAU,GAAG,oBAAoB,CAAC;AACxC,MAAM,UAAU,GAAG,qCAAqC,CAAC;AACzD,MAAM,SAAS,GAAG,qCAAqC,CAAC;AAExD,wEAAwE;AAExE;;;GAGG;AACH,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,OAAO,KAAK,EAAE,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,wBAAwB,CAAC,IAAY;IAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,CACL,8CAA8C,MAAM,CAAC,GAAG,KAAK;QAC7D,+DAA+D;QAC/D,gDAAgD,CACjD,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,kBAAkB,CAAC;IAC5B,CAAC;IACD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,IAAI,mBAAmB;QAAE,OAAO,IAAI,CAAC;IACpD,8CAA8C;IAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAmB;IAClD,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;IAC9E,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,GAAG,IAAI,gBAAgB,OAAO,EAAE,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAA4B;IAC7D,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,WAAW,WAAW,CAAC;QAC5C,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,IAAI,CAAC;IACtE,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QACxC,OAAO,GAAG,IAAI,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAoBD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAgB;IAC5C,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAgB,QAAQ,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAe,YAAY,EAAE,QAAQ,CAAC,CAAC;IAEjE,MAAM,OAAO,GAAoC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAEjE,IAAI,IAAoB,CAAC;IACzB,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAiE,EAAE,OAAO,EAAE,CAAC;QACvF,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACxD,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAIP;YACF,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YAClC,OAAO;SACR,CAAC;QACF,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACzD,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACxD,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACrD,CAAC;AA4BD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAgB;IAC5C,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;IACzB,MAAM,UAAU,GAAG,CAAC,CAAC,SAAS,CAAoB,YAAY,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAgB,QAAQ,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAe,YAAY,EAAE,QAAQ,CAAC,CAAC;IAEjE,4DAA4D;IAC5D,kEAAkE;IAClE,qEAAqE;IACrE,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;IAClD,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,qEAAqE;IACrE,gEAAgE;IAChE,mBAAmB;IACnB,IAAI,WAA4C,CAAC;IAEjD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,WAAW,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;gBACL,KAAK,EAAE,CAAC,6BAA6B,KAAK,CAAC,OAAO,6BAA6B,CAAC;gBAChF,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,KAAK;gBACZ,QAAQ,EAAE,IAAI;gBACd,gBAAgB,EAAE,KAAK;gBACvB,QAAQ;aACT,CAAC;QACJ,CAAC;QACD,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;YAC1B,OAAO;gBACL,KAAK,EAAE;oBACL,+BAA+B,KAAK,CAAC,OAAO,+BAA+B;iBAC5E;gBACD,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,KAAK;gBACZ,QAAQ,EAAE,KAAK;gBACf,gBAAgB,EAAE,IAAI;gBACtB,QAAQ;aACT,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,CAAC;QACN,2DAA2D;QAC3D,gEAAgE;QAChE,sDAAsD;QACtD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC;YAC7B,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YAClC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACxB,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;QACH,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAC9B,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;gBACL,KAAK,EAAE,CAAC,UAAU,CAAC;gBACnB,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,IAAI;gBACX,QAAQ,EAAE,KAAK;gBACf,gBAAgB,EAAE,KAAK;gBACvB,QAAQ;aACT,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC3C,MAAM,IAAI,GAA6B;QACrC,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE;YAClB,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,CAAC;KACF,CAAC;IACF,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAErD,qEAAqE;IACrE,oEAAoE;IACpE,oEAAoE;IACpE,kEAAkE;IAClE,0BAA0B;IAC1B,IAAI,OAAO,CAAC,eAAe,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO;YACL,KAAK,EAAE,CAAC,UAAU,CAAC;YACnB,QAAQ,EAAE,KAAK;YACf,KAAK,EAAE,IAAI;YACX,QAAQ,EAAE,KAAK;YACf,gBAAgB,EAAE,KAAK;YACvB,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,+DAA+D;IAC/D,sEAAsE;IACtE,uCAAuC;IACvC,IAAI,WAAW,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;QACzD,KAAK,CAAC,IAAI,CACR,GAAG,WAAW,CAAC,EAAE,IAAI,WAAW,CAAC,IAAI,gCAAgC,CACtE,CAAC;IACJ,CAAC;IAED,+CAA+C;IAC/C,OAAO;QACL,KAAK;QACL,QAAQ,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC;QAC5B,KAAK,EAAE,KAAK;QACZ,QAAQ,EAAE,KAAK;QACf,gBAAgB,EAAE,KAAK;QACvB,QAAQ;KACT,CAAC;AACJ,CAAC;AAqBD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;IACzB,MAAM,UAAU,GAAG,CAAC,CAAC,SAAS,CAAoB,YAAY,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAgB,QAAQ,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAe,YAAY,EAAE,QAAQ,CAAC,CAAC;IAEjE,kEAAkE;IAClE,WAAW;IACX,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;IAClD,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,mBAAmB,GAAG,KAAK,CAAC;IAEhC,gEAAgE;IAChE,oEAAoE;IACpE,oBAAoB;IACpB,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/C,SAAS,CAAC;QACR,8DAA8D;QAC9D,gEAAgE;QAChE,iEAAiE;QACjE,8DAA8D;QAC9D,4BAA4B;QAC5B,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC;YACtC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YAClC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;SACzB,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,aAAa,CAAC;YAC7C,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE;gBAClB,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACtC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;YACtC,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,eAAe,KAAK,CAAC,EAAE,CAAC;YAClC,IAAI,cAAc,KAAK,CAAC;gBAAE,mBAAmB,GAAG,IAAI,CAAC;YACrD,MAAM;QACR,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;YAC/B,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,gCAAgC,CAAC,CAAC;gBAChE,4DAA4D;gBAC5D,yDAAyD;gBACzD,4CAA4C;gBAC5C,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,cAAc,IAAI,OAAO,CAAC,eAAe,CAAC;QAC1C,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAChC,CAAC;IAED,IAAI,mBAAmB,EAAE,CAAC;QACxB,OAAO;YACL,KAAK,EAAE,CAAC,SAAS,CAAC;YAClB,QAAQ,EAAE,KAAK;YACf,cAAc,EAAE,CAAC;YACjB,KAAK,EAAE,IAAI;YACX,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,aAAa,cAAc,SAAS,CAAC,CAAC;IAEjD,OAAO;QACL,KAAK;QACL,QAAQ,EAAE,WAAW,GAAG,CAAC;QACzB,cAAc;QACd,KAAK,EAAE,KAAK;QACZ,QAAQ;KACT,CAAC;AACJ,CAAC;AAoBD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAiB;IAC9C,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;IAEzB,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,gEAAgE;QAChE,gEAAgE;QAChE,6CAA6C;QAC7C,EAAE;QACF,gEAAgE;QAChE,gEAAgE;QAChE,uDAAuD;QACvD,mBAAmB;QACnB,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;QACvC,MAAM,IAAI,GAAuD;YAC/D,UAAU,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;SAClC,CAAC;QACF,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC;QACnE,IAAI,YAAY;YAAE,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACnD,MAAM,4BAA4B,CAAC,IAAI,CAAC,CAAC;QACzC,8CAA8C;QAC9C,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACvB,CAAC;IAED,MAAM,SAAS,GAA0B,EAAE,CAAC;IAC5C,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;QAAE,SAAS,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IACtE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACnD,OAAO;QACL,KAAK,EAAE;YACL,mCAAmC,MAAM,CAAC,GAAG,GAAG;YAChD,eAAe,MAAM,CAAC,OAAO,EAAE;SAChC;KACF,CAAC;AACJ,CAAC;AAOD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;AACrC,CAAC;AAcD;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEnC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9D,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,OAAO;gBACL,KAAK,EAAE;oBACL,iCAAiC;oBACjC,yCAAyC;iBAC1C;gBACD,MAAM;aACP,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,CAAC,iCAAiC,CAAC,EAAE,MAAM,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,KAAK,GAAG;QACZ,4BAA4B;QAC5B,gBAAgB,MAAM,CAAC,GAAG,EAAE;QAC5B,gBAAgB,MAAM,CAAC,OAAO,EAAE;QAChC,gBAAgB,YAAY,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE;KACnD,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED,oEAAoE;AACpE,SAAS,YAAY,CAAC,EAAU;IAC9B,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,EAAE,IAAI,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACtC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,GAAG,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,GAAG,EAAE,CAAC;IAChC,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,IAAI,UAAU,GAAG,CAAC;IACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,OAAO,GAAG,EAAE,CAAC;IAChC,OAAO,GAAG,KAAK,IAAI,UAAU,IAAI,UAAU,GAAG,CAAC;AACjD,CAAC;AAED,wEAAwE;AAExE;;;GAGG;AACH,SAAS,gBAAgB,CAAC,GAAW;IACnC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,wDAAwD,GAAG,IAAI,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,GAAW;IACtC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,iEAAiE,GAAG,IAAI,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,8BAA8B,CAAC,CAAC;IAE7E,qEAAqE;IAErE,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SAC7B,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CACL,qBAAqB,EACrB,uDAAuD,CACxD;SACA,MAAM,CACL,aAAa,EACb,0EAA0E,EAC1E,gBAAgB,CACjB;SACA,MAAM,CACL,KAAK,EAAE,IAAoD,EAAE,EAAE;QAC7D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;gBACxB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;gBACvC,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC,CAAC;YACH,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CACF,CAAC;IAEJ,qEAAqE;IAErE,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SAC7B,WAAW,CACV,4DAA4D,CAC7D;SACA,QAAQ,CAAC,MAAM,EAAE,2DAA2D,CAAC;SAC7E,MAAM,CAAC,KAAK,EAAE,EAAsB,EAAE,EAAE;QACvC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;YAC3C,0DAA0D;YAC1D,uDAAuD;YACvD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,QAAQ;gBAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/C,6DAA6D;YAC7D,4DAA4D;YAC5D,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBAC7B,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC7D,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;YACD,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC;gBACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,qEAAqE;IAErE,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;SAC3B,WAAW,CACV,yEAAyE,CAC1E;SACA,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,EAAE,CAAC;YAC3B,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,QAAQ;gBAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/C,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAChD,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,qEAAqE;IAErE,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;SAC/B,WAAW,CAAC,4DAA4D,CAAC;SACzE,MAAM,CACL,iBAAiB,EACjB,kDAAkD,EAClD,mBAAmB,CACpB;SACA,MAAM,CACL,kBAAkB,EAClB,4EAA4E,CAC7E;SACA,MAAM,CAAC,KAAK,EAAE,IAAiD,EAAE,EAAE;QAClE,IAAI,CAAC;YACH,MAAM,KAAK,GAAe,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAChE,IAAI,IAAI,CAAC,UAAU;gBAAE,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;YAC7C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,qEAAqE;IAErE,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SAC7B,WAAW,CAAC,wEAAwE,CAAC;SACrF,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,OAAO,EAAE,CAAC;YAC5B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,qEAAqE;IAErE,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;SACjC,WAAW,CAAC,gDAAgD,CAAC;SAC7D,MAAM,CAAC,QAAQ,EAAE,uCAAuC,CAAC;SACzD,MAAM,CAAC,CAAC,IAAwB,EAAE,EAAE;QACnC,IAAI,CAAC;YACH,MAAM,KAAK,GAAgB,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,IAAI;gBAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;YACjC,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAC7B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACrB,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACrB,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACpB,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACtB,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACrB,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAEvB,OAAO,GAAG,CAAC;AACb,CAAC"}