@hasna/browser 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +913 -92
- package/dist/index.js +48 -0
- package/dist/lib/api-detector.d.ts +17 -0
- package/dist/lib/api-detector.d.ts.map +1 -0
- package/dist/lib/datasets.d.ts +33 -0
- package/dist/lib/datasets.d.ts.map +1 -0
- package/dist/lib/deep-performance.d.ts +49 -0
- package/dist/lib/deep-performance.d.ts.map +1 -0
- package/dist/lib/env-detector.d.ts +12 -0
- package/dist/lib/env-detector.d.ts.map +1 -0
- package/dist/lib/structured-extract.d.ts +26 -0
- package/dist/lib/structured-extract.d.ts.map +1 -0
- package/dist/lib/workflows.d.ts +46 -0
- package/dist/lib/workflows.d.ts.map +1 -0
- package/dist/mcp/index.js +905 -84
- package/dist/server/index.js +48 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -333,6 +333,54 @@ function runMigrations(db) {
|
|
|
333
333
|
CREATE INDEX IF NOT EXISTS idx_auth_flows_domain ON auth_flows(domain);
|
|
334
334
|
CREATE INDEX IF NOT EXISTS idx_auth_flows_name ON auth_flows(name);
|
|
335
335
|
`
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
version: 7,
|
|
339
|
+
sql: `
|
|
340
|
+
CREATE TABLE IF NOT EXISTS workflows (
|
|
341
|
+
id TEXT PRIMARY KEY,
|
|
342
|
+
name TEXT NOT NULL UNIQUE,
|
|
343
|
+
description TEXT,
|
|
344
|
+
steps TEXT NOT NULL DEFAULT '[]',
|
|
345
|
+
start_url TEXT,
|
|
346
|
+
last_run TEXT,
|
|
347
|
+
last_heal TEXT,
|
|
348
|
+
heal_count INTEGER DEFAULT 0,
|
|
349
|
+
run_count INTEGER DEFAULT 0,
|
|
350
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
351
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
352
|
+
);
|
|
353
|
+
`
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
version: 8,
|
|
357
|
+
sql: `
|
|
358
|
+
CREATE TABLE IF NOT EXISTS datasets (
|
|
359
|
+
id TEXT PRIMARY KEY,
|
|
360
|
+
name TEXT NOT NULL UNIQUE,
|
|
361
|
+
source_url TEXT,
|
|
362
|
+
source_type TEXT NOT NULL DEFAULT 'page',
|
|
363
|
+
data TEXT NOT NULL DEFAULT '[]',
|
|
364
|
+
schema TEXT,
|
|
365
|
+
row_count INTEGER DEFAULT 0,
|
|
366
|
+
last_refresh TEXT,
|
|
367
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
368
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
CREATE TABLE IF NOT EXISTS api_endpoints (
|
|
372
|
+
id TEXT PRIMARY KEY,
|
|
373
|
+
session_id TEXT,
|
|
374
|
+
url TEXT NOT NULL,
|
|
375
|
+
method TEXT DEFAULT 'GET',
|
|
376
|
+
response_schema TEXT,
|
|
377
|
+
sample_response TEXT,
|
|
378
|
+
status_code INTEGER,
|
|
379
|
+
content_type TEXT,
|
|
380
|
+
discovered_at TEXT DEFAULT (datetime('now'))
|
|
381
|
+
);
|
|
382
|
+
CREATE INDEX IF NOT EXISTS idx_api_endpoints_session ON api_endpoints(session_id);
|
|
383
|
+
`
|
|
336
384
|
}
|
|
337
385
|
];
|
|
338
386
|
for (const m of migrations) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API endpoint detection — scan network log for JSON API responses.
|
|
3
|
+
*/
|
|
4
|
+
export interface DetectedAPI {
|
|
5
|
+
url: string;
|
|
6
|
+
method: string;
|
|
7
|
+
status_code: number;
|
|
8
|
+
content_type: string;
|
|
9
|
+
response_schema: Record<string, string>;
|
|
10
|
+
sample_size: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Scan network log for API endpoints that return JSON.
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectAPIs(sessionId: string): DetectedAPI[];
|
|
16
|
+
export declare function listDiscoveredAPIs(sessionId?: string): any[];
|
|
17
|
+
//# sourceMappingURL=api-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-detector.d.ts","sourceRoot":"","sources":["../../src/lib/api-detector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAkD3D;AAED,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,GAAG,EAAE,CAM5D"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dataset management — save, refresh, export extracted data.
|
|
3
|
+
*/
|
|
4
|
+
export interface Dataset {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
source_url: string | null;
|
|
8
|
+
source_type: string;
|
|
9
|
+
data: any[];
|
|
10
|
+
schema: Record<string, string> | null;
|
|
11
|
+
row_count: number;
|
|
12
|
+
last_refresh: string | null;
|
|
13
|
+
created_at: string;
|
|
14
|
+
updated_at: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function saveDataset(data: {
|
|
17
|
+
name: string;
|
|
18
|
+
sourceUrl?: string;
|
|
19
|
+
sourceType?: string;
|
|
20
|
+
rows: any[];
|
|
21
|
+
schema?: Record<string, string>;
|
|
22
|
+
}): Dataset;
|
|
23
|
+
export declare function getDataset(id: string): Dataset | null;
|
|
24
|
+
export declare function getDatasetByName(name: string): Dataset | null;
|
|
25
|
+
export declare function listDatasets(): Array<Omit<Dataset, "data"> & {
|
|
26
|
+
data: string;
|
|
27
|
+
}>;
|
|
28
|
+
export declare function deleteDataset(name: string): boolean;
|
|
29
|
+
export declare function exportDataset(name: string, format: "json" | "csv"): {
|
|
30
|
+
path: string;
|
|
31
|
+
size: number;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=datasets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datasets.d.ts","sourceRoot":"","sources":["../../src/lib/datasets.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,OAAO,CAclJ;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAKrD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAK7D;AAED,wBAAgB,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAI9E;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA6BlG"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep performance metrics — resource breakdown, third-party analysis, DOM complexity.
|
|
3
|
+
*/
|
|
4
|
+
import type { Page } from "playwright";
|
|
5
|
+
export interface DeepPerformance {
|
|
6
|
+
web_vitals: {
|
|
7
|
+
fcp?: number;
|
|
8
|
+
lcp?: number;
|
|
9
|
+
cls?: number;
|
|
10
|
+
ttfb?: number;
|
|
11
|
+
inp?: number;
|
|
12
|
+
};
|
|
13
|
+
resources: {
|
|
14
|
+
total_transfer_bytes: number;
|
|
15
|
+
total_resources: number;
|
|
16
|
+
by_type: Record<string, {
|
|
17
|
+
count: number;
|
|
18
|
+
size_bytes: number;
|
|
19
|
+
}>;
|
|
20
|
+
largest: Array<{
|
|
21
|
+
url: string;
|
|
22
|
+
size_bytes: number;
|
|
23
|
+
type: string;
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
26
|
+
third_party: Array<{
|
|
27
|
+
domain: string;
|
|
28
|
+
scripts: number;
|
|
29
|
+
total_bytes: number;
|
|
30
|
+
category: string;
|
|
31
|
+
}>;
|
|
32
|
+
dom: {
|
|
33
|
+
node_count: number;
|
|
34
|
+
max_depth: number;
|
|
35
|
+
element_count: number;
|
|
36
|
+
text_node_count: number;
|
|
37
|
+
};
|
|
38
|
+
main_thread: {
|
|
39
|
+
long_tasks: number;
|
|
40
|
+
total_blocking_ms: number;
|
|
41
|
+
};
|
|
42
|
+
memory: {
|
|
43
|
+
js_heap_used_mb: number;
|
|
44
|
+
js_heap_total_mb: number;
|
|
45
|
+
js_heap_limit_mb: number;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export declare function getDeepPerformance(page: Page): Promise<DeepPerformance>;
|
|
49
|
+
//# sourceMappingURL=deep-performance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-performance.d.ts","sourceRoot":"","sources":["../../src/lib/deep-performance.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,SAAS,EAAE;QACT,oBAAoB,EAAE,MAAM,CAAC;QAC7B,eAAe,EAAE,MAAM,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC/D,OAAO,EAAE,KAAK,CAAC;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACnE,CAAC;IACF,WAAW,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/F,GAAG,EAAE;QACH,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,MAAM,EAAE;QACN,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAqBD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CA4G7E"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment detection — determine if a site is prod, dev, staging, or local.
|
|
3
|
+
*/
|
|
4
|
+
import type { Page } from "playwright";
|
|
5
|
+
export type Environment = "local" | "dev" | "staging" | "prod";
|
|
6
|
+
export interface EnvDetectionResult {
|
|
7
|
+
env: Environment;
|
|
8
|
+
confidence: "high" | "medium" | "low";
|
|
9
|
+
signals: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function detectEnvironment(page: Page): Promise<EnvDetectionResult>;
|
|
12
|
+
//# sourceMappingURL=env-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-detector.d.ts","sourceRoot":"","sources":["../../src/lib/env-detector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,WAAW,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoH/E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured data extraction from web pages.
|
|
3
|
+
* Detects tables, lists, JSON-LD, Schema.org, repeated elements.
|
|
4
|
+
*/
|
|
5
|
+
import type { Page } from "playwright";
|
|
6
|
+
export interface StructuredData {
|
|
7
|
+
tables: Array<{
|
|
8
|
+
headers: string[];
|
|
9
|
+
rows: string[][];
|
|
10
|
+
selector: string;
|
|
11
|
+
}>;
|
|
12
|
+
lists: Array<{
|
|
13
|
+
items: string[];
|
|
14
|
+
selector: string;
|
|
15
|
+
}>;
|
|
16
|
+
jsonLd: any[];
|
|
17
|
+
openGraph: Record<string, string>;
|
|
18
|
+
metaTags: Record<string, string>;
|
|
19
|
+
repeatedElements: Array<{
|
|
20
|
+
selector: string;
|
|
21
|
+
count: number;
|
|
22
|
+
sample: string[];
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
export declare function extractStructuredData(page: Page): Promise<StructuredData>;
|
|
26
|
+
//# sourceMappingURL=structured-extract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structured-extract.d.ts","sourceRoot":"","sources":["../../src/lib/structured-extract.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzE,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,gBAAgB,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAChF;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAgF/E"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Saved workflows — reusable browser automation sequences with self-healing.
|
|
3
|
+
* Record a flow once, replay it forever. If selectors change, auto-heal and update.
|
|
4
|
+
*/
|
|
5
|
+
import type { Page } from "playwright";
|
|
6
|
+
import type { RecordingStep } from "../types/index.js";
|
|
7
|
+
export interface Workflow {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
description: string | null;
|
|
11
|
+
steps: RecordingStep[];
|
|
12
|
+
start_url: string | null;
|
|
13
|
+
last_run: string | null;
|
|
14
|
+
last_heal: string | null;
|
|
15
|
+
heal_count: number;
|
|
16
|
+
run_count: number;
|
|
17
|
+
created_at: string;
|
|
18
|
+
updated_at: string;
|
|
19
|
+
}
|
|
20
|
+
export interface WorkflowRunResult {
|
|
21
|
+
success: boolean;
|
|
22
|
+
steps_executed: number;
|
|
23
|
+
steps_failed: number;
|
|
24
|
+
steps_healed: number;
|
|
25
|
+
healed_details: Array<{
|
|
26
|
+
step: number;
|
|
27
|
+
original: string;
|
|
28
|
+
healed_to: string;
|
|
29
|
+
method: string;
|
|
30
|
+
}>;
|
|
31
|
+
errors: string[];
|
|
32
|
+
duration_ms: number;
|
|
33
|
+
}
|
|
34
|
+
export declare function saveWorkflow(data: {
|
|
35
|
+
name: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
steps: RecordingStep[];
|
|
38
|
+
startUrl?: string;
|
|
39
|
+
}): Workflow;
|
|
40
|
+
export declare function saveWorkflowFromRecording(recordingId: string, name: string, description?: string): Workflow;
|
|
41
|
+
export declare function getWorkflow(id: string): Workflow | null;
|
|
42
|
+
export declare function getWorkflowByName(name: string): Workflow | null;
|
|
43
|
+
export declare function listWorkflows(): Workflow[];
|
|
44
|
+
export declare function deleteWorkflow(name: string): boolean;
|
|
45
|
+
export declare function runWorkflow(workflow: Workflow, page: Page): Promise<WorkflowRunResult>;
|
|
46
|
+
//# sourceMappingURL=workflows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../src/lib/workflows.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7F,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAID,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,CAO9H;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,CAQ3G;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAKvD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAK/D;AAED,wBAAgB,aAAa,IAAI,QAAQ,EAAE,CAI1C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGpD;AAkBD,wBAAsB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA+F5F"}
|