playwright-mimic 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +695 -446
  2. package/dist/agentic/agent.d.ts +106 -0
  3. package/dist/agentic/agent.d.ts.map +1 -0
  4. package/dist/agentic/agent.js +528 -0
  5. package/dist/agentic/agent.js.map +1 -0
  6. package/dist/agentic/index.d.ts +13 -0
  7. package/dist/agentic/index.d.ts.map +1 -0
  8. package/dist/agentic/index.js +12 -0
  9. package/dist/agentic/index.js.map +1 -0
  10. package/dist/agentic/planner.d.ts +41 -0
  11. package/dist/agentic/planner.d.ts.map +1 -0
  12. package/dist/agentic/planner.js +136 -0
  13. package/dist/agentic/planner.js.map +1 -0
  14. package/dist/agentic/react.d.ts +35 -0
  15. package/dist/agentic/react.d.ts.map +1 -0
  16. package/dist/agentic/react.js +170 -0
  17. package/dist/agentic/react.js.map +1 -0
  18. package/dist/agentic/recovery.d.ts +55 -0
  19. package/dist/agentic/recovery.d.ts.map +1 -0
  20. package/dist/agentic/recovery.js +200 -0
  21. package/dist/agentic/recovery.js.map +1 -0
  22. package/dist/agentic/reflection.d.ts +40 -0
  23. package/dist/agentic/reflection.d.ts.map +1 -0
  24. package/dist/agentic/reflection.js +142 -0
  25. package/dist/agentic/reflection.js.map +1 -0
  26. package/dist/agentic/types.d.ts +177 -0
  27. package/dist/agentic/types.d.ts.map +1 -0
  28. package/dist/agentic/types.js +8 -0
  29. package/dist/agentic/types.js.map +1 -0
  30. package/dist/agentic/wait.d.ts +50 -0
  31. package/dist/agentic/wait.d.ts.map +1 -0
  32. package/dist/agentic/wait.js +140 -0
  33. package/dist/agentic/wait.js.map +1 -0
  34. package/dist/agentic-mimic.d.ts +56 -0
  35. package/dist/agentic-mimic.d.ts.map +1 -0
  36. package/dist/agentic-mimic.js +98 -0
  37. package/dist/agentic-mimic.js.map +1 -0
  38. package/dist/index.d.ts +8 -8
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +9 -9
  41. package/dist/index.js.map +1 -1
  42. package/dist/mimic/actionType.d.ts +7 -0
  43. package/dist/mimic/actionType.d.ts.map +1 -0
  44. package/dist/mimic/actionType.js +44 -0
  45. package/dist/mimic/actionType.js.map +1 -0
  46. package/dist/mimic/annotations.d.ts +21 -0
  47. package/dist/mimic/annotations.d.ts.map +1 -0
  48. package/dist/mimic/annotations.js +36 -0
  49. package/dist/mimic/annotations.js.map +1 -0
  50. package/dist/mimic/cli.d.ts +15 -0
  51. package/dist/mimic/cli.d.ts.map +1 -0
  52. package/dist/mimic/cli.js +17 -0
  53. package/dist/mimic/cli.js.map +1 -0
  54. package/dist/mimic/click.d.ts +39 -0
  55. package/dist/mimic/click.d.ts.map +1 -0
  56. package/dist/mimic/click.js +348 -0
  57. package/dist/mimic/click.js.map +1 -0
  58. package/dist/mimic/forms.d.ts +52 -0
  59. package/dist/mimic/forms.d.ts.map +1 -0
  60. package/dist/mimic/forms.js +511 -0
  61. package/dist/mimic/forms.js.map +1 -0
  62. package/dist/mimic/markers.d.ts +133 -0
  63. package/dist/mimic/markers.d.ts.map +1 -0
  64. package/dist/mimic/markers.js +589 -0
  65. package/dist/mimic/markers.js.map +1 -0
  66. package/dist/mimic/navigation.d.ts +19 -0
  67. package/dist/mimic/navigation.d.ts.map +1 -0
  68. package/dist/mimic/navigation.js +136 -0
  69. package/dist/mimic/navigation.js.map +1 -0
  70. package/dist/mimic/playwrightCodeGenerator.d.ts +55 -0
  71. package/dist/mimic/playwrightCodeGenerator.d.ts.map +1 -0
  72. package/dist/mimic/playwrightCodeGenerator.js +270 -0
  73. package/dist/mimic/playwrightCodeGenerator.js.map +1 -0
  74. package/dist/mimic/replay.d.ts +21 -0
  75. package/dist/mimic/replay.d.ts.map +1 -0
  76. package/dist/mimic/replay.js +142 -0
  77. package/dist/mimic/replay.js.map +1 -0
  78. package/dist/mimic/schema/action.d.ts +315 -0
  79. package/dist/mimic/schema/action.d.ts.map +1 -0
  80. package/dist/mimic/schema/action.js +186 -0
  81. package/dist/mimic/schema/action.js.map +1 -0
  82. package/dist/mimic/selector.d.ts +143 -0
  83. package/dist/mimic/selector.d.ts.map +1 -0
  84. package/dist/mimic/selector.js +1515 -0
  85. package/dist/mimic/selector.js.map +1 -0
  86. package/dist/mimic/selectorDescriptor.d.ts +25 -0
  87. package/dist/mimic/selectorDescriptor.d.ts.map +1 -0
  88. package/dist/mimic/selectorDescriptor.js +32 -0
  89. package/dist/mimic/selectorDescriptor.js.map +1 -0
  90. package/dist/mimic/selectorSerialization.d.ts +18 -0
  91. package/dist/mimic/selectorSerialization.d.ts.map +1 -0
  92. package/dist/mimic/selectorSerialization.js +32 -0
  93. package/dist/mimic/selectorSerialization.js.map +1 -0
  94. package/dist/mimic/selectorTypes.d.ts +122 -0
  95. package/dist/mimic/selectorTypes.d.ts.map +1 -0
  96. package/dist/mimic/selectorTypes.js +2 -0
  97. package/dist/mimic/selectorTypes.js.map +1 -0
  98. package/dist/mimic/selectorUtils.d.ts +52 -0
  99. package/dist/mimic/selectorUtils.d.ts.map +1 -0
  100. package/dist/mimic/selectorUtils.js +251 -0
  101. package/dist/mimic/selectorUtils.js.map +1 -0
  102. package/dist/mimic/storage.d.ts +110 -0
  103. package/dist/mimic/storage.d.ts.map +1 -0
  104. package/dist/mimic/storage.js +409 -0
  105. package/dist/mimic/storage.js.map +1 -0
  106. package/dist/mimic/types.d.ts +85 -0
  107. package/dist/mimic/types.d.ts.map +1 -0
  108. package/dist/mimic/types.js +7 -0
  109. package/dist/mimic/types.js.map +1 -0
  110. package/dist/mimic.d.ts +29 -4
  111. package/dist/mimic.d.ts.map +1 -1
  112. package/dist/mimic.js +530 -32
  113. package/dist/mimic.js.map +1 -1
  114. package/dist/mimicry.d.ts +4 -4
  115. package/dist/mimicry.d.ts.map +1 -1
  116. package/dist/mimicry.js +22 -13
  117. package/dist/mimicry.js.map +1 -1
  118. package/package.json +30 -6
package/dist/mimic.js CHANGED
@@ -2,52 +2,538 @@
2
2
  * Minimal flow example function
3
3
  */
4
4
  import { test } from '@playwright/test';
5
- import { getBaseAction } from './mimicry/actionType.js';
6
- import { getNavigationAction, executeNavigationAction } from './mimicry/navigation.js';
7
- import { buildSelectorForTarget, captureTargets } from './mimicry/selector.js';
8
- import { executeClickAction, getClickAction } from './mimicry/click.js';
9
- import { startTestCase } from './utils/token-counter.js';
5
+ import { generateText, Output } from 'ai';
6
+ import { z } from 'zod';
7
+ import { getBaseAction } from './mimic/actionType.js';
8
+ import { getNavigationAction, executeNavigationAction } from './mimic/navigation.js';
9
+ import { captureScreenshot, getMimic } from './mimic/markers.js';
10
+ import { executeClickAction, getClickAction } from './mimic/click.js';
11
+ import { getFormAction, executeFormAction } from './mimic/forms.js';
12
+ import { getFromSelector } from './mimic/selectorUtils.js';
13
+ import { startTestCase, countTokens } from './utils/token-counter.js';
14
+ import { hashTestText, hashStepText, getSnapshot, saveSnapshot, recordFailure, shouldUseSnapshot } from './mimic/storage.js';
15
+ import { replayFromSnapshot } from './mimic/replay.js';
16
+ import { isTroubleshootMode } from './mimic/cli.js';
17
+ import { addAnnotation } from './mimic/annotations.js';
18
+ /**
19
+ * Schema for intent accomplishment check result
20
+ *
21
+ * Note: All fields must be required (no .optional()) for AI SDK structured output compatibility.
22
+ * Use empty string for remainingActions when accomplished is true.
23
+ */
24
+ const zIntentAccomplished = z.object({
25
+ accomplished: z.boolean().describe('Whether the step intent has been fully accomplished'),
26
+ reasoning: z.string().describe('Brief explanation of why the intent is or is not accomplished'),
27
+ remainingActions: z.string().describe('What actions might still be needed if not accomplished (provide empty string "" if accomplished is true)'),
28
+ });
29
+ /**
30
+ * Check if a step's intent has been accomplished
31
+ *
32
+ * Uses the LLM to analyze the current page state and determine if the step's
33
+ * intent has been fully fulfilled. This allows the system to continue
34
+ * executing actions for a single step until the intent is complete.
35
+ *
36
+ * @param page - Playwright Page object
37
+ * @param brain - Language model for intent analysis
38
+ * @param stepText - The original step text to check intent for
39
+ * @param actionsTaken - Array of actions already taken for this step
40
+ * @returns Promise resolving to whether the intent is accomplished
41
+ */
42
+ /**
43
+ * Check if a step's intent has been accomplished
44
+ *
45
+ * Uses the LLM to analyze the current page state and determine if the step's
46
+ * intent has been fully fulfilled. This allows the system to continue
47
+ * executing actions for a single step until the intent is complete.
48
+ *
49
+ * @param page - Playwright Page object
50
+ * @param brain - Language model for intent analysis
51
+ * @param stepText - The original step text to check intent for
52
+ * @param actionsTaken - Array of actions already taken for this step
53
+ * @returns Promise resolving to whether the intent is accomplished
54
+ */
55
+ async function checkIntentAccomplished(page, brain, stepText, actionsTaken) {
56
+ try {
57
+ // Capture current page state
58
+ const currentUrl = page.url();
59
+ const pageTitle = await page.title();
60
+ const pageContent = await page.textContent('body') || '';
61
+ const pageContentPreview = pageContent.substring(0, 2000); // Limit content size
62
+ // Build description of actions taken
63
+ const actionsDescription = actionsTaken.length > 0
64
+ ? actionsTaken.map((action, idx) => `${idx + 1}. ${action.actionKind}: ${action.stepText}`).join('\n')
65
+ : 'No actions taken yet';
66
+ const prompt = `You are analyzing whether a test step's intent has been fully accomplished.
67
+
68
+ **Step Intent:**
69
+ ${stepText}
70
+
71
+ **Actions Taken So Far:**
72
+ ${actionsDescription}
73
+
74
+ **Current Page State:**
75
+ - URL: ${currentUrl}
76
+ - Page Title: ${pageTitle}
77
+ - Page Content Preview: ${pageContentPreview.substring(0, 500)}...
78
+
79
+ **Instructions:**
80
+ Analyze whether the step's intent has been FULLY accomplished based on:
81
+ 1. The literal meaning of the step text
82
+ 2. The actions that have been taken
83
+ 3. The current state of the page
84
+
85
+ Consider:
86
+ - Has the step's primary goal been achieved?
87
+ - Are there any remaining sub-tasks implied by the step?
88
+ - Would a reasonable person reading the step consider it complete?
89
+
90
+ Be strict: only mark as accomplished if the intent is FULLY satisfied. If the step requires multiple actions (e.g., "fill in the form and submit it"), it's not accomplished until ALL parts are done.
91
+
92
+ **Important:** Always provide all fields:
93
+ - If accomplished is true, set remainingActions to an empty string ""
94
+ - If accomplished is false, describe what actions are still needed in remainingActions`;
95
+ const result = await generateText({
96
+ model: brain,
97
+ prompt,
98
+ output: Output.object({ schema: zIntentAccomplished, name: 'intentAccomplished' }),
99
+ });
100
+ await countTokens(result);
101
+ const output = result.output;
102
+ if (!output.accomplished && output.remainingActions && output.remainingActions.trim()) {
103
+ console.log(`→ Step intent not yet accomplished. ${output.reasoning}`);
104
+ console.log(`→ Remaining: ${output.remainingActions}`);
105
+ }
106
+ else if (output.accomplished) {
107
+ console.log(`✓ Step intent accomplished: ${output.reasoning}`);
108
+ }
109
+ return output.accomplished;
110
+ }
111
+ catch (error) {
112
+ // If intent check fails, default to false (continue trying)
113
+ console.warn(`Failed to check intent accomplishment: ${error instanceof Error ? error.message : String(error)}`);
114
+ return false;
115
+ }
116
+ }
10
117
  /**
11
118
  * Minimal flow function that takes a Playwright page and input string
12
119
  *
13
120
  * @param page - Playwright Page object
14
121
  * @param input - Input string to process
122
+ * @param testFilePath - Directory path of the test file (for snapshot storage)
123
+ * @param troubleshootMode - Whether troubleshoot mode is enabled
15
124
  * @returns Flow execution result with validated context
16
125
  */
17
- export async function mimic(input, { page, brains, testInfo }) {
126
+ export async function mimic(input, { page, brains, testInfo, testFilePath, troubleshootMode }) {
18
127
  if (testInfo?.title)
19
128
  await startTestCase(testInfo.title);
129
+ // Generate test hash for snapshot identification
130
+ const testHash = hashTestText(input);
131
+ const isTroubleshoot = troubleshootMode ?? isTroubleshootMode();
132
+ // Normal execution with LLM - track steps for snapshot creation
20
133
  const steps = input.split('\n')
21
134
  // lets clean up things
22
135
  .map(step => step.trim())
23
136
  // and remove empty steps
24
- .filter(step => step.length > 0);
137
+ .filter((step) => step.length > 0);
138
+ const expectedStepCount = steps.length;
139
+ // Check if we should use an existing snapshot
140
+ // Even in troubleshoot mode, try to use snapshot first - only regenerate on failure
141
+ const useSnapshot = testFilePath && await shouldUseSnapshot(testFilePath, testHash, isTroubleshoot, expectedStepCount);
142
+ if (useSnapshot) {
143
+ const snapshot = await getSnapshot(testFilePath, testHash);
144
+ if (snapshot) {
145
+ // Add annotation indicating we're loading from snapshot
146
+ addAnnotation(testInfo, 'snapshot-load', `📦 Loading test from mimic snapshot file (${snapshot.steps.length} step${snapshot.steps.length !== 1 ? 's' : ''} cached)`);
147
+ try {
148
+ // Replay from snapshot (skip LLM calls for faster execution)
149
+ await replayFromSnapshot(page, snapshot, testInfo);
150
+ // If replay succeeds, we're done
151
+ return;
152
+ }
153
+ catch (error) {
154
+ // Replay failed - regenerate actions
155
+ // Add annotation at the top indicating test is being updated
156
+ addAnnotation(testInfo, 'test-update', `🔄 Test snapshot replay failed, regenerating actions: ${error instanceof Error ? error.message : String(error)}`);
157
+ // Record the failure before regenerating
158
+ if (testFilePath) {
159
+ await recordFailure(testFilePath, testHash, undefined, undefined, error instanceof Error ? error.message : String(error));
160
+ }
161
+ // Fall through to regenerate actions below
162
+ }
163
+ }
164
+ }
165
+ else if (testFilePath) {
166
+ // No snapshot exists or snapshot shouldn't be used - check if we're updating
167
+ const existingSnapshot = await getSnapshot(testFilePath, testHash);
168
+ if (existingSnapshot && existingSnapshot.flags?.lastFailedAt) {
169
+ // We have a failed snapshot - add annotation that we're regenerating
170
+ addAnnotation(testInfo, 'test-update', '🔄 Regenerating test actions due to previous failure');
171
+ }
172
+ }
173
+ // executedSteps will be populated during step execution below
174
+ const executedSteps = [];
175
+ // Load existing snapshot to check for cached steps
176
+ // This allows selective regeneration - only regenerate steps that don't exist or have changed
177
+ let existingSnapshot = null;
178
+ if (testFilePath) {
179
+ existingSnapshot = await getSnapshot(testFilePath, testHash);
180
+ }
181
+ // Build a map of existing steps by their hash for quick lookup
182
+ // This enables selective regeneration: only regenerate steps that don't exist in the snapshot
183
+ const existingStepsByHash = {};
184
+ if (existingSnapshot) {
185
+ // Support both new format (stepsByHash) and old format (steps array) for backward compatibility
186
+ if (existingSnapshot.stepsByHash) {
187
+ Object.assign(existingStepsByHash, existingSnapshot.stepsByHash);
188
+ }
189
+ else if (existingSnapshot.steps) {
190
+ // Convert old format to new format for backward compatibility
191
+ for (const step of existingSnapshot.steps) {
192
+ existingStepsByHash[step.stepHash] = step;
193
+ }
194
+ }
195
+ }
196
+ // Note: Full snapshot replay is handled above in the useSnapshot block
197
+ // Below we handle selective regeneration: only regenerate steps that don't exist in the snapshot
198
+ // Capture screenshot with markers at the start of test execution
199
+ // This provides a visual reference of the initial page state with all markers
200
+ // Attach it to the test report so it's visible in Playwright HTML reports
201
+ try {
202
+ console.log('📸 [mimic] Capturing initial screenshot with markers for test attachment...');
203
+ const { image: screenshot } = await captureScreenshot(page);
204
+ console.log(`📸 [mimic] Screenshot captured (${(screenshot.length / 1024).toFixed(2)}KB)`);
205
+ // Attach screenshot to test report if testInfo is available
206
+ // This makes it visible in Playwright HTML reports like a regular screenshot
207
+ if (testInfo) {
208
+ await testInfo.attach('initial-page-with-markers.png', {
209
+ body: screenshot,
210
+ contentType: 'image/png',
211
+ });
212
+ console.log('📎 [mimic] Screenshot attached to test report');
213
+ }
214
+ }
215
+ catch (error) {
216
+ // If screenshot capture fails, log but don't fail the test
217
+ console.warn('⚠️ [mimic] Failed to capture initial screenshot:', error instanceof Error ? error.message : String(error));
218
+ }
219
+ test.slow(true);
25
220
  // now lets process each step
26
- for (const step of steps) {
27
- await test.step(step, async () => {
28
- const baseAction = await getBaseAction(page, brains, step);
29
- switch (baseAction.kind) {
30
- case 'navigation':
31
- console.log(`Navigating to ${step}`);
32
- const navigationAction = await getNavigationAction(page, brains, step);
33
- await executeNavigationAction(page, navigationAction);
34
- break;
35
- case 'click':
36
- console.log(`Clicking on ${step}`);
37
- const targetElements = await captureTargets(page, { interactableOnly: true });
38
- const clickActionResult = await getClickAction(page, brains, step, targetElements);
39
- // TODO: better way to work out if the top priority candidate is a clickable element
40
- const clickable = await buildSelectorForTarget(page, clickActionResult.candidates.find(Boolean));
41
- await executeClickAction(clickable, clickActionResult);
42
- break;
43
- case 'form update':
44
- const formElements = await captureTargets(page, { interactableOnly: true });
45
- console.log(`Form element count: ${formElements.length}`);
46
- break;
47
- default:
48
- throw new Error(`Unknown base action type: ${baseAction.kind}`);
221
+ for (let stepIndex = 0; stepIndex < steps.length; stepIndex++) {
222
+ const step = steps[stepIndex];
223
+ // Type guard: ensure step is defined (should always be true after filter)
224
+ if (!step) {
225
+ continue;
226
+ }
227
+ // Check if this step already exists in the snapshot
228
+ // This enables selective regeneration: only regenerate steps that don't exist or have changed
229
+ const stepHash = hashStepText(step);
230
+ const existingStep = existingStepsByHash[stepHash];
231
+ // If step exists in snapshot and we're not forcing full regeneration, use it for replay
232
+ // Otherwise, regenerate the step
233
+ // Note: Full snapshot replay (all steps) is handled above, this is for selective regeneration
234
+ // We skip selective regeneration if we already did full replay (useSnapshot path)
235
+ if (existingStep && existingSnapshot && !existingSnapshot.flags?.forceRegenerate && !useSnapshot) {
236
+ // Step exists in snapshot - replay it instead of regenerating
237
+ console.log(`📦 [mimic] Using cached step: "${step}" (hash: ${stepHash})`);
238
+ try {
239
+ await test.step(step, async () => {
240
+ // Replay the step from snapshot
241
+ switch (existingStep.actionKind) {
242
+ case 'navigation':
243
+ const navAction = existingStep.actionDetails;
244
+ await executeNavigationAction(page, navAction, testInfo, step);
245
+ break;
246
+ case 'click':
247
+ const clickAction = existingStep.actionDetails;
248
+ if (!existingStep.targetElement) {
249
+ throw new Error(`Cached step missing targetElement`);
250
+ }
251
+ let clickElement;
252
+ try {
253
+ clickElement = getFromSelector(page, existingStep.targetElement.selector);
254
+ await clickElement.waitFor({ timeout: 5000 });
255
+ }
256
+ catch (error) {
257
+ if (existingStep.targetElement.mimicId !== undefined) {
258
+ clickElement = getMimic(page, existingStep.targetElement.mimicId);
259
+ }
260
+ else {
261
+ throw error;
262
+ }
263
+ }
264
+ const selectedCandidate = clickAction.candidates[0];
265
+ if (!selectedCandidate) {
266
+ throw new Error(`Cached step has no candidates`);
267
+ }
268
+ await executeClickAction(clickElement, clickAction, selectedCandidate, testInfo, step);
269
+ break;
270
+ case 'form update':
271
+ const formAction = existingStep.actionDetails;
272
+ if (!existingStep.targetElement) {
273
+ throw new Error(`Cached step missing targetElement`);
274
+ }
275
+ let formElement;
276
+ try {
277
+ formElement = getFromSelector(page, existingStep.targetElement.selector);
278
+ await formElement.waitFor({ timeout: 5000 });
279
+ }
280
+ catch (error) {
281
+ if (existingStep.targetElement.mimicId !== undefined) {
282
+ formElement = getMimic(page, existingStep.targetElement.mimicId);
283
+ }
284
+ else {
285
+ throw error;
286
+ }
287
+ }
288
+ await executeFormAction(page, formAction, formElement, testInfo, step);
289
+ break;
290
+ }
291
+ // Add to executed steps for snapshot
292
+ const cachedStepResult = {
293
+ stepIndex,
294
+ stepText: step,
295
+ actionKind: existingStep.actionKind,
296
+ actionDetails: existingStep.actionDetails,
297
+ ...(existingStep.targetElement && { targetElement: existingStep.targetElement }),
298
+ };
299
+ executedSteps.push(cachedStepResult);
300
+ });
301
+ continue; // Skip to next step
49
302
  }
50
- });
303
+ catch (error) {
304
+ // Replay failed - fall through to regenerate
305
+ console.warn(`⚠️ [mimic] Cached step replay failed, regenerating: ${error instanceof Error ? error.message : String(error)}`);
306
+ }
307
+ }
308
+ // Step doesn't exist in snapshot or replay failed - regenerate it
309
+ console.log(`🔄 [mimic] Regenerating step: "${step}" (hash: ${stepHash})`);
310
+ try {
311
+ await test.step(step, async () => {
312
+ // Build test context from previous steps and current state
313
+ const currentUrl = page.url();
314
+ const currentPageTitle = await page.title().catch(() => 'Unknown');
315
+ const testContext = {
316
+ previousSteps: executedSteps.map((executedStep) => ({
317
+ stepIndex: executedStep.stepIndex,
318
+ stepText: executedStep.stepText,
319
+ actionKind: executedStep.actionKind,
320
+ // Extract URL from navigation actions if available
321
+ url: executedStep.actionKind === 'navigation'
322
+ ? executedStep.actionDetails.params?.url || undefined
323
+ : undefined,
324
+ })),
325
+ currentState: {
326
+ url: currentUrl,
327
+ pageTitle: currentPageTitle,
328
+ },
329
+ totalSteps: steps.length,
330
+ currentStepIndex: stepIndex,
331
+ };
332
+ // Track all actions taken for this step
333
+ const stepActions = [];
334
+ const maxActionsPerStep = 10; // Prevent infinite loops
335
+ let actionCount = 0;
336
+ let intentAccomplished = false;
337
+ // Loop until intent is accomplished or max actions reached
338
+ while (!intentAccomplished && actionCount < maxActionsPerStep) {
339
+ actionCount++;
340
+ // Check if intent is already accomplished (skip check on first action)
341
+ if (actionCount > 1) {
342
+ intentAccomplished = await checkIntentAccomplished(page, brains, step, stepActions);
343
+ if (intentAccomplished) {
344
+ console.log(`✓ Step intent accomplished after ${actionCount - 1} action(s)`);
345
+ break;
346
+ }
347
+ console.log(`→ Continuing to add actions for step (attempt ${actionCount})...`);
348
+ break;
349
+ }
350
+ // Get the next action to execute for this step
351
+ const baseAction = await getBaseAction(page, brains, step, testContext);
352
+ let stepResult;
353
+ // Wait a bit for markers to be applied to all elements
354
+ // await page.waitForTimeout(500);
355
+ switch (baseAction.kind) {
356
+ case 'navigation':
357
+ // Navigation actions will log their own plain English annotations
358
+ const navigationAction = await getNavigationAction(page, brains, step, testContext);
359
+ const executedNavAction = await executeNavigationAction(page, navigationAction, testInfo, step);
360
+ stepResult = {
361
+ stepIndex,
362
+ stepText: step,
363
+ actionKind: 'navigation',
364
+ actionDetails: executedNavAction,
365
+ };
366
+ break;
367
+ case 'click':
368
+ // Click actions will log their own plain English annotations
369
+ const clickActionResult = await getClickAction(page, brains, step, testContext);
370
+ // Defensive check: ensure candidates array exists and is valid
371
+ if (!clickActionResult || !clickActionResult.candidates || !Array.isArray(clickActionResult.candidates)) {
372
+ throw new Error(`Invalid click action result: candidates array is missing or invalid for step: ${step}`);
373
+ }
374
+ // TODO: better way to work out if the top priority candidate is a clickable element
375
+ const selectedCandidate = clickActionResult.candidates.sort((a, b) => b.confidence - a.confidence).find(Boolean);
376
+ if (!selectedCandidate) {
377
+ throw new Error(`No candidate element found for click action: ${step}`);
378
+ }
379
+ // Use marker ID from the candidate to get the locator
380
+ if (!selectedCandidate.mimicId) {
381
+ throw new Error(`Selected candidate is missing mimicId for click action: ${step}`);
382
+ }
383
+ const clickable = getMimic(page, selectedCandidate.mimicId);
384
+ const clickResult = await executeClickAction(clickable, clickActionResult, selectedCandidate, testInfo, step);
385
+ // Store best selector descriptor with mimicId as fallback
386
+ if (!clickResult.selector) {
387
+ throw new Error(`Could not generate selector for click action: ${step}`);
388
+ }
389
+ const targetElement = {
390
+ selector: clickResult.selector,
391
+ mimicId: selectedCandidate.mimicId
392
+ };
393
+ stepResult = {
394
+ stepIndex,
395
+ stepText: step,
396
+ actionKind: 'click',
397
+ actionDetails: clickResult.actionResult,
398
+ targetElement,
399
+ };
400
+ break;
401
+ case 'form update':
402
+ // Form actions will log their own plain English annotations
403
+ const formActionResult = await getFormAction(page, brains, step, testContext);
404
+ // Use marker ID from the form result to get the locator
405
+ if (!formActionResult.mimicId) {
406
+ throw new Error(`Form action result is missing mimicId for form action: ${step}`);
407
+ }
408
+ const targetFormElement = getMimic(page, formActionResult.mimicId);
409
+ const formResult = await executeFormAction(page, formActionResult, targetFormElement, testInfo, step);
410
+ // Handle the return type - executeFormAction returns { actionResult, selector }
411
+ const selector = formResult.selector;
412
+ const actionDetails = formResult.actionResult;
413
+ // Store best selector descriptor with mimicId as fallback
414
+ if (!selector) {
415
+ throw new Error(`Could not generate selector for form action: ${step}`);
416
+ }
417
+ const formTargetElement = {
418
+ selector,
419
+ mimicId: formActionResult.mimicId
420
+ };
421
+ stepResult = {
422
+ stepIndex,
423
+ stepText: step,
424
+ actionKind: 'form update',
425
+ actionDetails,
426
+ targetElement: formTargetElement,
427
+ };
428
+ break;
429
+ default:
430
+ throw new Error(`Unknown base action type: ${baseAction.kind}`);
431
+ }
432
+ // Add this action to the step's actions
433
+ stepActions.push(stepResult);
434
+ // After executing an action, check if intent is accomplished
435
+ // (but skip if we just checked before this action)
436
+ if (actionCount === 1 || actionCount >= maxActionsPerStep) {
437
+ intentAccomplished = await checkIntentAccomplished(page, brains, step, stepActions);
438
+ }
439
+ }
440
+ // Add all actions for this step to executedSteps
441
+ // Each action represents a sub-action taken to accomplish the step
442
+ executedSteps.push(...stepActions);
443
+ if (actionCount >= maxActionsPerStep && !intentAccomplished) {
444
+ console.warn(`⚠️ Reached maximum actions (${maxActionsPerStep}) for step: ${step}. Intent may not be fully accomplished.`);
445
+ }
446
+ });
447
+ }
448
+ catch (error) {
449
+ // Record failure and rethrow with step information
450
+ if (testFilePath) {
451
+ await recordFailure(testFilePath, testHash, stepIndex, step, error instanceof Error ? error.message : String(error));
452
+ }
453
+ throw new Error(`Step ${stepIndex + 1} failed: ${step}\n${error instanceof Error ? error.message : String(error)}`);
454
+ }
455
+ }
456
+ // Save snapshot on successful completion
457
+ // Only save if we executed at least as many steps as input lines and all steps succeeded
458
+ // (We only reach here if no errors were thrown, meaning all steps succeeded)
459
+ if (testFilePath && executedSteps.length > 0) {
460
+ // Count unique steps executed (by stepIndex)
461
+ const uniqueStepIndices = new Set(executedSteps.map(step => step.stepIndex));
462
+ const executedStepCount = uniqueStepIndices.size;
463
+ // Only save if we have at least as many steps as input lines
464
+ if (executedStepCount >= expectedStepCount) {
465
+ // Check if this was a regeneration (snapshot existed but we regenerated)
466
+ const existingSnapshot = await getSnapshot(testFilePath, testHash);
467
+ const wasRegeneration = existingSnapshot !== null;
468
+ const now = new Date().toISOString();
469
+ // Hash each step text and create snapshot steps with hashes
470
+ // Build stepsByHash map for efficient lookup and selective regeneration
471
+ // Start with existing steps to preserve steps that weren't regenerated
472
+ const stepsByHash = {};
473
+ if (existingSnapshot) {
474
+ // Support both new format (stepsByHash) and old format (steps array) for backward compatibility
475
+ if (existingSnapshot.stepsByHash) {
476
+ Object.assign(stepsByHash, existingSnapshot.stepsByHash);
477
+ }
478
+ else if (existingSnapshot.steps) {
479
+ // Convert old format to new format
480
+ for (const step of existingSnapshot.steps) {
481
+ stepsByHash[step.stepHash] = step;
482
+ }
483
+ }
484
+ }
485
+ // Process executed steps and update/merge with existing snapshot
486
+ // This will overwrite existing steps that were regenerated, but preserve others
487
+ for (const step of executedSteps) {
488
+ const stepHash = hashStepText(step.stepText);
489
+ const baseStep = {
490
+ stepHash,
491
+ stepIndex: step.stepIndex,
492
+ stepText: step.stepText,
493
+ actionKind: step.actionKind,
494
+ actionDetails: step.actionDetails,
495
+ executedAt: now,
496
+ };
497
+ // Conditionally include targetElement only if it exists
498
+ const snapshotStep = step.targetElement
499
+ ? { ...baseStep, targetElement: step.targetElement }
500
+ : baseStep;
501
+ // Store in stepsByHash (will overwrite if step was regenerated, or add if new)
502
+ stepsByHash[stepHash] = snapshotStep;
503
+ }
504
+ // Build ordered steps array from stepsByHash for backward compatibility
505
+ // Sort by stepIndex to maintain order
506
+ const allSteps = Object.values(stepsByHash);
507
+ allSteps.sort((a, b) => a.stepIndex - b.stepIndex);
508
+ const snapshotSteps = allSteps;
509
+ // Build snapshot object (screenshot is attached to test report, not stored in JSON)
510
+ const snapshot = {
511
+ testHash,
512
+ testText: input,
513
+ stepsByHash, // New format: indexed by stepHash for efficient lookup
514
+ steps: snapshotSteps, // Backward compatibility: ordered array
515
+ flags: {
516
+ needsRetry: false,
517
+ hasErrors: false,
518
+ troubleshootingEnabled: isTroubleshoot,
519
+ skipSnapshot: false,
520
+ forceRegenerate: false,
521
+ debugMode: false,
522
+ createdAt: existingSnapshot?.flags?.createdAt || now,
523
+ lastPassedAt: now,
524
+ lastFailedAt: null,
525
+ },
526
+ };
527
+ await saveSnapshot(testFilePath, snapshot);
528
+ // Add annotation if this was a regeneration
529
+ if (wasRegeneration) {
530
+ addAnnotation(testInfo, 'test-update', '✅ Test actions successfully regenerated and saved');
531
+ }
532
+ }
533
+ else {
534
+ // Not all steps were executed - don't save incomplete snapshot
535
+ console.warn(`⚠️ Not saving snapshot: only ${executedStepCount} of ${expectedStepCount} steps executed`);
536
+ }
51
537
  }
52
538
  }
53
539
  function trimTemplate(strings, ...values) {
@@ -63,9 +549,21 @@ function trimTemplate(strings, ...values) {
63
549
  .join('\n');
64
550
  }
65
551
  export const createMimic = (config) => {
552
+ // Extract test file path from TestInfo if available
553
+ // Pass full file path (not directory) to storage functions
554
+ const testFilePath = config.testInfo?.file || undefined;
555
+ config.eyes = config.eyes ?? config.brains;
556
+ // Check troubleshoot mode
557
+ const troubleshootMode = isTroubleshootMode();
66
558
  return async (prompt, ...args) => {
67
559
  const lines = trimTemplate(prompt, ...args);
68
- return await mimic(lines, config);
560
+ return await mimic(lines, {
561
+ page: config.page,
562
+ brains: config.brains,
563
+ testInfo: config.testInfo,
564
+ ...(testFilePath ? { testFilePath } : {}),
565
+ troubleshootMode,
566
+ });
69
567
  };
70
568
  };
71
569
  //# sourceMappingURL=mimic.js.map
package/dist/mimic.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mimic.js","sourceRoot":"","sources":["../src/mimic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAkB,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAG,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAMzD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,KAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAKlE;IAEC,IAAI,QAAQ,EAAE,KAAK;QAAE,MAAM,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEzD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;QAC7B,uBAAuB;SACtB,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,yBAAyB;SACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEnC,6BAA6B;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;YAC/B,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YAC3D,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;gBACxB,KAAK,YAAY;oBACf,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;oBACrC,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;oBACvE,MAAM,uBAAuB,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;oBACtD,MAAM;gBACR,KAAK,OAAO;oBACV,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;oBACnC,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC9E,MAAM,iBAAiB,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;oBACnF,oFAAoF;oBACpF,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,IAAI,EAAE,iBAAiB,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAQ,CAAC,CAAC;oBACxG,MAAM,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;oBAEvD,MAAM;gBACR,KAAK,aAAa;oBAChB,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC5E,OAAO,CAAC,GAAG,CAAC,uBAAuB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;oBAC1D,MAAM;gBACR;oBAEE,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;YACpE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;AAEH,CAAC;AACD,SAAS,YAAY,CAAC,OAA6B,EAAE,GAAG,MAAa;IACnE,uDAAuD;IACvD,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;QAC1C,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,qEAAqE;IACrE,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SAC/B,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAK3B,EAAE,EAAE;IACH,OAAO,KAAK,EAAE,MAA4B,EAAE,GAAG,IAAe,EAAE,EAAE;QAChE,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5C,OAAO,MAAM,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"mimic.js","sourceRoot":"","sources":["../src/mimic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAkB,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAG,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAyB,MAAM,kBAAkB,CAAC;AAG3F,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC7H,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AA6BvD;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;IACzF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+DAA+D,CAAC;IAC/F,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0GAA0G,CAAC;CAClJ,CAAC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,uBAAuB,CACpC,IAAU,EACV,KAAoB,EACpB,QAAgB,EAChB,YAAmC;IAEnC,IAAI,CAAC;QACH,6BAA6B;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACzD,MAAM,kBAAkB,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,qBAAqB;QAEhF,qCAAqC;QACrC,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC;YAChD,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAC/B,GAAG,GAAG,GAAG,CAAC,KAAK,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,QAAQ,EAAE,CACvD,CAAC,IAAI,CAAC,IAAI,CAAC;YACd,CAAC,CAAC,sBAAsB,CAAC;QAE3B,MAAM,MAAM,GAAG;;;EAGjB,QAAQ;;;EAGR,kBAAkB;;;SAGX,UAAU;gBACH,SAAS;0BACC,kBAAkB,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;;;;;;;;;;;;;;;;;uFAiByB,CAAC;QAEpF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;YAChC,KAAK,EAAE,KAAK;YACZ,MAAM;YACN,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC;SACnF,CAAC,CAAC;QAEH,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAE1B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC;YACtF,OAAO,CAAC,GAAG,CAAC,uCAAuC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YACvE,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,MAAM,CAAC,YAAY,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,4DAA4D;QAC5D,OAAO,CAAC,IAAI,CAAC,0CAA0C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjH,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAGD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,KAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAMlG;IAEC,IAAI,QAAQ,EAAE,KAAK;QAAE,MAAM,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEzD,iDAAiD;IACjD,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,cAAc,GAAG,gBAAgB,IAAI,kBAAkB,EAAE,CAAC;IAEhE,gEAAgE;IAChE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;QAC7B,uBAAuB;SACtB,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,yBAAyB;SACxB,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAErD,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,CAAC;IAEvC,8CAA8C;IAC9C,oFAAoF;IACpF,MAAM,WAAW,GAAG,YAAY,IAAI,MAAM,iBAAiB,CAAC,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,CAAC,CAAC;IAEvH,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,YAAa,EAAE,QAAQ,CAAC,CAAC;QAC5D,IAAI,QAAQ,EAAE,CAAC;YACb,wDAAwD;YACxD,aAAa,CACX,QAAQ,EACR,eAAe,EACf,6CAA6C,QAAQ,CAAC,KAAK,CAAC,MAAM,QAAQ,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,CAC3H,CAAC;YAEF,IAAI,CAAC;gBACH,6DAA6D;gBAC7D,MAAM,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBACnD,iCAAiC;gBACjC,OAAO;YACT,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,qCAAqC;gBACrC,6DAA6D;gBAC7D,aAAa,CACX,QAAQ,EACR,aAAa,EACb,yDAAyD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAClH,CAAC;gBAEF,yCAAyC;gBACzC,IAAI,YAAY,EAAE,CAAC;oBACjB,MAAM,aAAa,CACjB,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,SAAS,EACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;gBACJ,CAAC;gBAED,2CAA2C;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,YAAY,EAAE,CAAC;QACxB,6EAA6E;QAC7E,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QACnE,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,CAAC;YAC7D,qEAAqE;YACrE,aAAa,CACX,QAAQ,EACR,aAAa,EACb,sDAAsD,CACvD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,8DAA8D;IAC9D,MAAM,aAAa,GAA0B,EAAE,CAAC;IAEhD,mDAAmD;IACnD,8FAA8F;IAC9F,IAAI,gBAAgB,GAAoB,IAAI,CAAC;IAC7C,IAAI,YAAY,EAAE,CAAC;QACjB,gBAAgB,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC;IAED,+DAA+D;IAC/D,8FAA8F;IAC9F,MAAM,mBAAmB,GAAiC,EAAE,CAAC;IAC7D,IAAI,gBAAgB,EAAE,CAAC;QACrB,gGAAgG;QAChG,IAAI,gBAAgB,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC;YAClC,8DAA8D;YAC9D,KAAK,MAAM,IAAI,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC;gBAC1C,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,iGAAiG;IAEjG,iEAAiE;IACjE,8EAA8E;IAC9E,0EAA0E;IAC1E,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;QAC3F,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAE3F,4DAA4D;QAC5D,6EAA6E;QAC7E,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,CAAC,MAAM,CAAC,+BAA+B,EAAE;gBACrD,IAAI,EAAE,UAAU;gBAChB,WAAW,EAAE,WAAW;aACzB,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,2DAA2D;QAC3D,OAAO,CAAC,IAAI,CAAC,mDAAmD,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5H,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,6BAA6B;IAC7B,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;QAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;QAE9B,0EAA0E;QAC1E,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QAED,oDAAoD;QACpD,8FAA8F;QAC9F,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAEnD,wFAAwF;QACxF,iCAAiC;QACjC,8FAA8F;QAC9F,kFAAkF;QAClF,IAAI,YAAY,IAAI,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,eAAe,IAAI,CAAC,WAAW,EAAE,CAAC;YACjG,8DAA8D;YAC9D,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,YAAY,QAAQ,GAAG,CAAC,CAAC;YAC3E,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;oBAC/B,gCAAgC;oBAChC,QAAQ,YAAY,CAAC,UAAU,EAAE,CAAC;wBAChC,KAAK,YAAY;4BACf,MAAM,SAAS,GAAG,YAAY,CAAC,aAAiC,CAAC;4BACjE,MAAM,uBAAuB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;4BAC/D,MAAM;wBACR,KAAK,OAAO;4BACV,MAAM,WAAW,GAAG,YAAY,CAAC,aAAkC,CAAC;4BACpE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;gCAChC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;4BACvD,CAAC;4BACD,IAAI,YAAY,CAAC;4BACjB,IAAI,CAAC;gCACH,YAAY,GAAG,eAAe,CAAC,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gCAC1E,MAAM,YAAY,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;4BAChD,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCACf,IAAI,YAAY,CAAC,aAAa,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;oCACrD,YAAY,GAAG,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;gCACpE,CAAC;qCAAM,CAAC;oCACN,MAAM,KAAK,CAAC;gCACd,CAAC;4BACH,CAAC;4BACD,MAAM,iBAAiB,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;4BACpD,IAAI,CAAC,iBAAiB,EAAE,CAAC;gCACvB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;4BACnD,CAAC;4BACD,MAAM,kBAAkB,CAAC,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;4BACvF,MAAM;wBACR,KAAK,aAAa;4BAChB,MAAM,UAAU,GAAG,YAAY,CAAC,aAAiC,CAAC;4BAClE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;gCAChC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;4BACvD,CAAC;4BACD,IAAI,WAAW,CAAC;4BAChB,IAAI,CAAC;gCACH,WAAW,GAAG,eAAe,CAAC,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gCACzE,MAAM,WAAW,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;4BAC/C,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCACf,IAAI,YAAY,CAAC,aAAa,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;oCACrD,WAAW,GAAG,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;gCACnE,CAAC;qCAAM,CAAC;oCACN,MAAM,KAAK,CAAC;gCACd,CAAC;4BACH,CAAC;4BACD,MAAM,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;4BACvE,MAAM;oBACV,CAAC;oBAED,qCAAqC;oBACrC,MAAM,gBAAgB,GAAwB;wBAC5C,SAAS;wBACT,QAAQ,EAAE,IAAI;wBACd,UAAU,EAAE,YAAY,CAAC,UAAU;wBACnC,aAAa,EAAE,YAAY,CAAC,aAAa;wBACzC,GAAG,CAAC,YAAY,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,YAAY,CAAC,aAAa,EAAE,CAAC;qBACjF,CAAC;oBACF,aAAa,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBACvC,CAAC,CAAC,CAAC;gBACH,SAAS,CAAC,oBAAoB;YAChC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,6CAA6C;gBAC7C,OAAO,CAAC,IAAI,CAAC,wDAAwD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACjI,CAAC;QACH,CAAC;QAED,kEAAkE;QAClE,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,YAAY,QAAQ,GAAG,CAAC,CAAC;QAC3E,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;gBAC/B,2DAA2D;gBAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC9B,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBAEnE,MAAM,WAAW,GAAgB;oBAC/B,aAAa,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;wBAClD,SAAS,EAAE,YAAY,CAAC,SAAS;wBACjC,QAAQ,EAAE,YAAY,CAAC,QAAQ;wBAC/B,UAAU,EAAE,YAAY,CAAC,UAAU;wBACnC,mDAAmD;wBACnD,GAAG,EAAE,YAAY,CAAC,UAAU,KAAK,YAAY;4BAC3C,CAAC,CAAE,YAAY,CAAC,aAAqB,CAAC,MAAM,EAAE,GAAG,IAAI,SAAS;4BAC9D,CAAC,CAAC,SAAS;qBACd,CAAC,CAAC;oBACH,YAAY,EAAE;wBACZ,GAAG,EAAE,UAAU;wBACf,SAAS,EAAE,gBAAgB;qBAC5B;oBACD,UAAU,EAAE,KAAK,CAAC,MAAM;oBACxB,gBAAgB,EAAE,SAAS;iBAC5B,CAAC;gBAEF,wCAAwC;gBACxC,MAAM,WAAW,GAA0B,EAAE,CAAC;gBAC9C,MAAM,iBAAiB,GAAG,EAAE,CAAC,CAAC,yBAAyB;gBACvD,IAAI,WAAW,GAAG,CAAC,CAAC;gBACpB,IAAI,kBAAkB,GAAG,KAAK,CAAC;gBAE/B,2DAA2D;gBAC3D,OAAO,CAAC,kBAAkB,IAAI,WAAW,GAAG,iBAAiB,EAAE,CAAC;oBAC9D,WAAW,EAAE,CAAC;oBAEd,uEAAuE;oBACvE,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;wBACpB,kBAAkB,GAAG,MAAM,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;wBACpF,IAAI,kBAAkB,EAAE,CAAC;4BACvB,OAAO,CAAC,GAAG,CAAC,oCAAoC,WAAW,GAAG,CAAC,YAAY,CAAC,CAAC;4BAC7E,MAAM;wBACR,CAAC;wBACD,OAAO,CAAC,GAAG,CAAC,iDAAiD,WAAW,MAAM,CAAC,CAAC;wBAChF,MAAM;oBACR,CAAC;oBACD,+CAA+C;oBAC/C,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;oBAExE,IAAI,UAA+B,CAAC;oBAEpC,uDAAuD;oBACvD,kCAAkC;oBAElC,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;wBACxB,KAAK,YAAY;4BACf,kEAAkE;4BAClE,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;4BACpF,MAAM,iBAAiB,GAAG,MAAM,uBAAuB,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;4BAEhG,UAAU,GAAG;gCACX,SAAS;gCACT,QAAQ,EAAE,IAAI;gCACd,UAAU,EAAE,YAAY;gCACxB,aAAa,EAAE,iBAAiB;6BACjC,CAAC;4BACF,MAAM;wBAER,KAAK,OAAO;4BACV,6DAA6D;4BAC7D,MAAM,iBAAiB,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;4BAEhF,+DAA+D;4BAC/D,IAAI,CAAC,iBAAiB,IAAI,CAAC,iBAAiB,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;gCACxG,MAAM,IAAI,KAAK,CAAC,iFAAiF,IAAI,EAAE,CAAC,CAAC;4BAC3G,CAAC;4BAED,oFAAoF;4BACpF,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAW,GAAG,CAAC,CAAC,UAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;4BACnH,IAAI,CAAC,iBAAiB,EAAE,CAAC;gCACvB,MAAM,IAAI,KAAK,CAAC,gDAAgD,IAAI,EAAE,CAAC,CAAC;4BAC1E,CAAC;4BACD,sDAAsD;4BACtD,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;gCAC/B,MAAM,IAAI,KAAK,CAAC,2DAA2D,IAAI,EAAE,CAAC,CAAC;4BACrF,CAAC;4BACD,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;4BAC5D,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;4BAE9G,0DAA0D;4BAC1D,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;gCAC1B,MAAM,IAAI,KAAK,CAAC,iDAAiD,IAAI,EAAE,CAAC,CAAC;4BAC3E,CAAC;4BACD,MAAM,aAAa,GAAwB;gCACzC,QAAQ,EAAE,WAAW,CAAC,QAAQ;gCAC9B,OAAO,EAAE,iBAAiB,CAAC,OAAO;6BACnC,CAAC;4BAEF,UAAU,GAAG;gCACX,SAAS;gCACT,QAAQ,EAAE,IAAI;gCACd,UAAU,EAAE,OAAO;gCACnB,aAAa,EAAE,WAAW,CAAC,YAAY;gCACvC,aAAa;6BACd,CAAC;4BACF,MAAM;wBAER,KAAK,aAAa;4BAChB,4DAA4D;4BAC5D,MAAM,gBAAgB,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;4BAE9E,wDAAwD;4BACxD,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;gCAC9B,MAAM,IAAI,KAAK,CAAC,0DAA0D,IAAI,EAAE,CAAC,CAAC;4BACpF,CAAC;4BACD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;4BACnE,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;4BAEtG,gFAAgF;4BAChF,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC;4BACrC,MAAM,aAAa,GAAG,UAAU,CAAC,YAAY,CAAC;4BAE9C,0DAA0D;4BAC1D,IAAI,CAAC,QAAQ,EAAE,CAAC;gCACd,MAAM,IAAI,KAAK,CAAC,gDAAgD,IAAI,EAAE,CAAC,CAAC;4BAC1E,CAAC;4BACD,MAAM,iBAAiB,GAAwB;gCAC7C,QAAQ;gCACR,OAAO,EAAE,gBAAgB,CAAC,OAAO;6BAClC,CAAC;4BAEF,UAAU,GAAG;gCACX,SAAS;gCACT,QAAQ,EAAE,IAAI;gCACd,UAAU,EAAE,aAAa;gCACzB,aAAa;gCACb,aAAa,EAAE,iBAAiB;6BACjC,CAAC;4BACF,MAAM;wBAER;4BACE,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;oBACpE,CAAC;oBAED,wCAAwC;oBACxC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAE7B,6DAA6D;oBAC7D,mDAAmD;oBACnD,IAAI,WAAW,KAAK,CAAC,IAAI,WAAW,IAAI,iBAAiB,EAAE,CAAC;wBAC1D,kBAAkB,GAAG,MAAM,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;oBACtF,CAAC;gBACH,CAAC;gBAED,iDAAiD;gBACjD,mEAAmE;gBACnE,aAAa,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;gBAEnC,IAAI,WAAW,IAAI,iBAAiB,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAC5D,OAAO,CAAC,IAAI,CAAC,gCAAgC,iBAAiB,eAAe,IAAI,yCAAyC,CAAC,CAAC;gBAC9H,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,mDAAmD;YACnD,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,aAAa,CACjB,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,KAAK,CACb,QAAQ,SAAS,GAAG,CAAC,YAAY,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACnG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,yFAAyF;IACzF,6EAA6E;IAC7E,IAAI,YAAY,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,6CAA6C;QAC7C,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC7E,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,IAAI,CAAC;QAEjD,6DAA6D;QAC7D,IAAI,iBAAiB,IAAI,iBAAiB,EAAE,CAAC;YAC3C,yEAAyE;YACzE,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YACnE,MAAM,eAAe,GAAG,gBAAgB,KAAK,IAAI,CAAC;YAClD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAErC,4DAA4D;YAC5D,wEAAwE;YACxE,uEAAuE;YACvE,MAAM,WAAW,GAAiC,EAAE,CAAC;YACrD,IAAI,gBAAgB,EAAE,CAAC;gBACrB,gGAAgG;gBAChG,IAAI,gBAAgB,CAAC,WAAW,EAAE,CAAC;oBACjC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;gBAC3D,CAAC;qBAAM,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC;oBAClC,mCAAmC;oBACnC,KAAK,MAAM,IAAI,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC;wBAC1C,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;oBACpC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,iEAAiE;YACjE,gFAAgF;YAChF,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;gBACjC,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC7C,MAAM,QAAQ,GAAwC;oBACpD,QAAQ;oBACR,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,aAAa,EAAE,IAAI,CAAC,aAAa;oBACjC,UAAU,EAAE,GAAG;iBAChB,CAAC;gBAEF,wDAAwD;gBACxD,MAAM,YAAY,GAAiB,IAAI,CAAC,aAAa;oBACnD,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE;oBACpD,CAAC,CAAC,QAAwB,CAAC;gBAE7B,+EAA+E;gBAC/E,WAAW,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAC;YACvC,CAAC;YAED,wEAAwE;YACxE,sCAAsC;YACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC5C,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;YACnD,MAAM,aAAa,GAAmB,QAAQ,CAAC;YAE/C,oFAAoF;YACpF,MAAM,QAAQ,GAAa;gBACzB,QAAQ;gBACR,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,uDAAuD;gBACpE,KAAK,EAAE,aAAa,EAAE,wCAAwC;gBAC9D,KAAK,EAAE;oBACL,UAAU,EAAE,KAAK;oBACjB,SAAS,EAAE,KAAK;oBAChB,sBAAsB,EAAE,cAAc;oBACtC,YAAY,EAAE,KAAK;oBACnB,eAAe,EAAE,KAAK;oBACtB,SAAS,EAAE,KAAK;oBAChB,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,IAAI,GAAG;oBACpD,YAAY,EAAE,GAAG;oBACjB,YAAY,EAAE,IAAI;iBACnB;aACF,CAAC;YAEF,MAAM,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YAE3C,4CAA4C;YAC5C,IAAI,eAAe,EAAE,CAAC;gBACpB,aAAa,CACX,QAAQ,EACR,aAAa,EACb,mDAAmD,CACpD,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,+DAA+D;YAC/D,OAAO,CAAC,IAAI,CAAC,iCAAiC,iBAAiB,OAAO,iBAAiB,iBAAiB,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC;AACH,CAAC;AACD,SAAS,YAAY,CAAC,OAA6B,EAAE,GAAG,MAAa;IACnE,uDAAuD;IACvD,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;QAC1C,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,qEAAqE;IACrE,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SAC/B,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAK3B,EAAE,EAAE;IACH,oDAAoD;IACpD,2DAA2D;IAC3D,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,EAAE,IAAI,IAAI,SAAS,CAAC;IAExD,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC;IAC3C,0BAA0B;IAC1B,MAAM,gBAAgB,GAAG,kBAAkB,EAAE,CAAC;IAE9C,OAAO,KAAK,EAAE,MAA4B,EAAE,GAAG,IAAe,EAAE,EAAE;QAChE,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5C,OAAO,MAAM,KAAK,CAAC,KAAK,EAAE;YACxB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,gBAAgB;SACjB,CAAC,CAAC;IACL,CAAC,CAAA;AACH,CAAC,CAAA"}