{"version":3,"file":"index-BaUNEwrZ.cjs","sources":["../../lib/vowel/platforms/shopify/router.ts","../../lib/vowel/platforms/shopify/routes.ts","../../lib/vowel/managers/CrossTabManager.ts","../../lib/vowel/platforms/shopify/actions.ts","../../lib/vowel/platforms/shopify/index.ts"],"sourcesContent":["/**\n * Shopify Router Adapter\n * Extends generic controlled navigation with Shopify-specific features\n * \n * Currently, the generic implementation works perfectly for Shopify,\n * so this is a simple extension with no overrides needed.\n */\n\nimport { ControlledNavigationRouter } from '../generic/router';\nimport type { ControlledNavigationRouterOptions } from '../generic/router';\n\n/**\n * Router adapter for Shopify storefronts\n * Opens navigation in a dedicated tab to preserve voice agent session\n * \n * @example\n * ```ts\n * const router = new ShopifyRouterAdapter();\n * router.setRoutes(discoveredRoutes);\n * \n * // Navigate to a collection (opens in separate tab)\n * await router.navigate('/collections/new-arrivals');\n * ```\n */\nexport class ShopifyRouterAdapter extends ControlledNavigationRouter {\n  constructor(options: ControlledNavigationRouterOptions = {}) {\n    // Pass Shopify-specific config to generic router\n    super({\n      channelName: options.channelName || 'vowel-navigation',\n      config: {\n        ...options.config,\n        features: ['navigation', 'addToCart', ...(options.config?.features || [])]\n      }\n    });\n  }\n\n  // No overrides needed - generic implementation works perfectly for Shopify\n  // Can add Shopify-specific methods here if needed in the future\n}\n\n","/**\n * Shopify Route Generator\n * Extends generic route generator with Shopify-specific URL categorization\n */\n\nimport { GenericRouteGenerator, GenericUrlCategorizer } from '../generic/routes';\nimport type { IUrlCategorizer, UrlCategory } from '../generic/routes';\nimport type { VowelRoute } from '../../types';\n\n/**\n * Shopify URL Categorizer\n * Recognizes Shopify-specific URL patterns (products, collections, etc.)\n */\nexport class ShopifyUrlCategorizer extends GenericUrlCategorizer implements IUrlCategorizer {\n  /**\n   * Categorize a URL based on Shopify patterns\n   * Falls back to generic categorization for non-Shopify URLs\n   * \n   * @param url - URL to categorize\n   * @returns Category information\n   */\n  categorizeUrl(url: string): UrlCategory {\n    let pathname: string;\n    \n    try {\n      pathname = new URL(url).pathname;\n    } catch (error) {\n      console.warn(`⚠️ Failed to parse URL ${url}, treating as pathname`);\n      pathname = url.startsWith('/') ? url : `/${url}`;\n    }\n\n    // Shopify-specific patterns\n\n    // Product pages\n    if (pathname.match(/^\\/products\\/[^\\/]+$/)) {\n      return {\n        type: \"product\",\n        category: \"products\",\n        description: this.extractProductDescription(pathname),\n        priority: \"high\",\n      };\n    }\n\n    // Collection pages\n    if (pathname.match(/^\\/collections\\/[^\\/]+$/)) {\n      return {\n        type: \"collection\",\n        category: \"collections\",\n        description: this.extractCollectionDescription(pathname),\n        priority: \"high\",\n      };\n    }\n\n    // Static pages\n    if (pathname.match(/^\\/pages\\/[^\\/]+$/)) {\n      return {\n        type: \"page\",\n        category: \"pages\",\n        description: this.extractShopifyPageDescription(pathname),\n        priority: \"medium\",\n      };\n    }\n\n    // Blog posts\n    if (pathname.match(/^\\/blogs\\/[^\\/]+\\/[^\\/]+$/)) {\n      return {\n        type: \"blog\",\n        category: \"blogs\",\n        description: this.extractShopifyBlogDescription(pathname),\n        priority: \"medium\",\n      };\n    }\n\n    // Shopify-specific common pages\n    const shopifyPages = this.getShopifyCommonPages();\n    if (shopifyPages[pathname]) {\n      return {\n        type: shopifyPages[pathname].type,\n        category: shopifyPages[pathname].type,\n        description: shopifyPages[pathname].description,\n        priority: shopifyPages[pathname].priority,\n      };\n    }\n\n    // Fall back to generic categorization\n    return super.categorizeUrl(url);\n  }\n\n  /**\n   * Get Shopify-specific common pages\n   * \n   * @returns Common Shopify pages mapping\n   */\n  protected getShopifyCommonPages(): Record<string, { type: string; description: string; priority: string }> {\n    return {\n      \"/\": { type: \"home\", description: \"Store homepage\", priority: \"highest\" },\n      \"/products\": { type: \"products\", description: \"Browse all products\", priority: \"high\" },\n      \"/collections\": { type: \"collections\", description: \"Browse all collections\", priority: \"high\" },\n      \"/cart\": { type: \"cart\", description: \"Shopping cart\", priority: \"high\" },\n      \"/search\": { type: \"search\", description: \"Search products\", priority: \"medium\" },\n      \"/account\": { type: \"account\", description: \"Customer account\", priority: \"medium\" },\n      \"/account/login\": { type: \"account\", description: \"Customer login\", priority: \"medium\" },\n      \"/account/register\": { type: \"account\", description: \"Customer registration\", priority: \"medium\" },\n    };\n  }\n\n  /**\n   * Extract product description from URL path\n   * \n   * @param pathname - URL path\n   * @returns Human-readable description\n   */\n  private extractProductDescription(pathname: string): string {\n    const handle = pathname.split(\"/\").pop();\n    return `View ${handle?.replace(/-/g, \" \")} product`;\n  }\n\n  /**\n   * Extract collection description from URL path\n   * \n   * @param pathname - URL path\n   * @returns Human-readable description\n   */\n  private extractCollectionDescription(pathname: string): string {\n    const handle = pathname.split(\"/\").pop();\n    return `Browse ${handle?.replace(/-/g, \" \")} collection`;\n  }\n\n  /**\n   * Extract Shopify page description from URL path\n   * \n   * @param pathname - URL path\n   * @returns Human-readable description\n   */\n  private extractShopifyPageDescription(pathname: string): string {\n    const handle = pathname.split(\"/\").pop();\n    return `${handle?.replace(/-/g, \" \")} page`;\n  }\n\n  /**\n   * Extract Shopify blog post description from URL path\n   * \n   * @param pathname - URL path\n   * @returns Human-readable description\n   */\n  private extractShopifyBlogDescription(pathname: string): string {\n    const parts = pathname.split(\"/\");\n    const postHandle = parts[3];\n    return `${postHandle?.replace(/-/g, \" \")} blog post`;\n  }\n}\n\n/**\n * Shopify Route Generator\n * Extends generic route generator with Shopify-specific features\n * \n * @example\n * ```ts\n * const generator = new ShopifyRouteGenerator();\n * const routes = await generator.generateRoutes('https://mystore.com');\n * console.log(`Generated ${routes.length} routes`);\n * ```\n */\nexport class ShopifyRouteGenerator extends GenericRouteGenerator {\n  constructor() {\n    super(new ShopifyUrlCategorizer());\n  }\n\n  /**\n   * Get Shopify-specific hardcoded routes\n   * These routes are guaranteed to be included regardless of sitemap parsing\n   * \n   * @returns Hardcoded Shopify routes\n   */\n  protected getHardcodedRoutes(): VowelRoute[] {\n    // Note: In production, you might want to make this configurable\n    // or remove the hardcoded store URL\n    return [];\n  }\n\n  /**\n   * Get Shopify-specific fallback routes\n   * Used when sitemap parsing fails\n   * \n   * @returns Basic Shopify routes\n   */\n  protected getFallbackRoutes(): VowelRoute[] {\n    return [\n      {\n        path: \"/\",\n        description: \"Store homepage\",\n        metadata: { type: \"home\", priority: \"highest\" },\n      },\n      {\n        path: \"/products\",\n        description: \"Browse all products\",\n        metadata: { type: \"products\", priority: \"high\" },\n      },\n      {\n        path: \"/collections\",\n        description: \"Browse collections\",\n        metadata: { type: \"collections\", priority: \"high\" },\n      },\n      {\n        path: \"/cart\",\n        description: \"Shopping cart\",\n        metadata: { type: \"cart\", priority: \"high\" },\n      },\n      {\n        path: \"/search\",\n        description: \"Search products\",\n        metadata: { type: \"search\", priority: \"medium\" },\n      },\n    ];\n  }\n}\n\n","/**\n * Cross-Tab Communication Manager\n * Handles communication between main page (with voice agent) and navigation tab\n * Uses BroadcastChannel API for reliable cross-tab messaging\n */\n\n/**\n * Message types for cross-tab communication\n */\nexport type CrossTabMessageType = \n  | 'addToCart'\n  | 'removeFromCart'\n  | 'updateQuantity'\n  | 'navigate'\n  | 'getContext'\n  | 'contextResponse'\n  // Smart DOM Tools (Levenshtein Search with Spoken IDs)\n  | 'searchElements'           // Search by term (text, classes, aria-labels, values, etc.)\n  | 'searchElementsResponse'   // Response with spoken IDs (e.g., \"apple_banana\")\n  | 'getPageSnapshot'           // Get compressed view of all elements\n  | 'pageSnapshotResponse'     // Response with compressed snapshot\n  // DOM Interaction Tools (use spoken IDs from search)\n  | 'clickElement'\n  | 'typeIntoElement'\n  | 'pressKey'\n  | 'focusElement'\n  | 'scrollToElement'\n  | 'domActionResponse';\n\n/**\n * Cross-tab message structure\n */\nexport interface CrossTabMessage {\n  type: CrossTabMessageType;\n  payload: any;\n  timestamp: number;\n  messageId: string;\n}\n\n/**\n * Cross-tab communication manager\n * Manages BroadcastChannel for communication between main tab and navigation tab\n * \n * @example\n * ```ts\n * // On main page (with voice agent)\n * const manager = CrossTabManager.getInstance();\n * manager.sendMessage('addToCart', { productId: '123', quantity: 1 });\n * \n * // On navigation tab\n * const manager = CrossTabManager.getInstance();\n * manager.onMessage((message) => {\n *   if (message.type === 'addToCart') {\n *     // Add item to cart\n *   }\n * });\n * ```\n */\nexport class CrossTabManager {\n  private static instance: CrossTabManager | null = null;\n  private channel: BroadcastChannel | null = null;\n  private messageHandlers: Map<CrossTabMessageType, Set<(payload: any) => void>> = new Map();\n  private readonly channelName = 'vowel-navigation';\n\n  private constructor() {\n    this.initChannel();\n  }\n\n  /**\n   * Get singleton instance\n   */\n  static getInstance(): CrossTabManager {\n    if (!CrossTabManager.instance) {\n      CrossTabManager.instance = new CrossTabManager();\n    }\n    return CrossTabManager.instance;\n  }\n\n  /**\n   * Initialize BroadcastChannel\n   */\n  private initChannel(): void {\n    if (typeof window === 'undefined' || !window.BroadcastChannel) {\n      console.warn('⚠️ BroadcastChannel not supported in this browser');\n      return;\n    }\n\n    try {\n      this.channel = new BroadcastChannel(this.channelName);\n      \n      this.channel.onmessage = (event: MessageEvent<CrossTabMessage>) => {\n        const message = event.data;\n        console.log('📨 Received cross-tab message:', message.type, message.payload);\n        \n        // Call registered handlers for this message type\n        const handlers = this.messageHandlers.get(message.type);\n        if (handlers) {\n          handlers.forEach(handler => {\n            try {\n              handler(message.payload);\n            } catch (error) {\n              console.error('❌ Error in message handler:', error);\n            }\n          });\n        }\n      };\n\n      console.log('✅ CrossTabManager initialized');\n    } catch (error) {\n      console.error('❌ Failed to initialize BroadcastChannel:', error);\n    }\n  }\n\n  /**\n   * Send a message to all tabs\n   */\n  sendMessage(type: CrossTabMessageType, payload: any): void {\n    if (!this.channel) {\n      console.warn('⚠️ BroadcastChannel not available');\n      return;\n    }\n\n    const message: CrossTabMessage = {\n      type,\n      payload,\n      timestamp: Date.now(),\n      messageId: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n    };\n\n    try {\n      this.channel.postMessage(message);\n      console.log('📤 Sent cross-tab message:', type, payload);\n    } catch (error) {\n      console.error('❌ Failed to send message:', error);\n    }\n  }\n\n  /**\n   * Register a message handler for a specific message type\n   * \n   * @param type - Message type to listen for\n   * @param handler - Callback function\n   * @returns Unsubscribe function\n   */\n  onMessage(type: CrossTabMessageType, handler: (payload: any) => void): () => void {\n    if (!this.messageHandlers.has(type)) {\n      this.messageHandlers.set(type, new Set());\n    }\n\n    const handlers = this.messageHandlers.get(type)!;\n    handlers.add(handler);\n\n    console.log(`👂 Registered handler for message type: ${type}`);\n\n    // Return unsubscribe function\n    return () => {\n      handlers.delete(handler);\n      if (handlers.size === 0) {\n        this.messageHandlers.delete(type);\n      }\n    };\n  }\n\n  /**\n   * Register a global message handler (receives all messages)\n   * \n   * @param handler - Callback function that receives the full message\n   * @returns Unsubscribe function\n   */\n  onAnyMessage(handler: (message: CrossTabMessage) => void): () => void {\n    if (!this.channel) {\n      console.warn('⚠️ BroadcastChannel not available');\n      return () => {};\n    }\n\n    const listener = (event: MessageEvent<CrossTabMessage>) => {\n      try {\n        handler(event.data);\n      } catch (error) {\n        console.error('❌ Error in global message handler:', error);\n      }\n    };\n\n    this.channel.addEventListener('message', listener);\n\n    // Return unsubscribe function\n    return () => {\n      if (this.channel) {\n        this.channel.removeEventListener('message', listener);\n      }\n    };\n  }\n\n  /**\n   * Send a request and wait for a response\n   * Useful for getting data from the navigation tab\n   * \n   * @param type - Request message type\n   * @param payload - Request payload\n   * @param responseType - Expected response message type\n   * @param timeout - Timeout in milliseconds (default: 5000)\n   * @returns Promise that resolves with response payload\n   */\n  async request(\n    type: CrossTabMessageType,\n    payload: any,\n    responseType: CrossTabMessageType,\n    timeout: number = 5000\n  ): Promise<any> {\n    return new Promise((resolve, reject) => {\n      const timeoutId = setTimeout(() => {\n        unsubscribe();\n        reject(new Error(`Request timeout after ${timeout}ms`));\n      }, timeout);\n\n      const unsubscribe = this.onMessage(responseType, (responsePayload) => {\n        clearTimeout(timeoutId);\n        unsubscribe();\n        resolve(responsePayload);\n      });\n\n      this.sendMessage(type, payload);\n    });\n  }\n\n  /**\n   * Close the channel (cleanup)\n   */\n  close(): void {\n    if (this.channel) {\n      this.channel.close();\n      this.channel = null;\n      console.log('🔌 CrossTabManager closed');\n    }\n  }\n\n  /**\n   * Check if BroadcastChannel is supported\n   */\n  static isSupported(): boolean {\n    return typeof window !== 'undefined' && !!window.BroadcastChannel;\n  }\n}\n\n","/**\n * Shopify Action Handlers\n * Handles voice actions in the Shopify storefront context\n * Uses cross-tab communication to control navigation tab from main page\n */\n\nimport type { ToolResult } from \"../../types\";\nimport { CrossTabManager } from \"../../managers/CrossTabManager\";\n\n/**\n * Product interface for DOM extraction\n */\ninterface Product {\n  id: string;\n  title: string;\n  price?: string;\n  image?: string;\n  element?: Element;\n}\n\n/**\n * Shopify Store Data Manager\n * Handles client-side store data operations through DOM manipulation\n * \n * @example\n * ```ts\n * const manager = new ShopifyStoreManager();\n * const products = await manager.getProducts();\n * await manager.addToCart('product-123', 1);\n * ```\n */\nexport class ShopifyStoreManager {\n  private cache: Map<string, Product[]> = new Map();\n\n  /**\n   * Get products from the current page\n   * Extracts product information from DOM elements\n   * \n   * @returns Products array\n   */\n  async getProducts(): Promise<Product[]> {\n    const cacheKey = \"products\";\n\n    if (this.cache.has(cacheKey)) {\n      return this.cache.get(cacheKey)!;\n    }\n\n    // Try to get products from current page\n    const products = this.extractProductsFromDOM();\n\n    // Cache results\n    this.cache.set(cacheKey, products);\n    return products;\n  }\n\n  /**\n   * Extract products from current DOM\n   * Searches for common Shopify product element patterns\n   * \n   * @returns Products found on current page\n   */\n  private extractProductsFromDOM(): Product[] {\n    const products: Product[] = [];\n\n    // Look for product cards/elements using common selectors\n    const productSelectors = [\n      \"[data-product-id]\",\n      \".product-card\",\n      \".product-item\",\n      \".product\",\n      \"[data-product]\",\n    ];\n\n    productSelectors.forEach((selector) => {\n      const elements = document.querySelectorAll(selector);\n      elements.forEach((element) => {\n        const product = this.extractProductFromElement(element);\n        if (product) {\n          products.push(product);\n        }\n      });\n    });\n\n    return products;\n  }\n\n  /**\n   * Extract product data from DOM element\n   * Attempts to find product information using common patterns\n   * \n   * @param element - Product element\n   * @returns Product data or null\n   */\n  private extractProductFromElement(element: Element): Product | null {\n    try {\n      const id =\n        element.getAttribute(\"data-product-id\") ||\n        element\n          .querySelector(\"[data-product-id]\")\n          ?.getAttribute(\"data-product-id\");\n\n      const title =\n        element\n          .querySelector(\"h1, h2, h3, .title, [data-product-title]\")\n          ?.textContent?.trim() ||\n        element.querySelector(\".product-title\")?.textContent?.trim();\n\n      const price =\n        element.querySelector(\".price, [data-price]\")?.textContent?.trim() ||\n        element.querySelector(\".product-price\")?.textContent?.trim();\n\n      const image = element.querySelector(\"img\")?.src;\n\n      if (id && title) {\n        return {\n          id,\n          title,\n          price,\n          image,\n          element, // Keep reference for DOM interactions\n        };\n      }\n    } catch (error) {\n      console.warn(\"Failed to extract product from element:\", error);\n    }\n\n    return null;\n  }\n\n  /**\n   * Add product to cart\n   * Simulates clicking the \"Add to Cart\" button\n   * \n   * @param productId - Product ID to add\n   * @param quantity - Quantity to add (default: 1)\n   * @returns Result of add operation\n   */\n  async addToCart(\n    productId: string,\n    quantity: number = 1\n  ): Promise<{ success: boolean; productId: string; quantity: number; error?: string }> {\n    try {\n      // Use Shopify AJAX Cart API to add item\n      // This works across tabs and doesn't require DOM manipulation\n      const response = await fetch('/cart/add.js', {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          id: productId,\n          quantity: quantity,\n        }),\n      });\n\n      if (!response.ok) {\n        const error = await response.text();\n        throw new Error(`Failed to add to cart: ${error}`);\n      }\n\n      const result = await response.json();\n      console.log('✅ Added to cart:', result);\n      \n      return { success: true, productId, quantity };\n    } catch (error) {\n      // If main tab fails, try sending message to navigation tab\n      console.warn('⚠️ Main tab addToCart failed, sending to navigation tab');\n      try {\n        const crossTab = CrossTabManager.getInstance();\n        crossTab.sendMessage('addToCart', { productId, quantity });\n        return { success: true, productId, quantity };\n      } catch (crossTabError) {\n        return {\n          success: false,\n          productId,\n          quantity,\n          error: error instanceof Error ? error.message : String(error),\n        };\n      }\n    }\n  }\n\n  /**\n   * Search products by query\n   * Filters products on current page by search term\n   * \n   * @param query - Search query\n   * @returns Matching products\n   */\n  async searchProducts(query: string): Promise<Product[]> {\n    const products = await this.getProducts();\n    const searchTerm = query.toLowerCase();\n\n    return products.filter(\n      (product) =>\n        product.title?.toLowerCase().includes(searchTerm) ||\n        product.id?.toLowerCase().includes(searchTerm)\n    );\n  }\n\n  /**\n   * Navigate to collection\n   * Uses router-based navigation to preserve voice agent connection\n   * \n   * @param collectionHandle - Collection handle/slug\n   * @param navigate - Navigation function from router\n   * @returns Navigation result\n   */\n  async navigateToCollection(\n    collectionHandle: string,\n    navigate?: NavigateFunction\n  ): Promise<{\n    success: boolean;\n    navigated: boolean;\n    url: string;\n  }> {\n    const collectionUrl = `/collections/${collectionHandle}`;\n    \n    if (navigate) {\n      // Use router navigation to preserve voice connection\n      await navigate(collectionUrl);\n    } else {\n      // Fallback to full page navigation\n      console.warn(\"⚠️ No navigate function provided, using full page navigation\");\n      window.location.href = collectionUrl;\n    }\n    \n    return { success: true, navigated: true, url: collectionUrl };\n  }\n\n  /**\n   * Get store information from page\n   * \n   * @returns Store info\n   */\n  async getStoreInfo(): Promise<{\n    name: string;\n    url: string;\n    currency: string;\n    locale: string;\n  }> {\n    return {\n      name:\n        document.querySelector(\"title\")?.textContent?.split(\" | \")[0] ||\n        \"Store\",\n      url: window.location.origin,\n      currency: \"USD\", // Would need to detect this properly from Shopify context\n      locale: navigator.language,\n    };\n  }\n}\n\n/**\n * Navigation function type\n */\ntype NavigateFunction = (path: string) => Promise<void>;\n\n/**\n * Shopify Action Handler\n * Implements voice actions for Shopify storefront\n * Registers actions that can be called by the voice agent\n * \n * @example\n * ```ts\n * const handler = new ShopifyActionHandler(router.navigate.bind(router));\n * \n * // Register with Vowel client\n * vowel.registerAction('searchProducts', \n *   handler.getActionDefinition('searchProducts'),\n *   handler.searchProducts.bind(handler)\n * );\n * ```\n */\nexport class ShopifyActionHandler {\n  private storeManager: ShopifyStoreManager;\n  private navigate?: NavigateFunction;\n\n  constructor(navigate?: NavigateFunction) {\n    this.storeManager = new ShopifyStoreManager();\n    this.navigate = navigate;\n  }\n\n  /**\n   * Search for products\n   * Navigates the controlled tab to search page and extracts results\n   * \n   * @param params - Search parameters\n   * @returns Search results\n   */\n  async searchProducts(params: { query: string }): Promise<ToolResult> {\n    try {\n      console.log('🔍 [ShopifyActionHandler] Searching for:', params.query);\n      \n      // Navigate controlled tab to search page\n      const searchUrl = `/search?q=${encodeURIComponent(params.query)}`;\n      if (this.navigate) {\n        console.log('   🧭 Navigating controlled tab to search page:', searchUrl);\n        await this.navigate(searchUrl);\n        \n        // Wait a bit for page to load and results to be available\n        await new Promise(resolve => setTimeout(resolve, 1500));\n        \n        // Request search results from controlled tab via CrossTabManager\n        console.log('   📡 Requesting search results from controlled tab...');\n        const crossTab = CrossTabManager.getInstance();\n        \n        try {\n          const context = await crossTab.request(\n            'getContext',\n            { type: 'search', query: params.query },\n            'contextResponse',\n            5000 // 5 second timeout\n          );\n          \n          console.log('   ✅ Received search results:', context);\n          \n          const products = context.products || [];\n          return {\n            success: true,\n            result: {\n              products: products.slice(0, 10),\n              total: products.length,\n              query: params.query,\n              searchUrl: searchUrl\n            },\n            response: products.length > 0\n              ? `Found ${products.length} products matching \"${params.query}\". The search page is now open in the content window. You can ask me to go to a specific product by name.`\n              : `No products found for \"${params.query}\". Try a different search term.`,\n          };\n        } catch (timeoutError) {\n          console.warn('   ⚠️ Timeout waiting for search results, returning navigation success');\n          return {\n            success: true,\n            result: {\n              products: [],\n              total: 0,\n              query: params.query,\n              searchUrl: searchUrl\n            },\n            response: `Opened search page for \"${params.query}\". The results should be visible in the content window.`,\n          };\n        }\n      } else {\n        // Fallback: search in current page only\n        console.warn('   ⚠️ No navigate function, searching current page only');\n        const products = await this.storeManager.searchProducts(params.query);\n        return {\n          success: true,\n          result: {\n            products: products.slice(0, 10).map((p) => ({\n              id: p.id,\n              title: p.title,\n              price: p.price,\n              image: p.image,\n            })),\n            total: products.length,\n            query: params.query,\n          },\n          response: `Found ${products.length} products matching \"${params.query}\" on current page`,\n        };\n      }\n    } catch (error) {\n      console.error('   ❌ Search error:', error);\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Add product to cart\n   * \n   * @param params - Add to cart parameters\n   * @returns Add result\n   */\n  async addToCart(params: {\n    productId?: string;\n    quantity?: number;\n  }): Promise<ToolResult> {\n    try {\n      if (!params.productId) {\n        throw new Error(\"Product ID is required\");\n      }\n\n      const result = await this.storeManager.addToCart(\n        params.productId,\n        params.quantity || 1\n      );\n\n      if (result.success) {\n        return {\n          success: true,\n          result,\n          response: `Added product to cart`,\n        };\n      } else {\n        return {\n          success: false,\n          error: result.error || \"Failed to add to cart\",\n        };\n      }\n    } catch (error) {\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Navigate to collection\n   * \n   * @param params - Collection parameters\n   * @returns Navigation result\n   */\n  async navigateToCollection(params: { collection: string }): Promise<ToolResult> {\n    try {\n      const result = await this.storeManager.navigateToCollection(\n        params.collection,\n        this.navigate\n      );\n      return {\n        success: true,\n        result,\n        response: `Navigating to ${params.collection} collection`,\n      };\n    } catch (error) {\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Get current page context\n   * \n   * @returns Page context\n   */\n  async getCurrentPageContext(): Promise<ToolResult> {\n    return {\n      success: true,\n      result: {\n        url: window.location.href,\n        pathname: window.location.pathname,\n        search: window.location.search,\n        timestamp: Date.now(),\n      },\n    };\n  }\n\n  /**\n   * Get store information\n   * \n   * @param _params - Info request parameters (unused)\n   * @returns Store information\n   */\n  async getStoreInfo(_params?: { info?: string }): Promise<ToolResult> {\n    try {\n      const info = await this.storeManager.getStoreInfo();\n      return {\n        success: true,\n        result: info,\n        response: `Store: ${info.name} at ${info.url}`,\n      };\n    } catch (error) {\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Navigate to product page\n   * First tries to get products from controlled tab, then searches by name\n   * \n   * @param params - Product parameters\n   * @returns Navigation result\n   */\n  async navigateToProduct(params: {\n    product?: string;\n    productId?: string;\n  }): Promise<ToolResult> {\n    try {\n      console.log('🧭 [ShopifyActionHandler] Navigating to product:', params);\n      \n      // Try to get products from controlled tab first (if we're on search page)\n      const crossTab = CrossTabManager.getInstance();\n      let products: Product[] = [];\n      \n      try {\n        console.log('   📡 Requesting product list from controlled tab...');\n        const context = await crossTab.request(\n          'getContext',\n          { type: 'products' },\n          'contextResponse',\n          3000\n        );\n        products = context.products || [];\n        console.log('   ✅ Got', products.length, 'products from controlled tab');\n      } catch (error) {\n        console.warn('   ⚠️ Could not get products from controlled tab, trying main tab DOM');\n        products = await this.storeManager.getProducts();\n      }\n      \n      // Find product by title or ID\n      const searchTerm = params.product?.toLowerCase() || '';\n      const product = products.find(\n        (p) =>\n          p.title?.toLowerCase().includes(searchTerm) ||\n          p.id === params.productId ||\n          // Fuzzy match for better UX\n          searchTerm.split(' ').every(word => p.title?.toLowerCase().includes(word))\n      );\n\n      if (product && product.id) {\n        // Use handle if available (from controlled tab), otherwise use ID\n        const productHandle = (product as any).handle || product.id;\n        const productUrl = (product as any).url || `/products/${productHandle}`;\n        \n        console.log('   🎯 Found product:', product.title);\n        console.log('   🔗 URL:', productUrl);\n        \n        if (this.navigate) {\n          // Use router navigation to preserve voice connection\n          await this.navigate(productUrl);\n        } else {\n          // Fallback to full page navigation\n          console.warn(\"⚠️ No navigate function provided, using full page navigation\");\n          window.location.href = productUrl;\n        }\n        \n        return {\n          success: true,\n          result: { navigated: true, product: product.title, url: productUrl },\n          response: `Opening ${product.title} in the content window`,\n        };\n      }\n\n      console.warn('   ❌ Product not found:', params);\n      return {\n        success: false,\n        error: `Product not found: \"${params.product || params.productId}\". Try searching first or be more specific.`,\n        response: `I couldn't find that product. Try searching for it first, or be more specific with the product name.`,\n      };\n    } catch (error) {\n      console.error('   ❌ Navigation error:', error);\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Search for elements by term using Levenshtein distance\n   * Returns elements with spoken-word IDs (e.g., \"apple_banana\")\n   * \n   * Searches across all element properties:\n   * - Text content\n   * - CSS classes\n   * - ARIA labels\n   * - Placeholders\n   * - Values (inputs, selects, etc.)\n   * - Element IDs\n   * \n   * @param params - Search parameters\n   * @returns Search results with spoken IDs\n   */\n  /**\n   * @deprecated This function is temporarily disabled. Use getPageSnapshot() instead.\n   * \n   * DEPRECATION NOTICE: searchElements is being replaced with getPageSnapshot.\n   * The AI should always use getPageSnapshot to get a full page view, then search\n   * within the snapshot results client-side.\n   * \n   * This method now redirects to getPageSnapshot() with a deprecation warning.\n   */\n  async searchElements(_params: {\n    query: string;\n    maxResults?: number;\n    minSimilarity?: number;\n    requireInteractive?: boolean;\n    requireVisible?: boolean;\n    tag?: string;\n  }): Promise<ToolResult> {\n    console.warn('⚠️ [ShopifyActionHandler] searchElements() is DEPRECATED');\n    console.warn('   Please use getPageSnapshot() instead for all element queries');\n    console.warn('   Redirecting to getPageSnapshot()...');\n    \n    // Redirect to getPageSnapshot\n    return this.getPageSnapshot({});\n    \n    /* ============================================================================\n     * ORIGINAL IMPLEMENTATION (TEMPORARILY DISABLED)\n     * This code is kept for reference but not currently used.\n     * ============================================================================\n    try {\n      console.log('🔍 [ShopifyActionHandler] Searching for elements...');\n      console.log('   Query:', params.query);\n      console.log('   Options:', params);\n      \n      const crossTab = CrossTabManager.getInstance();\n      \n      const results = await crossTab.request(\n        'searchElements',\n        { query: params.query, options: params },\n        'searchElementsResponse',\n        5000\n      );\n      \n      console.log('✅ [ShopifyActionHandler] Found', results.elements?.length || 0, 'elements');\n      \n      if (results.elements?.length > 0) {\n        console.log('   Top result:', results.elements[0].id, '-', results.elements[0].tag);\n      }\n      \n      return {\n        success: true,\n        result: results,\n        response: `Found ${results.elements?.length || 0} elements matching \"${params.query}\"`,\n      };\n    } catch (error) {\n      console.error('❌ [ShopifyActionHandler] Search elements failed:', error);\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n    ============================================================================ */\n  }\n\n  /**\n   * Click an element on the controlled tab\n   * \n   * @param params.id - Spoken ID from search results (e.g., \"apple_banana\")\n   * @returns Click result\n   */\n  async clickElement(params: { id: string }): Promise<ToolResult> {\n    try {\n      console.log(`🖱️ [ShopifyActionHandler] Clicking element: ${params.id}`);\n      \n      const crossTab = CrossTabManager.getInstance();\n      \n      const result = await crossTab.request(\n        'clickElement',\n        { id: params.id },\n        'domActionResponse',\n        5000\n      );\n      \n      if (result.success) {\n        console.log('✅ [ShopifyActionHandler] Click successful');\n        return {\n          success: true,\n          result,\n          response: `Clicked element ${params.id}`,\n        };\n      } else {\n        console.error('❌ [ShopifyActionHandler] Click failed:', result.error);\n        return {\n          success: false,\n          error: result.error || 'Click failed',\n        };\n      }\n    } catch (error) {\n      console.error('❌ [ShopifyActionHandler] Click error:', error);\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Type text into an element on the controlled tab\n   * \n   * @param params.id - Spoken ID from search results\n   * @param params.text - Text to type\n   * @returns Type result\n   */\n  async typeIntoElement(params: { id: string; text: string }): Promise<ToolResult> {\n    try {\n      console.log(`⌨️ [ShopifyActionHandler] Typing into element: ${params.id}`);\n      console.log('   Text:', params.text);\n      \n      const crossTab = CrossTabManager.getInstance();\n      \n      const result = await crossTab.request(\n        'typeIntoElement',\n        { id: params.id, text: params.text },\n        'domActionResponse',\n        10000 // Longer timeout for typing\n      );\n      \n      if (result.success) {\n        console.log('✅ [ShopifyActionHandler] Type successful');\n        return {\n          success: true,\n          result,\n          response: `Typed \"${params.text}\" into element ${params.id}`,\n        };\n      } else {\n        console.error('❌ [ShopifyActionHandler] Type failed:', result.error);\n        return {\n          success: false,\n          error: result.error || 'Type failed',\n        };\n      }\n    } catch (error) {\n      console.error('❌ [ShopifyActionHandler] Type error:', error);\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Press a key on the controlled tab\n   * \n   * @param params.key - Key to press (e.g., 'Enter', 'Escape')\n   * @returns Key press result\n   */\n  async pressKey(params: { key: string }): Promise<ToolResult> {\n    try {\n      console.log('⌨️ [ShopifyActionHandler] Pressing key:', params.key);\n      \n      const crossTab = CrossTabManager.getInstance();\n      \n      const result = await crossTab.request(\n        'pressKey',\n        { key: params.key },\n        'domActionResponse',\n        5000\n      );\n      \n      if (result.success) {\n        console.log('✅ [ShopifyActionHandler] Key press successful');\n        return {\n          success: true,\n          result,\n          response: `Pressed key ${params.key}`,\n        };\n      } else {\n        console.error('❌ [ShopifyActionHandler] Key press failed:', result.error);\n        return {\n          success: false,\n          error: result.error || 'Key press failed',\n        };\n      }\n    } catch (error) {\n      console.error('❌ [ShopifyActionHandler] Key press error:', error);\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Focus an element on the controlled tab\n   * \n   * @param params.id - Spoken ID from search results\n   * @returns Focus result\n   */\n  async focusElement(params: { id: string }): Promise<ToolResult> {\n    try {\n      console.log(`🎯 [ShopifyActionHandler] Focusing element: ${params.id}`);\n      \n      const crossTab = CrossTabManager.getInstance();\n      \n      const result = await crossTab.request(\n        'focusElement',\n        { id: params.id },\n        'domActionResponse',\n        5000\n      );\n      \n      if (result.success) {\n        console.log('✅ [ShopifyActionHandler] Focus successful');\n        return {\n          success: true,\n          result,\n          response: `Focused element ${params.id}`,\n        };\n      } else {\n        console.error('❌ [ShopifyActionHandler] Focus failed:', result.error);\n        return {\n          success: false,\n          error: result.error || 'Focus failed',\n        };\n      }\n    } catch (error) {\n      console.error('❌ [ShopifyActionHandler] Focus error:', error);\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Scroll to an element on the controlled tab\n   * \n   * @param params.id - Spoken ID from search results\n   * @returns Scroll result\n   */\n  async scrollToElement(params: { id: string }): Promise<ToolResult> {\n    try {\n      console.log(`📜 [ShopifyActionHandler] Scrolling to element: ${params.id}`);\n      \n      const crossTab = CrossTabManager.getInstance();\n      \n      const result = await crossTab.request(\n        'scrollToElement',\n        { id: params.id },\n        'domActionResponse',\n        5000\n      );\n      \n      if (result.success) {\n        console.log('✅ [ShopifyActionHandler] Scroll successful');\n        return {\n          success: true,\n          result,\n          response: `Scrolled to element ${params.id}`,\n        };\n      } else {\n        console.error('❌ [ShopifyActionHandler] Scroll failed:', result.error);\n        return {\n          success: false,\n          error: result.error || 'Scroll failed',\n        };\n      }\n    } catch (error) {\n      console.error('❌ [ShopifyActionHandler] Scroll error:', error);\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Get compressed page snapshot\n   * Returns a highly compressed view of all interactive/visible elements\n   * Use this when search fails to get context about what's on the page\n   * \n   * @returns Compressed snapshot with element IDs, tags, text, etc.\n   */\n  async getPageSnapshot(_params: {}): Promise<ToolResult> {\n    try {\n      console.log('📸 [ShopifyActionHandler] Getting page snapshot...');\n      \n      const crossTab = CrossTabManager.getInstance();\n      \n      const snapshot = await crossTab.request(\n        'getPageSnapshot',\n        {},\n        'pageSnapshotResponse',\n        5000\n      );\n      \n      console.log('✅ [ShopifyActionHandler] Received page snapshot');\n      console.log('   📊 Snapshot preview (first 200 chars):');\n      console.log('   ', snapshot.snapshot?.substring(0, 200) + '...');\n      \n      return {\n        success: true,\n        result: snapshot,\n        response: `Page snapshot retrieved with ${snapshot.elementCount || 0} elements`,\n      };\n    } catch (error) {\n      console.error('❌ [ShopifyActionHandler] Get page snapshot failed:', error);\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Get all action definitions for registering with Vowel\n   * \n   * @returns Record of action names to their definitions\n   */\n  getActionDefinitions() {\n    return {\n      // ============================================================\n      // LEGACY TOOLS - DISABLED (Use DOM tools instead)\n      // ============================================================\n      // These tools are kept in code but commented out in definitions\n      // so the AI cannot use them. DOM tools are now the only way\n      // to interact with pages, ensuring theme-agnostic behavior.\n      // ============================================================\n      \n      // searchProducts: {\n      //   description: \"[DISABLED - Use DOM tools instead] Legacy search that navigates to /search page. Use getPageSnapshot + clickElement + typeIntoElement + pressKey instead.\",\n      //   parameters: {\n      //     query: {\n      //       type: \"string\",\n      //       description: \"Search query for products\",\n      //     },\n      //   },\n      // },\n      \n      // navigateToProduct: {\n      //   description: \"[DISABLED - Use DOM tools instead] Navigate to a specific product page. Use getPageSnapshot to find product links and clickElement instead.\",\n      //   parameters: {\n      //     product: {\n      //       type: \"string\",\n      //       description: \"Product name to navigate to\",\n      //       optional: true,\n      //     },\n      //     productId: {\n      //       type: \"string\",\n      //       description: \"Exact product ID if known\",\n      //       optional: true,\n      //     },\n      //   },\n      // },\n      \n      // navigateToCollection: {\n      //   description: \"[DISABLED - Use DOM tools instead] Navigate to a product collection. Use getPageSnapshot to find collection links and clickElement instead.\",\n      //   parameters: {\n      //     collection: {\n      //       type: \"string\",\n      //       description: \"Collection handle/slug\",\n      //     },\n      //   },\n      // },\n      \n      // addToCart: {\n      //   description: \"[DISABLED - Use DOM tools instead] Add product to cart. Use getPageSnapshot to find add-to-cart button and clickElement instead.\",\n      //   parameters: {\n      //     productId: {\n      //       type: \"string\",\n      //       description: \"Product variant ID to add to cart\",\n      //     },\n      //     quantity: {\n      //       type: \"number\",\n      //       description: \"Quantity to add (default: 1)\",\n      //       optional: true,\n      //     },\n      //   },\n      // },\n      \n      // getStoreInfo: {\n      //   description: \"[DISABLED] Get general store information\",\n      //   parameters: {\n      //     info: {\n      //       type: \"string\",\n      //       description: \"Type of information requested\",\n      //       optional: true,\n      //     },\n      //   },\n      // },\n      \n      getCurrentPageContext: {\n        description: \"Get current page context including URL and what page the user is viewing\",\n        parameters: {},\n      },\n      \n      // ============================================================\n      // SMART DOM TOOLS - Page Snapshot with Spoken IDs\n      // ============================================================\n      // Simple, powerful tools for ANY Shopify theme\n      // 1. getPageSnapshot - get ALL elements on the page (ALWAYS USE THIS FIRST)\n      // 2. Use the spoken ID (e.g., \"apple_banana\") to interact\n      // ============================================================\n      \n      searchElements: {\n        description: `⚠️ DEPRECATED: This tool now redirects to getPageSnapshot(). Always use getPageSnapshot() instead.\n\n[DEPRECATED - USE getPageSnapshot() INSTEAD]\nThis tool has been replaced with getPageSnapshot() which provides a full page view.\nAny call to searchElements will automatically redirect to getPageSnapshot().\n\nThe AI should ALWAYS call getPageSnapshot() first to see all available elements,\nthen use the element IDs from the snapshot to interact with clickElement, typeIntoElement, etc.`,\n        parameters: {\n          query: {\n            type: \"string\",\n            description: \"Search query - can be button text, aria-label, class name, placeholder, etc. The fuzzy matcher searches ALL element properties.\",\n          },\n          maxResults: {\n            type: \"number\",\n            description: \"Maximum elements to return (default: 10)\",\n            optional: true,\n          },\n          minSimilarity: {\n            type: \"number\",\n            description: \"Minimum similarity score 0-1 (default: 0.3). Higher = stricter. Substring matches automatically score 0.9+. Use lower values for fuzzy matching.\",\n            optional: true,\n          },\n          requireInteractive: {\n            type: \"boolean\",\n            description: \"Only return interactive elements (buttons, links, inputs, etc.)\",\n            optional: true,\n          },\n          requireVisible: {\n            type: \"boolean\",\n            description: \"Only return visible elements (default: true)\",\n            optional: true,\n          },\n          tag: {\n            type: \"string\",\n            description: \"Filter by HTML tag (e.g., 'button', 'input', 'a')\",\n            optional: true,\n          },\n        },\n      },\n      \n      clickElement: {\n        description: \"Click an element using its spoken ID from searchElements results. Opens modals, toggles menus, submits forms, clicks links, etc. NOTE: Do NOT show IDs to user unless asked.\",\n        parameters: {\n          id: {\n            type: \"string\",\n            description: \"Spoken ID from search results (e.g., 'apple_banana'). This is INTERNAL - don't show to user.\",\n          },\n        },\n      },\n      \n      typeIntoElement: {\n        description: \"Type text into an input using its spoken ID from searchElements results. For search boxes, form inputs, textareas, etc. NOTE: Do NOT show IDs to user unless asked.\",\n        parameters: {\n          id: {\n            type: \"string\",\n            description: \"Spoken ID from search results (must be an input element). This is INTERNAL - don't show to user.\",\n          },\n          text: {\n            type: \"string\",\n            description: \"Text to type (e.g., search query, form data)\",\n          },\n        },\n      },\n      \n      pressKey: {\n        description: \"Press a keyboard key. Use to submit forms (Enter), close modals (Escape), navigate (Tab), etc. Works on currently focused element.\",\n        parameters: {\n          key: {\n            type: \"string\",\n            description: \"Key to press (e.g., 'Enter', 'Escape', 'Tab', 'ArrowDown')\",\n          },\n        },\n      },\n      \n      focusElement: {\n        description: \"Focus an element using its spoken ID from searchElements results. Sets keyboard focus. NOTE: Do NOT show IDs to user unless asked.\",\n        parameters: {\n          id: {\n            type: \"string\",\n            description: \"Spoken ID from search results. This is INTERNAL - don't show to user.\",\n          },\n        },\n      },\n      \n      scrollToElement: {\n        description: \"Scroll an element into view using its spoken ID from searchElements results. Makes element visible. NOTE: Do NOT show IDs to user unless asked.\",\n        parameters: {\n          id: {\n            type: \"string\",\n            description: \"Spoken ID from search results. This is INTERNAL - don't show to user.\",\n          },\n        },\n      },\n      \n      getPageSnapshot: {\n        description: `⭐ PRIMARY TOOL - ALWAYS USE THIS FIRST ⭐\n\nGet a compressed view of ALL interactive and visible elements on the page.\n\nCRITICAL: You MUST call getPageSnapshot() BEFORE any other DOM interaction.\nThis is the ONLY way to discover what elements are available on the page.\n\nReturns: Compressed snapshot showing element IDs, tags, text content, placeholders, aria-labels, etc.\nFormat: id|tag|text|value|placeholder|aria|flags (pipe-separated for compactness)\n\nOnce you have the snapshot:\n1. Search through the returned elements to find what you need\n2. Use the element's spoken ID (e.g., \"apple_banana\") with clickElement, typeIntoElement, etc.\n\nWORKFLOW:\n1. User: \"Click the add to cart button\"\n2. AI: Call getPageSnapshot() → Get all elements\n3. AI: Find element with text \"add to cart\" in snapshot results\n4. AI: Use that element's ID with clickElement({id: \"apple_banana\"})\n\nDO NOT attempt to interact with elements without calling getPageSnapshot first!`,\n        parameters: {},\n      },\n    };\n  }\n}\n\n","/**\n * Shopify Platform Adapter\n * Complete integration package for Shopify storefronts\n * Extends generic controlled navigation with Shopify-specific features\n * \n * @module @vowel.to/client/platforms/shopify\n * \n * @example\n * ```ts\n * import { \n *   ShopifyRouterAdapter,\n *   ShopifyActionHandler,\n *   ShopifyRouteGenerator \n * } from '@vowel.to/client/platforms/shopify';\n * import { Vowel } from '@vowel.to/client';\n * \n * // Setup router\n * const router = new ShopifyRouterAdapter();\n * \n * // Generate routes from sitemap\n * const generator = new ShopifyRouteGenerator();\n * const routes = await generator.generateRoutes('https://mystore.com');\n * router.setRoutes(routes);\n * \n * // Create Vowel client\n * const vowel = new Vowel({\n *   appId: 'your-app-id',\n *   router,\n *   routes\n * });\n * \n * // Register Shopify actions\n * const actionHandler = new ShopifyActionHandler();\n * const definitions = actionHandler.getActionDefinitions();\n * \n * vowel.registerAction('searchProducts', \n *   definitions.searchProducts,\n *   actionHandler.searchProducts.bind(actionHandler)\n * );\n * ```\n */\n\n// Re-export generic components that work as-is for Shopify\nexport { \n  initializeNavigationListener,\n  initializeAutomationListener,\n  autoInitializeAutomationListener,\n  FuzzyDOMSearcher,\n  DOMManipulator,\n  snapshotForAI,\n  generateAriaTree\n} from '../generic';\n\n// Re-export generic types\nexport type {\n  LevenshteinSearchOptions,\n  SearchResultElement,\n  DOMSearchResults,\n  AriaNode,\n  AriaSnapshot,\n  AriaTreeOptions\n} from '../generic';\n\n// Export Shopify-specific components\nexport { ShopifyRouterAdapter } from \"./router\";\nexport { ShopifyRouteGenerator, ShopifyUrlCategorizer } from \"./routes\";\nexport { ShopifyActionHandler, ShopifyStoreManager } from \"./actions\";\n\n// Export dual adapters (NEW)\nexport { \n  ShopifyNavigationAdapter,\n  ShopifyAutomationAdapter,\n  initializeShopifyAdapters\n} from \"./adapters\";\n\n// Import for helper function\nimport { ShopifyRouterAdapter } from \"./router\";\nimport { ShopifyActionHandler } from \"./actions\";\nimport { ShopifyRouteGenerator } from \"./routes\";\nimport { initializeShopifyAdapters } from \"./adapters\";\nimport type { VowelRoute, NavigationAdapter, AutomationAdapter } from \"../../types\";\n\n/**\n * Helper function to initialize a complete Shopify integration\n * Sets up router, discovers routes, and registers actions\n * Fault-tolerant: always returns valid routes, falling back to basic routes if discovery fails\n * \n * @param config - Configuration options\n * @returns Initialized components\n * \n * @example\n * ```ts\n * import { initializeShopifyIntegration } from '@vowel.to/client/platforms/shopify';\n * import { Vowel } from '@vowel.to/client';\n * \n * const { router, routes, actionHandler } = await initializeShopifyIntegration({\n *   storeUrl: 'https://mystore.com'\n * });\n * \n * const vowel = new Vowel({\n *   appId: 'your-app-id',\n *   router,\n *   routes\n * });\n * \n * // Register all Shopify actions\n * const definitions = actionHandler.getActionDefinitions();\n * Object.entries(definitions).forEach(([name, definition]) => {\n *   vowel.registerAction(name, definition, (actionHandler as any)[name].bind(actionHandler));\n * });\n * ```\n */\nexport async function initializeShopifyIntegration(config: {\n  storeUrl?: string;\n  useFallbackRoutes?: boolean;\n}): Promise<{\n  router: ShopifyRouterAdapter;\n  routes: VowelRoute[];\n  actionHandler: ShopifyActionHandler;\n}> {\n  const { storeUrl, useFallbackRoutes = false } = config;\n  \n  const router = new ShopifyRouterAdapter();\n  const generator = new ShopifyRouteGenerator();\n  // Pass router's navigate function to action handler for client-side navigation\n  const actionHandler = new ShopifyActionHandler(router.navigate.bind(router));\n\n  let routes: VowelRoute[];\n\n  try {\n    const baseUrl = storeUrl || (typeof window !== 'undefined' ? window.location.origin : '');\n    \n    if (useFallbackRoutes) {\n      console.log(\"📋 Using fallback routes (sitemap discovery disabled)\");\n      // Directly get fallback routes without attempting sitemap discovery\n      routes = await generator.generateRoutes(baseUrl);\n    } else {\n      console.log(\"🔍 Attempting to discover routes from sitemap...\");\n      // Try to discover routes from sitemap\n      routes = await generator.generateRoutes(baseUrl);\n      \n      if (routes.length === 0) {\n        console.warn(\"⚠️ No routes were discovered\");\n      } else {\n        console.log(`✅ Successfully loaded ${routes.length} routes`);\n      }\n    }\n  } catch (error) {\n    console.error(\"❌ Route generation failed completely:\", error);\n    // This should rarely happen as RouteGenerator has its own fallback\n    // But we'll provide a minimal set of routes as a last resort\n    routes = [{\n      path: \"/\",\n      description: \"Store homepage\",\n      metadata: { type: \"home\", priority: \"highest\" },\n    }];\n  }\n\n  router.setRoutes(routes);\n\n  return {\n    router,\n    routes,\n    actionHandler,\n  };\n}\n\n/**\n * Initialize Shopify integration with dual adapters (NEW)\n * Uses the modern dual-adapter architecture with NavigationAdapter and AutomationAdapter\n * \n * @param config - Configuration options\n * @returns Initialized adapters, routes, and action handler\n * \n * @example\n * ```ts\n * import { initializeShopifyDualAdapters } from '@vowel.to/client/platforms/shopify';\n * import { Vowel } from '@vowel.to/client';\n * \n * const { navigationAdapter, automationAdapter, routes, actionHandler } = \n *   await initializeShopifyDualAdapters({\n *     storeUrl: 'https://mystore.com'\n *   });\n * \n * const vowel = new Vowel({\n *   appId: 'your-app-id',\n *   navigationAdapter,\n *   automationAdapter,\n *   routes,\n *   floatingCursor: { enabled: true }\n * });\n * \n * // Register all Shopify actions\n * const definitions = actionHandler.getActionDefinitions();\n * Object.entries(definitions).forEach(([name, definition]) => {\n *   vowel.registerAction(name, definition, (actionHandler as any)[name].bind(actionHandler));\n * });\n * ```\n */\nexport async function initializeShopifyDualAdapters(config: {\n  storeUrl?: string;\n  useFallbackRoutes?: boolean;\n  navigationChannelName?: string;\n  automationChannelName?: string;\n}): Promise<{\n  navigationAdapter: NavigationAdapter;\n  automationAdapter: AutomationAdapter;\n  routes: VowelRoute[];\n  actionHandler: ShopifyActionHandler;\n}> {\n  const { storeUrl, useFallbackRoutes = false, navigationChannelName, automationChannelName } = config;\n  \n  console.log('🛍️ [Shopify] Initializing dual-adapter integration...');\n  \n  // Initialize dual adapters\n  const { navigationAdapter, automationAdapter } = initializeShopifyAdapters({\n    storeUrl,\n    navigationChannelName,\n    automationChannelName\n  });\n  \n  // Generate routes\n  const generator = new ShopifyRouteGenerator();\n  let routes: VowelRoute[];\n\n  try {\n    const baseUrl = storeUrl || (typeof window !== 'undefined' ? window.location.origin : '');\n    \n    if (useFallbackRoutes) {\n      console.log(\"📋 Using fallback routes (sitemap discovery disabled)\");\n      routes = await generator.generateRoutes(baseUrl);\n    } else {\n      console.log(\"🔍 Attempting to discover routes from sitemap...\");\n      routes = await generator.generateRoutes(baseUrl);\n      \n      if (routes.length === 0) {\n        console.warn(\"⚠️ No routes were discovered\");\n      } else {\n        console.log(`✅ Successfully loaded ${routes.length} routes`);\n      }\n    }\n  } catch (error) {\n    console.error(\"❌ Route generation failed completely:\", error);\n    routes = [{\n      path: \"/\",\n      description: \"Store homepage\",\n      metadata: { type: \"home\", priority: \"highest\" },\n    }];\n  }\n  \n  // Create action handler\n  const actionHandler = new ShopifyActionHandler(\n    (path: string) => navigationAdapter.navigate(path)\n  );\n  \n  console.log('✅ [Shopify] Dual-adapter integration initialized');\n  \n  return {\n    navigationAdapter,\n    automationAdapter,\n    routes,\n    actionHandler,\n  };\n}\n"],"names":["ControlledNavigationRouter","GenericUrlCategorizer","GenericRouteGenerator","ShopifyRouterAdapter","ShopifyRouteGenerator","ShopifyActionHandler","initializeShopifyAdapters"],"mappings":";;;;;;;;;AAwBO,MAAM,6BAA6BA,iCAAA,CAA2B;AAAA,EACnE,WAAA,CAAY,OAAA,GAA6C,EAAC,EAAG;AAE3D,IAAA,KAAA,CAAM;AAAA,MACJ,WAAA,EAAa,QAAQ,WAAA,IAAe,kBAAA;AAAA,MACpC,MAAA,EAAQ;AAAA,QACN,GAAG,OAAA,CAAQ,MAAA;AAAA,QACX,QAAA,EAAU,CAAC,YAAA,EAAc,WAAA,EAAa,GAAI,OAAA,CAAQ,MAAA,EAAQ,QAAA,IAAY,EAAG;AAAA;AAC3E,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAIF;;ACzBO,MAAM,8BAA8BC,wCAAA,CAAiD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ1F,cAAc,GAAA,EAA0B;AACtC,IAAA,IAAI,QAAA;AAEJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,IAAI,GAAA,CAAI,GAAG,CAAA,CAAE,QAAA;AAAA,IAC1B,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,uBAAA,EAA0B,GAAG,CAAA,sBAAA,CAAwB,CAAA;AAClE,MAAA,QAAA,GAAW,IAAI,UAAA,CAAW,GAAG,CAAA,GAAI,GAAA,GAAM,IAAI,GAAG,CAAA,CAAA;AAAA,IAChD;AAKA,IAAA,IAAI,QAAA,CAAS,KAAA,CAAM,sBAAsB,CAAA,EAAG;AAC1C,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,SAAA;AAAA,QACN,QAAA,EAAU,UAAA;AAAA,QACV,WAAA,EAAa,IAAA,CAAK,yBAAA,CAA0B,QAAQ,CAAA;AAAA,QACpD,QAAA,EAAU;AAAA,OACZ;AAAA,IACF;AAGA,IAAA,IAAI,QAAA,CAAS,KAAA,CAAM,yBAAyB,CAAA,EAAG;AAC7C,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,YAAA;AAAA,QACN,QAAA,EAAU,aAAA;AAAA,QACV,WAAA,EAAa,IAAA,CAAK,4BAAA,CAA6B,QAAQ,CAAA;AAAA,QACvD,QAAA,EAAU;AAAA,OACZ;AAAA,IACF;AAGA,IAAA,IAAI,QAAA,CAAS,KAAA,CAAM,mBAAmB,CAAA,EAAG;AACvC,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,MAAA;AAAA,QACN,QAAA,EAAU,OAAA;AAAA,QACV,WAAA,EAAa,IAAA,CAAK,6BAAA,CAA8B,QAAQ,CAAA;AAAA,QACxD,QAAA,EAAU;AAAA,OACZ;AAAA,IACF;AAGA,IAAA,IAAI,QAAA,CAAS,KAAA,CAAM,2BAA2B,CAAA,EAAG;AAC/C,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,MAAA;AAAA,QACN,QAAA,EAAU,OAAA;AAAA,QACV,WAAA,EAAa,IAAA,CAAK,6BAAA,CAA8B,QAAQ,CAAA;AAAA,QACxD,QAAA,EAAU;AAAA,OACZ;AAAA,IACF;AAGA,IAAA,MAAM,YAAA,GAAe,KAAK,qBAAA,EAAsB;AAChD,IAAA,IAAI,YAAA,CAAa,QAAQ,CAAA,EAAG;AAC1B,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,YAAA,CAAa,QAAQ,CAAA,CAAE,IAAA;AAAA,QAC7B,QAAA,EAAU,YAAA,CAAa,QAAQ,CAAA,CAAE,IAAA;AAAA,QACjC,WAAA,EAAa,YAAA,CAAa,QAAQ,CAAA,CAAE,WAAA;AAAA,QACpC,QAAA,EAAU,YAAA,CAAa,QAAQ,CAAA,CAAE;AAAA,OACnC;AAAA,IACF;AAGA,IAAA,OAAO,KAAA,CAAM,cAAc,GAAG,CAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,qBAAA,GAAiG;AACzG,IAAA,OAAO;AAAA,MACL,KAAK,EAAE,IAAA,EAAM,QAAQ,WAAA,EAAa,gBAAA,EAAkB,UAAU,SAAA,EAAU;AAAA,MACxE,aAAa,EAAE,IAAA,EAAM,YAAY,WAAA,EAAa,qBAAA,EAAuB,UAAU,MAAA,EAAO;AAAA,MACtF,gBAAgB,EAAE,IAAA,EAAM,eAAe,WAAA,EAAa,wBAAA,EAA0B,UAAU,MAAA,EAAO;AAAA,MAC/F,SAAS,EAAE,IAAA,EAAM,QAAQ,WAAA,EAAa,eAAA,EAAiB,UAAU,MAAA,EAAO;AAAA,MACxE,WAAW,EAAE,IAAA,EAAM,UAAU,WAAA,EAAa,iBAAA,EAAmB,UAAU,QAAA,EAAS;AAAA,MAChF,YAAY,EAAE,IAAA,EAAM,WAAW,WAAA,EAAa,kBAAA,EAAoB,UAAU,QAAA,EAAS;AAAA,MACnF,kBAAkB,EAAE,IAAA,EAAM,WAAW,WAAA,EAAa,gBAAA,EAAkB,UAAU,QAAA,EAAS;AAAA,MACvF,qBAAqB,EAAE,IAAA,EAAM,WAAW,WAAA,EAAa,uBAAA,EAAyB,UAAU,QAAA;AAAS,KACnG;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,0BAA0B,QAAA,EAA0B;AAC1D,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,CAAM,GAAG,EAAE,GAAA,EAAI;AACvC,IAAA,OAAO,CAAA,KAAA,EAAQ,MAAA,EAAQ,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAC,CAAA,QAAA,CAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,6BAA6B,QAAA,EAA0B;AAC7D,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,CAAM,GAAG,EAAE,GAAA,EAAI;AACvC,IAAA,OAAO,CAAA,OAAA,EAAU,MAAA,EAAQ,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAC,CAAA,WAAA,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,8BAA8B,QAAA,EAA0B;AAC9D,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,CAAM,GAAG,EAAE,GAAA,EAAI;AACvC,IAAA,OAAO,CAAA,EAAG,MAAA,EAAQ,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAC,CAAA,KAAA,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,8BAA8B,QAAA,EAA0B;AAC9D,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,GAAG,CAAA;AAChC,IAAA,MAAM,UAAA,GAAa,MAAM,CAAC,CAAA;AAC1B,IAAA,OAAO,CAAA,EAAG,UAAA,EAAY,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAC,CAAA,UAAA,CAAA;AAAA,EAC1C;AACF;AAaO,MAAM,8BAA8BC,wCAAA,CAAsB;AAAA,EAC/D,WAAA,GAAc;AACZ,IAAA,KAAA,CAAM,IAAI,uBAAuB,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQU,kBAAA,GAAmC;AAG3C,IAAA,OAAO,EAAC;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQU,iBAAA,GAAkC;AAC1C,IAAA,OAAO;AAAA,MACL;AAAA,QACE,IAAA,EAAM,GAAA;AAAA,QACN,WAAA,EAAa,gBAAA;AAAA,QACb,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,SAAA;AAAU,OAChD;AAAA,MACA;AAAA,QACE,IAAA,EAAM,WAAA;AAAA,QACN,WAAA,EAAa,qBAAA;AAAA,QACb,QAAA,EAAU,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,MAAA;AAAO,OACjD;AAAA,MACA;AAAA,QACE,IAAA,EAAM,cAAA;AAAA,QACN,WAAA,EAAa,oBAAA;AAAA,QACb,QAAA,EAAU,EAAE,IAAA,EAAM,aAAA,EAAe,UAAU,MAAA;AAAO,OACpD;AAAA,MACA;AAAA,QACE,IAAA,EAAM,OAAA;AAAA,QACN,WAAA,EAAa,eAAA;AAAA,QACb,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,MAAA;AAAO,OAC7C;AAAA,MACA;AAAA,QACE,IAAA,EAAM,SAAA;AAAA,QACN,WAAA,EAAa,iBAAA;AAAA,QACb,QAAA,EAAU,EAAE,IAAA,EAAM,QAAA,EAAU,UAAU,QAAA;AAAS;AACjD,KACF;AAAA,EACF;AACF;;AC7JO,MAAM,eAAA,CAAgB;AAAA,EAC3B,OAAe,QAAA,GAAmC,IAAA;AAAA,EAC1C,OAAA,GAAmC,IAAA;AAAA,EACnC,eAAA,uBAA6E,GAAA,EAAI;AAAA,EACxE,WAAA,GAAc,kBAAA;AAAA,EAEvB,WAAA,GAAc;AACpB,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WAAA,GAA+B;AACpC,IAAA,IAAI,CAAC,gBAAgB,QAAA,EAAU;AAC7B,MAAA,eAAA,CAAgB,QAAA,GAAW,IAAI,eAAA,EAAgB;AAAA,IACjD;AACA,IAAA,OAAO,eAAA,CAAgB,QAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAA,GAAoB;AAC1B,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,CAAC,OAAO,gBAAA,EAAkB;AAC7D,MAAA,OAAA,CAAQ,KAAK,mDAAmD,CAAA;AAChE,MAAA;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,OAAA,GAAU,IAAI,gBAAA,CAAiB,IAAA,CAAK,WAAW,CAAA;AAEpD,MAAA,IAAA,CAAK,OAAA,CAAQ,SAAA,GAAY,CAAC,KAAA,KAAyC;AACjE,QAAA,MAAM,UAAU,KAAA,CAAM,IAAA;AACtB,QAAA,OAAA,CAAQ,GAAA,CAAI,gCAAA,EAAkC,OAAA,CAAQ,IAAA,EAAM,QAAQ,OAAO,CAAA;AAG3E,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,QAAQ,IAAI,CAAA;AACtD,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,QAAA,CAAS,QAAQ,CAAA,OAAA,KAAW;AAC1B,YAAA,IAAI;AACF,cAAA,OAAA,CAAQ,QAAQ,OAAO,CAAA;AAAA,YACzB,SAAS,KAAA,EAAO;AACd,cAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAAA,YACpD;AAAA,UACF,CAAC,CAAA;AAAA,QACH;AAAA,MACF,CAAA;AAEA,MAAA,OAAA,CAAQ,IAAI,+BAA+B,CAAA;AAAA,IAC7C,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,4CAA4C,KAAK,CAAA;AAAA,IACjE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAA,CAAY,MAA2B,OAAA,EAAoB;AACzD,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,OAAA,CAAQ,KAAK,mCAAmC,CAAA;AAChD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAA2B;AAAA,MAC/B,IAAA;AAAA,MACA,OAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,MACpB,SAAA,EAAW,CAAA,EAAG,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,MAAA,CAAO,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,KACrE;AAEA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,OAAA,CAAQ,YAAY,OAAO,CAAA;AAChC,MAAA,OAAA,CAAQ,GAAA,CAAI,4BAAA,EAA8B,IAAA,EAAM,OAAO,CAAA;AAAA,IACzD,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,6BAA6B,KAAK,CAAA;AAAA,IAClD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAA,CAAU,MAA2B,OAAA,EAA6C;AAChF,IAAA,IAAI,CAAC,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,IAAI,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,IAAA,kBAAM,IAAI,KAAK,CAAA;AAAA,IAC1C;AAEA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,IAAI,CAAA;AAC9C,IAAA,QAAA,CAAS,IAAI,OAAO,CAAA;AAEpB,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,wCAAA,EAA2C,IAAI,CAAA,CAAE,CAAA;AAG7D,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,OAAO,OAAO,CAAA;AACvB,MAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,QAAA,IAAA,CAAK,eAAA,CAAgB,OAAO,IAAI,CAAA;AAAA,MAClC;AAAA,IACF,CAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,OAAA,EAAyD;AACpE,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,OAAA,CAAQ,KAAK,mCAAmC,CAAA;AAChD,MAAA,OAAO,MAAM;AAAA,MAAC,CAAA;AAAA,IAChB;AAEA,IAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAAyC;AACzD,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,MAAM,IAAI,CAAA;AAAA,MACpB,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,sCAAsC,KAAK,CAAA;AAAA,MAC3D;AAAA,IACF,CAAA;AAEA,IAAA,IAAA,CAAK,OAAA,CAAQ,gBAAA,CAAiB,SAAA,EAAW,QAAQ,CAAA;AAGjD,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,KAAK,OAAA,EAAS;AAChB,QAAA,IAAA,CAAK,OAAA,CAAQ,mBAAA,CAAoB,SAAA,EAAW,QAAQ,CAAA;AAAA,MACtD;AAAA,IACF,CAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,OAAA,CACJ,IAAA,EACA,OAAA,EACA,YAAA,EACA,UAAkB,GAAA,EACJ;AACd,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,SAAA,GAAY,WAAW,MAAM;AACjC,QAAA,WAAA,EAAY;AACZ,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,OAAO,IAAI,CAAC,CAAA;AAAA,MACxD,GAAG,OAAO,CAAA;AAEV,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,SAAA,CAAU,YAAA,EAAc,CAAC,eAAA,KAAoB;AACpE,QAAA,YAAA,CAAa,SAAS,CAAA;AACtB,QAAA,WAAA,EAAY;AACZ,QAAA,OAAA,CAAQ,eAAe,CAAA;AAAA,MACzB,CAAC,CAAA;AAED,MAAA,IAAA,CAAK,WAAA,CAAY,MAAM,OAAO,CAAA;AAAA,IAChC,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,KAAA,GAAc;AACZ,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AACnB,MAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,MAAA,OAAA,CAAQ,IAAI,2BAA2B,CAAA;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WAAA,GAAuB;AAC5B,IAAA,OAAO,OAAO,MAAA,KAAW,WAAA,IAAe,CAAC,CAAC,MAAA,CAAO,gBAAA;AAAA,EACnD;AACF;;ACnNO,MAAM,mBAAA,CAAoB;AAAA,EACvB,KAAA,uBAAoC,GAAA,EAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhD,MAAM,WAAA,GAAkC;AACtC,IAAA,MAAM,QAAA,GAAW,UAAA;AAEjB,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC5B,MAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAA;AAAA,IAChC;AAGA,IAAA,MAAM,QAAA,GAAW,KAAK,sBAAA,EAAuB;AAG7C,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACjC,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,sBAAA,GAAoC;AAC1C,IAAA,MAAM,WAAsB,EAAC;AAG7B,IAAA,MAAM,gBAAA,GAAmB;AAAA,MACvB,mBAAA;AAAA,MACA,eAAA;AAAA,MACA,eAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,gBAAA,CAAiB,OAAA,CAAQ,CAAC,QAAA,KAAa;AACrC,MAAA,MAAM,QAAA,GAAW,QAAA,CAAS,gBAAA,CAAiB,QAAQ,CAAA;AACnD,MAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC5B,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,yBAAA,CAA0B,OAAO,CAAA;AACtD,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AAAA,QACvB;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,0BAA0B,OAAA,EAAkC;AAClE,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,GACJ,OAAA,CAAQ,YAAA,CAAa,iBAAiB,CAAA,IACtC,QACG,aAAA,CAAc,mBAAmB,CAAA,EAChC,YAAA,CAAa,iBAAiB,CAAA;AAEpC,MAAA,MAAM,KAAA,GACJ,OAAA,CACG,aAAA,CAAc,0CAA0C,CAAA,EACvD,WAAA,EAAa,IAAA,EAAK,IACtB,OAAA,CAAQ,aAAA,CAAc,gBAAgB,CAAA,EAAG,aAAa,IAAA,EAAK;AAE7D,MAAA,MAAM,KAAA,GACJ,OAAA,CAAQ,aAAA,CAAc,sBAAsB,CAAA,EAAG,WAAA,EAAa,IAAA,EAAK,IACjE,OAAA,CAAQ,aAAA,CAAc,gBAAgB,CAAA,EAAG,aAAa,IAAA,EAAK;AAE7D,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,aAAA,CAAc,KAAK,CAAA,EAAG,GAAA;AAE5C,MAAA,IAAI,MAAM,KAAA,EAAO;AACf,QAAA,OAAO;AAAA,UACL,EAAA;AAAA,UACA,KAAA;AAAA,UACA,KAAA;AAAA,UACA,KAAA;AAAA,UACA;AAAA;AAAA,SACF;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,2CAA2C,KAAK,CAAA;AAAA,IAC/D;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,SAAA,CACJ,SAAA,EACA,QAAA,GAAmB,CAAA,EACiE;AACpF,IAAA,IAAI;AAGF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,cAAA,EAAgB;AAAA,QAC3C,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB;AAAA,SAClB;AAAA,QACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,EAAA,EAAI,SAAA;AAAA,UACJ;AAAA,SACD;AAAA,OACF,CAAA;AAED,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,KAAK,CAAA,CAAE,CAAA;AAAA,MACnD;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,IAAA,EAAK;AACnC,MAAA,OAAA,CAAQ,GAAA,CAAI,oBAAoB,MAAM,CAAA;AAEtC,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAW,QAAA,EAAS;AAAA,IAC9C,SAAS,KAAA,EAAO;AAEd,MAAA,OAAA,CAAQ,KAAK,yDAAyD,CAAA;AACtE,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,EAAY;AAC7C,QAAA,QAAA,CAAS,WAAA,CAAY,WAAA,EAAa,EAAE,SAAA,EAAW,UAAU,CAAA;AACzD,QAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAW,QAAA,EAAS;AAAA,MAC9C,SAAS,aAAA,EAAe;AACtB,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,SAAA;AAAA,UACA,QAAA;AAAA,UACA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,SAC9D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAe,KAAA,EAAmC;AACtD,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,WAAA,EAAY;AACxC,IAAA,MAAM,UAAA,GAAa,MAAM,WAAA,EAAY;AAErC,IAAA,OAAO,QAAA,CAAS,MAAA;AAAA,MACd,CAAC,OAAA,KACC,OAAA,CAAQ,KAAA,EAAO,aAAY,CAAE,QAAA,CAAS,UAAU,CAAA,IAChD,OAAA,CAAQ,EAAA,EAAI,WAAA,EAAY,CAAE,SAAS,UAAU;AAAA,KACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,oBAAA,CACJ,gBAAA,EACA,QAAA,EAKC;AACD,IAAA,MAAM,aAAA,GAAgB,gBAAgB,gBAAgB,CAAA,CAAA;AAEtD,IAAA,IAAI,QAAA,EAAU;AAEZ,MAAA,MAAM,SAAS,aAAa,CAAA;AAAA,IAC9B,CAAA,MAAO;AAEL,MAAA,OAAA,CAAQ,KAAK,8DAA8D,CAAA;AAC3E,MAAA,MAAA,CAAO,SAAS,IAAA,GAAO,aAAA;AAAA,IACzB;AAEA,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,KAAK,aAAA,EAAc;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAA,GAKH;AACD,IAAA,OAAO;AAAA,MACL,IAAA,EACE,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,EAAG,aAAa,KAAA,CAAM,KAAK,CAAA,CAAE,CAAC,CAAA,IAC5D,OAAA;AAAA,MACF,GAAA,EAAK,OAAO,QAAA,CAAS,MAAA;AAAA,MACrB,QAAA,EAAU,KAAA;AAAA;AAAA,MACV,QAAQ,SAAA,CAAU;AAAA,KACpB;AAAA,EACF;AACF;AAuBO,MAAM,oBAAA,CAAqB;AAAA,EACxB,YAAA;AAAA,EACA,QAAA;AAAA,EAER,YAAY,QAAA,EAA6B;AACvC,IAAA,IAAA,CAAK,YAAA,GAAe,IAAI,mBAAA,EAAoB;AAC5C,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAe,MAAA,EAAgD;AACnE,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,GAAA,CAAI,0CAAA,EAA4C,MAAA,CAAO,KAAK,CAAA;AAGpE,MAAA,MAAM,SAAA,GAAY,CAAA,UAAA,EAAa,kBAAA,CAAmB,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AAC/D,MAAA,IAAI,KAAK,QAAA,EAAU;AACjB,QAAA,OAAA,CAAQ,GAAA,CAAI,mDAAmD,SAAS,CAAA;AACxE,QAAA,MAAM,IAAA,CAAK,SAAS,SAAS,CAAA;AAG7B,QAAA,MAAM,IAAI,OAAA,CAAQ,CAAA,OAAA,KAAW,UAAA,CAAW,OAAA,EAAS,IAAI,CAAC,CAAA;AAGtD,QAAA,OAAA,CAAQ,IAAI,wDAAwD,CAAA;AACpE,QAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,EAAY;AAE7C,QAAA,IAAI;AACF,UAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,OAAA;AAAA,YAC7B,YAAA;AAAA,YACA,EAAE,IAAA,EAAM,QAAA,EAAU,KAAA,EAAO,OAAO,KAAA,EAAM;AAAA,YACtC,iBAAA;AAAA,YACA;AAAA;AAAA,WACF;AAEA,UAAA,OAAA,CAAQ,GAAA,CAAI,iCAAiC,OAAO,CAAA;AAEpD,UAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,QAAA,IAAY,EAAC;AACtC,UAAA,OAAO;AAAA,YACL,OAAA,EAAS,IAAA;AAAA,YACT,MAAA,EAAQ;AAAA,cACN,QAAA,EAAU,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,cAC9B,OAAO,QAAA,CAAS,MAAA;AAAA,cAChB,OAAO,MAAA,CAAO,KAAA;AAAA,cACd;AAAA,aACF;AAAA,YACA,QAAA,EAAU,QAAA,CAAS,MAAA,GAAS,CAAA,GACxB,CAAA,MAAA,EAAS,QAAA,CAAS,MAAM,CAAA,oBAAA,EAAuB,MAAA,CAAO,KAAK,CAAA,yGAAA,CAAA,GAC3D,CAAA,uBAAA,EAA0B,OAAO,KAAK,CAAA,+BAAA;AAAA,WAC5C;AAAA,QACF,SAAS,YAAA,EAAc;AACrB,UAAA,OAAA,CAAQ,KAAK,wEAAwE,CAAA;AACrF,UAAA,OAAO;AAAA,YACL,OAAA,EAAS,IAAA;AAAA,YACT,MAAA,EAAQ;AAAA,cACN,UAAU,EAAC;AAAA,cACX,KAAA,EAAO,CAAA;AAAA,cACP,OAAO,MAAA,CAAO,KAAA;AAAA,cACd;AAAA,aACF;AAAA,YACA,QAAA,EAAU,CAAA,wBAAA,EAA2B,MAAA,CAAO,KAAK,CAAA,uDAAA;AAAA,WACnD;AAAA,QACF;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,OAAA,CAAQ,KAAK,yDAAyD,CAAA;AACtE,QAAA,MAAM,WAAW,MAAM,IAAA,CAAK,YAAA,CAAa,cAAA,CAAe,OAAO,KAAK,CAAA;AACpE,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,MAAA,EAAQ;AAAA,YACN,QAAA,EAAU,SAAS,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,cAC1C,IAAI,CAAA,CAAE,EAAA;AAAA,cACN,OAAO,CAAA,CAAE,KAAA;AAAA,cACT,OAAO,CAAA,CAAE,KAAA;AAAA,cACT,OAAO,CAAA,CAAE;AAAA,aACX,CAAE,CAAA;AAAA,YACF,OAAO,QAAA,CAAS,MAAA;AAAA,YAChB,OAAO,MAAA,CAAO;AAAA,WAChB;AAAA,UACA,UAAU,CAAA,MAAA,EAAS,QAAA,CAAS,MAAM,CAAA,oBAAA,EAAuB,OAAO,KAAK,CAAA,iBAAA;AAAA,SACvE;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,sBAAsB,KAAK,CAAA;AACzC,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAU,MAAA,EAGQ;AACtB,IAAA,IAAI;AACF,MAAA,IAAI,CAAC,OAAO,SAAA,EAAW;AACrB,QAAA,MAAM,IAAI,MAAM,wBAAwB,CAAA;AAAA,MAC1C;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,YAAA,CAAa,SAAA;AAAA,QACrC,MAAA,CAAO,SAAA;AAAA,QACP,OAAO,QAAA,IAAY;AAAA,OACrB;AAEA,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,MAAA;AAAA,UACA,QAAA,EAAU,CAAA,qBAAA;AAAA,SACZ;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO,OAAO,KAAA,IAAS;AAAA,SACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,qBAAqB,MAAA,EAAqD;AAC9E,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,YAAA,CAAa,oBAAA;AAAA,QACrC,MAAA,CAAO,UAAA;AAAA,QACP,IAAA,CAAK;AAAA,OACP;AACA,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA;AAAA,QACA,QAAA,EAAU,CAAA,cAAA,EAAiB,MAAA,CAAO,UAAU,CAAA,WAAA;AAAA,OAC9C;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,qBAAA,GAA6C;AACjD,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,MAAA,EAAQ;AAAA,QACN,GAAA,EAAK,OAAO,QAAA,CAAS,IAAA;AAAA,QACrB,QAAA,EAAU,OAAO,QAAA,CAAS,QAAA;AAAA,QAC1B,MAAA,EAAQ,OAAO,QAAA,CAAS,MAAA;AAAA,QACxB,SAAA,EAAW,KAAK,GAAA;AAAI;AACtB,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,OAAA,EAAkD;AACnE,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,YAAA,CAAa,YAAA,EAAa;AAClD,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA,EAAQ,IAAA;AAAA,QACR,UAAU,CAAA,OAAA,EAAU,IAAA,CAAK,IAAI,CAAA,IAAA,EAAO,KAAK,GAAG,CAAA;AAAA,OAC9C;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,kBAAkB,MAAA,EAGA;AACtB,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,GAAA,CAAI,oDAAoD,MAAM,CAAA;AAGtE,MAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,EAAY;AAC7C,MAAA,IAAI,WAAsB,EAAC;AAE3B,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,IAAI,sDAAsD,CAAA;AAClE,QAAA,MAAM,OAAA,GAAU,MAAM,QAAA,CAAS,OAAA;AAAA,UAC7B,YAAA;AAAA,UACA,EAAE,MAAM,UAAA,EAAW;AAAA,UACnB,iBAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA,QAAA,GAAW,OAAA,CAAQ,YAAY,EAAC;AAChC,QAAA,OAAA,CAAQ,GAAA,CAAI,UAAA,EAAY,QAAA,CAAS,MAAA,EAAQ,8BAA8B,CAAA;AAAA,MACzE,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAK,uEAAuE,CAAA;AACpF,QAAA,QAAA,GAAW,MAAM,IAAA,CAAK,YAAA,CAAa,WAAA,EAAY;AAAA,MACjD;AAGA,MAAA,MAAM,UAAA,GAAa,MAAA,CAAO,OAAA,EAAS,WAAA,EAAY,IAAK,EAAA;AACpD,MAAA,MAAM,UAAU,QAAA,CAAS,IAAA;AAAA,QACvB,CAAC,CAAA,KACC,CAAA,CAAE,KAAA,EAAO,WAAA,EAAY,CAAE,QAAA,CAAS,UAAU,CAAA,IAC1C,CAAA,CAAE,EAAA,KAAO,MAAA,CAAO,SAAA;AAAA,QAEhB,UAAA,CAAW,KAAA,CAAM,GAAG,CAAA,CAAE,KAAA,CAAM,CAAA,IAAA,KAAQ,CAAA,CAAE,KAAA,EAAO,WAAA,EAAY,CAAE,QAAA,CAAS,IAAI,CAAC;AAAA,OAC7E;AAEA,MAAA,IAAI,OAAA,IAAW,QAAQ,EAAA,EAAI;AAEzB,QAAA,MAAM,aAAA,GAAiB,OAAA,CAAgB,MAAA,IAAU,OAAA,CAAQ,EAAA;AACzD,QAAA,MAAM,UAAA,GAAc,OAAA,CAAgB,GAAA,IAAO,CAAA,UAAA,EAAa,aAAa,CAAA,CAAA;AAErE,QAAA,OAAA,CAAQ,GAAA,CAAI,sBAAA,EAAwB,OAAA,CAAQ,KAAK,CAAA;AACjD,QAAA,OAAA,CAAQ,GAAA,CAAI,cAAc,UAAU,CAAA;AAEpC,QAAA,IAAI,KAAK,QAAA,EAAU;AAEjB,UAAA,MAAM,IAAA,CAAK,SAAS,UAAU,CAAA;AAAA,QAChC,CAAA,MAAO;AAEL,UAAA,OAAA,CAAQ,KAAK,8DAA8D,CAAA;AAC3E,UAAA,MAAA,CAAO,SAAS,IAAA,GAAO,UAAA;AAAA,QACzB;AAEA,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,MAAA,EAAQ,EAAE,SAAA,EAAW,IAAA,EAAM,SAAS,OAAA,CAAQ,KAAA,EAAO,KAAK,UAAA,EAAW;AAAA,UACnE,QAAA,EAAU,CAAA,QAAA,EAAW,OAAA,CAAQ,KAAK,CAAA,sBAAA;AAAA,SACpC;AAAA,MACF;AAEA,MAAA,OAAA,CAAQ,IAAA,CAAK,2BAA2B,MAAM,CAAA;AAC9C,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,KAAA,EAAO,CAAA,oBAAA,EAAuB,MAAA,CAAO,OAAA,IAAW,OAAO,SAAS,CAAA,2CAAA,CAAA;AAAA,QAChE,QAAA,EAAU,CAAA,oGAAA;AAAA,OACZ;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,0BAA0B,KAAK,CAAA;AAC7C,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BA,MAAM,eAAe,OAAA,EAOG;AACtB,IAAA,OAAA,CAAQ,KAAK,0DAA0D,CAAA;AACvE,IAAA,OAAA,CAAQ,KAAK,iEAAiE,CAAA;AAC9E,IAAA,OAAA,CAAQ,KAAK,wCAAwC,CAAA;AAGrD,IAAA,OAAO,IAAA,CAAK,eAAA,CAAgB,EAAE,CAAA;AAAA,EAuChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,MAAA,EAA6C;AAC9D,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,6CAAA,EAAgD,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AAEvE,MAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,EAAY;AAE7C,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,OAAA;AAAA,QAC5B,cAAA;AAAA,QACA,EAAE,EAAA,EAAI,MAAA,CAAO,EAAA,EAAG;AAAA,QAChB,mBAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,OAAA,CAAQ,IAAI,2CAA2C,CAAA;AACvD,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,MAAA;AAAA,UACA,QAAA,EAAU,CAAA,gBAAA,EAAmB,MAAA,CAAO,EAAE,CAAA;AAAA,SACxC;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,KAAA,CAAM,wCAAA,EAA0C,MAAA,CAAO,KAAK,CAAA;AACpE,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO,OAAO,KAAA,IAAS;AAAA,SACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,yCAAyC,KAAK,CAAA;AAC5D,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,gBAAgB,MAAA,EAA2D;AAC/E,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,+CAAA,EAAkD,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AACzE,MAAA,OAAA,CAAQ,GAAA,CAAI,UAAA,EAAY,MAAA,CAAO,IAAI,CAAA;AAEnC,MAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,EAAY;AAE7C,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,OAAA;AAAA,QAC5B,iBAAA;AAAA,QACA,EAAE,EAAA,EAAI,MAAA,CAAO,EAAA,EAAI,IAAA,EAAM,OAAO,IAAA,EAAK;AAAA,QACnC,mBAAA;AAAA,QACA;AAAA;AAAA,OACF;AAEA,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,OAAA,CAAQ,IAAI,0CAA0C,CAAA;AACtD,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,MAAA;AAAA,UACA,UAAU,CAAA,OAAA,EAAU,MAAA,CAAO,IAAI,CAAA,eAAA,EAAkB,OAAO,EAAE,CAAA;AAAA,SAC5D;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,KAAA,CAAM,uCAAA,EAAyC,MAAA,CAAO,KAAK,CAAA;AACnE,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO,OAAO,KAAA,IAAS;AAAA,SACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,wCAAwC,KAAK,CAAA;AAC3D,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,MAAA,EAA8C;AAC3D,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,GAAA,CAAI,yCAAA,EAA2C,MAAA,CAAO,GAAG,CAAA;AAEjE,MAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,EAAY;AAE7C,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,OAAA;AAAA,QAC5B,UAAA;AAAA,QACA,EAAE,GAAA,EAAK,MAAA,CAAO,GAAA,EAAI;AAAA,QAClB,mBAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,OAAA,CAAQ,IAAI,+CAA+C,CAAA;AAC3D,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,MAAA;AAAA,UACA,QAAA,EAAU,CAAA,YAAA,EAAe,MAAA,CAAO,GAAG,CAAA;AAAA,SACrC;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,KAAA,CAAM,4CAAA,EAA8C,MAAA,CAAO,KAAK,CAAA;AACxE,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO,OAAO,KAAA,IAAS;AAAA,SACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,6CAA6C,KAAK,CAAA;AAChE,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,MAAA,EAA6C;AAC9D,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,4CAAA,EAA+C,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AAEtE,MAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,EAAY;AAE7C,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,OAAA;AAAA,QAC5B,cAAA;AAAA,QACA,EAAE,EAAA,EAAI,MAAA,CAAO,EAAA,EAAG;AAAA,QAChB,mBAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,OAAA,CAAQ,IAAI,2CAA2C,CAAA;AACvD,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,MAAA;AAAA,UACA,QAAA,EAAU,CAAA,gBAAA,EAAmB,MAAA,CAAO,EAAE,CAAA;AAAA,SACxC;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,KAAA,CAAM,wCAAA,EAA0C,MAAA,CAAO,KAAK,CAAA;AACpE,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO,OAAO,KAAA,IAAS;AAAA,SACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,yCAAyC,KAAK,CAAA;AAC5D,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBAAgB,MAAA,EAA6C;AACjE,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,gDAAA,EAAmD,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AAE1E,MAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,EAAY;AAE7C,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,OAAA;AAAA,QAC5B,iBAAA;AAAA,QACA,EAAE,EAAA,EAAI,MAAA,CAAO,EAAA,EAAG;AAAA,QAChB,mBAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,OAAA,CAAQ,IAAI,4CAA4C,CAAA;AACxD,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,IAAA;AAAA,UACT,MAAA;AAAA,UACA,QAAA,EAAU,CAAA,oBAAA,EAAuB,MAAA,CAAO,EAAE,CAAA;AAAA,SAC5C;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,KAAA,CAAM,yCAAA,EAA2C,MAAA,CAAO,KAAK,CAAA;AACrE,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO,OAAO,KAAA,IAAS;AAAA,SACzB;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,0CAA0C,KAAK,CAAA;AAC7D,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,gBAAgB,OAAA,EAAkC;AACtD,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,IAAI,oDAAoD,CAAA;AAEhE,MAAA,MAAM,QAAA,GAAW,gBAAgB,WAAA,EAAY;AAE7C,MAAA,MAAM,QAAA,GAAW,MAAM,QAAA,CAAS,OAAA;AAAA,QAC9B,iBAAA;AAAA,QACA,EAAC;AAAA,QACD,sBAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAA,OAAA,CAAQ,IAAI,iDAAiD,CAAA;AAC7D,MAAA,OAAA,CAAQ,IAAI,2CAA2C,CAAA;AACvD,MAAA,OAAA,CAAQ,GAAA,CAAI,OAAO,QAAA,CAAS,QAAA,EAAU,UAAU,CAAA,EAAG,GAAG,IAAI,KAAK,CAAA;AAE/D,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,IAAA;AAAA,QACT,MAAA,EAAQ,QAAA;AAAA,QACR,QAAA,EAAU,CAAA,6BAAA,EAAgC,QAAA,CAAS,YAAA,IAAgB,CAAC,CAAA,SAAA;AAAA,OACtE;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,sDAAsD,KAAK,CAAA;AACzE,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC9D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,oBAAA,GAAuB;AACrB,IAAA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAuEL,qBAAA,EAAuB;AAAA,QACrB,WAAA,EAAa,0EAAA;AAAA,QACb,YAAY;AAAC,OACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,cAAA,EAAgB;AAAA,QACd,WAAA,EAAa,CAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA,+FAAA,CAAA;AAAA,QAQb,UAAA,EAAY;AAAA,UACV,KAAA,EAAO;AAAA,YACL,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa;AAAA,WACf;AAAA,UACA,UAAA,EAAY;AAAA,YACV,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa,0CAAA;AAAA,YACb,QAAA,EAAU;AAAA,WACZ;AAAA,UACA,aAAA,EAAe;AAAA,YACb,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa,kJAAA;AAAA,YACb,QAAA,EAAU;AAAA,WACZ;AAAA,UACA,kBAAA,EAAoB;AAAA,YAClB,IAAA,EAAM,SAAA;AAAA,YACN,WAAA,EAAa,iEAAA;AAAA,YACb,QAAA,EAAU;AAAA,WACZ;AAAA,UACA,cAAA,EAAgB;AAAA,YACd,IAAA,EAAM,SAAA;AAAA,YACN,WAAA,EAAa,8CAAA;AAAA,YACb,QAAA,EAAU;AAAA,WACZ;AAAA,UACA,GAAA,EAAK;AAAA,YACH,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa,mDAAA;AAAA,YACb,QAAA,EAAU;AAAA;AACZ;AACF,OACF;AAAA,MAEA,YAAA,EAAc;AAAA,QACZ,WAAA,EAAa,8KAAA;AAAA,QACb,UAAA,EAAY;AAAA,UACV,EAAA,EAAI;AAAA,YACF,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa;AAAA;AACf;AACF,OACF;AAAA,MAEA,eAAA,EAAiB;AAAA,QACf,WAAA,EAAa,qKAAA;AAAA,QACb,UAAA,EAAY;AAAA,UACV,EAAA,EAAI;AAAA,YACF,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa;AAAA,WACf;AAAA,UACA,IAAA,EAAM;AAAA,YACJ,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa;AAAA;AACf;AACF,OACF;AAAA,MAEA,QAAA,EAAU;AAAA,QACR,WAAA,EAAa,oIAAA;AAAA,QACb,UAAA,EAAY;AAAA,UACV,GAAA,EAAK;AAAA,YACH,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa;AAAA;AACf;AACF,OACF;AAAA,MAEA,YAAA,EAAc;AAAA,QACZ,WAAA,EAAa,oIAAA;AAAA,QACb,UAAA,EAAY;AAAA,UACV,EAAA,EAAI;AAAA,YACF,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa;AAAA;AACf;AACF,OACF;AAAA,MAEA,eAAA,EAAiB;AAAA,QACf,WAAA,EAAa,iJAAA;AAAA,QACb,UAAA,EAAY;AAAA,UACV,EAAA,EAAI;AAAA,YACF,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa;AAAA;AACf;AACF,OACF;AAAA,MAEA,eAAA,EAAiB;AAAA,QACf,WAAA,EAAa,CAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA,+EAAA,CAAA;AAAA,QAqBb,YAAY;AAAC;AACf,KACF;AAAA,EACF;AACF;;ACx9BA,eAAsB,6BAA6B,MAAA,EAOhD;AACD,EAAA,MAAM,EAAE,QAAA,EAAU,iBAAA,GAAoB,KAAA,EAAM,GAAI,MAAA;AAEhD,EAAA,MAAM,MAAA,GAAS,IAAIC,oBAAAA,EAAqB;AACxC,EAAA,MAAM,SAAA,GAAY,IAAIC,qBAAAA,EAAsB;AAE5C,EAAA,MAAM,gBAAgB,IAAIC,oBAAAA,CAAqB,OAAO,QAAA,CAAS,IAAA,CAAK,MAAM,CAAC,CAAA;AAE3E,EAAA,IAAI,MAAA;AAEJ,EAAA,IAAI;AACF,IAAA,MAAM,UAAU,QAAA,KAAa,OAAO,WAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,EAAA,CAAA;AAEtF,IAAA,IAAI,iBAAA,EAAmB;AACrB,MAAA,OAAA,CAAQ,IAAI,uDAAuD,CAAA;AAEnE,MAAA,MAAA,GAAS,MAAM,SAAA,CAAU,cAAA,CAAe,OAAO,CAAA;AAAA,IACjD,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,IAAI,kDAAkD,CAAA;AAE9D,MAAA,MAAA,GAAS,MAAM,SAAA,CAAU,cAAA,CAAe,OAAO,CAAA;AAE/C,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,QAAA,OAAA,CAAQ,KAAK,8BAA8B,CAAA;AAAA,MAC7C,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,sBAAA,EAAyB,MAAA,CAAO,MAAM,CAAA,OAAA,CAAS,CAAA;AAAA,MAC7D;AAAA,IACF;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,yCAAyC,KAAK,CAAA;AAG5D,IAAA,MAAA,GAAS,CAAC;AAAA,MACR,IAAA,EAAM,GAAA;AAAA,MACN,WAAA,EAAa,gBAAA;AAAA,MACb,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,SAAA;AAAU,KAC/C,CAAA;AAAA,EACH;AAEA,EAAA,MAAA,CAAO,UAAU,MAAM,CAAA;AAEvB,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AACF;AAkCA,eAAsB,8BAA8B,MAAA,EAUjD;AACD,EAAA,MAAM,EAAE,QAAA,EAAU,iBAAA,GAAoB,KAAA,EAAO,qBAAA,EAAuB,uBAAsB,GAAI,MAAA;AAE9F,EAAA,OAAA,CAAQ,IAAI,wDAAwD,CAAA;AAGpE,EAAA,MAAM,EAAE,iBAAA,EAAmB,iBAAA,EAAkB,GAAIC,kCAAAA,CAA0B;AAAA,IACzE,QAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAA,GACD,CAAA;AAGD,EAAA,MAAM,SAAA,GAAY,IAAIF,qBAAAA,EAAsB;AAC5C,EAAA,IAAI,MAAA;AAEJ,EAAA,IAAI;AACF,IAAA,MAAM,UAAU,QAAA,KAAa,OAAO,WAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,EAAA,CAAA;AAEtF,IAAA,IAAI,iBAAA,EAAmB;AACrB,MAAA,OAAA,CAAQ,IAAI,uDAAuD,CAAA;AACnE,MAAA,MAAA,GAAS,MAAM,SAAA,CAAU,cAAA,CAAe,OAAO,CAAA;AAAA,IACjD,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,IAAI,kDAAkD,CAAA;AAC9D,MAAA,MAAA,GAAS,MAAM,SAAA,CAAU,cAAA,CAAe,OAAO,CAAA;AAE/C,MAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,QAAA,OAAA,CAAQ,KAAK,8BAA8B,CAAA;AAAA,MAC7C,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,sBAAA,EAAyB,MAAA,CAAO,MAAM,CAAA,OAAA,CAAS,CAAA;AAAA,MAC7D;AAAA,IACF;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,yCAAyC,KAAK,CAAA;AAC5D,IAAA,MAAA,GAAS,CAAC;AAAA,MACR,IAAA,EAAM,GAAA;AAAA,MACN,WAAA,EAAa,gBAAA;AAAA,MACb,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAU,SAAA;AAAU,KAC/C,CAAA;AAAA,EACH;AAGA,EAAA,MAAM,gBAAgB,IAAIC,oBAAAA;AAAA,IACxB,CAAC,IAAA,KAAiB,iBAAA,CAAkB,QAAA,CAAS,IAAI;AAAA,GACnD;AAEA,EAAA,OAAA,CAAQ,IAAI,kDAAkD,CAAA;AAE9D,EAAA,OAAO;AAAA,IACL,iBAAA;AAAA,IACA,iBAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AACF;;;;;;;;;;;;;;;;;;;;"}