@e2edev/e2e 0.9.0 → 0.11.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.
Files changed (230) hide show
  1. package/README.md +12 -6
  2. package/dist/agent/act-validation.d.ts +2 -0
  3. package/dist/agent/act-validation.d.ts.map +1 -1
  4. package/dist/agent/act-validation.js +2 -2
  5. package/dist/agent/act-validation.js.map +1 -1
  6. package/dist/agent/act.d.ts +1 -0
  7. package/dist/agent/act.d.ts.map +1 -1
  8. package/dist/agent/act.js +41 -18
  9. package/dist/agent/act.js.map +1 -1
  10. package/dist/agent/ai-sdk.d.ts +2 -2
  11. package/dist/agent/ai-sdk.d.ts.map +1 -1
  12. package/dist/agent/ai-sdk.js +3 -4
  13. package/dist/agent/ai-sdk.js.map +1 -1
  14. package/dist/agent/default-agent.d.ts +17 -2
  15. package/dist/agent/default-agent.d.ts.map +1 -1
  16. package/dist/agent/default-agent.js +17 -3
  17. package/dist/agent/default-agent.js.map +1 -1
  18. package/dist/agent/error.d.ts.map +1 -1
  19. package/dist/agent/error.js +1 -0
  20. package/dist/agent/error.js.map +1 -1
  21. package/dist/agent/executor.d.ts +13 -0
  22. package/dist/agent/executor.d.ts.map +1 -1
  23. package/dist/agent/executor.js.map +1 -1
  24. package/dist/agent/index.d.ts.map +1 -1
  25. package/dist/agent/index.js +17 -12
  26. package/dist/agent/index.js.map +1 -1
  27. package/dist/agent/invocation.d.ts +26 -6
  28. package/dist/agent/invocation.d.ts.map +1 -1
  29. package/dist/agent/invocation.js +9 -6
  30. package/dist/agent/invocation.js.map +1 -1
  31. package/dist/agent/model/adapter.d.ts +3 -0
  32. package/dist/agent/model/adapter.d.ts.map +1 -1
  33. package/dist/agent/model/adapter.js.map +1 -1
  34. package/dist/agent/model/overflow.d.ts +20 -0
  35. package/dist/agent/model/overflow.d.ts.map +1 -0
  36. package/dist/agent/model/overflow.js +82 -0
  37. package/dist/agent/model/overflow.js.map +1 -0
  38. package/dist/agent/model/prompt-cache.d.ts +47 -0
  39. package/dist/agent/model/prompt-cache.d.ts.map +1 -0
  40. package/dist/agent/model/prompt-cache.js +78 -0
  41. package/dist/agent/model/prompt-cache.js.map +1 -0
  42. package/dist/agent/model/sdk.d.ts +41 -24
  43. package/dist/agent/model/sdk.d.ts.map +1 -1
  44. package/dist/agent/model/sdk.js +64 -91
  45. package/dist/agent/model/sdk.js.map +1 -1
  46. package/dist/agent/primitives.d.ts.map +1 -1
  47. package/dist/agent/primitives.js +2 -1
  48. package/dist/agent/primitives.js.map +1 -1
  49. package/dist/agent/public.d.ts +1 -1
  50. package/dist/agent/public.d.ts.map +1 -1
  51. package/dist/agent/public.js.map +1 -1
  52. package/dist/agent/screen-update.d.ts +8 -3
  53. package/dist/agent/screen-update.d.ts.map +1 -1
  54. package/dist/agent/screen-update.js +18 -5
  55. package/dist/agent/screen-update.js.map +1 -1
  56. package/dist/agent/tool-loop.d.ts.map +1 -1
  57. package/dist/agent/tool-loop.js +149 -33
  58. package/dist/agent/tool-loop.js.map +1 -1
  59. package/dist/agent/tool-output.d.ts +31 -0
  60. package/dist/agent/tool-output.d.ts.map +1 -0
  61. package/dist/agent/tool-output.js +60 -0
  62. package/dist/agent/tool-output.js.map +1 -0
  63. package/dist/agent/tool.d.ts +9 -3
  64. package/dist/agent/tool.d.ts.map +1 -1
  65. package/dist/agent/tool.js +2 -2
  66. package/dist/agent/tool.js.map +1 -1
  67. package/dist/agent/usage.d.ts +7 -0
  68. package/dist/agent/usage.d.ts.map +1 -1
  69. package/dist/agent/usage.js +11 -0
  70. package/dist/agent/usage.js.map +1 -1
  71. package/dist/cli/index.d.ts.map +1 -1
  72. package/dist/cli/index.js +121 -33
  73. package/dist/cli/index.js.map +1 -1
  74. package/dist/cli/init/engine-versions.json +1 -0
  75. package/dist/cli/init/engines.d.ts +13 -8
  76. package/dist/cli/init/engines.d.ts.map +1 -1
  77. package/dist/cli/init/engines.js +26 -7
  78. package/dist/cli/init/engines.js.map +1 -1
  79. package/dist/cli/init/gateways.d.ts +22 -0
  80. package/dist/cli/init/gateways.d.ts.map +1 -0
  81. package/dist/cli/init/gateways.js +50 -0
  82. package/dist/cli/init/gateways.js.map +1 -0
  83. package/dist/cli/init/scaffold.d.ts +7 -1
  84. package/dist/cli/init/scaffold.d.ts.map +1 -1
  85. package/dist/cli/init/scaffold.js +26 -13
  86. package/dist/cli/init/scaffold.js.map +1 -1
  87. package/dist/cli/init.d.ts.map +1 -1
  88. package/dist/cli/init.js +51 -13
  89. package/dist/cli/init.js.map +1 -1
  90. package/dist/collect/collect.d.ts +7 -0
  91. package/dist/collect/collect.d.ts.map +1 -1
  92. package/dist/collect/collect.js +16 -0
  93. package/dist/collect/collect.js.map +1 -1
  94. package/dist/collect/registry.d.ts.map +1 -1
  95. package/dist/collect/registry.js +13 -4
  96. package/dist/collect/registry.js.map +1 -1
  97. package/dist/collect/select.d.ts +2 -0
  98. package/dist/collect/select.d.ts.map +1 -1
  99. package/dist/collect/select.js +9 -0
  100. package/dist/collect/select.js.map +1 -1
  101. package/dist/config/agent.d.ts +16 -33
  102. package/dist/config/agent.d.ts.map +1 -1
  103. package/dist/config/agent.js +50 -140
  104. package/dist/config/agent.js.map +1 -1
  105. package/dist/config/esm-hooks.d.ts +28 -0
  106. package/dist/config/esm-hooks.d.ts.map +1 -0
  107. package/dist/config/esm-hooks.js +35 -0
  108. package/dist/config/esm-hooks.js.map +1 -0
  109. package/dist/config/load.d.ts +6 -0
  110. package/dist/config/load.d.ts.map +1 -1
  111. package/dist/config/load.js +52 -5
  112. package/dist/config/load.js.map +1 -1
  113. package/dist/config/resolve.d.ts +7 -0
  114. package/dist/config/resolve.d.ts.map +1 -1
  115. package/dist/config/resolve.js +53 -13
  116. package/dist/config/resolve.js.map +1 -1
  117. package/dist/engine/index.d.ts +8 -2
  118. package/dist/engine/index.d.ts.map +1 -1
  119. package/dist/engine/index.js.map +1 -1
  120. package/dist/engine/surface.d.ts +2 -2
  121. package/dist/engine/surface.d.ts.map +1 -1
  122. package/dist/explore/body.d.ts +36 -0
  123. package/dist/explore/body.d.ts.map +1 -0
  124. package/dist/explore/body.js +168 -0
  125. package/dist/explore/body.js.map +1 -0
  126. package/dist/explore/executor.d.ts +25 -0
  127. package/dist/explore/executor.d.ts.map +1 -0
  128. package/dist/explore/executor.js +86 -0
  129. package/dist/explore/executor.js.map +1 -0
  130. package/dist/explore/index.d.ts +64 -0
  131. package/dist/explore/index.d.ts.map +1 -0
  132. package/dist/explore/index.js +183 -0
  133. package/dist/explore/index.js.map +1 -0
  134. package/dist/explore/plan.d.ts +74 -0
  135. package/dist/explore/plan.d.ts.map +1 -0
  136. package/dist/explore/plan.js +149 -0
  137. package/dist/explore/plan.js.map +1 -0
  138. package/dist/explore/reporter.d.ts +11 -0
  139. package/dist/explore/reporter.d.ts.map +1 -0
  140. package/dist/explore/reporter.js +54 -0
  141. package/dist/explore/reporter.js.map +1 -0
  142. package/dist/explore/state.d.ts +58 -0
  143. package/dist/explore/state.d.ts.map +1 -0
  144. package/dist/explore/state.js +147 -0
  145. package/dist/explore/state.js.map +1 -0
  146. package/dist/internal/atomic-write.d.ts +1 -1
  147. package/dist/internal/atomic-write.d.ts.map +1 -1
  148. package/dist/internal/atomic-write.js.map +1 -1
  149. package/dist/internal/package-version.d.ts +2 -0
  150. package/dist/internal/package-version.d.ts.map +1 -1
  151. package/dist/internal/package-version.js +9 -0
  152. package/dist/internal/package-version.js.map +1 -1
  153. package/dist/internal/redact.d.ts +12 -4
  154. package/dist/internal/redact.d.ts.map +1 -1
  155. package/dist/internal/redact.js +61 -12
  156. package/dist/internal/redact.js.map +1 -1
  157. package/dist/internal/zip.d.ts +32 -0
  158. package/dist/internal/zip.d.ts.map +1 -0
  159. package/dist/internal/zip.js +183 -0
  160. package/dist/internal/zip.js.map +1 -0
  161. package/dist/report/build.d.ts +55 -0
  162. package/dist/report/build.d.ts.map +1 -1
  163. package/dist/report/build.js +10 -1
  164. package/dist/report/build.js.map +1 -1
  165. package/dist/report/debug-steps.d.ts.map +1 -1
  166. package/dist/report/debug-steps.js +15 -0
  167. package/dist/report/debug-steps.js.map +1 -1
  168. package/dist/report/format.d.ts +11 -1
  169. package/dist/report/format.d.ts.map +1 -1
  170. package/dist/report/format.js +15 -3
  171. package/dist/report/format.js.map +1 -1
  172. package/dist/report/list.d.ts.map +1 -1
  173. package/dist/report/list.js +2 -0
  174. package/dist/report/list.js.map +1 -1
  175. package/dist/run/artifacts.d.ts.map +1 -1
  176. package/dist/run/artifacts.js +8 -6
  177. package/dist/run/artifacts.js.map +1 -1
  178. package/dist/run/events.d.ts +4 -2
  179. package/dist/run/events.d.ts.map +1 -1
  180. package/dist/run/events.js.map +1 -1
  181. package/dist/run/execute.d.ts.map +1 -1
  182. package/dist/run/execute.js +29 -2
  183. package/dist/run/execute.js.map +1 -1
  184. package/dist/run/fixtures.d.ts +10 -1
  185. package/dist/run/fixtures.d.ts.map +1 -1
  186. package/dist/run/fixtures.js +39 -22
  187. package/dist/run/fixtures.js.map +1 -1
  188. package/dist/run/in-process.d.ts +8 -0
  189. package/dist/run/in-process.d.ts.map +1 -1
  190. package/dist/run/in-process.js +3 -3
  191. package/dist/run/in-process.js.map +1 -1
  192. package/dist/run/records.d.ts +8 -6
  193. package/dist/run/records.d.ts.map +1 -1
  194. package/dist/run/runner.d.ts +22 -1
  195. package/dist/run/runner.d.ts.map +1 -1
  196. package/dist/run/runner.js +22 -14
  197. package/dist/run/runner.js.map +1 -1
  198. package/dist/run/secrecy.d.ts +23 -0
  199. package/dist/run/secrecy.d.ts.map +1 -0
  200. package/dist/run/secrecy.js +22 -0
  201. package/dist/run/secrecy.js.map +1 -0
  202. package/dist/run/steps.d.ts +11 -0
  203. package/dist/run/steps.d.ts.map +1 -1
  204. package/dist/run/steps.js +1 -0
  205. package/dist/run/steps.js.map +1 -1
  206. package/dist/run/trace-redaction.d.ts +17 -0
  207. package/dist/run/trace-redaction.d.ts.map +1 -0
  208. package/dist/run/trace-redaction.js +148 -0
  209. package/dist/run/trace-redaction.js.map +1 -0
  210. package/dist/run/worker-models.d.ts +14 -14
  211. package/dist/run/worker-models.d.ts.map +1 -1
  212. package/dist/run/worker-models.js +34 -26
  213. package/dist/run/worker-models.js.map +1 -1
  214. package/dist/telemetry/events.d.ts.map +1 -1
  215. package/dist/telemetry/events.js +17 -2
  216. package/dist/telemetry/events.js.map +1 -1
  217. package/dist/types.d.ts +32 -25
  218. package/dist/types.d.ts.map +1 -1
  219. package/package.json +6 -4
  220. package/skills/e2e/SKILL.md +12 -5
  221. package/skills/e2e/references/agent.md +22 -17
  222. package/skills/e2e/references/debugging.md +3 -2
  223. package/skills/e2e/references/explore.md +83 -0
  224. package/skills/e2e/references/running.md +8 -3
  225. package/skills/e2e/references/setup.md +17 -13
  226. package/skills/e2e/references/writing-tests.md +1 -0
  227. package/dist/config/esm.d.ts +0 -4
  228. package/dist/config/esm.d.ts.map +0 -1
  229. package/dist/config/esm.js +0 -35
  230. package/dist/config/esm.js.map +0 -1
@@ -3,11 +3,10 @@
3
3
  ## Requirements
4
4
 
5
5
  - Node.js 22.12 or newer.
6
- - ES modules. The `package.json` nearest to the config and the tests must set
7
- `"type": "module"`. An `e2e.config.mts` is ESM on its own, but `.ts` tests
8
- still follow their package. In a CommonJS package either run
9
- `npm pkg set type=module` (this also changes how its `.js` files run) or put
10
- the tests in their own ESM package directory.
6
+ - ES modules. e2e loads `.ts` config, tests, and helpers as ES modules
7
+ whatever the nearest `package.json` `type` says, so a CommonJS package (a
8
+ Next.js app, for instance) needs no change. Write them with `import`, never
9
+ `require` or `module.exports`.
11
10
  - For browser tests, `@e2edev/playwright`. Missing browsers download when the
12
11
  engine first boots. In CI install them up front:
13
12
  `npx playwright install chromium --with-deps`.
@@ -57,6 +56,7 @@ unknown keys are `INVALID_CONFIG`.
57
56
  import type { E2EConfig } from '@e2edev/e2e';
58
57
  import { createAgent } from '@e2edev/e2e/agent';
59
58
  import { playwright } from '@e2edev/playwright';
59
+ import { gateway } from 'ai';
60
60
 
61
61
  export default {
62
62
  tests: 'tests/**/*.e2e.ts',
@@ -68,8 +68,13 @@ export default {
68
68
  }),
69
69
  },
70
70
  ],
71
- // Only for agent.* steps. The model comes from E2E_MODEL unless set here.
72
- agent: createAgent({ system: 'You are a thorough QA agent. Verify every outcome on screen.' }),
71
+ // Only for agent.* steps. The model is an AI SDK instance; gateway() from 'ai' reads AI_GATEWAY_API_KEY.
72
+ agents: {
73
+ default: createAgent({
74
+ model: gateway('openai/gpt-5.4-mini'),
75
+ system: 'You are a thorough QA agent. Verify every outcome on screen.',
76
+ }),
77
+ },
73
78
  credentials: {
74
79
  admin: { username: 'admin@example.test', password: process.env.ADMIN_PASSWORD ?? '' },
75
80
  },
@@ -87,7 +92,7 @@ export default {
87
92
  | `workers` | half the cores, `1` in CI | Test files run in parallel across workers, at most the `workers` the engine declares per target (a device target: one per device). |
88
93
  | `reporters` | `['list']` | `list`, `json`, `junit`, and reporter objects (`{ name, onEvent?, onRunFinished? }`) that receive the finished run. `json` excludes `list`; `--reporter` keeps the objects. |
89
94
  | `cache` | `'read-write'`, `'read-only'` in CI | The trace cache for `agent.act`; `'off'` disables it. |
90
- | `agent` | unset | `createAgent(...)`, an options block `{ model, context, visionModel, maxSteps, maxModelCalls, vision, providerOptions }`, or a custom `StepExecutor`. Omitted, the built-in agent runs with `E2E_MODEL`. A model passed to `createAgent({ model })` is the one model for `act` and the judgments, over `E2E_MODEL`. |
95
+ | `agents` | `{ default: built-in }` | Agents by name. `default` is what tests run with; `e2e run --agent <name>` runs with another. Each entry is `createAgent(...)`, an options block `{ model, context, visionModel, maxSteps, maxModelCalls, vision, providerOptions }`, or a custom `StepExecutor`. `model` is an AI SDK instance; without one anywhere, acquiring `agent` is `MODEL_UNAVAILABLE`. |
91
96
  | `credentials` | `{}` | Named `{ username, password, allowedOrigins? }` entries; `password` may be a function returning the value. |
92
97
  | `screen.testIdAttribute` | `'data-testid'` | Attribute read by `getByTestId`. |
93
98
  | `artifacts` | `['screenshot', 'trace']` | Kinds to keep (`screenshot`, `trace`, and the opt-in `video`), or `{ kinds, store, video }`; `video: { retain: 'on-failure' }` keeps only the recordings of attempts that did not pass. |
@@ -110,6 +115,8 @@ process, and identity. `playwright()` accepts:
110
115
  | `browser` | `'chromium'` (default), `'firefox'`, `'webkit'`. |
111
116
  | `viewport` | `{ width, height }`, default 1280x720. |
112
117
  | `connect` | `{ cdpEndpoint }` to attach to a remote Chromium over CDP instead of launching. |
118
+ | `headers` | Request headers sent to allowed origins only (a Vercel `x-vercel-protection-bypass`, ngrok's `ngrok-skip-browser-warning`). Reaches every path onto the page, `agent.act` included; turns the browser HTTP cache off and blocks service workers. |
119
+ | `basicAuth` | `{ username, password }` answering a `401` challenge from an allowed origin; never sent to any other. |
113
120
 
114
121
  Two browsers are two targets sharing one app declaration:
115
122
 
@@ -183,10 +190,7 @@ or read the address from the environment:
183
190
 
184
191
  | Variable | Effect |
185
192
  | --- | --- |
186
- | `E2E_MODEL` | `provider/model-id` for `agent.*` steps when the config sets no model. Routed through the Vercel AI Gateway. |
187
- | `E2E_MODEL_API_KEY` | Credential for that model. `AI_GATEWAY_API_KEY` is the fallback. |
188
- | `E2E_MODEL_ENDPOINT` | Any OpenAI-compatible endpoint URL for that model; the gateway is the default. HTTPS unless loopback. `agent.model.endpoint` wins. |
189
- | `E2E_VISION_MODEL` | Model for calls with `vision`; falls back to the main model. |
193
+ | `AI_GATEWAY_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY`, ... | Read by the provider package the config constructs the model with (`gateway()` from `ai`, `openrouter()`, `openai()`), not by the runner. The runner reads no model variable; the model is always an AI SDK instance in the config. |
190
194
  | `E2E_USER_<NAME>_USERNAME`, `E2E_USER_<NAME>_PASSWORD` | Override `credentials.<name>`. `<NAME>` is the credential name uppercased, other characters as `_`. |
191
195
  | `CI` | Turns on CI defaults: `retries: 1`, `workers: 1`, `test.only` rejected, cache read-only, `reuseExisting` ignored. |
192
196
  | `E2E_TELEMETRY_DISABLED`, `DO_NOT_TRACK` | Turn anonymous usage telemetry off; `e2e telemetry disable` saves the same choice. `E2E_TELEMETRY_DEBUG=1` prints each event instead of sending it. |
@@ -209,7 +213,7 @@ const iphone = agentDevice({ platform: 'ios', app: 'com.example.app' });
209
213
  export default {
210
214
  targets: [{ engine: iphone }],
211
215
  workers: 1,
212
- agent: createAgent({ tools: agentDeviceTools(iphone) }),
216
+ agents: { default: createAgent({ tools: agentDeviceTools(iphone) }) },
213
217
  } satisfies E2EConfig;
214
218
  ```
215
219
 
@@ -65,6 +65,7 @@ test.setup('sign in', { sessions: ['admin'] }, async ({ app, screen, session })
65
65
  | `requires` | `[]` | Capabilities the engine must contribute, e.g. `['web']`. Otherwise the test is skipped at selection instead of failing with `UNSUPPORTED_CAPABILITY`. |
66
66
  | `session` | unset | Restore state saved by a setup test. |
67
67
  | `agentContext` | unset | Extra context for `agent.*` calls in this test or group. |
68
+ | `agent` | the run's agent | Pin the test or group to a configured agent (`agents.<name>`). Innermost wins; `agent.act(..., { agent })` can name another for one call. |
68
69
  | `serial` | `false` | Groups only. Members share one app state, run in order on one worker, and retry as a whole. Inside, per-member `retries`, `session`, `platforms`, `requires`, and `skip` are errors. |
69
70
 
70
71
  Hook order follows nesting, not position: outer `beforeEach` first, inner
@@ -1,4 +0,0 @@
1
- /** Package-scope diagnostics for TypeScript config and test entry points. */
2
- /** Explains how to opt a `.ts` entry point's package into ESM when required. */
3
- export declare function esmPackageHint(modulePath: string): string | undefined;
4
- //# sourceMappingURL=esm.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"esm.d.ts","sourceRoot":"","sources":["../../src/config/esm.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAK7E,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA2BrE"}
@@ -1,35 +0,0 @@
1
- /** Package-scope diagnostics for TypeScript config and test entry points. */
2
- import { existsSync, readFileSync, realpathSync } from 'node:fs';
3
- import path from 'node:path';
4
- /** Explains how to opt a `.ts` entry point's package into ESM when required. */
5
- export function esmPackageHint(modulePath) {
6
- const filename = existsSync(modulePath) ? realpathSync(modulePath) : modulePath;
7
- if (path.extname(filename) !== '.ts')
8
- return undefined;
9
- let dir = path.dirname(filename);
10
- for (;;) {
11
- const manifestPath = path.join(dir, 'package.json');
12
- if (existsSync(manifestPath)) {
13
- let manifest;
14
- try {
15
- manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
16
- }
17
- catch {
18
- // Leave malformed or unreadable manifests to the loader's own diagnostic.
19
- return undefined;
20
- }
21
- if (typeof manifest !== 'object' || manifest === null || Array.isArray(manifest)) {
22
- return undefined;
23
- }
24
- if ('type' in manifest && manifest.type === 'module')
25
- return undefined;
26
- return `e2e requires ES modules for .ts config and test files, but ${manifestPath} does not set "type": "module". To opt this package into ESM, run npm pkg set type=module from ${dir}. This also changes how existing .js files in the package are interpreted.`;
27
- }
28
- const parent = path.dirname(dir);
29
- if (parent === dir || path.basename(parent) === 'node_modules')
30
- break;
31
- dir = parent;
32
- }
33
- return `e2e requires ES modules for .ts config and test files. Create a package.json with "type": "module" in ${path.dirname(filename)}, or run e2e init in the project directory.`;
34
- }
35
- //# sourceMappingURL=esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"esm.js","sourceRoot":"","sources":["../../src/config/esm.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,gFAAgF;AAChF,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAChF,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IAEvD,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,SAAS,CAAC;QACR,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QACpD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7B,IAAI,QAAiB,CAAC;YACtB,IAAI,CAAC;gBACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;YAC5D,CAAC;YAAC,MAAM,CAAC;gBACP,0EAA0E;gBAC1E,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjF,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,IAAI,MAAM,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAC;YACvE,OAAO,8DAA8D,YAAY,kGAAkG,GAAG,4EAA4E,CAAC;QACrQ,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,cAAc;YAAE,MAAM;QACtE,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IAED,OAAO,yGAAyG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,6CAA6C,CAAC;AACtL,CAAC"}