vaspera 2.10.0 → 2.10.1
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/__tests__/scanners/ai-code/ai-detector.test.d.ts +2 -0
- package/dist/__tests__/scanners/ai-code/ai-detector.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/ai-code/ai-detector.test.js +188 -0
- package/dist/__tests__/scanners/ai-code/ai-detector.test.js.map +1 -0
- package/dist/__tests__/scanners/ai-code/confidence-scorer.test.d.ts +2 -0
- package/dist/__tests__/scanners/ai-code/confidence-scorer.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/ai-code/confidence-scorer.test.js +363 -0
- package/dist/__tests__/scanners/ai-code/confidence-scorer.test.js.map +1 -0
- package/dist/__tests__/scanners/ai-code/hallucination-checker.test.d.ts +2 -0
- package/dist/__tests__/scanners/ai-code/hallucination-checker.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/ai-code/hallucination-checker.test.js +226 -0
- package/dist/__tests__/scanners/ai-code/hallucination-checker.test.js.map +1 -0
- package/dist/__tests__/scanners/ai-code/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/ai-code/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/ai-code/index.test.js +214 -0
- package/dist/__tests__/scanners/ai-code/index.test.js.map +1 -0
- package/dist/__tests__/scanners/deploy/health-checker.test.d.ts +2 -0
- package/dist/__tests__/scanners/deploy/health-checker.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/deploy/health-checker.test.js +67 -0
- package/dist/__tests__/scanners/deploy/health-checker.test.js.map +1 -0
- package/dist/__tests__/scanners/deploy/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/deploy/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/deploy/index.test.js +84 -0
- package/dist/__tests__/scanners/deploy/index.test.js.map +1 -0
- package/dist/__tests__/scanners/deploy/provider-detector.test.d.ts +2 -0
- package/dist/__tests__/scanners/deploy/provider-detector.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/deploy/provider-detector.test.js +88 -0
- package/dist/__tests__/scanners/deploy/provider-detector.test.js.map +1 -0
- package/dist/__tests__/scanners/deploy/types.test.d.ts +2 -0
- package/dist/__tests__/scanners/deploy/types.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/deploy/types.test.js +126 -0
- package/dist/__tests__/scanners/deploy/types.test.js.map +1 -0
- package/dist/__tests__/scanners/fp-feedback.test.js +1 -1
- package/dist/__tests__/scanners/fp-feedback.test.js.map +1 -1
- package/dist/__tests__/scanners/fp-tracker.test.js +1 -1
- package/dist/__tests__/scanners/fp-tracker.test.js.map +1 -1
- package/dist/__tests__/scanners/runtime/app-launcher.test.d.ts +2 -0
- package/dist/__tests__/scanners/runtime/app-launcher.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/runtime/app-launcher.test.js +94 -0
- package/dist/__tests__/scanners/runtime/app-launcher.test.js.map +1 -0
- package/dist/__tests__/scanners/runtime/golden-path-runner.test.d.ts +2 -0
- package/dist/__tests__/scanners/runtime/golden-path-runner.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/runtime/golden-path-runner.test.js +195 -0
- package/dist/__tests__/scanners/runtime/golden-path-runner.test.js.map +1 -0
- package/dist/__tests__/scanners/runtime/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/runtime/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/runtime/index.test.js +120 -0
- package/dist/__tests__/scanners/runtime/index.test.js.map +1 -0
- package/dist/__tests__/scanners/runtime/types.test.d.ts +2 -0
- package/dist/__tests__/scanners/runtime/types.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/runtime/types.test.js +126 -0
- package/dist/__tests__/scanners/runtime/types.test.js.map +1 -0
- package/dist/__tests__/scanners/scale/bottleneck-detector.test.d.ts +2 -0
- package/dist/__tests__/scanners/scale/bottleneck-detector.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/scale/bottleneck-detector.test.js +187 -0
- package/dist/__tests__/scanners/scale/bottleneck-detector.test.js.map +1 -0
- package/dist/__tests__/scanners/scale/index.test.d.ts +2 -0
- package/dist/__tests__/scanners/scale/index.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/scale/index.test.js +87 -0
- package/dist/__tests__/scanners/scale/index.test.js.map +1 -0
- package/dist/__tests__/scanners/scale/load-profiler.test.d.ts +2 -0
- package/dist/__tests__/scanners/scale/load-profiler.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/scale/load-profiler.test.js +122 -0
- package/dist/__tests__/scanners/scale/load-profiler.test.js.map +1 -0
- package/dist/__tests__/scanners/scale/types.test.d.ts +2 -0
- package/dist/__tests__/scanners/scale/types.test.d.ts.map +1 -0
- package/dist/__tests__/scanners/scale/types.test.js +129 -0
- package/dist/__tests__/scanners/scale/types.test.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +874 -0
- package/dist/index.js.map +1 -1
- package/dist/install-skills.d.ts +11 -0
- package/dist/install-skills.d.ts.map +1 -0
- package/dist/install-skills.js +81 -0
- package/dist/install-skills.js.map +1 -0
- package/dist/scanners/ai-code/ai-detector.d.ts +25 -0
- package/dist/scanners/ai-code/ai-detector.d.ts.map +1 -0
- package/dist/scanners/ai-code/ai-detector.js +192 -0
- package/dist/scanners/ai-code/ai-detector.js.map +1 -0
- package/dist/scanners/ai-code/confidence-scorer.d.ts +40 -0
- package/dist/scanners/ai-code/confidence-scorer.d.ts.map +1 -0
- package/dist/scanners/ai-code/confidence-scorer.js +148 -0
- package/dist/scanners/ai-code/confidence-scorer.js.map +1 -0
- package/dist/scanners/ai-code/hallucination-checker.d.ts +36 -0
- package/dist/scanners/ai-code/hallucination-checker.d.ts.map +1 -0
- package/dist/scanners/ai-code/hallucination-checker.js +298 -0
- package/dist/scanners/ai-code/hallucination-checker.js.map +1 -0
- package/dist/scanners/ai-code/index.d.ts +30 -0
- package/dist/scanners/ai-code/index.d.ts.map +1 -0
- package/dist/scanners/ai-code/index.js +224 -0
- package/dist/scanners/ai-code/index.js.map +1 -0
- package/dist/scanners/ai-code/types.d.ts +192 -0
- package/dist/scanners/ai-code/types.d.ts.map +1 -0
- package/dist/scanners/ai-code/types.js +37 -0
- package/dist/scanners/ai-code/types.js.map +1 -0
- package/dist/scanners/deploy/health-checker.d.ts +38 -0
- package/dist/scanners/deploy/health-checker.d.ts.map +1 -0
- package/dist/scanners/deploy/health-checker.js +272 -0
- package/dist/scanners/deploy/health-checker.js.map +1 -0
- package/dist/scanners/deploy/index.d.ts +44 -0
- package/dist/scanners/deploy/index.d.ts.map +1 -0
- package/dist/scanners/deploy/index.js +208 -0
- package/dist/scanners/deploy/index.js.map +1 -0
- package/dist/scanners/deploy/provider-detector.d.ts +25 -0
- package/dist/scanners/deploy/provider-detector.d.ts.map +1 -0
- package/dist/scanners/deploy/provider-detector.js +177 -0
- package/dist/scanners/deploy/provider-detector.js.map +1 -0
- package/dist/scanners/deploy/types.d.ts +406 -0
- package/dist/scanners/deploy/types.d.ts.map +1 -0
- package/dist/scanners/deploy/types.js +58 -0
- package/dist/scanners/deploy/types.js.map +1 -0
- package/dist/scanners/deploy/vercel-integration.d.ts +52 -0
- package/dist/scanners/deploy/vercel-integration.d.ts.map +1 -0
- package/dist/scanners/deploy/vercel-integration.js +280 -0
- package/dist/scanners/deploy/vercel-integration.js.map +1 -0
- package/dist/scanners/runtime/app-launcher.d.ts +33 -0
- package/dist/scanners/runtime/app-launcher.d.ts.map +1 -0
- package/dist/scanners/runtime/app-launcher.js +419 -0
- package/dist/scanners/runtime/app-launcher.js.map +1 -0
- package/dist/scanners/runtime/golden-path-runner.d.ts +48 -0
- package/dist/scanners/runtime/golden-path-runner.d.ts.map +1 -0
- package/dist/scanners/runtime/golden-path-runner.js +373 -0
- package/dist/scanners/runtime/golden-path-runner.js.map +1 -0
- package/dist/scanners/runtime/index.d.ts +41 -0
- package/dist/scanners/runtime/index.d.ts.map +1 -0
- package/dist/scanners/runtime/index.js +164 -0
- package/dist/scanners/runtime/index.js.map +1 -0
- package/dist/scanners/runtime/playwright-executor.d.ts +50 -0
- package/dist/scanners/runtime/playwright-executor.d.ts.map +1 -0
- package/dist/scanners/runtime/playwright-executor.js +387 -0
- package/dist/scanners/runtime/playwright-executor.js.map +1 -0
- package/dist/scanners/runtime/types.d.ts +215 -0
- package/dist/scanners/runtime/types.d.ts.map +1 -0
- package/dist/scanners/runtime/types.js +40 -0
- package/dist/scanners/runtime/types.js.map +1 -0
- package/dist/scanners/scale/bottleneck-detector.d.ts +17 -0
- package/dist/scanners/scale/bottleneck-detector.d.ts.map +1 -0
- package/dist/scanners/scale/bottleneck-detector.js +250 -0
- package/dist/scanners/scale/bottleneck-detector.js.map +1 -0
- package/dist/scanners/scale/capacity-estimator.d.ts +17 -0
- package/dist/scanners/scale/capacity-estimator.d.ts.map +1 -0
- package/dist/scanners/scale/capacity-estimator.js +197 -0
- package/dist/scanners/scale/capacity-estimator.js.map +1 -0
- package/dist/scanners/scale/index.d.ts +37 -0
- package/dist/scanners/scale/index.d.ts.map +1 -0
- package/dist/scanners/scale/index.js +101 -0
- package/dist/scanners/scale/index.js.map +1 -0
- package/dist/scanners/scale/load-profiler.d.ts +48 -0
- package/dist/scanners/scale/load-profiler.d.ts.map +1 -0
- package/dist/scanners/scale/load-profiler.js +377 -0
- package/dist/scanners/scale/load-profiler.js.map +1 -0
- package/dist/scanners/scale/types.d.ts +529 -0
- package/dist/scanners/scale/types.d.ts.map +1 -0
- package/dist/scanners/scale/types.js +57 -0
- package/dist/scanners/scale/types.js.map +1 -0
- package/dist/scanners/secrets.d.ts.map +1 -1
- package/dist/scanners/secrets.js +13 -2
- package/dist/scanners/secrets.js.map +1 -1
- package/package.json +4 -2
- package/skills/vaspera-add-tests/SKILL.md +102 -0
- package/skills/vaspera-ai-verify/SKILL.md +166 -0
- package/skills/vaspera-audit/SKILL.md +67 -0
- package/skills/vaspera-certify/SKILL.md +130 -0
- package/skills/vaspera-deploy/SKILL.md +152 -0
- package/skills/vaspera-fix-critical/SKILL.md +52 -0
- package/skills/vaspera-fix-high/SKILL.md +81 -0
- package/skills/vaspera-fix-medium/SKILL.md +56 -0
- package/skills/vaspera-fix-rls/SKILL.md +85 -0
- package/skills/vaspera-harden/SKILL.md +102 -0
- package/skills/vaspera-help/SKILL.md +61 -0
- package/skills/vaspera-load-test/SKILL.md +167 -0
- package/skills/vaspera-verify/SKILL.md +70 -0
- package/skills/vaspera-verify-e2e/SKILL.md +117 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Golden Path Runner
|
|
3
|
+
*
|
|
4
|
+
* Executes user-defined flows against a running app using Playwright.
|
|
5
|
+
* Flows are defined in YAML files under .vaspera/flows/
|
|
6
|
+
*
|
|
7
|
+
* @module scanners/runtime/golden-path-runner
|
|
8
|
+
*/
|
|
9
|
+
import { readFile, readdir, mkdir, writeFile } from "fs/promises";
|
|
10
|
+
import { join } from "path";
|
|
11
|
+
import { parse as parseYaml } from "yaml";
|
|
12
|
+
import { logger } from "../../logger.js";
|
|
13
|
+
import { GoldenPathFlowSchema, } from "./types.js";
|
|
14
|
+
const FLOWS_DIR = ".vaspera/flows";
|
|
15
|
+
const SCREENSHOTS_DIR = ".vaspera/screenshots";
|
|
16
|
+
/**
|
|
17
|
+
* Load a golden path flow from a YAML file
|
|
18
|
+
*/
|
|
19
|
+
export async function loadFlow(flowPath) {
|
|
20
|
+
const content = await readFile(flowPath, "utf-8");
|
|
21
|
+
const parsed = parseYaml(content);
|
|
22
|
+
return GoldenPathFlowSchema.parse(parsed);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Discover all flows in a project
|
|
26
|
+
*/
|
|
27
|
+
export async function discoverFlows(projectPath) {
|
|
28
|
+
const flowsDir = join(projectPath, FLOWS_DIR);
|
|
29
|
+
const flows = [];
|
|
30
|
+
try {
|
|
31
|
+
const files = await readdir(flowsDir);
|
|
32
|
+
for (const file of files) {
|
|
33
|
+
if (file.endsWith(".yaml") || file.endsWith(".yml")) {
|
|
34
|
+
try {
|
|
35
|
+
const flowPath = join(flowsDir, file);
|
|
36
|
+
const flow = await loadFlow(flowPath);
|
|
37
|
+
flows.push({ path: flowPath, flow });
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
logger.warn("runtime.flow_parse_error", {
|
|
41
|
+
file,
|
|
42
|
+
error: error.message,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
logger.debug("runtime.no_flows_directory", { path: flowsDir });
|
|
50
|
+
}
|
|
51
|
+
return flows;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Execute a single step (without Playwright - basic HTTP/assertion version)
|
|
55
|
+
* This is a lightweight version for initial implementation.
|
|
56
|
+
* Full Playwright integration will be added as a separate module.
|
|
57
|
+
*/
|
|
58
|
+
async function executeStep(step, stepIndex, baseUrl, context) {
|
|
59
|
+
const startTime = Date.now();
|
|
60
|
+
try {
|
|
61
|
+
switch (step.action) {
|
|
62
|
+
case "navigate": {
|
|
63
|
+
const url = step.url?.startsWith("http")
|
|
64
|
+
? step.url
|
|
65
|
+
: `${baseUrl}${step.url}`;
|
|
66
|
+
const response = await fetch(url, {
|
|
67
|
+
method: "GET",
|
|
68
|
+
signal: AbortSignal.timeout(step.timeout || 10000),
|
|
69
|
+
});
|
|
70
|
+
context.currentUrl = url;
|
|
71
|
+
context.lastResponse = response;
|
|
72
|
+
return {
|
|
73
|
+
step: stepIndex,
|
|
74
|
+
action: step.action,
|
|
75
|
+
success: response.ok,
|
|
76
|
+
duration: Date.now() - startTime,
|
|
77
|
+
error: response.ok ? undefined : `HTTP ${response.status}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
case "api": {
|
|
81
|
+
const url = step.url?.startsWith("http")
|
|
82
|
+
? step.url
|
|
83
|
+
: `${baseUrl}${step.url}`;
|
|
84
|
+
const response = await fetch(url, {
|
|
85
|
+
method: step.method || "GET",
|
|
86
|
+
headers: {
|
|
87
|
+
"Content-Type": "application/json",
|
|
88
|
+
...step.headers,
|
|
89
|
+
},
|
|
90
|
+
body: step.body ? JSON.stringify(step.body) : undefined,
|
|
91
|
+
signal: AbortSignal.timeout(step.timeout || 10000),
|
|
92
|
+
});
|
|
93
|
+
context.lastResponse = response;
|
|
94
|
+
return {
|
|
95
|
+
step: stepIndex,
|
|
96
|
+
action: step.action,
|
|
97
|
+
success: response.ok,
|
|
98
|
+
duration: Date.now() - startTime,
|
|
99
|
+
error: response.ok ? undefined : `HTTP ${response.status}`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
case "assert": {
|
|
103
|
+
// For assertions, we need Playwright for DOM checks
|
|
104
|
+
// For now, support URL assertions only
|
|
105
|
+
if (step.url) {
|
|
106
|
+
const passed = context.currentUrl.includes(step.url);
|
|
107
|
+
return {
|
|
108
|
+
step: stepIndex,
|
|
109
|
+
action: step.action,
|
|
110
|
+
success: passed,
|
|
111
|
+
duration: Date.now() - startTime,
|
|
112
|
+
assertion: {
|
|
113
|
+
expected: step.url,
|
|
114
|
+
actual: context.currentUrl,
|
|
115
|
+
passed,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// DOM assertions require Playwright - return skipped
|
|
120
|
+
return {
|
|
121
|
+
step: stepIndex,
|
|
122
|
+
action: step.action,
|
|
123
|
+
success: true,
|
|
124
|
+
duration: Date.now() - startTime,
|
|
125
|
+
error: "DOM assertions require Playwright (skipped)",
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
case "wait": {
|
|
129
|
+
const waitTime = step.timeout || 1000;
|
|
130
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
131
|
+
return {
|
|
132
|
+
step: stepIndex,
|
|
133
|
+
action: step.action,
|
|
134
|
+
success: true,
|
|
135
|
+
duration: Date.now() - startTime,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
case "click":
|
|
139
|
+
case "fill":
|
|
140
|
+
case "select":
|
|
141
|
+
case "screenshot": {
|
|
142
|
+
// These require Playwright - return skipped
|
|
143
|
+
return {
|
|
144
|
+
step: stepIndex,
|
|
145
|
+
action: step.action,
|
|
146
|
+
success: true,
|
|
147
|
+
duration: Date.now() - startTime,
|
|
148
|
+
error: `${step.action} requires Playwright (skipped)`,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
default:
|
|
152
|
+
return {
|
|
153
|
+
step: stepIndex,
|
|
154
|
+
action: step.action,
|
|
155
|
+
success: false,
|
|
156
|
+
duration: Date.now() - startTime,
|
|
157
|
+
error: `Unknown action: ${step.action}`,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
return {
|
|
163
|
+
step: stepIndex,
|
|
164
|
+
action: step.action,
|
|
165
|
+
success: false,
|
|
166
|
+
duration: Date.now() - startTime,
|
|
167
|
+
error: error.message,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Run a golden path flow
|
|
173
|
+
*
|
|
174
|
+
* By default uses lightweight HTTP-based execution.
|
|
175
|
+
* Pass usePlaywright: true to use full browser automation.
|
|
176
|
+
*/
|
|
177
|
+
export async function runFlow(flow, baseUrl, options = {}) {
|
|
178
|
+
// Try Playwright if requested
|
|
179
|
+
if (options.usePlaywright) {
|
|
180
|
+
try {
|
|
181
|
+
const { isPlaywrightAvailable, runFlowWithPlaywright } = await import("./playwright-executor.js");
|
|
182
|
+
if (await isPlaywrightAvailable()) {
|
|
183
|
+
return runFlowWithPlaywright(flow, baseUrl, {
|
|
184
|
+
headless: options.headless,
|
|
185
|
+
slowMo: options.slowMo,
|
|
186
|
+
screenshotsDir: options.screenshotsDir,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
logger.warn("runtime.playwright_requested_but_unavailable");
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
logger.warn("runtime.playwright_import_failed");
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Fall back to HTTP-based execution
|
|
196
|
+
const startTime = Date.now();
|
|
197
|
+
const stepResults = [];
|
|
198
|
+
const screenshots = [];
|
|
199
|
+
let failed = false;
|
|
200
|
+
const context = {
|
|
201
|
+
currentUrl: baseUrl,
|
|
202
|
+
lastResponse: undefined,
|
|
203
|
+
};
|
|
204
|
+
logger.info("runtime.flow_started", {
|
|
205
|
+
name: flow.name,
|
|
206
|
+
steps: flow.steps.length,
|
|
207
|
+
});
|
|
208
|
+
for (let i = 0; i < flow.steps.length; i++) {
|
|
209
|
+
const step = flow.steps[i];
|
|
210
|
+
if (failed) {
|
|
211
|
+
// Skip remaining steps after a failure
|
|
212
|
+
stepResults.push({
|
|
213
|
+
step: i,
|
|
214
|
+
action: step.action,
|
|
215
|
+
success: false,
|
|
216
|
+
duration: 0,
|
|
217
|
+
error: "Skipped due to previous failure",
|
|
218
|
+
});
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
const result = await executeStep(step, i, baseUrl, context);
|
|
222
|
+
stepResults.push(result);
|
|
223
|
+
if (!result.success && !result.error?.includes("skipped")) {
|
|
224
|
+
failed = true;
|
|
225
|
+
logger.warn("runtime.step_failed", {
|
|
226
|
+
flow: flow.name,
|
|
227
|
+
step: i,
|
|
228
|
+
action: step.action,
|
|
229
|
+
error: result.error,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
logger.debug("runtime.step_passed", {
|
|
234
|
+
flow: flow.name,
|
|
235
|
+
step: i,
|
|
236
|
+
action: step.action,
|
|
237
|
+
duration: result.duration,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const passedSteps = stepResults.filter((r) => r.success && !r.error?.includes("skipped")).length;
|
|
242
|
+
const failedSteps = stepResults.filter((r) => !r.success && !r.error?.includes("skipped")).length;
|
|
243
|
+
logger.info("runtime.flow_completed", {
|
|
244
|
+
name: flow.name,
|
|
245
|
+
passed: passedSteps,
|
|
246
|
+
failed: failedSteps,
|
|
247
|
+
duration: Date.now() - startTime,
|
|
248
|
+
});
|
|
249
|
+
return {
|
|
250
|
+
flowName: flow.name,
|
|
251
|
+
success: !failed,
|
|
252
|
+
totalSteps: flow.steps.length,
|
|
253
|
+
passedSteps,
|
|
254
|
+
failedSteps,
|
|
255
|
+
duration: Date.now() - startTime,
|
|
256
|
+
steps: stepResults,
|
|
257
|
+
screenshots,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Run all flows in a project
|
|
262
|
+
*/
|
|
263
|
+
export async function runAllFlows(projectPath, baseUrl, options = {}) {
|
|
264
|
+
const discoveredFlows = await discoverFlows(projectPath);
|
|
265
|
+
const results = [];
|
|
266
|
+
// Filter by priority if specified
|
|
267
|
+
let flows = discoveredFlows;
|
|
268
|
+
if (options.priority) {
|
|
269
|
+
const priorities = [
|
|
270
|
+
"critical",
|
|
271
|
+
"high",
|
|
272
|
+
"medium",
|
|
273
|
+
"low",
|
|
274
|
+
];
|
|
275
|
+
const minPriorityIndex = priorities.indexOf(options.priority);
|
|
276
|
+
flows = flows.filter((f) => {
|
|
277
|
+
const flowPriorityIndex = priorities.indexOf(f.flow.priority || "medium");
|
|
278
|
+
return flowPriorityIndex <= minPriorityIndex;
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
// Filter by tags if specified
|
|
282
|
+
if (options.tags && options.tags.length > 0) {
|
|
283
|
+
flows = flows.filter((f) => f.flow.tags?.some((tag) => options.tags?.includes(tag)));
|
|
284
|
+
}
|
|
285
|
+
// Sort by priority (critical first)
|
|
286
|
+
const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
287
|
+
flows.sort((a, b) => priorityOrder[a.flow.priority || "medium"] -
|
|
288
|
+
priorityOrder[b.flow.priority || "medium"]);
|
|
289
|
+
logger.info("runtime.running_flows", {
|
|
290
|
+
total: flows.length,
|
|
291
|
+
priority: options.priority,
|
|
292
|
+
});
|
|
293
|
+
for (const { flow } of flows) {
|
|
294
|
+
const result = await runFlow(flow, flow.baseUrl || baseUrl, {
|
|
295
|
+
usePlaywright: options.usePlaywright,
|
|
296
|
+
headless: options.headless,
|
|
297
|
+
slowMo: options.slowMo,
|
|
298
|
+
screenshotsDir: options.screenshotsDir,
|
|
299
|
+
});
|
|
300
|
+
results.push(result);
|
|
301
|
+
// Stop on critical flow failure
|
|
302
|
+
if (!result.success && flow.priority === "critical") {
|
|
303
|
+
logger.error("runtime.critical_flow_failed", { name: flow.name });
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return results;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Generate a sample flow file
|
|
311
|
+
*/
|
|
312
|
+
export async function generateSampleFlow(projectPath, name = "sample") {
|
|
313
|
+
const flowsDir = join(projectPath, FLOWS_DIR);
|
|
314
|
+
// Ensure directory exists
|
|
315
|
+
await mkdir(flowsDir, { recursive: true });
|
|
316
|
+
const sampleFlow = `# ${name} Golden Path Flow
|
|
317
|
+
# Define user flows to verify your app works correctly
|
|
318
|
+
|
|
319
|
+
name: "${name}"
|
|
320
|
+
description: "Sample golden path flow - customize for your app"
|
|
321
|
+
priority: medium
|
|
322
|
+
tags:
|
|
323
|
+
- sample
|
|
324
|
+
- smoke-test
|
|
325
|
+
|
|
326
|
+
steps:
|
|
327
|
+
# Navigate to the home page
|
|
328
|
+
- action: navigate
|
|
329
|
+
url: "/"
|
|
330
|
+
description: "Load home page"
|
|
331
|
+
|
|
332
|
+
# Verify home page loaded
|
|
333
|
+
- action: assert
|
|
334
|
+
url: "/"
|
|
335
|
+
description: "Verify on home page"
|
|
336
|
+
|
|
337
|
+
# Wait for any async content
|
|
338
|
+
- action: wait
|
|
339
|
+
timeout: 1000
|
|
340
|
+
description: "Wait for page to settle"
|
|
341
|
+
|
|
342
|
+
# Test an API endpoint
|
|
343
|
+
- action: api
|
|
344
|
+
url: "/api/health"
|
|
345
|
+
method: GET
|
|
346
|
+
description: "Check health endpoint"
|
|
347
|
+
|
|
348
|
+
# Navigate to another page
|
|
349
|
+
# - action: navigate
|
|
350
|
+
# url: "/about"
|
|
351
|
+
# description: "Go to about page"
|
|
352
|
+
|
|
353
|
+
# Fill a form (requires Playwright)
|
|
354
|
+
# - action: fill
|
|
355
|
+
# selector: "#email"
|
|
356
|
+
# value: "test@example.com"
|
|
357
|
+
# description: "Enter email"
|
|
358
|
+
|
|
359
|
+
# Click a button (requires Playwright)
|
|
360
|
+
# - action: click
|
|
361
|
+
# selector: "[data-testid='submit']"
|
|
362
|
+
# description: "Submit form"
|
|
363
|
+
|
|
364
|
+
# Take a screenshot (requires Playwright)
|
|
365
|
+
# - action: screenshot
|
|
366
|
+
# description: "Capture final state"
|
|
367
|
+
`;
|
|
368
|
+
const flowPath = join(flowsDir, `${name}.yaml`);
|
|
369
|
+
await writeFile(flowPath, sampleFlow, "utf-8");
|
|
370
|
+
logger.info("runtime.sample_flow_created", { path: flowPath });
|
|
371
|
+
return flowPath;
|
|
372
|
+
}
|
|
373
|
+
//# sourceMappingURL=golden-path-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"golden-path-runner.js","sourceRoot":"","sources":["../../../src/scanners/runtime/golden-path-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Verification Scanner
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates app launching, golden path testing, and runtime verification.
|
|
5
|
+
* This is the entry point for M7 runtime verification capabilities.
|
|
6
|
+
*
|
|
7
|
+
* @module scanners/runtime
|
|
8
|
+
*/
|
|
9
|
+
import type { RuntimeVerificationResult, GoldenPathFlow } from "./types.js";
|
|
10
|
+
export * from "./types.js";
|
|
11
|
+
export { detectFramework, launchApp, stopApp, stopAllApps, getRunningApps, } from "./app-launcher.js";
|
|
12
|
+
export { discoverFlows, runFlow, runAllFlows, generateSampleFlow, loadFlow, } from "./golden-path-runner.js";
|
|
13
|
+
export { isPlaywrightAvailable, launchBrowser, closeBrowser, runFlowWithPlaywright, } from "./playwright-executor.js";
|
|
14
|
+
/**
|
|
15
|
+
* Run full runtime verification
|
|
16
|
+
*
|
|
17
|
+
* 1. Detect framework
|
|
18
|
+
* 2. Launch the app
|
|
19
|
+
* 3. Run golden path flows
|
|
20
|
+
* 4. Calculate score
|
|
21
|
+
* 5. Stop the app
|
|
22
|
+
*/
|
|
23
|
+
export declare function runRuntimeVerification(projectPath: string, options?: {
|
|
24
|
+
port?: number;
|
|
25
|
+
timeout?: number;
|
|
26
|
+
priority?: GoldenPathFlow["priority"];
|
|
27
|
+
stopAfter?: boolean;
|
|
28
|
+
}): Promise<RuntimeVerificationResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Quick health check - just launch and verify app starts
|
|
31
|
+
*/
|
|
32
|
+
export declare function quickHealthCheck(projectPath: string, options?: {
|
|
33
|
+
port?: number;
|
|
34
|
+
timeout?: number;
|
|
35
|
+
}): Promise<{
|
|
36
|
+
healthy: boolean;
|
|
37
|
+
url: string;
|
|
38
|
+
startupTime: number;
|
|
39
|
+
error?: string;
|
|
40
|
+
}>;
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/runtime/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiBH,OAAO,KAAK,EACV,yBAAyB,EAGzB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,SAAS,EACT,OAAO,EACP,WAAW,EACX,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,aAAa,EACb,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,QAAQ,GACT,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAiDlC;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IACP,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACtC,SAAS,CAAC,EAAE,OAAO,CAAC;CAChB,GACL,OAAO,CAAC,yBAAyB,CAAC,CAuFpC;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAChD,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsBjF"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Verification Scanner
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates app launching, golden path testing, and runtime verification.
|
|
5
|
+
* This is the entry point for M7 runtime verification capabilities.
|
|
6
|
+
*
|
|
7
|
+
* @module scanners/runtime
|
|
8
|
+
*/
|
|
9
|
+
import { logger } from "../../logger.js";
|
|
10
|
+
import { detectFramework, launchApp, stopApp, } from "./app-launcher.js";
|
|
11
|
+
import { runAllFlows, } from "./golden-path-runner.js";
|
|
12
|
+
export * from "./types.js";
|
|
13
|
+
export { detectFramework, launchApp, stopApp, stopAllApps, getRunningApps, } from "./app-launcher.js";
|
|
14
|
+
export { discoverFlows, runFlow, runAllFlows, generateSampleFlow, loadFlow, } from "./golden-path-runner.js";
|
|
15
|
+
export { isPlaywrightAvailable, launchBrowser, closeBrowser, runFlowWithPlaywright, } from "./playwright-executor.js";
|
|
16
|
+
/**
|
|
17
|
+
* Calculate runtime verification score
|
|
18
|
+
*/
|
|
19
|
+
function calculateScore(goldenPathResults) {
|
|
20
|
+
const goldenPathsTotal = goldenPathResults.length;
|
|
21
|
+
const goldenPathsPassed = goldenPathResults.filter((r) => r.success).length;
|
|
22
|
+
// Calculate overall score (0-100)
|
|
23
|
+
let overallScore = 0;
|
|
24
|
+
if (goldenPathsTotal > 0) {
|
|
25
|
+
// Golden paths are weighted by priority
|
|
26
|
+
const priorityWeights = { critical: 3, high: 2, medium: 1.5, low: 1 };
|
|
27
|
+
let weightedPassed = 0;
|
|
28
|
+
let totalWeight = 0;
|
|
29
|
+
for (const result of goldenPathResults) {
|
|
30
|
+
// Infer priority from flow name or default to medium
|
|
31
|
+
const priority = "medium"; // TODO: Store priority in result
|
|
32
|
+
const weight = priorityWeights[priority];
|
|
33
|
+
totalWeight += weight;
|
|
34
|
+
if (result.success) {
|
|
35
|
+
weightedPassed += weight;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (totalWeight > 0) {
|
|
39
|
+
overallScore = Math.round((weightedPassed / totalWeight) * 100);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// No flows defined - partial score
|
|
44
|
+
overallScore = 50; // Neutral score when no flows
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
goldenPathsPassed,
|
|
48
|
+
goldenPathsTotal,
|
|
49
|
+
visualRegressionsPassed: 0, // TODO: Implement visual regression
|
|
50
|
+
visualRegressionsTotal: 0,
|
|
51
|
+
apiTestsPassed: 0, // Counted within golden paths for now
|
|
52
|
+
apiTestsTotal: 0,
|
|
53
|
+
overallScore,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Run full runtime verification
|
|
58
|
+
*
|
|
59
|
+
* 1. Detect framework
|
|
60
|
+
* 2. Launch the app
|
|
61
|
+
* 3. Run golden path flows
|
|
62
|
+
* 4. Calculate score
|
|
63
|
+
* 5. Stop the app
|
|
64
|
+
*/
|
|
65
|
+
export async function runRuntimeVerification(projectPath, options = {}) {
|
|
66
|
+
const startTime = Date.now();
|
|
67
|
+
const { port, timeout = 60000, priority, stopAfter = true } = options;
|
|
68
|
+
logger.info("runtime.verification_started", { projectPath });
|
|
69
|
+
// Step 1: Detect framework
|
|
70
|
+
const detection = await detectFramework(projectPath);
|
|
71
|
+
logger.info("runtime.framework_detected", {
|
|
72
|
+
framework: detection.framework,
|
|
73
|
+
confidence: detection.confidence,
|
|
74
|
+
});
|
|
75
|
+
// Step 2: Launch the app
|
|
76
|
+
const launchConfig = {
|
|
77
|
+
projectPath,
|
|
78
|
+
framework: detection.framework,
|
|
79
|
+
port: port || detection.port,
|
|
80
|
+
timeout,
|
|
81
|
+
};
|
|
82
|
+
const launchResult = await launchApp(launchConfig);
|
|
83
|
+
if (!launchResult.success) {
|
|
84
|
+
return {
|
|
85
|
+
success: false,
|
|
86
|
+
framework: detection.framework,
|
|
87
|
+
appUrl: launchResult.url,
|
|
88
|
+
duration: Date.now() - startTime,
|
|
89
|
+
goldenPaths: [],
|
|
90
|
+
visualRegressions: [],
|
|
91
|
+
score: {
|
|
92
|
+
goldenPathsPassed: 0,
|
|
93
|
+
goldenPathsTotal: 0,
|
|
94
|
+
visualRegressionsPassed: 0,
|
|
95
|
+
visualRegressionsTotal: 0,
|
|
96
|
+
apiTestsPassed: 0,
|
|
97
|
+
apiTestsTotal: 0,
|
|
98
|
+
overallScore: 0,
|
|
99
|
+
},
|
|
100
|
+
error: launchResult.error || "App failed to start",
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
logger.info("runtime.app_launched", {
|
|
104
|
+
url: launchResult.url,
|
|
105
|
+
startupTime: launchResult.startupTime,
|
|
106
|
+
});
|
|
107
|
+
// Step 3: Run golden path flows
|
|
108
|
+
let goldenPathResults = [];
|
|
109
|
+
try {
|
|
110
|
+
goldenPathResults = await runAllFlows(projectPath, launchResult.url, {
|
|
111
|
+
priority,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
logger.error("runtime.golden_path_error", {
|
|
116
|
+
error: error.message,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
// Step 4: Calculate score
|
|
120
|
+
const score = calculateScore(goldenPathResults);
|
|
121
|
+
// Step 5: Stop the app
|
|
122
|
+
if (stopAfter) {
|
|
123
|
+
await stopApp(projectPath, launchResult.port);
|
|
124
|
+
}
|
|
125
|
+
const result = {
|
|
126
|
+
success: score.overallScore >= 70, // Threshold for "passing"
|
|
127
|
+
framework: detection.framework,
|
|
128
|
+
appUrl: launchResult.url,
|
|
129
|
+
duration: Date.now() - startTime,
|
|
130
|
+
goldenPaths: goldenPathResults,
|
|
131
|
+
visualRegressions: [], // TODO: Implement
|
|
132
|
+
score,
|
|
133
|
+
};
|
|
134
|
+
logger.info("runtime.verification_completed", {
|
|
135
|
+
success: result.success,
|
|
136
|
+
score: score.overallScore,
|
|
137
|
+
duration: result.duration,
|
|
138
|
+
});
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Quick health check - just launch and verify app starts
|
|
143
|
+
*/
|
|
144
|
+
export async function quickHealthCheck(projectPath, options = {}) {
|
|
145
|
+
const { port, timeout = 30000 } = options;
|
|
146
|
+
const detection = await detectFramework(projectPath);
|
|
147
|
+
const launchResult = await launchApp({
|
|
148
|
+
projectPath,
|
|
149
|
+
framework: detection.framework,
|
|
150
|
+
port: port || detection.port,
|
|
151
|
+
timeout,
|
|
152
|
+
});
|
|
153
|
+
// Always stop after health check
|
|
154
|
+
if (launchResult.pid) {
|
|
155
|
+
await stopApp(projectPath, launchResult.port);
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
healthy: launchResult.success && launchResult.healthStatus === "healthy",
|
|
159
|
+
url: launchResult.url,
|
|
160
|
+
startupTime: launchResult.startupTime,
|
|
161
|
+
error: launchResult.error,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scanners/runtime/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes golden path steps using Playwright for full browser automation.
|
|
5
|
+
* This module is optional - falls back to HTTP-based execution when Playwright
|
|
6
|
+
* is not available.
|
|
7
|
+
*
|
|
8
|
+
* @module scanners/runtime/playwright-executor
|
|
9
|
+
*/
|
|
10
|
+
import type { GoldenPathFlow, StepResult } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Check if Playwright is available
|
|
13
|
+
*/
|
|
14
|
+
export declare function isPlaywrightAvailable(): Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Launch browser for testing
|
|
17
|
+
*/
|
|
18
|
+
export declare function launchBrowser(options?: {
|
|
19
|
+
headless?: boolean;
|
|
20
|
+
slowMo?: number;
|
|
21
|
+
}): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* Close browser
|
|
24
|
+
*/
|
|
25
|
+
export declare function closeBrowser(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Execute a step using Playwright
|
|
28
|
+
*/
|
|
29
|
+
export declare function executeStepWithPlaywright(step: GoldenPathFlow["steps"][0], stepIndex: number, baseUrl: string, context: {
|
|
30
|
+
currentUrl: string;
|
|
31
|
+
screenshotsDir?: string;
|
|
32
|
+
}): Promise<StepResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Run a complete flow with Playwright
|
|
35
|
+
*/
|
|
36
|
+
export declare function runFlowWithPlaywright(flow: GoldenPathFlow, baseUrl: string, options?: {
|
|
37
|
+
headless?: boolean;
|
|
38
|
+
slowMo?: number;
|
|
39
|
+
screenshotsDir?: string;
|
|
40
|
+
}): Promise<{
|
|
41
|
+
flowName: string;
|
|
42
|
+
success: boolean;
|
|
43
|
+
totalSteps: number;
|
|
44
|
+
passedSteps: number;
|
|
45
|
+
failedSteps: number;
|
|
46
|
+
duration: number;
|
|
47
|
+
steps: StepResult[];
|
|
48
|
+
screenshots: string[];
|
|
49
|
+
}>;
|
|
50
|
+
//# sourceMappingURL=playwright-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright-executor.d.ts","sourceRoot":"","sources":["../../../src/scanners/runtime/playwright-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7D;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAe9D;AAUD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBxB;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAUlD;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,OAAO,CAAC,UAAU,CAAC,CA0OrB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACpB,GACL,OAAO,CAAC;IACT,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC,CAwGD"}
|