@kernel.chat/kbot 3.8.2 → 3.9.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/agent.d.ts +2 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +18 -1
- package/dist/agent.js.map +1 -1
- package/dist/automations.d.ts +96 -0
- package/dist/automations.d.ts.map +1 -0
- package/dist/automations.js +576 -0
- package/dist/automations.js.map +1 -0
- package/dist/cli.js +265 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
// kbot Automations — Event-driven automation system
|
|
2
|
+
//
|
|
3
|
+
// Always-on agents triggered by file changes, schedules, git hooks, or webhooks.
|
|
4
|
+
// Inspired by Cursor's "Automations" — but running in the terminal.
|
|
5
|
+
//
|
|
6
|
+
// Usage:
|
|
7
|
+
// kbot automate list # List all automations
|
|
8
|
+
// kbot automate add --trigger "file:..." ... # Create automation
|
|
9
|
+
// kbot automate remove <id> # Remove by ID
|
|
10
|
+
// kbot automate run <id> # Manual trigger
|
|
11
|
+
// kbot automate start # Start daemon
|
|
12
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, watch } from 'node:fs';
|
|
13
|
+
import { join, resolve } from 'node:path';
|
|
14
|
+
import { homedir } from 'node:os';
|
|
15
|
+
import { execSync } from 'node:child_process';
|
|
16
|
+
import { randomUUID, timingSafeEqual } from 'node:crypto';
|
|
17
|
+
// ── Paths ──
|
|
18
|
+
const KBOT_DIR = join(homedir(), '.kbot');
|
|
19
|
+
const AUTOMATIONS_FILE = join(KBOT_DIR, 'automations.json');
|
|
20
|
+
const AUTOMATIONS_LOG = join(KBOT_DIR, 'automations.log');
|
|
21
|
+
// ── Persistence ──
|
|
22
|
+
function ensureDir() {
|
|
23
|
+
if (!existsSync(KBOT_DIR)) {
|
|
24
|
+
mkdirSync(KBOT_DIR, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function loadAutomations() {
|
|
28
|
+
ensureDir();
|
|
29
|
+
if (!existsSync(AUTOMATIONS_FILE))
|
|
30
|
+
return [];
|
|
31
|
+
try {
|
|
32
|
+
const raw = readFileSync(AUTOMATIONS_FILE, 'utf-8');
|
|
33
|
+
return JSON.parse(raw);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function saveAutomations(automations) {
|
|
40
|
+
ensureDir();
|
|
41
|
+
writeFileSync(AUTOMATIONS_FILE, JSON.stringify(automations, null, 2), 'utf-8');
|
|
42
|
+
}
|
|
43
|
+
function appendLog(entry) {
|
|
44
|
+
ensureDir();
|
|
45
|
+
const line = JSON.stringify(entry) + '\n';
|
|
46
|
+
try {
|
|
47
|
+
const { appendFileSync } = require('node:fs');
|
|
48
|
+
appendFileSync(AUTOMATIONS_LOG, line, 'utf-8');
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Non-critical — logging failure shouldn't block execution
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// ── CRUD ──
|
|
55
|
+
export function createAutomation(config) {
|
|
56
|
+
const automations = loadAutomations();
|
|
57
|
+
const automation = {
|
|
58
|
+
id: randomUUID().slice(0, 8),
|
|
59
|
+
name: config.name,
|
|
60
|
+
trigger: config.trigger,
|
|
61
|
+
action: config.action,
|
|
62
|
+
enabled: config.enabled ?? true,
|
|
63
|
+
runCount: 0,
|
|
64
|
+
};
|
|
65
|
+
automations.push(automation);
|
|
66
|
+
saveAutomations(automations);
|
|
67
|
+
// If it's a git trigger, install hooks immediately
|
|
68
|
+
if (automation.trigger.type === 'git') {
|
|
69
|
+
installGitHooks(automation);
|
|
70
|
+
}
|
|
71
|
+
return automation;
|
|
72
|
+
}
|
|
73
|
+
export function listAutomations() {
|
|
74
|
+
return loadAutomations();
|
|
75
|
+
}
|
|
76
|
+
export function getAutomation(id) {
|
|
77
|
+
return loadAutomations().find((a) => a.id === id);
|
|
78
|
+
}
|
|
79
|
+
export function removeAutomation(id) {
|
|
80
|
+
const automations = loadAutomations();
|
|
81
|
+
const idx = automations.findIndex((a) => a.id === id);
|
|
82
|
+
if (idx === -1)
|
|
83
|
+
return false;
|
|
84
|
+
const [removed] = automations.splice(idx, 1);
|
|
85
|
+
saveAutomations(automations);
|
|
86
|
+
// Clean up git hooks if needed
|
|
87
|
+
if (removed.trigger.type === 'git') {
|
|
88
|
+
uninstallGitHooks(removed);
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
export function toggleAutomation(id, enabled) {
|
|
93
|
+
const automations = loadAutomations();
|
|
94
|
+
const automation = automations.find((a) => a.id === id);
|
|
95
|
+
if (!automation)
|
|
96
|
+
return false;
|
|
97
|
+
automation.enabled = enabled;
|
|
98
|
+
saveAutomations(automations);
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
// ── Execution ──
|
|
102
|
+
export async function runAutomation(id, context) {
|
|
103
|
+
const automations = loadAutomations();
|
|
104
|
+
const automation = automations.find((a) => a.id === id);
|
|
105
|
+
if (!automation) {
|
|
106
|
+
return {
|
|
107
|
+
automationId: id,
|
|
108
|
+
startedAt: new Date().toISOString(),
|
|
109
|
+
finishedAt: new Date().toISOString(),
|
|
110
|
+
success: false,
|
|
111
|
+
error: `Automation "${id}" not found`,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
const startedAt = new Date().toISOString();
|
|
115
|
+
// Build the prompt with context
|
|
116
|
+
let enrichedPrompt = automation.action.prompt;
|
|
117
|
+
if (context?.filePath) {
|
|
118
|
+
enrichedPrompt += `\n\nTriggered by file: ${context.filePath}`;
|
|
119
|
+
}
|
|
120
|
+
if (context?.gitEvent) {
|
|
121
|
+
enrichedPrompt += `\n\nTriggered by git event: ${context.gitEvent}`;
|
|
122
|
+
}
|
|
123
|
+
if (context?.webhookBody) {
|
|
124
|
+
enrichedPrompt += `\n\nWebhook payload:\n${JSON.stringify(context.webhookBody, null, 2)}`;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
// Dynamic import to avoid circular deps — agent.ts is heavy
|
|
128
|
+
const { runAgent } = await import('./agent.js');
|
|
129
|
+
const result = await runAgent(enrichedPrompt, {
|
|
130
|
+
agent: automation.action.agent,
|
|
131
|
+
});
|
|
132
|
+
// Update run stats
|
|
133
|
+
automation.lastRun = new Date().toISOString();
|
|
134
|
+
automation.runCount += 1;
|
|
135
|
+
saveAutomations(automations);
|
|
136
|
+
const runResult = {
|
|
137
|
+
automationId: id,
|
|
138
|
+
startedAt,
|
|
139
|
+
finishedAt: new Date().toISOString(),
|
|
140
|
+
success: true,
|
|
141
|
+
output: typeof result.content === 'string' ? result.content.slice(0, 2000) : undefined,
|
|
142
|
+
};
|
|
143
|
+
appendLog(runResult);
|
|
144
|
+
return runResult;
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
const runResult = {
|
|
148
|
+
automationId: id,
|
|
149
|
+
startedAt,
|
|
150
|
+
finishedAt: new Date().toISOString(),
|
|
151
|
+
success: false,
|
|
152
|
+
error: err instanceof Error ? err.message : String(err),
|
|
153
|
+
};
|
|
154
|
+
appendLog(runResult);
|
|
155
|
+
return runResult;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// ── Schedule Parsing ──
|
|
159
|
+
/**
|
|
160
|
+
* Parse simple schedule strings into millisecond intervals.
|
|
161
|
+
*
|
|
162
|
+
* Supported formats:
|
|
163
|
+
* "every 5m" → 300_000
|
|
164
|
+
* "every 1h" → 3_600_000
|
|
165
|
+
* "every 30s" → 30_000
|
|
166
|
+
* "daily 09:00" → fires once a day at 09:00 local time
|
|
167
|
+
*/
|
|
168
|
+
export function parseSchedule(cron) {
|
|
169
|
+
const trimmed = cron.trim().toLowerCase();
|
|
170
|
+
// "every Xs", "every Xm", "every Xh"
|
|
171
|
+
const everyMatch = trimmed.match(/^every\s+(\d+)\s*(s|sec|seconds?|m|min|minutes?|h|hr|hours?)$/);
|
|
172
|
+
if (everyMatch) {
|
|
173
|
+
const value = parseInt(everyMatch[1], 10);
|
|
174
|
+
const unit = everyMatch[2];
|
|
175
|
+
if (unit.startsWith('s'))
|
|
176
|
+
return { intervalMs: value * 1_000 };
|
|
177
|
+
if (unit.startsWith('m'))
|
|
178
|
+
return { intervalMs: value * 60_000 };
|
|
179
|
+
if (unit.startsWith('h'))
|
|
180
|
+
return { intervalMs: value * 3_600_000 };
|
|
181
|
+
}
|
|
182
|
+
// "daily HH:MM"
|
|
183
|
+
const dailyMatch = trimmed.match(/^daily\s+(\d{1,2}):(\d{2})$/);
|
|
184
|
+
if (dailyMatch) {
|
|
185
|
+
const hour = parseInt(dailyMatch[1], 10);
|
|
186
|
+
const minute = parseInt(dailyMatch[2], 10);
|
|
187
|
+
if (hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59) {
|
|
188
|
+
return { dailyAt: { hour, minute } };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
throw new Error(`Invalid schedule: "${cron}". Use: "every 5m", "every 1h", "every 30s", or "daily 09:00"`);
|
|
192
|
+
}
|
|
193
|
+
// ── Trigger Parsing (CLI shorthand) ──
|
|
194
|
+
/**
|
|
195
|
+
* Parse CLI trigger shorthand into a typed trigger:
|
|
196
|
+
* "file:src/**\/*.ts:change" → FileTrigger
|
|
197
|
+
* "file:src/**\/*.ts:change,create" → FileTrigger
|
|
198
|
+
* "schedule:every 5m" → ScheduleTrigger
|
|
199
|
+
* "git:pre-commit" → GitTrigger
|
|
200
|
+
* "git:pre-commit,post-commit" → GitTrigger
|
|
201
|
+
* "webhook:/my-hook" → WebhookTrigger
|
|
202
|
+
* "webhook:/my-hook:mysecret" → WebhookTrigger
|
|
203
|
+
*/
|
|
204
|
+
export function parseTriggerString(input) {
|
|
205
|
+
const colonIdx = input.indexOf(':');
|
|
206
|
+
if (colonIdx === -1) {
|
|
207
|
+
throw new Error(`Invalid trigger: "${input}". Format: type:config (e.g., "file:src/**/*.ts:change")`);
|
|
208
|
+
}
|
|
209
|
+
const triggerType = input.slice(0, colonIdx).toLowerCase();
|
|
210
|
+
const rest = input.slice(colonIdx + 1);
|
|
211
|
+
switch (triggerType) {
|
|
212
|
+
case 'file': {
|
|
213
|
+
// file:pattern:events OR file:pattern (defaults to change)
|
|
214
|
+
const parts = rest.split(':');
|
|
215
|
+
const pattern = parts[0];
|
|
216
|
+
const events = parts[1]
|
|
217
|
+
? parts[1].split(',').map((e) => e.trim())
|
|
218
|
+
: ['change'];
|
|
219
|
+
// Validate events
|
|
220
|
+
const validEvents = new Set(['change', 'create', 'delete']);
|
|
221
|
+
for (const e of events) {
|
|
222
|
+
if (!validEvents.has(e)) {
|
|
223
|
+
throw new Error(`Invalid file event: "${e}". Use: change, create, delete`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return { type: 'file', patterns: [pattern], events };
|
|
227
|
+
}
|
|
228
|
+
case 'schedule': {
|
|
229
|
+
// Validate it parses
|
|
230
|
+
parseSchedule(rest);
|
|
231
|
+
return { type: 'schedule', cron: rest };
|
|
232
|
+
}
|
|
233
|
+
case 'git': {
|
|
234
|
+
const events = rest.split(',').map((e) => e.trim());
|
|
235
|
+
const validGitEvents = new Set(['pre-commit', 'post-commit', 'pre-push']);
|
|
236
|
+
for (const e of events) {
|
|
237
|
+
if (!validGitEvents.has(e)) {
|
|
238
|
+
throw new Error(`Invalid git event: "${e}". Use: pre-commit, post-commit, pre-push`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return { type: 'git', events };
|
|
242
|
+
}
|
|
243
|
+
case 'webhook': {
|
|
244
|
+
const parts = rest.split(':');
|
|
245
|
+
const path = parts[0].startsWith('/') ? parts[0] : '/' + parts[0];
|
|
246
|
+
const secret = parts[1] || undefined;
|
|
247
|
+
return { type: 'webhook', path, secret };
|
|
248
|
+
}
|
|
249
|
+
default:
|
|
250
|
+
throw new Error(`Unknown trigger type: "${triggerType}". Use: file, schedule, git, webhook`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// ── File Watching ──
|
|
254
|
+
const activeWatchers = new Map();
|
|
255
|
+
function matchGlob(pattern, filepath) {
|
|
256
|
+
// Simple glob matching: supports * and **
|
|
257
|
+
const regexStr = pattern
|
|
258
|
+
.replace(/\./g, '\\.')
|
|
259
|
+
.replace(/\*\*/g, '{{DOUBLESTAR}}')
|
|
260
|
+
.replace(/\*/g, '[^/]*')
|
|
261
|
+
.replace(/\{\{DOUBLESTAR\}\}/g, '.*');
|
|
262
|
+
const regex = new RegExp('^' + regexStr + '$');
|
|
263
|
+
return regex.test(filepath);
|
|
264
|
+
}
|
|
265
|
+
function startFileWatcher(automation, log) {
|
|
266
|
+
const trigger = automation.trigger;
|
|
267
|
+
const watchers = [];
|
|
268
|
+
// Debounce: avoid triggering multiple times for the same save
|
|
269
|
+
let lastTrigger = 0;
|
|
270
|
+
const DEBOUNCE_MS = 2_000;
|
|
271
|
+
for (const pattern of trigger.patterns) {
|
|
272
|
+
// Determine the watch root — walk up from the pattern to find a concrete dir
|
|
273
|
+
const watchRoot = getWatchRoot(pattern);
|
|
274
|
+
if (!existsSync(watchRoot)) {
|
|
275
|
+
log(`[automations] Warning: watch root "${watchRoot}" does not exist for pattern "${pattern}"`);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
try {
|
|
279
|
+
const watcher = watch(watchRoot, { recursive: true }, (eventType, filename) => {
|
|
280
|
+
if (!filename || !automation.enabled)
|
|
281
|
+
return;
|
|
282
|
+
const fullPath = join(watchRoot, filename);
|
|
283
|
+
const now = Date.now();
|
|
284
|
+
// Check debounce
|
|
285
|
+
if (now - lastTrigger < DEBOUNCE_MS)
|
|
286
|
+
return;
|
|
287
|
+
// Check if the file matches the glob pattern
|
|
288
|
+
if (!matchGlob(pattern, fullPath) && !matchGlob(pattern, filename))
|
|
289
|
+
return;
|
|
290
|
+
// Map fs.watch eventType to our event types
|
|
291
|
+
const eventMap = { rename: 'create', change: 'change' };
|
|
292
|
+
const mappedEvent = eventMap[eventType] || 'change';
|
|
293
|
+
if (!trigger.events.includes(mappedEvent))
|
|
294
|
+
return;
|
|
295
|
+
lastTrigger = now;
|
|
296
|
+
log(`[automations] File trigger fired: ${automation.name} (${filename})`);
|
|
297
|
+
// Fire and forget — don't block the watcher
|
|
298
|
+
runAutomation(automation.id, { filePath: fullPath }).catch((err) => {
|
|
299
|
+
log(`[automations] Error running "${automation.name}": ${err}`);
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
watchers.push(watcher);
|
|
303
|
+
log(`[automations] Watching: ${pattern} (root: ${watchRoot})`);
|
|
304
|
+
}
|
|
305
|
+
catch (err) {
|
|
306
|
+
log(`[automations] Failed to watch "${pattern}": ${err}`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return watchers;
|
|
310
|
+
}
|
|
311
|
+
function getWatchRoot(pattern) {
|
|
312
|
+
// Find the first directory component without a glob character
|
|
313
|
+
const parts = pattern.split('/');
|
|
314
|
+
const concreteParts = [];
|
|
315
|
+
for (const part of parts) {
|
|
316
|
+
if (part.includes('*') || part.includes('?') || part.includes('{'))
|
|
317
|
+
break;
|
|
318
|
+
concreteParts.push(part);
|
|
319
|
+
}
|
|
320
|
+
return concreteParts.length > 0 ? resolve(concreteParts.join('/')) : resolve('.');
|
|
321
|
+
}
|
|
322
|
+
// ── Schedule Timers ──
|
|
323
|
+
const activeTimers = new Map();
|
|
324
|
+
function startScheduleTimer(automation, log) {
|
|
325
|
+
const trigger = automation.trigger;
|
|
326
|
+
const parsed = parseSchedule(trigger.cron);
|
|
327
|
+
if (parsed.intervalMs) {
|
|
328
|
+
log(`[automations] Schedule: "${automation.name}" every ${parsed.intervalMs / 1000}s`);
|
|
329
|
+
const timer = setInterval(() => {
|
|
330
|
+
if (!automation.enabled)
|
|
331
|
+
return;
|
|
332
|
+
log(`[automations] Schedule trigger fired: ${automation.name}`);
|
|
333
|
+
runAutomation(automation.id).catch((err) => {
|
|
334
|
+
log(`[automations] Error running "${automation.name}": ${err}`);
|
|
335
|
+
});
|
|
336
|
+
}, parsed.intervalMs);
|
|
337
|
+
activeTimers.set(automation.id, timer);
|
|
338
|
+
}
|
|
339
|
+
else if (parsed.dailyAt) {
|
|
340
|
+
const { hour, minute } = parsed.dailyAt;
|
|
341
|
+
log(`[automations] Schedule: "${automation.name}" daily at ${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`);
|
|
342
|
+
// Calculate ms until next occurrence, then setInterval for 24h
|
|
343
|
+
const scheduleNext = () => {
|
|
344
|
+
const now = new Date();
|
|
345
|
+
const target = new Date(now);
|
|
346
|
+
target.setHours(hour, minute, 0, 0);
|
|
347
|
+
// If target time already passed today, schedule for tomorrow
|
|
348
|
+
if (target.getTime() <= now.getTime()) {
|
|
349
|
+
target.setDate(target.getDate() + 1);
|
|
350
|
+
}
|
|
351
|
+
const msUntil = target.getTime() - now.getTime();
|
|
352
|
+
const timer = setTimeout(() => {
|
|
353
|
+
if (automation.enabled) {
|
|
354
|
+
log(`[automations] Daily trigger fired: ${automation.name}`);
|
|
355
|
+
runAutomation(automation.id).catch((err) => {
|
|
356
|
+
log(`[automations] Error running "${automation.name}": ${err}`);
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
// Schedule next day
|
|
360
|
+
scheduleNext();
|
|
361
|
+
}, msUntil);
|
|
362
|
+
activeTimers.set(automation.id, timer);
|
|
363
|
+
};
|
|
364
|
+
scheduleNext();
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// ── Git Hooks ──
|
|
368
|
+
function findGitDir() {
|
|
369
|
+
try {
|
|
370
|
+
const gitDir = execSync('git rev-parse --git-dir', { encoding: 'utf-8' }).trim();
|
|
371
|
+
return resolve(gitDir);
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
function installGitHooks(automation) {
|
|
378
|
+
const trigger = automation.trigger;
|
|
379
|
+
const gitDir = findGitDir();
|
|
380
|
+
if (!gitDir)
|
|
381
|
+
return;
|
|
382
|
+
const hooksDir = join(gitDir, 'hooks');
|
|
383
|
+
if (!existsSync(hooksDir)) {
|
|
384
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
385
|
+
}
|
|
386
|
+
for (const event of trigger.events) {
|
|
387
|
+
const hookPath = join(hooksDir, event);
|
|
388
|
+
const marker = `# kbot-automation:${automation.id}`;
|
|
389
|
+
// Read existing hook content (preserve other hooks)
|
|
390
|
+
let existing = '';
|
|
391
|
+
if (existsSync(hookPath)) {
|
|
392
|
+
existing = readFileSync(hookPath, 'utf-8');
|
|
393
|
+
// Don't double-install
|
|
394
|
+
if (existing.includes(marker))
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
// Build the hook script snippet
|
|
398
|
+
const hookSnippet = [
|
|
399
|
+
'',
|
|
400
|
+
marker,
|
|
401
|
+
`# Automation: ${automation.name}`,
|
|
402
|
+
`if command -v kbot >/dev/null 2>&1; then`,
|
|
403
|
+
` kbot automate run ${automation.id} &`,
|
|
404
|
+
`fi`,
|
|
405
|
+
`# end kbot-automation:${automation.id}`,
|
|
406
|
+
'',
|
|
407
|
+
].join('\n');
|
|
408
|
+
if (!existing) {
|
|
409
|
+
// New hook file
|
|
410
|
+
writeFileSync(hookPath, `#!/bin/sh\n${hookSnippet}`, { mode: 0o755 });
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
// Append to existing
|
|
414
|
+
writeFileSync(hookPath, existing + hookSnippet, { mode: 0o755 });
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function uninstallGitHooks(automation) {
|
|
419
|
+
const trigger = automation.trigger;
|
|
420
|
+
const gitDir = findGitDir();
|
|
421
|
+
if (!gitDir)
|
|
422
|
+
return;
|
|
423
|
+
const hooksDir = join(gitDir, 'hooks');
|
|
424
|
+
for (const event of trigger.events) {
|
|
425
|
+
const hookPath = join(hooksDir, event);
|
|
426
|
+
if (!existsSync(hookPath))
|
|
427
|
+
continue;
|
|
428
|
+
const content = readFileSync(hookPath, 'utf-8');
|
|
429
|
+
const startMarker = `# kbot-automation:${automation.id}`;
|
|
430
|
+
const endMarker = `# end kbot-automation:${automation.id}`;
|
|
431
|
+
const startIdx = content.indexOf(startMarker);
|
|
432
|
+
const endIdx = content.indexOf(endMarker);
|
|
433
|
+
if (startIdx === -1 || endIdx === -1)
|
|
434
|
+
continue;
|
|
435
|
+
const cleaned = content.slice(0, startIdx) + content.slice(endIdx + endMarker.length);
|
|
436
|
+
// If only the shebang remains, remove the file
|
|
437
|
+
if (cleaned.trim() === '#!/bin/sh') {
|
|
438
|
+
const { unlinkSync } = require('node:fs');
|
|
439
|
+
unlinkSync(hookPath);
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
writeFileSync(hookPath, cleaned, { mode: 0o755 });
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
// ── Webhook Handler (called by kbot serve) ──
|
|
447
|
+
export async function handleWebhookTrigger(path, body, providedSecret) {
|
|
448
|
+
const automations = loadAutomations();
|
|
449
|
+
const matching = automations.filter((a) => a.enabled && a.trigger.type === 'webhook' && a.trigger.path === path);
|
|
450
|
+
if (matching.length === 0) {
|
|
451
|
+
return { triggered: false, error: `No automation found for webhook path: ${path}` };
|
|
452
|
+
}
|
|
453
|
+
const results = [];
|
|
454
|
+
for (const automation of matching) {
|
|
455
|
+
const trigger = automation.trigger;
|
|
456
|
+
// Validate secret if configured
|
|
457
|
+
if (trigger.secret) {
|
|
458
|
+
if (!providedSecret) {
|
|
459
|
+
results.push({ triggered: false, automationId: automation.id, error: 'Missing webhook secret' });
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
// Constant-time comparison
|
|
463
|
+
const expected = Buffer.from(trigger.secret, 'utf-8');
|
|
464
|
+
const provided = Buffer.from(providedSecret, 'utf-8');
|
|
465
|
+
if (expected.length !== provided.length || !timingSafeEqual(expected, provided)) {
|
|
466
|
+
results.push({ triggered: false, automationId: automation.id, error: 'Invalid webhook secret' });
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
// Fire the automation
|
|
471
|
+
runAutomation(automation.id, { webhookBody: body }).catch(() => {
|
|
472
|
+
// Logged inside runAutomation
|
|
473
|
+
});
|
|
474
|
+
results.push({ triggered: true, automationId: automation.id });
|
|
475
|
+
}
|
|
476
|
+
// Return the first match result
|
|
477
|
+
return results[0] || { triggered: false, error: 'No matching automation' };
|
|
478
|
+
}
|
|
479
|
+
// ── Daemon ──
|
|
480
|
+
let daemonRunning = false;
|
|
481
|
+
export function startAutomationDaemon(options) {
|
|
482
|
+
if (daemonRunning) {
|
|
483
|
+
return { stop: () => { }, running: true };
|
|
484
|
+
}
|
|
485
|
+
const log = options?.log ?? ((msg) => process.stderr.write(msg + '\n'));
|
|
486
|
+
const automations = loadAutomations().filter((a) => a.enabled);
|
|
487
|
+
if (automations.length === 0) {
|
|
488
|
+
log('[automations] No enabled automations found.');
|
|
489
|
+
return { stop: () => { }, running: false };
|
|
490
|
+
}
|
|
491
|
+
daemonRunning = true;
|
|
492
|
+
log(`[automations] Starting daemon with ${automations.length} automation(s)...`);
|
|
493
|
+
// Start file watchers
|
|
494
|
+
for (const a of automations) {
|
|
495
|
+
if (a.trigger.type === 'file') {
|
|
496
|
+
const watchers = startFileWatcher(a, log);
|
|
497
|
+
if (watchers.length > 0) {
|
|
498
|
+
activeWatchers.set(a.id, watchers);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
// Start schedule timers
|
|
503
|
+
for (const a of automations) {
|
|
504
|
+
if (a.trigger.type === 'schedule') {
|
|
505
|
+
startScheduleTimer(a, log);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
// Git hooks are installed at creation time, not by the daemon
|
|
509
|
+
const gitAutomations = automations.filter((a) => a.trigger.type === 'git');
|
|
510
|
+
if (gitAutomations.length > 0) {
|
|
511
|
+
log(`[automations] ${gitAutomations.length} git hook automation(s) active (hooks installed in .git/hooks/)`);
|
|
512
|
+
}
|
|
513
|
+
// Webhook automations are handled by kbot serve
|
|
514
|
+
const webhookAutomations = automations.filter((a) => a.trigger.type === 'webhook');
|
|
515
|
+
if (webhookAutomations.length > 0) {
|
|
516
|
+
log(`[automations] ${webhookAutomations.length} webhook automation(s) active (use "kbot serve" to accept requests)`);
|
|
517
|
+
}
|
|
518
|
+
const stop = () => {
|
|
519
|
+
daemonRunning = false;
|
|
520
|
+
// Stop file watchers
|
|
521
|
+
for (const [id, watchers] of activeWatchers) {
|
|
522
|
+
for (const w of watchers) {
|
|
523
|
+
try {
|
|
524
|
+
w.close();
|
|
525
|
+
}
|
|
526
|
+
catch { /* already closed */ }
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
activeWatchers.clear();
|
|
530
|
+
// Stop timers
|
|
531
|
+
for (const [id, timer] of activeTimers) {
|
|
532
|
+
clearTimeout(timer);
|
|
533
|
+
clearInterval(timer);
|
|
534
|
+
}
|
|
535
|
+
activeTimers.clear();
|
|
536
|
+
log('[automations] Daemon stopped.');
|
|
537
|
+
};
|
|
538
|
+
// Graceful shutdown
|
|
539
|
+
const onSignal = () => {
|
|
540
|
+
stop();
|
|
541
|
+
process.exit(0);
|
|
542
|
+
};
|
|
543
|
+
process.on('SIGINT', onSignal);
|
|
544
|
+
process.on('SIGTERM', onSignal);
|
|
545
|
+
return { stop, running: true };
|
|
546
|
+
}
|
|
547
|
+
// ── Formatting (for CLI output) ──
|
|
548
|
+
export function formatAutomationList(automations) {
|
|
549
|
+
if (automations.length === 0) {
|
|
550
|
+
return 'No automations configured. Use `kbot automate add` to create one.';
|
|
551
|
+
}
|
|
552
|
+
const lines = [];
|
|
553
|
+
lines.push('');
|
|
554
|
+
for (const a of automations) {
|
|
555
|
+
const status = a.enabled ? '\x1b[32m ON\x1b[0m' : '\x1b[31mOFF\x1b[0m';
|
|
556
|
+
const triggerDesc = formatTriggerShort(a.trigger);
|
|
557
|
+
lines.push(` [${status}] \x1b[1m${a.name}\x1b[0m (${a.id})`);
|
|
558
|
+
lines.push(` Trigger: ${triggerDesc}`);
|
|
559
|
+
lines.push(` Agent: ${a.action.agent} | Runs: ${a.runCount}${a.lastRun ? ` | Last: ${a.lastRun}` : ''}`);
|
|
560
|
+
lines.push('');
|
|
561
|
+
}
|
|
562
|
+
return lines.join('\n');
|
|
563
|
+
}
|
|
564
|
+
function formatTriggerShort(trigger) {
|
|
565
|
+
switch (trigger.type) {
|
|
566
|
+
case 'file':
|
|
567
|
+
return `file:${trigger.patterns.join(',')} [${trigger.events.join(',')}]`;
|
|
568
|
+
case 'schedule':
|
|
569
|
+
return `schedule:${trigger.cron}`;
|
|
570
|
+
case 'git':
|
|
571
|
+
return `git:${trigger.events.join(',')}`;
|
|
572
|
+
case 'webhook':
|
|
573
|
+
return `webhook:${trigger.path}${trigger.secret ? ' (secret)' : ''}`;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
//# sourceMappingURL=automations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automations.js","sourceRoot":"","sources":["../src/automations.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,EAAE;AACF,iFAAiF;AACjF,oEAAoE;AACpE,EAAE;AACF,SAAS;AACT,wEAAwE;AACxE,qEAAqE;AACrE,gEAAgE;AAChE,kEAAkE;AAClE,gEAAgE;AAEhE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAkB,MAAM,SAAS,CAAA;AACnG,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,QAAQ,EAAS,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAc,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAqDrE,cAAc;AAEd,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAA;AACzC,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAA;AAC3D,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAA;AAEzD,oBAAoB;AAEpB,SAAS,SAAS;IAChB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,CAAC;AACH,CAAC;AAED,SAAS,eAAe;IACtB,SAAS,EAAE,CAAA;IACX,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC;QAAE,OAAO,EAAE,CAAA;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAA;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAA;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,WAAyB;IAChD,SAAS,EAAE,CAAA;IACX,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;AAChF,CAAC;AAED,SAAS,SAAS,CAAC,KAA0B;IAC3C,SAAS,EAAE,CAAA;IACX,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IACzC,IAAI,CAAC;QACH,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,SAAS,CAA6B,CAAA;QACzE,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;IAC7D,CAAC;AACH,CAAC;AAED,aAAa;AAEb,MAAM,UAAU,gBAAgB,CAAC,MAKhC;IACC,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;IAErC,MAAM,UAAU,GAAe;QAC7B,EAAE,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;QAC/B,QAAQ,EAAE,CAAC;KACZ,CAAA;IAED,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC5B,eAAe,CAAC,WAAW,CAAC,CAAA;IAE5B,mDAAmD;IACnD,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACtC,eAAe,CAAC,UAAU,CAAC,CAAA;IAC7B,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,eAAe,EAAE,CAAA;AAC1B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,OAAO,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;AACnD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACzC,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;IACrC,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IACrD,IAAI,GAAG,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IAE5B,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC5C,eAAe,CAAC,WAAW,CAAC,CAAA;IAE5B,+BAA+B;IAC/B,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACnC,iBAAiB,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAU,EAAE,OAAgB;IAC3D,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;IACrC,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IACvD,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAA;IAE7B,UAAU,CAAC,OAAO,GAAG,OAAO,CAAA;IAC5B,eAAe,CAAC,WAAW,CAAC,CAAA;IAC5B,OAAO,IAAI,CAAA;AACb,CAAC;AAED,kBAAkB;AAElB,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAU,EACV,OAAyE;IAEzE,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;IACrC,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IAEvD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO;YACL,YAAY,EAAE,EAAE;YAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,eAAe,EAAE,aAAa;SACtC,CAAA;IACH,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAE1C,gCAAgC;IAChC,IAAI,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAA;IAC7C,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC;QACtB,cAAc,IAAI,0BAA0B,OAAO,CAAC,QAAQ,EAAE,CAAA;IAChE,CAAC;IACD,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC;QACtB,cAAc,IAAI,+BAA+B,OAAO,CAAC,QAAQ,EAAE,CAAA;IACrE,CAAC;IACD,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;QACzB,cAAc,IAAI,yBAAyB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAA;IAC3F,CAAC;IAED,IAAI,CAAC;QACH,4DAA4D;QAC5D,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAA;QAC/C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,cAAc,EAAE;YAC5C,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK;SAC/B,CAAC,CAAA;QAEF,mBAAmB;QACnB,UAAU,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAC7C,UAAU,CAAC,QAAQ,IAAI,CAAC,CAAA;QACxB,eAAe,CAAC,WAAW,CAAC,CAAA;QAE5B,MAAM,SAAS,GAAwB;YACrC,YAAY,EAAE,EAAE;YAChB,SAAS;YACT,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SACvF,CAAA;QAED,SAAS,CAAC,SAAS,CAAC,CAAA;QACpB,OAAO,SAAS,CAAA;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,SAAS,GAAwB;YACrC,YAAY,EAAE,EAAE;YAChB,SAAS;YACT,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAA;QAED,SAAS,CAAC,SAAS,CAAC,CAAA;QACpB,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,yBAAyB;AAEzB;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAEzC,qCAAqC;IACrC,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAA;IACjG,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACzC,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;QAE1B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,UAAU,EAAE,KAAK,GAAG,KAAK,EAAE,CAAA;QAC9D,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,UAAU,EAAE,KAAK,GAAG,MAAM,EAAE,CAAA;QAC/D,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,UAAU,EAAE,KAAK,GAAG,SAAS,EAAE,CAAA;IACpE,CAAC;IAED,gBAAgB;IAChB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAC/D,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAC1C,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,EAAE,EAAE,CAAC;YAC3D,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;QACtC,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,+DAA+D,CAAC,CAAA;AAC5G,CAAC;AAED,wCAAwC;AAExC;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACnC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,qBAAqB,KAAK,0DAA0D,CAAC,CAAA;IACvG,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAA;IAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAA;IAEtC,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,6DAA6D;YAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;YACxB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;gBACrB,CAAC,CAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAA2B;gBACrE,CAAC,CAAC,CAAC,QAAiB,CAAC,CAAA;YAEvB,kBAAkB;YAClB,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAA;YAC3D,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,gCAAgC,CAAC,CAAA;gBAC5E,CAAC;YACH,CAAC;YAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;QACtD,CAAC;QAED,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,qBAAqB;YACrB,aAAa,CAAC,IAAI,CAAC,CAAA;YACnB,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;QACzC,CAAC;QAED,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAyB,CAAA;YAC3E,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,CAAC,CAAC,CAAA;YACzE,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC3B,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,2CAA2C,CAAC,CAAA;gBACtF,CAAC;YACH,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;QAChC,CAAC;QAED,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;YACjE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,SAAS,CAAA;YACpC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;QAC1C,CAAC;QAED;YACE,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,sCAAsC,CAAC,CAAA;IAChG,CAAC;AACH,CAAC;AAED,sBAAsB;AAEtB,MAAM,cAAc,GAA6B,IAAI,GAAG,EAAE,CAAA;AAE1D,SAAS,SAAS,CAAC,OAAe,EAAE,QAAgB;IAClD,0CAA0C;IAC1C,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC;SAClC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,OAAO,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAA;IACvC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,QAAQ,GAAG,GAAG,CAAC,CAAA;IAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;AAC7B,CAAC;AAED,SAAS,gBAAgB,CAAC,UAAsB,EAAE,GAA0B;IAC1E,MAAM,OAAO,GAAG,UAAU,CAAC,OAAsB,CAAA;IACjD,MAAM,QAAQ,GAAgB,EAAE,CAAA;IAEhC,8DAA8D;IAC9D,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,MAAM,WAAW,GAAG,KAAK,CAAA;IAEzB,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACvC,6EAA6E;QAC7E,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;QAEvC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,GAAG,CAAC,sCAAsC,SAAS,iCAAiC,OAAO,GAAG,CAAC,CAAA;YAC/F,SAAQ;QACV,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE;gBAC5E,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC,OAAO;oBAAE,OAAM;gBAE5C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;gBAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAEtB,iBAAiB;gBACjB,IAAI,GAAG,GAAG,WAAW,GAAG,WAAW;oBAAE,OAAM;gBAE3C,6CAA6C;gBAC7C,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC;oBAAE,OAAM;gBAE1E,4CAA4C;gBAC5C,MAAM,QAAQ,GAA2B,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;gBAC/E,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAA;gBAEnD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAA6C,CAAC;oBAAE,OAAM;gBAEnF,WAAW,GAAG,GAAG,CAAA;gBACjB,GAAG,CAAC,qCAAqC,UAAU,CAAC,IAAI,KAAK,QAAQ,GAAG,CAAC,CAAA;gBAEzE,4CAA4C;gBAC5C,aAAa,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBACjE,GAAG,CAAC,gCAAgC,UAAU,CAAC,IAAI,MAAM,GAAG,EAAE,CAAC,CAAA;gBACjE,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;YAEF,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACtB,GAAG,CAAC,2BAA2B,OAAO,WAAW,SAAS,GAAG,CAAC,CAAA;QAChE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,kCAAkC,OAAO,MAAM,GAAG,EAAE,CAAC,CAAA;QAC3D,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,8DAA8D;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,aAAa,GAAa,EAAE,CAAA;IAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,MAAK;QACzE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;IAED,OAAO,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AACnF,CAAC;AAED,wBAAwB;AAExB,MAAM,YAAY,GAAgF,IAAI,GAAG,EAAE,CAAA;AAE3G,SAAS,kBAAkB,CAAC,UAAsB,EAAE,GAA0B;IAC5E,MAAM,OAAO,GAAG,UAAU,CAAC,OAA0B,CAAA;IACrD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAE1C,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,GAAG,CAAC,4BAA4B,UAAU,CAAC,IAAI,WAAW,MAAM,CAAC,UAAU,GAAG,IAAI,GAAG,CAAC,CAAA;QACtF,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,IAAI,CAAC,UAAU,CAAC,OAAO;gBAAE,OAAM;YAC/B,GAAG,CAAC,yCAAyC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAA;YAC/D,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACzC,GAAG,CAAC,gCAAgC,UAAU,CAAC,IAAI,MAAM,GAAG,EAAE,CAAC,CAAA;YACjE,CAAC,CAAC,CAAA;QACJ,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAA;QAErB,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;IACxC,CAAC;SAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC1B,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAA;QACvC,GAAG,CAAC,4BAA4B,UAAU,CAAC,IAAI,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;QAEhI,+DAA+D;QAC/D,MAAM,YAAY,GAAG,GAAS,EAAE;YAC9B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;YACtB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAA;YAC5B,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;YAEnC,6DAA6D;YAC7D,IAAI,MAAM,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;gBACtC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;YACtC,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAA;YAChD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;oBACvB,GAAG,CAAC,sCAAsC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAA;oBAC5D,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;wBACzC,GAAG,CAAC,gCAAgC,UAAU,CAAC,IAAI,MAAM,GAAG,EAAE,CAAC,CAAA;oBACjE,CAAC,CAAC,CAAA;gBACJ,CAAC;gBACD,oBAAoB;gBACpB,YAAY,EAAE,CAAA;YAChB,CAAC,EAAE,OAAO,CAAC,CAAA;YAEX,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;QACxC,CAAC,CAAA;QAED,YAAY,EAAE,CAAA;IAChB,CAAC;AACH,CAAC;AAED,kBAAkB;AAElB,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,yBAAyB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QAChF,OAAO,OAAO,CAAC,MAAM,CAAC,CAAA;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,UAAsB;IAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,OAAqB,CAAA;IAChD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM;QAAE,OAAM;IAEnB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACtC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QACtC,MAAM,MAAM,GAAG,qBAAqB,UAAU,CAAC,EAAE,EAAE,CAAA;QAEnD,oDAAoD;QACpD,IAAI,QAAQ,GAAG,EAAE,CAAA;QACjB,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAE1C,uBAAuB;YACvB,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,SAAQ;QACzC,CAAC;QAED,gCAAgC;QAChC,MAAM,WAAW,GAAG;YAClB,EAAE;YACF,MAAM;YACN,iBAAiB,UAAU,CAAC,IAAI,EAAE;YAClC,0CAA0C;YAC1C,uBAAuB,UAAU,CAAC,EAAE,IAAI;YACxC,IAAI;YACJ,yBAAyB,UAAU,CAAC,EAAE,EAAE;YACxC,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEZ,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,gBAAgB;YAChB,aAAa,CAAC,QAAQ,EAAE,cAAc,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QACvE,CAAC;aAAM,CAAC;YACN,qBAAqB;YACrB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAClE,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,UAAsB;IAC/C,MAAM,OAAO,GAAG,UAAU,CAAC,OAAqB,CAAA;IAChD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM;QAAE,OAAM;IAEnB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAEtC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QACtC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,SAAQ;QAEnC,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC/C,MAAM,WAAW,GAAG,qBAAqB,UAAU,CAAC,EAAE,EAAE,CAAA;QACxD,MAAM,SAAS,GAAG,yBAAyB,UAAU,CAAC,EAAE,EAAE,CAAA;QAE1D,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAEzC,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC;YAAE,SAAQ;QAE9C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;QAErF,+CAA+C;QAC/C,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,WAAW,EAAE,CAAC;YACnC,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,SAAS,CAA6B,CAAA;YACrE,UAAU,CAAC,QAAQ,CAAC,CAAA;QACtB,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QACnD,CAAC;IACH,CAAC;AACH,CAAC;AAED,+CAA+C;AAE/C,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAY,EACZ,IAAa,EACb,cAAuB;IAEvB,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;IACrC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,IAAK,CAAC,CAAC,OAA0B,CAAC,IAAI,KAAK,IAAI,CAChG,CAAA;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,yCAAyC,IAAI,EAAE,EAAE,CAAA;IACrF,CAAC;IAED,MAAM,OAAO,GAAoE,EAAE,CAAA;IAEnF,KAAK,MAAM,UAAU,IAAI,QAAQ,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAyB,CAAA;QAEpD,gCAAgC;QAChC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAA;gBAChG,SAAQ;YACV,CAAC;YAED,2BAA2B;YAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;YACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;YACrD,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;gBAChF,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAA;gBAChG,SAAQ;YACV,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,aAAa,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YAC7D,8BAA8B;QAChC,CAAC,CAAC,CAAA;QAEF,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,gCAAgC;IAChC,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAA;AAC5E,CAAC;AAED,eAAe;AAEf,IAAI,aAAa,GAAG,KAAK,CAAA;AAEzB,MAAM,UAAU,qBAAqB,CAAC,OAAyC;IAI7E,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1C,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAA;IAC/E,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;IAE9D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,GAAG,CAAC,6CAA6C,CAAC,CAAA;QAClD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IAC3C,CAAC;IAED,aAAa,GAAG,IAAI,CAAA;IACpB,GAAG,CAAC,sCAAsC,WAAW,CAAC,MAAM,mBAAmB,CAAC,CAAA;IAEhF,sBAAsB;IACtB,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;YACzC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAClC,kBAAkB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;IAED,8DAA8D;IAC9D,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,KAAK,CAAC,CAAA;IAC1E,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,GAAG,CAAC,iBAAiB,cAAc,CAAC,MAAM,iEAAiE,CAAC,CAAA;IAC9G,CAAC;IAED,gDAAgD;IAChD,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAA;IAClF,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,iBAAiB,kBAAkB,CAAC,MAAM,qEAAqE,CAAC,CAAA;IACtH,CAAC;IAED,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,aAAa,GAAG,KAAK,CAAA;QAErB,qBAAqB;QACrB,KAAK,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,cAAc,EAAE,CAAC;YAC5C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,IAAI,CAAC;oBAAC,CAAC,CAAC,KAAK,EAAE,CAAA;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;QACD,cAAc,CAAC,KAAK,EAAE,CAAA;QAEtB,cAAc;QACd,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,YAAY,EAAE,CAAC;YACvC,YAAY,CAAC,KAAsC,CAAC,CAAA;YACpD,aAAa,CAAC,KAAuC,CAAC,CAAA;QACxD,CAAC;QACD,YAAY,CAAC,KAAK,EAAE,CAAA;QAEpB,GAAG,CAAC,+BAA+B,CAAC,CAAA;IACtC,CAAC,CAAA;IAED,oBAAoB;IACpB,MAAM,QAAQ,GAAG,GAAS,EAAE;QAC1B,IAAI,EAAE,CAAA;QACN,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAA;IACD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAC9B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;IAE/B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAChC,CAAC;AAED,oCAAoC;AAEpC,MAAM,UAAU,oBAAoB,CAAC,WAAyB;IAC5D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,mEAAmE,CAAA;IAC5E,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAEd,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAA;QACtE,MAAM,WAAW,GAAG,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;QACjD,KAAK,CAAC,IAAI,CAAC,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAC9D,KAAK,CAAC,IAAI,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAA;QAC5C,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,KAAK,YAAY,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAC9G,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,SAAS,kBAAkB,CAAC,OAA0B;IACpD,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,MAAM;YACT,OAAO,QAAQ,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;QAC3E,KAAK,UAAU;YACb,OAAO,YAAY,OAAO,CAAC,IAAI,EAAE,CAAA;QACnC,KAAK,KAAK;YACR,OAAO,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;QAC1C,KAAK,SAAS;YACZ,OAAO,WAAW,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;IACxE,CAAC;AACH,CAAC"}
|