sela-core 1.0.7 → 1.0.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 +27 -17
- package/dist/cli/ErrorHandler.d.ts +1 -1
- package/dist/cli/ErrorHandler.js +14 -14
- package/dist/cli/commands/bulk.d.ts +1 -1
- package/dist/cli/commands/bulk.d.ts.map +1 -1
- package/dist/cli/commands/bulk.js +51 -33
- package/dist/cli/commands/init.d.ts +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +26 -18
- package/dist/cli/commands/merge.d.ts +13 -0
- package/dist/cli/commands/merge.d.ts.map +1 -0
- package/dist/cli/commands/merge.js +119 -0
- package/dist/cli/commands/showReport.d.ts +1 -1
- package/dist/cli/commands/showReport.d.ts.map +1 -1
- package/dist/cli/commands/showReport.js +12 -10
- package/dist/cli/commands/status.d.ts +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +8 -8
- package/dist/cli/commands/sync.d.ts +1 -1
- package/dist/cli/commands/sync.d.ts.map +1 -1
- package/dist/cli/commands/sync.js +38 -30
- package/dist/cli/index.js +12 -9
- package/dist/cli/ui/DnaTable.d.ts +1 -1
- package/dist/cli/ui/DnaTable.d.ts.map +1 -1
- package/dist/cli/ui/DnaTable.js +23 -16
- package/dist/cli/ui/RefactorWizard.d.ts +3 -3
- package/dist/cli/ui/RefactorWizard.d.ts.map +1 -1
- package/dist/cli/ui/RefactorWizard.js +108 -82
- package/dist/config/ConfigLoader.d.ts +2 -2
- package/dist/config/ConfigLoader.d.ts.map +1 -1
- package/dist/config/ConfigLoader.js +15 -15
- package/dist/config/DryRunGuard.d.ts +1 -1
- package/dist/config/DryRunGuard.js +7 -7
- package/dist/config/SelaConfig.d.ts +13 -17
- package/dist/config/SelaConfig.d.ts.map +1 -1
- package/dist/config/SelaConfig.js +32 -26
- package/dist/engine/HealingRegistry.d.ts +1 -1
- package/dist/engine/HealingRegistry.js +3 -3
- package/dist/engine/SelaEngine.d.ts +1 -1
- package/dist/engine/SelaEngine.d.ts.map +1 -1
- package/dist/engine/SelaEngine.js +117 -51
- package/dist/errors/SelaError.d.ts +8 -1
- package/dist/errors/SelaError.d.ts.map +1 -1
- package/dist/errors/SelaError.js +14 -7
- package/dist/fixtures/expectProxy.d.ts +2 -2
- package/dist/fixtures/expectProxy.js +16 -16
- package/dist/fixtures/index.d.ts +18 -2
- package/dist/fixtures/index.d.ts.map +1 -1
- package/dist/fixtures/index.js +47 -27
- package/dist/fixtures/moduleExpect.js +7 -7
- package/dist/fixtures/proxyTag.d.ts +1 -1
- package/dist/fixtures/proxyTag.js +4 -4
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/reporter/SelaReporter.d.ts +45 -12
- package/dist/reporter/SelaReporter.d.ts.map +1 -1
- package/dist/reporter/SelaReporter.js +139 -39
- package/dist/services/ASTSourceUpdater.d.ts +48 -3
- package/dist/services/ASTSourceUpdater.d.ts.map +1 -1
- package/dist/services/ASTSourceUpdater.js +283 -105
- package/dist/services/AnchorResolver.d.ts +157 -0
- package/dist/services/AnchorResolver.d.ts.map +1 -0
- package/dist/services/AnchorResolver.js +289 -0
- package/dist/services/ArgumentTypeAnalyzer.js +7 -7
- package/dist/services/BlastRadiusAnalyzer.d.ts.map +1 -1
- package/dist/services/BlastRadiusAnalyzer.js +5 -2
- package/dist/services/ChainValidator.js +22 -22
- package/dist/services/CrossFileHealer.js +7 -7
- package/dist/services/DecisionEngine.d.ts +51 -0
- package/dist/services/DecisionEngine.d.ts.map +1 -0
- package/dist/services/DecisionEngine.js +260 -0
- package/dist/services/DefinitionTracer.d.ts +1 -1
- package/dist/services/DefinitionTracer.d.ts.map +1 -1
- package/dist/services/DefinitionTracer.js +28 -13
- package/dist/services/DnaEditorService.d.ts +2 -2
- package/dist/services/DnaEditorService.d.ts.map +1 -1
- package/dist/services/DnaEditorService.js +81 -62
- package/dist/services/DnaIndexService.d.ts +1 -1
- package/dist/services/DnaIndexService.d.ts.map +1 -1
- package/dist/services/DnaIndexService.js +14 -14
- package/dist/services/HealReportService.d.ts +31 -55
- package/dist/services/HealReportService.d.ts.map +1 -1
- package/dist/services/HealReportService.js +864 -1240
- package/dist/services/HealingAdvisory.d.ts +9 -1
- package/dist/services/HealingAdvisory.d.ts.map +1 -1
- package/dist/services/HealingAdvisory.js +9 -1
- package/dist/services/HealingCacheService.d.ts +8 -8
- package/dist/services/HealingCacheService.d.ts.map +1 -1
- package/dist/services/HealingCacheService.js +24 -24
- package/dist/services/HealthReportService.d.ts +1 -1
- package/dist/services/HealthReportService.d.ts.map +1 -1
- package/dist/services/HealthReportService.js +25 -25
- package/dist/services/InitializerUpdater.d.ts.map +1 -1
- package/dist/services/InitializerUpdater.js +12 -2
- package/dist/services/IntentAuditor.d.ts.map +1 -1
- package/dist/services/IntentAuditor.js +32 -21
- package/dist/services/InteractiveReview.d.ts +8 -17
- package/dist/services/InteractiveReview.d.ts.map +1 -1
- package/dist/services/InteractiveReview.js +34 -124
- package/dist/services/LLMService.d.ts +1 -1
- package/dist/services/LLMService.js +16 -16
- package/dist/services/MutationApplier.d.ts +55 -0
- package/dist/services/MutationApplier.d.ts.map +1 -0
- package/dist/services/MutationApplier.js +322 -0
- package/dist/services/PRAutomationService.d.ts +2 -2
- package/dist/services/PRAutomationService.d.ts.map +1 -1
- package/dist/services/PRAutomationService.js +43 -39
- package/dist/services/PendingPromptLedger.d.ts +9 -2
- package/dist/services/PendingPromptLedger.d.ts.map +1 -1
- package/dist/services/PendingPromptLedger.js +31 -6
- package/dist/services/ReportGenerator.d.ts +116 -30
- package/dist/services/ReportGenerator.d.ts.map +1 -1
- package/dist/services/ReportGenerator.js +149 -62
- package/dist/services/ReportMergeService.d.ts +95 -0
- package/dist/services/ReportMergeService.d.ts.map +1 -0
- package/dist/services/ReportMergeService.js +0 -0
- package/dist/services/SafetyGuard.d.ts +4 -7
- package/dist/services/SafetyGuard.d.ts.map +1 -1
- package/dist/services/SafetyGuard.js +29 -106
- package/dist/services/SelectorSanitizer.d.ts +52 -0
- package/dist/services/SelectorSanitizer.d.ts.map +1 -0
- package/dist/services/SelectorSanitizer.js +318 -0
- package/dist/services/SnapshotService.js +6 -6
- package/dist/services/SourceLinkService.d.ts +2 -2
- package/dist/services/SourceLinkService.d.ts.map +1 -1
- package/dist/services/SourceLinkService.js +31 -22
- package/dist/services/SourceUpdater.d.ts +1 -1
- package/dist/services/SourceUpdater.d.ts.map +1 -1
- package/dist/services/SourceUpdater.js +44 -26
- package/dist/services/TemplateDiffService.d.ts.map +1 -1
- package/dist/services/TemplateDiffService.js +18 -15
- package/dist/services/TraceBackEngine.d.ts +67 -0
- package/dist/services/TraceBackEngine.d.ts.map +1 -0
- package/dist/services/TraceBackEngine.js +672 -0
- package/dist/services/WorkspaceSnapshotService.d.ts +6 -6
- package/dist/services/WorkspaceSnapshotService.d.ts.map +1 -1
- package/dist/services/WorkspaceSnapshotService.js +10 -12
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/DOMUtils.d.ts +18 -2
- package/dist/utils/DOMUtils.d.ts.map +1 -1
- package/dist/utils/DOMUtils.js +335 -49
- package/dist/utils/IsolatedDiff.d.ts +2 -2
- package/dist/utils/IsolatedDiff.d.ts.map +1 -1
- package/dist/utils/IsolatedDiff.js +13 -10
- package/package.json +2 -2
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export interface FileSnapshot {
|
|
2
2
|
/** Absolute, normalised path of the tracked file. */
|
|
3
3
|
absolutePath: string;
|
|
4
|
-
/** Project-relative path (posix slashes)
|
|
4
|
+
/** Project-relative path (posix slashes) - for diff headers + PR commits. */
|
|
5
5
|
relativePath: string;
|
|
6
6
|
/**
|
|
7
7
|
* Disk content captured BEFORE Sela's first write to this file.
|
|
8
|
-
* May contain the developer's uncommitted edits
|
|
8
|
+
* May contain the developer's uncommitted edits - that's the point.
|
|
9
9
|
*/
|
|
10
10
|
contentBefore: string;
|
|
11
11
|
/** Disk content captured AFTER Sela's latest write. `null` until first postWrite(). */
|
|
12
12
|
contentAfter: string | null;
|
|
13
|
-
/** Content of the file at `HEAD` (last committed)
|
|
13
|
+
/** Content of the file at `HEAD` (last committed) - `null` when untracked / no git. */
|
|
14
14
|
headContent: string | null;
|
|
15
15
|
/** True when `contentBefore !== headContent`, i.e. developer had dirty edits. */
|
|
16
16
|
hadUncommittedChanges: boolean;
|
|
@@ -25,11 +25,11 @@ export declare class WorkspaceSnapshotService {
|
|
|
25
25
|
setCwd(cwd: string): void;
|
|
26
26
|
/**
|
|
27
27
|
* Record the pre-mutation state of `filePath` if not already tracked.
|
|
28
|
-
* Idempotent
|
|
28
|
+
* Idempotent - only the FIRST call per file matters.
|
|
29
29
|
*/
|
|
30
30
|
preWrite(filePath: string): void;
|
|
31
31
|
/**
|
|
32
|
-
* Refresh the post-mutation state. Safe to call multiple times
|
|
32
|
+
* Refresh the post-mutation state. Safe to call multiple times - each
|
|
33
33
|
* call overwrites `contentAfter` with the latest disk state.
|
|
34
34
|
*/
|
|
35
35
|
postWrite(filePath: string): void;
|
|
@@ -45,7 +45,7 @@ export declare class WorkspaceSnapshotService {
|
|
|
45
45
|
/** All snapshots with a real mutation recorded. */
|
|
46
46
|
getMutatedSnapshots(): FileSnapshot[];
|
|
47
47
|
/**
|
|
48
|
-
* Rewind every tracked file on disk to `contentBefore`
|
|
48
|
+
* Rewind every tracked file on disk to `contentBefore` - restoring the
|
|
49
49
|
* developer's pre-Sela workspace state byte-for-byte.
|
|
50
50
|
*/
|
|
51
51
|
restoreOriginal(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceSnapshotService.d.ts","sourceRoot":"","sources":["../../src/services/WorkspaceSnapshotService.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uFAAuF;IACvF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iFAAiF;IACjF,qBAAqB,EAAE,OAAO,CAAC;IAC/B,uEAAuE;IACvE,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,qBAAa,wBAAwB;IACnC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,GAAG,CAAS;gBAER,GAAG,GAAE,MAAsB;IAIvC,sEAAsE;IACtE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAqBhC;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"WorkspaceSnapshotService.d.ts","sourceRoot":"","sources":["../../src/services/WorkspaceSnapshotService.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uFAAuF;IACvF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iFAAiF;IACjF,qBAAqB,EAAE,OAAO,CAAC;IAC/B,uEAAuE;IACvE,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,qBAAa,wBAAwB;IACnC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,GAAG,CAAS;gBAER,GAAG,GAAE,MAAsB;IAIvC,sEAAsE;IACtE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAqBhC;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAOjC,0EAA0E;IAC1E,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAIlD,+CAA+C;IAC/C,eAAe,IAAI,YAAY,EAAE;IAIjC;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAMpC,mDAAmD;IACnD,mBAAmB,IAAI,YAAY,EAAE;IAMrC;;;OAGG;IACH,eAAe,IAAI,IAAI;IAMvB;;;;OAIG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAOhD,OAAO,CAAC,cAAc;IAUtB;;;;OAIG;IACH,cAAc,IAAI,IAAI;IAOtB,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,eAAe;CAcxB;AAED,eAAO,MAAM,uBAAuB,0BAAiC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// src/services/WorkspaceSnapshotService.ts
|
|
3
3
|
//
|
|
4
|
-
// Clean-Room Architecture
|
|
4
|
+
// Clean-Room Architecture - file 1 of 2.
|
|
5
5
|
//
|
|
6
6
|
// Tracks the EXACT content of every file Sela mutates during a session, so:
|
|
7
7
|
// • The HTML report diff can be generated from an isolated in-memory diff
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
// byte-for-byte after a PR is opened on an isolated branch.
|
|
11
11
|
//
|
|
12
12
|
// Lifecycle:
|
|
13
|
-
// preWrite(path)
|
|
13
|
+
// preWrite(path) - first call per file records `contentBefore` (disk
|
|
14
14
|
// snapshot right before Sela touches it) + HEAD blob.
|
|
15
|
-
// postWrite(path)
|
|
16
|
-
// restoreOriginal()
|
|
17
|
-
// restoreMutated()
|
|
18
|
-
// clear()
|
|
15
|
+
// postWrite(path) - refreshes `contentAfter` (latest disk state).
|
|
16
|
+
// restoreOriginal()- writes contentBefore back to every tracked file.
|
|
17
|
+
// restoreMutated() - writes contentAfter back to every tracked file.
|
|
18
|
+
// clear() - empties the ledger.
|
|
19
19
|
//
|
|
20
20
|
// Singleton `sharedWorkspaceSnapshot` is the canonical instance the
|
|
21
21
|
// SourceUpdater / ASTSourceUpdater write hooks talk to.
|
|
@@ -69,7 +69,7 @@ class WorkspaceSnapshotService {
|
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
71
|
* Record the pre-mutation state of `filePath` if not already tracked.
|
|
72
|
-
* Idempotent
|
|
72
|
+
* Idempotent - only the FIRST call per file matters.
|
|
73
73
|
*/
|
|
74
74
|
preWrite(filePath) {
|
|
75
75
|
const abs = this.normalise(filePath);
|
|
@@ -90,7 +90,7 @@ class WorkspaceSnapshotService {
|
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
/**
|
|
93
|
-
* Refresh the post-mutation state. Safe to call multiple times
|
|
93
|
+
* Refresh the post-mutation state. Safe to call multiple times - each
|
|
94
94
|
* call overwrites `contentAfter` with the latest disk state.
|
|
95
95
|
*/
|
|
96
96
|
postWrite(filePath) {
|
|
@@ -98,9 +98,7 @@ class WorkspaceSnapshotService {
|
|
|
98
98
|
const snap = this.snapshots.get(abs);
|
|
99
99
|
if (!snap)
|
|
100
100
|
return;
|
|
101
|
-
snap.contentAfter = fs.existsSync(abs)
|
|
102
|
-
? fs.readFileSync(abs, "utf8")
|
|
103
|
-
: "";
|
|
101
|
+
snap.contentAfter = fs.existsSync(abs) ? fs.readFileSync(abs, "utf8") : "";
|
|
104
102
|
}
|
|
105
103
|
/** Lookup by absolute or relative path. Returns `null` when untracked. */
|
|
106
104
|
getSnapshot(filePath) {
|
|
@@ -125,7 +123,7 @@ class WorkspaceSnapshotService {
|
|
|
125
123
|
return this.getAllSnapshots().filter((s) => s.contentAfter !== null && s.contentAfter !== s.contentBefore);
|
|
126
124
|
}
|
|
127
125
|
/**
|
|
128
|
-
* Rewind every tracked file on disk to `contentBefore`
|
|
126
|
+
* Rewind every tracked file on disk to `contentBefore` - restoring the
|
|
129
127
|
* developer's pre-Sela workspace state byte-for-byte.
|
|
130
128
|
*/
|
|
131
129
|
restoreOriginal() {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export interface AncestorNode {
|
|
|
2
2
|
tag: string;
|
|
3
3
|
id: string | null;
|
|
4
4
|
classes: string[];
|
|
5
|
-
/** "{tag}#{id}[{classes_sorted_asc}]"
|
|
5
|
+
/** "{tag}#{id}[{classes_sorted_asc}]" - stable fingerprint for drift comparison */
|
|
6
6
|
fingerprint: string;
|
|
7
7
|
}
|
|
8
8
|
export type GhostCondition = "G1_DISPLAY_NONE" | "G2_VISIBILITY_HIDDEN" | "G3_OPACITY_ZERO" | "G4_POINTER_EVENTS_NONE" | "G5_ZERO_AREA" | "G6_CONTENT_VISIBILITY_HIDDEN";
|
package/dist/utils/DOMUtils.d.ts
CHANGED
|
@@ -24,8 +24,24 @@ export declare class DOMUtils {
|
|
|
24
24
|
*/
|
|
25
25
|
private static _getNeighborhoodFromFrame;
|
|
26
26
|
/**
|
|
27
|
-
* Runs the
|
|
28
|
-
* context (
|
|
27
|
+
* Runs the "Smart Neighborhood" DOM-extraction script inside the given
|
|
28
|
+
* execution context (a Page or a Frame). Implements asymmetric scope:
|
|
29
|
+
*
|
|
30
|
+
* - FULL semantic ancestry spine (anchor → root, crossing shadow→host)
|
|
31
|
+
* is always kept — this is cheap and carries the critical context
|
|
32
|
+
* (form/fieldset/dialog/landmark/id anchors).
|
|
33
|
+
* - SIBLINGS are pruned to a fixed K-window around the spine child; the
|
|
34
|
+
* number dropped is surfaced via `data-sibling-total` so the AI knows
|
|
35
|
+
* pruning occurred (and never assumes a positional selector is safe).
|
|
36
|
+
* - GLOBAL uniqueness is probed in the SAME evaluate pass; when the
|
|
37
|
+
* anchor's primary signal matches >1 element page-wide, the count is
|
|
38
|
+
* attached as `fx-global-matches` — this defeats the "neighborhood is
|
|
39
|
+
* unique but the page is not" trap without shipping the whole DOM.
|
|
40
|
+
* - Char-budget (cheap proxy for tokens) bounds the final payload.
|
|
41
|
+
*
|
|
42
|
+
* Generic wrappers (div/span) with no semantic signal are collapsed; visual
|
|
43
|
+
* noise (class/style) is stripped; script/style/svg and hidden elements are
|
|
44
|
+
* dropped. Shadow DOM and same-origin iframe content are pierced and inlined.
|
|
29
45
|
*/
|
|
30
46
|
private static _evaluateNeighborhood;
|
|
31
47
|
static getElementDNA: (page: Page, selector: string) => Promise<ElementDNA>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DOMUtils.d.ts","sourceRoot":"","sources":["../../src/utils/DOMUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,qBAAa,QAAQ;IACnB;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAKjD;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;WAM5B,kBAAkB,CACpC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAerD;;;;OAIG;mBACkB,yBAAyB;IAoD9C
|
|
1
|
+
{"version":3,"file":"DOMUtils.d.ts","sourceRoot":"","sources":["../../src/utils/DOMUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,qBAAa,QAAQ;IACnB;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAKjD;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;WAM5B,kBAAkB,CACpC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAerD;;;;OAIG;mBACkB,yBAAyB;IAoD9C;;;;;;;;;;;;;;;;;;;OAmBG;mBACkB,qBAAqB;IAoW1C,MAAM,CAAC,aAAa,GAClB,MAAM,IAAI,EACV,UAAU,MAAM,KACf,OAAO,CAAC,UAAU,CAAC,CAqCpB;CACH"}
|
package/dist/utils/DOMUtils.js
CHANGED
|
@@ -76,68 +76,354 @@ class DOMUtils {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
|
-
* Runs the
|
|
80
|
-
* context (
|
|
79
|
+
* Runs the "Smart Neighborhood" DOM-extraction script inside the given
|
|
80
|
+
* execution context (a Page or a Frame). Implements asymmetric scope:
|
|
81
|
+
*
|
|
82
|
+
* - FULL semantic ancestry spine (anchor → root, crossing shadow→host)
|
|
83
|
+
* is always kept — this is cheap and carries the critical context
|
|
84
|
+
* (form/fieldset/dialog/landmark/id anchors).
|
|
85
|
+
* - SIBLINGS are pruned to a fixed K-window around the spine child; the
|
|
86
|
+
* number dropped is surfaced via `data-sibling-total` so the AI knows
|
|
87
|
+
* pruning occurred (and never assumes a positional selector is safe).
|
|
88
|
+
* - GLOBAL uniqueness is probed in the SAME evaluate pass; when the
|
|
89
|
+
* anchor's primary signal matches >1 element page-wide, the count is
|
|
90
|
+
* attached as `fx-global-matches` — this defeats the "neighborhood is
|
|
91
|
+
* unique but the page is not" trap without shipping the whole DOM.
|
|
92
|
+
* - Char-budget (cheap proxy for tokens) bounds the final payload.
|
|
93
|
+
*
|
|
94
|
+
* Generic wrappers (div/span) with no semantic signal are collapsed; visual
|
|
95
|
+
* noise (class/style) is stripped; script/style/svg and hidden elements are
|
|
96
|
+
* dropped. Shadow DOM and same-origin iframe content are pierced and inlined.
|
|
81
97
|
*/
|
|
82
98
|
static async _evaluateNeighborhood(context, selector) {
|
|
83
|
-
console.log(`[DOM-EXTRACT] 🧠
|
|
84
|
-
const result = await context.evaluate(() => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
99
|
+
console.log(`[DOM-EXTRACT] 🧠 Smart-Neighborhood extraction for: "${selector}"`);
|
|
100
|
+
const result = await context.evaluate((cfg) => {
|
|
101
|
+
const { selector, K, maxText, budget } = cfg;
|
|
102
|
+
// ---- Tag taxonomies ------------------------------------------------
|
|
103
|
+
const SKIP = new Set([
|
|
104
|
+
"script",
|
|
105
|
+
"style",
|
|
106
|
+
"link",
|
|
107
|
+
"svg",
|
|
108
|
+
"noscript",
|
|
109
|
+
"template",
|
|
110
|
+
"meta",
|
|
111
|
+
]);
|
|
112
|
+
// Kept verbatim but never directly selectable → no fx-id index.
|
|
113
|
+
const CONTAINER = new Set([
|
|
114
|
+
"html",
|
|
115
|
+
"body",
|
|
116
|
+
"form",
|
|
117
|
+
"nav",
|
|
118
|
+
"section",
|
|
119
|
+
"header",
|
|
120
|
+
"footer",
|
|
121
|
+
"main",
|
|
122
|
+
"article",
|
|
123
|
+
"aside",
|
|
124
|
+
"ul",
|
|
125
|
+
"ol",
|
|
126
|
+
"dl",
|
|
127
|
+
"table",
|
|
128
|
+
"thead",
|
|
129
|
+
"tbody",
|
|
130
|
+
"tfoot",
|
|
131
|
+
"tr",
|
|
132
|
+
"colgroup",
|
|
133
|
+
"fieldset",
|
|
134
|
+
"figure",
|
|
135
|
+
"figcaption",
|
|
136
|
+
"caption",
|
|
137
|
+
"menu",
|
|
138
|
+
"details",
|
|
139
|
+
]);
|
|
140
|
+
// Generic layout wrappers: collapsed when they carry no semantic signal.
|
|
141
|
+
const COLLAPSIBLE = new Set(["div", "span"]);
|
|
142
|
+
const SIGNAL_ATTRS = ["id", "data-testid", "name", "role", "aria-label"];
|
|
143
|
+
// Output attribute allow-list (class/style intentionally excluded).
|
|
144
|
+
const PRESERVED = [
|
|
145
|
+
"id",
|
|
146
|
+
"data-testid",
|
|
147
|
+
"name",
|
|
148
|
+
"role",
|
|
149
|
+
"type",
|
|
150
|
+
"href",
|
|
151
|
+
"alt",
|
|
152
|
+
"title",
|
|
153
|
+
"placeholder",
|
|
154
|
+
"value",
|
|
155
|
+
"aria-label",
|
|
156
|
+
"aria-labelledby",
|
|
157
|
+
"aria-describedby",
|
|
158
|
+
"for",
|
|
159
|
+
"list",
|
|
160
|
+
"src",
|
|
161
|
+
"srcdoc",
|
|
162
|
+
];
|
|
163
|
+
const isTransparent = (tag) => tag === "body" || tag === "html";
|
|
164
|
+
// ---- Deep query: pierce shadow roots + same-origin iframes ---------
|
|
165
|
+
const deepQuery = (root, sel) => {
|
|
166
|
+
let found = null;
|
|
167
|
+
try {
|
|
168
|
+
found = root.querySelector(sel);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
found = null;
|
|
172
|
+
}
|
|
173
|
+
if (found)
|
|
174
|
+
return found;
|
|
175
|
+
let nodes = [];
|
|
176
|
+
try {
|
|
177
|
+
nodes = Array.from(root.querySelectorAll("*"));
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
nodes = [];
|
|
181
|
+
}
|
|
182
|
+
for (const e of nodes) {
|
|
183
|
+
if (e.shadowRoot) {
|
|
184
|
+
const r = deepQuery(e.shadowRoot, sel);
|
|
185
|
+
if (r)
|
|
186
|
+
return r;
|
|
187
|
+
}
|
|
188
|
+
if (e.tagName === "IFRAME") {
|
|
189
|
+
try {
|
|
190
|
+
const d = e.contentDocument;
|
|
191
|
+
if (d) {
|
|
192
|
+
const r = deepQuery(d, sel);
|
|
193
|
+
if (r)
|
|
194
|
+
return r;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
/* cross-origin frame — skip */
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
};
|
|
204
|
+
// ---- Visibility ----------------------------------------------------
|
|
205
|
+
const isHidden = (el) => {
|
|
206
|
+
const e = el;
|
|
207
|
+
if (e.getAttribute && e.getAttribute("aria-hidden") === "true")
|
|
208
|
+
return true;
|
|
209
|
+
if (e.hasAttribute && e.hasAttribute("hidden"))
|
|
210
|
+
return true;
|
|
211
|
+
if (el.tagName === "INPUT" && e.getAttribute("type") === "hidden")
|
|
212
|
+
return true;
|
|
213
|
+
if (e.style &&
|
|
214
|
+
(e.style.display === "none" || e.style.visibility === "hidden"))
|
|
215
|
+
return true;
|
|
216
|
+
try {
|
|
217
|
+
const view = el.ownerDocument?.defaultView || window;
|
|
218
|
+
const cs = view.getComputedStyle(e);
|
|
219
|
+
if (cs && (cs.display === "none" || cs.visibility === "hidden"))
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
/* getComputedStyle across docs may throw — ignore */
|
|
224
|
+
}
|
|
225
|
+
return false;
|
|
226
|
+
};
|
|
227
|
+
const hasSignal = (el) => SIGNAL_ATTRS.some((a) => !!el.getAttribute?.(a));
|
|
228
|
+
const containsHeader = (el) => el.tagName === "TH" || !!el.querySelector?.("th");
|
|
229
|
+
// ---- Anchor + ancestry spine --------------------------------------
|
|
230
|
+
const anchor = deepQuery(document, selector);
|
|
231
|
+
const spine = new Set();
|
|
232
|
+
// Walk an element + all its ancestors into the spine, crossing shadow
|
|
233
|
+
// boundaries (ShadowRoot, nodeType 11 → host element).
|
|
234
|
+
const addLineage = (start) => {
|
|
235
|
+
let cur = start;
|
|
236
|
+
while (cur) {
|
|
237
|
+
spine.add(cur);
|
|
238
|
+
if (!cur.parentNode)
|
|
239
|
+
break;
|
|
240
|
+
cur =
|
|
241
|
+
cur.parentNode.nodeType === 11
|
|
242
|
+
? cur.parentNode.host || null
|
|
243
|
+
: cur.parentNode;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
if (anchor) {
|
|
247
|
+
addLineage(anchor);
|
|
248
|
+
// Detached semantic refs (#14-16): the accessible name/description
|
|
249
|
+
// may live anywhere in the document, linked only by id. Pull those
|
|
250
|
+
// nodes (and their lineage) into the spine so pruning never drops
|
|
251
|
+
// the context the AI needs for getByLabel / aria-based selectors.
|
|
252
|
+
const refIds = [];
|
|
253
|
+
["aria-labelledby", "aria-describedby", "list"].forEach((a) => {
|
|
254
|
+
const v = anchor.getAttribute(a);
|
|
255
|
+
if (v)
|
|
256
|
+
refIds.push(...v.split(/\s+/).filter(Boolean));
|
|
257
|
+
});
|
|
258
|
+
refIds.forEach((id) => {
|
|
259
|
+
const e = document.getElementById(id);
|
|
260
|
+
if (e)
|
|
261
|
+
addLineage(e);
|
|
262
|
+
});
|
|
263
|
+
// Reverse link: <label for="anchorId"> sitting elsewhere in the DOM.
|
|
264
|
+
const aid = anchor.getAttribute("id");
|
|
265
|
+
if (aid) {
|
|
266
|
+
try {
|
|
267
|
+
document
|
|
268
|
+
.querySelectorAll(`label[for="${aid.replace(/(["\\])/g, "\\$1")}"]`)
|
|
269
|
+
.forEach((l) => addLineage(l));
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
/* ignore malformed id */
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// ---- Global uniqueness probe (same evaluate pass) -----------------
|
|
277
|
+
const globalMatches = (el) => {
|
|
278
|
+
const esc = (v) => v.replace(/(["\\])/g, "\\$1");
|
|
279
|
+
const testid = el.getAttribute("data-testid");
|
|
280
|
+
const id = el.getAttribute("id");
|
|
281
|
+
const name = el.getAttribute("name");
|
|
282
|
+
const role = el.getAttribute("role");
|
|
283
|
+
const tag = el.tagName.toLowerCase();
|
|
284
|
+
let sel = "";
|
|
285
|
+
if (testid)
|
|
286
|
+
sel = `[data-testid="${esc(testid)}"]`;
|
|
287
|
+
else if (id)
|
|
288
|
+
sel = `#${window.CSS?.escape ? CSS.escape(id) : id}`;
|
|
289
|
+
else if (name)
|
|
290
|
+
sel = `${tag}[name="${esc(name)}"]`;
|
|
291
|
+
else if (role)
|
|
292
|
+
sel = `${tag}[role="${esc(role)}"]`;
|
|
293
|
+
else {
|
|
294
|
+
// No stable attr — count same-tag elements sharing trimmed text.
|
|
295
|
+
const txt = (el.textContent || "").trim();
|
|
296
|
+
if (!txt)
|
|
297
|
+
return 1;
|
|
298
|
+
let n = 0;
|
|
299
|
+
document.querySelectorAll(tag).forEach((c) => {
|
|
300
|
+
if ((c.textContent || "").trim() === txt)
|
|
301
|
+
n++;
|
|
302
|
+
});
|
|
303
|
+
return n;
|
|
304
|
+
}
|
|
305
|
+
try {
|
|
306
|
+
return document.querySelectorAll(sel).length;
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
return 1;
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
const counter = { v: 0 };
|
|
313
|
+
const truncate = (s) => s.length > maxText ? s.slice(0, maxText) + "…" : s;
|
|
314
|
+
const renderNode = (node) => {
|
|
315
|
+
// --- Text node ---
|
|
88
316
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
89
|
-
const
|
|
90
|
-
return
|
|
317
|
+
const t = node.textContent ? node.textContent.trim() : "";
|
|
318
|
+
return t ? truncate(t) : null;
|
|
91
319
|
}
|
|
92
|
-
|
|
93
|
-
if (node.nodeType !== Node.ELEMENT_NODE &&
|
|
94
|
-
!(node instanceof ShadowRoot))
|
|
320
|
+
const isShadow = typeof ShadowRoot !== "undefined" && node instanceof ShadowRoot;
|
|
321
|
+
if (node.nodeType !== Node.ELEMENT_NODE && !isShadow)
|
|
95
322
|
return null;
|
|
96
|
-
const el =
|
|
323
|
+
const el = isShadow
|
|
97
324
|
? node.host
|
|
98
325
|
: node;
|
|
99
|
-
const tag =
|
|
100
|
-
if (
|
|
326
|
+
const tag = isShadow ? "shadow-root" : el.tagName.toLowerCase();
|
|
327
|
+
if (SKIP.has(tag))
|
|
101
328
|
return null;
|
|
102
|
-
|
|
329
|
+
if (!isShadow && isHidden(el))
|
|
330
|
+
return null;
|
|
331
|
+
// --- Gather children: shadow root + light DOM + same-doc iframe ---
|
|
332
|
+
let childNodes = [];
|
|
333
|
+
if (!isShadow && el.shadowRoot) {
|
|
334
|
+
childNodes.push(...Array.from(el.shadowRoot.childNodes));
|
|
335
|
+
}
|
|
336
|
+
childNodes.push(...Array.from(node.childNodes));
|
|
337
|
+
if (tag === "iframe") {
|
|
338
|
+
try {
|
|
339
|
+
const d = el.contentDocument;
|
|
340
|
+
if (d && d.body)
|
|
341
|
+
childNodes.push(...Array.from(d.body.childNodes));
|
|
342
|
+
}
|
|
343
|
+
catch {
|
|
344
|
+
/* cross-origin frame — handled by the >> drill instead */
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// --- Asymmetric scope: K-window siblings around the spine child ---
|
|
348
|
+
// Header rows (containing <th>) are always pinned so table column
|
|
349
|
+
// context survives even when data rows are pruned.
|
|
350
|
+
let siblingTotal = -1;
|
|
351
|
+
if (anchor && spine.has(el) && el !== anchor) {
|
|
352
|
+
const elemKids = childNodes.filter((n) => n.nodeType === Node.ELEMENT_NODE);
|
|
353
|
+
const pivot = elemKids.findIndex((k) => spine.has(k));
|
|
354
|
+
if (pivot >= 0) {
|
|
355
|
+
const keep = new Set();
|
|
356
|
+
let pruned = false;
|
|
357
|
+
elemKids.forEach((k, i) => {
|
|
358
|
+
if (spine.has(k) ||
|
|
359
|
+
(i >= pivot - K && i <= pivot + K) ||
|
|
360
|
+
containsHeader(k))
|
|
361
|
+
keep.add(k);
|
|
362
|
+
else
|
|
363
|
+
pruned = true;
|
|
364
|
+
});
|
|
365
|
+
if (pruned) {
|
|
366
|
+
siblingTotal = elemKids.length;
|
|
367
|
+
childNodes = childNodes.filter((n) => n.nodeType !== Node.ELEMENT_NODE ||
|
|
368
|
+
keep.has(n));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
// Generic wrappers with no semantic signal collapse to their
|
|
373
|
+
// children; transparent roots (body/html) emit children only.
|
|
374
|
+
// Neither emits a tag or consumes an fx-id index.
|
|
375
|
+
const collapses = COLLAPSIBLE.has(tag) && !hasSignal(el);
|
|
376
|
+
if (collapses || isTransparent(tag)) {
|
|
377
|
+
return childNodes.map(renderNode).filter(Boolean).join("") || null;
|
|
378
|
+
}
|
|
379
|
+
// Reserve this element's fx-id BEFORE rendering children so the
|
|
380
|
+
// index reflects document order (parent indexed before its kids).
|
|
381
|
+
const isContainer = CONTAINER.has(tag);
|
|
382
|
+
const fxId = isContainer ? -1 : counter.v++;
|
|
383
|
+
const childHtml = childNodes.map(renderNode).filter(Boolean).join("");
|
|
384
|
+
// --- Build attributes ---
|
|
103
385
|
const attrs = [];
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
386
|
+
if (fxId >= 0)
|
|
387
|
+
attrs.push(`fx-id="${fxId}"`);
|
|
388
|
+
if (anchor && el === anchor) {
|
|
389
|
+
const n = globalMatches(el);
|
|
390
|
+
if (n > 1)
|
|
391
|
+
attrs.push(`fx-global-matches="${n}"`);
|
|
392
|
+
}
|
|
393
|
+
if (siblingTotal > 0)
|
|
394
|
+
attrs.push(`data-sibling-total="${siblingTotal}"`);
|
|
395
|
+
for (const a of PRESERVED) {
|
|
114
396
|
const v = el.getAttribute?.(a);
|
|
115
|
-
if (v)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
397
|
+
if (v)
|
|
398
|
+
attrs.push(`${a}="${a === "srcdoc" ? v.substring(0, 200) : v}"`);
|
|
399
|
+
}
|
|
400
|
+
// Image filename fallback: even without alt/title the basename of the
|
|
401
|
+
// src often carries intent (e.g. trash-can-icon.svg).
|
|
402
|
+
if (tag === "img") {
|
|
403
|
+
const src = el.getAttribute("src");
|
|
404
|
+
if (src) {
|
|
405
|
+
const base = src
|
|
406
|
+
.split("?")[0]
|
|
407
|
+
.split("#")[0]
|
|
408
|
+
.split("/")
|
|
409
|
+
.filter(Boolean)
|
|
410
|
+
.pop();
|
|
411
|
+
if (base)
|
|
412
|
+
attrs.push(`data-src-name="${base}"`);
|
|
119
413
|
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
childrenArr.push(...Array.from(el.shadowRoot.childNodes));
|
|
126
|
-
}
|
|
127
|
-
childrenArr.push(...Array.from(node.childNodes));
|
|
128
|
-
// 5. עיבוד ילדים וטקסט פנימי
|
|
129
|
-
const childrenHtml = childrenArr
|
|
130
|
-
.map(processNode)
|
|
131
|
-
.filter(Boolean)
|
|
132
|
-
.join("");
|
|
133
|
-
// אם אין ילדים אבל יש טקסט (כמו בכפתור), ניקח אותו
|
|
134
|
-
const innerContent = childrenHtml || node.textContent?.trim() || "";
|
|
135
|
-
const attrStr = attrs.length > 0 ? " " + attrs.join(" ") : "";
|
|
136
|
-
return `<${tag}${attrStr}>${innerContent}</${tag}>`;
|
|
414
|
+
}
|
|
415
|
+
const inner = childHtml ||
|
|
416
|
+
(node.textContent ? truncate(node.textContent.trim()) : "");
|
|
417
|
+
const attrStr = attrs.length ? " " + attrs.join(" ") : "";
|
|
418
|
+
return `<${tag}${attrStr}>${inner}</${tag}>`;
|
|
137
419
|
};
|
|
138
420
|
const root = document.body || document.documentElement;
|
|
139
|
-
|
|
140
|
-
|
|
421
|
+
let out = renderNode(root) || "";
|
|
422
|
+
// Char-budget hard cap (cheap token proxy) — degrade, never overflow.
|
|
423
|
+
if (out.length > budget)
|
|
424
|
+
out = out.slice(0, budget) + "<!--fx-truncated-->";
|
|
425
|
+
return out;
|
|
426
|
+
}, { selector, K: 3, maxText: 200, budget: 25000 });
|
|
141
427
|
return result;
|
|
142
428
|
}
|
|
143
429
|
static getElementDNA = async (page, selector) => {
|
|
@@ -32,13 +32,13 @@ export declare function extractChangeBlocks(before: string, after: string): Chan
|
|
|
32
32
|
export interface ApplyBlocksResult {
|
|
33
33
|
ok: boolean;
|
|
34
34
|
result?: string;
|
|
35
|
-
/** Human-readable failure reason
|
|
35
|
+
/** Human-readable failure reason - surfaced in the PR-automation log. */
|
|
36
36
|
reason?: string;
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
39
|
* Replay a list of change blocks against a fresh base buffer (typically
|
|
40
40
|
* the file's `HEAD` blob). Each block is applied via UNIQUE substring
|
|
41
|
-
* replacement
|
|
41
|
+
* replacement - when the old block is missing or ambiguous in the base,
|
|
42
42
|
* we fail loudly rather than silently mutating the wrong spot.
|
|
43
43
|
*/
|
|
44
44
|
export declare function applyChangeBlocks(base: string, blocks: ChangeBlock[]): ApplyBlocksResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IsolatedDiff.d.ts","sourceRoot":"","sources":["../../src/utils/IsolatedDiff.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,mBAAwB,GAC7B,MAAM,CAsBR;
|
|
1
|
+
{"version":3,"file":"IsolatedDiff.d.ts","sourceRoot":"","sources":["../../src/utils/IsolatedDiff.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,mBAAwB,GAC7B,MAAM,CAsBR;AA6PD,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,WAAW,EAAE,CAoDf;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EAAE,GACpB,iBAAiB,CAuDnB"}
|