sela-core 0.1.0-alpha.39 → 0.1.0-alpha.41
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/boot/bootImpl.d.ts +14 -0
- package/dist/boot/bootImpl.d.ts.map +1 -0
- package/dist/boot/bootImpl.js +68 -0
- package/dist/boot/register.cjs +45 -0
- package/dist/boot/register.d.cts +2 -0
- package/dist/boot/register.d.cts.map +1 -0
- package/dist/boot/register.d.mts +2 -0
- package/dist/boot/register.d.mts.map +1 -0
- package/dist/boot/register.mjs +10 -0
- package/dist/cli/commands/init.js +48 -16
- package/dist/cli/commands/merge.d.ts.map +1 -1
- package/dist/cli/commands/merge.js +5 -0
- package/dist/cli/commands/shadowRegression.js +1 -1
- package/dist/config/ConfigLoader.d.ts.map +1 -1
- package/dist/config/ConfigLoader.js +33 -12
- package/dist/config/SelaConfig.d.ts +59 -0
- package/dist/config/SelaConfig.d.ts.map +1 -1
- package/dist/config/SelaConfig.js +36 -0
- package/dist/engine/SelaEngine.d.ts +3 -1
- package/dist/engine/SelaEngine.d.ts.map +1 -1
- package/dist/engine/SelaEngine.js +193 -3
- package/dist/errors/SelaError.d.ts +7 -0
- package/dist/errors/SelaError.d.ts.map +1 -1
- package/dist/errors/SelaError.js +7 -1
- package/dist/fixtures/index.d.ts.map +1 -1
- package/dist/fixtures/index.js +5 -4
- package/dist/providers/AnthropicProvider.d.ts +9 -0
- package/dist/providers/AnthropicProvider.d.ts.map +1 -0
- package/dist/providers/AnthropicProvider.js +33 -0
- package/dist/providers/LLMProvider.d.ts +13 -0
- package/dist/providers/LLMProvider.d.ts.map +1 -0
- package/dist/providers/LLMProvider.js +7 -0
- package/dist/providers/OpenAICompatibleProvider.d.ts +8 -0
- package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -0
- package/dist/providers/OpenAICompatibleProvider.js +48 -0
- package/dist/providers/ProviderFactory.d.ts +4 -0
- package/dist/providers/ProviderFactory.d.ts.map +1 -0
- package/dist/providers/ProviderFactory.js +50 -0
- package/dist/providers/SanitizingProvider.d.ts +8 -0
- package/dist/providers/SanitizingProvider.d.ts.map +1 -0
- package/dist/providers/SanitizingProvider.js +27 -0
- package/dist/services/ASTSourceUpdater.d.ts.map +1 -1
- package/dist/services/ASTSourceUpdater.js +39 -5
- package/dist/services/CrossFileHealer.d.ts +7 -1
- package/dist/services/CrossFileHealer.d.ts.map +1 -1
- package/dist/services/CrossFileHealer.js +243 -9
- package/dist/services/DefinitionTracer.d.ts +1 -0
- package/dist/services/DefinitionTracer.d.ts.map +1 -1
- package/dist/services/DefinitionTracer.js +59 -36
- package/dist/services/HealReportService.d.ts +32 -0
- package/dist/services/HealReportService.d.ts.map +1 -1
- package/dist/services/HealReportService.js +111 -18
- package/dist/services/IntentAuditor.d.ts +9 -7
- package/dist/services/IntentAuditor.d.ts.map +1 -1
- package/dist/services/IntentAuditor.js +21 -16
- package/dist/services/LLMService.d.ts +10 -7
- package/dist/services/LLMService.d.ts.map +1 -1
- package/dist/services/LLMService.js +76 -10
- package/dist/services/PRAutomationService.d.ts +7 -2
- package/dist/services/PRAutomationService.d.ts.map +1 -1
- package/dist/services/PRAutomationService.js +144 -133
- package/dist/services/RegressionManifestService.d.ts +8 -0
- package/dist/services/RegressionManifestService.d.ts.map +1 -1
- package/dist/services/RegressionManifestService.js +8 -0
- package/dist/services/RegressionReclassifier.d.ts +25 -0
- package/dist/services/RegressionReclassifier.d.ts.map +1 -0
- package/dist/services/RegressionReclassifier.js +195 -0
- package/dist/services/ReportMergeService.d.ts +9 -0
- package/dist/services/ReportMergeService.d.ts.map +1 -1
- package/dist/services/ReportMergeService.js +28 -0
- package/dist/services/SmartDOMPruner.d.ts +154 -0
- package/dist/services/SmartDOMPruner.d.ts.map +1 -0
- package/dist/services/SmartDOMPruner.js +678 -0
- package/dist/services/TraceBackEngine.d.ts +23 -6
- package/dist/services/TraceBackEngine.d.ts.map +1 -1
- package/dist/services/TraceBackEngine.js +51 -13
- package/dist/services/VisualSnapshotService.d.ts +54 -0
- package/dist/services/VisualSnapshotService.d.ts.map +1 -0
- package/dist/services/VisualSnapshotService.js +279 -0
- package/dist/services/vcs/GitHubProvider.d.ts +17 -0
- package/dist/services/vcs/GitHubProvider.d.ts.map +1 -0
- package/dist/services/vcs/GitHubProvider.js +162 -0
- package/dist/services/vcs/GitLabProvider.d.ts +17 -0
- package/dist/services/vcs/GitLabProvider.d.ts.map +1 -0
- package/dist/services/vcs/GitLabProvider.js +175 -0
- package/dist/services/vcs/VCSProvider.d.ts +100 -0
- package/dist/services/vcs/VCSProvider.d.ts.map +1 -0
- package/dist/services/vcs/VCSProvider.js +7 -0
- package/dist/services/vcs/VCSProviderFactory.d.ts +7 -0
- package/dist/services/vcs/VCSProviderFactory.d.ts.map +1 -0
- package/dist/services/vcs/VCSProviderFactory.js +42 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/shell.d.ts +7 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +32 -0
- package/package.json +7 -1
|
@@ -1992,9 +1992,40 @@ class ASTSourceUpdater {
|
|
|
1992
1992
|
// and prevents dead variables (CLAUDE.md §5, Rules A–C).
|
|
1993
1993
|
if (input.apply && input.newSelector) {
|
|
1994
1994
|
const healFields = (0, HealFieldParser_1.parseHealFields)(input.newSelector);
|
|
1995
|
-
const
|
|
1995
|
+
const argResult = (0, TraceBackEngine_1.resolveArgTargetsEx)(trace.target.targetNode, healFields);
|
|
1996
|
+
const argTargets = argResult.targets;
|
|
1996
1997
|
const hasSymbolic = argTargets.some((t) => !t.isCallSiteLiteral);
|
|
1998
|
+
// Guard: unresolvable symbolic arg (screenplay this.target.selector, dynamic
|
|
1999
|
+
// template factories) → abort immediately, no disk mutation.
|
|
2000
|
+
if (argResult.hasBlockingArg && argTargets.length === 0) {
|
|
2001
|
+
return {
|
|
2002
|
+
kind: "abort",
|
|
2003
|
+
trace: {
|
|
2004
|
+
status: "abort",
|
|
2005
|
+
severity: "hard",
|
|
2006
|
+
code: "UNSUPPORTED",
|
|
2007
|
+
reason: "locator argument is an unresolvable runtime-injected symbolic expression",
|
|
2008
|
+
},
|
|
2009
|
+
};
|
|
2010
|
+
}
|
|
1997
2011
|
if (argTargets.length > 0 && hasSymbolic) {
|
|
2012
|
+
// Cross-file arg targets (factory or alias dict) — delegate to CrossFileHealer.
|
|
2013
|
+
const crossFileArgTargets = argTargets.filter((t) => t.crossFileRef);
|
|
2014
|
+
if (crossFileArgTargets.length > 0) {
|
|
2015
|
+
const cfTarget = crossFileArgTargets[0];
|
|
2016
|
+
const crossHealResult = ASTSourceUpdater.tryCrossFileHeal(input, cfTarget.crossFileRef, trace);
|
|
2017
|
+
if (crossHealResult !== null)
|
|
2018
|
+
return crossHealResult;
|
|
2019
|
+
return {
|
|
2020
|
+
kind: "abort",
|
|
2021
|
+
trace: {
|
|
2022
|
+
status: "abort",
|
|
2023
|
+
severity: "soft",
|
|
2024
|
+
code: "CROSS_FILE",
|
|
2025
|
+
reason: `cross-file arg heal failed for ${cfTarget.crossFileRef.kind}`,
|
|
2026
|
+
},
|
|
2027
|
+
};
|
|
2028
|
+
}
|
|
1998
2029
|
const argDecision = (0, DecisionEngine_1.decideArgs)({
|
|
1999
2030
|
argTargets,
|
|
2000
2031
|
failingCallSite: failingNode,
|
|
@@ -2005,7 +2036,7 @@ class ASTSourceUpdater {
|
|
|
2005
2036
|
});
|
|
2006
2037
|
if (argDecision) {
|
|
2007
2038
|
const batch = ASTSourceUpdater.decisionToBatch(input.filePath, argDecision);
|
|
2008
|
-
const
|
|
2039
|
+
const argDecResult = {
|
|
2009
2040
|
kind: "decision",
|
|
2010
2041
|
trace,
|
|
2011
2042
|
decision: argDecision,
|
|
@@ -2013,9 +2044,9 @@ class ASTSourceUpdater {
|
|
|
2013
2044
|
writtenLine: trace.target.targetNode.getStartLineNumber(),
|
|
2014
2045
|
};
|
|
2015
2046
|
if (batch.edits.length > 0) {
|
|
2016
|
-
|
|
2047
|
+
argDecResult.outcome = await MutationApplier_1.MutationApplier.applyFileBatchAsync(batch, input.applyOptions ?? {});
|
|
2017
2048
|
}
|
|
2018
|
-
return
|
|
2049
|
+
return argDecResult;
|
|
2019
2050
|
}
|
|
2020
2051
|
}
|
|
2021
2052
|
}
|
|
@@ -2159,7 +2190,10 @@ class ASTSourceUpdater {
|
|
|
2159
2190
|
});
|
|
2160
2191
|
let crossResult;
|
|
2161
2192
|
if (crossFileRef.kind === "variable") {
|
|
2162
|
-
crossResult = CrossFileHealer_1.CrossFileHealer.heal(crossFileRef.modulePath, crossFileRef.symbolName, input.newSelector, input.filePath, fsProject);
|
|
2193
|
+
crossResult = CrossFileHealer_1.CrossFileHealer.heal(crossFileRef.modulePath, crossFileRef.symbolName, input.newSelector, input.filePath, fsProject, 0, crossFileRef.propertyPath);
|
|
2194
|
+
}
|
|
2195
|
+
else if (crossFileRef.kind === "factory") {
|
|
2196
|
+
crossResult = CrossFileHealer_1.CrossFileHealer.healFactory(crossFileRef.modulePath, crossFileRef.symbolName, input.newSelector, input.filePath, fsProject);
|
|
2163
2197
|
}
|
|
2164
2198
|
else {
|
|
2165
2199
|
crossResult = CrossFileHealer_1.CrossFileHealer.healPomProperty(crossFileRef.modulePath, crossFileRef.symbolName, crossFileRef.propName, input.newSelector, input.filePath, fsProject);
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { Project } from "ts-morph";
|
|
2
2
|
import type { ASTUpdateResult } from "./ASTSourceUpdater.js";
|
|
3
3
|
export declare class CrossFileHealer {
|
|
4
|
-
static heal(modulePath: string, symbolName: string, newValue: string, callerFilePath: string, project: Project, depth?: number): ASTUpdateResult;
|
|
4
|
+
static heal(modulePath: string, symbolName: string, newValue: string, callerFilePath: string, project: Project, depth?: number, propertyPath?: string[]): ASTUpdateResult;
|
|
5
|
+
/**
|
|
6
|
+
* Heal the return literal of an exported factory function.
|
|
7
|
+
* Handles: `const fn = () => "#selector"` and `function fn() { return "#selector"; }`.
|
|
8
|
+
* Returns failure when the return is a dynamic TemplateExpression (Rule D).
|
|
9
|
+
*/
|
|
10
|
+
static healFactory(modulePath: string, functionName: string, newValue: string, callerFilePath: string, project: Project): ASTUpdateResult;
|
|
5
11
|
/**
|
|
6
12
|
* Heal a property on a POM class: finds the class by name in the module,
|
|
7
13
|
* locates the string literal argument of a locator stored in `propName`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CrossFileHealer.d.ts","sourceRoot":"","sources":["../../src/services/CrossFileHealer.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,
|
|
1
|
+
{"version":3,"file":"CrossFileHealer.d.ts","sourceRoot":"","sources":["../../src/services/CrossFileHealer.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,EAOR,MAAM,UAAU,CAAC;AAGlB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAuC7D,qBAAa,eAAe;IAC1B,MAAM,CAAC,IAAI,CACT,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,EAChB,KAAK,SAAI,EACT,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,eAAe;IA+HlB;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAChB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,GACf,eAAe;IA2ElB;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,eAAe,CACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,GACf,eAAe;CAoEnB;AAMD,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAgCf"}
|
|
@@ -69,7 +69,7 @@ function captureDefinitionDiff(before, externalSf, externalPath) {
|
|
|
69
69
|
// ═══════════════════════════════════════════════════════════════════
|
|
70
70
|
const DEPTH_GUARD = 3;
|
|
71
71
|
class CrossFileHealer {
|
|
72
|
-
static heal(modulePath, symbolName, newValue, callerFilePath, project, depth = 0) {
|
|
72
|
+
static heal(modulePath, symbolName, newValue, callerFilePath, project, depth = 0, propertyPath) {
|
|
73
73
|
if (depth >= DEPTH_GUARD) {
|
|
74
74
|
return {
|
|
75
75
|
success: false,
|
|
@@ -107,7 +107,7 @@ class CrossFileHealer {
|
|
|
107
107
|
// Follow re-export chains (barrel files).
|
|
108
108
|
if (traceResult.crossFile) {
|
|
109
109
|
logger_1.logger.debug(`CrossFileHealer "${symbolName}" re-exported from "${traceResult.modulePath}" - following chain`);
|
|
110
|
-
return CrossFileHealer.heal(traceResult.modulePath, traceResult.symbolName, newValue, externalPath, project, depth + 1);
|
|
110
|
+
return CrossFileHealer.heal(traceResult.modulePath, traceResult.symbolName, newValue, externalPath, project, depth + 1, propertyPath);
|
|
111
111
|
}
|
|
112
112
|
return {
|
|
113
113
|
success: false,
|
|
@@ -115,16 +115,48 @@ class CrossFileHealer {
|
|
|
115
115
|
strategy: "semantic-cross-file",
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
|
+
// Navigate into nested object properties when a path is provided.
|
|
119
|
+
// e.g. symbolName="Selectors", propertyPath=["Auth","LoginBtn"] resolves
|
|
120
|
+
// the StringLiteral inside `Selectors.Auth.LoginBtn`.
|
|
121
|
+
let targetNode = traceResult.targetNode;
|
|
122
|
+
if (propertyPath && propertyPath.length > 0) {
|
|
123
|
+
for (const key of propertyPath) {
|
|
124
|
+
if (!ts_morph_1.Node.isObjectLiteralExpression(targetNode)) {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
reason: `CrossFileHealer: "${key}" not reachable — "${symbolName}" is not an ObjectLiteralExpression at this level`,
|
|
128
|
+
strategy: "semantic-cross-file",
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const prop = targetNode.getProperty(key);
|
|
132
|
+
if (!prop || !ts_morph_1.Node.isPropertyAssignment(prop)) {
|
|
133
|
+
return {
|
|
134
|
+
success: false,
|
|
135
|
+
reason: `CrossFileHealer: property "${key}" not found in "${symbolName}"`,
|
|
136
|
+
strategy: "semantic-cross-file",
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
const init = prop.getInitializer();
|
|
140
|
+
if (!init) {
|
|
141
|
+
return {
|
|
142
|
+
success: false,
|
|
143
|
+
reason: `CrossFileHealer: property "${key}" in "${symbolName}" has no initializer`,
|
|
144
|
+
strategy: "semantic-cross-file",
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
targetNode = init;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
118
150
|
const before = traceResult.targetFile.getFullText();
|
|
119
|
-
const result = InitializerUpdater_js_1.InitializerUpdater.apply(
|
|
151
|
+
const result = InitializerUpdater_js_1.InitializerUpdater.apply(targetNode, traceResult.targetFile, newValue);
|
|
120
152
|
if (!result) {
|
|
121
153
|
return {
|
|
122
154
|
success: false,
|
|
123
|
-
reason: `CrossFileHealer: InitializerUpdater rejected node type ${
|
|
155
|
+
reason: `CrossFileHealer: InitializerUpdater rejected node type ${targetNode.getKindName()}`,
|
|
124
156
|
strategy: "semantic-cross-file",
|
|
125
157
|
};
|
|
126
158
|
}
|
|
127
|
-
logger_1.logger.debug(`CrossFileHealer healed "${symbolName}" in ${path.basename(externalPath)} ` +
|
|
159
|
+
logger_1.logger.debug(`CrossFileHealer healed "${symbolName}${propertyPath ? "." + propertyPath.join(".") : ""}" in ${path.basename(externalPath)} ` +
|
|
128
160
|
`@ line ${result.lineUpdated + 1}`);
|
|
129
161
|
return {
|
|
130
162
|
success: true,
|
|
@@ -136,6 +168,78 @@ class CrossFileHealer {
|
|
|
136
168
|
unifiedDiff: captureDefinitionDiff(before, traceResult.targetFile, externalPath),
|
|
137
169
|
};
|
|
138
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Heal the return literal of an exported factory function.
|
|
173
|
+
* Handles: `const fn = () => "#selector"` and `function fn() { return "#selector"; }`.
|
|
174
|
+
* Returns failure when the return is a dynamic TemplateExpression (Rule D).
|
|
175
|
+
*/
|
|
176
|
+
static healFactory(modulePath, functionName, newValue, callerFilePath, project) {
|
|
177
|
+
const externalPath = resolveModulePath(modulePath, callerFilePath);
|
|
178
|
+
if (!externalPath) {
|
|
179
|
+
return {
|
|
180
|
+
success: false,
|
|
181
|
+
reason: `CrossFileHealer.healFactory: module "${modulePath}" not found relative to "${path.basename(callerFilePath)}"`,
|
|
182
|
+
strategy: "semantic-cross-file",
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
let externalSf = project.getSourceFile(externalPath);
|
|
186
|
+
if (externalSf) {
|
|
187
|
+
externalSf.refreshFromFileSystemSync();
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
try {
|
|
191
|
+
externalSf = project.addSourceFileAtPath(externalPath);
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
return {
|
|
195
|
+
success: false,
|
|
196
|
+
reason: `CrossFileHealer.healFactory: failed to load "${path.basename(externalPath)}": ${e.message}`,
|
|
197
|
+
strategy: "semantic-cross-file",
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const factoryReturn = findFactoryReturnNode(externalSf, functionName);
|
|
202
|
+
if (!factoryReturn) {
|
|
203
|
+
return {
|
|
204
|
+
success: false,
|
|
205
|
+
reason: `CrossFileHealer.healFactory: "${functionName}" not found or has no analyzable return in ${path.basename(externalPath)}`,
|
|
206
|
+
strategy: "semantic-cross-file",
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
if (factoryReturn.kind === "interpolated") {
|
|
210
|
+
return {
|
|
211
|
+
success: false,
|
|
212
|
+
reason: `CrossFileHealer.healFactory: "${functionName}" returns a dynamic TemplateExpression (Rule D — cannot mutate)`,
|
|
213
|
+
strategy: "semantic-cross-file",
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (factoryReturn.kind === "complex") {
|
|
217
|
+
return {
|
|
218
|
+
success: false,
|
|
219
|
+
reason: `CrossFileHealer.healFactory: "${functionName}" return is not a directly mutable literal — ${factoryReturn.reason}`,
|
|
220
|
+
strategy: "semantic-cross-file",
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
const before = externalSf.getFullText();
|
|
224
|
+
const result = InitializerUpdater_js_1.InitializerUpdater.apply(factoryReturn.node, externalSf, newValue);
|
|
225
|
+
if (!result) {
|
|
226
|
+
return {
|
|
227
|
+
success: false,
|
|
228
|
+
reason: `CrossFileHealer.healFactory: InitializerUpdater rejected ${factoryReturn.node.getKindName()} for "${functionName}"`,
|
|
229
|
+
strategy: "semantic-cross-file",
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
logger_1.logger.debug(`CrossFileHealer.healFactory healed "${functionName}" return in ${path.basename(externalPath)} @ line ${result.lineUpdated + 1}`);
|
|
233
|
+
return {
|
|
234
|
+
success: true,
|
|
235
|
+
reason: `factory return heal in ${path.basename(externalPath)}`,
|
|
236
|
+
strategy: "semantic-cross-file",
|
|
237
|
+
lineUpdated: result.lineUpdated,
|
|
238
|
+
healedLocatorString: newValue,
|
|
239
|
+
definitionSite: { file: externalPath, line: result.lineUpdated + 1 },
|
|
240
|
+
unifiedDiff: captureDefinitionDiff(before, externalSf, externalPath),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
139
243
|
/**
|
|
140
244
|
* Heal a property on a POM class: finds the class by name in the module,
|
|
141
245
|
* locates the string literal argument of a locator stored in `propName`
|
|
@@ -217,13 +321,95 @@ exports.CrossFileHealer = CrossFileHealer;
|
|
|
217
321
|
// ─────────────────────────────────────────────────────────────────
|
|
218
322
|
function resolveModulePath(modulePath, fromFile) {
|
|
219
323
|
const base = path.dirname(path.resolve(fromFile));
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
324
|
+
// Absolute path passed directly (e.g., test harnesses passing a real temp file path).
|
|
325
|
+
if (path.isAbsolute(modulePath)) {
|
|
326
|
+
for (const candidate of [modulePath, modulePath + ".ts", modulePath + ".js"]) {
|
|
327
|
+
if (fs.existsSync(candidate))
|
|
328
|
+
return candidate;
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
// Relative imports — resolve directly.
|
|
333
|
+
if (modulePath.startsWith(".")) {
|
|
334
|
+
const resolved = path.resolve(base, modulePath);
|
|
335
|
+
for (const candidate of [resolved, resolved + ".ts", resolved + ".js"]) {
|
|
336
|
+
if (fs.existsSync(candidate))
|
|
337
|
+
return candidate;
|
|
338
|
+
}
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
// Non-relative — try TS path alias resolution via nearest tsconfig.json.
|
|
342
|
+
const tsconfig = findTsConfig(base);
|
|
343
|
+
if (tsconfig) {
|
|
344
|
+
const aliased = resolvePathAlias(modulePath, tsconfig);
|
|
345
|
+
if (aliased) {
|
|
346
|
+
for (const candidate of [aliased, aliased + ".ts", aliased + ".js"]) {
|
|
347
|
+
if (fs.existsSync(candidate))
|
|
348
|
+
return candidate;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
function findTsConfig(startDir) {
|
|
355
|
+
let dir = path.resolve(startDir);
|
|
356
|
+
const root = path.parse(dir).root;
|
|
357
|
+
while (dir !== root) {
|
|
358
|
+
const candidate = path.join(dir, "tsconfig.json");
|
|
359
|
+
if (fs.existsSync(candidate)) {
|
|
360
|
+
try {
|
|
361
|
+
const raw = JSON.parse(fs.readFileSync(candidate, "utf-8"));
|
|
362
|
+
const co = raw.compilerOptions ?? {};
|
|
363
|
+
return {
|
|
364
|
+
configDir: dir,
|
|
365
|
+
baseUrl: co.baseUrl,
|
|
366
|
+
paths: co.paths ?? {},
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
dir = path.dirname(dir);
|
|
374
|
+
}
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
function resolvePathAlias(modulePath, tsconfig) {
|
|
378
|
+
const { configDir, baseUrl, paths } = tsconfig;
|
|
379
|
+
const baseDir = baseUrl ? path.resolve(configDir, baseUrl) : configDir;
|
|
380
|
+
for (const [pattern, replacements] of Object.entries(paths)) {
|
|
381
|
+
const matched = matchPattern(pattern, modulePath);
|
|
382
|
+
if (matched !== null) {
|
|
383
|
+
for (const replacement of replacements) {
|
|
384
|
+
// Replace `*` in replacement with the captured wildcard portion.
|
|
385
|
+
const expanded = replacement.includes("*")
|
|
386
|
+
? replacement.replace("*", matched)
|
|
387
|
+
: replacement;
|
|
388
|
+
return path.resolve(baseDir, expanded);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
224
391
|
}
|
|
225
392
|
return null;
|
|
226
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Returns the captured wildcard string if `modulePath` matches `pattern`,
|
|
396
|
+
* or null if it does not match.
|
|
397
|
+
* e.g. pattern="@shared-selectors/*", modulePath="@shared-selectors/auth" → "auth"
|
|
398
|
+
*/
|
|
399
|
+
function matchPattern(pattern, modulePath) {
|
|
400
|
+
const starIdx = pattern.indexOf("*");
|
|
401
|
+
if (starIdx === -1) {
|
|
402
|
+
return pattern === modulePath ? "" : null;
|
|
403
|
+
}
|
|
404
|
+
const prefix = pattern.slice(0, starIdx);
|
|
405
|
+
const suffix = pattern.slice(starIdx + 1);
|
|
406
|
+
if (!modulePath.startsWith(prefix))
|
|
407
|
+
return null;
|
|
408
|
+
const afterPrefix = modulePath.slice(prefix.length);
|
|
409
|
+
if (suffix && !afterPrefix.endsWith(suffix))
|
|
410
|
+
return null;
|
|
411
|
+
return suffix ? afterPrefix.slice(0, afterPrefix.length - suffix.length) : afterPrefix;
|
|
412
|
+
}
|
|
227
413
|
/**
|
|
228
414
|
* Locate the first mutable string literal used as a locator selector inside
|
|
229
415
|
* a class property. Checks property declarations first, then constructor
|
|
@@ -283,3 +469,51 @@ function findFirstStringArg(node) {
|
|
|
283
469
|
}
|
|
284
470
|
return null;
|
|
285
471
|
}
|
|
472
|
+
/**
|
|
473
|
+
* Find the first `return` value of an exported function/arrow named `funcName`
|
|
474
|
+
* and classify it.
|
|
475
|
+
*/
|
|
476
|
+
function findFactoryReturnNode(sf, funcName) {
|
|
477
|
+
// Arrow const: `export const fn = (x) => expr`
|
|
478
|
+
const varDecl = sf.getVariableDeclaration(funcName);
|
|
479
|
+
if (varDecl) {
|
|
480
|
+
const init = varDecl.getInitializer();
|
|
481
|
+
if (init && ts_morph_1.Node.isArrowFunction(init)) {
|
|
482
|
+
const body = init.getBody();
|
|
483
|
+
// Concise body: `() => "#selector"`
|
|
484
|
+
if (!ts_morph_1.Node.isBlock(body)) {
|
|
485
|
+
return classifyReturnExpr(body);
|
|
486
|
+
}
|
|
487
|
+
// Block body: `() => { return "#selector"; }`
|
|
488
|
+
return getFirstReturnExpr(body);
|
|
489
|
+
}
|
|
490
|
+
return { kind: "complex", reason: `"${funcName}" initializer is not an ArrowFunction` };
|
|
491
|
+
}
|
|
492
|
+
// Named function declaration: `export function fn(x) { return "..."; }`
|
|
493
|
+
const fnDecl = sf.getFunction(funcName);
|
|
494
|
+
if (fnDecl) {
|
|
495
|
+
const body = fnDecl.getBody();
|
|
496
|
+
if (!body)
|
|
497
|
+
return { kind: "complex", reason: `"${funcName}" function has no body` };
|
|
498
|
+
return getFirstReturnExpr(body);
|
|
499
|
+
}
|
|
500
|
+
return null;
|
|
501
|
+
}
|
|
502
|
+
function getFirstReturnExpr(block) {
|
|
503
|
+
for (const ret of block.getDescendantsOfKind(ts_morph_1.SyntaxKind.ReturnStatement)) {
|
|
504
|
+
const expr = ret.getExpression();
|
|
505
|
+
if (expr)
|
|
506
|
+
return classifyReturnExpr(expr);
|
|
507
|
+
}
|
|
508
|
+
return { kind: "complex", reason: "no return statement found" };
|
|
509
|
+
}
|
|
510
|
+
function classifyReturnExpr(expr) {
|
|
511
|
+
if (ts_morph_1.Node.isStringLiteral(expr) || ts_morph_1.Node.isNoSubstitutionTemplateLiteral(expr)) {
|
|
512
|
+
return { kind: "literal", node: expr };
|
|
513
|
+
}
|
|
514
|
+
if (ts_morph_1.Node.isTemplateExpression(expr)) {
|
|
515
|
+
// TemplateExpression always has interpolations → Rule D.
|
|
516
|
+
return { kind: "interpolated" };
|
|
517
|
+
}
|
|
518
|
+
return { kind: "complex", reason: `return is ${expr.getKindName()} — not a static literal` };
|
|
519
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefinitionTracer.d.ts","sourceRoot":"","sources":["../../src/services/DefinitionTracer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,UAAU,EAKV,aAAa,EACb,6BAA6B,EAC7B,kBAAkB,EAGnB,MAAM,UAAU,CAAC;AAOlB,MAAM,MAAM,WAAW,GACnB;IACE,KAAK,EAAE,IAAI,CAAC;IACZ,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,6FAA6F;IAC7F,eAAe,CAAC,EAAE,IAAI,CAAC;CACxB,GACD;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"DefinitionTracer.d.ts","sourceRoot":"","sources":["../../src/services/DefinitionTracer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,UAAU,EAKV,aAAa,EACb,6BAA6B,EAC7B,kBAAkB,EAGnB,MAAM,UAAU,CAAC;AAOlB,MAAM,MAAM,WAAW,GACnB;IACE,KAAK,EAAE,IAAI,CAAC;IACZ,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,6FAA6F;IAC7F,eAAe,CAAC,EAAE,IAAI,CAAC;CACxB,GACD;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAClG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,kBAAkB,GAC1B;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,EAAE,kBAAkB,CAAC;IACjC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,YAAY,EAAE,UAAU,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,aAAa,GAAG,6BAA6B,CAAC;IAC3D,YAAY,EAAE,UAAU,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAcxC,qBAAa,gBAAgB;IAK3B,MAAM,CAAC,eAAe,CACpB,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAClB,KAAK,SAAI,GACR,WAAW;IA0Fd,MAAM,CAAC,mBAAmB,CACxB,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,GACjB,WAAW;IAwGd,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,WAAW;CAkC5E;AASD,qBAAa,wBAAwB;IACnC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,GAAG,kBAAkB;CAmF3E"}
|
|
@@ -96,56 +96,79 @@ class DefinitionTracer {
|
|
|
96
96
|
reason: "node is not a PropertyAccessExpression",
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (imported) {
|
|
107
|
-
logger_1.logger.debug(`tracePropertyAccess: "${objectName}" comes from "${imported.modulePath}" (cross-file)`);
|
|
108
|
-
return { found: false, crossFile: true, ...imported };
|
|
109
|
-
}
|
|
110
|
-
return {
|
|
111
|
-
found: false,
|
|
112
|
-
crossFile: false,
|
|
113
|
-
reason: `object "${objectName}" not found in file or imports`,
|
|
114
|
-
};
|
|
99
|
+
// Walk the full chain to extract root identifier + ordered property path.
|
|
100
|
+
// e.g. Selectors.Auth.LoginBtn → root="Selectors", path=["Auth","LoginBtn"]
|
|
101
|
+
const propChain = [];
|
|
102
|
+
let cursor = propAccessNode;
|
|
103
|
+
while (ts_morph_1.Node.isPropertyAccessExpression(cursor)) {
|
|
104
|
+
propChain.unshift(cursor.getName());
|
|
105
|
+
cursor = cursor.getExpression();
|
|
115
106
|
}
|
|
116
|
-
|
|
117
|
-
if (!init || !ts_morph_1.Node.isObjectLiteralExpression(init)) {
|
|
107
|
+
if (!ts_morph_1.Node.isIdentifier(cursor)) {
|
|
118
108
|
return {
|
|
119
109
|
found: false,
|
|
120
110
|
crossFile: false,
|
|
121
|
-
reason: `
|
|
111
|
+
reason: `property chain root is ${cursor.getKindName()}, not an Identifier`,
|
|
122
112
|
};
|
|
123
113
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
114
|
+
const rootName = cursor.getText().trim();
|
|
115
|
+
// ── In-file resolution ───────────────────────────────────────────
|
|
116
|
+
const objDecl = findVarDeclInFile(sourceFile, rootName, callerLine);
|
|
117
|
+
if (objDecl) {
|
|
118
|
+
let currentNode = objDecl.getInitializer();
|
|
119
|
+
let lastPropNode = undefined;
|
|
120
|
+
for (const key of propChain) {
|
|
121
|
+
if (!currentNode || !ts_morph_1.Node.isObjectLiteralExpression(currentNode)) {
|
|
122
|
+
return {
|
|
123
|
+
found: false,
|
|
124
|
+
crossFile: false,
|
|
125
|
+
reason: `"${key}" not reachable — "${rootName}" is not an ObjectLiteralExpression at this level`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const prop = currentNode.getProperty(key);
|
|
129
|
+
if (!prop || !ts_morph_1.Node.isPropertyAssignment(prop)) {
|
|
130
|
+
return {
|
|
131
|
+
found: false,
|
|
132
|
+
crossFile: false,
|
|
133
|
+
reason: `property "${key}" not found in "${rootName}"`,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
lastPropNode = prop;
|
|
137
|
+
currentNode = prop.getInitializer();
|
|
138
|
+
}
|
|
139
|
+
if (!currentNode) {
|
|
140
|
+
return {
|
|
141
|
+
found: false,
|
|
142
|
+
crossFile: false,
|
|
143
|
+
reason: `"${rootName}.${propChain.join(".")}" chain resolved to undefined`,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
logger_1.logger.debug(`tracePropertyAccess: "${rootName}.${propChain.join(".")}" → ` +
|
|
147
|
+
`${currentNode.getKindName()} "${currentNode.getText().slice(0, 60)}" ` +
|
|
148
|
+
`@ ${sourceFile.getBaseName()}:${currentNode.getStartLineNumber()}`);
|
|
127
149
|
return {
|
|
128
|
-
found:
|
|
129
|
-
|
|
130
|
-
|
|
150
|
+
found: true,
|
|
151
|
+
targetNode: currentNode,
|
|
152
|
+
targetFile: sourceFile,
|
|
153
|
+
declarationNode: lastPropNode,
|
|
131
154
|
};
|
|
132
155
|
}
|
|
133
|
-
|
|
134
|
-
|
|
156
|
+
// ── Cross-file resolution ────────────────────────────────────────
|
|
157
|
+
const imported = findImportedSymbol(sourceFile, rootName);
|
|
158
|
+
if (imported) {
|
|
159
|
+
logger_1.logger.debug(`tracePropertyAccess: "${rootName}" comes from "${imported.modulePath}" (cross-file), path=[${propChain.join(",")}]`);
|
|
135
160
|
return {
|
|
136
161
|
found: false,
|
|
137
|
-
crossFile:
|
|
138
|
-
|
|
162
|
+
crossFile: true,
|
|
163
|
+
modulePath: imported.modulePath,
|
|
164
|
+
symbolName: imported.symbolName,
|
|
165
|
+
propertyPath: propChain,
|
|
139
166
|
};
|
|
140
167
|
}
|
|
141
|
-
logger_1.logger.debug(`tracePropertyAccess: "${objectName}.${propName}" → ` +
|
|
142
|
-
`${valueNode.getKindName()} "${valueNode.getText()}" ` +
|
|
143
|
-
`@ ${sourceFile.getBaseName()}:${valueNode.getStartLineNumber()}`);
|
|
144
168
|
return {
|
|
145
|
-
found:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
declarationNode: prop,
|
|
169
|
+
found: false,
|
|
170
|
+
crossFile: false,
|
|
171
|
+
reason: `"${rootName}" not found in file or imports`,
|
|
149
172
|
};
|
|
150
173
|
}
|
|
151
174
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AuditVerdict, AuditVerdictValue } from "./IntentAuditor";
|
|
2
2
|
import type { ElementSnapshotV2 } from "../types";
|
|
3
3
|
import { type ReportData, type RegressionState, type RegressionResult } from "./ReportGenerator";
|
|
4
|
+
import type { RegressionManifestRecord } from "./RegressionManifestService";
|
|
4
5
|
import type { ConfidenceVectors } from "./confidence/types";
|
|
5
6
|
export type HealEventKind = "HEALED" | "FAILED" | "PROTECTED" | "BYPASSED";
|
|
6
7
|
export interface DnaSummary {
|
|
@@ -38,12 +39,32 @@ interface HealEventBase {
|
|
|
38
39
|
framePath: string[];
|
|
39
40
|
inIframe: boolean;
|
|
40
41
|
inShadowDom: boolean;
|
|
42
|
+
/** True when this event originated as a BYPASSED fix later resolved by Job 2. */
|
|
43
|
+
wasBypassed?: boolean;
|
|
44
|
+
/** Per-fix blast-radius verdict attached by shadow-regression. */
|
|
45
|
+
regressionState?: RegressionState;
|
|
46
|
+
/** Human-readable note surfaced on the card (passed / why it failed). */
|
|
47
|
+
regressionNote?: string;
|
|
48
|
+
/** The downstream tests that ran for THIS fix — scoped, not the whole run. */
|
|
49
|
+
regressionTests?: RegressionResult[];
|
|
41
50
|
}
|
|
42
51
|
/**
|
|
43
52
|
* Compute a stable, run-independent key for an event.
|
|
44
53
|
* Based solely on immutable facts: normalized file path, line number, and original (broken) selector.
|
|
45
54
|
*/
|
|
46
55
|
export declare function computeEventDeterministicKey(sourceFile: string, sourceLine: number, oldSelector: string): string;
|
|
56
|
+
export interface VisualDiff {
|
|
57
|
+
/** cwd-relative path to the committed DNA baseline PNG, or null on first heal. */
|
|
58
|
+
dnaSnapshotPath: string | null;
|
|
59
|
+
/** cwd-relative path to the live element screenshot captured during this heal. */
|
|
60
|
+
liveSnapshotPath: string | null;
|
|
61
|
+
/** ISO timestamp from the DNA JSON's visualSnapshot.capturedAt field. */
|
|
62
|
+
dnaSnapshotCapturedAt: string | null;
|
|
63
|
+
/** ISO timestamp of the live capture taken during this heal event. */
|
|
64
|
+
liveSnapshotCapturedAt: string | null;
|
|
65
|
+
/** False when the element could not be resolved for screenshotting. */
|
|
66
|
+
elementFound: boolean;
|
|
67
|
+
}
|
|
47
68
|
export interface HealedEvent extends HealEventBase {
|
|
48
69
|
kind: "HEALED";
|
|
49
70
|
dryRun?: boolean;
|
|
@@ -72,6 +93,8 @@ export interface HealedEvent extends HealEventBase {
|
|
|
72
93
|
};
|
|
73
94
|
/** Four-vector confidence breakdown from ConfidenceVectorRule. Optional for backward compat. */
|
|
74
95
|
confidenceVectors?: ConfidenceVectors;
|
|
96
|
+
/** Side-by-side visual baseline vs. live element screenshots. */
|
|
97
|
+
visualDiff?: VisualDiff;
|
|
75
98
|
}
|
|
76
99
|
export interface FailedEvent extends HealEventBase {
|
|
77
100
|
kind: "FAILED";
|
|
@@ -218,10 +241,19 @@ export declare const REPORT_JSON_FILE = "sela-report.json";
|
|
|
218
241
|
* Merge a regression verdict into the report at `targetDir` and rewrite
|
|
219
242
|
* `sela-report.html` + `sela-report.json`. Returns the HTML path.
|
|
220
243
|
* Throws when no base report exists (Job 2 must run after Job 1).
|
|
244
|
+
*
|
|
245
|
+
* When `regression.records` (the manifest) is supplied, each BYPASSED event is
|
|
246
|
+
* reclassified against its OWN blast-radius verdict (see
|
|
247
|
+
* {@link reclassifyBypassEvents}): a fix whose downstream tests all passed is
|
|
248
|
+
* promoted to HEALED, one whose tests broke is demoted to FAILED. Stats + ROI
|
|
249
|
+
* are recomputed from the reclassified stream so the donut, KPIs and filters
|
|
250
|
+
* reflect the post-regression truth — history is left untouched (Job 1 owns it).
|
|
221
251
|
*/
|
|
222
252
|
export declare function mergeRegressionIntoReport(targetDir: string, regression: {
|
|
223
253
|
regressionState: RegressionState;
|
|
224
254
|
regressionTests: RegressionResult[];
|
|
255
|
+
/** Manifest records that drive per-fix bypass reclassification. */
|
|
256
|
+
records?: RegressionManifestRecord[];
|
|
225
257
|
}, opts?: {
|
|
226
258
|
reportJsonPath?: string;
|
|
227
259
|
}): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HealReportService.d.ts","sourceRoot":"","sources":["../../src/services/HealReportService.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGlD,OAAO,EAEL,KAAK,UAAU,EAEf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"HealReportService.d.ts","sourceRoot":"","sources":["../../src/services/HealReportService.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGlD,OAAO,EAEL,KAAK,UAAU,EAEf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAM5D,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC;AAE3E,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,YAAY,CAAC,eAAe,CAAC,CAAC;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,oGAAoG;IACpG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IAOrB,iFAAiF;IACjF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kEAAkE;IAClE,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,eAAe,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,MAAM,CAKR;AAED,MAAM,WAAW,UAAU;IACzB,kFAAkF;IAClF,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kFAAkF;IAClF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,yEAAyE;IACzE,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,sEAAsE;IACtE,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,uEAAuE;IACvE,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,UAAU,CAAC;IACtB,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,aAAa,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,gGAAgG;IAChG,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,iEAAiE;IACjE,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,gGAAgG;IAChG,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mDAAmD;IACnD,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,WAAW,GACX,cAAc,GACd,aAAa,CAAC;AAsBlB,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAInD;AAUD,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,GACtC,UAAU,GAAG,IAAI,CAgBnB;AAMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,SAAS,CAAoC;IAErD,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAc9B,IAAI,IAAI,MAAM;IAId,KAAK,IAAI,IAAI;IAKb,UAAU,IAAI,OAAO;IAIrB,eAAe,IAAI,WAAW,EAAE;IAIhC,kBAAkB,IAAI,cAAc,EAAE;IAMtC,eAAe,IAAI,WAAW,EAAE;IAIhC,iBAAiB,IAAI,aAAa,EAAE;IAIpC;;;;OAIG;IACH,uBAAuB,CACrB,KAAK,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EACrE,SAAS,EAAE,MAAM,GAChB,MAAM;IA2BT,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,YAAY;IAWpB;;;;;OAKG;IACH,WAAW,CACT,SAAS,GAAE,MAAsB,EACjC,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAC5B,MAAM,GAAG,IAAI;IAmBhB;;;;;;;;;;;;;;;;OAgBG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM;IA+B5D;;;;;;;;;;OAUG;IACH,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI;CAcvD;AAMD,eAAO,MAAM,gBAAgB,mBAA0B,CAAC;AAWxD,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE;IACV,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,gBAAgB,EAAE,CAAC;IACpC,mEAAmE;IACnE,OAAO,CAAC,EAAE,wBAAwB,EAAE,CAAC;CACtC,EACD,IAAI,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GACrC,MAAM,CAuCR"}
|