doc-detective 4.19.0 → 4.20.0
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/common/src/schemas/schemas.json +86416 -6069
- package/dist/common/src/types/generated/closeSurface_v3.d.ts +79 -13
- package/dist/common/src/types/generated/closeSurface_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/config_v3.d.ts +24 -0
- package/dist/common/src/types/generated/config_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/context_v3.d.ts +24 -0
- package/dist/common/src/types/generated/context_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/report_v3.d.ts +24 -0
- package/dist/common/src/types/generated/report_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/resolvedTests_v3.d.ts +48 -0
- package/dist/common/src/types/generated/resolvedTests_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/screenshot_v3.d.ts +40 -3
- package/dist/common/src/types/generated/screenshot_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/spec_v3.d.ts +24 -0
- package/dist/common/src/types/generated/spec_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/startSurface_v3.d.ts +108 -0
- package/dist/common/src/types/generated/startSurface_v3.d.ts.map +1 -0
- package/dist/common/src/types/generated/startSurface_v3.js +7 -0
- package/dist/common/src/types/generated/startSurface_v3.js.map +1 -0
- package/dist/common/src/types/generated/step_v3.d.ts +532 -107
- package/dist/common/src/types/generated/step_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/surface_v3.d.ts +35 -2
- package/dist/common/src/types/generated/surface_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/test_v3.d.ts +1837 -851
- package/dist/common/src/types/generated/test_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/type_v3.d.ts +60 -10
- package/dist/common/src/types/generated/type_v3.d.ts.map +1 -1
- package/dist/common/src/types/generated/waitUntil_v3.d.ts +22 -8
- package/dist/common/src/types/generated/waitUntil_v3.d.ts.map +1 -1
- package/dist/core/detectTests.d.ts.map +1 -1
- package/dist/core/detectTests.js +26 -1
- package/dist/core/detectTests.js.map +1 -1
- package/dist/core/expressions.d.ts.map +1 -1
- package/dist/core/expressions.js +19 -1
- package/dist/core/expressions.js.map +1 -1
- package/dist/core/resolveTests.d.ts.map +1 -1
- package/dist/core/resolveTests.js +24 -6
- package/dist/core/resolveTests.js.map +1 -1
- package/dist/core/tests/appSurface.d.ts +106 -0
- package/dist/core/tests/appSurface.d.ts.map +1 -0
- package/dist/core/tests/appSurface.js +521 -0
- package/dist/core/tests/appSurface.js.map +1 -0
- package/dist/core/tests/click.d.ts +2 -1
- package/dist/core/tests/click.d.ts.map +1 -1
- package/dist/core/tests/click.js +2 -1
- package/dist/core/tests/click.js.map +1 -1
- package/dist/core/tests/closeSurface.d.ts +3 -1
- package/dist/core/tests/closeSurface.d.ts.map +1 -1
- package/dist/core/tests/closeSurface.js +43 -5
- package/dist/core/tests/closeSurface.js.map +1 -1
- package/dist/core/tests/findElement.d.ts +2 -1
- package/dist/core/tests/findElement.d.ts.map +1 -1
- package/dist/core/tests/findElement.js +59 -1
- package/dist/core/tests/findElement.js.map +1 -1
- package/dist/core/tests/runCode.d.ts.map +1 -1
- package/dist/core/tests/runCode.js +9 -0
- package/dist/core/tests/runCode.js.map +1 -1
- package/dist/core/tests/saveScreenshot.d.ts +2 -1
- package/dist/core/tests/saveScreenshot.d.ts.map +1 -1
- package/dist/core/tests/saveScreenshot.js +57 -12
- package/dist/core/tests/saveScreenshot.js.map +1 -1
- package/dist/core/tests/startRecording.d.ts +2 -1
- package/dist/core/tests/startRecording.d.ts.map +1 -1
- package/dist/core/tests/startRecording.js +11 -5
- package/dist/core/tests/startRecording.js.map +1 -1
- package/dist/core/tests/typeKeys.d.ts +2 -1
- package/dist/core/tests/typeKeys.d.ts.map +1 -1
- package/dist/core/tests/typeKeys.js +84 -4
- package/dist/core/tests/typeKeys.js.map +1 -1
- package/dist/core/tests.d.ts +9 -2
- package/dist/core/tests.d.ts.map +1 -1
- package/dist/core/tests.js +233 -32
- package/dist/core/tests.js.map +1 -1
- package/dist/core/utils.d.ts +14 -1
- package/dist/core/utils.d.ts.map +1 -1
- package/dist/core/utils.js +90 -1
- package/dist/core/utils.js.map +1 -1
- package/dist/index.cjs +87807 -6698
- package/dist/runtime/loader.d.ts +8 -0
- package/dist/runtime/loader.d.ts.map +1 -1
- package/dist/runtime/loader.js +10 -0
- package/dist/runtime/loader.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { resolveHeavyDepPath, resolveHeavyDepPathInCache, resolveHeavyDepSource, ensureRuntimeInstalled } from "../../runtime/loader.js";
|
|
2
|
+
export { classifyAppIdentifier, defaultAppSurfaceName, classifyNativeSelector, buildUiaLocator, createAppSessionState, appSurfacePreflight, isAppDriverRequired, stepTargetsAppSurface, resolveAppSurfaceRef, startAppSurface, findAppElement, buildAppLocator, closeAppSurface, teardownAppSession, invalidateStaleAppiumManifest, };
|
|
3
|
+
export type { AppSessionState, AppSurfaceEntry };
|
|
4
|
+
type AppIdentifierKind = "path" | "aumid" | "id";
|
|
5
|
+
declare function classifyAppIdentifier(app: string): AppIdentifierKind;
|
|
6
|
+
declare function defaultAppSurfaceName(app: string): string;
|
|
7
|
+
type NativeSelectorKind = "xpath" | "accessibilityId" | "css";
|
|
8
|
+
declare function classifyNativeSelector(selector: string): NativeSelectorKind;
|
|
9
|
+
declare function buildUiaLocator(criteria: {
|
|
10
|
+
elementText?: string;
|
|
11
|
+
elementId?: string;
|
|
12
|
+
elementTestId?: string;
|
|
13
|
+
elementAria?: {
|
|
14
|
+
role?: string;
|
|
15
|
+
name?: string;
|
|
16
|
+
} | string;
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
}): {
|
|
19
|
+
strategy: string;
|
|
20
|
+
value: string;
|
|
21
|
+
} | null;
|
|
22
|
+
interface AppSurfaceEntry {
|
|
23
|
+
name: string;
|
|
24
|
+
appId: string;
|
|
25
|
+
driver: any;
|
|
26
|
+
launchedByUs: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface AppSessionState {
|
|
29
|
+
server?: {
|
|
30
|
+
port: number;
|
|
31
|
+
process: any;
|
|
32
|
+
};
|
|
33
|
+
appiumEntry?: string;
|
|
34
|
+
appiumHome?: string;
|
|
35
|
+
surfaces: Map<string, AppSurfaceEntry>;
|
|
36
|
+
activeApp?: string;
|
|
37
|
+
recordingHost: {
|
|
38
|
+
state: {
|
|
39
|
+
recordings: any[];
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
declare function createAppSessionState(): AppSessionState;
|
|
44
|
+
declare function isAppDriverRequired({ test }: {
|
|
45
|
+
test: any;
|
|
46
|
+
}): boolean;
|
|
47
|
+
declare function stepTargetsAppSurface(step: any): boolean;
|
|
48
|
+
declare function resolveAppSurfaceRef(surface: any, appSession?: AppSessionState): {
|
|
49
|
+
entry?: AppSurfaceEntry;
|
|
50
|
+
window?: any;
|
|
51
|
+
error?: string;
|
|
52
|
+
} | null;
|
|
53
|
+
declare function invalidateStaleAppiumManifest(home: string): void;
|
|
54
|
+
declare function appSurfacePreflight({ config, platform, deps, }: {
|
|
55
|
+
config: any;
|
|
56
|
+
platform: string;
|
|
57
|
+
deps?: {
|
|
58
|
+
resolveSource?: typeof resolveHeavyDepSource;
|
|
59
|
+
resolvePath?: typeof resolveHeavyDepPath;
|
|
60
|
+
resolvePathInCache?: typeof resolveHeavyDepPathInCache;
|
|
61
|
+
ensureInstalled?: typeof ensureRuntimeInstalled;
|
|
62
|
+
};
|
|
63
|
+
}): Promise<{
|
|
64
|
+
ok: true;
|
|
65
|
+
appiumEntry: string;
|
|
66
|
+
appiumHome: string;
|
|
67
|
+
} | {
|
|
68
|
+
ok: false;
|
|
69
|
+
reason: string;
|
|
70
|
+
}>;
|
|
71
|
+
declare function buildAppLocator(criteria: {
|
|
72
|
+
selector?: string;
|
|
73
|
+
[key: string]: any;
|
|
74
|
+
}): {
|
|
75
|
+
strategy: string;
|
|
76
|
+
value: string;
|
|
77
|
+
} | {
|
|
78
|
+
error: string;
|
|
79
|
+
};
|
|
80
|
+
declare function findAppElement({ driver, criteria, timeout, }: {
|
|
81
|
+
driver: any;
|
|
82
|
+
criteria: any;
|
|
83
|
+
timeout?: number;
|
|
84
|
+
}): Promise<{
|
|
85
|
+
element?: any;
|
|
86
|
+
error?: string;
|
|
87
|
+
}>;
|
|
88
|
+
declare function startAppSurface({ config, step, appSession, platform, serverDeps, }: {
|
|
89
|
+
config: any;
|
|
90
|
+
step: any;
|
|
91
|
+
appSession: AppSessionState;
|
|
92
|
+
platform: string;
|
|
93
|
+
serverDeps: {
|
|
94
|
+
startServer: (appiumEntry: string, appiumHome: string) => Promise<{
|
|
95
|
+
port: number;
|
|
96
|
+
process: any;
|
|
97
|
+
}>;
|
|
98
|
+
startDriver: (capabilities: any, port: number) => Promise<any>;
|
|
99
|
+
};
|
|
100
|
+
}): Promise<any>;
|
|
101
|
+
declare function closeAppSurface({ entry, appSession, }: {
|
|
102
|
+
entry: AppSurfaceEntry;
|
|
103
|
+
appSession: AppSessionState;
|
|
104
|
+
}): Promise<void>;
|
|
105
|
+
declare function teardownAppSession(appSession: AppSessionState | undefined, killServer: (pid: number | undefined) => Promise<void>): Promise<void>;
|
|
106
|
+
//# sourceMappingURL=appSurface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appSurface.d.ts","sourceRoot":"","sources":["../../../src/core/tests/appSurface.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
// Native app surfaces (phase A1 of docs/design/native-app-surfaces.md).
|
|
2
|
+
// The top half is pure helpers — identifier classification, default surface
|
|
3
|
+
// naming, native-selector escape-hatch classification, and the per-platform
|
|
4
|
+
// semantic-locator mappings (A1 ships the Windows/UIA column) — unit-testable
|
|
5
|
+
// without a Windows host. The bottom half is the runtime: the per-context app
|
|
6
|
+
// session (its own Appium server, homed where the native driver is
|
|
7
|
+
// installed), the preflight that converts environment gaps into SKIPs, and
|
|
8
|
+
// the app-side implementations of startSurface / find / click / type /
|
|
9
|
+
// screenshot / closeSurface.
|
|
10
|
+
import fs from "node:fs";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { resolveHeavyDepPath, resolveHeavyDepPathInCache, resolveHeavyDepSource, ensureRuntimeInstalled, } from "../../runtime/loader.js";
|
|
13
|
+
import { appiumHomeForDriverPath } from "../appium.js";
|
|
14
|
+
import { getRuntimeDir } from "../../runtime/cacheDir.js";
|
|
15
|
+
import { log } from "../utils.js";
|
|
16
|
+
import { resolveCropGeometry } from "./ffmpegRecorder.js";
|
|
17
|
+
import { validate } from "../../common/src/validate.js";
|
|
18
|
+
export { classifyAppIdentifier, defaultAppSurfaceName, classifyNativeSelector, buildUiaLocator, createAppSessionState, appSurfacePreflight, isAppDriverRequired, stepTargetsAppSurface, resolveAppSurfaceRef, startAppSurface, findAppElement, buildAppLocator, closeAppSurface, teardownAppSession,
|
|
19
|
+
// Exported as a test seam: the manifest-staleness rules are load-bearing
|
|
20
|
+
// (a stale manifest makes the lazily-installed driver invisible to Appium).
|
|
21
|
+
invalidateStaleAppiumManifest, };
|
|
22
|
+
// Classify an `app` identifier by syntax — never by a user-supplied type enum:
|
|
23
|
+
// a `!` marks a UWP AppUserModelID, a path separator (or drive prefix) marks a
|
|
24
|
+
// filesystem path, a reverse-DNS token marks a bundle/package/desktop-file id,
|
|
25
|
+
// and anything else is treated as a (relative) executable path.
|
|
26
|
+
function classifyAppIdentifier(app) {
|
|
27
|
+
if (app.includes("!"))
|
|
28
|
+
return "aumid";
|
|
29
|
+
if (/[\\/]/.test(app) || /^[A-Za-z]:/.test(app))
|
|
30
|
+
return "path";
|
|
31
|
+
if (/^[A-Za-z0-9_-]+(\.[A-Za-z0-9_-]+){2,}$/.test(app))
|
|
32
|
+
return "id";
|
|
33
|
+
return "path";
|
|
34
|
+
}
|
|
35
|
+
// The default surface-registry name for an app: the executable basename
|
|
36
|
+
// without extension for paths (`notepad.exe` → `notepad`,
|
|
37
|
+
// `Calculator.app` → `Calculator`), the final dot-segment for reverse-DNS ids
|
|
38
|
+
// (`com.apple.TextEdit` → `TextEdit`), and the package family name's app token
|
|
39
|
+
// (before the publisher-hash suffix) for AUMIDs
|
|
40
|
+
// (`Microsoft.WindowsCalculator_8wekyb3d8bbwe!App` → `WindowsCalculator`).
|
|
41
|
+
function defaultAppSurfaceName(app) {
|
|
42
|
+
const kind = classifyAppIdentifier(app);
|
|
43
|
+
if (kind === "aumid") {
|
|
44
|
+
const familyName = app.split("!")[0];
|
|
45
|
+
const lastSegment = familyName.split(".").pop() ?? familyName;
|
|
46
|
+
return lastSegment.split("_")[0] || app;
|
|
47
|
+
}
|
|
48
|
+
if (kind === "id") {
|
|
49
|
+
return app.split(".").pop() || app;
|
|
50
|
+
}
|
|
51
|
+
const basename = app.split(/[\\/]/).pop() ?? app;
|
|
52
|
+
const withoutExtension = basename.replace(/\.[A-Za-z0-9]+$/, "");
|
|
53
|
+
return withoutExtension || basename;
|
|
54
|
+
}
|
|
55
|
+
// The `selector` escape hatch on app surfaces accepts platform-native
|
|
56
|
+
// locators, detected by syntax: `//…`/`(…` is XPath (every native driver
|
|
57
|
+
// speaks it), `~…` is an accessibility id. Anything else is CSS — browser-only,
|
|
58
|
+
// so callers reject it on app surfaces with a pointer to these forms.
|
|
59
|
+
function classifyNativeSelector(selector) {
|
|
60
|
+
if (selector.startsWith("//") || selector.startsWith("("))
|
|
61
|
+
return "xpath";
|
|
62
|
+
if (selector.startsWith("~"))
|
|
63
|
+
return "accessibilityId";
|
|
64
|
+
return "css";
|
|
65
|
+
}
|
|
66
|
+
// Escape a value for embedding in an XPath string literal. Values without
|
|
67
|
+
// double quotes embed directly; values with them use concat() (XPath 1.0 has
|
|
68
|
+
// no character escaping inside literals).
|
|
69
|
+
function xpathLiteral(value) {
|
|
70
|
+
if (!value.includes('"'))
|
|
71
|
+
return `"${value}"`;
|
|
72
|
+
const parts = value
|
|
73
|
+
.split('"')
|
|
74
|
+
.map((part) => `"${part}"`)
|
|
75
|
+
.join(`, '"', `);
|
|
76
|
+
return `concat(${parts})`;
|
|
77
|
+
}
|
|
78
|
+
// Map an ARIA-ish role to a UIA ControlType tag (XPath element name in the
|
|
79
|
+
// Windows driver's XML view). Unknown roles pass through capitalized so new
|
|
80
|
+
// control types work without a table update.
|
|
81
|
+
function uiaControlType(role) {
|
|
82
|
+
const known = {
|
|
83
|
+
button: "Button",
|
|
84
|
+
checkbox: "CheckBox",
|
|
85
|
+
combobox: "ComboBox",
|
|
86
|
+
dialog: "Window",
|
|
87
|
+
document: "Document",
|
|
88
|
+
link: "Hyperlink",
|
|
89
|
+
list: "List",
|
|
90
|
+
listitem: "ListItem",
|
|
91
|
+
menu: "Menu",
|
|
92
|
+
menuitem: "MenuItem",
|
|
93
|
+
radio: "RadioButton",
|
|
94
|
+
slider: "Slider",
|
|
95
|
+
tab: "TabItem",
|
|
96
|
+
table: "Table",
|
|
97
|
+
text: "Text",
|
|
98
|
+
textbox: "Edit",
|
|
99
|
+
toolbar: "ToolBar",
|
|
100
|
+
tree: "Tree",
|
|
101
|
+
treeitem: "TreeItem",
|
|
102
|
+
window: "Window",
|
|
103
|
+
};
|
|
104
|
+
return (known[role.toLowerCase()] ?? role.charAt(0).toUpperCase() + role.slice(1));
|
|
105
|
+
}
|
|
106
|
+
// Build a Windows (UIA) locator from the shared semantic element fields —
|
|
107
|
+
// the A1 column of the design's mapping table: elementText → @Name,
|
|
108
|
+
// elementId → AutomationId, elementAria → ControlType (+ @Name),
|
|
109
|
+
// elementTestId → AutomationId. Returns null when no supported field is
|
|
110
|
+
// present (the caller reports which fields ARE supported on app surfaces).
|
|
111
|
+
// A lone elementId/elementTestId uses the driver's "accessibility id"
|
|
112
|
+
// strategy (the AutomationId fast path); anything combined compiles to XPath.
|
|
113
|
+
function buildUiaLocator(criteria) {
|
|
114
|
+
const automationId = criteria.elementId ?? criteria.elementTestId;
|
|
115
|
+
const aria = typeof criteria.elementAria === "string"
|
|
116
|
+
? { name: criteria.elementAria }
|
|
117
|
+
: criteria.elementAria;
|
|
118
|
+
const predicates = [];
|
|
119
|
+
if (automationId !== undefined)
|
|
120
|
+
predicates.push(`@AutomationId=${xpathLiteral(automationId)}`);
|
|
121
|
+
if (criteria.elementText !== undefined)
|
|
122
|
+
predicates.push(`@Name=${xpathLiteral(criteria.elementText)}`);
|
|
123
|
+
// elementText and elementAria's name both map to @Name on Windows; when
|
|
124
|
+
// they carry the same value, one predicate suffices (two would be
|
|
125
|
+
// redundant; two DIFFERENT values are rejected upstream in buildAppLocator
|
|
126
|
+
// as an impossible match).
|
|
127
|
+
if (aria?.name !== undefined && aria.name !== criteria.elementText)
|
|
128
|
+
predicates.push(`@Name=${xpathLiteral(aria.name)}`);
|
|
129
|
+
const tag = aria?.role ? uiaControlType(aria.role) : undefined;
|
|
130
|
+
if (!tag && predicates.length === 0)
|
|
131
|
+
return null;
|
|
132
|
+
// Fast path: a lone AutomationId maps to the accessibility id strategy.
|
|
133
|
+
// (predicates.length === 1 with automationId set already implies no
|
|
134
|
+
// elementText/aria-name predicate joined it.)
|
|
135
|
+
if (automationId !== undefined && predicates.length === 1 && !tag) {
|
|
136
|
+
return { strategy: "accessibility id", value: automationId };
|
|
137
|
+
}
|
|
138
|
+
const predicate = predicates.length ? `[${predicates.join(" and ")}]` : "";
|
|
139
|
+
return { strategy: "xpath", value: `//${tag ?? "*"}${predicate}` };
|
|
140
|
+
}
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
// Runtime: app sessions, preflight, and app-side step implementations.
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
const APP_DRIVER_PACKAGE = "appium-novawindows-driver";
|
|
145
|
+
function createAppSessionState() {
|
|
146
|
+
return { surfaces: new Map(), recordingHost: { state: { recordings: [] } } };
|
|
147
|
+
}
|
|
148
|
+
// Steps that provision or (by object form) target an app surface. Used by
|
|
149
|
+
// runContext to decide whether the app preflight must run for this test.
|
|
150
|
+
function isAppDriverRequired({ test }) {
|
|
151
|
+
if (!Array.isArray(test?.steps))
|
|
152
|
+
return false;
|
|
153
|
+
return test.steps.some((step) => typeof step?.startSurface !== "undefined" || stepTargetsAppSurface(step));
|
|
154
|
+
}
|
|
155
|
+
// True when any action payload in the step names an app surface with the
|
|
156
|
+
// object form ({ app: … }). The bare-string form is identity-only and
|
|
157
|
+
// resolves against the registries at runtime instead.
|
|
158
|
+
function stepTargetsAppSurface(step) {
|
|
159
|
+
if (!step || typeof step !== "object")
|
|
160
|
+
return false;
|
|
161
|
+
return Object.values(step).some((payload) => payload &&
|
|
162
|
+
typeof payload === "object" &&
|
|
163
|
+
payload.surface &&
|
|
164
|
+
typeof payload.surface === "object" &&
|
|
165
|
+
typeof payload.surface.app === "string");
|
|
166
|
+
}
|
|
167
|
+
// Resolve a step's `surface` reference to a registered app surface, or null
|
|
168
|
+
// when the reference isn't an app reference (browser/process/engine) or names
|
|
169
|
+
// nothing in the registry. Object form is authoritative; a bare string only
|
|
170
|
+
// matches when the registry actually holds that name.
|
|
171
|
+
function resolveAppSurfaceRef(surface, appSession) {
|
|
172
|
+
if (!appSession)
|
|
173
|
+
return null;
|
|
174
|
+
if (surface && typeof surface === "object" && typeof surface.app === "string") {
|
|
175
|
+
const entry = appSession.surfaces.get(surface.app.trim());
|
|
176
|
+
if (!entry) {
|
|
177
|
+
return {
|
|
178
|
+
error: `No app surface named "${surface.app}" is open. Open it first with startSurface.`,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
return { entry, window: surface.window };
|
|
182
|
+
}
|
|
183
|
+
if (typeof surface === "string") {
|
|
184
|
+
const entry = appSession.surfaces.get(surface.trim());
|
|
185
|
+
if (entry)
|
|
186
|
+
return { entry };
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
// Appium discovers extensions by scanning <APPIUM_HOME>/node_modules — but
|
|
191
|
+
// only when its manifest cache (node_modules/.cache/appium/extensions.yaml)
|
|
192
|
+
// doesn't exist yet; an existing manifest is trusted as-is. A driver
|
|
193
|
+
// lazy-installed into a home whose manifest predates it is therefore
|
|
194
|
+
// invisible ("Could not find a driver for automationName …") even though the
|
|
195
|
+
// package is right there. Deleting the manifest cache makes the next server
|
|
196
|
+
// start rebuild it from what's actually installed. No-op when the manifest
|
|
197
|
+
// is absent or already lists the driver.
|
|
198
|
+
function invalidateStaleAppiumManifest(home) {
|
|
199
|
+
const cacheDir = path.join(home, "node_modules", ".cache", "appium");
|
|
200
|
+
try {
|
|
201
|
+
const manifest = fs.readFileSync(path.join(cacheDir, "extensions.yaml"), "utf8");
|
|
202
|
+
if (!manifest.includes(APP_DRIVER_PACKAGE)) {
|
|
203
|
+
fs.rmSync(cacheDir, { recursive: true, force: true });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// Manifest absent/unreadable — appium builds it fresh on start.
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Preflight for app surfaces: platform support and driver availability.
|
|
211
|
+
// Returns { ok: true } or a skip reason — an unmet environment is a gating
|
|
212
|
+
// fact (SKIPPED), never a FAIL, matching the `requires` gate semantics.
|
|
213
|
+
// Installing the driver (and, when needed, an Appium copy in the same home)
|
|
214
|
+
// happens here so the failure mode is a clean skip before any step runs.
|
|
215
|
+
async function appSurfacePreflight({ config, platform, deps = {}, }) {
|
|
216
|
+
if (platform !== "windows") {
|
|
217
|
+
return {
|
|
218
|
+
ok: false,
|
|
219
|
+
reason: `Skipping context on '${platform}': native app surfaces run on Windows only in this phase. Gate the test with runOn platforms (["windows"]) so this skip is intentional.`,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const ctx = { cacheDir: config?.cacheDir };
|
|
223
|
+
const resolveSource = deps.resolveSource ?? resolveHeavyDepSource;
|
|
224
|
+
const resolvePath = deps.resolvePath ?? resolveHeavyDepPath;
|
|
225
|
+
const resolvePathInCache = deps.resolvePathInCache ?? resolveHeavyDepPathInCache;
|
|
226
|
+
const ensureInstalled = deps.ensureInstalled ?? ensureRuntimeInstalled;
|
|
227
|
+
let source = resolveSource(APP_DRIVER_PACKAGE, ctx);
|
|
228
|
+
if (!source) {
|
|
229
|
+
try {
|
|
230
|
+
await ensureInstalled([APP_DRIVER_PACKAGE], { ctx });
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
return {
|
|
234
|
+
ok: false,
|
|
235
|
+
reason: `Skipping context: the Windows app driver (${APP_DRIVER_PACKAGE}) is not installed and could not be installed (${error?.message ?? error}). Install it with \`doc-detective install runtime ${APP_DRIVER_PACKAGE}\` or check network access.`,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
source = resolveSource(APP_DRIVER_PACKAGE, ctx);
|
|
239
|
+
if (!source) {
|
|
240
|
+
return {
|
|
241
|
+
ok: false,
|
|
242
|
+
reason: `Skipping context: the Windows app driver (${APP_DRIVER_PACKAGE}) did not resolve after install. Inspect the runtime cache and reinstall with \`doc-detective install runtime ${APP_DRIVER_PACKAGE}\`.`,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// Appium discovers drivers in <APPIUM_HOME>/node_modules, so the server
|
|
247
|
+
// must be homed where the driver actually lives. A shim-resolved driver
|
|
248
|
+
// shares the shim's home with appium; a cache-resolved driver needs an
|
|
249
|
+
// appium copy in the cache too (a one-time install).
|
|
250
|
+
if (source === "shim") {
|
|
251
|
+
const driverEntry = resolvePath(APP_DRIVER_PACKAGE, ctx);
|
|
252
|
+
const home = driverEntry ? appiumHomeForDriverPath(driverEntry) : null;
|
|
253
|
+
const appiumEntry = resolvePath("appium", ctx);
|
|
254
|
+
if (home && appiumEntry) {
|
|
255
|
+
invalidateStaleAppiumManifest(home);
|
|
256
|
+
return { ok: true, appiumEntry, appiumHome: home };
|
|
257
|
+
}
|
|
258
|
+
// Fall through to the cache path when the shim layout is unexpected —
|
|
259
|
+
// logged so a spurious cache-side Appium install is diagnosable.
|
|
260
|
+
log(config, "debug", `The Windows app driver resolved from the shim but its Appium home/entry did not (home: ${home}, appium: ${appiumEntry}); falling back to a cache-side Appium install.`);
|
|
261
|
+
}
|
|
262
|
+
if (!resolvePathInCache("appium", ctx)) {
|
|
263
|
+
try {
|
|
264
|
+
await ensureInstalled(["appium"], { ctx, force: true });
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
return {
|
|
268
|
+
ok: false,
|
|
269
|
+
reason: `Skipping context: Appium could not be installed alongside the Windows app driver (${error?.message ?? error}).`,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
const appiumEntry = resolvePathInCache("appium", ctx);
|
|
274
|
+
if (!appiumEntry) {
|
|
275
|
+
return {
|
|
276
|
+
ok: false,
|
|
277
|
+
reason: `Skipping context: Appium did not resolve from the runtime cache after install.`,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
const appiumHome = getRuntimeDir(ctx);
|
|
281
|
+
invalidateStaleAppiumManifest(appiumHome);
|
|
282
|
+
return { ok: true, appiumEntry, appiumHome };
|
|
283
|
+
}
|
|
284
|
+
// Build a driver locator from a step's element criteria (the shared semantic
|
|
285
|
+
// fields) or the native `selector` escape hatch. Returns the locator or an
|
|
286
|
+
// error message naming what is unsupported on app surfaces.
|
|
287
|
+
function buildAppLocator(criteria) {
|
|
288
|
+
if (typeof criteria.selector === "string") {
|
|
289
|
+
const kind = classifyNativeSelector(criteria.selector);
|
|
290
|
+
if (kind === "xpath")
|
|
291
|
+
return { strategy: "xpath", value: criteria.selector };
|
|
292
|
+
if (kind === "accessibilityId")
|
|
293
|
+
return {
|
|
294
|
+
strategy: "accessibility id",
|
|
295
|
+
value: criteria.selector.slice(1),
|
|
296
|
+
};
|
|
297
|
+
return {
|
|
298
|
+
error: `CSS selectors are browser-only. On app surfaces, use the semantic fields (elementText, elementId, elementAria) or a native locator: an XPath (//Button[@Name="Save"]) or an accessibility id (~SaveButton).`,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
const unsupported = ["elementClass", "elementAttribute"].filter((field) => criteria[field] !== undefined);
|
|
302
|
+
if (unsupported.length) {
|
|
303
|
+
return {
|
|
304
|
+
error: `${unsupported.join(" and ")} ${unsupported.length > 1 ? "are" : "is"} not supported on app surfaces; use elementText, elementId, elementAria, or a native selector.`,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
// elementText and elementAria's accessible name both map to the SAME
|
|
308
|
+
// property (@Name) on Windows, so two different values can never match one
|
|
309
|
+
// element — surface the conflict instead of failing silently as not-found.
|
|
310
|
+
const ariaName = typeof criteria.elementAria === "string"
|
|
311
|
+
? criteria.elementAria
|
|
312
|
+
: criteria.elementAria?.name;
|
|
313
|
+
if (criteria.elementText !== undefined &&
|
|
314
|
+
ariaName !== undefined &&
|
|
315
|
+
criteria.elementText !== ariaName) {
|
|
316
|
+
return {
|
|
317
|
+
error: `elementText ("${criteria.elementText}") and elementAria ("${ariaName}") both map to the accessible Name on app surfaces but have different values — no element can match both. Specify one of them.`,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
const locator = buildUiaLocator(criteria);
|
|
321
|
+
if (!locator) {
|
|
322
|
+
return {
|
|
323
|
+
error: "No app-mappable element criteria specified. Use elementText, elementId, elementTestId, elementAria, or a native selector.",
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
return locator;
|
|
327
|
+
}
|
|
328
|
+
// Locate an element on an app surface's driver session. Waits up to `timeout`
|
|
329
|
+
// for existence. Returns the wdio element or an error string.
|
|
330
|
+
async function findAppElement({ driver, criteria, timeout = 5000, }) {
|
|
331
|
+
const locator = buildAppLocator(criteria);
|
|
332
|
+
if ("error" in locator)
|
|
333
|
+
return { error: locator.error };
|
|
334
|
+
const selector = locator.strategy === "accessibility id"
|
|
335
|
+
? `~${locator.value}`
|
|
336
|
+
: locator.value;
|
|
337
|
+
// Locate and wait in separate try blocks: driver.$() normally returns a
|
|
338
|
+
// lazy handle without touching the session, so a throw there means the
|
|
339
|
+
// session itself is broken (app crash, dead server) — a driver error, not
|
|
340
|
+
// a criteria miss. Only the waitForExist timeout is the not-found path.
|
|
341
|
+
let element;
|
|
342
|
+
try {
|
|
343
|
+
element = await driver.$(selector);
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
return {
|
|
347
|
+
error: `App driver error while locating an element (locator: ${selector}): ${error?.message ?? error}`,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
try {
|
|
351
|
+
await element.waitForExist({ timeout });
|
|
352
|
+
return { element };
|
|
353
|
+
}
|
|
354
|
+
catch {
|
|
355
|
+
return {
|
|
356
|
+
error: `No element matched ${JSON.stringify(criteria)} on the app surface within ${timeout}ms (locator: ${selector}).`,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// The startSurface step (app branch): launch the app through the native
|
|
361
|
+
// driver, wait for readiness, and register the surface. Starts the app
|
|
362
|
+
// session's Appium server on first use.
|
|
363
|
+
async function startAppSurface({ config, step, appSession, platform, serverDeps, }) {
|
|
364
|
+
const result = { status: "PASS", description: "", outputs: {} };
|
|
365
|
+
// Validate the step payload like every other handler, so a malformed
|
|
366
|
+
// descriptor (e.g. missing `app`) fails cleanly instead of throwing.
|
|
367
|
+
const isValidStep = validate({ schemaKey: "step_v3", object: step });
|
|
368
|
+
if (!isValidStep.valid) {
|
|
369
|
+
result.status = "FAIL";
|
|
370
|
+
result.description = `Invalid step definition: ${isValidStep.errors}`;
|
|
371
|
+
return result;
|
|
372
|
+
}
|
|
373
|
+
step = isValidStep.object;
|
|
374
|
+
const descriptor = step.startSurface;
|
|
375
|
+
// Reserved fields land in later phases — fail with the roadmap named
|
|
376
|
+
// rather than silently ignoring what the author asked for.
|
|
377
|
+
for (const field of ["device", "install", "activity"]) {
|
|
378
|
+
if (descriptor[field] !== undefined) {
|
|
379
|
+
result.status = "FAIL";
|
|
380
|
+
result.description = `startSurface.${field} is reserved for the mobile phases of the native app roadmap (docs/design/native-app-surfaces.md) and is not implemented yet.`;
|
|
381
|
+
return result;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (descriptor.env !== undefined) {
|
|
385
|
+
result.status = "FAIL";
|
|
386
|
+
result.description = `startSurface.env is not supported by the Windows app driver. Set environment variables in the shell that launches Doc Detective, or launch the app via runShell instead.`;
|
|
387
|
+
return result;
|
|
388
|
+
}
|
|
389
|
+
if (platform !== "windows") {
|
|
390
|
+
result.status = "FAIL";
|
|
391
|
+
result.description = `startSurface (app) runs on Windows only in this phase. Gate the test with runOn platforms (["windows"]).`;
|
|
392
|
+
return result;
|
|
393
|
+
}
|
|
394
|
+
const appId = descriptor.app.trim();
|
|
395
|
+
const name = (descriptor.name ?? defaultAppSurfaceName(appId)).trim();
|
|
396
|
+
if (appSession.surfaces.has(name)) {
|
|
397
|
+
result.status = "FAIL";
|
|
398
|
+
result.description = `An app surface named "${name}" is already open. Pass a distinct startSurface.name.`;
|
|
399
|
+
return result;
|
|
400
|
+
}
|
|
401
|
+
// First app surface in this context: bring up the app Appium server.
|
|
402
|
+
if (!appSession.server) {
|
|
403
|
+
if (!appSession.appiumEntry || !appSession.appiumHome) {
|
|
404
|
+
result.status = "FAIL";
|
|
405
|
+
result.description =
|
|
406
|
+
"App session is not preflighted; this is a runner bug (runContext must run appSurfacePreflight before app steps).";
|
|
407
|
+
return result;
|
|
408
|
+
}
|
|
409
|
+
try {
|
|
410
|
+
appSession.server = await serverDeps.startServer(appSession.appiumEntry, appSession.appiumHome);
|
|
411
|
+
}
|
|
412
|
+
catch (error) {
|
|
413
|
+
// Post-preflight server-start failures (port race, resource pressure)
|
|
414
|
+
// become a clean step FAIL instead of a context-level exception.
|
|
415
|
+
result.status = "FAIL";
|
|
416
|
+
result.description = `Couldn't start the app automation server: ${error?.message ?? error}`;
|
|
417
|
+
return result;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
const capabilities = {
|
|
421
|
+
platformName: "Windows",
|
|
422
|
+
"appium:automationName": "NovaWindows",
|
|
423
|
+
"appium:app": appId,
|
|
424
|
+
"appium:newCommandTimeout": 600,
|
|
425
|
+
"wdio:enforceWebDriverClassic": true,
|
|
426
|
+
};
|
|
427
|
+
if (Array.isArray(descriptor.args) && descriptor.args.length) {
|
|
428
|
+
// NovaWindows (like WinAppDriver) takes appArguments as a single string.
|
|
429
|
+
capabilities["appium:appArguments"] = descriptor.args.join(" ");
|
|
430
|
+
}
|
|
431
|
+
if (descriptor.workingDirectory && descriptor.workingDirectory !== ".") {
|
|
432
|
+
capabilities["appium:appWorkingDir"] = path.resolve(descriptor.workingDirectory);
|
|
433
|
+
}
|
|
434
|
+
Object.assign(capabilities, descriptor.driverOptions ?? {});
|
|
435
|
+
let driver;
|
|
436
|
+
try {
|
|
437
|
+
driver = await serverDeps.startDriver(capabilities, appSession.server.port);
|
|
438
|
+
}
|
|
439
|
+
catch (error) {
|
|
440
|
+
result.status = "FAIL";
|
|
441
|
+
result.description = `Couldn't launch app "${appId}": ${error?.message ?? error}. Check the path/AUMID and that the session is interactive.`;
|
|
442
|
+
return result;
|
|
443
|
+
}
|
|
444
|
+
// Startup readiness: fixed delay and/or an element that must exist.
|
|
445
|
+
const timeout = descriptor.timeout ?? 60000;
|
|
446
|
+
if (descriptor.waitUntil?.delayMs) {
|
|
447
|
+
await new Promise((resolve) => setTimeout(resolve, descriptor.waitUntil.delayMs));
|
|
448
|
+
}
|
|
449
|
+
if (descriptor.waitUntil?.find) {
|
|
450
|
+
const found = await findAppElement({
|
|
451
|
+
driver,
|
|
452
|
+
criteria: descriptor.waitUntil.find,
|
|
453
|
+
timeout,
|
|
454
|
+
});
|
|
455
|
+
if (found.error) {
|
|
456
|
+
try {
|
|
457
|
+
await driver.deleteSession();
|
|
458
|
+
}
|
|
459
|
+
catch {
|
|
460
|
+
// best-effort: the launch failed readiness; don't mask that error
|
|
461
|
+
}
|
|
462
|
+
result.status = "FAIL";
|
|
463
|
+
result.description = `App "${appId}" launched but never became ready: ${found.error}`;
|
|
464
|
+
return result;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
appSession.surfaces.set(name, {
|
|
468
|
+
name,
|
|
469
|
+
appId,
|
|
470
|
+
driver,
|
|
471
|
+
launchedByUs: true,
|
|
472
|
+
});
|
|
473
|
+
appSession.activeApp = name;
|
|
474
|
+
// Late-bind window crops: an autoRecord capture in an app-only context
|
|
475
|
+
// starts before any app window exists, so it records the full display with
|
|
476
|
+
// a pending marker. The first app surface to open supplies its window rect
|
|
477
|
+
// as the crop — scoping the recording to the app under test — which the
|
|
478
|
+
// stop-side transcode then applies.
|
|
479
|
+
const pendingHandles = (appSession.recordingHost?.state?.recordings ?? []).filter((handle) => handle?.pendingAppWindowCrop && !handle.crop);
|
|
480
|
+
for (const handle of pendingHandles) {
|
|
481
|
+
try {
|
|
482
|
+
handle.crop = await resolveCropGeometry({ driver, target: "window" });
|
|
483
|
+
handle.pendingAppWindowCrop = false;
|
|
484
|
+
}
|
|
485
|
+
catch (error) {
|
|
486
|
+
log(config, "warning", `Couldn't resolve the app window geometry for the active recording; it stays full-display. ${error?.message ?? error}`);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
log(config, "debug", `Opened app surface "${name}" (${appId}).`);
|
|
490
|
+
result.description = `Opened app surface "${name}" (${appId}).`;
|
|
491
|
+
result.outputs = { name, app: appId };
|
|
492
|
+
return result;
|
|
493
|
+
}
|
|
494
|
+
// Close a registered app surface: end its driver session (which terminates
|
|
495
|
+
// the app when the driver launched it) and deregister it.
|
|
496
|
+
async function closeAppSurface({ entry, appSession, }) {
|
|
497
|
+
appSession.surfaces.delete(entry.name);
|
|
498
|
+
if (appSession.activeApp === entry.name)
|
|
499
|
+
appSession.activeApp = undefined;
|
|
500
|
+
try {
|
|
501
|
+
await entry.driver.deleteSession();
|
|
502
|
+
}
|
|
503
|
+
catch {
|
|
504
|
+
// Idempotent: the app/session may already be gone.
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
// Context teardown: close every remaining app surface, then stop the app
|
|
508
|
+
// session's Appium server. Killing only what we launched is the driver's
|
|
509
|
+
// contract (deleteSession terminates driver-launched apps).
|
|
510
|
+
async function teardownAppSession(appSession, killServer) {
|
|
511
|
+
if (!appSession)
|
|
512
|
+
return;
|
|
513
|
+
for (const entry of [...appSession.surfaces.values()]) {
|
|
514
|
+
await closeAppSurface({ entry, appSession });
|
|
515
|
+
}
|
|
516
|
+
if (appSession.server) {
|
|
517
|
+
await killServer(appSession.server.process?.pid);
|
|
518
|
+
appSession.server = undefined;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
//# sourceMappingURL=appSurface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appSurface.js","sourceRoot":"","sources":["../../../src/core/tests/appSurface.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,4EAA4E;AAC5E,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,mEAAmE;AACnE,2EAA2E;AAC3E,uEAAuE;AACvE,6BAA6B;AAE7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAExD,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,eAAe,EACf,eAAe,EACf,kBAAkB;AAClB,yEAAyE;AACzE,4EAA4E;AAC5E,6BAA6B,GAC9B,CAAC;AAKF,+EAA+E;AAC/E,+EAA+E;AAC/E,+EAA+E;AAC/E,gEAAgE;AAChE,SAAS,qBAAqB,CAAC,GAAW;IACxC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IACtC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/D,IAAI,wCAAwC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,wEAAwE;AACxE,0DAA0D;AAC1D,8EAA8E;AAC9E,+EAA+E;AAC/E,gDAAgD;AAChD,2EAA2E;AAC3E,SAAS,qBAAqB,CAAC,GAAW;IACxC,MAAM,IAAI,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,UAAU,CAAC;QAC9D,OAAO,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;IAC1C,CAAC;IACD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC;IACrC,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC;IACjD,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACjE,OAAO,gBAAgB,IAAI,QAAQ,CAAC;AACtC,CAAC;AAID,sEAAsE;AACtE,yEAAyE;AACzE,gFAAgF;AAChF,sEAAsE;AACtE,SAAS,sBAAsB,CAAC,QAAgB;IAC9C,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1E,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,iBAAiB,CAAC;IACvD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0EAA0E;AAC1E,6EAA6E;AAC7E,0CAA0C;AAC1C,SAAS,YAAY,CAAC,KAAa;IACjC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,KAAK,GAAG,CAAC;IAC9C,MAAM,KAAK,GAAG,KAAK;SAChB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,GAAG,CAAC;SAC1B,IAAI,CAAC,SAAS,CAAC,CAAC;IACnB,OAAO,UAAU,KAAK,GAAG,CAAC;AAC5B,CAAC;AAED,2EAA2E;AAC3E,4EAA4E;AAC5E,6CAA6C;AAC7C,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,KAAK,GAA2B;QACpC,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE,UAAU;QACpB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,UAAU;QACpB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,UAAU;QACpB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,UAAU;QACpB,KAAK,EAAE,aAAa;QACpB,MAAM,EAAE,QAAQ;QAChB,GAAG,EAAE,SAAS;QACd,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,MAAM;QACf,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,UAAU;QACpB,MAAM,EAAE,QAAQ;KACjB,CAAC;IACF,OAAO,CACL,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAC1E,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,oEAAoE;AACpE,iEAAiE;AACjE,wEAAwE;AACxE,2EAA2E;AAC3E,sEAAsE;AACtE,8EAA8E;AAC9E,SAAS,eAAe,CAAC,QAMxB;IACC,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,aAAa,CAAC;IAClE,MAAM,IAAI,GACR,OAAO,QAAQ,CAAC,WAAW,KAAK,QAAQ;QACtC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,WAAW,EAAE;QAChC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;IAE3B,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,IAAI,YAAY,KAAK,SAAS;QAC5B,UAAU,CAAC,IAAI,CAAC,iBAAiB,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACjE,IAAI,QAAQ,CAAC,WAAW,KAAK,SAAS;QACpC,UAAU,CAAC,IAAI,CAAC,SAAS,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACjE,wEAAwE;IACxE,kEAAkE;IAClE,2EAA2E;IAC3E,2BAA2B;IAC3B,IAAI,IAAI,EAAE,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,WAAW;QAChE,UAAU,CAAC,IAAI,CAAC,SAAS,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEtD,MAAM,GAAG,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE/D,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjD,wEAAwE;IACxE,oEAAoE;IACpE,8CAA8C;IAC9C,IAAI,YAAY,KAAK,SAAS,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAClE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAC/D,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,GAAG,SAAS,EAAE,EAAE,CAAC;AACrE,CAAC;AAED,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAE9E,MAAM,kBAAkB,GAAG,2BAA2B,CAAC;AAyBvD,SAAS,qBAAqB;IAC5B,OAAO,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,EAAE,aAAa,EAAE,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAC/E,CAAC;AAED,0EAA0E;AAC1E,yEAAyE;AACzE,SAAS,mBAAmB,CAAC,EAAE,IAAI,EAAiB;IAClD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CACpB,CAAC,IAAS,EAAE,EAAE,CACZ,OAAO,IAAI,EAAE,YAAY,KAAK,WAAW,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,sEAAsE;AACtE,sDAAsD;AACtD,SAAS,qBAAqB,CAAC,IAAS;IACtC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAC7B,CAAC,OAAY,EAAE,EAAE,CACf,OAAO;QACP,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,CAAC,OAAO;QACf,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ;QACnC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,QAAQ,CAC1C,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,8EAA8E;AAC9E,4EAA4E;AAC5E,sDAAsD;AACtD,SAAS,oBAAoB,CAC3B,OAAY,EACZ,UAA4B;IAE5B,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC9E,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,KAAK,EAAE,yBAAyB,OAAO,CAAC,GAAG,6CAA6C;aACzF,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;IAC3C,CAAC;IACD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACtD,IAAI,KAAK;YAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,2EAA2E;AAC3E,4EAA4E;AAC5E,qEAAqE;AACrE,qEAAqE;AACrE,6EAA6E;AAC7E,4EAA4E;AAC5E,2EAA2E;AAC3E,yCAAyC;AACzC,SAAS,6BAA6B,CAAC,IAAY;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACrE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAC9B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,EACtC,MAAM,CACP,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC3C,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;IAClE,CAAC;AACH,CAAC;AAED,wEAAwE;AACxE,2EAA2E;AAC3E,wEAAwE;AACxE,4EAA4E;AAC5E,yEAAyE;AACzE,KAAK,UAAU,mBAAmB,CAAC,EACjC,MAAM,EACN,QAAQ,EACR,IAAI,GAAG,EAAE,GAUV;IAIC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,wBAAwB,QAAQ,yIAAyI;SAClL,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC3C,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,qBAAqB,CAAC;IAClE,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,mBAAmB,CAAC;IAC5D,MAAM,kBAAkB,GACtB,IAAI,CAAC,kBAAkB,IAAI,0BAA0B,CAAC;IACxD,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,sBAAsB,CAAC;IAEvE,IAAI,MAAM,GAAG,aAAa,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,CAAC,kBAAkB,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,6CAA6C,kBAAkB,kDAAkD,KAAK,EAAE,OAAO,IAAI,KAAK,sDAAsD,kBAAkB,6BAA6B;aACtP,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,aAAa,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,6CAA6C,kBAAkB,iHAAiH,kBAAkB,KAAK;aAChN,CAAC;QACJ,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,wEAAwE;IACxE,uEAAuE;IACvE,qDAAqD;IACrD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,WAAW,GAAG,WAAW,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACvE,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC/C,IAAI,IAAI,IAAI,WAAW,EAAE,CAAC;YACxB,6BAA6B,CAAC,IAAI,CAAC,CAAC;YACpC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QACrD,CAAC;QACD,sEAAsE;QACtE,iEAAiE;QACjE,GAAG,CACD,MAAM,EACN,OAAO,EACP,0FAA0F,IAAI,aAAa,WAAW,iDAAiD,CACxK,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,qFAAqF,KAAK,EAAE,OAAO,IAAI,KAAK,IAAI;aACzH,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,WAAW,GAAG,kBAAkB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACtD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,gFAAgF;SACzF,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACtC,6BAA6B,CAAC,UAAU,CAAC,CAAC;IAC1C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AAC/C,CAAC;AAED,6EAA6E;AAC7E,2EAA2E;AAC3E,4DAA4D;AAC5D,SAAS,eAAe,CAAC,QAGxB;IACC,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,sBAAsB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,IAAI,KAAK,OAAO;YAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC7E,IAAI,IAAI,KAAK,iBAAiB;YAC5B,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;aAClC,CAAC;QACJ,OAAO;YACL,KAAK,EAAE,6MAA6M;SACrN,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC,MAAM,CAC7D,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,SAAS,CACzC,CAAC;IACF,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;QACvB,OAAO;YACL,KAAK,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,gGAAgG;SAC7K,CAAC;IACJ,CAAC;IACD,qEAAqE;IACrE,2EAA2E;IAC3E,2EAA2E;IAC3E,MAAM,QAAQ,GACZ,OAAO,QAAQ,CAAC,WAAW,KAAK,QAAQ;QACtC,CAAC,CAAC,QAAQ,CAAC,WAAW;QACtB,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IACjC,IACE,QAAQ,CAAC,WAAW,KAAK,SAAS;QAClC,QAAQ,KAAK,SAAS;QACtB,QAAQ,CAAC,WAAW,KAAK,QAAQ,EACjC,CAAC;QACD,OAAO;YACL,KAAK,EAAE,iBAAiB,QAAQ,CAAC,WAAW,wBAAwB,QAAQ,gIAAgI;SAC7M,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,KAAK,EACH,2HAA2H;SAC9H,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8EAA8E;AAC9E,8DAA8D;AAC9D,KAAK,UAAU,cAAc,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,OAAO,GAAG,IAAI,GAKf;IACC,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,OAAO,IAAI,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;IACxD,MAAM,QAAQ,GACZ,OAAO,CAAC,QAAQ,KAAK,kBAAkB;QACrC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE;QACrB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACpB,wEAAwE;IACxE,uEAAuE;IACvE,0EAA0E;IAC1E,wEAAwE;IACxE,IAAI,OAAY,CAAC;IACjB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO;YACL,KAAK,EAAE,wDAAwD,QAAQ,MAAM,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE;SACvG,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACxC,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,KAAK,EAAE,sBAAsB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,8BAA8B,OAAO,gBAAgB,QAAQ,IAAI;SACvH,CAAC;IACJ,CAAC;AACH,CAAC;AAED,wEAAwE;AACxE,uEAAuE;AACvE,wCAAwC;AACxC,KAAK,UAAU,eAAe,CAAC,EAC7B,MAAM,EACN,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,UAAU,GAgBX;IACC,MAAM,MAAM,GAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAErE,qEAAqE;IACrE,qEAAqE;IACrE,MAAM,WAAW,GAAG,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,MAAM,CAAC,WAAW,GAAG,4BAA4B,WAAW,CAAC,MAAM,EAAE,CAAC;QACtE,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC;IAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC;IAErC,qEAAqE;IACrE,2DAA2D;IAC3D,KAAK,MAAM,KAAK,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;QACtD,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACvB,MAAM,CAAC,WAAW,GAAG,gBAAgB,KAAK,+HAA+H,CAAC;YAC1K,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,MAAM,CAAC,WAAW,GAAG,0KAA0K,CAAC;QAChM,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,MAAM,CAAC,WAAW,GAAG,0GAA0G,CAAC;QAChI,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACtE,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,MAAM,CAAC,WAAW,GAAG,yBAAyB,IAAI,uDAAuD,CAAC;QAC1G,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,qEAAqE;IACrE,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,CAAC,WAAW,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;YACtD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACvB,MAAM,CAAC,WAAW;gBAChB,kHAAkH,CAAC;YACrH,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,CAAC;YACH,UAAU,CAAC,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CAC9C,UAAU,CAAC,WAAW,EACtB,UAAU,CAAC,UAAU,CACtB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,sEAAsE;YACtE,iEAAiE;YACjE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACvB,MAAM,CAAC,WAAW,GAAG,6CAA6C,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC;YAC5F,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAwB;QACxC,YAAY,EAAE,SAAS;QACvB,uBAAuB,EAAE,aAAa;QACtC,YAAY,EAAE,KAAK;QACnB,0BAA0B,EAAE,GAAG;QAC/B,8BAA8B,EAAE,IAAI;KACrC,CAAC;IACF,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7D,yEAAyE;QACzE,YAAY,CAAC,qBAAqB,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,UAAU,CAAC,gBAAgB,IAAI,UAAU,CAAC,gBAAgB,KAAK,GAAG,EAAE,CAAC;QACvE,YAAY,CAAC,sBAAsB,CAAC,GAAG,IAAI,CAAC,OAAO,CACjD,UAAU,CAAC,gBAAgB,CAC5B,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IAE5D,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CACnC,YAAY,EACZ,UAAU,CAAC,MAAM,CAAC,IAAI,CACvB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,MAAM,CAAC,WAAW,GAAG,wBAAwB,KAAK,MAAM,KAAK,EAAE,OAAO,IAAI,KAAK,6DAA6D,CAAC;QAC7I,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,oEAAoE;IACpE,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,IAAI,KAAK,CAAC;IAC5C,IAAI,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;QAClC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC5B,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAClD,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC;YACjC,MAAM;YACN,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC,IAAI;YACnC,OAAO;SACR,CAAC,CAAC;QACH,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,kEAAkE;YACpE,CAAC;YACD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACvB,MAAM,CAAC,WAAW,GAAG,QAAQ,KAAK,sCAAsC,KAAK,CAAC,KAAK,EAAE,CAAC;YACtF,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE;QAC5B,IAAI;QACJ,KAAK;QACL,MAAM;QACN,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;IACH,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC;IAE5B,uEAAuE;IACvE,2EAA2E;IAC3E,2EAA2E;IAC3E,wEAAwE;IACxE,oCAAoC;IACpC,MAAM,cAAc,GAAG,CACrB,UAAU,CAAC,aAAa,EAAE,KAAK,EAAE,UAAU,IAAI,EAAE,CAClD,CAAC,MAAM,CAAC,CAAC,MAAW,EAAE,EAAE,CAAC,MAAM,EAAE,oBAAoB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACxE,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,GAAG,MAAM,mBAAmB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YACtE,MAAM,CAAC,oBAAoB,GAAG,KAAK,CAAC;QACtC,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,GAAG,CACD,MAAM,EACN,SAAS,EACT,6FAA6F,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,CACvH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,uBAAuB,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC;IACjE,MAAM,CAAC,WAAW,GAAG,uBAAuB,IAAI,MAAM,KAAK,IAAI,CAAC;IAChE,MAAM,CAAC,OAAO,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IACtC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,2EAA2E;AAC3E,0DAA0D;AAC1D,KAAK,UAAU,eAAe,CAAC,EAC7B,KAAK,EACL,UAAU,GAIX;IACC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,UAAU,CAAC,SAAS,KAAK,KAAK,CAAC,IAAI;QAAE,UAAU,CAAC,SAAS,GAAG,SAAS,CAAC;IAC1E,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,mDAAmD;IACrD,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,yEAAyE;AACzE,4DAA4D;AAC5D,KAAK,UAAU,kBAAkB,CAC/B,UAAuC,EACvC,UAAsD;IAEtD,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QACtD,MAAM,eAAe,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACjD,UAAU,CAAC,MAAM,GAAG,SAAS,CAAC;IAChC,CAAC;AACH,CAAC"}
|