@anweat/dsh-browser 0.1.17 → 0.2.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +238 -71
- package/assets/skills/dsh-browser/SKILL.md +120 -0
- package/assets/skills/dsh-browser/references/develop.md +48 -0
- package/assets/skills/dsh-browser/references/observe.md +91 -0
- package/assets/skills/dsh-browser/references/opencli.md +25 -0
- package/assets/skills/dsh-browser/references/recipes.md +149 -0
- package/assets/skills/dsh-browser/references/userscripts.md +44 -0
- package/cordis.patch.yml +4 -0
- package/lib/actions/act.d.ts +3 -0
- package/lib/actions/act.js +147 -0
- package/lib/actions/act.js.map +1 -0
- package/lib/actions/automation.d.ts +3 -0
- package/lib/actions/automation.js +356 -0
- package/lib/actions/automation.js.map +1 -0
- package/lib/actions/crawl.d.ts +3 -0
- package/lib/actions/crawl.js +28 -0
- package/lib/actions/crawl.js.map +1 -0
- package/lib/actions/errors.d.ts +53 -0
- package/lib/actions/errors.js +178 -0
- package/lib/actions/errors.js.map +1 -0
- package/lib/actions/index-view.d.ts +42 -0
- package/lib/actions/index-view.js +268 -0
- package/lib/actions/index-view.js.map +1 -0
- package/lib/actions/inspect.d.ts +3 -0
- package/lib/actions/inspect.js +35 -0
- package/lib/actions/inspect.js.map +1 -0
- package/lib/actions/observe.d.ts +3 -0
- package/lib/actions/observe.js +121 -0
- package/lib/actions/observe.js.map +1 -0
- package/lib/actions/opencli.d.ts +3 -0
- package/lib/actions/opencli.js +51 -0
- package/lib/actions/opencli.js.map +1 -0
- package/lib/actions/registry.d.ts +35 -0
- package/lib/actions/registry.js +89 -0
- package/lib/actions/registry.js.map +1 -0
- package/lib/actions/run.d.ts +34 -0
- package/lib/actions/run.js +226 -0
- package/lib/actions/run.js.map +1 -0
- package/lib/actions/runtime.d.ts +3 -0
- package/lib/actions/runtime.js +33 -0
- package/lib/actions/runtime.js.map +1 -0
- package/lib/actions/schema.d.ts +31 -0
- package/lib/actions/schema.js +309 -0
- package/lib/actions/schema.js.map +1 -0
- package/lib/actions/script.d.ts +3 -0
- package/lib/actions/script.js +97 -0
- package/lib/actions/script.js.map +1 -0
- package/lib/actions/shared.d.ts +31 -0
- package/lib/actions/shared.js +45 -0
- package/lib/actions/shared.js.map +1 -0
- package/lib/actions/surface.d.ts +22 -0
- package/lib/actions/surface.js +18 -0
- package/lib/actions/surface.js.map +1 -0
- package/lib/actions/target.d.ts +3 -0
- package/lib/actions/target.js +66 -0
- package/lib/actions/target.js.map +1 -0
- package/lib/actions/types.d.ts +181 -0
- package/lib/actions/types.js +48 -0
- package/lib/actions/types.js.map +1 -0
- package/lib/activation-rules.d.ts +29 -0
- package/lib/activation-rules.js +33 -0
- package/lib/activation-rules.js.map +1 -0
- package/lib/approval-policy.d.ts +40 -2
- package/lib/approval-policy.js +184 -97
- package/lib/approval-policy.js.map +1 -1
- package/lib/automation-assets-rpc.d.ts +8 -2
- package/lib/automation-assets-rpc.js +67 -6
- package/lib/automation-assets-rpc.js.map +1 -1
- package/lib/automation-assets.d.ts +152 -4
- package/lib/automation-assets.js +255 -15
- package/lib/automation-assets.js.map +1 -1
- package/lib/automation-convert.d.ts +23 -0
- package/lib/automation-convert.js +110 -0
- package/lib/automation-convert.js.map +1 -0
- package/lib/automation-development.d.ts +26 -0
- package/lib/automation-development.js +47 -0
- package/lib/automation-development.js.map +1 -1
- package/lib/automation-execution.d.ts +57 -1
- package/lib/automation-execution.js +167 -11
- package/lib/automation-execution.js.map +1 -1
- package/lib/automation-journal.d.ts +92 -0
- package/lib/automation-journal.js +449 -0
- package/lib/automation-journal.js.map +1 -0
- package/lib/automation-v2.d.ts +138 -0
- package/lib/automation-v2.js +631 -0
- package/lib/automation-v2.js.map +1 -0
- package/lib/automation.d.ts +82 -5
- package/lib/automation.js +239 -82
- package/lib/automation.js.map +1 -1
- package/lib/browser-service.d.ts +304 -32
- package/lib/browser-service.js +631 -182
- package/lib/browser-service.js.map +1 -1
- package/lib/client/SettingsCard.js +95 -57
- package/lib/client/SettingsCard.js.map +1 -1
- package/lib/client/asset-editor.d.ts +55 -0
- package/lib/client/asset-editor.js +101 -0
- package/lib/client/asset-editor.js.map +1 -0
- package/lib/client/automation-assets-client.d.ts +99 -2
- package/lib/client/automation-assets-client.js +243 -10
- package/lib/client/automation-assets-client.js.map +1 -1
- package/lib/client/form.d.ts +48 -4
- package/lib/client/form.js +142 -29
- package/lib/client/form.js.map +1 -1
- package/lib/client/index.d.ts +25 -2
- package/lib/client/index.js +5 -1
- package/lib/client/index.js.map +1 -1
- package/lib/client/locales.d.ts +85 -6
- package/lib/client/locales.js +64 -12
- package/lib/client/locales.js.map +1 -1
- package/lib/client/prompts-form.d.ts +67 -0
- package/lib/client/prompts-form.js +140 -0
- package/lib/client/prompts-form.js.map +1 -0
- package/lib/client/prompts-status-client.d.ts +34 -0
- package/lib/client/prompts-status-client.js +53 -0
- package/lib/client/prompts-status-client.js.map +1 -0
- package/lib/client.js +1914 -329
- package/lib/client.js.map +1 -1
- package/lib/config.d.ts +50 -1
- package/lib/config.js +31 -1
- package/lib/config.js.map +1 -1
- package/lib/dialogs.d.ts +37 -0
- package/lib/dialogs.js +73 -0
- package/lib/dialogs.js.map +1 -0
- package/lib/freedom.d.ts +23 -7
- package/lib/freedom.js +48 -59
- package/lib/freedom.js.map +1 -1
- package/lib/index.d.ts +4 -4
- package/lib/index.js +36 -10
- package/lib/index.js.map +1 -1
- package/lib/journal.d.ts +109 -0
- package/lib/journal.js +238 -0
- package/lib/journal.js.map +1 -0
- package/lib/locator.d.ts +82 -0
- package/lib/locator.js +190 -0
- package/lib/locator.js.map +1 -0
- package/lib/observe-script.d.ts +27 -0
- package/lib/observe-script.js +565 -0
- package/lib/observe-script.js.map +1 -0
- package/lib/observe.d.ts +179 -0
- package/lib/observe.js +368 -0
- package/lib/observe.js.map +1 -0
- package/lib/policy-keys.d.ts +30 -0
- package/lib/policy-keys.js +34 -0
- package/lib/policy-keys.js.map +1 -0
- package/lib/prompt-limits.d.ts +30 -0
- package/lib/prompt-limits.js +31 -0
- package/lib/prompt-limits.js.map +1 -0
- package/lib/prompts.d.ts +131 -0
- package/lib/prompts.js +295 -0
- package/lib/prompts.js.map +1 -0
- package/lib/skill.d.ts +100 -0
- package/lib/skill.js +181 -0
- package/lib/skill.js.map +1 -0
- package/lib/tool-defs.d.ts +72 -0
- package/lib/tool-defs.js +67 -0
- package/lib/tool-defs.js.map +1 -0
- package/lib/tools.d.ts +19 -4
- package/lib/tools.js +124 -922
- package/lib/tools.js.map +1 -1
- package/package.json +5 -1
- package/scripts/dump-prompts.mjs +29 -0
- package/scripts/measure-tool-surface.mjs +190 -0
package/lib/observe.d.ts
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured page observation behind `observe.read` sections.
|
|
3
|
+
*
|
|
4
|
+
* The in-page scan (`observe-script.ts`) reads the DOM; this module turns its output into the
|
|
5
|
+
* model-facing record:
|
|
6
|
+
*
|
|
7
|
+
* - every listed element gets a candidate LocatorSpec that was CHECKED against the live page: it matches
|
|
8
|
+
* that element and no other (`locator`), or, when no candidate is unique, the best one is returned with
|
|
9
|
+
* `ambiguous: true`, how many elements it matches, and the element's position among them (`nth`);
|
|
10
|
+
* - the whole result is fitted to a byte budget by dropping whole items or text from the end, so the JSON
|
|
11
|
+
* is always valid and `truncation` says what was left out.
|
|
12
|
+
*
|
|
13
|
+
* A property that was not observed is absent: `false` always means "observed, and not so".
|
|
14
|
+
* @module dsh-browser/observe
|
|
15
|
+
*/
|
|
16
|
+
import { type BrowserFrameSpec, type BrowserTarget } from './locator.ts';
|
|
17
|
+
export declare const OBSERVE_SECTIONS: readonly ["content", "controls", "links", "tables"];
|
|
18
|
+
export type ObserveSection = typeof OBSERVE_SECTIONS[number];
|
|
19
|
+
export declare const OBSERVE_DEFAULT_ITEMS = 50;
|
|
20
|
+
export declare const OBSERVE_MAX_ITEMS = 500;
|
|
21
|
+
export declare const OBSERVE_DEFAULT_BYTES = 24000;
|
|
22
|
+
export declare const OBSERVE_MIN_BYTES = 2000;
|
|
23
|
+
export declare const OBSERVE_MAX_BYTES = 90000;
|
|
24
|
+
export interface ObserveRegion {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
width: number;
|
|
28
|
+
height: number;
|
|
29
|
+
}
|
|
30
|
+
/** The arguments of observe.read after validation. */
|
|
31
|
+
export interface ObserveRequest {
|
|
32
|
+
sections: readonly ObserveSection[];
|
|
33
|
+
target?: BrowserTarget;
|
|
34
|
+
region?: ObserveRegion;
|
|
35
|
+
maxItems: number;
|
|
36
|
+
maxBytes: number;
|
|
37
|
+
includeValues: boolean;
|
|
38
|
+
timeoutMs: number;
|
|
39
|
+
}
|
|
40
|
+
export declare class ObserveArgError extends Error {
|
|
41
|
+
constructor(message: string);
|
|
42
|
+
}
|
|
43
|
+
/** Check and complete the raw arguments (the registry validated their types already). */
|
|
44
|
+
export declare function normalizeObserve(raw: {
|
|
45
|
+
sections?: readonly string[];
|
|
46
|
+
target?: BrowserTarget;
|
|
47
|
+
region?: ObserveRegion;
|
|
48
|
+
maxItems?: number;
|
|
49
|
+
maxBytes?: number;
|
|
50
|
+
includeValues?: boolean;
|
|
51
|
+
timeoutMs?: number;
|
|
52
|
+
}): ObserveRequest;
|
|
53
|
+
interface RawCandidate extends Record<string, unknown> {
|
|
54
|
+
}
|
|
55
|
+
interface RawOption {
|
|
56
|
+
id?: number;
|
|
57
|
+
value: string;
|
|
58
|
+
label: string;
|
|
59
|
+
selected?: boolean;
|
|
60
|
+
checked?: boolean;
|
|
61
|
+
disabled?: boolean;
|
|
62
|
+
cands?: RawCandidate[];
|
|
63
|
+
}
|
|
64
|
+
interface RawControl {
|
|
65
|
+
id?: number;
|
|
66
|
+
source: 'dom' | 'aria';
|
|
67
|
+
path: string[];
|
|
68
|
+
role?: string;
|
|
69
|
+
name?: string;
|
|
70
|
+
type?: string;
|
|
71
|
+
visible?: boolean;
|
|
72
|
+
disabled?: boolean;
|
|
73
|
+
readonly?: boolean;
|
|
74
|
+
checked?: boolean | 'mixed';
|
|
75
|
+
expanded?: boolean;
|
|
76
|
+
hasValue?: boolean;
|
|
77
|
+
value?: string | string[];
|
|
78
|
+
sensitive?: boolean;
|
|
79
|
+
options?: RawOption[];
|
|
80
|
+
optionsTotal?: number;
|
|
81
|
+
constraints?: Record<string, unknown>;
|
|
82
|
+
validity?: {
|
|
83
|
+
valid: boolean;
|
|
84
|
+
flags?: string[];
|
|
85
|
+
validationMessage?: string;
|
|
86
|
+
};
|
|
87
|
+
actions: string[];
|
|
88
|
+
cands?: RawCandidate[];
|
|
89
|
+
}
|
|
90
|
+
interface RawLink {
|
|
91
|
+
id: number;
|
|
92
|
+
path: string[];
|
|
93
|
+
text: string;
|
|
94
|
+
href: string;
|
|
95
|
+
visible: boolean;
|
|
96
|
+
target?: string;
|
|
97
|
+
cands: RawCandidate[];
|
|
98
|
+
}
|
|
99
|
+
interface RawTable {
|
|
100
|
+
id: number;
|
|
101
|
+
path: string[];
|
|
102
|
+
name?: string;
|
|
103
|
+
headers: string[];
|
|
104
|
+
rows: string[][];
|
|
105
|
+
totalRows: number;
|
|
106
|
+
declaredRows?: number;
|
|
107
|
+
coverage: 'complete' | 'partial';
|
|
108
|
+
reason?: string;
|
|
109
|
+
cands: RawCandidate[];
|
|
110
|
+
}
|
|
111
|
+
interface RawFrame {
|
|
112
|
+
framePath: string[];
|
|
113
|
+
src?: string;
|
|
114
|
+
url?: string;
|
|
115
|
+
sameOrigin?: boolean;
|
|
116
|
+
crossOrigin?: boolean;
|
|
117
|
+
limitation?: string;
|
|
118
|
+
skipped?: string;
|
|
119
|
+
}
|
|
120
|
+
export interface RawScan {
|
|
121
|
+
controls: RawControl[];
|
|
122
|
+
links: RawLink[];
|
|
123
|
+
tables: RawTable[];
|
|
124
|
+
frames: RawFrame[];
|
|
125
|
+
/** Iframes past the 50th, not listed at all. */
|
|
126
|
+
framesOmitted?: number;
|
|
127
|
+
counts: {
|
|
128
|
+
controls: number;
|
|
129
|
+
links: number;
|
|
130
|
+
tables: number;
|
|
131
|
+
};
|
|
132
|
+
shadowRoots: number;
|
|
133
|
+
}
|
|
134
|
+
/** Where the scan root sits relative to the page: the iframe selectors that lead to it. */
|
|
135
|
+
interface ScopeBase {
|
|
136
|
+
framePath: string[];
|
|
137
|
+
frame?: BrowserFrameSpec;
|
|
138
|
+
}
|
|
139
|
+
declare function scopeBase(target: BrowserTarget | undefined): ScopeBase;
|
|
140
|
+
/** Run the in-page scan on the whole document, or on the one element a strict locator names. */
|
|
141
|
+
export declare function scanPage(page: any, request: ObserveRequest, base: ScopeBase): Promise<RawScan>;
|
|
142
|
+
type Json = Record<string, unknown>;
|
|
143
|
+
export interface ObservedSections {
|
|
144
|
+
controls?: Json[];
|
|
145
|
+
links?: Json[];
|
|
146
|
+
tables?: Json[];
|
|
147
|
+
frames?: Json[];
|
|
148
|
+
counts: Json;
|
|
149
|
+
limits: string[];
|
|
150
|
+
}
|
|
151
|
+
/** Check every candidate on the live page and build the records. */
|
|
152
|
+
export declare function describeScan(page: any, raw: RawScan, request: ObserveRequest, base: ScopeBase): Promise<ObservedSections>;
|
|
153
|
+
export { scopeBase };
|
|
154
|
+
export interface FitInput {
|
|
155
|
+
/** Everything outside the sections: url, title, targetId, generation, counts, frames, limits. */
|
|
156
|
+
head: Json;
|
|
157
|
+
text?: string;
|
|
158
|
+
controls?: Json[];
|
|
159
|
+
links?: Json[];
|
|
160
|
+
tables?: Json[];
|
|
161
|
+
}
|
|
162
|
+
export interface Truncation {
|
|
163
|
+
omittedBySection: Record<string, number>;
|
|
164
|
+
reason: string;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Shrink the sections until the serialized record fits `maxBytes`. The largest section is shaved first,
|
|
168
|
+
* a step at a time, so the budget ends up shared instead of one section taking all of it. Items and rows
|
|
169
|
+
* are dropped whole and text is cut at a character, so the JSON stays valid. `found` is how many items
|
|
170
|
+
* the page had per section before maxItems applied.
|
|
171
|
+
*/
|
|
172
|
+
export declare function fitObservation(input: FitInput, maxBytes: number, found: {
|
|
173
|
+
controls?: number;
|
|
174
|
+
links?: number;
|
|
175
|
+
tables?: number;
|
|
176
|
+
}, maxItems: number): {
|
|
177
|
+
record: Json;
|
|
178
|
+
truncation?: Truncation;
|
|
179
|
+
};
|
package/lib/observe.js
ADDED
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured page observation behind `observe.read` sections.
|
|
3
|
+
*
|
|
4
|
+
* The in-page scan (`observe-script.ts`) reads the DOM; this module turns its output into the
|
|
5
|
+
* model-facing record:
|
|
6
|
+
*
|
|
7
|
+
* - every listed element gets a candidate LocatorSpec that was CHECKED against the live page: it matches
|
|
8
|
+
* that element and no other (`locator`), or, when no candidate is unique, the best one is returned with
|
|
9
|
+
* `ambiguous: true`, how many elements it matches, and the element's position among them (`nth`);
|
|
10
|
+
* - the whole result is fitted to a byte budget by dropping whole items or text from the end, so the JSON
|
|
11
|
+
* is always valid and `truncation` says what was left out.
|
|
12
|
+
*
|
|
13
|
+
* A property that was not observed is absent: `false` always means "observed, and not so".
|
|
14
|
+
* @module dsh-browser/observe
|
|
15
|
+
*/
|
|
16
|
+
import { OBSERVE_MAX_FRAMES, OBSERVE_MAX_FRAME_DEPTH, OBSERVE_SOURCE, IDENTITY_SOURCE } from "./observe-script.js";
|
|
17
|
+
import { resolveLocator, validateLocatorSpec, withStrictLocator } from "./locator.js";
|
|
18
|
+
export const OBSERVE_SECTIONS = ['content', 'controls', 'links', 'tables'];
|
|
19
|
+
export const OBSERVE_DEFAULT_ITEMS = 50;
|
|
20
|
+
export const OBSERVE_MAX_ITEMS = 500;
|
|
21
|
+
export const OBSERVE_DEFAULT_BYTES = 24_000;
|
|
22
|
+
export const OBSERVE_MIN_BYTES = 2_000;
|
|
23
|
+
export const OBSERVE_MAX_BYTES = 90_000;
|
|
24
|
+
export class ObserveArgError extends Error {
|
|
25
|
+
constructor(message) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = 'ObserveArgError';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Check and complete the raw arguments (the registry validated their types already). */
|
|
31
|
+
export function normalizeObserve(raw) {
|
|
32
|
+
const sections = [...new Set(raw.sections ?? ['content'])];
|
|
33
|
+
if (!sections.length)
|
|
34
|
+
throw new ObserveArgError('sections must list at least one of content, controls, links, tables');
|
|
35
|
+
for (const section of sections)
|
|
36
|
+
if (!OBSERVE_SECTIONS.includes(section))
|
|
37
|
+
throw new ObserveArgError(`unknown section "${section}"; use content, controls, links, or tables`);
|
|
38
|
+
const maxItems = raw.maxItems ?? OBSERVE_DEFAULT_ITEMS;
|
|
39
|
+
if (!Number.isInteger(maxItems) || maxItems < 1 || maxItems > OBSERVE_MAX_ITEMS)
|
|
40
|
+
throw new ObserveArgError(`maxItems must be an integer from 1 to ${OBSERVE_MAX_ITEMS}`);
|
|
41
|
+
const maxBytes = raw.maxBytes ?? OBSERVE_DEFAULT_BYTES;
|
|
42
|
+
if (!Number.isInteger(maxBytes) || maxBytes < OBSERVE_MIN_BYTES || maxBytes > OBSERVE_MAX_BYTES)
|
|
43
|
+
throw new ObserveArgError(`maxBytes must be an integer from ${OBSERVE_MIN_BYTES} to ${OBSERVE_MAX_BYTES}`);
|
|
44
|
+
const region = raw.region;
|
|
45
|
+
if (region) {
|
|
46
|
+
const { x, y, width, height } = region;
|
|
47
|
+
if (![x, y, width, height].every(Number.isFinite) || width <= 0 || height <= 0)
|
|
48
|
+
throw new ObserveArgError('region must be {x, y, width, height} in viewport pixels with a positive width and height');
|
|
49
|
+
}
|
|
50
|
+
const timeoutMs = raw.timeoutMs ?? 15_000;
|
|
51
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 1 || timeoutMs > 30_000)
|
|
52
|
+
throw new ObserveArgError('timeoutMs must be between 1 and 30,000 ms');
|
|
53
|
+
return {
|
|
54
|
+
sections,
|
|
55
|
+
...raw.target !== undefined ? { target: raw.target } : {},
|
|
56
|
+
...region ? { region } : {},
|
|
57
|
+
maxItems, maxBytes, includeValues: raw.includeValues === true, timeoutMs,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function scopeBase(target) {
|
|
61
|
+
if (target === undefined)
|
|
62
|
+
return { framePath: [] };
|
|
63
|
+
const spec = validateLocatorSpec(typeof target === 'string' ? { selector: target } : target);
|
|
64
|
+
if (spec.framePath)
|
|
65
|
+
return { framePath: [...spec.framePath] };
|
|
66
|
+
if (spec.frame?.selector)
|
|
67
|
+
return { framePath: [spec.frame.selector] };
|
|
68
|
+
if (spec.frame)
|
|
69
|
+
return { framePath: [], frame: spec.frame };
|
|
70
|
+
return { framePath: [] };
|
|
71
|
+
}
|
|
72
|
+
/** Run the in-page scan on the whole document, or on the one element a strict locator names. */
|
|
73
|
+
export async function scanPage(page, request, base) {
|
|
74
|
+
const options = {
|
|
75
|
+
controls: request.sections.includes('controls'),
|
|
76
|
+
links: request.sections.includes('links'),
|
|
77
|
+
tables: request.sections.includes('tables'),
|
|
78
|
+
maxItems: request.maxItems,
|
|
79
|
+
includeValues: request.includeValues,
|
|
80
|
+
...request.region ? { region: request.region } : {},
|
|
81
|
+
maxFrameDepth: Math.max(0, OBSERVE_MAX_FRAME_DEPTH - base.framePath.length),
|
|
82
|
+
maxFrames: OBSERVE_MAX_FRAMES,
|
|
83
|
+
// A frame addressed by name or url cannot be extended with nested framePath entries.
|
|
84
|
+
noFrames: base.frame !== undefined,
|
|
85
|
+
};
|
|
86
|
+
if (request.target === undefined)
|
|
87
|
+
return await page.evaluate(`(${OBSERVE_SOURCE})(document, ${JSON.stringify(options)})`);
|
|
88
|
+
const locator = resolveLocator(page, request.target);
|
|
89
|
+
// The function text is turned into a real Function so Playwright serializes it as a function, not an expression.
|
|
90
|
+
const run = new Function('el', 'opts', `return (${OBSERVE_SOURCE})(el, opts)`);
|
|
91
|
+
return await withStrictLocator(locator, l => l.evaluate(run, options, { timeout: request.timeoutMs }));
|
|
92
|
+
}
|
|
93
|
+
const IDENTITY = new Function('els', `return (${IDENTITY_SOURCE})(els)`);
|
|
94
|
+
function fullSpec(candidate, path, base) {
|
|
95
|
+
const framePath = [...base.framePath, ...path];
|
|
96
|
+
return {
|
|
97
|
+
...candidate,
|
|
98
|
+
...framePath.length ? { framePath } : {},
|
|
99
|
+
...base.frame ? { frame: base.frame } : {},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Pick the first candidate that matches exactly the element with this number. A candidate matching more
|
|
104
|
+
* elements is remembered (fewest matches wins) and returned flagged `ambiguous` if no candidate is unique.
|
|
105
|
+
*/
|
|
106
|
+
async function bind(page, id, candidates, path, base) {
|
|
107
|
+
let best;
|
|
108
|
+
for (const candidate of candidates ?? []) {
|
|
109
|
+
let spec;
|
|
110
|
+
let ids;
|
|
111
|
+
try {
|
|
112
|
+
spec = fullSpec(candidate, path, base);
|
|
113
|
+
ids = await resolveLocator(page, spec).evaluateAll(IDENTITY);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const at = ids.indexOf(id);
|
|
119
|
+
if (at < 0)
|
|
120
|
+
continue;
|
|
121
|
+
if (ids.length === 1)
|
|
122
|
+
return { locator: spec };
|
|
123
|
+
if (!best || ids.length < best.matches)
|
|
124
|
+
best = { spec, matches: ids.length, nth: at };
|
|
125
|
+
}
|
|
126
|
+
return best ? { locator: best.spec, ambiguous: true, matches: best.matches, nth: best.nth } : { ambiguous: true };
|
|
127
|
+
}
|
|
128
|
+
/** Bind with a small pool and a time limit; whatever is not reached in time stays unbound and is reported. */
|
|
129
|
+
async function bindAll(items, job, deadline) {
|
|
130
|
+
let cursor = 0;
|
|
131
|
+
let skipped = 0;
|
|
132
|
+
const worker = async () => {
|
|
133
|
+
while (cursor < items.length) {
|
|
134
|
+
const item = items[cursor++];
|
|
135
|
+
if (Date.now() > deadline) {
|
|
136
|
+
skipped += 1;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
await job(item);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
await Promise.all(Array.from({ length: Math.min(6, items.length) }, worker));
|
|
143
|
+
return skipped;
|
|
144
|
+
}
|
|
145
|
+
function locatorFields(binding) {
|
|
146
|
+
return {
|
|
147
|
+
...binding.locator ? { locator: binding.locator } : {},
|
|
148
|
+
...binding.ambiguous ? { ambiguous: true } : {},
|
|
149
|
+
...binding.matches !== undefined ? { matches: binding.matches, nth: binding.nth } : {},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/** Check every candidate on the live page and build the records. */
|
|
153
|
+
export async function describeScan(page, raw, request, base) {
|
|
154
|
+
const deadline = Date.now() + 12_000;
|
|
155
|
+
let skipped = 0;
|
|
156
|
+
// `unverified` marks an item whose locator was not checked because the time ran out.
|
|
157
|
+
const pending = (binding) => binding ? locatorFields(binding) : { unverified: true };
|
|
158
|
+
const controls = [];
|
|
159
|
+
if (request.sections.includes('controls')) {
|
|
160
|
+
const bound = raw.controls.map(control => ({ control, binding: undefined, options: undefined }));
|
|
161
|
+
skipped += await bindAll(bound, async (entry) => {
|
|
162
|
+
const { control } = entry;
|
|
163
|
+
if (control.role === 'radiogroup') {
|
|
164
|
+
entry.options = [];
|
|
165
|
+
for (const option of control.options ?? [])
|
|
166
|
+
entry.options.push(option.id !== undefined ? await bind(page, option.id, option.cands, control.path, base) : undefined);
|
|
167
|
+
entry.binding = {};
|
|
168
|
+
}
|
|
169
|
+
else if (control.id !== undefined)
|
|
170
|
+
entry.binding = await bind(page, control.id, control.cands, control.path, base);
|
|
171
|
+
}, deadline);
|
|
172
|
+
for (const { control, binding, options: optionBindings } of bound) {
|
|
173
|
+
const options = control.role === 'radiogroup'
|
|
174
|
+
? (control.options ?? []).map((option, index) => ({
|
|
175
|
+
label: option.label, value: option.value, checked: option.checked === true, ...option.disabled ? { disabled: true } : {}, ...pending(optionBindings?.[index]),
|
|
176
|
+
}))
|
|
177
|
+
: control.options;
|
|
178
|
+
controls.push({
|
|
179
|
+
...control.role ? { role: control.role } : {},
|
|
180
|
+
...control.name ? { name: control.name } : {},
|
|
181
|
+
...control.type ? { type: control.type } : {},
|
|
182
|
+
...control.role === 'radiogroup' ? {} : pending(binding),
|
|
183
|
+
actions: control.actions,
|
|
184
|
+
...control.visible !== undefined ? { visible: control.visible } : {},
|
|
185
|
+
...control.disabled !== undefined ? { disabled: control.disabled } : {},
|
|
186
|
+
...control.readonly !== undefined ? { readonly: control.readonly } : {},
|
|
187
|
+
...control.checked !== undefined ? { checked: control.checked } : {},
|
|
188
|
+
...control.expanded !== undefined ? { expanded: control.expanded } : {},
|
|
189
|
+
...control.hasValue !== undefined ? { hasValue: control.hasValue } : {},
|
|
190
|
+
...control.value !== undefined ? { value: control.value } : {},
|
|
191
|
+
...control.sensitive ? { sensitive: true } : {},
|
|
192
|
+
...options ? { options } : {},
|
|
193
|
+
...control.optionsTotal !== undefined ? { optionsTotal: control.optionsTotal } : {},
|
|
194
|
+
...control.constraints ? { constraints: control.constraints } : {},
|
|
195
|
+
...control.validity ? { validity: control.validity } : {},
|
|
196
|
+
source: control.source,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const links = [];
|
|
201
|
+
if (request.sections.includes('links')) {
|
|
202
|
+
const bound = raw.links.map(link => ({ link, binding: undefined }));
|
|
203
|
+
skipped += await bindAll(bound, async (entry) => { entry.binding = await bind(page, entry.link.id, entry.link.cands, entry.link.path, base); }, deadline);
|
|
204
|
+
for (const { link, binding } of bound) {
|
|
205
|
+
links.push({ text: link.text, href: link.href, ...pending(binding), visible: link.visible, ...link.target ? { target: link.target } : {} });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const tables = [];
|
|
209
|
+
if (request.sections.includes('tables')) {
|
|
210
|
+
const bound = raw.tables.map(table => ({ table, binding: undefined }));
|
|
211
|
+
skipped += await bindAll(bound, async (entry) => { entry.binding = await bind(page, entry.table.id, entry.table.cands, entry.table.path, base); }, deadline);
|
|
212
|
+
for (const { table, binding } of bound) {
|
|
213
|
+
tables.push({
|
|
214
|
+
...table.name ? { name: table.name } : {},
|
|
215
|
+
...pending(binding),
|
|
216
|
+
headers: table.headers, rows: table.rows, totalRows: table.totalRows,
|
|
217
|
+
...table.declaredRows !== undefined ? { declaredRows: table.declaredRows } : {},
|
|
218
|
+
coverage: table.coverage,
|
|
219
|
+
...table.reason ? { reason: table.reason } : {},
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const limits = [];
|
|
224
|
+
if (skipped)
|
|
225
|
+
limits.push(`locator checking ran out of time: ${skipped} item(s) are listed without a checked locator (unverified: true)`);
|
|
226
|
+
const crossOrigin = raw.frames.filter(frame => frame.crossOrigin).length;
|
|
227
|
+
if (crossOrigin)
|
|
228
|
+
limits.push(`${crossOrigin} cross-origin or sandboxed iframe(s) are listed in frames but their content is not observed; act.* can still reach into one with its framePath if you know the element`);
|
|
229
|
+
if (raw.frames.some(frame => frame.skipped))
|
|
230
|
+
limits.push('some iframes were not entered (nesting or count limit)');
|
|
231
|
+
if (raw.framesOmitted)
|
|
232
|
+
limits.push(`${raw.framesOmitted} more iframe(s) were neither listed nor entered`);
|
|
233
|
+
return {
|
|
234
|
+
...request.sections.includes('controls') ? { controls } : {},
|
|
235
|
+
...request.sections.includes('links') ? { links } : {},
|
|
236
|
+
...request.sections.includes('tables') ? { tables } : {},
|
|
237
|
+
...raw.frames.length ? { frames: raw.frames.map(frame => ({ ...frame })) } : {},
|
|
238
|
+
counts: {
|
|
239
|
+
...request.sections.includes('controls') ? { controls: raw.counts.controls } : {},
|
|
240
|
+
...request.sections.includes('links') ? { links: raw.counts.links } : {},
|
|
241
|
+
...request.sections.includes('tables') ? { tables: raw.counts.tables } : {},
|
|
242
|
+
},
|
|
243
|
+
limits,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
export { scopeBase };
|
|
247
|
+
// ---- fitting to a byte budget ---------------------------------------------------------------------
|
|
248
|
+
const bytes = (value) => Buffer.byteLength(JSON.stringify(value));
|
|
249
|
+
const TRUNCATION_RESERVE = 420;
|
|
250
|
+
/** Drop the last characters of a string without splitting a surrogate pair. */
|
|
251
|
+
function cutText(text, drop) {
|
|
252
|
+
let end = Math.max(0, text.length - drop);
|
|
253
|
+
if (end > 0 && end < text.length && /[\ud800-\udbff]/.test(text[end - 1]))
|
|
254
|
+
end -= 1;
|
|
255
|
+
return text.slice(0, end);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Shrink the sections until the serialized record fits `maxBytes`. The largest section is shaved first,
|
|
259
|
+
* a step at a time, so the budget ends up shared instead of one section taking all of it. Items and rows
|
|
260
|
+
* are dropped whole and text is cut at a character, so the JSON stays valid. `found` is how many items
|
|
261
|
+
* the page had per section before maxItems applied.
|
|
262
|
+
*/
|
|
263
|
+
export function fitObservation(input, maxBytes, found, maxItems) {
|
|
264
|
+
let text = input.text;
|
|
265
|
+
const lists = {
|
|
266
|
+
frames: Array.isArray(input.head.frames) ? [...input.head.frames] : undefined,
|
|
267
|
+
controls: input.controls ? [...input.controls] : undefined,
|
|
268
|
+
links: input.links ? [...input.links] : undefined,
|
|
269
|
+
tables: input.tables ? input.tables.map(table => ({ ...table, rows: [...table.rows] })) : undefined,
|
|
270
|
+
};
|
|
271
|
+
const droppedText = { chars: 0 };
|
|
272
|
+
const compose = () => ({
|
|
273
|
+
...input.head,
|
|
274
|
+
...lists.frames ? { frames: lists.frames } : {},
|
|
275
|
+
...text !== undefined ? { text } : {},
|
|
276
|
+
...lists.controls ? { controls: lists.controls } : {},
|
|
277
|
+
...lists.links ? { links: lists.links } : {},
|
|
278
|
+
...lists.tables ? { tables: lists.tables } : {},
|
|
279
|
+
});
|
|
280
|
+
const byBytes = new Set();
|
|
281
|
+
const byItems = new Set();
|
|
282
|
+
for (const name of ['controls', 'links', 'tables']) {
|
|
283
|
+
const total = found[name];
|
|
284
|
+
if (lists[name] && total !== undefined && total > lists[name].length)
|
|
285
|
+
byItems.add(name);
|
|
286
|
+
}
|
|
287
|
+
const tableRowsAtItems = (lists.tables ?? []).reduce((sum, table) => sum + Math.max(0, Number(table.totalRows) - table.rows.length), 0);
|
|
288
|
+
if (tableRowsAtItems > 0)
|
|
289
|
+
byItems.add('tables');
|
|
290
|
+
// Room kept for the `truncation` member the caller adds when anything was left out.
|
|
291
|
+
const budget = maxBytes - TRUNCATION_RESERVE;
|
|
292
|
+
for (let guard = 0; guard < 2_000; guard += 1) {
|
|
293
|
+
const total = bytes(compose());
|
|
294
|
+
if (total <= budget)
|
|
295
|
+
break;
|
|
296
|
+
const over = total - budget;
|
|
297
|
+
// Section sizes, largest first.
|
|
298
|
+
const sizes = [];
|
|
299
|
+
if (text !== undefined && text.length > 0)
|
|
300
|
+
sizes.push({ name: 'content', size: bytes(text) });
|
|
301
|
+
for (const name of ['controls', 'links', 'tables'])
|
|
302
|
+
if (lists[name]?.length)
|
|
303
|
+
sizes.push({ name, size: bytes(lists[name]) });
|
|
304
|
+
// The frame list is the last thing to give up: it explains what was not covered.
|
|
305
|
+
if (!sizes.length && lists.frames?.length)
|
|
306
|
+
sizes.push({ name: 'frames', size: bytes(lists.frames) });
|
|
307
|
+
if (!sizes.length)
|
|
308
|
+
break;
|
|
309
|
+
sizes.sort((a, b) => b.size - a.size);
|
|
310
|
+
const target = sizes[0];
|
|
311
|
+
const step = Math.min(over, Math.max(300, Math.ceil(target.size * 0.15)));
|
|
312
|
+
byBytes.add(target.name);
|
|
313
|
+
if (target.name === 'content') {
|
|
314
|
+
const before = text.length;
|
|
315
|
+
text = cutText(text, step);
|
|
316
|
+
droppedText.chars += before - text.length;
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
const list = lists[target.name];
|
|
320
|
+
let freed = 0;
|
|
321
|
+
while (freed < step && list.length) {
|
|
322
|
+
if (target.name === 'tables') {
|
|
323
|
+
// Rows of the table that has the most go first; a table with no rows left goes whole.
|
|
324
|
+
const widest = list.reduce((best, table) => table.rows.length > best.rows.length ? table : best, list[0]);
|
|
325
|
+
const rows = widest.rows;
|
|
326
|
+
if (rows.length) {
|
|
327
|
+
freed += bytes(rows.pop()) + 1;
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
const index = list.lastIndexOf(list.reduce((best, table) => bytes(table) > bytes(best) ? table : best, list[list.length - 1]));
|
|
331
|
+
freed += bytes(list.splice(index, 1)[0]) + 1;
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
freed += bytes(list.pop()) + 1;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
const record = compose();
|
|
338
|
+
const omittedBySection = {};
|
|
339
|
+
if (droppedText.chars > 0)
|
|
340
|
+
omittedBySection.content = droppedText.chars;
|
|
341
|
+
for (const name of ['controls', 'links']) {
|
|
342
|
+
const listed = lists[name];
|
|
343
|
+
if (listed && found[name] !== undefined && found[name] > listed.length)
|
|
344
|
+
omittedBySection[name] = found[name] - listed.length;
|
|
345
|
+
}
|
|
346
|
+
const framesTotal = Array.isArray(input.head.frames) ? input.head.frames.length : 0;
|
|
347
|
+
if (lists.frames && lists.frames.length < framesTotal)
|
|
348
|
+
omittedBySection.frames = framesTotal - lists.frames.length;
|
|
349
|
+
if (lists.tables) {
|
|
350
|
+
if (found.tables !== undefined && found.tables > lists.tables.length)
|
|
351
|
+
omittedBySection.tables = found.tables - lists.tables.length;
|
|
352
|
+
const rowsOmitted = lists.tables.reduce((sum, table) => sum + Math.max(0, Number(table.totalRows) - table.rows.length), 0);
|
|
353
|
+
if (rowsOmitted > 0)
|
|
354
|
+
omittedBySection.tableRows = rowsOmitted;
|
|
355
|
+
}
|
|
356
|
+
if (!Object.keys(omittedBySection).length)
|
|
357
|
+
return { record };
|
|
358
|
+
const parts = [];
|
|
359
|
+
const itemSections = [...byItems].filter(name => omittedBySection[name] !== undefined || (name === 'tables' && omittedBySection.tableRows !== undefined));
|
|
360
|
+
if (itemSections.length)
|
|
361
|
+
parts.push(`maxItems=${maxItems} reached for ${itemSections.join(', ')}`);
|
|
362
|
+
const byteSections = [...byBytes].filter(name => omittedBySection[name === 'tables' ? 'tables' : name] !== undefined || (name === 'tables' && omittedBySection.tableRows !== undefined));
|
|
363
|
+
if (byteSections.length)
|
|
364
|
+
parts.push(`maxBytes=${maxBytes} reached for ${byteSections.join(', ')}`);
|
|
365
|
+
const units = 'content counts characters, tableRows counts rows, the others count items';
|
|
366
|
+
return { record, truncation: { omittedBySection, reason: `${parts.join('; ') || 'output limit reached'} (${units})` } };
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=observe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observe.js","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keys of the two JSON policy objects, in one place.
|
|
3
|
+
*
|
|
4
|
+
* The settings card validates what a person types into the "automation asset policy" and "usage buffer" boxes against
|
|
5
|
+
* these lists and prints them under the boxes, so a key added to a policy is added here once. This module has no
|
|
6
|
+
* imports on purpose: the card bundles it for the browser. test/policy-keys.test.ts holds the lists equal to what the
|
|
7
|
+
* resolvers return and to the Host Config schema.
|
|
8
|
+
* @module dsh-browser/policy-keys
|
|
9
|
+
*/
|
|
10
|
+
/** Every key of `automationAssets`, in documentation order. */
|
|
11
|
+
export declare const ASSET_POLICY_KEYS: readonly ["enabled", "directory", "persistenceMode", "activationMode", "minSuccessfulRuns", "minDistinctSessions", "successWindowDays", "minSuccessRate", "maxCandidates", "candidateTtlDays", "maxSuggestionsPerDay", "maxDrafts", "maxActiveAssets", "retrievalTopK", "catalogTokenBudget", "modelDevelopmentEnabled", "maxModelDraftWritesPerSession", "maxTestCredentials", "minInputSetsForActivation"];
|
|
12
|
+
export type AssetPolicyKey = typeof ASSET_POLICY_KEYS[number];
|
|
13
|
+
/** The keys of `automationAssets` that are not plain non-negative numbers. */
|
|
14
|
+
export declare const ASSET_POLICY_BOOLEAN_KEYS: readonly AssetPolicyKey[];
|
|
15
|
+
export declare const ASSET_POLICY_STRING_KEYS: readonly AssetPolicyKey[];
|
|
16
|
+
export declare const ASSET_POLICY_ENUMS: Partial<Record<AssetPolicyKey, readonly string[]>>;
|
|
17
|
+
/** Numeric keys with a range the card enforces itself; the resolver would otherwise clamp silently. */
|
|
18
|
+
export declare const ASSET_POLICY_INTEGER_RANGES: Partial<Record<AssetPolicyKey, readonly [number, number]>>;
|
|
19
|
+
/** `usagePolicy`: every key with the inclusive integer range the resolver enforces. */
|
|
20
|
+
export declare const USAGE_POLICY_BOUNDS: {
|
|
21
|
+
readonly minDelayMs: readonly [0, 60000];
|
|
22
|
+
readonly maxConcurrency: readonly [1, 8];
|
|
23
|
+
readonly burst: readonly [1, 20];
|
|
24
|
+
readonly maxPagesPerRun: readonly [1, 100];
|
|
25
|
+
readonly maxDepth: readonly [0, 5];
|
|
26
|
+
readonly retryLimit: readonly [0, 5];
|
|
27
|
+
readonly backoffBaseMs: readonly [1, 60000];
|
|
28
|
+
readonly cooldownMs: readonly [100, 300000];
|
|
29
|
+
};
|
|
30
|
+
export declare const USAGE_POLICY_KEYS: (keyof typeof USAGE_POLICY_BOUNDS)[];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keys of the two JSON policy objects, in one place.
|
|
3
|
+
*
|
|
4
|
+
* The settings card validates what a person types into the "automation asset policy" and "usage buffer" boxes against
|
|
5
|
+
* these lists and prints them under the boxes, so a key added to a policy is added here once. This module has no
|
|
6
|
+
* imports on purpose: the card bundles it for the browser. test/policy-keys.test.ts holds the lists equal to what the
|
|
7
|
+
* resolvers return and to the Host Config schema.
|
|
8
|
+
* @module dsh-browser/policy-keys
|
|
9
|
+
*/
|
|
10
|
+
/** Every key of `automationAssets`, in documentation order. */
|
|
11
|
+
export const ASSET_POLICY_KEYS = [
|
|
12
|
+
'enabled', 'directory', 'persistenceMode', 'activationMode', 'minSuccessfulRuns', 'minDistinctSessions',
|
|
13
|
+
'successWindowDays', 'minSuccessRate', 'maxCandidates', 'candidateTtlDays', 'maxSuggestionsPerDay',
|
|
14
|
+
'maxDrafts', 'maxActiveAssets', 'retrievalTopK', 'catalogTokenBudget',
|
|
15
|
+
'modelDevelopmentEnabled', 'maxModelDraftWritesPerSession', 'maxTestCredentials', 'minInputSetsForActivation',
|
|
16
|
+
];
|
|
17
|
+
/** The keys of `automationAssets` that are not plain non-negative numbers. */
|
|
18
|
+
export const ASSET_POLICY_BOOLEAN_KEYS = ['enabled', 'modelDevelopmentEnabled'];
|
|
19
|
+
export const ASSET_POLICY_STRING_KEYS = ['directory'];
|
|
20
|
+
export const ASSET_POLICY_ENUMS = {
|
|
21
|
+
persistenceMode: ['off', 'manual', 'suggest', 'auto-draft'],
|
|
22
|
+
activationMode: ['manual', 'auto-tested'],
|
|
23
|
+
};
|
|
24
|
+
/** Numeric keys with a range the card enforces itself; the resolver would otherwise clamp silently. */
|
|
25
|
+
export const ASSET_POLICY_INTEGER_RANGES = {
|
|
26
|
+
minInputSetsForActivation: [1, 5],
|
|
27
|
+
};
|
|
28
|
+
/** `usagePolicy`: every key with the inclusive integer range the resolver enforces. */
|
|
29
|
+
export const USAGE_POLICY_BOUNDS = {
|
|
30
|
+
minDelayMs: [0, 60_000], maxConcurrency: [1, 8], burst: [1, 20], maxPagesPerRun: [1, 100],
|
|
31
|
+
maxDepth: [0, 5], retryLimit: [0, 5], backoffBaseMs: [1, 60_000], cooldownMs: [100, 300_000],
|
|
32
|
+
};
|
|
33
|
+
export const USAGE_POLICY_KEYS = Object.keys(USAGE_POLICY_BOUNDS);
|
|
34
|
+
//# sourceMappingURL=policy-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-keys.js","sourceRoot":"","sources":["../src/policy-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,+DAA+D;AAC/D,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,SAAS,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,qBAAqB;IACvG,mBAAmB,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB,EAAE,sBAAsB;IAClG,WAAW,EAAE,iBAAiB,EAAE,eAAe,EAAE,oBAAoB;IACrE,yBAAyB,EAAE,+BAA+B,EAAE,oBAAoB,EAAE,2BAA2B;CACrG,CAAA;AAIV,8EAA8E;AAC9E,MAAM,CAAC,MAAM,yBAAyB,GAA8B,CAAC,SAAS,EAAE,yBAAyB,CAAC,CAAA;AAC1G,MAAM,CAAC,MAAM,wBAAwB,GAA8B,CAAC,WAAW,CAAC,CAAA;AAChF,MAAM,CAAC,MAAM,kBAAkB,GAAuD;IACpF,eAAe,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC;IAC3D,cAAc,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC;CAC1C,CAAA;AACD,uGAAuG;AACvG,MAAM,CAAC,MAAM,2BAA2B,GAA+D;IACrG,yBAAyB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;CAClC,CAAA;AAED,uFAAuF;AACvF,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC;IACzF,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC;CAChC,CAAA;AAE9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAyC,CAAA"}
|