@enricai/barnacle 1.6.1 → 1.6.2
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 +13 -11
- package/dist/scraper/deep-query.d.ts +36 -0
- package/dist/scraper/deep-query.d.ts.map +1 -0
- package/dist/scraper/deep-query.js +87 -0
- package/dist/scraper/deep-query.js.map +1 -0
- package/dist/scraper/errors.d.ts +11 -2
- package/dist/scraper/errors.d.ts.map +1 -1
- package/dist/scraper/errors.js +10 -1
- package/dist/scraper/errors.js.map +1 -1
- package/dist/scraper/flow-runner.d.ts +55 -4
- package/dist/scraper/flow-runner.d.ts.map +1 -1
- package/dist/scraper/flow-runner.js +240 -50
- package/dist/scraper/flow-runner.js.map +1 -1
- package/dist/scraper/phantom-click.d.ts +45 -0
- package/dist/scraper/phantom-click.d.ts.map +1 -0
- package/dist/scraper/phantom-click.js +37 -0
- package/dist/scraper/phantom-click.js.map +1 -0
- package/dist/scraper/session-browserbase.d.ts +48 -0
- package/dist/scraper/session-browserbase.d.ts.map +1 -1
- package/dist/scraper/session-browserbase.js +10 -5
- package/dist/scraper/session-browserbase.js.map +1 -1
- package/dist/scraper/session-shared.d.ts +6 -0
- package/dist/scraper/session-shared.d.ts.map +1 -1
- package/dist/scraper/session-shared.js.map +1 -1
- package/dist/scraper/submit-control.d.ts +51 -0
- package/dist/scraper/submit-control.d.ts.map +1 -0
- package/dist/scraper/submit-control.js +142 -0
- package/dist/scraper/submit-control.js.map +1 -0
- package/dist/scripts/recon-browser.d.ts +23 -18
- package/dist/scripts/recon-browser.d.ts.map +1 -1
- package/dist/scripts/recon-browser.js +51 -42
- package/dist/scripts/recon-browser.js.map +1 -1
- package/dist/scripts/recon-generate.d.ts +28 -7
- package/dist/scripts/recon-generate.d.ts.map +1 -1
- package/dist/scripts/recon-generate.js +50 -24
- package/dist/scripts/recon-generate.js.map +1 -1
- package/dist/scripts/recon-http.d.ts +36 -5
- package/dist/scripts/recon-http.d.ts.map +1 -1
- package/dist/scripts/recon-http.js +77 -47
- package/dist/scripts/recon-http.js.map +1 -1
- package/dist/scripts/recon-replay-jobs.d.ts +25 -1
- package/dist/scripts/recon-replay-jobs.d.ts.map +1 -1
- package/dist/scripts/recon-replay-jobs.js +33 -23
- package/dist/scripts/recon-replay-jobs.js.map +1 -1
- package/dist/scripts/recon-shared.d.ts +35 -0
- package/dist/scripts/recon-shared.d.ts.map +1 -1
- package/dist/scripts/recon-shared.js +92 -0
- package/dist/scripts/recon-shared.js.map +1 -1
- package/dist/scripts/recon-summarize.d.ts +5 -1
- package/dist/scripts/recon-summarize.d.ts.map +1 -1
- package/dist/scripts/recon-summarize.js +19 -7
- package/dist/scripts/recon-summarize.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phantom-click.d.ts","sourceRoot":"","sources":["../../src/scraper/phantom-click.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,sFAAsF;AACtF,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,GAAG,EAAE,oBAAoB,CAAC;IAC1B,IAAI,EAAE,oBAAoB,CAAC;CAC5B;AAED,MAAM,MAAM,mBAAmB;AAC7B,0FAA0F;AACxF,SAAS;AACX,mEAAmE;GACjE,WAAW;AACb,kKAAkK;GAChK,YAAY,CAAC;AAEjB;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,mBAAmB,CAStF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pure phantom-click predicate. `describeAttemptEffectSignals` (flow-runner.ts)
|
|
4
|
+
* renders pre/post deltas into a diagnostic string for LLM consumption; this
|
|
5
|
+
* module renders the same shape of data into a decision so the cascade can
|
|
6
|
+
* escalate immediately instead of repeating techniques that all no-op the
|
|
7
|
+
* same way (see recon-submit-phantom-click bug report).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.TRIVIAL_DOM_DELTA_BYTES = void 0;
|
|
11
|
+
exports.classifyPhantomClick = classifyPhantomClick;
|
|
12
|
+
/**
|
|
13
|
+
* Bytes of body-HTML growth treated as noise rather than a real DOM effect.
|
|
14
|
+
* Reused from `describeAttemptEffectSignals`'s dom-grew-without-network
|
|
15
|
+
* boundary (flow-runner.ts) so both signals agree on what counts as
|
|
16
|
+
* "trivial" — e.g. the bug report's attempt 5 (+30B) must classify as
|
|
17
|
+
* phantom, not effective.
|
|
18
|
+
*/
|
|
19
|
+
exports.TRIVIAL_DOM_DELTA_BYTES = 500;
|
|
20
|
+
/**
|
|
21
|
+
* Classifies one cascade attempt as `phantom` (Stagehand claimed success but
|
|
22
|
+
* pre/post shows zero network, zero URL change, and only trivial DOM
|
|
23
|
+
* growth), `unresolved` (Stagehand never resolved/executed the action), or
|
|
24
|
+
* `effective` (a real, observable change occurred). The cascade uses this to
|
|
25
|
+
* escalate off a phantom click immediately instead of burning all five
|
|
26
|
+
* techniques on the same no-op.
|
|
27
|
+
*/
|
|
28
|
+
function classifyPhantomClick(attempt) {
|
|
29
|
+
if (attempt.actResultSuccess !== true)
|
|
30
|
+
return "unresolved";
|
|
31
|
+
const networkDelta = attempt.post.networkCount - attempt.pre.networkCount;
|
|
32
|
+
const bytesDelta = attempt.post.bodyHtmlLength - attempt.pre.bodyHtmlLength;
|
|
33
|
+
const urlChanged = attempt.post.url !== attempt.pre.url;
|
|
34
|
+
const hasEffect = networkDelta !== 0 || urlChanged || bytesDelta >= exports.TRIVIAL_DOM_DELTA_BYTES;
|
|
35
|
+
return hasEffect ? "effective" : "phantom";
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=phantom-click.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phantom-click.js","sourceRoot":"","sources":["../../src/scraper/phantom-click.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;AAyBH;;;;;;GAMG;AACU,QAAA,uBAAuB,GAAG,GAAG,CAAC;AAE3C;;;;;;;GAOG;AACH,8BAAqC,OAA4B;IAC/D,IAAI,OAAO,CAAC,gBAAgB,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC;IAE3D,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAC1E,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC5E,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;IAExD,MAAM,SAAS,GAAG,YAAY,KAAK,CAAC,IAAI,UAAU,IAAI,UAAU,IAAI,QAAA,uBAAuB,CAAC;IAC5F,OAAO,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7C,CAAC"}
|
|
@@ -1,4 +1,52 @@
|
|
|
1
1
|
import { type BrowserSession, type BrowserSessionOptions } from "../scraper/session-shared";
|
|
2
|
+
import type { Logger } from "../types/logging";
|
|
3
|
+
/**
|
|
4
|
+
* Shape of the LogLine objects Stagehand passes to its `logger` callback.
|
|
5
|
+
* We declare a minimal local subset rather than importing from Stagehand
|
|
6
|
+
* because the type isn't re-exported from the package's top-level entrypoint.
|
|
7
|
+
*/
|
|
8
|
+
export interface StagehandLogLine {
|
|
9
|
+
message: string;
|
|
10
|
+
category?: string;
|
|
11
|
+
level?: number;
|
|
12
|
+
auxiliary?: Record<string, {
|
|
13
|
+
value: string;
|
|
14
|
+
type: string;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build a custom Stagehand logger that filters out the noisy upstream
|
|
19
|
+
* `AI_TypeValidationError` schema-validation spam. The errors come from
|
|
20
|
+
* Stagehand's internal Haiku LLM returning bare integers like "4671"
|
|
21
|
+
* when its Zod schema requires "N-N" format (regex /^\\d+-\\d+$/ at
|
|
22
|
+
* stagehand inference.js:147+240). Each error stack-trace is ~500 bytes
|
|
23
|
+
* of pino I/O — verified at 118 occurrences in run 1781485435455
|
|
24
|
+
* (2026-06-14), totaling ~5-7 min of wasted wall clock.
|
|
25
|
+
*
|
|
26
|
+
* The existing cascade Fix 1B (resolvedAction-null fast-skip) already
|
|
27
|
+
* handles the consequence: when Stagehand returns success=false due to
|
|
28
|
+
* this schema error, attempt 1 short-circuits cleanly and attempt 2
|
|
29
|
+
* (observe-act) runs on a structured target instead. The error log
|
|
30
|
+
* lines are pure noise.
|
|
31
|
+
*
|
|
32
|
+
* Filter is precise — only matches when category is "AISDK error"
|
|
33
|
+
* AND the cause body contains both `AI_TypeValidationError` and
|
|
34
|
+
* `elementId`. Other AISDK errors (rate limits, malformed requests,
|
|
35
|
+
* server errors) pass through unchanged. Site-agnostic — the
|
|
36
|
+
* upstream Stagehand bug is universal across tenants.
|
|
37
|
+
*
|
|
38
|
+
* Returns the callback + a `reportSuppressed` function that the
|
|
39
|
+
* session teardown calls to log the final suppression count, plus a
|
|
40
|
+
* `getSuppressedCount` live accessor so callers can read the running
|
|
41
|
+
* total while a step is still executing — e.g. treating "resolver
|
|
42
|
+
* threw on this step" as evidence a reported-success click was
|
|
43
|
+
* phantom, without waiting for teardown.
|
|
44
|
+
*/
|
|
45
|
+
export declare function makeFilteredStagehandLogger(pinoLogger: Logger): {
|
|
46
|
+
callback: (line: StagehandLogLine) => void;
|
|
47
|
+
reportSuppressed: () => void;
|
|
48
|
+
getSuppressedCount: () => number;
|
|
49
|
+
};
|
|
2
50
|
/**
|
|
3
51
|
* Spins up one Browserbase cloud session with the configured Stagehand LLM.
|
|
4
52
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-browserbase.d.ts","sourceRoot":"","sources":["../../src/scraper/session-browserbase.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAG3B,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"session-browserbase.d.ts","sourceRoot":"","sources":["../../src/scraper/session-browserbase.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAG3B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAI9C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG;IAC/D,QAAQ,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC3C,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,kBAAkB,EAAE,MAAM,MAAM,CAAC;CAClC,CA6BA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,+BAA+B,CACnD,IAAI,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,GAAG,gCAAgC,CAAC,GACvF,OAAO,CAAC,cAAc,CAAC,CAsHzB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeFilteredStagehandLogger = makeFilteredStagehandLogger;
|
|
3
4
|
exports.createBrowserbaseBrowserSession = createBrowserbaseBrowserSession;
|
|
4
5
|
const stagehand_1 = require("@browserbasehq/stagehand");
|
|
5
6
|
const config_1 = require("../config");
|
|
@@ -31,9 +32,11 @@ const logger = (0, logging_1.getLogger)({ name: "scraper/session-browserbase" })
|
|
|
31
32
|
* upstream Stagehand bug is universal across tenants.
|
|
32
33
|
*
|
|
33
34
|
* Returns the callback + a `reportSuppressed` function that the
|
|
34
|
-
* session teardown calls to log the final suppression count
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
* session teardown calls to log the final suppression count, plus a
|
|
36
|
+
* `getSuppressedCount` live accessor so callers can read the running
|
|
37
|
+
* total while a step is still executing — e.g. treating "resolver
|
|
38
|
+
* threw on this step" as evidence a reported-success click was
|
|
39
|
+
* phantom, without waiting for teardown.
|
|
37
40
|
*/
|
|
38
41
|
function makeFilteredStagehandLogger(pinoLogger) {
|
|
39
42
|
let suppressedCount = 0;
|
|
@@ -62,7 +65,8 @@ function makeFilteredStagehandLogger(pinoLogger) {
|
|
|
62
65
|
pinoLogger.info(`stagehand-logger: suppressed ${suppressedCount} AISDK elementId-regex errors (upstream Stagehand bug; cascade Fix 1B handles consequence)`);
|
|
63
66
|
}
|
|
64
67
|
};
|
|
65
|
-
|
|
68
|
+
const getSuppressedCount = () => suppressedCount;
|
|
69
|
+
return { callback, reportSuppressed, getSuppressedCount };
|
|
66
70
|
}
|
|
67
71
|
/**
|
|
68
72
|
* Spins up one Browserbase cloud session with the configured Stagehand LLM.
|
|
@@ -151,7 +155,7 @@ async function createBrowserbaseBrowserSession(opts) {
|
|
|
151
155
|
operatingSystems: ["windows"],
|
|
152
156
|
}
|
|
153
157
|
: baseFingerprint;
|
|
154
|
-
const { callback: stagehandLoggerCallback, reportSuppressed: reportSuppressedAisdkErrors } = makeFilteredStagehandLogger(logger);
|
|
158
|
+
const { callback: stagehandLoggerCallback, reportSuppressed: reportSuppressedAisdkErrors, getSuppressedCount: getSuppressedAisdkElementIdErrorCount, } = makeFilteredStagehandLogger(logger);
|
|
155
159
|
let stagehand;
|
|
156
160
|
try {
|
|
157
161
|
stagehand = new stagehand_1.Stagehand({
|
|
@@ -215,6 +219,7 @@ async function createBrowserbaseBrowserSession(opts) {
|
|
|
215
219
|
sessionId,
|
|
216
220
|
provider: "browserbase",
|
|
217
221
|
close,
|
|
222
|
+
getSuppressedAisdkElementIdErrorCount,
|
|
218
223
|
};
|
|
219
224
|
}
|
|
220
225
|
//# sourceMappingURL=session-browserbase.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-browserbase.js","sourceRoot":"","sources":["../../src/scraper/session-browserbase.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session-browserbase.js","sourceRoot":"","sources":["../../src/scraper/session-browserbase.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,6 +31,12 @@ export interface BrowserSession {
|
|
|
31
31
|
/** Which provider produced this session — informational, useful for logs. */
|
|
32
32
|
provider: ProviderName;
|
|
33
33
|
close(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Live count of suppressed AISDK elementId-regex errors so far this
|
|
36
|
+
* session. Only present on providers that filter Stagehand's logger for
|
|
37
|
+
* this upstream error (currently Browserbase); absent on Steel.
|
|
38
|
+
*/
|
|
39
|
+
getSuppressedAisdkElementIdErrorCount?: () => number;
|
|
34
40
|
}
|
|
35
41
|
/**
|
|
36
42
|
* Returns a fetch wrapper that aborts after `timeoutMs` milliseconds.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-shared.d.ts","sourceRoot":"","sources":["../../src/scraper/session-shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AAIzC,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,OAAO,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,MAAM,8BAA8B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C,CAAC;AAEF,uDAAuD;AACvD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,8BAA8B,CAAC,EAAE,8BAA8B,CAAC;CACjE;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC;IACpB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"session-shared.d.ts","sourceRoot":"","sources":["../../src/scraper/session-shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AAIzC,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,OAAO,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,MAAM,8BAA8B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C,CAAC;AAEF,uDAAuD;AACvD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,8BAA8B,CAAC,EAAE,8BAA8B,CAAC;CACjE;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC;IACpB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB;;;;OAIG;IACH,qCAAqC,CAAC,EAAE,MAAM,MAAM,CAAC;CACtD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,KAAK,CAYlE;AAaD,wBAAgB,kBAAkB,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAEtE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-shared.js","sourceRoot":"","sources":["../../src/scraper/session-shared.ts"],"names":[],"mappings":";;;;AAGA,yCAA0C;
|
|
1
|
+
{"version":3,"file":"session-shared.js","sourceRoot":"","sources":["../../src/scraper/session-shared.ts"],"names":[],"mappings":";;;;AAGA,yCAA0C;AA4C1C;;;;GAIG;AACH,4BAAmC,SAAiB;IAClD,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;QACnB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;QAC9D,kFAAkF;QAClF,gDAAgD;QAChD,MAAM,OAAO,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,MAAM,CACtD,CAAC,CAAC,EAAoB,EAAE,CAAC,CAAC,YAAY,WAAW,CAClD,CAAC;QACF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1E,OAAO,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,SAAS,GAAG;IAChB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;IAC5B,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;IAC5B,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;IAC5B,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;CACrB,CAAC;AAEX;IACE,OAAO,IAAA,mBAAU,EAAC,SAAS,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Submit-control locator: ranks every submit-shaped candidate the deep
|
|
3
|
+
* resolver (`deep-query.ts`) can reach — piercing open shadow roots — so
|
|
4
|
+
* the cascade can act on the best-ranked candidate and retry the runner-up
|
|
5
|
+
* if the first click phantoms. A false-positive submit click on a real run
|
|
6
|
+
* (e.g. clicking "Save draft") is worse than the current failure, since it
|
|
7
|
+
* could submit a half-filled application — so ranking is deliberately
|
|
8
|
+
* conservative: only tiers with strong, unambiguous submit signal are
|
|
9
|
+
* included, and "Back"/"Cancel"/"Save draft"-shaped controls never appear.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Builds a self-contained `page.evaluate` expression string that walks the
|
|
13
|
+
* whole document (light DOM plus every open shadow root, arbitrarily deep)
|
|
14
|
+
* and returns every submit-shaped candidate ranked by confidence tier,
|
|
15
|
+
* highest first. Ties within a tier keep document order. Elements that
|
|
16
|
+
* match no positive tier — including anything caught by
|
|
17
|
+
* {@link NEGATIVE_TEXT_EXPR} — are excluded entirely rather than ranked
|
|
18
|
+
* last, so the caller never has to guess where the "safe" cutoff is.
|
|
19
|
+
*
|
|
20
|
+
* Each returned candidate carries `deepIndex`, the candidate's position in
|
|
21
|
+
* this same deterministic deep-traversal order. {@link buildClickByDeepIndexExpr}
|
|
22
|
+
* re-runs the identical traversal and clicks the element at that index, so
|
|
23
|
+
* the caller can locate once, decide which candidate to try, then click by
|
|
24
|
+
* index without holding a live element handle across the two round trips.
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildRankSubmitCandidatesExpr(): string;
|
|
27
|
+
/**
|
|
28
|
+
* Builds a self-contained `page.evaluate` expression string that re-runs
|
|
29
|
+
* the same deterministic deep traversal as {@link buildRankSubmitCandidatesExpr}
|
|
30
|
+
* and clicks the element at `deepIndex` (dispatching focus + bubbling
|
|
31
|
+
* mousedown/mouseup/click, matching `deep-query.ts`'s controlled-state click
|
|
32
|
+
* convention). Returns `{ clicked: false }` without throwing if the index is
|
|
33
|
+
* out of range for the current DOM (e.g. the page changed between the
|
|
34
|
+
* locate and click calls).
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildClickByDeepIndexExpr(deepIndex: number): string;
|
|
37
|
+
/** Confidence tier for a ranked submit candidate — higher is more confident. See {@link buildRankSubmitCandidatesExpr}. */
|
|
38
|
+
export type SubmitCandidateTier = 1 | 2 | 3;
|
|
39
|
+
/** One ranked candidate returned by {@link buildRankSubmitCandidatesExpr}'s `page.evaluate` call. */
|
|
40
|
+
export interface SubmitCandidate {
|
|
41
|
+
/** Position in the deterministic deep-traversal order; pass to {@link buildClickByDeepIndexExpr} to click this exact candidate. */
|
|
42
|
+
deepIndex: number;
|
|
43
|
+
tier: SubmitCandidateTier;
|
|
44
|
+
tag: string;
|
|
45
|
+
accessibleName: string;
|
|
46
|
+
}
|
|
47
|
+
/** Result of {@link buildClickByDeepIndexExpr}'s `page.evaluate` call. */
|
|
48
|
+
export interface ClickByDeepIndexResult {
|
|
49
|
+
clicked: boolean;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=submit-control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit-control.d.ts","sourceRoot":"","sources":["../../src/scraper/submit-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAyEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,CAsBtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAYnE;AAED,2HAA2H;AAC3H,MAAM,MAAM,mBAAmB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE5C,qGAAqG;AACrG,MAAM,WAAW,eAAe;IAC9B,mIAAmI;IACnI,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,0EAA0E;AAC1E,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;CAClB"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Submit-control locator: ranks every submit-shaped candidate the deep
|
|
4
|
+
* resolver (`deep-query.ts`) can reach — piercing open shadow roots — so
|
|
5
|
+
* the cascade can act on the best-ranked candidate and retry the runner-up
|
|
6
|
+
* if the first click phantoms. A false-positive submit click on a real run
|
|
7
|
+
* (e.g. clicking "Save draft") is worse than the current failure, since it
|
|
8
|
+
* could submit a half-filled application — so ranking is deliberately
|
|
9
|
+
* conservative: only tiers with strong, unambiguous submit signal are
|
|
10
|
+
* included, and "Back"/"Cancel"/"Save draft"-shaped controls never appear.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.buildRankSubmitCandidatesExpr = buildRankSubmitCandidatesExpr;
|
|
14
|
+
exports.buildClickByDeepIndexExpr = buildClickByDeepIndexExpr;
|
|
15
|
+
/**
|
|
16
|
+
* Verbs that identify a control as NOT the submit action even when it is
|
|
17
|
+
* button-shaped and reachable. Checked before any positive tier so a
|
|
18
|
+
* button whose text merely contains "submit" as a substring of a longer
|
|
19
|
+
* negative phrase (unlikely in practice, but the exclusion is what makes
|
|
20
|
+
* the ranking conservative) cannot slip through.
|
|
21
|
+
*/
|
|
22
|
+
const NEGATIVE_TEXT_EXPR = `((text) => {
|
|
23
|
+
const negatives = ["back", "cancel", "save draft", "save for later", "previous", "close"];
|
|
24
|
+
return negatives.some((n) => text === n || text.startsWith(n + " ") || text.endsWith(" " + n));
|
|
25
|
+
})`;
|
|
26
|
+
/**
|
|
27
|
+
* Normalizes an element's accessible name to lowercase, whitespace-collapsed
|
|
28
|
+
* text, preferring `aria-label` over visible `textContent` (mirrors
|
|
29
|
+
* `SUBMIT_SHAPED_EL_EXPR`'s own normalization in deep-query.ts so both
|
|
30
|
+
* modules treat the same DOM the same way).
|
|
31
|
+
*/
|
|
32
|
+
const ACCESSIBLE_NAME_EXPR = `((el) => {
|
|
33
|
+
const norm = (s) => (s || "").replace(/\\s+/g, " ").trim().toLowerCase();
|
|
34
|
+
return norm(el.getAttribute("aria-label") || el.textContent || "");
|
|
35
|
+
})`;
|
|
36
|
+
/**
|
|
37
|
+
* Recursive open-shadow-root walker, identical in shape to `deep-query.ts`'s
|
|
38
|
+
* private `DEEP_ELEMENTS_EXPR` (duplicated rather than imported because both
|
|
39
|
+
* are browser-context expression strings composed by string interpolation,
|
|
40
|
+
* not runtime code that can share a module import).
|
|
41
|
+
*/
|
|
42
|
+
const DEEP_ELEMENTS_EXPR = `((root) => {
|
|
43
|
+
const out = [];
|
|
44
|
+
const walk = (node) => {
|
|
45
|
+
const kids = node.querySelectorAll ? Array.from(node.querySelectorAll("*")) : [];
|
|
46
|
+
for (const el of kids) {
|
|
47
|
+
out.push(el);
|
|
48
|
+
if (el.shadowRoot) walk(el.shadowRoot);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
walk(root);
|
|
52
|
+
return out;
|
|
53
|
+
})`;
|
|
54
|
+
/**
|
|
55
|
+
* Ranking tiers, most confident first. Each tier's `test` receives the
|
|
56
|
+
* element plus its precomputed accessible name and reports whether it
|
|
57
|
+
* belongs in that tier — the first matching tier wins, so an element that
|
|
58
|
+
* qualifies for tier 1 is never re-evaluated against tier 2/3.
|
|
59
|
+
*
|
|
60
|
+
* 1. Explicit `type="submit"` — unambiguous native semantics.
|
|
61
|
+
* 2. Accessible name is exactly (or is dominated by) "submit" — covers the
|
|
62
|
+
* shadow-root button whose text is "Submit" but carries no type
|
|
63
|
+
* attribute (Stencil/web-component controls often omit it).
|
|
64
|
+
* 3. Button/role="button" element whose accessible name contains "submit"
|
|
65
|
+
* as a distinct word alongside other text (e.g. "Submit Application"),
|
|
66
|
+
* with no negative verb present — covers Angular-style controls matched
|
|
67
|
+
* by role + text rather than by type.
|
|
68
|
+
*/
|
|
69
|
+
const RANK_TIERS_EXPR = `((el, name) => {
|
|
70
|
+
const isNegative = ${NEGATIVE_TEXT_EXPR};
|
|
71
|
+
if (isNegative(name)) return 0;
|
|
72
|
+
const tag = (el.tagName || "").toLowerCase();
|
|
73
|
+
const type = (el.getAttribute("type") || "").toLowerCase();
|
|
74
|
+
const role = (el.getAttribute("role") || "").toLowerCase();
|
|
75
|
+
const isButtonLike = tag === "button" || tag === "input" || role === "button";
|
|
76
|
+
if (!isButtonLike) return 0;
|
|
77
|
+
if ((tag === "button" || tag === "input") && type === "submit") return 3;
|
|
78
|
+
if (name === "submit") return 2;
|
|
79
|
+
if (/\\bsubmit\\b/.test(name)) return 1;
|
|
80
|
+
return 0;
|
|
81
|
+
})`;
|
|
82
|
+
/**
|
|
83
|
+
* Builds a self-contained `page.evaluate` expression string that walks the
|
|
84
|
+
* whole document (light DOM plus every open shadow root, arbitrarily deep)
|
|
85
|
+
* and returns every submit-shaped candidate ranked by confidence tier,
|
|
86
|
+
* highest first. Ties within a tier keep document order. Elements that
|
|
87
|
+
* match no positive tier — including anything caught by
|
|
88
|
+
* {@link NEGATIVE_TEXT_EXPR} — are excluded entirely rather than ranked
|
|
89
|
+
* last, so the caller never has to guess where the "safe" cutoff is.
|
|
90
|
+
*
|
|
91
|
+
* Each returned candidate carries `deepIndex`, the candidate's position in
|
|
92
|
+
* this same deterministic deep-traversal order. {@link buildClickByDeepIndexExpr}
|
|
93
|
+
* re-runs the identical traversal and clicks the element at that index, so
|
|
94
|
+
* the caller can locate once, decide which candidate to try, then click by
|
|
95
|
+
* index without holding a live element handle across the two round trips.
|
|
96
|
+
*/
|
|
97
|
+
function buildRankSubmitCandidatesExpr() {
|
|
98
|
+
return `(() => {
|
|
99
|
+
const accessibleName = ${ACCESSIBLE_NAME_EXPR};
|
|
100
|
+
const rankTier = ${RANK_TIERS_EXPR};
|
|
101
|
+
const deepElements = ${DEEP_ELEMENTS_EXPR};
|
|
102
|
+
const all = deepElements(document);
|
|
103
|
+
const ranked = [];
|
|
104
|
+
for (let i = 0; i < all.length; i++) {
|
|
105
|
+
const el = all[i];
|
|
106
|
+
const name = accessibleName(el);
|
|
107
|
+
const tier = rankTier(el, name);
|
|
108
|
+
if (tier === 0) continue;
|
|
109
|
+
ranked.push({
|
|
110
|
+
deepIndex: i,
|
|
111
|
+
tier,
|
|
112
|
+
tag: (el.tagName || "").toLowerCase(),
|
|
113
|
+
accessibleName: name,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
ranked.sort((a, b) => b.tier - a.tier || a.deepIndex - b.deepIndex);
|
|
117
|
+
return ranked;
|
|
118
|
+
})()`;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Builds a self-contained `page.evaluate` expression string that re-runs
|
|
122
|
+
* the same deterministic deep traversal as {@link buildRankSubmitCandidatesExpr}
|
|
123
|
+
* and clicks the element at `deepIndex` (dispatching focus + bubbling
|
|
124
|
+
* mousedown/mouseup/click, matching `deep-query.ts`'s controlled-state click
|
|
125
|
+
* convention). Returns `{ clicked: false }` without throwing if the index is
|
|
126
|
+
* out of range for the current DOM (e.g. the page changed between the
|
|
127
|
+
* locate and click calls).
|
|
128
|
+
*/
|
|
129
|
+
function buildClickByDeepIndexExpr(deepIndex) {
|
|
130
|
+
return `(() => {
|
|
131
|
+
const deepElements = ${DEEP_ELEMENTS_EXPR};
|
|
132
|
+
const all = deepElements(document);
|
|
133
|
+
const el = all[${JSON.stringify(deepIndex)}];
|
|
134
|
+
if (!el) return { clicked: false };
|
|
135
|
+
if (typeof el.focus === "function") { try { el.focus(); } catch (e) {} }
|
|
136
|
+
el.dispatchEvent(new Event("mousedown", { bubbles: true }));
|
|
137
|
+
el.dispatchEvent(new Event("mouseup", { bubbles: true }));
|
|
138
|
+
el.dispatchEvent(new Event("click", { bubbles: true }));
|
|
139
|
+
return { clicked: true };
|
|
140
|
+
})()`;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=submit-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit-control.js","sourceRoot":"","sources":["../../src/scraper/submit-control.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;AAEH;;;;;;GAMG;AACH,MAAM,kBAAkB,GAAG;;;GAGxB,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,oBAAoB,GAAG;;;GAG1B,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG;;;;;;;;;;;GAWxB,CAAC;AAEJ;;;;;;;;;;;;;;GAcG;AACH,MAAM,eAAe,GAAG;uBACD,kBAAkB;;;;;;;;;;;GAWtC,CAAC;AAEJ;;;;;;;;;;;;;;GAcG;AACH;IACE,OAAO;6BACoB,oBAAoB;uBAC1B,eAAe;2BACX,kBAAkB;;;;;;;;;;;;;;;;;OAiBtC,CAAC;AACR,CAAC;AAED;;;;;;;;GAQG;AACH,mCAA0C,SAAiB;IACzD,OAAO;2BACkB,kBAAkB;;qBAExB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;;;;;;;OAOvC,CAAC;AACR,CAAC"}
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Phase 1 recon: drives a real browser through a user-defined flow while
|
|
3
|
-
* wiretapping every network response.
|
|
4
|
-
*
|
|
3
|
+
* wiretapping every network response. Every artifact is rooted under one
|
|
4
|
+
* run-scoped directory resolved once at startup via
|
|
5
|
+
* {@link resolveReconRunDir} (default `/tmp/recon/<runId>`, override with
|
|
6
|
+
* `RECON_OUT_DIR`/`RECON_RUN_ID`) so concurrent or repeated runs cannot
|
|
7
|
+
* intermix files. Captures are written to
|
|
8
|
+
* `<runDir>/graphql/<NNN>-<phase>-<operationName>.json` — one file per call,
|
|
5
9
|
* diffable and greppable. The browser's full cookie jar is snapshotted at
|
|
6
10
|
* each phase boundary (initial goto, pre-step, post-step, run completion) and
|
|
7
|
-
* written to
|
|
11
|
+
* written to `<runDir>/cookies/<NNN>-<label>-<phase>.json`, so the jar state
|
|
8
12
|
* can be diffed across the journey (e.g. what a click-tracker traversal
|
|
9
13
|
* establishes vs. what a later step adds).
|
|
10
14
|
*
|
|
11
15
|
* Recovery model — each flow step runs through a 4-attempt self-healing cascade
|
|
12
16
|
* (act → observe+act → observe+act with ignoreSelectors → Anthropic-SDK rephrase),
|
|
13
17
|
* verified by "did the network counter advance OR did the URL change". On terminal
|
|
14
|
-
* cascade failure the step is dumped to
|
|
15
|
-
* main() loop attempts up to MAX_REPLANS=2 global replans, where
|
|
16
|
-
* the remaining flow tail given the failure context.
|
|
17
|
-
* skip the LLM-rephrase attempt and the replan loop
|
|
18
|
-
* docs/playbook.md sections 1c–1e for the full
|
|
18
|
+
* cascade failure the step is dumped to `<runDir>/step-failures/` and the
|
|
19
|
+
* script's main() loop attempts up to MAX_REPLANS=2 global replans, where
|
|
20
|
+
* Claude rewrites the remaining flow tail given the failure context.
|
|
21
|
+
* Bedrock-only deployments skip the LLM-rephrase attempt and the replan loop
|
|
22
|
+
* with a startup warn. See docs/playbook.md sections 1c–1e for the full
|
|
23
|
+
* design.
|
|
19
24
|
*
|
|
20
25
|
* Usage:
|
|
21
26
|
* pnpm tsx src/scripts/recon-browser.ts \
|
|
@@ -62,13 +67,13 @@ interface ReplanEvent {
|
|
|
62
67
|
}
|
|
63
68
|
/**
|
|
64
69
|
* Reads the browser's full cookie jar for the given phase and writes it under
|
|
65
|
-
* `
|
|
66
|
-
* layout as `wireNetworkCapture`'s network
|
|
67
|
-
* filenames chronologically (zero-padded, shared
|
|
68
|
-
* flow-runner's capture counter) so snapshots sort in the
|
|
69
|
-
* actually occurred. Never throws — cookie telemetry is
|
|
70
|
-
* the existing capture-write behavior: a write failure
|
|
71
|
-
* recon run continues.
|
|
70
|
+
* the resolved run dir's `cookies` subdir, so a run's snapshots land in the
|
|
71
|
+
* same append-only, diffable layout as `wireNetworkCapture`'s network
|
|
72
|
+
* captures. `counter` indexes filenames chronologically (zero-padded, shared
|
|
73
|
+
* convention with flow-runner's capture counter) so snapshots sort in the
|
|
74
|
+
* order the phases actually occurred. Never throws — cookie telemetry is
|
|
75
|
+
* best-effort, matching the existing capture-write behavior: a write failure
|
|
76
|
+
* logs a warning and the recon run continues.
|
|
72
77
|
*/
|
|
73
78
|
declare function snapshotAndPersistCookieJar(page: Page, counter: {
|
|
74
79
|
n: number;
|
|
@@ -280,9 +285,9 @@ declare function replanRemainingFlow(params: {
|
|
|
280
285
|
stagehand: Stagehand;
|
|
281
286
|
captureFn?: CaptureFn;
|
|
282
287
|
/**
|
|
283
|
-
* Files in
|
|
284
|
-
* window. Used to surface structured server-side validation
|
|
285
|
-
* to the replan LLM when a submit actually fired but was rejected.
|
|
288
|
+
* Files in the run's captures dir recorded during the failed step's
|
|
289
|
+
* attempt window. Used to surface structured server-side validation
|
|
290
|
+
* errors to the replan LLM when a submit actually fired but was rejected.
|
|
286
291
|
*/
|
|
287
292
|
recentCaptures?: readonly string[];
|
|
288
293
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recon-browser.d.ts","sourceRoot":"","sources":["../../src/scripts/recon-browser.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"recon-browser.d.ts","sourceRoot":"","sources":["../../src/scripts/recon-browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAMH,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EAAU,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAyBnF,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,SAAS,EAkBf,MAAM,uBAAuB,CAAC;AAM/B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,UAAU,WAAW;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,cAAc,GAAG,mBAAmB,CAAC;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD;AAoED;;;;;;;;;GASG;AACH,iBAAe,2BAA2B,CACxC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE;IAAE,CAAC,EAAE,MAAM,CAAA;CAAE,EACtB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAUf;AAWD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,GAAE,MAAe,GAAG,SAAS,CAQ7F;AAiBD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,OAAO,GAAG;IAC5D,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CA4BA;AA0HD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C,GAAG,MAAM,GAAG,IAAI,CAmBhB;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS;IACjB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,EAAE,GACF,OAAO,CAGT;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAoBT;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,SAAS,WAAW,EAAE,EACpC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,YAAY,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAChD,OAAO,CAaT;AA+GD;;;;;;;GAOG;AACH,UAAU,cAAc;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAOhB,UAAU,CAAC,EAAE,OAAO,CAAC;IAMrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;CAC/B;AAuCD;;;;;GAKG;AACH,iBAAS,eAAe,CAAC,IAAI,EAAE,cAAc,GACzC,MAAM,GACN;IACE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,IAAI,CAAC;CACzB,CAqBJ;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,iBAAS,0BAA0B,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAStD;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,cAAc,EAAE,SAAS,MAAM,EAAE,EACjC,UAAU,EAAE,MAAM,GACjB,cAAc,EAAE,CAGlB;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,UAAU,EAAE,MAAM,GACjB,OAAO,CAIT;AAED;;;;;;;;;;;GAWG;AACH,iBAAS,oBAAoB,CAAC,MAAM,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACnC,wEAAwE;IACxE,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,4FAA4F;IAC5F,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,oGAAoG;IACpG,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,uGAAuG;IACvG,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,oGAAoG;IACpG,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,uGAAuG;IACvG,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;CACpC,GAAG,IAAI,CA6FP;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,MAAM,CAkBR;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACpC,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,SAAS,WAAW,EAAE,GACnC,MAAM,CAcR;AAED,iBAAe,uBAAuB,CACpC,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC1B,uBAAuB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,GACA,OAAO,CAAC;IACT,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC,CAAC,CA8ED;AAED;;;;GAIG;AACH,iBAAe,mBAAmB,CAAC,MAAM,EAAE;IACzC,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,SAAS;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,aAAa,CAAC,YAAY,CAAC,CAAA;KAAE,EAAE,CAAC;IACvF;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CACvC,GAAG,OAAO,CAAC,cAAc,EAAE,GAAG,IAAI,CAAC,CA0SnC;AAg7BD,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,4BAA4B,EAC5B,sBAAsB,EACtB,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,8BAA8B,EAC9B,yBAAyB,EACzB,gBAAgB,EAChB,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,aAAa,EACb,0BAA0B,EAC1B,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EACf,6BAA6B,EAC7B,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC;AAG5C,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,2BAA2B,GAC5B,CAAC"}
|