mstro-app 0.3.7 → 0.3.9
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/README.md +4 -8
- package/bin/mstro.js +54 -15
- package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -1
- package/dist/server/cli/headless/claude-invoker.js +18 -9
- package/dist/server/cli/headless/claude-invoker.js.map +1 -1
- package/dist/server/cli/headless/headless-logger.d.ts +10 -0
- package/dist/server/cli/headless/headless-logger.d.ts.map +1 -0
- package/dist/server/cli/headless/headless-logger.js +66 -0
- package/dist/server/cli/headless/headless-logger.js.map +1 -0
- package/dist/server/cli/headless/mcp-config.d.ts.map +1 -1
- package/dist/server/cli/headless/mcp-config.js +6 -5
- package/dist/server/cli/headless/mcp-config.js.map +1 -1
- package/dist/server/cli/headless/runner.d.ts.map +1 -1
- package/dist/server/cli/headless/runner.js +4 -0
- package/dist/server/cli/headless/runner.js.map +1 -1
- package/dist/server/cli/headless/stall-assessor.d.ts +21 -0
- package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
- package/dist/server/cli/headless/stall-assessor.js +74 -20
- package/dist/server/cli/headless/stall-assessor.js.map +1 -1
- package/dist/server/cli/headless/tool-watchdog.d.ts +0 -12
- package/dist/server/cli/headless/tool-watchdog.d.ts.map +1 -1
- package/dist/server/cli/headless/tool-watchdog.js +30 -9
- package/dist/server/cli/headless/tool-watchdog.js.map +1 -1
- package/dist/server/cli/headless/types.d.ts +8 -1
- package/dist/server/cli/headless/types.d.ts.map +1 -1
- package/dist/server/cli/improvisation-session-manager.d.ts +16 -0
- package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
- package/dist/server/cli/improvisation-session-manager.js +94 -11
- package/dist/server/cli/improvisation-session-manager.js.map +1 -1
- package/dist/server/index.js +0 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/bouncer-cli.d.ts +3 -0
- package/dist/server/mcp/bouncer-cli.d.ts.map +1 -0
- package/dist/server/mcp/bouncer-cli.js +54 -0
- package/dist/server/mcp/bouncer-cli.js.map +1 -0
- package/dist/server/mcp/bouncer-integration.d.ts +2 -0
- package/dist/server/mcp/bouncer-integration.d.ts.map +1 -1
- package/dist/server/mcp/bouncer-integration.js +55 -39
- package/dist/server/mcp/bouncer-integration.js.map +1 -1
- package/dist/server/mcp/bouncer-sandbox.d.ts +60 -0
- package/dist/server/mcp/bouncer-sandbox.d.ts.map +1 -0
- package/dist/server/mcp/bouncer-sandbox.js +182 -0
- package/dist/server/mcp/bouncer-sandbox.js.map +1 -0
- package/dist/server/mcp/security-patterns.d.ts +6 -12
- package/dist/server/mcp/security-patterns.d.ts.map +1 -1
- package/dist/server/mcp/security-patterns.js +197 -10
- package/dist/server/mcp/security-patterns.js.map +1 -1
- package/dist/server/services/plan/composer.d.ts +4 -0
- package/dist/server/services/plan/composer.d.ts.map +1 -0
- package/dist/server/services/plan/composer.js +181 -0
- package/dist/server/services/plan/composer.js.map +1 -0
- package/dist/server/services/plan/dependency-resolver.d.ts +28 -0
- package/dist/server/services/plan/dependency-resolver.d.ts.map +1 -0
- package/dist/server/services/plan/dependency-resolver.js +152 -0
- package/dist/server/services/plan/dependency-resolver.js.map +1 -0
- package/dist/server/services/plan/executor.d.ts +91 -0
- package/dist/server/services/plan/executor.d.ts.map +1 -0
- package/dist/server/services/plan/executor.js +545 -0
- package/dist/server/services/plan/executor.js.map +1 -0
- package/dist/server/services/plan/parser.d.ts +11 -0
- package/dist/server/services/plan/parser.d.ts.map +1 -0
- package/dist/server/services/plan/parser.js +415 -0
- package/dist/server/services/plan/parser.js.map +1 -0
- package/dist/server/services/plan/state-reconciler.d.ts +2 -0
- package/dist/server/services/plan/state-reconciler.d.ts.map +1 -0
- package/dist/server/services/plan/state-reconciler.js +105 -0
- package/dist/server/services/plan/state-reconciler.js.map +1 -0
- package/dist/server/services/plan/types.d.ts +120 -0
- package/dist/server/services/plan/types.d.ts.map +1 -0
- package/dist/server/services/plan/types.js +4 -0
- package/dist/server/services/plan/types.js.map +1 -0
- package/dist/server/services/plan/watcher.d.ts +14 -0
- package/dist/server/services/plan/watcher.d.ts.map +1 -0
- package/dist/server/services/plan/watcher.js +69 -0
- package/dist/server/services/plan/watcher.js.map +1 -0
- package/dist/server/services/websocket/file-explorer-handlers.js +20 -0
- package/dist/server/services/websocket/file-explorer-handlers.js.map +1 -1
- package/dist/server/services/websocket/handler.d.ts +0 -1
- package/dist/server/services/websocket/handler.d.ts.map +1 -1
- package/dist/server/services/websocket/handler.js +28 -2
- package/dist/server/services/websocket/handler.js.map +1 -1
- package/dist/server/services/websocket/plan-handlers.d.ts +6 -0
- package/dist/server/services/websocket/plan-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/plan-handlers.js +494 -0
- package/dist/server/services/websocket/plan-handlers.js.map +1 -0
- package/dist/server/services/websocket/quality-handlers.d.ts +4 -0
- package/dist/server/services/websocket/quality-handlers.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-handlers.js +470 -0
- package/dist/server/services/websocket/quality-handlers.js.map +1 -0
- package/dist/server/services/websocket/quality-persistence.d.ts +45 -0
- package/dist/server/services/websocket/quality-persistence.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-persistence.js +187 -0
- package/dist/server/services/websocket/quality-persistence.js.map +1 -0
- package/dist/server/services/websocket/quality-service.d.ts +54 -0
- package/dist/server/services/websocket/quality-service.d.ts.map +1 -0
- package/dist/server/services/websocket/quality-service.js +816 -0
- package/dist/server/services/websocket/quality-service.js.map +1 -0
- package/dist/server/services/websocket/session-handlers.d.ts.map +1 -1
- package/dist/server/services/websocket/session-handlers.js +23 -0
- package/dist/server/services/websocket/session-handlers.js.map +1 -1
- package/dist/server/services/websocket/types.d.ts +2 -2
- package/dist/server/services/websocket/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/server/cli/headless/claude-invoker.ts +21 -9
- package/server/cli/headless/headless-logger.ts +78 -0
- package/server/cli/headless/mcp-config.ts +6 -5
- package/server/cli/headless/runner.ts +4 -0
- package/server/cli/headless/stall-assessor.ts +101 -20
- package/server/cli/headless/tool-watchdog.ts +18 -9
- package/server/cli/headless/types.ts +10 -1
- package/server/cli/improvisation-session-manager.ts +118 -11
- package/server/index.ts +0 -4
- package/server/mcp/bouncer-cli.ts +73 -0
- package/server/mcp/bouncer-integration.ts +66 -44
- package/server/mcp/bouncer-sandbox.ts +214 -0
- package/server/mcp/security-patterns.ts +206 -10
- package/server/services/plan/composer.ts +199 -0
- package/server/services/plan/dependency-resolver.ts +179 -0
- package/server/services/plan/executor.ts +604 -0
- package/server/services/plan/parser.ts +459 -0
- package/server/services/plan/state-reconciler.ts +132 -0
- package/server/services/plan/types.ts +164 -0
- package/server/services/plan/watcher.ts +73 -0
- package/server/services/websocket/file-explorer-handlers.ts +20 -0
- package/server/services/websocket/handler.ts +28 -2
- package/server/services/websocket/plan-handlers.ts +592 -0
- package/server/services/websocket/quality-handlers.ts +570 -0
- package/server/services/websocket/quality-persistence.ts +250 -0
- package/server/services/websocket/quality-service.ts +975 -0
- package/server/services/websocket/session-handlers.ts +26 -0
- package/server/services/websocket/types.ts +62 -2
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Mstro, Inc. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file for details.
|
|
3
|
+
/**
|
|
4
|
+
* Detect cycles in the dependency graph.
|
|
5
|
+
* Returns the first cycle found as an array of issue IDs, or null if acyclic.
|
|
6
|
+
*/
|
|
7
|
+
export function detectCycles(issues) {
|
|
8
|
+
const issueByPath = new Map();
|
|
9
|
+
for (const issue of issues) {
|
|
10
|
+
issueByPath.set(issue.path, issue);
|
|
11
|
+
}
|
|
12
|
+
// DFS with coloring: 0=white, 1=gray, 2=black
|
|
13
|
+
const color = new Map();
|
|
14
|
+
const parent = new Map();
|
|
15
|
+
for (const issue of issues) {
|
|
16
|
+
color.set(issue.path, 0);
|
|
17
|
+
}
|
|
18
|
+
for (const issue of issues) {
|
|
19
|
+
if (color.get(issue.path) === 0) {
|
|
20
|
+
const cycle = dfs(issue.path, issueByPath, color, parent);
|
|
21
|
+
if (cycle)
|
|
22
|
+
return cycle;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
function dfs(path, issueByPath, color, parent) {
|
|
28
|
+
color.set(path, 1); // Gray
|
|
29
|
+
const issue = issueByPath.get(path);
|
|
30
|
+
if (!issue) {
|
|
31
|
+
color.set(path, 2);
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
for (const dep of issue.blocks) {
|
|
35
|
+
if (!issueByPath.has(dep))
|
|
36
|
+
continue;
|
|
37
|
+
const depColor = color.get(dep);
|
|
38
|
+
if (depColor === 1) {
|
|
39
|
+
// Found cycle — reconstruct
|
|
40
|
+
const cycle = [dep, path];
|
|
41
|
+
let cur = path;
|
|
42
|
+
while (parent.has(cur) && parent.get(cur) !== dep) {
|
|
43
|
+
cur = parent.get(cur);
|
|
44
|
+
cycle.push(cur);
|
|
45
|
+
}
|
|
46
|
+
return cycle.map(p => issueByPath.get(p)?.id || p);
|
|
47
|
+
}
|
|
48
|
+
if (depColor === 0) {
|
|
49
|
+
parent.set(dep, path);
|
|
50
|
+
const cycle = dfs(dep, issueByPath, color, parent);
|
|
51
|
+
if (cycle)
|
|
52
|
+
return cycle;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
color.set(path, 2); // Black
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Compute the set of issues that are ready to work on.
|
|
60
|
+
* An issue is ready if:
|
|
61
|
+
* - It's not an epic
|
|
62
|
+
* - Its status is backlog or todo (not started, done, or cancelled)
|
|
63
|
+
* - All its blocked_by items are done or cancelled
|
|
64
|
+
*
|
|
65
|
+
* If epicScope is provided, only returns issues belonging to that epic.
|
|
66
|
+
*/
|
|
67
|
+
export function resolveReadyToWork(issues, epicScope) {
|
|
68
|
+
const issueByPath = new Map();
|
|
69
|
+
for (const issue of issues) {
|
|
70
|
+
issueByPath.set(issue.path, issue);
|
|
71
|
+
}
|
|
72
|
+
const readyStatuses = new Set(['backlog', 'todo']);
|
|
73
|
+
const doneStatuses = new Set(['done', 'cancelled']);
|
|
74
|
+
const priorityOrder = { P0: 0, P1: 1, P2: 2, P3: 3 };
|
|
75
|
+
// Build set of child paths for epic scoping
|
|
76
|
+
let epicChildPaths = null;
|
|
77
|
+
if (epicScope) {
|
|
78
|
+
const epic = issueByPath.get(epicScope);
|
|
79
|
+
if (epic) {
|
|
80
|
+
epicChildPaths = new Set(epic.children);
|
|
81
|
+
// Also include issues that reference this epic via their epic field
|
|
82
|
+
for (const issue of issues) {
|
|
83
|
+
if (issue.epic === epicScope)
|
|
84
|
+
epicChildPaths.add(issue.path);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return issues
|
|
89
|
+
.filter(issue => {
|
|
90
|
+
if (issue.type === 'epic')
|
|
91
|
+
return false;
|
|
92
|
+
if (!readyStatuses.has(issue.status))
|
|
93
|
+
return false;
|
|
94
|
+
// If scoped to an epic, only include that epic's children
|
|
95
|
+
if (epicChildPaths && !epicChildPaths.has(issue.path))
|
|
96
|
+
return false;
|
|
97
|
+
// Check all blockers are resolved
|
|
98
|
+
if (issue.blockedBy.length > 0) {
|
|
99
|
+
const allResolved = issue.blockedBy.every(bp => {
|
|
100
|
+
const blocker = issueByPath.get(bp);
|
|
101
|
+
return blocker && doneStatuses.has(blocker.status);
|
|
102
|
+
});
|
|
103
|
+
if (!allResolved)
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
return true;
|
|
107
|
+
})
|
|
108
|
+
.sort((a, b) => {
|
|
109
|
+
// Sort by priority (P0 first)
|
|
110
|
+
return (priorityOrder[a.priority] ?? 9) - (priorityOrder[b.priority] ?? 9);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Compute the critical path through incomplete issues.
|
|
115
|
+
* Returns the longest chain of dependent issues.
|
|
116
|
+
*/
|
|
117
|
+
export function computeCriticalPath(issues) {
|
|
118
|
+
const issueByPath = new Map();
|
|
119
|
+
for (const issue of issues) {
|
|
120
|
+
issueByPath.set(issue.path, issue);
|
|
121
|
+
}
|
|
122
|
+
const doneStatuses = new Set(['done', 'cancelled']);
|
|
123
|
+
const incompleteIssues = issues.filter(i => !doneStatuses.has(i.status) && i.type !== 'epic');
|
|
124
|
+
// Compute longest path using DFS with memoization
|
|
125
|
+
const longestFrom = new Map();
|
|
126
|
+
function getLongest(path) {
|
|
127
|
+
if (longestFrom.has(path))
|
|
128
|
+
return longestFrom.get(path);
|
|
129
|
+
const issue = issueByPath.get(path);
|
|
130
|
+
if (!issue || doneStatuses.has(issue.status)) {
|
|
131
|
+
longestFrom.set(path, []);
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
let best = [];
|
|
135
|
+
for (const dep of issue.blocks) {
|
|
136
|
+
const sub = getLongest(dep);
|
|
137
|
+
if (sub.length > best.length)
|
|
138
|
+
best = sub;
|
|
139
|
+
}
|
|
140
|
+
const result = [issue, ...best];
|
|
141
|
+
longestFrom.set(path, result);
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
let criticalPath = [];
|
|
145
|
+
for (const issue of incompleteIssues) {
|
|
146
|
+
const path = getLongest(issue.path);
|
|
147
|
+
if (path.length > criticalPath.length)
|
|
148
|
+
criticalPath = path;
|
|
149
|
+
}
|
|
150
|
+
return criticalPath;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=dependency-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency-resolver.js","sourceRoot":"","sources":["../../../../server/services/plan/dependency-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan Executor — Wave-based execution with Claude Code Agent Teams.
|
|
3
|
+
*
|
|
4
|
+
* Reads the dependency DAG from .pm/, picks ALL unblocked issues per wave,
|
|
5
|
+
* spawns a coordinator Claude session that uses Agent Teams to execute them
|
|
6
|
+
* in parallel, then reconciles state and repeats for newly-unblocked issues.
|
|
7
|
+
*/
|
|
8
|
+
import { EventEmitter } from 'node:events';
|
|
9
|
+
export type ExecutionStatus = 'idle' | 'starting' | 'executing' | 'paused' | 'stopping' | 'complete' | 'error';
|
|
10
|
+
export interface ExecutionMetrics {
|
|
11
|
+
issuesCompleted: number;
|
|
12
|
+
issuesAttempted: number;
|
|
13
|
+
totalDuration: number;
|
|
14
|
+
currentIssueId: string | null;
|
|
15
|
+
/** IDs of issues being executed in the current wave */
|
|
16
|
+
currentWaveIds: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare class PlanExecutor extends EventEmitter {
|
|
19
|
+
private status;
|
|
20
|
+
private workingDir;
|
|
21
|
+
private shouldStop;
|
|
22
|
+
private shouldPause;
|
|
23
|
+
private epicScope;
|
|
24
|
+
private metrics;
|
|
25
|
+
constructor(workingDir: string);
|
|
26
|
+
getStatus(): ExecutionStatus;
|
|
27
|
+
getMetrics(): ExecutionMetrics;
|
|
28
|
+
startEpic(epicPath: string): Promise<void>;
|
|
29
|
+
start(): Promise<void>;
|
|
30
|
+
pause(): void;
|
|
31
|
+
stop(): void;
|
|
32
|
+
resume(): Promise<void>;
|
|
33
|
+
private executeWave;
|
|
34
|
+
/**
|
|
35
|
+
* After a wave, check each issue's status on disk.
|
|
36
|
+
* The coordinator agent is instructed to mark issues as done via front matter,
|
|
37
|
+
* so we trust the disk state and update metrics accordingly.
|
|
38
|
+
*/
|
|
39
|
+
private reconcileWaveResults;
|
|
40
|
+
/**
|
|
41
|
+
* Look for an output document matching an issue ID in .pm/docs/.
|
|
42
|
+
*/
|
|
43
|
+
private findOutputDoc;
|
|
44
|
+
private pickReadyIssues;
|
|
45
|
+
/**
|
|
46
|
+
* Build the team lead prompt for a wave of issues.
|
|
47
|
+
* Uses Agent Teams (TeamCreate/SendMessage) for true parallel execution
|
|
48
|
+
* as separate processes — each teammate gets its own context window.
|
|
49
|
+
*/
|
|
50
|
+
private buildCoordinatorPrompt;
|
|
51
|
+
/**
|
|
52
|
+
* Revert issues that stayed in_progress after a failed wave.
|
|
53
|
+
*/
|
|
54
|
+
private revertIncompleteIssues;
|
|
55
|
+
/** Saved content of any pre-existing .claude/settings.json so we can restore it */
|
|
56
|
+
private savedClaudeSettings;
|
|
57
|
+
private claudeSettingsInstalled;
|
|
58
|
+
/**
|
|
59
|
+
* Pre-approve tools in project .claude/settings.json so Agent Teams
|
|
60
|
+
* teammates can work without interactive permission prompts.
|
|
61
|
+
* Teammates are separate processes that inherit the lead's permission
|
|
62
|
+
* settings. Without pre-approved tools, they hit interactive prompts
|
|
63
|
+
* that can't be answered in headless/background mode (known bug #25254).
|
|
64
|
+
*/
|
|
65
|
+
private installTeammatePermissions;
|
|
66
|
+
/**
|
|
67
|
+
* Restore original .claude/settings.json after wave execution.
|
|
68
|
+
*/
|
|
69
|
+
private uninstallTeammatePermissions;
|
|
70
|
+
/** Saved content of any pre-existing .mcp.json so we can restore it */
|
|
71
|
+
private savedMcpJson;
|
|
72
|
+
private mcpJsonInstalled;
|
|
73
|
+
/**
|
|
74
|
+
* Write .mcp.json in the working directory so Agent Teams teammates
|
|
75
|
+
* (separate processes) auto-discover the bouncer MCP server.
|
|
76
|
+
* This is essential — teammates don't inherit --mcp-config or
|
|
77
|
+
* --permission-prompt-tool from the team lead. .mcp.json project-level
|
|
78
|
+
* discovery + global PreToolUse hooks are the two bouncer paths for teammates.
|
|
79
|
+
*
|
|
80
|
+
* Also generates ~/.mstro/mcp-config.json for the team lead (--mcp-config).
|
|
81
|
+
*/
|
|
82
|
+
private installBouncerForSubagents;
|
|
83
|
+
/**
|
|
84
|
+
* Restore or remove .mcp.json after execution.
|
|
85
|
+
*/
|
|
86
|
+
private uninstallBouncerForSubagents;
|
|
87
|
+
private listExistingDocs;
|
|
88
|
+
private slugify;
|
|
89
|
+
private updateIssueFrontMatter;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../../server/services/plan/executor.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAW3C,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;AAE/G,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,uDAAuD;IACvD,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,OAAO,CAMb;gBAEU,UAAU,EAAE,MAAM;IAK9B,SAAS,IAAI,eAAe;IAI5B,UAAU,IAAI,gBAAgB;IAIxB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyC5B,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;IAIZ,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;YAQT,WAAW;IA+DzB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAsC5B;;OAEG;IACH,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,eAAe;IAmBvB;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAuH9B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAgB9B,mFAAmF;IACnF,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,uBAAuB,CAAS;IAExC;;;;;;OAMG;IACH,OAAO,CAAC,0BAA0B;IAkDlC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAoBpC,uEAAuE;IACvE,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,gBAAgB,CAAS;IAEjC;;;;;;;;OAQG;IACH,OAAO,CAAC,0BAA0B;IAmClC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAsBpC,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,sBAAsB;CAY/B"}
|