@praveencs/agent 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/src/cli/commands/daemon.d.ts.map +1 -1
  2. package/dist/src/cli/commands/daemon.js +147 -7
  3. package/dist/src/cli/commands/daemon.js.map +1 -1
  4. package/dist/src/cli/commands/goal.d.ts +7 -0
  5. package/dist/src/cli/commands/goal.d.ts.map +1 -0
  6. package/dist/src/cli/commands/goal.js +246 -0
  7. package/dist/src/cli/commands/goal.js.map +1 -0
  8. package/dist/src/cli/commands/memory.d.ts +3 -0
  9. package/dist/src/cli/commands/memory.d.ts.map +1 -0
  10. package/dist/src/cli/commands/memory.js +108 -0
  11. package/dist/src/cli/commands/memory.js.map +1 -0
  12. package/dist/src/cli/index.d.ts.map +1 -1
  13. package/dist/src/cli/index.js +7 -2
  14. package/dist/src/cli/index.js.map +1 -1
  15. package/dist/src/daemon/manager.d.ts +9 -3
  16. package/dist/src/daemon/manager.d.ts.map +1 -1
  17. package/dist/src/daemon/manager.js +31 -10
  18. package/dist/src/daemon/manager.js.map +1 -1
  19. package/dist/src/daemon/service.d.ts +76 -0
  20. package/dist/src/daemon/service.d.ts.map +1 -0
  21. package/dist/src/daemon/service.js +284 -0
  22. package/dist/src/daemon/service.js.map +1 -0
  23. package/dist/src/daemon/triggers.d.ts +34 -0
  24. package/dist/src/daemon/triggers.d.ts.map +1 -0
  25. package/dist/src/daemon/triggers.js +76 -0
  26. package/dist/src/daemon/triggers.js.map +1 -0
  27. package/dist/src/goals/store.d.ts +128 -0
  28. package/dist/src/goals/store.d.ts.map +1 -0
  29. package/dist/src/goals/store.js +234 -0
  30. package/dist/src/goals/store.js.map +1 -0
  31. package/dist/src/memory/store.d.ts +69 -0
  32. package/dist/src/memory/store.d.ts.map +1 -0
  33. package/dist/src/memory/store.js +255 -0
  34. package/dist/src/memory/store.js.map +1 -0
  35. package/package.json +3 -1
@@ -0,0 +1,76 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ /**
5
+ * Load triggers from .agent/triggers.yaml
6
+ */
7
+ export async function loadTriggers(workDir) {
8
+ const dir = workDir ?? process.cwd();
9
+ const triggersPath = path.join(dir, '.agent', 'triggers.yaml');
10
+ try {
11
+ const content = await readFile(triggersPath, 'utf-8');
12
+ const parsed = parseYaml(content);
13
+ if (!parsed?.triggers || !Array.isArray(parsed.triggers)) {
14
+ return [];
15
+ }
16
+ return parsed.triggers
17
+ .filter(t => t.enabled !== false)
18
+ .map(t => ({
19
+ ...t,
20
+ enabled: t.enabled !== false,
21
+ debounce: t.debounce ?? 2000,
22
+ }));
23
+ }
24
+ catch {
25
+ return [];
26
+ }
27
+ }
28
+ /**
29
+ * Get the default triggers template
30
+ */
31
+ export function getDefaultTriggersYaml() {
32
+ return `# Agent Daemon Triggers
33
+ # These define what the daemon watches and automates.
34
+ # Event types: file.changed, cron, webhook, git.push, goal.check
35
+
36
+ triggers:
37
+ # Process the goal/task queue every 2 minutes
38
+ - name: goal-processor
39
+ event: goal.check
40
+ schedule: "*/2 * * * *"
41
+ enabled: true
42
+ action:
43
+ type: goal-progress
44
+
45
+ # Daily standup report from git log
46
+ # - name: morning-standup
47
+ # event: cron
48
+ # schedule: "0 9 * * 1-5"
49
+ # enabled: false
50
+ # action:
51
+ # skill: git-commit
52
+ # input:
53
+ # type: standup-report
54
+
55
+ # Auto code-review on file changes
56
+ # - name: auto-review
57
+ # event: file.changed
58
+ # watch: "src/**/*.ts"
59
+ # debounce: 5000
60
+ # enabled: false
61
+ # action:
62
+ # skill: code-review
63
+ # input:
64
+ # scope: changed-files
65
+
66
+ # System health check every hour
67
+ # - name: health-check
68
+ # event: cron
69
+ # schedule: "0 * * * *"
70
+ # enabled: false
71
+ # action:
72
+ # skill: system-monitor
73
+ # report: true
74
+ `;
75
+ }
76
+ //# sourceMappingURL=triggers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triggers.js","sourceRoot":"","sources":["../../../src/daemon/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAmC1C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAgB;IAC/C,MAAM,GAAG,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;IAE/D,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAiB,CAAC;QAElD,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvD,OAAO,EAAE,CAAC;QACd,CAAC;QAED,OAAO,MAAM,CAAC,QAAQ;aACjB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACP,GAAG,CAAC;YACJ,OAAO,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK;YAC5B,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;SAC/B,CAAC,CAAC,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB;IAClC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CV,CAAC;AACF,CAAC"}
@@ -0,0 +1,128 @@
1
+ import { MemoryStore } from '../memory/store.js';
2
+ /**
3
+ * Goal & Task management for autonomous execution
4
+ */
5
+ export interface Goal {
6
+ id: number;
7
+ title: string;
8
+ description: string | null;
9
+ status: 'active' | 'paused' | 'completed' | 'failed' | 'cancelled';
10
+ priority: number;
11
+ created_at: string;
12
+ updated_at: string;
13
+ deadline: string | null;
14
+ parent_goal_id: number | null;
15
+ progress: number;
16
+ metadata: Record<string, any>;
17
+ }
18
+ export interface Task {
19
+ id: number;
20
+ goal_id: number;
21
+ title: string;
22
+ description: string | null;
23
+ status: 'pending' | 'queued' | 'running' | 'completed' | 'failed' | 'blocked' | 'cancelled';
24
+ skill: string | null;
25
+ input: Record<string, any>;
26
+ output: string | null;
27
+ depends_on: number[];
28
+ scheduled_at: string | null;
29
+ started_at: string | null;
30
+ completed_at: string | null;
31
+ retry_count: number;
32
+ max_retries: number;
33
+ error: string | null;
34
+ requires_approval: boolean;
35
+ approved_at: string | null;
36
+ created_at: string;
37
+ }
38
+ export declare class GoalStore {
39
+ private db;
40
+ constructor(memoryStore: MemoryStore);
41
+ /**
42
+ * Create a new goal
43
+ */
44
+ addGoal(title: string, options?: {
45
+ description?: string;
46
+ priority?: number;
47
+ deadline?: string;
48
+ parentGoalId?: number;
49
+ }): Goal;
50
+ /**
51
+ * Get a goal by ID
52
+ */
53
+ getGoal(id: number): Goal | null;
54
+ /**
55
+ * List goals by status
56
+ */
57
+ listGoals(status?: Goal['status']): Goal[];
58
+ /**
59
+ * Update goal status
60
+ */
61
+ updateGoalStatus(id: number, status: Goal['status']): void;
62
+ /**
63
+ * Update goal progress (0.0 to 1.0)
64
+ */
65
+ updateGoalProgress(id: number): void;
66
+ /**
67
+ * Delete a goal and its tasks
68
+ */
69
+ removeGoal(id: number): boolean;
70
+ /**
71
+ * Add a task to a goal
72
+ */
73
+ addTask(goalId: number, title: string, options?: {
74
+ description?: string;
75
+ skill?: string;
76
+ input?: Record<string, any>;
77
+ dependsOn?: number[];
78
+ requiresApproval?: boolean;
79
+ scheduledAt?: string;
80
+ }): Task;
81
+ /**
82
+ * Get a task by ID
83
+ */
84
+ getTask(id: number): Task | null;
85
+ /**
86
+ * List tasks for a goal
87
+ */
88
+ listTasks(goalId: number): Task[];
89
+ /**
90
+ * Get the next executable task (respects dependencies)
91
+ */
92
+ getNextTask(): Task | null;
93
+ /**
94
+ * Mark task as running
95
+ */
96
+ startTask(id: number): void;
97
+ /**
98
+ * Mark task as completed
99
+ */
100
+ completeTask(id: number, output: string): void;
101
+ /**
102
+ * Mark task as failed
103
+ */
104
+ failTask(id: number, error: string): void;
105
+ /**
106
+ * Approve a task that requires human approval
107
+ */
108
+ approveTask(id: number): boolean;
109
+ /**
110
+ * Get tasks waiting for approval
111
+ */
112
+ getPendingApprovals(): Task[];
113
+ /**
114
+ * Get summary stats
115
+ */
116
+ stats(): {
117
+ activeGoals: number;
118
+ completedGoals: number;
119
+ pendingTasks: number;
120
+ runningTasks: number;
121
+ completedTasks: number;
122
+ failedTasks: number;
123
+ awaitingApproval: number;
124
+ };
125
+ private parseTask;
126
+ private logAudit;
127
+ }
128
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/goals/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,234 @@
1
+ export class GoalStore {
2
+ db;
3
+ constructor(memoryStore) {
4
+ // Reuse the same database from MemoryStore
5
+ this.db = memoryStore.db;
6
+ }
7
+ // ─── Goal Operations ──────────────────────────────────────
8
+ /**
9
+ * Create a new goal
10
+ */
11
+ addGoal(title, options = {}) {
12
+ const stmt = this.db.prepare(`
13
+ INSERT INTO goals (title, description, priority, deadline, parent_goal_id)
14
+ VALUES (?, ?, ?, ?, ?)
15
+ `);
16
+ const result = stmt.run(title, options.description ?? null, options.priority ?? 5, options.deadline ?? null, options.parentGoalId ?? null);
17
+ this.logAudit('goal.created', 'goal', result.lastInsertRowid, title);
18
+ return this.getGoal(result.lastInsertRowid);
19
+ }
20
+ /**
21
+ * Get a goal by ID
22
+ */
23
+ getGoal(id) {
24
+ const row = this.db.prepare('SELECT * FROM goals WHERE id = ?').get(id);
25
+ if (!row)
26
+ return null;
27
+ return { ...row, metadata: JSON.parse(row.metadata || '{}') };
28
+ }
29
+ /**
30
+ * List goals by status
31
+ */
32
+ listGoals(status) {
33
+ let rows;
34
+ if (status) {
35
+ rows = this.db.prepare('SELECT * FROM goals WHERE status = ? ORDER BY priority ASC, created_at DESC').all(status);
36
+ }
37
+ else {
38
+ rows = this.db.prepare('SELECT * FROM goals ORDER BY status ASC, priority ASC, created_at DESC').all();
39
+ }
40
+ return rows.map(r => ({ ...r, metadata: JSON.parse(r.metadata || '{}') }));
41
+ }
42
+ /**
43
+ * Update goal status
44
+ */
45
+ updateGoalStatus(id, status) {
46
+ this.db.prepare(`
47
+ UPDATE goals SET status = ?, updated_at = datetime('now') WHERE id = ?
48
+ `).run(status, id);
49
+ this.logAudit(`goal.${status}`, 'goal', id, `Goal #${id} → ${status}`);
50
+ }
51
+ /**
52
+ * Update goal progress (0.0 to 1.0)
53
+ */
54
+ updateGoalProgress(id) {
55
+ const tasks = this.listTasks(id);
56
+ if (tasks.length === 0)
57
+ return;
58
+ const completed = tasks.filter(t => t.status === 'completed').length;
59
+ const progress = completed / tasks.length;
60
+ this.db.prepare(`
61
+ UPDATE goals SET progress = ?, updated_at = datetime('now') WHERE id = ?
62
+ `).run(progress, id);
63
+ // Auto-complete goal if all tasks done
64
+ if (progress >= 1.0) {
65
+ this.updateGoalStatus(id, 'completed');
66
+ }
67
+ }
68
+ /**
69
+ * Delete a goal and its tasks
70
+ */
71
+ removeGoal(id) {
72
+ const result = this.db.prepare('DELETE FROM goals WHERE id = ?').run(id);
73
+ return result.changes > 0;
74
+ }
75
+ // ─── Task Operations ──────────────────────────────────────
76
+ /**
77
+ * Add a task to a goal
78
+ */
79
+ addTask(goalId, title, options = {}) {
80
+ const stmt = this.db.prepare(`
81
+ INSERT INTO tasks (goal_id, title, description, skill, input, depends_on, requires_approval, scheduled_at)
82
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
83
+ `);
84
+ const result = stmt.run(goalId, title, options.description ?? null, options.skill ?? null, JSON.stringify(options.input ?? {}), JSON.stringify(options.dependsOn ?? []), options.requiresApproval ? 1 : 0, options.scheduledAt ?? null);
85
+ this.logAudit('task.created', 'task', result.lastInsertRowid, title);
86
+ return this.getTask(result.lastInsertRowid);
87
+ }
88
+ /**
89
+ * Get a task by ID
90
+ */
91
+ getTask(id) {
92
+ const row = this.db.prepare('SELECT * FROM tasks WHERE id = ?').get(id);
93
+ if (!row)
94
+ return null;
95
+ return this.parseTask(row);
96
+ }
97
+ /**
98
+ * List tasks for a goal
99
+ */
100
+ listTasks(goalId) {
101
+ const rows = this.db.prepare('SELECT * FROM tasks WHERE goal_id = ? ORDER BY id ASC').all(goalId);
102
+ return rows.map(r => this.parseTask(r));
103
+ }
104
+ /**
105
+ * Get the next executable task (respects dependencies)
106
+ */
107
+ getNextTask() {
108
+ // Get all pending/queued tasks ordered by goal priority
109
+ const candidates = this.db.prepare(`
110
+ SELECT t.* FROM tasks t
111
+ JOIN goals g ON t.goal_id = g.id
112
+ WHERE t.status IN ('pending', 'queued')
113
+ AND g.status = 'active'
114
+ ORDER BY g.priority ASC, t.id ASC
115
+ `).all();
116
+ for (const row of candidates) {
117
+ const task = this.parseTask(row);
118
+ // Check dependencies
119
+ if (task.depends_on.length > 0) {
120
+ const deps = task.depends_on.map(id => this.getTask(id));
121
+ const allMet = deps.every(d => d?.status === 'completed');
122
+ if (!allMet)
123
+ continue;
124
+ }
125
+ // Check if approval is needed and granted
126
+ if (task.requires_approval && !task.approved_at)
127
+ continue;
128
+ return task;
129
+ }
130
+ return null;
131
+ }
132
+ /**
133
+ * Mark task as running
134
+ */
135
+ startTask(id) {
136
+ this.db.prepare(`
137
+ UPDATE tasks SET status = 'running', started_at = datetime('now') WHERE id = ?
138
+ `).run(id);
139
+ this.logAudit('task.started', 'task', id, `Task #${id} started`);
140
+ }
141
+ /**
142
+ * Mark task as completed
143
+ */
144
+ completeTask(id, output) {
145
+ this.db.prepare(`
146
+ UPDATE tasks SET status = 'completed', output = ?, completed_at = datetime('now')
147
+ WHERE id = ?
148
+ `).run(output, id);
149
+ this.logAudit('task.completed', 'task', id, `Task #${id} completed`);
150
+ // Update goal progress
151
+ const task = this.getTask(id);
152
+ if (task)
153
+ this.updateGoalProgress(task.goal_id);
154
+ }
155
+ /**
156
+ * Mark task as failed
157
+ */
158
+ failTask(id, error) {
159
+ const task = this.getTask(id);
160
+ if (!task)
161
+ return;
162
+ if (task.retry_count < task.max_retries) {
163
+ // Retry
164
+ this.db.prepare(`
165
+ UPDATE tasks SET status = 'pending', retry_count = retry_count + 1, error = ?
166
+ WHERE id = ?
167
+ `).run(error, id);
168
+ this.logAudit('task.retry', 'task', id, `Task #${id} retry ${task.retry_count + 1}/${task.max_retries}: ${error}`);
169
+ }
170
+ else {
171
+ // Final failure
172
+ this.db.prepare(`
173
+ UPDATE tasks SET status = 'failed', error = ?, completed_at = datetime('now')
174
+ WHERE id = ?
175
+ `).run(error, id);
176
+ this.logAudit('task.failed', 'task', id, `Task #${id} failed: ${error}`);
177
+ }
178
+ }
179
+ /**
180
+ * Approve a task that requires human approval
181
+ */
182
+ approveTask(id) {
183
+ const result = this.db.prepare(`
184
+ UPDATE tasks SET approved_at = datetime('now'), status = 'queued'
185
+ WHERE id = ? AND requires_approval = 1
186
+ `).run(id);
187
+ if (result.changes > 0) {
188
+ this.logAudit('task.approved', 'task', id, `Task #${id} approved`);
189
+ }
190
+ return result.changes > 0;
191
+ }
192
+ /**
193
+ * Get tasks waiting for approval
194
+ */
195
+ getPendingApprovals() {
196
+ const rows = this.db.prepare(`
197
+ SELECT * FROM tasks
198
+ WHERE requires_approval = 1 AND approved_at IS NULL
199
+ AND status NOT IN ('cancelled', 'completed', 'failed')
200
+ ORDER BY id ASC
201
+ `).all();
202
+ return rows.map(r => this.parseTask(r));
203
+ }
204
+ /**
205
+ * Get summary stats
206
+ */
207
+ stats() {
208
+ return {
209
+ activeGoals: this.db.prepare("SELECT COUNT(*) as c FROM goals WHERE status = 'active'").get().c,
210
+ completedGoals: this.db.prepare("SELECT COUNT(*) as c FROM goals WHERE status = 'completed'").get().c,
211
+ pendingTasks: this.db.prepare("SELECT COUNT(*) as c FROM tasks WHERE status IN ('pending','queued')").get().c,
212
+ runningTasks: this.db.prepare("SELECT COUNT(*) as c FROM tasks WHERE status = 'running'").get().c,
213
+ completedTasks: this.db.prepare("SELECT COUNT(*) as c FROM tasks WHERE status = 'completed'").get().c,
214
+ failedTasks: this.db.prepare("SELECT COUNT(*) as c FROM tasks WHERE status = 'failed'").get().c,
215
+ awaitingApproval: this.db.prepare("SELECT COUNT(*) as c FROM tasks WHERE requires_approval = 1 AND approved_at IS NULL AND status NOT IN ('cancelled','completed','failed')").get().c,
216
+ };
217
+ }
218
+ // ─── Helpers ──────────────────────────────────────────────
219
+ parseTask(row) {
220
+ return {
221
+ ...row,
222
+ input: JSON.parse(row.input || '{}'),
223
+ depends_on: JSON.parse(row.depends_on || '[]'),
224
+ requires_approval: !!row.requires_approval,
225
+ };
226
+ }
227
+ logAudit(eventType, entityType, entityId, details) {
228
+ this.db.prepare(`
229
+ INSERT INTO audit_events (event_type, entity_type, entity_id, action, details)
230
+ VALUES (?, ?, ?, ?, ?)
231
+ `).run(eventType, entityType, entityId, eventType, details);
232
+ }
233
+ }
234
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/goals/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Memory Store — Persistent agent memory backed by SQLite + FTS5
3
+ *
4
+ * Stores facts, project context, and learned information
5
+ * that persists across sessions.
6
+ */
7
+ export interface Memory {
8
+ id: number;
9
+ content: string;
10
+ category: 'project' | 'preference' | 'fact' | 'learned' | 'general';
11
+ source: 'user' | 'agent' | 'auto';
12
+ tags: string[];
13
+ created_at: string;
14
+ accessed_at: string | null;
15
+ relevance_score: number;
16
+ }
17
+ export interface MemorySearchResult extends Memory {
18
+ rank: number;
19
+ }
20
+ export declare class MemoryStore {
21
+ private db;
22
+ private static instance;
23
+ constructor(dbPath: string);
24
+ /**
25
+ * Get singleton instance scoped to a working directory
26
+ */
27
+ static open(workDir: string): MemoryStore;
28
+ /**
29
+ * Run database migrations
30
+ */
31
+ private migrate;
32
+ /**
33
+ * Save a new memory
34
+ */
35
+ save(content: string, category?: Memory['category'], source?: Memory['source'], tags?: string[]): Memory;
36
+ /**
37
+ * Search memories using full-text search
38
+ */
39
+ search(query: string, limit?: number): MemorySearchResult[];
40
+ /**
41
+ * Get all memories, optionally filtered by category
42
+ */
43
+ list(category?: Memory['category'], limit?: number): Memory[];
44
+ /**
45
+ * Get a specific memory by ID
46
+ */
47
+ getMemory(id: number): Memory | null;
48
+ /**
49
+ * Delete a memory
50
+ */
51
+ forget(id: number): boolean;
52
+ /**
53
+ * Get relevant context for an LLM prompt
54
+ * Searches memories and returns formatted context
55
+ */
56
+ getContext(query: string, maxTokens?: number): string;
57
+ /**
58
+ * Get memory count and stats
59
+ */
60
+ stats(): {
61
+ total: number;
62
+ byCategory: Record<string, number>;
63
+ bySource: Record<string, number>;
64
+ };
65
+ private logAudit;
66
+ getAuditLog(limit?: number): any[];
67
+ close(): void;
68
+ }
69
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/memory/store.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,MAAM,WAAW,MAAM;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACpE,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAClC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAmB,SAAQ,MAAM;IAC9C,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,WAAW;IACpB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA4B;gBAEvC,MAAM,EAAE,MAAM;IAY1B;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;IASzC;;OAEG;IACH,OAAO,CAAC,OAAO;IAsGf;;OAEG;IACH,IAAI,CACA,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAM,CAAC,UAAU,CAAa,EACxC,MAAM,GAAE,MAAM,CAAC,QAAQ,CAAU,EACjC,IAAI,GAAE,MAAM,EAAO,GACpB,MAAM;IAYT;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,kBAAkB,EAAE;IA0BvD;;OAEG;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,SAAK,GAAG,MAAM,EAAE;IAqBzD;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOpC;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAS3B;;;OAGG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM;IAkBlD;;OAEG;IACH,KAAK,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE;IAoBhG,OAAO,CAAC,QAAQ;IAOhB,WAAW,CAAC,KAAK,SAAK,GAAG,GAAG,EAAE;IAQ9B,KAAK,IAAI,IAAI;CAIhB"}