vite-plugin-smart-prefetch 0.3.3 β†’ 0.3.5

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/plugin/analytics/bigquery-connector.ts","../src/plugin/model/guessjs-ml-trainer.ts","../src/plugin/config-generator.ts","../src/plugin/cache-manager.ts","../src/plugin/index.ts"],"sourcesContent":["/**\n * @farmart/vite-plugin-smart-prefetch\n * Self-learning smart prefetch plugin for Vite applications\n */\n\n// Main plugin export (server-side only)\nexport { smartPrefetch } from './plugin';\n\n// Type exports (safe for both server and client)\nexport type {\n PluginOptions,\n PrefetchStrategy,\n AnalyticsConfig,\n BigQueryCredentials,\n DataRangeConfig,\n ModelConfig,\n ManualRules,\n CacheConfig,\n AdvancedConfig,\n PrefetchModel,\n PrefetchConfig,\n PrefetchTarget,\n NavigationData,\n ViteManifest,\n} from './types';\n\n// NOTE: PrefetchManager has been moved to '@farmart/vite-plugin-smart-prefetch/runtime'\n// to avoid bundling server-side dependencies (BigQuery) into client code\n","/**\n * BigQuery Analytics Connector\n * Queries GA4 event data from BigQuery to extract real navigation transitions\n */\n\nimport { BigQuery } from '@google-cloud/bigquery';\nimport { writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport type { NavigationData, DataRangeConfig } from '../../types';\n\nexport class BigQueryAnalyticsConnector {\n private bigquery: BigQuery;\n private projectId: string;\n private datasetId: string;\n private debug: boolean;\n\n constructor(projectId: string, datasetId: string, debug = false) {\n this.projectId = projectId;\n this.datasetId = datasetId;\n this.debug = debug;\n\n // Initialize BigQuery client\n // Uses default credentials from environment\n this.bigquery = new BigQuery({\n projectId: projectId,\n });\n\n if (this.debug) {\n console.log('βœ… BigQuery Analytics connector initialized');\n console.log(` Project ID: ${projectId}`);\n console.log(` Dataset ID: ${datasetId}`);\n }\n }\n\n /**\n * Fetch real navigation transitions from BigQuery GA4 export\n * Queries the events table for page_view events with previous_page_path parameter\n */\n async fetchNavigationSequences(config: DataRangeConfig = {}): Promise<NavigationData[]> {\n const { days = 30 } = config;\n const minSessions = 1;\n\n console.log(`πŸ“Š Fetching navigation data from BigQuery...`);\n console.log(` Dataset: ${this.datasetId}`);\n console.log(` Date range: Last ${days} days`);\n\n try {\n // Query GA4 events for page transitions\n // Strategy: Use user_id and session_id to reconstruct user sessions and page transitions\n // This groups pages viewed by the same user in the same session to infer navigation flow\n const query = `\n WITH page_sessions AS (\n SELECT\n user_id,\n (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1) as session_id,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_location' LIMIT 1) as page_location,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) as page_path,\n event_timestamp,\n ROW_NUMBER() OVER (\n PARTITION BY user_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)\n ORDER BY event_timestamp\n ) as page_sequence\n FROM \\`${this.projectId}.${this.datasetId}.events_*\\`\n WHERE\n event_name = 'page_view'\n AND _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL ${days} DAY))\n AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())\n AND (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) IS NOT NULL\n ),\n transitions AS (\n SELECT\n COALESCE(curr.page_path, '(direct)') as from_page,\n LEAD(curr.page_path) OVER (\n PARTITION BY curr.user_id, curr.session_id\n ORDER BY curr.page_sequence\n ) as to_page\n FROM page_sessions curr\n WHERE curr.page_sequence > 0\n )\n SELECT\n from_page as previous_page_path,\n to_page as page_path,\n COUNT(*) as transition_count\n FROM transitions\n WHERE to_page IS NOT NULL\n GROUP BY from_page, to_page\n ORDER BY transition_count DESC\n LIMIT 10000\n `;\n\n if (this.debug) {\n console.log(`πŸ“€ BigQuery Query:`);\n console.log(query);\n }\n\n const [rows] = await this.bigquery.query({\n query,\n location: 'US',\n });\n\n if (this.debug) {\n console.log(`βœ… Query executed successfully`);\n console.log(` Rows returned: ${rows.length}`);\n }\n\n const navigationData: NavigationData[] = [];\n\n // IMPORTANT: Save RAW rows for inspection\n const rawData = rows.map((row: any) => ({\n previous_page_path: row.previous_page_path,\n page_path: row.page_path,\n transition_count: row.transition_count\n }));\n\n // Process rows and convert to NavigationData format\n rows.forEach((row: any) => {\n const previousPage = row.previous_page_path || '(direct)';\n const currentPage = row.page_path || '';\n const transitionCount = parseInt(row.transition_count || '0');\n\n // Normalize page paths\n const normalizedPrevious = previousPage === '(direct)' || previousPage === '(not set)' ? '(direct)' : this.normalizeRoute(previousPage);\n const normalizedCurrent = this.normalizeRoute(currentPage);\n\n // Only add valid transitions\n if (normalizedCurrent && transitionCount >= minSessions) {\n navigationData.push({\n from: normalizedPrevious,\n to: normalizedCurrent,\n count: transitionCount,\n });\n }\n });\n\n // Save raw and processed data to files for inspection\n this.saveDataForInspection(rawData, navigationData);\n\n if (this.debug) {\n console.log(`βœ… Processed ${navigationData.length} navigation transitions`);\n\n // Show top 5 transitions\n if (navigationData.length > 0) {\n console.log(`\\n Top 5 transitions:`);\n navigationData.slice(0, 5).forEach((nav, i) => {\n console.log(` ${i + 1}. ${nav.from} β†’ ${nav.to} (${nav.count} transitions)`);\n });\n }\n\n // Show unique routes\n const uniqueRoutes = new Set<string>();\n navigationData.forEach((nav) => {\n if (nav.from !== '(direct)') uniqueRoutes.add(nav.from);\n uniqueRoutes.add(nav.to);\n });\n console.log(`\\n πŸ“Š Unique routes: ${uniqueRoutes.size}`);\n console.log(` Routes: ${Array.from(uniqueRoutes).sort().join(', ')}`);\n\n console.log(`\\n πŸ“ Raw data saved to: .bigquery-raw-data/`);\n }\n\n return navigationData;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n // Check if this is a permission error\n if (errorMessage.includes('bigquery.jobs.create') || errorMessage.includes('PERMISSION_DENIED')) {\n console.error('❌ Failed to fetch BigQuery data: Permission Denied');\n console.error(' Service account needs BigQuery Job User role in the project');\n console.error(' Error details:', errorMessage);\n } else {\n console.error('❌ Failed to fetch BigQuery data:', error);\n }\n\n throw new Error(\n `BigQuery Analytics error: ${errorMessage}`\n );\n }\n }\n\n /**\n * Map friendly page names (with spaces/capitals) back to route paths\n * GA4 may log display names instead of URL paths\n * Examples: \"Audit Logs\" β†’ \"/audit-logs\", \"API Documentation\" β†’ \"/api-docs\", \"Home\" β†’ \"/\"\n */\n private friendlyNameToRoute(name: string): string {\n // Mapping of friendly names to route paths\n const friendlyToRoute: Record<string, string> = {\n // Exact matches (with spaces and capitals)\n 'API Documentation': '/api-docs',\n 'Audit Logs': '/audit-logs',\n '/Home': '/',\n '/home': '/',\n 'Home': '/',\n '/Dashboard': '/dashboard',\n 'Dashboard': '/dashboard',\n\n // PascalCase variants (all 27 routes)\n 'Profile': '/profile',\n 'Settings': '/settings',\n 'Preferences': '/preferences',\n 'Privacy': '/privacy',\n 'Security': '/security',\n 'Analytics': '/analytics',\n 'Reports': '/reports',\n 'Metrics': '/metrics',\n 'Projects': '/projects',\n 'Tasks': '/tasks',\n 'Teams': '/teams',\n 'Workspaces': '/workspaces',\n 'Workflows': '/workflows',\n 'Templates': '/templates',\n 'Logs': '/logs',\n 'AuditLogs': '/audit-logs',\n 'Integrations': '/integrations',\n 'ApiDocs': '/api-docs',\n 'Support': '/support',\n 'Help': '/help',\n 'Billing': '/billing',\n 'Plans': '/plans',\n 'Usage': '/usage',\n 'Permissions': '/permissions',\n 'Notifications': '/notifications',\n };\n\n // Check for exact match first\n if (friendlyToRoute[name]) {\n return friendlyToRoute[name];\n }\n\n // Try case-insensitive match\n const lowerName = name.toLowerCase();\n for (const [key, value] of Object.entries(friendlyToRoute)) {\n if (key.toLowerCase() === lowerName) {\n return value;\n }\n }\n\n // If it's already a route path, normalize it to lowercase\n if (name.startsWith('/')) {\n if (name === '/') {\n return '/';\n }\n return name.toLowerCase();\n }\n\n // Fallback: convert to lowercase and add leading slash\n return '/' + lowerName;\n }\n\n /**\n * Normalize route paths\n * Converts dynamic segments to parameters and friendly names to route paths\n */\n private normalizeRoute(path: string): string {\n // Filter out build artifacts and non-route paths\n const buildArtifacts = [\n /\\.(js|css|jpg|jpeg|png|gif|svg|webp|woff|woff2|ttf|eot|map)(\\?|#|$)/i,\n /\\[hash\\]/i,\n /\\/chunks\\//i,\n /\\/vendor\\//i,\n /\\/assets\\//i,\n /\\.vite\\//i,\n ];\n\n if (buildArtifacts.some((pattern) => pattern.test(path))) {\n return '';\n }\n\n // First, convert friendly names (with spaces/capitals) to route paths\n // e.g., \"Audit Logs\" β†’ \"/audit-logs\", \"API Documentation\" β†’ \"/api-docs\"\n let normalized = this.friendlyNameToRoute(path);\n\n // Remove query parameters and hash\n normalized = normalized.split('?')[0].split('#')[0];\n\n // Remove trailing slash (except for root /)\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n\n // Ensure lowercase for consistency (convert spaces to hyphens)\n if (normalized !== '/') {\n normalized = normalized.toLowerCase().replace(/ +/g, '-');\n }\n\n // Replace common ID patterns with :id\n normalized = normalized\n .replace(/\\/[0-9a-f]{24}(?=\\/|$)/gi, '/:id')\n .replace(/\\/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}(?=\\/|$)/gi, '/:id')\n .replace(/\\/\\d+(?=\\/|$)/g, '/:id')\n .replace(/\\/[\\w.-]+@[\\w.-]+\\.[\\w]+(?=\\/|$)/gi, '/:email')\n .replace(/\\/\\d{4}-\\d{2}-\\d{2}(?=\\/|$)/g, '/:date');\n\n return normalized;\n }\n\n /**\n * Save raw and processed data for inspection\n * Helps identify issues in data transformation pipeline\n */\n private saveDataForInspection(rawData: any[], processedData: NavigationData[]): void {\n try {\n const outputDir = '.bigquery-raw-data';\n const outputPath = join(process.cwd(), outputDir);\n\n // Create directory if it doesn't exist\n mkdirSync(outputPath, { recursive: true });\n\n // Raw data: exactly as it comes from BigQuery\n const rawFile = join(outputPath, 'raw-bigquery-response.json');\n writeFileSync(rawFile, JSON.stringify(rawData, null, 2));\n\n // Processed data: after normalization and filtering\n const processedFile = join(outputPath, 'processed-navigation-data.json');\n writeFileSync(processedFile, JSON.stringify(processedData, null, 2));\n\n // Summary statistics\n const summary = {\n timestamp: new Date().toISOString(),\n rawRowCount: rawData.length,\n processedRowCount: processedData.length,\n dataLoss: rawData.length - processedData.length,\n dataLossPercentage: ((rawData.length - processedData.length) / rawData.length * 100).toFixed(2) + '%',\n totalTransitions: processedData.reduce((sum, d) => sum + d.count, 0),\n uniqueFromRoutes: new Set(processedData.map(d => d.from)).size,\n uniqueToRoutes: new Set(processedData.map(d => d.to)).size,\n topTransitions: processedData.slice(0, 10)\n };\n\n const summaryFile = join(outputPath, 'data-transformation-summary.json');\n writeFileSync(summaryFile, JSON.stringify(summary, null, 2));\n\n if (this.debug) {\n console.log(`\\nπŸ“Š Data Inspection Summary:`);\n console.log(` Raw rows from BigQuery: ${summary.rawRowCount}`);\n console.log(` Processed rows (after filtering): ${summary.processedRowCount}`);\n console.log(` Data loss: ${summary.dataLoss} rows (${summary.dataLossPercentage})`);\n console.log(` Total transitions count: ${summary.totalTransitions}`);\n console.log(` Unique source routes: ${summary.uniqueFromRoutes}`);\n console.log(` Unique destination routes: ${summary.uniqueToRoutes}`);\n console.log(`\\n Files saved:`);\n console.log(` β€’ ${rawFile}`);\n console.log(` β€’ ${processedFile}`);\n console.log(` β€’ ${summaryFile}`);\n }\n } catch (error) {\n console.warn(`⚠️ Could not save inspection data:`, error instanceof Error ? error.message : error);\n }\n }\n\n /**\n * Fetch navigation data WITH segment information\n * Includes segment/role field so plugin can group by any role dynamically\n * @param config - Data range configuration\n * @returns Navigation data with segment field included\n */\n async fetchNavigationWithSegments(config: DataRangeConfig = {}): Promise<any[]> {\n const { days = 30 } = config;\n\n console.log(`πŸ“Š Fetching navigation data with segments from BigQuery...`);\n console.log(` Dataset: ${this.datasetId}`);\n console.log(` Date range: Last ${days} days`);\n\n try {\n // Query GA4 events for page transitions INCLUDING segment information\n // Extracts user_role (or user_segment) from event_params\n const query = `\n WITH page_sessions AS (\n SELECT\n user_id,\n (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1) as session_id,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) as page_path,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'user_role' LIMIT 1) as user_role,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'user_segment' LIMIT 1) as user_segment,\n event_timestamp,\n ROW_NUMBER() OVER (\n PARTITION BY user_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)\n ORDER BY event_timestamp\n ) as page_sequence\n FROM \\`${this.projectId}.${this.datasetId}.events_*\\`\n WHERE\n event_name = 'page_view'\n AND _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL ${days} DAY))\n AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())\n AND (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) IS NOT NULL\n ),\n transitions AS (\n SELECT\n COALESCE(curr.page_path, '(direct)') as from_page,\n LEAD(curr.page_path) OVER (\n PARTITION BY curr.user_id, curr.session_id\n ORDER BY curr.page_sequence\n ) as to_page,\n COALESCE(curr.user_role, curr.user_segment, 'unknown') as segment\n FROM page_sessions curr\n WHERE curr.page_sequence > 0\n )\n SELECT\n from_page as previous_page_path,\n to_page as page_path,\n segment,\n COUNT(*) as transition_count\n FROM transitions\n WHERE to_page IS NOT NULL\n GROUP BY from_page, to_page, segment\n ORDER BY segment, transition_count DESC\n LIMIT 50000\n `;\n\n if (this.debug) {\n console.log(`πŸ“€ Query with segments:`);\n console.log(query);\n }\n\n const [rows] = await this.bigquery.query({\n query,\n location: 'US',\n });\n\n if (this.debug) {\n console.log(`βœ… Query executed successfully`);\n console.log(` Rows returned: ${rows.length}`);\n }\n\n const navigationData: any[] = [];\n\n rows.forEach((row: any) => {\n const previousPage = row.previous_page_path || '(direct)';\n const currentPage = row.page_path || '';\n const transitionCount = parseInt(row.transition_count || '0');\n const segment = row.segment || 'unknown';\n\n const normalizedPrevious = previousPage === '(direct)' || previousPage === '(not set)' ? '(direct)' : this.normalizeRoute(previousPage);\n const normalizedCurrent = this.normalizeRoute(currentPage);\n\n if (normalizedCurrent && transitionCount >= 1) {\n navigationData.push({\n from: normalizedPrevious,\n to: normalizedCurrent,\n count: transitionCount,\n segment: segment, // Include segment/role field\n });\n }\n });\n\n if (this.debug && navigationData.length > 0) {\n console.log(`βœ… Processed ${navigationData.length} transitions with segment data`);\n\n // Show detected segments\n const uniqueSegments = new Set(navigationData.map((d: any) => d.segment));\n console.log(`\\n Detected segments: ${Array.from(uniqueSegments).sort().join(', ')}`);\n\n // Show top transitions per segment\n const bySegment = new Map();\n navigationData.forEach((d: any) => {\n if (!bySegment.has(d.segment)) {\n bySegment.set(d.segment, []);\n }\n bySegment.get(d.segment).push(d);\n });\n\n bySegment.forEach((transitions: any[], segment: string) => {\n console.log(`\\n Top 3 transitions for ${segment}:`);\n transitions\n .sort((a, b) => b.count - a.count)\n .slice(0, 3)\n .forEach((nav: any, i: number) => {\n console.log(` ${i + 1}. ${nav.from} β†’ ${nav.to} (${nav.count} transitions)`);\n });\n });\n }\n\n return navigationData;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n console.warn(`⚠️ Failed to fetch navigation data with segments: ${errorMessage}`);\n return [];\n }\n }\n\n /**\n * Test connection to BigQuery\n * Note: May fail if service account lacks bigquery.jobs.create permission\n * but actual queries may still work. This is expected for viewer-only accounts.\n */\n async testConnection(): Promise<boolean> {\n try {\n const query = `SELECT 1 as test_value`;\n await this.bigquery.query({\n query,\n location: 'US',\n });\n\n if (this.debug) {\n console.log('βœ… BigQuery connection test successful');\n }\n\n return true;\n } catch (error) {\n // Don't treat test failure as fatal - viewer accounts may lack bigquery.jobs.create\n // but can still query via read-only APIs\n if (this.debug) {\n console.warn('⚠️ BigQuery connection test failed (may be expected for read-only accounts)');\n }\n return false;\n }\n }\n}\n","/**\n * Markov Chain Model Trainer\n * Builds a Markov chain from user navigation data\n * Probability: P(dest | src) = count(srcβ†’dest) / total_transitions_from_src\n */\n\nimport type {\n NavigationData,\n PrefetchModel,\n ModelConfig,\n PrefetchTarget,\n RouteMetadata,\n} from '../../types';\n\nexport class MarkovChainTrainer {\n private config: ModelConfig;\n private debug: boolean;\n\n constructor(config: ModelConfig, debug = false) {\n this.config = config;\n this.debug = debug;\n }\n\n /**\n * Train Markov chain model from navigation data\n * Calculates transition probabilities: P(dest | src) = transitions(srcβ†’dest) / total_from_src\n */\n trainMLModel(\n navigationData: NavigationData[],\n environment: string\n ): PrefetchModel {\n if (this.debug) {\n console.log(`\\nπŸ€– Training Markov Chain Model...`);\n console.log(` Model type: ${this.config.type}`);\n console.log(` Threshold: ${this.config.threshold * 100}%`);\n console.log(` Max prefetch per route: ${this.config.maxPrefetch}`);\n console.log(` Input transitions: ${navigationData.length}`);\n }\n\n // Build navigation graph: sourceRoute -> { targetRoute: count }\n const navigationGraph = this.buildNavigationGraph(navigationData);\n const routes = this.extractRoutes(navigationData);\n\n if (this.debug) {\n console.log(`\\n πŸ“Š Analysis:`);\n console.log(` Unique routes: ${routes.size}`);\n console.log(` Routes: ${Array.from(routes).sort().join(', ')}`);\n console.log(` Source routes: ${navigationGraph.size}`);\n }\n\n // Calculate Markov probabilities: P(dest | src) = count(srcβ†’dest) / total_from_src\n const predictions = this.calculateMarkovProbabilities(navigationGraph);\n\n if (this.debug) {\n console.log(`\\n Predictions generated:`);\n console.log(` Routes with predictions: ${predictions.size}`);\n const totalTargets = Array.from(predictions.values()).reduce(\n (sum, targets) => sum + targets.length,\n 0\n );\n console.log(` Total prefetch targets: ${totalTargets}`);\n }\n\n // Build PrefetchModel\n const model: PrefetchModel = {\n version: '1.0.0',\n generatedAt: new Date().toISOString(),\n environment,\n config: this.config,\n dataSource: {\n provider: 'markov-chain',\n dateRange: this.getDateRange(30),\n totalSessions: navigationData.reduce((sum, d) => sum + d.count, 0),\n totalRoutes: routes.size,\n },\n routes: {},\n };\n\n // Populate predictions\n predictions.forEach((targets, source) => {\n model.routes[source] = {\n prefetch: targets,\n metadata: this.calculateMetadata(navigationGraph, source),\n };\n });\n\n if (this.debug) {\n console.log(`\\n βœ… Model trained successfully`);\n const sampleRoutes = Array.from(predictions.entries()).slice(0, 3);\n if (sampleRoutes.length > 0) {\n console.log(`\\n Sample predictions:`);\n sampleRoutes.forEach(([source, targets]) => {\n console.log(` ${source}:`);\n targets.forEach((target) => {\n console.log(\n ` β†’ ${target.route} (${(target.probability * 100).toFixed(1)}%, ${target.priority})`\n );\n });\n });\n }\n }\n\n return model;\n }\n\n /**\n * Extract all unique routes from navigation data\n */\n private extractRoutes(data: NavigationData[]): Set<string> {\n const routes = new Set<string>();\n\n data.forEach((d) => {\n routes.add(d.from);\n routes.add(d.to);\n });\n\n return routes;\n }\n\n /**\n * Build navigation graph from user navigation patterns\n * Graph represents: sourceRoute -> { targetRoute: transitionCount }\n */\n private buildNavigationGraph(\n data: NavigationData[]\n ): Map<string, Map<string, number>> {\n const graph = new Map<string, Map<string, number>>();\n\n data.forEach(({ from, to, count }) => {\n if (!graph.has(from)) {\n graph.set(from, new Map());\n }\n\n const targets = graph.get(from)!;\n targets.set(to, (targets.get(to) || 0) + count);\n });\n\n return graph;\n }\n\n /**\n * Calculate Markov probabilities with normalization\n * P(dest | src) = count(srcβ†’dest) / total_transitions_from_src\n * Then normalizes scores to 0-1 range\n */\n private calculateMarkovProbabilities(\n navigationGraph: Map<string, Map<string, number>>\n ): Map<string, PrefetchTarget[]> {\n const predictions = new Map<string, PrefetchTarget[]>();\n\n navigationGraph.forEach((targets, source) => {\n const targetArray: PrefetchTarget[] = [];\n\n // Calculate total transitions from this source\n const totalFromSource = Array.from(targets.values()).reduce(\n (sum, count) => sum + count,\n 0\n );\n\n if (totalFromSource === 0) return;\n\n // Calculate base probability for each destination: P(dest | src) = count / total\n const probabilities = new Map<string, number>();\n targets.forEach((count, destination) => {\n probabilities.set(destination, count / totalFromSource);\n });\n\n // Normalize probabilities to 0-1 range\n const maxProb = Math.max(...Array.from(probabilities.values()));\n if (maxProb > 0) {\n probabilities.forEach((prob, dest) => {\n probabilities.set(dest, prob / maxProb);\n });\n }\n\n // Sort by probability (descending)\n const sorted = Array.from(probabilities.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, this.config.maxPrefetch);\n\n // Apply threshold and create targets\n sorted.forEach(([route, probability]) => {\n if (probability >= this.config.threshold) {\n targetArray.push({\n route,\n probability,\n count: targets.get(route) || 0,\n priority: this.getPriority(probability),\n });\n }\n });\n\n if (targetArray.length > 0) {\n predictions.set(source, targetArray);\n }\n });\n\n return predictions;\n }\n\n /**\n * Determine priority based on ML confidence score\n */\n private getPriority(score: number): 'high' | 'medium' | 'low' {\n if (score >= 0.7) return 'high';\n if (score >= 0.4) return 'medium';\n return 'low';\n }\n\n /**\n * Calculate metadata for a route\n */\n private calculateMetadata(\n navigationGraph: Map<string, Map<string, number>>,\n route: string\n ): RouteMetadata {\n const targets = navigationGraph.get(route);\n\n if (!targets || targets.size === 0) {\n return {\n totalTransitions: 0,\n topDestination: '',\n };\n }\n\n const totalTransitions = Array.from(targets.values()).reduce(\n (sum, count) => sum + count,\n 0\n );\n\n // Find top destination\n let topDestination = '';\n let maxCount = 0;\n targets.forEach((count, targetRoute) => {\n if (count > maxCount) {\n maxCount = count;\n topDestination = targetRoute;\n }\n });\n\n return {\n totalTransitions,\n topDestination,\n };\n }\n\n /**\n * Train segment-specific Markov models from navigation data with segment field\n * Creates separate models for each user segment/role\n */\n trainSegmentedModels(\n navigationDataWithSegments: any[],\n environment: string\n ): Map<string, PrefetchModel> {\n if (this.debug) {\n console.log(`\\nπŸ€– Training Segment-Specific Markov Models...`);\n }\n\n // Group data by segment\n const dataBySegment = new Map<string, NavigationData[]>();\n\n navigationDataWithSegments.forEach((data) => {\n const segment = data.segment || 'default';\n if (!dataBySegment.has(segment)) {\n dataBySegment.set(segment, []);\n }\n dataBySegment.get(segment)!.push({\n from: data.from,\n to: data.to,\n count: data.count,\n });\n });\n\n if (this.debug) {\n console.log(`\\n πŸ“Š Detected segments:`);\n dataBySegment.forEach((data, segment) => {\n console.log(` β€’ ${segment}: ${data.length} transitions`);\n });\n }\n\n // Train a model for each segment\n const segmentModels = new Map<string, PrefetchModel>();\n dataBySegment.forEach((navigationData, segment) => {\n if (this.debug) {\n console.log(`\\n πŸ”„ Training model for segment: \"${segment}\"`);\n }\n\n const model = this.trainMLModel(navigationData, environment);\n\n // Add segment info to model\n model.dataSource!.provider = `markov-chain[${segment}]`;\n\n segmentModels.set(segment, model);\n\n if (this.debug) {\n const totalTargets = Object.values(model.routes).reduce(\n (sum, route) => sum + (route.prefetch?.length || 0),\n 0\n );\n console.log(` βœ… Model for \"${segment}\" trained with ${totalTargets} prefetch targets`);\n }\n });\n\n if (this.debug) {\n console.log(`\\n βœ… All ${segmentModels.size} segment models trained successfully`);\n }\n\n return segmentModels;\n }\n\n /**\n * Get date range string\n */\n private getDateRange(days: number): string {\n const end = new Date();\n const start = new Date();\n start.setDate(start.getDate() - days);\n\n return `${start.toISOString().split('T')[0]} to ${end.toISOString().split('T')[0]}`;\n }\n}\n\n// Export with old name for backward compatibility\nexport { MarkovChainTrainer as GuessJSMLTrainer };\n","/**\n * Configuration Generator\n * Maps routes to Vite chunks and generates final prefetch configuration\n */\n\nimport type {\n PrefetchModel,\n PrefetchConfig,\n ViteManifest,\n ManualRules,\n PrefetchTarget,\n} from '../types';\n\nexport class ConfigGenerator {\n private manifest: ViteManifest;\n private manualRules: ManualRules;\n private debug: boolean;\n private vite: any = null;\n private isDev: boolean = false;\n\n /**\n * Maps routes to their component names based on vite.config.ts chunk strategy\n *\n * ⚠️ HARDCODED MAPPINGS ARE NOT RECOMMENDED FOR PRODUCTION\n *\n * These mappings should NOT be hardcoded in the plugin.\n * Instead, implement one of these approaches:\n *\n * 1. **Extract from Vite Config (RECOMMENDED)**:\n * Pass route-to-chunk mappings from your vite.config.ts manualChunks strategy\n * This keeps mappings DRY and maintainable.\n *\n * 2. **Generate from Route Files**:\n * Scan your routes/pages directory to dynamically build mappings\n *\n * 3. **Use Route Metadata**:\n * Add metadata to route definitions specifying their chunk names\n *\n * Current hardcoded mappings (will be removed in v0.4.0):\n */\n private static readonly ROUTE_TO_COMPONENT_NAME: Record<string, string> = {\n '/': 'Home',\n '/home': 'Home',\n '/dashboard': 'Dashboard',\n\n '/profile': 'Profile',\n '/settings': 'Settings',\n '/preferences': 'Preferences',\n '/privacy': 'Privacy',\n '/security': 'Security',\n\n '/analytics': 'Analytics',\n '/reports': 'Reports',\n '/metrics': 'Metrics',\n\n '/projects': 'Projects',\n '/tasks': 'Tasks',\n '/teams': 'Teams',\n '/workspaces': 'Workspaces',\n\n '/workflows': 'Workflows',\n '/templates': 'Templates',\n '/logs': 'Logs',\n '/audit-logs': 'AuditLogs',\n\n '/integrations': 'Integrations',\n '/api-docs': 'ApiDocs',\n '/api-documentation': 'ApiDocs', // Alias for space-separated variant\n '/support': 'Support',\n '/help': 'Help',\n\n '/billing': 'Billing',\n '/plans': 'Plans',\n '/usage': 'Usage',\n\n '/permissions': 'Permissions',\n '/notifications': 'Notifications',\n };\n\n /**\n * Maps component names to chunk names based on vite.config.ts manualChunks strategy\n *\n * ⚠️ HARDCODED MAPPINGS ARE NOT RECOMMENDED FOR PRODUCTION\n *\n * Each component is assigned to a specific chunk group for code splitting.\n * These mappings should be extracted from your actual vite.config.ts, not hardcoded.\n *\n * Note: Core components (Home, Dashboard) are not in manual chunks - they're part of main bundle\n * For these, we return the main bundle file path 'js/index-*.js' which will be resolved from manifest\n *\n * Will be removed in v0.4.0. Use plugin config to pass mappings instead.\n */\n private static readonly COMPONENT_TO_CHUNK_NAME: Record<string, string> = {\n // Core components - loaded with main bundle (not code-split)\n Home: 'index', // Special marker for main entry point\n Dashboard: 'index',\n\n // User Profile & Settings chunk\n Profile: 'chunk-user-profile',\n Settings: 'chunk-user-profile',\n Preferences: 'chunk-user-profile',\n Privacy: 'chunk-user-profile',\n Security: 'chunk-user-profile',\n\n // Analytics & Reporting chunk\n Analytics: 'chunk-analytics',\n Reports: 'chunk-analytics',\n Metrics: 'chunk-analytics',\n\n // Project Management chunk\n Projects: 'chunk-projects',\n Tasks: 'chunk-projects',\n Teams: 'chunk-projects',\n Workspaces: 'chunk-projects',\n\n // Workflows & Operations chunk\n Workflows: 'chunk-operations',\n Templates: 'chunk-operations',\n Logs: 'chunk-operations',\n AuditLogs: 'chunk-operations',\n\n // Integration chunk\n Integrations: 'chunk-integrations',\n ApiDocs: 'chunk-integrations',\n Support: 'chunk-integrations',\n Help: 'chunk-integrations',\n\n // Billing & Plans chunk\n Billing: 'chunk-billing',\n Plans: 'chunk-billing',\n Usage: 'chunk-billing',\n\n // Admin & Notifications chunk\n Permissions: 'chunk-admin',\n Notifications: 'chunk-admin',\n };\n\n constructor(manifest: ViteManifest, manualRules: ManualRules = {}, debug = false, vite?: any) {\n this.manifest = manifest;\n this.manualRules = manualRules;\n this.debug = debug;\n this.vite = vite || null;\n this.isDev = !!vite; // If vite is provided, we're in dev mode\n }\n\n /**\n * Generate final prefetch configuration with chunk mappings\n * Includes common prefetch rules and segment-specific rules if available\n */\n generate(model: PrefetchModel): PrefetchConfig {\n if (this.debug) {\n console.log(`\\nπŸ“¦ Generating prefetch configuration...`);\n console.log(` Manifest entries: ${Object.keys(this.manifest).length}`);\n console.log(` Model routes: ${Object.keys(model.routes).length}`);\n console.log(` Manual rules: ${Object.keys(this.manualRules).length}`);\n if (Object.values(model.routes).some(r => r.segments)) {\n console.log(` ℹ️ Segment-based rules detected`);\n }\n }\n\n // Merge manual rules into model\n const mergedModel = this.mergeManualRules(model);\n\n // Extract route patterns for dynamic route matching (TanStack Router support)\n const routePatterns = this.extractRoutePatterns(Object.keys(mergedModel.routes));\n\n // Map routes to chunks\n const config: PrefetchConfig = {\n version: model.version,\n generatedAt: model.generatedAt,\n environment: model.environment,\n dataSource: model.dataSource!,\n model: {\n type: model.config!.type,\n threshold: model.config!.threshold,\n maxPrefetch: model.config!.maxPrefetch,\n },\n routePatterns, // NEW: Include route patterns for dynamic matching\n routes: {},\n chunks: {},\n };\n\n let mappedRoutes = 0;\n let unmappedRoutes = 0;\n let totalSegmentRules = 0;\n\n // Process each route\n Object.entries(mergedModel.routes).forEach(([sourceRoute, prediction]) => {\n const prefetchTargets: Array<PrefetchTarget & { chunk?: string }> = [];\n const segmentConfigs: Record<string, Array<PrefetchTarget & { chunk?: string }>> = {};\n\n // Also map the source route's own chunk (so it can be used as a destination elsewhere)\n const sourceChunk = this.routeToChunk(sourceRoute);\n if (sourceChunk && !config.chunks[sourceRoute]) {\n config.chunks[sourceRoute] = sourceChunk;\n }\n\n // Process common prefetch rules\n prediction.prefetch.forEach((target) => {\n const chunkFile = this.routeToChunk(target.route);\n let imports: string[] = [];\n\n if (chunkFile) {\n // Get the manifest entry for this chunk to extract imports\n const manifestEntry = this.getManifestEntryByFile(chunkFile);\n const importChunkIds = manifestEntry?.imports || [];\n\n // Resolve import chunk IDs to actual file paths\n imports = importChunkIds\n .map((chunkId) => {\n const entry = this.manifest[chunkId];\n return entry?.file;\n })\n .filter((file): file is string => !!file);\n\n // Add to chunks lookup\n config.chunks[target.route] = chunkFile;\n mappedRoutes++;\n\n if (this.debug) {\n console.log(` βœ… ${sourceRoute} β†’ ${target.route}`);\n console.log(` Chunk: ${chunkFile}`);\n if (imports.length > 0) {\n console.log(` Dependencies: ${imports.join(', ')}`);\n }\n }\n } else {\n if (this.debug) {\n console.log(` ⚠️ No chunk found for route: ${target.route}`);\n console.log(` Attempted to map using routeToChunk()`);\n }\n unmappedRoutes++;\n }\n\n // CRITICAL FIX: Include ALL prefetch targets in config, even if chunk is null\n // This ensures every prefetch rule is available, and the runtime can skip\n // or handle missing chunks gracefully\n prefetchTargets.push({\n ...target,\n chunk: chunkFile || undefined, // Include chunk (may be undefined)\n chunk_prod: chunkFile || undefined, // Include production chunk path\n imports: imports,\n });\n });\n\n // Process segment-specific rules if available\n if (prediction.segments) {\n Object.entries(prediction.segments).forEach(([segment, segmentTargets]) => {\n const segmentPrefetchTargets: Array<PrefetchTarget & { chunk?: string }> = [];\n\n segmentTargets.forEach((target) => {\n const chunkFile = this.routeToChunk(target.route);\n let imports: string[] = [];\n\n if (chunkFile) {\n const manifestEntry = this.getManifestEntryByFile(chunkFile);\n const importChunkIds = manifestEntry?.imports || [];\n\n imports = importChunkIds\n .map((chunkId) => {\n const entry = this.manifest[chunkId];\n return entry?.file;\n })\n .filter((file): file is string => !!file);\n\n config.chunks[target.route] = chunkFile;\n totalSegmentRules++;\n }\n\n // CRITICAL FIX: Include ALL segment prefetch targets in config, even if chunk is null\n segmentPrefetchTargets.push({\n ...target,\n chunk: chunkFile || undefined, // Include chunk (may be undefined)\n chunk_prod: chunkFile || undefined, // Include production chunk path\n imports: imports,\n });\n });\n\n if (segmentPrefetchTargets.length > 0) {\n segmentConfigs[segment] = segmentPrefetchTargets;\n }\n });\n\n if (this.debug && Object.keys(segmentConfigs).length > 0) {\n console.log(` πŸ‘₯ Segment configs for ${sourceRoute}: ${Object.keys(segmentConfigs).join(', ')}`);\n }\n }\n\n // Get patterns for this route for dynamic matching (TanStack Router support)\n const patterns = routePatterns[sourceRoute] || [sourceRoute];\n\n // Only include routes with valid chunk mappings\n if (prefetchTargets.length > 0 || Object.keys(segmentConfigs).length > 0) {\n config.routes[sourceRoute] = {\n patterns, // NEW: Include patterns for dynamic route matching\n prefetch: prefetchTargets,\n ...(Object.keys(segmentConfigs).length > 0 && {\n segments: segmentConfigs,\n }),\n metadata: prediction.metadata,\n };\n }\n });\n\n if (this.debug) {\n console.log(`βœ… Configuration generated`);\n console.log(` Routes with prefetch: ${Object.keys(config.routes).length}`);\n console.log(` Mapped chunks: ${mappedRoutes}`);\n console.log(` Segment-specific rules: ${totalSegmentRules}`);\n console.log(` Unmapped routes: ${unmappedRoutes}`);\n }\n\n // Add segment info if any routes have segments\n const allSegments = new Set<string>();\n Object.values(config.routes).forEach(route => {\n if (route.segments) {\n Object.keys(route.segments).forEach(seg => allSegments.add(seg));\n }\n });\n\n if (allSegments.size > 0) {\n config.segmentInfo = {\n available: Array.from(allSegments),\n description: 'Load segment-specific config based on user role/segment'\n };\n }\n\n return config;\n }\n\n /**\n * Merge manual rules into model\n * Manual rules take precedence over ML predictions\n */\n private mergeManualRules(model: PrefetchModel): PrefetchModel {\n const merged = { ...model, routes: { ...model.routes } };\n\n Object.entries(this.manualRules).forEach(([sourceRoute, targetRoutes]) => {\n if (!merged.routes[sourceRoute]) {\n merged.routes[sourceRoute] = {\n prefetch: [],\n };\n }\n\n // Add manual rules with high priority\n targetRoutes.forEach((targetRoute) => {\n // Check if this rule already exists\n const existing = merged.routes[sourceRoute].prefetch.find(\n (t) => t.route === targetRoute\n );\n\n if (existing) {\n // Update existing with manual flag and high priority\n existing.manual = true;\n existing.priority = 'high';\n existing.probability = 1.0;\n } else {\n // Add new manual rule\n merged.routes[sourceRoute].prefetch.unshift({\n route: targetRoute,\n probability: 1.0,\n count: 0, // Not from analytics\n priority: 'high',\n manual: true,\n });\n }\n });\n\n if (this.debug) {\n console.log(` βœ… Added manual rule: ${sourceRoute} β†’ [${targetRoutes.join(', ')}]`);\n }\n });\n\n return merged;\n }\n\n /**\n * NEW STRATEGY 0: Route to Chunk Name Mapping\n * Maps route β†’ component name β†’ chunk name β†’ manifest file\n * This is the most reliable method as it uses the actual vite.config.ts chunking strategy\n */\n private routeToChunkViaName(route: string): string | null {\n const normalizedRoute = route.toLowerCase();\n\n // Step 1: Get component name from route\n const componentName = ConfigGenerator.ROUTE_TO_COMPONENT_NAME[normalizedRoute];\n if (!componentName) {\n if (this.debug) {\n console.log(` ❌ Route ${route} not in ROUTE_TO_COMPONENT_NAME mapping`);\n }\n return null;\n }\n\n // Step 2: Get chunk name from component\n const chunkName = ConfigGenerator.COMPONENT_TO_CHUNK_NAME[componentName];\n if (!chunkName) {\n if (this.debug) {\n console.log(` ❌ Component ${componentName} not in COMPONENT_TO_CHUNK_NAME mapping`);\n }\n return null;\n }\n\n // Step 3: Find chunk file in manifest by name property\n const chunkEntry = Object.entries(this.manifest).find(\n ([key, entry]) =>\n (entry as any).name === chunkName || key.includes(chunkName)\n );\n\n if (!chunkEntry) {\n if (this.debug) {\n console.log(` ❌ Chunk name ${chunkName} not found in manifest`);\n }\n return null;\n }\n\n const chunkFile = (chunkEntry[1] as any).file;\n if (this.debug) {\n console.log(\n ` βœ… Via-Name Strategy: ${route} β†’ ${componentName} β†’ ${chunkName} β†’ ${chunkFile}`\n );\n }\n\n return chunkFile;\n }\n\n /**\n * Map route to chunk file using Vite manifest\n * Tries multiple strategies to find the correct chunk\n */\n private routeToChunk(route: string): string | null {\n // Strategy 0: Route β†’ Component β†’ Chunk Name mapping (NEW - MOST RELIABLE)\n const viaName = this.routeToChunkViaName(route);\n if (viaName) {\n return viaName;\n }\n\n // Strategy 1: Direct match (e.g., src/pages/orders/index.tsx)\n const directMatch = this.findDirectMatch(route);\n if (directMatch) {\n return directMatch;\n }\n\n // Strategy 2: Pattern match (e.g., orders β†’ src/pages/orders/*)\n const patternMatch = this.findPatternMatch(route);\n if (patternMatch) {\n return patternMatch;\n }\n\n // Strategy 3: Fuzzy match (e.g., /dispatch-order β†’ dispatchOrder)\n const fuzzyMatch = this.findFuzzyMatch(route);\n if (fuzzyMatch) {\n return fuzzyMatch;\n }\n\n return null;\n }\n\n /**\n * Strategy 1: Direct path match\n */\n private findDirectMatch(route: string): string | null {\n // Remove :id or $id parameters (React Router and TanStack Router) but keep the route structure\n const normalizedRoute = route.replace(/\\/[:$]\\w+/g, '');\n const cleanRoutePath = normalizedRoute.replace(/^\\//, ''); // Remove leading slash\n\n // Convert hyphenated routes to PascalCase for component name matching\n // e.g., /audit-logs β†’ AuditLogs, /api-docs β†’ ApiDocs, /dashboard β†’ Dashboard\n const routeSegments = normalizedRoute.split('/').filter(Boolean);\n const pascalCaseComponent = routeSegments\n .map(segment => {\n // Convert each segment: api-docs β†’ ApiDocs, dashboard β†’ Dashboard\n const words = segment.split('-');\n return words\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n })\n .join('/');\n\n // For single-segment routes like /dashboard, create both versions\n let singleSegmentPascal = null;\n if (routeSegments.length === 1) {\n const segment = routeSegments[0];\n const words = segment.split('-');\n singleSegmentPascal = words\n .map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())\n .join('');\n }\n\n // Try common patterns using normalized route (without :id or $id)\n // PRIORITIZE: Direct file names for pages first (e.g., Dashboard.tsx)\n const patterns = [\n // HIGHEST PRIORITY: Exact page component name matches\n singleSegmentPascal ? `src/pages/${singleSegmentPascal}.tsx` : null,\n singleSegmentPascal ? `src/pages/${singleSegmentPascal}.ts` : null,\n singleSegmentPascal ? `src/pages/${singleSegmentPascal}.jsx` : null,\n singleSegmentPascal ? `src/pages/${singleSegmentPascal}.js` : null,\n // For multi-segment routes with hyphens\n `src/pages/${pascalCaseComponent}.tsx`,\n `src/pages/${pascalCaseComponent}.ts`,\n `src/pages/${pascalCaseComponent}.jsx`,\n `src/pages/${pascalCaseComponent}.js`,\n // Features folder\n `src/features${normalizedRoute}/index.ts`,\n `src/features${normalizedRoute}/index.tsx`,\n `src/features${normalizedRoute}/index.js`,\n `src/features${normalizedRoute}/index.jsx`,\n // Pages folder - try both directory and file formats\n `src/pages${normalizedRoute}/index.tsx`,\n `src/pages${normalizedRoute}/index.ts`,\n `src/pages${normalizedRoute}/index.jsx`,\n `src/pages${normalizedRoute}/index.js`,\n `src/pages${normalizedRoute}.tsx`,\n `src/pages${normalizedRoute}.ts`,\n `src/pages${normalizedRoute}.jsx`,\n `src/pages${normalizedRoute}.js`,\n // Fallback to old capitalize method (single capital letter)\n `src/pages/${this.capitalize(cleanRoutePath)}.tsx`,\n `src/pages/${this.capitalize(cleanRoutePath)}.ts`,\n // Full paths with app prefix\n `apps/farmart-pro/src/features${normalizedRoute}/index.ts`,\n `apps/farmart-pro/src/features${normalizedRoute}/index.tsx`,\n `apps/farmart-pro/src/pages${normalizedRoute}/index.tsx`,\n ].filter(Boolean); // Remove null entries\n\n for (let i = 0; i < patterns.length; i++) {\n const pattern = patterns[i];\n if (!pattern) continue; // Skip null patterns\n const entry = this.manifest[pattern];\n if (entry) {\n return entry.file;\n }\n }\n\n return null;\n }\n\n /**\n * Capitalize first letter of string\n */\n private capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n /**\n * Strategy 2: Pattern matching with wildcards\n */\n private findPatternMatch(route: string): string | null {\n const routeSegments = route.split('/').filter(Boolean);\n if (routeSegments.length === 0) return null;\n\n // Find manifest entries that match route pattern\n const candidates = Object.entries(this.manifest)\n .filter(([path]) => {\n const pathSegments = path.split('/').filter(Boolean);\n\n // Check if path contains route segments (support both :id and $id)\n return routeSegments.every((segment) =>\n pathSegments.some((ps) =>\n ps.toLowerCase().includes(segment.replace(/[:$]\\w+/, '').toLowerCase())\n )\n );\n })\n .sort(([pathA], [pathB]) => {\n // Prioritize pages folder\n if (pathA.includes('/pages/') && !pathB.includes('/pages/')) return -1;\n if (!pathA.includes('/pages/') && pathB.includes('/pages/')) return 1;\n\n // Prioritize entry points\n const aIsEntry = pathA.includes('index.tsx') || pathA.includes('index.ts');\n const bIsEntry = pathB.includes('index.tsx') || pathB.includes('index.ts');\n if (aIsEntry && !bIsEntry) return -1;\n if (!aIsEntry && bIsEntry) return 1;\n\n // Prioritize tsx over other extensions\n if (pathA.includes('.tsx') && !pathB.includes('.tsx')) return -1;\n if (!pathA.includes('.tsx') && pathB.includes('.tsx')) return 1;\n\n return 0;\n });\n\n if (candidates.length > 0) {\n if (this.debug) {\n console.log(` βœ… Pattern match found: ${candidates[0][0]} β†’ ${candidates[0][1].file}`);\n }\n return candidates[0][1].file;\n }\n\n if (this.debug) {\n console.log(` No pattern match found`);\n }\n\n return null;\n }\n\n /**\n * Strategy 3: Fuzzy matching\n * Converts route to camelCase/PascalCase and searches\n */\n private findFuzzyMatch(route: string): string | null {\n // Remove parameters first\n const cleanRoute = route.replace(/\\/[:$]\\w+/g, '');\n\n // Convert /api-docs to ApiDocs (PascalCase for file names)\n const routeSegments = cleanRoute.split('/').filter(Boolean);\n const pascalCase = routeSegments\n .map((segment) => {\n const words = segment.split('-');\n return words\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n })\n .join('');\n\n // Also try camelCase (for method names)\n const camelCase = pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);\n\n if (this.debug) {\n console.log(` Fuzzy match - Route: ${route}`);\n console.log(` Trying PascalCase: ${pascalCase}, camelCase: ${camelCase}`);\n }\n\n // Search manifest for matching files - prioritize exact name matches\n // CRITICAL: Only match source files (pages/features), NOT dependency chunks\n const candidates = Object.entries(this.manifest)\n .filter(([path, entry]) => {\n // Skip dependency chunks (start with underscore or just contain 'chunk-' in the file name)\n if (path.startsWith('_') || path.startsWith('node_modules')) {\n return false;\n }\n\n const fileName = path.split('/').pop() || '';\n const fileNameWithoutExt = fileName.replace(/\\.[^.]+$/, '');\n\n // Exact match is best (exact file name)\n if (fileNameWithoutExt === pascalCase || fileNameWithoutExt === camelCase) {\n return true;\n }\n\n // Partial match (file name includes our component name)\n if (fileName.includes(pascalCase) || fileName.includes(camelCase)) {\n return true;\n }\n\n // Segment match (any path segment contains our component name)\n const pathSegments = path.toLowerCase().split('/');\n const lowerPascal = pascalCase.toLowerCase();\n const lowerCamel = camelCase.toLowerCase();\n\n return pathSegments.some(seg =>\n seg.includes(lowerPascal) || seg.includes(lowerCamel)\n );\n })\n .sort(([pathA, entryA], [pathB, entryB]) => {\n // Prioritize source files over chunk manifests\n const aHasSrc = (entryA as any).src ? 1 : 0;\n const bHasSrc = (entryB as any).src ? 1 : 0;\n if (aHasSrc !== bHasSrc) return bHasSrc - aHasSrc;\n\n // Prefer matches that have the exact file name\n const fileA = pathA.split('/').pop()?.replace(/\\.[^.]+$/, '') || '';\n const fileB = pathB.split('/').pop()?.replace(/\\.[^.]+$/, '') || '';\n\n // Exact match gets priority\n if (fileA === pascalCase) return -1;\n if (fileB === pascalCase) return 1;\n if (fileA === camelCase) return -1;\n if (fileB === camelCase) return 1;\n\n // Prefer files in pages folder\n if (pathA.includes('/pages/') && !pathB.includes('/pages/')) return -1;\n if (!pathA.includes('/pages/') && pathB.includes('/pages/')) return 1;\n\n return 0;\n });\n\n if (candidates.length > 0) {\n const result = candidates[0][1].file;\n if (this.debug) {\n console.log(` βœ… Fuzzy match found: ${candidates[0][0]} β†’ ${result}`);\n }\n return result;\n }\n\n if (this.debug) {\n console.log(` No fuzzy match found`);\n }\n\n return null;\n }\n\n /**\n * Get manifest entry by file name\n */\n private getManifestEntryByFile(fileName: string) {\n return Object.values(this.manifest).find((entry) => entry.file === fileName);\n }\n\n /**\n * Get all chunks referenced in config\n */\n getReferencedChunks(config: PrefetchConfig): string[] {\n return Object.values(config.chunks);\n }\n\n /**\n * Validate that all chunks exist in manifest\n */\n validateChunks(config: PrefetchConfig): {\n valid: boolean;\n missing: string[];\n } {\n const missing: string[] = [];\n const manifestFiles = new Set(Object.values(this.manifest).map((e) => e.file));\n\n Object.entries(config.chunks).forEach(([route, chunk]) => {\n if (!manifestFiles.has(chunk)) {\n missing.push(`${route} -> ${chunk}`);\n }\n });\n\n return {\n valid: missing.length === 0,\n missing,\n };\n }\n\n /**\n * Extract route patterns for dynamic route matching\n * Groups routes by their base path and includes pattern variants\n * E.g., /purchase-order and /purchase-order/:id become patterns for matching\n */\n private extractRoutePatterns(routes: string[]): Record<string, string[]> {\n const patterns: Record<string, string[]> = {};\n\n for (const route of routes) {\n // Check if route contains dynamic parameters (:param or $param for TanStack)\n if (route.includes(':') || route.includes('$')) {\n // This is a dynamic route pattern - keep as-is\n patterns[route] = [route];\n\n // Also add the base route if it exists and is different\n const base = route.split(/[:$]/)[0];\n if (base && base !== route) {\n // Ensure base route also gets patterns\n if (!patterns[base]) {\n patterns[base] = [base, route];\n } else if (!patterns[base].includes(route)) {\n patterns[base].push(route);\n }\n }\n } else {\n // Static route - just use itself\n patterns[route] = [route];\n }\n }\n\n if (this.debug && Object.keys(patterns).length > 0) {\n console.log(`\\nπŸ” Extracted route patterns for dynamic matching:`);\n Object.entries(patterns).forEach(([route, patternList]) => {\n if (patternList.length > 1) {\n console.log(` ${route} β†’ [${patternList.join(', ')}]`);\n }\n });\n }\n\n return patterns;\n }\n\n /**\n * Match a pathname against route patterns\n * Supports both static routes and dynamic routes with parameters\n */\n private matchRoutePattern(pathname: string, pattern: string): boolean {\n // Convert route pattern to regex\n // E.g., /purchase-order/:id β†’ /purchase-order/[^/]+\n const patternRegex = new RegExp(\n '^' + pattern\n .replace(/:[^/]+/g, '[^/]+') // Match :param style\n .replace(/\\$[^/]+/g, '[^/]+') // Match $param style (TanStack Router)\n .replace(/\\*/g, '.*') + // Match wildcard\n '$'\n );\n return patternRegex.test(pathname);\n }\n\n /**\n * Find matching route pattern for a given pathname\n * Used by hooks to match actual navigation paths to config routes\n */\n findMatchingPattern(\n pathname: string,\n routes: Record<string, any>\n ): string | null {\n for (const [route, config] of Object.entries(routes)) {\n const patterns = (config as any).patterns || [route];\n for (const pattern of patterns) {\n if (this.matchRoutePattern(pathname, pattern)) {\n return route;\n }\n }\n }\n return null;\n }\n\n /**\n * Generate segment-specific prefetch configurations\n * Creates one config per user segment/role\n */\n generateSegmentConfigs(\n segmentModels: Map<string, PrefetchModel>\n ): Map<string, PrefetchConfig> {\n const segmentConfigs = new Map<string, PrefetchConfig>();\n\n segmentModels.forEach((model, segment) => {\n if (this.debug) {\n console.log(`\\nπŸ“¦ Generating config for segment: \"${segment}\"`);\n }\n\n const config = this.generate(model);\n\n // Add segment metadata to config\n (config as any).segment = segment;\n\n segmentConfigs.set(segment, config);\n\n if (this.debug) {\n console.log(` βœ… Config generated for \"${segment}\"`);\n console.log(` Routes: ${Object.keys(config.routes).length}`);\n console.log(` Chunks: ${Object.keys(config.chunks).length}`);\n }\n });\n\n if (this.debug) {\n console.log(`\\nβœ… Generated ${segmentConfigs.size} segment-specific configurations`);\n }\n\n return segmentConfigs;\n }\n}\n","/**\n * Cache Manager\n * Manages caching of trained models to avoid redundant GA API calls\n * Uses Node.js fs to cache models locally during build time\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { PrefetchModel, CacheConfig } from '../types';\n\nexport class CacheManager {\n private cacheDir: string;\n private ttl: number;\n private enabled: boolean;\n private debug: boolean;\n\n constructor(config: CacheConfig = {}, debug = false) {\n this.enabled = config.enabled ?? true; // Enabled by default\n this.ttl = config.ttl ?? 24 * 60 * 60 * 1000; // Default: 24 hours\n this.cacheDir = config.path ?? path.join(process.cwd(), '.prefetch-cache');\n this.debug = debug;\n\n if (this.enabled && !fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n if (this.debug) {\n console.log(`πŸ“ Created cache directory: ${this.cacheDir}`);\n }\n }\n }\n\n /**\n * Get cached model for environment\n * Returns null if cache doesn't exist or is expired\n */\n async get(environment: string): Promise<PrefetchModel | null> {\n if (!this.enabled) {\n if (this.debug) console.log('⏭️ Cache disabled, skipping cache lookup');\n return null;\n }\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n if (this.debug) console.log(`πŸ“¦ Cache miss for environment: ${environment}`);\n return null;\n }\n\n const stats = fs.statSync(cacheFile);\n const cacheAge = Date.now() - stats.mtimeMs;\n\n if (cacheAge > this.ttl) {\n if (this.debug) console.log(`⏰ Cache expired for ${environment} (${Math.round(cacheAge / 1000 / 60)} minutes old)`);\n fs.unlinkSync(cacheFile);\n return null;\n }\n\n const cachedData = fs.readFileSync(cacheFile, 'utf-8');\n const model: PrefetchModel = JSON.parse(cachedData);\n\n if (this.debug) {\n console.log(`βœ… Cache hit for environment: ${environment} (${Math.round(cacheAge / 1000)} seconds old)`);\n console.log(` Cached model has ${Object.keys(model.routes).length} routes`);\n }\n\n return model;\n } catch (error) {\n console.error(`❌ Error reading cache for ${environment}:`, error);\n return null;\n }\n }\n\n /**\n * Save model to cache\n */\n async set(environment: string, model: PrefetchModel): Promise<void> {\n if (!this.enabled) {\n if (this.debug) console.log('⏭️ Cache disabled, skipping cache write');\n return;\n }\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n fs.writeFileSync(cacheFile, JSON.stringify(model, null, 2), 'utf-8');\n\n if (this.debug) {\n console.log(`πŸ’Ύ Cached model for ${environment}`);\n console.log(` Location: ${cacheFile}`);\n console.log(` Routes: ${Object.keys(model.routes).length}`);\n }\n } catch (error) {\n console.error(`❌ Error writing cache for ${environment}:`, error);\n }\n }\n\n /**\n * Invalidate cache for specific environment or all environments\n */\n async invalidate(environment?: string): Promise<void> {\n if (!this.enabled) return;\n\n try {\n if (environment) {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n if (fs.existsSync(cacheFile)) {\n fs.unlinkSync(cacheFile);\n if (this.debug) {\n console.log(`πŸ—‘οΈ Invalidated cache for ${environment}`);\n }\n }\n } else {\n // Clear all cache files\n const files = fs.readdirSync(this.cacheDir);\n files.forEach((file) => {\n if (file.endsWith('.json')) {\n fs.unlinkSync(path.join(this.cacheDir, file));\n }\n });\n if (this.debug) {\n console.log(`πŸ—‘οΈ Cleared all cache files`);\n }\n }\n } catch (error) {\n console.error(`❌ Error invalidating cache:`, error);\n }\n }\n\n /**\n * Get cache statistics\n */\n getStats(): {\n enabled: boolean;\n cacheDir: string;\n ttl: number;\n cachedEnvironments: string[];\n totalSize: number;\n } {\n const cachedEnvironments: string[] = [];\n let totalSize = 0;\n\n if (this.enabled && fs.existsSync(this.cacheDir)) {\n const files = fs.readdirSync(this.cacheDir);\n files.forEach((file) => {\n if (file.endsWith('.json')) {\n const filePath = path.join(this.cacheDir, file);\n const stats = fs.statSync(filePath);\n cachedEnvironments.push(file.replace('.json', ''));\n totalSize += stats.size;\n }\n });\n }\n\n return {\n enabled: this.enabled,\n cacheDir: this.cacheDir,\n ttl: this.ttl,\n cachedEnvironments,\n totalSize,\n };\n }\n\n /**\n * Check if cache exists and is valid for environment\n */\n async isValid(environment: string): Promise<boolean> {\n if (!this.enabled) return false;\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n return false;\n }\n\n const stats = fs.statSync(cacheFile);\n const cacheAge = Date.now() - stats.mtimeMs;\n\n return cacheAge <= this.ttl;\n } catch {\n return false;\n }\n }\n\n /**\n * Get cache age in milliseconds\n */\n async getCacheAge(environment: string): Promise<number | null> {\n if (!this.enabled) return null;\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n return null;\n }\n\n const stats = fs.statSync(cacheFile);\n return Date.now() - stats.mtimeMs;\n } catch {\n return null;\n }\n }\n}\n","/**\n * Main Vite Plugin\n * Integrates all components and provides Vite hooks\n */\n\nimport type { Plugin, ResolvedConfig } from 'vite';\nimport { BigQueryAnalyticsConnector } from './analytics/bigquery-connector';\nimport { GuessJSMLTrainer } from './model/guessjs-ml-trainer';\nimport { ConfigGenerator } from './config-generator';\nimport { CacheManager } from './cache-manager';\nimport type {\n PluginOptions,\n PrefetchModel,\n ViteManifest,\n} from '../types';\n\nexport function smartPrefetch(options: PluginOptions = {}): Plugin {\n const {\n framework = 'react',\n strategy = 'hybrid',\n analytics,\n manualRules = {},\n cache = {},\n advanced = {},\n } = options;\n\n const debug = advanced.debug ?? false;\n\n let config: ResolvedConfig;\n let cacheManager: CacheManager;\n let prefetchModel: PrefetchModel | null = null;\n let segmentModels: Map<string, PrefetchModel> | null = null;\n\n return {\n name: '@farmart/vite-plugin-smart-prefetch',\n enforce: 'post',\n\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n\n // Ensure Vite manifest is enabled\n if (!config.build.manifest) {\n config.build.manifest = true;\n if (debug) {\n console.log('βœ… Enabled Vite manifest generation');\n }\n }\n\n // Initialize cache manager\n cacheManager = new CacheManager(cache, debug);\n\n if (debug) {\n console.log('\\nπŸš€ Smart Prefetch Plugin Initialized');\n console.log(` Framework: ${framework}`);\n console.log(` Strategy: ${strategy}`);\n console.log(` Analytics: ${analytics ? 'enabled' : 'disabled'}`);\n console.log(` Manual rules: ${Object.keys(manualRules).length}`);\n console.log(` Cache: ${cache.enabled !== false ? 'enabled' : 'disabled'}`);\n }\n\n // In development mode, generate prefetch config for testing\n if (config.command === 'serve' && debug) {\n // Create a simple dev-time manifest for testing\n const devManifest: ViteManifest = {};\n\n // Create entries for all manual rules\n Object.keys(manualRules).forEach((route) => {\n const routeKey = `src/features${route}/index.tsx`;\n devManifest[routeKey] = {\n file: `features${route.replace(/\\//g, '-')}.js`,\n imports: [],\n };\n });\n\n // Also try to discover routes from src/pages directory\n const fs = await import('node:fs');\n const path = await import('node:path');\n const pagesDir = path.join(config.root, 'src/pages');\n\n if (fs.existsSync(pagesDir)) {\n const files = fs.readdirSync(pagesDir);\n files.forEach((file) => {\n if (file.endsWith('.tsx') || file.endsWith('.ts')) {\n const pageName = file.replace(/\\.(tsx|ts)$/, '');\n const routeKey = `src/pages/${file}`;\n devManifest[routeKey] = {\n file: `chunks/${pageName}-[hash].js`,\n imports: [],\n };\n }\n });\n }\n\n // Store for use in transformIndexHtml\n (config as any).__smartPrefetchDevManifest = devManifest;\n }\n },\n\n configureServer(server) {\n // In development mode, serve the prefetch-config.json dynamically\n // This ensures we always use the latest model instead of stale [hash] placeholders\n return () => {\n server.middlewares.use('/prefetch-config.json', async (req, res, next) => {\n if (req.method !== 'GET') {\n next();\n return;\n }\n\n try {\n // In dev mode, always generate a fresh config with current model\n if (!prefetchModel) {\n if (debug) {\n console.warn('⚠️ No prefetch model available yet');\n }\n res.statusCode = 503;\n res.end(JSON.stringify({ error: 'Prefetch model not ready, still loading analytics data...' }));\n return;\n }\n\n // Generate config dynamically on each request (dev only)\n // Create a minimal manifest for dev mode - just file paths without real hashes\n const devManifest: ViteManifest = {};\n\n // Map model routes to dev manifest entries\n Object.keys(prefetchModel.routes).forEach((route) => {\n // Create a fake but consistent manifest entry for dev\n const routeKey = `src/pages${route}/index.tsx`;\n const routeName = route.split('/').filter(Boolean).pop() || 'index';\n const devHash = 'dev-' + routeName.slice(0, 6).padEnd(8, '0');\n devManifest[routeKey] = {\n file: `chunks/${routeName}-${devHash}.js`,\n imports: [],\n };\n });\n\n // Generate final config with dev manifest and Vite server instance for chunk discovery\n const generator = new ConfigGenerator(devManifest as ViteManifest, manualRules, debug, server);\n const finalConfig = generator.generate(prefetchModel);\n\n res.setHeader('Content-Type', 'application/json');\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); // Never cache in dev\n res.end(JSON.stringify(finalConfig, null, 2));\n\n if (debug) {\n console.log('πŸ“€ Serving fresh prefetch-config.json from development server');\n }\n return;\n } catch (error) {\n if (debug) {\n console.error('Error serving prefetch-config.json:', error);\n }\n res.statusCode = 500;\n res.end(JSON.stringify({ error: 'Internal server error', details: String(error) }));\n }\n });\n };\n },\n\n async buildStart() {\n if (!analytics) {\n if (debug) {\n console.log('\\n⏭️ Analytics disabled, using manual rules only');\n }\n // Create model from manual rules only\n prefetchModel = createManualModel(manualRules, config.command === 'serve' ? 'development' : 'production');\n return;\n }\n\n const environment = analytics.environment || (config.command === 'serve' ? 'development' : 'production');\n\n // Check cache first\n const cached = await cacheManager.get(environment);\n if (cached) {\n prefetchModel = cached;\n return;\n }\n\n // Fetch and train model\n try {\n if (debug) {\n console.log(`\\nπŸ“Š Fetching ${analytics.provider} data and training model...`);\n }\n\n // Initialize BigQuery Analytics connector\n const bqConnector = new BigQueryAnalyticsConnector(\n (analytics.credentials as any).projectId,\n (analytics.credentials as any).datasetId,\n debug\n );\n\n console.log('\\n🎯 Using real navigation data from BigQuery GA4 export...');\n\n // Fetch navigation data\n const navigationData = await bqConnector.fetchNavigationSequences(analytics.dataRange);\n\n if (navigationData.length === 0) {\n console.warn('⚠️ No navigation data found, using manual rules only');\n prefetchModel = createManualModel(manualRules, environment);\n return;\n }\n\n // Train model using Markov chain ML with Bayesian probability\n // Uses real navigation data to predict likely route transitions\n console.log(`\\nπŸ€– Training model using Markov Chain ML...`);\n const mlTrainer = new GuessJSMLTrainer(analytics.model, debug);\n const prefetchModelResult = mlTrainer.trainMLModel(navigationData, environment);\n prefetchModel = prefetchModelResult;\n\n // Cache model\n await cacheManager.set(environment, prefetchModel);\n\n // Try to train segment-specific models if segment data is available\n try {\n const navigationWithSegments = await bqConnector.fetchNavigationWithSegments(analytics.dataRange);\n\n if (navigationWithSegments.length > 0) {\n console.log(`\\nπŸ‘₯ Training segment-specific models...`);\n segmentModels = mlTrainer.trainSegmentedModels(navigationWithSegments, environment);\n\n if (debug && segmentModels.size > 0) {\n console.log(` βœ… Trained ${segmentModels.size} segment-specific models`);\n }\n }\n } catch (error) {\n if (debug) {\n console.warn(`⚠️ Could not train segment models:`, error instanceof Error ? error.message : 'Unknown error');\n }\n // Segment training is optional, don't fail the build\n }\n } catch (error) {\n console.error('❌ Failed to fetch analytics data:', error);\n console.log('⚠️ Falling back to manual rules only');\n\n // Fallback to manual rules\n prefetchModel = createManualModel(manualRules, environment);\n \n // Don't fail the build, just warn\n if (debug) {\n console.error('Error details:', error);\n }\n }\n },\n\n async writeBundle(outputOptions) {\n if (!prefetchModel) {\n console.warn('⚠️ No prefetch model available, skipping config generation');\n return;\n }\n\n // Read manifest from disk instead of bundle\n const fs = await import('node:fs');\n const path = await import('node:path');\n\n const outDir = outputOptions.dir || 'dist';\n const manifestPath = path.join(outDir, '.vite', 'manifest.json');\n\n if (!fs.existsSync(manifestPath)) {\n console.warn('⚠️ Vite manifest not found at:', manifestPath);\n return;\n }\n\n const manifestContent = fs.readFileSync(manifestPath, 'utf-8');\n const manifest: ViteManifest = JSON.parse(manifestContent);\n\n if (debug) {\n console.log(`\\nπŸ“¦ Vite manifest loaded: ${Object.keys(manifest).length} entries`);\n }\n\n // Generate final config with chunk mappings\n const generator = new ConfigGenerator(manifest, manualRules, debug);\n const finalConfig = generator.generate(prefetchModel);\n\n // Validate chunks\n const validation = generator.validateChunks(finalConfig);\n if (!validation.valid) {\n console.warn('⚠️ Some chunks could not be mapped:');\n validation.missing.forEach((m) => console.warn(` ${m}`));\n } else {\n console.log(`βœ… All ${Object.keys(finalConfig.chunks).length} chunks successfully mapped with real build hashes`);\n }\n\n // Write prefetch-config.json to disk\n const configPath = path.join(outDir, 'prefetch-config.json');\n fs.writeFileSync(configPath, JSON.stringify(finalConfig, null, 2));\n\n // Save model routes for testing purposes\n const modelRoutesPath = path.join(outDir, 'model-routes.json');\n fs.writeFileSync(modelRoutesPath, JSON.stringify(prefetchModel.routes, null, 2));\n\n if (debug) {\n console.log('βœ… Emitted prefetch-config.json with real chunk hashes');\n console.log('βœ… Emitted model-routes.json');\n console.log(`πŸ“Š Total routes configured: ${Object.keys(finalConfig.routes).length}`);\n console.log(`πŸ“¦ Total chunks: ${Object.keys(finalConfig.chunks).length}`);\n }\n\n // Generate and write segment-specific configs\n if (segmentModels && segmentModels.size > 0) {\n console.log(`\\nπŸ“ Generating segment-specific prefetch configurations...`);\n\n const segmentGenerator = new ConfigGenerator(manifest, manualRules, debug);\n const segmentConfigs = segmentGenerator.generateSegmentConfigs(segmentModels);\n\n // Create segment configs directory\n const segmentDir = path.join(outDir, 'prefetch-configs');\n if (!fs.existsSync(segmentDir)) {\n fs.mkdirSync(segmentDir, { recursive: true });\n }\n\n // Write each segment config\n segmentConfigs.forEach((segConfig, segment) => {\n const segmentPath = path.join(segmentDir, `${segment}.json`);\n fs.writeFileSync(segmentPath, JSON.stringify(segConfig, null, 2));\n\n if (debug) {\n console.log(` βœ… Emitted ${segment}.json (${Object.keys(segConfig.routes).length} routes)`);\n }\n });\n\n // Write segment index/manifest\n const segmentIndex = {\n generatedAt: new Date().toISOString(),\n environment: analytics?.environment || (config.command === 'serve' ? 'development' : 'production'),\n segments: Array.from(segmentConfigs.keys()),\n description: 'Segment-specific prefetch configurations. Use based on user role/segment.'\n };\n\n const segmentIndexPath = path.join(segmentDir, 'index.json');\n fs.writeFileSync(segmentIndexPath, JSON.stringify(segmentIndex, null, 2));\n\n if (debug) {\n console.log(`\\nβœ… Emitted ${segmentConfigs.size} segment-specific configurations`);\n console.log(` Location: ${segmentDir}`);\n console.log(` Segments: ${Array.from(segmentConfigs.keys()).join(', ')}`);\n }\n }\n\n // Generate analytics dashboard if requested\n if (analytics?.dashboard) {\n const dashboardHtml = generateDashboard(finalConfig);\n const dashboardPath = path.join(outDir, 'prefetch-report.html');\n fs.writeFileSync(dashboardPath, dashboardHtml);\n\n if (debug) {\n console.log('βœ… Emitted prefetch-report.html');\n }\n }\n },\n\n transformIndexHtml() {\n // Inject runtime configuration into HTML\n return [\n {\n tag: 'script',\n attrs: { type: 'module' },\n children: `\n // Smart Prefetch Plugin Runtime Config\n window.__SMART_PREFETCH__ = {\n strategy: '${strategy}',\n framework: '${framework}',\n debug: ${debug},\n };\n `,\n injectTo: 'head',\n },\n ];\n },\n };\n}\n\n/**\n * Create a model from manual rules only (no analytics)\n */\nfunction createManualModel(\n manualRules: Record<string, string[]>,\n environment: string\n): PrefetchModel {\n const model: PrefetchModel = {\n version: '1.0.0',\n generatedAt: new Date().toISOString(),\n environment,\n routes: {},\n dataSource: {\n provider: 'manual',\n dateRange: 'N/A',\n totalSessions: 0,\n totalRoutes: Object.keys(manualRules).length,\n },\n config: {\n type: 'probability',\n threshold: 1.0,\n maxPrefetch: 10,\n },\n };\n\n Object.entries(manualRules).forEach(([source, targets]) => {\n model.routes[source] = {\n prefetch: targets.map((target) => ({\n route: target,\n probability: 1.0,\n count: 0,\n priority: 'high',\n manual: true,\n })),\n };\n });\n\n return model;\n}\n\n/**\n * Generate analytics dashboard HTML\n */\nfunction generateDashboard(config: any): string {\n const totalRoutes = Object.keys(config.routes).length;\n const totalPrefetches = Object.values(config.routes).reduce(\n (sum: number, route: any) => sum + route.prefetch.length,\n 0\n );\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Smart Prefetch Report</title>\n <style>\n body {\n font-family: system-ui, -apple-system, sans-serif;\n max-width: 1200px;\n margin: 0 auto;\n padding: 2rem;\n background: #f5f5f5;\n }\n h1 { color: #333; }\n .stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;\n margin: 2rem 0;\n }\n .stat-card {\n background: white;\n padding: 1.5rem;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n .stat-value { font-size: 2rem; font-weight: bold; color: #4CAF50; }\n .stat-label { color: #666; margin-top: 0.5rem; }\n .route-list {\n background: white;\n padding: 1.5rem;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n .route-item {\n padding: 1rem;\n border-bottom: 1px solid #eee;\n }\n .route-item:last-child { border-bottom: none; }\n .route-source { font-weight: bold; color: #333; }\n .prefetch-target {\n margin-left: 2rem;\n padding: 0.5rem;\n color: #666;\n }\n .priority-high { color: #4CAF50; }\n .priority-medium { color: #FF9800; }\n .priority-low { color: #9E9E9E; }\n </style>\n</head>\n<body>\n <h1>πŸš€ Smart Prefetch Report</h1>\n <p>Generated: ${config.generatedAt}</p>\n <p>Environment: ${config.environment}</p>\n\n <div class=\"stats\">\n <div class=\"stat-card\">\n <div class=\"stat-value\">${totalRoutes}</div>\n <div class=\"stat-label\">Routes with Prefetch</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${totalPrefetches}</div>\n <div class=\"stat-label\">Total Prefetch Targets</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${config.dataSource?.totalSessions?.toLocaleString() || 'N/A'}</div>\n <div class=\"stat-label\">Sessions Analyzed</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${(config.model.threshold * 100).toFixed(0)}%</div>\n <div class=\"stat-label\">Probability Threshold</div>\n </div>\n </div>\n\n <div class=\"route-list\">\n <h2>Prefetch Configuration</h2>\n ${Object.entries(config.routes)\n .map(\n ([source, data]: [string, any]) => `\n <div class=\"route-item\">\n <div class=\"route-source\">${source}</div>\n ${data.prefetch\n .map(\n (target: any) => `\n <div class=\"prefetch-target\">\n β†’ ${target.route}\n <span class=\"priority-${target.priority}\">\n (${(target.probability * 100).toFixed(1)}%, ${target.priority})\n </span>\n </div>\n `\n )\n .join('')}\n </div>\n `\n )\n .join('')}\n </div>\n</body>\n</html>`;\n}\n"],"mappings":"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","names":["path","path","fs","path"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/plugin/analytics/bigquery-connector.ts","../src/plugin/model/guessjs-ml-trainer.ts","../src/plugin/config-generator.ts","../src/plugin/cache-manager.ts","../src/plugin/index.ts"],"sourcesContent":["/**\n * @farmart/vite-plugin-smart-prefetch\n * Self-learning smart prefetch plugin for Vite applications\n */\n\n// Main plugin export (server-side only)\nexport { smartPrefetch } from './plugin';\n\n// Type exports (safe for both server and client)\nexport type {\n PluginOptions,\n PrefetchStrategy,\n AnalyticsConfig,\n BigQueryCredentials,\n DataRangeConfig,\n ModelConfig,\n ManualRules,\n CacheConfig,\n AdvancedConfig,\n PrefetchModel,\n PrefetchConfig,\n PrefetchTarget,\n NavigationData,\n ViteManifest,\n} from './types';\n\n// NOTE: PrefetchManager has been moved to '@farmart/vite-plugin-smart-prefetch/runtime'\n// to avoid bundling server-side dependencies (BigQuery) into client code\n","/**\n * BigQuery Analytics Connector\n * Queries GA4 event data from BigQuery to extract real navigation transitions\n */\n\nimport { BigQuery } from '@google-cloud/bigquery';\nimport { writeFileSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport type { NavigationData, DataRangeConfig } from '../../types';\n\nexport class BigQueryAnalyticsConnector {\n private bigquery: BigQuery;\n private projectId: string;\n private datasetId: string;\n private location: string;\n private debug: boolean;\n\n constructor(projectId: string, datasetId: string, location = 'asia-south1', debug = false) {\n this.projectId = projectId;\n this.datasetId = datasetId;\n this.location = location;\n this.debug = debug;\n\n // Initialize BigQuery client\n // Uses default credentials from environment\n this.bigquery = new BigQuery({\n projectId: projectId,\n });\n\n if (this.debug) {\n console.log('βœ… BigQuery Analytics connector initialized');\n console.log(` Project ID: ${projectId}`);\n console.log(` Dataset ID: ${datasetId}`);\n console.log(` Location: ${location}`);\n }\n }\n\n /**\n * Fetch real navigation transitions from BigQuery GA4 export\n * Queries the events table for page_view events with previous_page_path parameter\n */\n async fetchNavigationSequences(config: DataRangeConfig = {}): Promise<NavigationData[]> {\n const { days = 30 } = config;\n const minSessions = 1;\n\n console.log(`πŸ“Š Fetching navigation data from BigQuery...`);\n console.log(` Dataset: ${this.datasetId}`);\n console.log(` Date range: Last ${days} days`);\n\n try {\n // Query GA4 events for page transitions\n // Strategy: Use user_id and session_id to reconstruct user sessions and page transitions\n // This groups pages viewed by the same user in the same session to infer navigation flow\n const query = `\n WITH page_sessions AS (\n SELECT\n user_id,\n (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1) as session_id,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_location' LIMIT 1) as page_location,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) as page_path,\n event_timestamp,\n ROW_NUMBER() OVER (\n PARTITION BY user_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)\n ORDER BY event_timestamp\n ) as page_sequence\n FROM \\`${this.projectId}.${this.datasetId}.events_*\\`\n WHERE\n event_name = 'page_view'\n AND _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL ${days} DAY))\n AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())\n AND (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) IS NOT NULL\n ),\n transitions AS (\n SELECT\n COALESCE(curr.page_path, '(direct)') as from_page,\n LEAD(curr.page_path) OVER (\n PARTITION BY curr.user_id, curr.session_id\n ORDER BY curr.page_sequence\n ) as to_page\n FROM page_sessions curr\n WHERE curr.page_sequence > 0\n )\n SELECT\n from_page as previous_page_path,\n to_page as page_path,\n COUNT(*) as transition_count\n FROM transitions\n WHERE to_page IS NOT NULL\n GROUP BY from_page, to_page\n ORDER BY transition_count DESC\n LIMIT 10000\n `;\n\n if (this.debug) {\n console.log(`πŸ“€ BigQuery Query:`);\n console.log(query);\n }\n\n const [rows] = await this.bigquery.query({\n query,\n location: this.location,\n });\n\n if (this.debug) {\n console.log(`βœ… Query executed successfully`);\n console.log(` Rows returned: ${rows.length}`);\n }\n\n const navigationData: NavigationData[] = [];\n\n // IMPORTANT: Save RAW rows for inspection\n const rawData = rows.map((row: any) => ({\n previous_page_path: row.previous_page_path,\n page_path: row.page_path,\n transition_count: row.transition_count\n }));\n\n // Process rows and convert to NavigationData format\n rows.forEach((row: any) => {\n const previousPage = row.previous_page_path || '(direct)';\n const currentPage = row.page_path || '';\n const transitionCount = parseInt(row.transition_count || '0');\n\n // Normalize page paths\n const normalizedPrevious = previousPage === '(direct)' || previousPage === '(not set)' ? '(direct)' : this.normalizeRoute(previousPage);\n const normalizedCurrent = this.normalizeRoute(currentPage);\n\n // Only add valid transitions\n if (normalizedCurrent && transitionCount >= minSessions) {\n navigationData.push({\n from: normalizedPrevious,\n to: normalizedCurrent,\n count: transitionCount,\n });\n }\n });\n\n // Save raw and processed data to files for inspection\n this.saveDataForInspection(rawData, navigationData);\n\n if (this.debug) {\n console.log(`βœ… Processed ${navigationData.length} navigation transitions`);\n\n // Show top 5 transitions\n if (navigationData.length > 0) {\n console.log(`\\n Top 5 transitions:`);\n navigationData.slice(0, 5).forEach((nav, i) => {\n console.log(` ${i + 1}. ${nav.from} β†’ ${nav.to} (${nav.count} transitions)`);\n });\n }\n\n // Show unique routes\n const uniqueRoutes = new Set<string>();\n navigationData.forEach((nav) => {\n if (nav.from !== '(direct)') uniqueRoutes.add(nav.from);\n uniqueRoutes.add(nav.to);\n });\n console.log(`\\n πŸ“Š Unique routes: ${uniqueRoutes.size}`);\n console.log(` Routes: ${Array.from(uniqueRoutes).sort().join(', ')}`);\n\n console.log(`\\n πŸ“ Raw data saved to: .bigquery-raw-data/`);\n }\n\n return navigationData;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n // Check if this is a permission error\n if (errorMessage.includes('bigquery.jobs.create') || errorMessage.includes('PERMISSION_DENIED')) {\n console.error('❌ Failed to fetch BigQuery data: Permission Denied');\n console.error(' Service account needs BigQuery Job User role in the project');\n console.error(' Error details:', errorMessage);\n } else {\n console.error('❌ Failed to fetch BigQuery data:', error);\n }\n\n throw new Error(\n `BigQuery Analytics error: ${errorMessage}`\n );\n }\n }\n\n /**\n * Map friendly page names (with spaces/capitals) back to route paths\n * GA4 may log display names instead of URL paths\n * Examples: \"Audit Logs\" β†’ \"/audit-logs\", \"API Documentation\" β†’ \"/api-docs\", \"Home\" β†’ \"/\"\n */\n private friendlyNameToRoute(name: string): string {\n // Mapping of friendly names to route paths\n const friendlyToRoute: Record<string, string> = {\n // Exact matches (with spaces and capitals)\n 'API Documentation': '/api-docs',\n 'Audit Logs': '/audit-logs',\n '/Home': '/',\n '/home': '/',\n 'Home': '/',\n '/Dashboard': '/dashboard',\n 'Dashboard': '/dashboard',\n\n // PascalCase variants (all 27 routes)\n 'Profile': '/profile',\n 'Settings': '/settings',\n 'Preferences': '/preferences',\n 'Privacy': '/privacy',\n 'Security': '/security',\n 'Analytics': '/analytics',\n 'Reports': '/reports',\n 'Metrics': '/metrics',\n 'Projects': '/projects',\n 'Tasks': '/tasks',\n 'Teams': '/teams',\n 'Workspaces': '/workspaces',\n 'Workflows': '/workflows',\n 'Templates': '/templates',\n 'Logs': '/logs',\n 'AuditLogs': '/audit-logs',\n 'Integrations': '/integrations',\n 'ApiDocs': '/api-docs',\n 'Support': '/support',\n 'Help': '/help',\n 'Billing': '/billing',\n 'Plans': '/plans',\n 'Usage': '/usage',\n 'Permissions': '/permissions',\n 'Notifications': '/notifications',\n };\n\n // Check for exact match first\n if (friendlyToRoute[name]) {\n return friendlyToRoute[name];\n }\n\n // Try case-insensitive match\n const lowerName = name.toLowerCase();\n for (const [key, value] of Object.entries(friendlyToRoute)) {\n if (key.toLowerCase() === lowerName) {\n return value;\n }\n }\n\n // If it's already a route path, normalize it to lowercase\n if (name.startsWith('/')) {\n if (name === '/') {\n return '/';\n }\n return name.toLowerCase();\n }\n\n // Fallback: convert to lowercase and add leading slash\n return '/' + lowerName;\n }\n\n /**\n * Normalize route paths\n * Converts dynamic segments to parameters and friendly names to route paths\n */\n private normalizeRoute(path: string): string {\n // Filter out build artifacts and non-route paths\n const buildArtifacts = [\n /\\.(js|css|jpg|jpeg|png|gif|svg|webp|woff|woff2|ttf|eot|map)(\\?|#|$)/i,\n /\\[hash\\]/i,\n /\\/chunks\\//i,\n /\\/vendor\\//i,\n /\\/assets\\//i,\n /\\.vite\\//i,\n ];\n\n if (buildArtifacts.some((pattern) => pattern.test(path))) {\n return '';\n }\n\n // First, convert friendly names (with spaces/capitals) to route paths\n // e.g., \"Audit Logs\" β†’ \"/audit-logs\", \"API Documentation\" β†’ \"/api-docs\"\n let normalized = this.friendlyNameToRoute(path);\n\n // Remove query parameters and hash\n normalized = normalized.split('?')[0].split('#')[0];\n\n // Remove trailing slash (except for root /)\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n\n // Ensure lowercase for consistency (convert spaces to hyphens)\n if (normalized !== '/') {\n normalized = normalized.toLowerCase().replace(/ +/g, '-');\n }\n\n // Replace common ID patterns with :id\n normalized = normalized\n .replace(/\\/[0-9a-f]{24}(?=\\/|$)/gi, '/:id')\n .replace(/\\/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}(?=\\/|$)/gi, '/:id')\n .replace(/\\/\\d+(?=\\/|$)/g, '/:id')\n .replace(/\\/[\\w.-]+@[\\w.-]+\\.[\\w]+(?=\\/|$)/gi, '/:email')\n .replace(/\\/\\d{4}-\\d{2}-\\d{2}(?=\\/|$)/g, '/:date');\n\n return normalized;\n }\n\n /**\n * Save raw and processed data for inspection\n * Helps identify issues in data transformation pipeline\n */\n private saveDataForInspection(rawData: any[], processedData: NavigationData[]): void {\n try {\n const outputDir = '.bigquery-raw-data';\n const outputPath = join(process.cwd(), outputDir);\n\n // Create directory if it doesn't exist\n mkdirSync(outputPath, { recursive: true });\n\n // Raw data: exactly as it comes from BigQuery\n const rawFile = join(outputPath, 'raw-bigquery-response.json');\n writeFileSync(rawFile, JSON.stringify(rawData, null, 2));\n\n // Processed data: after normalization and filtering\n const processedFile = join(outputPath, 'processed-navigation-data.json');\n writeFileSync(processedFile, JSON.stringify(processedData, null, 2));\n\n // Summary statistics\n const summary = {\n timestamp: new Date().toISOString(),\n rawRowCount: rawData.length,\n processedRowCount: processedData.length,\n dataLoss: rawData.length - processedData.length,\n dataLossPercentage: ((rawData.length - processedData.length) / rawData.length * 100).toFixed(2) + '%',\n totalTransitions: processedData.reduce((sum, d) => sum + d.count, 0),\n uniqueFromRoutes: new Set(processedData.map(d => d.from)).size,\n uniqueToRoutes: new Set(processedData.map(d => d.to)).size,\n topTransitions: processedData.slice(0, 10)\n };\n\n const summaryFile = join(outputPath, 'data-transformation-summary.json');\n writeFileSync(summaryFile, JSON.stringify(summary, null, 2));\n\n if (this.debug) {\n console.log(`\\nπŸ“Š Data Inspection Summary:`);\n console.log(` Raw rows from BigQuery: ${summary.rawRowCount}`);\n console.log(` Processed rows (after filtering): ${summary.processedRowCount}`);\n console.log(` Data loss: ${summary.dataLoss} rows (${summary.dataLossPercentage})`);\n console.log(` Total transitions count: ${summary.totalTransitions}`);\n console.log(` Unique source routes: ${summary.uniqueFromRoutes}`);\n console.log(` Unique destination routes: ${summary.uniqueToRoutes}`);\n console.log(`\\n Files saved:`);\n console.log(` β€’ ${rawFile}`);\n console.log(` β€’ ${processedFile}`);\n console.log(` β€’ ${summaryFile}`);\n }\n } catch (error) {\n console.warn(`⚠️ Could not save inspection data:`, error instanceof Error ? error.message : error);\n }\n }\n\n /**\n * Fetch navigation data WITH segment information\n * Includes segment/role field so plugin can group by any role dynamically\n * @param config - Data range configuration\n * @returns Navigation data with segment field included\n */\n async fetchNavigationWithSegments(config: DataRangeConfig = {}): Promise<any[]> {\n const { days = 30 } = config;\n\n console.log(`πŸ“Š Fetching navigation data with segments from BigQuery...`);\n console.log(` Dataset: ${this.datasetId}`);\n console.log(` Date range: Last ${days} days`);\n\n try {\n // Query GA4 events for page transitions INCLUDING segment information\n // Extracts user_role (or user_segment) from event_params\n const query = `\n WITH page_sessions AS (\n SELECT\n user_id,\n (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1) as session_id,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) as page_path,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'user_role' LIMIT 1) as user_role,\n (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'user_segment' LIMIT 1) as user_segment,\n event_timestamp,\n ROW_NUMBER() OVER (\n PARTITION BY user_id, (SELECT value.int_value FROM UNNEST(event_params) WHERE KEY = 'ga_session_id' LIMIT 1)\n ORDER BY event_timestamp\n ) as page_sequence\n FROM \\`${this.projectId}.${this.datasetId}.events_*\\`\n WHERE\n event_name = 'page_view'\n AND _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL ${days} DAY))\n AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())\n AND (SELECT value.string_value FROM UNNEST(event_params) WHERE KEY = 'page_path' LIMIT 1) IS NOT NULL\n ),\n transitions AS (\n SELECT\n COALESCE(curr.page_path, '(direct)') as from_page,\n LEAD(curr.page_path) OVER (\n PARTITION BY curr.user_id, curr.session_id\n ORDER BY curr.page_sequence\n ) as to_page,\n COALESCE(curr.user_role, curr.user_segment, 'unknown') as segment\n FROM page_sessions curr\n WHERE curr.page_sequence > 0\n )\n SELECT\n from_page as previous_page_path,\n to_page as page_path,\n segment,\n COUNT(*) as transition_count\n FROM transitions\n WHERE to_page IS NOT NULL\n GROUP BY from_page, to_page, segment\n ORDER BY segment, transition_count DESC\n LIMIT 50000\n `;\n\n if (this.debug) {\n console.log(`πŸ“€ Query with segments:`);\n console.log(query);\n }\n\n const [rows] = await this.bigquery.query({\n query,\n location: this.location,\n });\n\n if (this.debug) {\n console.log(`βœ… Query executed successfully`);\n console.log(` Rows returned: ${rows.length}`);\n }\n\n const navigationData: any[] = [];\n\n rows.forEach((row: any) => {\n const previousPage = row.previous_page_path || '(direct)';\n const currentPage = row.page_path || '';\n const transitionCount = parseInt(row.transition_count || '0');\n const segment = row.segment || 'unknown';\n\n const normalizedPrevious = previousPage === '(direct)' || previousPage === '(not set)' ? '(direct)' : this.normalizeRoute(previousPage);\n const normalizedCurrent = this.normalizeRoute(currentPage);\n\n if (normalizedCurrent && transitionCount >= 1) {\n navigationData.push({\n from: normalizedPrevious,\n to: normalizedCurrent,\n count: transitionCount,\n segment: segment, // Include segment/role field\n });\n }\n });\n\n if (this.debug && navigationData.length > 0) {\n console.log(`βœ… Processed ${navigationData.length} transitions with segment data`);\n\n // Show detected segments\n const uniqueSegments = new Set(navigationData.map((d: any) => d.segment));\n console.log(`\\n Detected segments: ${Array.from(uniqueSegments).sort().join(', ')}`);\n\n // Show top transitions per segment\n const bySegment = new Map();\n navigationData.forEach((d: any) => {\n if (!bySegment.has(d.segment)) {\n bySegment.set(d.segment, []);\n }\n bySegment.get(d.segment).push(d);\n });\n\n bySegment.forEach((transitions: any[], segment: string) => {\n console.log(`\\n Top 3 transitions for ${segment}:`);\n transitions\n .sort((a, b) => b.count - a.count)\n .slice(0, 3)\n .forEach((nav: any, i: number) => {\n console.log(` ${i + 1}. ${nav.from} β†’ ${nav.to} (${nav.count} transitions)`);\n });\n });\n }\n\n return navigationData;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n console.warn(`⚠️ Failed to fetch navigation data with segments: ${errorMessage}`);\n return [];\n }\n }\n\n /**\n * Test connection to BigQuery\n * Note: May fail if service account lacks bigquery.jobs.create permission\n * but actual queries may still work. This is expected for viewer-only accounts.\n */\n async testConnection(): Promise<boolean> {\n try {\n const query = `SELECT 1 as test_value`;\n await this.bigquery.query({\n query,\n location: this.location,\n });\n\n if (this.debug) {\n console.log('βœ… BigQuery connection test successful');\n }\n\n return true;\n } catch (error) {\n // Don't treat test failure as fatal - viewer accounts may lack bigquery.jobs.create\n // but can still query via read-only APIs\n if (this.debug) {\n console.warn('⚠️ BigQuery connection test failed (may be expected for read-only accounts)');\n }\n return false;\n }\n }\n}\n","/**\n * Markov Chain Model Trainer\n * Builds a Markov chain from user navigation data\n * Probability: P(dest | src) = count(srcβ†’dest) / total_transitions_from_src\n */\n\nimport type {\n NavigationData,\n PrefetchModel,\n ModelConfig,\n PrefetchTarget,\n RouteMetadata,\n} from '../../types';\n\nexport class MarkovChainTrainer {\n private config: ModelConfig;\n private debug: boolean;\n\n constructor(config: ModelConfig, debug = false) {\n this.config = config;\n this.debug = debug;\n }\n\n /**\n * Train Markov chain model from navigation data\n * Calculates transition probabilities: P(dest | src) = transitions(srcβ†’dest) / total_from_src\n */\n trainMLModel(\n navigationData: NavigationData[],\n environment: string\n ): PrefetchModel {\n if (this.debug) {\n console.log(`\\nπŸ€– Training Markov Chain Model...`);\n console.log(` Model type: ${this.config.type}`);\n console.log(` Threshold: ${this.config.threshold * 100}%`);\n console.log(` Max prefetch per route: ${this.config.maxPrefetch}`);\n console.log(` Input transitions: ${navigationData.length}`);\n }\n\n // Build navigation graph: sourceRoute -> { targetRoute: count }\n const navigationGraph = this.buildNavigationGraph(navigationData);\n const routes = this.extractRoutes(navigationData);\n\n if (this.debug) {\n console.log(`\\n πŸ“Š Analysis:`);\n console.log(` Unique routes: ${routes.size}`);\n console.log(` Routes: ${Array.from(routes).sort().join(', ')}`);\n console.log(` Source routes: ${navigationGraph.size}`);\n }\n\n // Calculate Markov probabilities: P(dest | src) = count(srcβ†’dest) / total_from_src\n const predictions = this.calculateMarkovProbabilities(navigationGraph);\n\n if (this.debug) {\n console.log(`\\n Predictions generated:`);\n console.log(` Routes with predictions: ${predictions.size}`);\n const totalTargets = Array.from(predictions.values()).reduce(\n (sum, targets) => sum + targets.length,\n 0\n );\n console.log(` Total prefetch targets: ${totalTargets}`);\n }\n\n // Build PrefetchModel\n const model: PrefetchModel = {\n version: '1.0.0',\n generatedAt: new Date().toISOString(),\n environment,\n config: this.config,\n dataSource: {\n provider: 'markov-chain',\n dateRange: this.getDateRange(30),\n totalSessions: navigationData.reduce((sum, d) => sum + d.count, 0),\n totalRoutes: routes.size,\n },\n routes: {},\n };\n\n // Populate predictions\n predictions.forEach((targets, source) => {\n model.routes[source] = {\n prefetch: targets,\n metadata: this.calculateMetadata(navigationGraph, source),\n };\n });\n\n if (this.debug) {\n console.log(`\\n βœ… Model trained successfully`);\n const sampleRoutes = Array.from(predictions.entries()).slice(0, 3);\n if (sampleRoutes.length > 0) {\n console.log(`\\n Sample predictions:`);\n sampleRoutes.forEach(([source, targets]) => {\n console.log(` ${source}:`);\n targets.forEach((target) => {\n console.log(\n ` β†’ ${target.route} (${(target.probability * 100).toFixed(1)}%, ${target.priority})`\n );\n });\n });\n }\n }\n\n return model;\n }\n\n /**\n * Extract all unique routes from navigation data\n */\n private extractRoutes(data: NavigationData[]): Set<string> {\n const routes = new Set<string>();\n\n data.forEach((d) => {\n routes.add(d.from);\n routes.add(d.to);\n });\n\n return routes;\n }\n\n /**\n * Build navigation graph from user navigation patterns\n * Graph represents: sourceRoute -> { targetRoute: transitionCount }\n */\n private buildNavigationGraph(\n data: NavigationData[]\n ): Map<string, Map<string, number>> {\n const graph = new Map<string, Map<string, number>>();\n\n data.forEach(({ from, to, count }) => {\n if (!graph.has(from)) {\n graph.set(from, new Map());\n }\n\n const targets = graph.get(from)!;\n targets.set(to, (targets.get(to) || 0) + count);\n });\n\n return graph;\n }\n\n /**\n * Calculate Markov probabilities with normalization\n * P(dest | src) = count(srcβ†’dest) / total_transitions_from_src\n * Then normalizes scores to 0-1 range\n */\n private calculateMarkovProbabilities(\n navigationGraph: Map<string, Map<string, number>>\n ): Map<string, PrefetchTarget[]> {\n const predictions = new Map<string, PrefetchTarget[]>();\n\n navigationGraph.forEach((targets, source) => {\n const targetArray: PrefetchTarget[] = [];\n\n // Calculate total transitions from this source\n const totalFromSource = Array.from(targets.values()).reduce(\n (sum, count) => sum + count,\n 0\n );\n\n if (totalFromSource === 0) return;\n\n // Calculate base probability for each destination: P(dest | src) = count / total\n const probabilities = new Map<string, number>();\n targets.forEach((count, destination) => {\n probabilities.set(destination, count / totalFromSource);\n });\n\n // Normalize probabilities to 0-1 range\n const maxProb = Math.max(...Array.from(probabilities.values()));\n if (maxProb > 0) {\n probabilities.forEach((prob, dest) => {\n probabilities.set(dest, prob / maxProb);\n });\n }\n\n // Sort by probability (descending)\n const sorted = Array.from(probabilities.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, this.config.maxPrefetch);\n\n // Apply threshold and create targets\n sorted.forEach(([route, probability]) => {\n if (probability >= this.config.threshold) {\n targetArray.push({\n route,\n probability,\n count: targets.get(route) || 0,\n priority: this.getPriority(probability),\n });\n }\n });\n\n if (targetArray.length > 0) {\n predictions.set(source, targetArray);\n }\n });\n\n return predictions;\n }\n\n /**\n * Determine priority based on ML confidence score\n */\n private getPriority(score: number): 'high' | 'medium' | 'low' {\n if (score >= 0.7) return 'high';\n if (score >= 0.4) return 'medium';\n return 'low';\n }\n\n /**\n * Calculate metadata for a route\n */\n private calculateMetadata(\n navigationGraph: Map<string, Map<string, number>>,\n route: string\n ): RouteMetadata {\n const targets = navigationGraph.get(route);\n\n if (!targets || targets.size === 0) {\n return {\n totalTransitions: 0,\n topDestination: '',\n };\n }\n\n const totalTransitions = Array.from(targets.values()).reduce(\n (sum, count) => sum + count,\n 0\n );\n\n // Find top destination\n let topDestination = '';\n let maxCount = 0;\n targets.forEach((count, targetRoute) => {\n if (count > maxCount) {\n maxCount = count;\n topDestination = targetRoute;\n }\n });\n\n return {\n totalTransitions,\n topDestination,\n };\n }\n\n /**\n * Train segment-specific Markov models from navigation data with segment field\n * Creates separate models for each user segment/role\n */\n trainSegmentedModels(\n navigationDataWithSegments: any[],\n environment: string\n ): Map<string, PrefetchModel> {\n if (this.debug) {\n console.log(`\\nπŸ€– Training Segment-Specific Markov Models...`);\n }\n\n // Group data by segment\n const dataBySegment = new Map<string, NavigationData[]>();\n\n navigationDataWithSegments.forEach((data) => {\n const segment = data.segment || 'default';\n if (!dataBySegment.has(segment)) {\n dataBySegment.set(segment, []);\n }\n dataBySegment.get(segment)!.push({\n from: data.from,\n to: data.to,\n count: data.count,\n });\n });\n\n if (this.debug) {\n console.log(`\\n πŸ“Š Detected segments:`);\n dataBySegment.forEach((data, segment) => {\n console.log(` β€’ ${segment}: ${data.length} transitions`);\n });\n }\n\n // Train a model for each segment\n const segmentModels = new Map<string, PrefetchModel>();\n dataBySegment.forEach((navigationData, segment) => {\n if (this.debug) {\n console.log(`\\n πŸ”„ Training model for segment: \"${segment}\"`);\n }\n\n const model = this.trainMLModel(navigationData, environment);\n\n // Add segment info to model\n model.dataSource!.provider = `markov-chain[${segment}]`;\n\n segmentModels.set(segment, model);\n\n if (this.debug) {\n const totalTargets = Object.values(model.routes).reduce(\n (sum, route) => sum + (route.prefetch?.length || 0),\n 0\n );\n console.log(` βœ… Model for \"${segment}\" trained with ${totalTargets} prefetch targets`);\n }\n });\n\n if (this.debug) {\n console.log(`\\n βœ… All ${segmentModels.size} segment models trained successfully`);\n }\n\n return segmentModels;\n }\n\n /**\n * Get date range string\n */\n private getDateRange(days: number): string {\n const end = new Date();\n const start = new Date();\n start.setDate(start.getDate() - days);\n\n return `${start.toISOString().split('T')[0]} to ${end.toISOString().split('T')[0]}`;\n }\n}\n\n// Export with old name for backward compatibility\nexport { MarkovChainTrainer as GuessJSMLTrainer };\n","/**\n * Configuration Generator\n * Maps routes to Vite chunks and generates final prefetch configuration\n */\n\nimport type {\n PrefetchModel,\n PrefetchConfig,\n ViteManifest,\n ManualRules,\n PrefetchTarget,\n} from '../types';\n\nexport class ConfigGenerator {\n private manifest: ViteManifest;\n private manualRules: ManualRules;\n private debug: boolean;\n private vite: any = null;\n private isDev: boolean = false;\n\n /**\n * Maps routes to their component names based on vite.config.ts chunk strategy\n * This is derived from the route configuration in src/routes/index.ts\n * Note: These are the core routes from vite.config.ts chunking strategy\n * Routes not listed here will fall through to fuzzy matching\n */\n private static readonly ROUTE_TO_COMPONENT_NAME: Record<string, string> = {\n '/': 'Home',\n '/home': 'Home',\n '/dashboard': 'Dashboard',\n\n '/profile': 'Profile',\n '/settings': 'Settings',\n '/preferences': 'Preferences',\n '/privacy': 'Privacy',\n '/security': 'Security',\n\n '/analytics': 'Analytics',\n '/reports': 'Reports',\n '/metrics': 'Metrics',\n\n '/projects': 'Projects',\n '/tasks': 'Tasks',\n '/teams': 'Teams',\n '/workspaces': 'Workspaces',\n\n '/workflows': 'Workflows',\n '/templates': 'Templates',\n '/logs': 'Logs',\n '/audit-logs': 'AuditLogs',\n\n '/integrations': 'Integrations',\n '/api-docs': 'ApiDocs',\n '/api-documentation': 'ApiDocs', // Alias for space-separated variant\n '/support': 'Support',\n '/help': 'Help',\n\n '/billing': 'Billing',\n '/plans': 'Plans',\n '/usage': 'Usage',\n\n '/permissions': 'Permissions',\n '/notifications': 'Notifications',\n };\n\n /**\n * Maps component names to chunk names based on vite.config.ts manualChunks strategy\n * Each component is assigned to a specific chunk group for code splitting\n *\n * Note: Core components (Home, Dashboard) are not in manual chunks - they're part of main bundle\n * For these, we return the main bundle file path 'js/index-*.js' which will be resolved from manifest\n */\n private static readonly COMPONENT_TO_CHUNK_NAME: Record<string, string> = {\n // Core components - loaded with main bundle (not code-split)\n Home: 'index', // Special marker for main entry point\n Dashboard: 'index',\n\n // User Profile & Settings chunk\n Profile: 'chunk-user-profile',\n Settings: 'chunk-user-profile',\n Preferences: 'chunk-user-profile',\n Privacy: 'chunk-user-profile',\n Security: 'chunk-user-profile',\n\n // Analytics & Reporting chunk\n Analytics: 'chunk-analytics',\n Reports: 'chunk-analytics',\n Metrics: 'chunk-analytics',\n\n // Project Management chunk\n Projects: 'chunk-projects',\n Tasks: 'chunk-projects',\n Teams: 'chunk-projects',\n Workspaces: 'chunk-projects',\n\n // Workflows & Operations chunk\n Workflows: 'chunk-operations',\n Templates: 'chunk-operations',\n Logs: 'chunk-operations',\n AuditLogs: 'chunk-operations',\n\n // Integration chunk\n Integrations: 'chunk-integrations',\n ApiDocs: 'chunk-integrations',\n Support: 'chunk-integrations',\n Help: 'chunk-integrations',\n\n // Billing & Plans chunk\n Billing: 'chunk-billing',\n Plans: 'chunk-billing',\n Usage: 'chunk-billing',\n\n // Admin & Notifications chunk\n Permissions: 'chunk-admin',\n Notifications: 'chunk-admin',\n };\n\n constructor(manifest: ViteManifest, manualRules: ManualRules = {}, debug = false, vite?: any) {\n this.manifest = manifest;\n this.manualRules = manualRules;\n this.debug = debug;\n this.vite = vite || null;\n this.isDev = !!vite; // If vite is provided, we're in dev mode\n }\n\n /**\n * Generate final prefetch configuration with chunk mappings\n * Includes common prefetch rules and segment-specific rules if available\n */\n generate(model: PrefetchModel): PrefetchConfig {\n if (this.debug) {\n console.log(`\\nπŸ“¦ Generating prefetch configuration...`);\n console.log(` Manifest entries: ${Object.keys(this.manifest).length}`);\n console.log(` Model routes: ${Object.keys(model.routes).length}`);\n console.log(` Manual rules: ${Object.keys(this.manualRules).length}`);\n if (Object.values(model.routes).some(r => r.segments)) {\n console.log(` ℹ️ Segment-based rules detected`);\n }\n }\n\n // Merge manual rules into model\n const mergedModel = this.mergeManualRules(model);\n\n // Extract route patterns for dynamic route matching (TanStack Router support)\n const routePatterns = this.extractRoutePatterns(Object.keys(mergedModel.routes));\n\n // Map routes to chunks\n const config: PrefetchConfig = {\n version: model.version,\n generatedAt: model.generatedAt,\n environment: model.environment,\n dataSource: model.dataSource!,\n model: {\n type: model.config!.type,\n threshold: model.config!.threshold,\n maxPrefetch: model.config!.maxPrefetch,\n },\n routePatterns, // NEW: Include route patterns for dynamic matching\n routes: {},\n chunks: {},\n };\n\n let mappedRoutes = 0;\n let unmappedRoutes = 0;\n let totalSegmentRules = 0;\n\n // Process each route\n Object.entries(mergedModel.routes).forEach(([sourceRoute, prediction]) => {\n const prefetchTargets: Array<PrefetchTarget & { chunk: string }> = [];\n const segmentConfigs: Record<string, Array<PrefetchTarget & { chunk: string }>> = {};\n\n // Also map the source route's own chunk (so it can be used as a destination elsewhere)\n const sourceChunk = this.routeToChunk(sourceRoute);\n if (sourceChunk && !config.chunks[sourceRoute]) {\n config.chunks[sourceRoute] = sourceChunk;\n }\n\n // Process common prefetch rules\n prediction.prefetch.forEach((target) => {\n const chunkFile = this.routeToChunk(target.route);\n\n if (chunkFile) {\n // Get the manifest entry for this chunk to extract imports\n const manifestEntry = this.getManifestEntryByFile(chunkFile);\n const importChunkIds = manifestEntry?.imports || [];\n\n // Resolve import chunk IDs to actual file paths\n const imports = importChunkIds\n .map((chunkId) => {\n const entry = this.manifest[chunkId];\n return entry?.file;\n })\n .filter((file): file is string => !!file);\n\n prefetchTargets.push({\n ...target,\n chunk: chunkFile,\n chunk_prod: chunkFile, // NEW: Include production chunk path\n imports: imports, // Include dependency chunks (resolved to file paths)\n });\n\n // Add to chunks lookup\n config.chunks[target.route] = chunkFile;\n mappedRoutes++;\n\n // Enhanced debug logging\n if (this.debug) {\n console.log(` βœ… ${sourceRoute} β†’ ${target.route}`);\n console.log(` Chunk: ${chunkFile}`);\n if (imports.length > 0) {\n console.log(` Dependencies: ${imports.join(', ')}`);\n }\n }\n } else {\n if (this.debug) {\n console.log(` ⚠️ No chunk found for route: ${target.route}`);\n console.log(` Attempted to map using routeToChunk()`);\n }\n unmappedRoutes++;\n }\n });\n\n // Process segment-specific rules if available\n if (prediction.segments) {\n Object.entries(prediction.segments).forEach(([segment, segmentTargets]) => {\n const segmentPrefetchTargets: Array<PrefetchTarget & { chunk: string }> = [];\n\n segmentTargets.forEach((target) => {\n const chunkFile = this.routeToChunk(target.route);\n\n if (chunkFile) {\n const manifestEntry = this.getManifestEntryByFile(chunkFile);\n const importChunkIds = manifestEntry?.imports || [];\n\n const imports = importChunkIds\n .map((chunkId) => {\n const entry = this.manifest[chunkId];\n return entry?.file;\n })\n .filter((file): file is string => !!file);\n\n segmentPrefetchTargets.push({\n ...target,\n chunk: chunkFile,\n chunk_prod: chunkFile, // NEW: Include production chunk path\n imports: imports,\n });\n\n config.chunks[target.route] = chunkFile;\n totalSegmentRules++;\n }\n });\n\n if (segmentPrefetchTargets.length > 0) {\n segmentConfigs[segment] = segmentPrefetchTargets;\n }\n });\n\n if (this.debug && Object.keys(segmentConfigs).length > 0) {\n console.log(` πŸ‘₯ Segment configs for ${sourceRoute}: ${Object.keys(segmentConfigs).join(', ')}`);\n }\n }\n\n // Get patterns for this route for dynamic matching (TanStack Router support)\n const patterns = routePatterns[sourceRoute] || [sourceRoute];\n\n // Only include routes with valid chunk mappings\n if (prefetchTargets.length > 0 || Object.keys(segmentConfigs).length > 0) {\n config.routes[sourceRoute] = {\n patterns, // NEW: Include patterns for dynamic route matching\n prefetch: prefetchTargets,\n ...(Object.keys(segmentConfigs).length > 0 && {\n segments: segmentConfigs,\n }),\n metadata: prediction.metadata,\n };\n }\n });\n\n if (this.debug) {\n console.log(`βœ… Configuration generated`);\n console.log(` Routes with prefetch: ${Object.keys(config.routes).length}`);\n console.log(` Mapped chunks: ${mappedRoutes}`);\n console.log(` Segment-specific rules: ${totalSegmentRules}`);\n console.log(` Unmapped routes: ${unmappedRoutes}`);\n }\n\n // Add segment info if any routes have segments\n const allSegments = new Set<string>();\n Object.values(config.routes).forEach(route => {\n if (route.segments) {\n Object.keys(route.segments).forEach(seg => allSegments.add(seg));\n }\n });\n\n if (allSegments.size > 0) {\n config.segmentInfo = {\n available: Array.from(allSegments),\n description: 'Load segment-specific config based on user role/segment'\n };\n }\n\n return config;\n }\n\n /**\n * Merge manual rules into model\n * Manual rules take precedence over ML predictions\n */\n private mergeManualRules(model: PrefetchModel): PrefetchModel {\n const merged = { ...model, routes: { ...model.routes } };\n\n Object.entries(this.manualRules).forEach(([sourceRoute, targetRoutes]) => {\n if (!merged.routes[sourceRoute]) {\n merged.routes[sourceRoute] = {\n prefetch: [],\n };\n }\n\n // Add manual rules with high priority\n targetRoutes.forEach((targetRoute) => {\n // Check if this rule already exists\n const existing = merged.routes[sourceRoute].prefetch.find(\n (t) => t.route === targetRoute\n );\n\n if (existing) {\n // Update existing with manual flag and high priority\n existing.manual = true;\n existing.priority = 'high';\n existing.probability = 1.0;\n } else {\n // Add new manual rule\n merged.routes[sourceRoute].prefetch.unshift({\n route: targetRoute,\n probability: 1.0,\n count: 0, // Not from analytics\n priority: 'high',\n manual: true,\n });\n }\n });\n\n if (this.debug) {\n console.log(` βœ… Added manual rule: ${sourceRoute} β†’ [${targetRoutes.join(', ')}]`);\n }\n });\n\n return merged;\n }\n\n /**\n * NEW STRATEGY 0: Route to Chunk Name Mapping\n * Maps route β†’ component name β†’ chunk name β†’ manifest file\n * This is the most reliable method as it uses the actual vite.config.ts chunking strategy\n */\n private routeToChunkViaName(route: string): string | null {\n const normalizedRoute = route.toLowerCase();\n\n // Step 1: Get component name from route\n const componentName = ConfigGenerator.ROUTE_TO_COMPONENT_NAME[normalizedRoute];\n if (!componentName) {\n if (this.debug) {\n console.log(` ❌ Route ${route} not in ROUTE_TO_COMPONENT_NAME mapping`);\n }\n return null;\n }\n\n // Step 2: Get chunk name from component\n const chunkName = ConfigGenerator.COMPONENT_TO_CHUNK_NAME[componentName];\n if (!chunkName) {\n if (this.debug) {\n console.log(` ❌ Component ${componentName} not in COMPONENT_TO_CHUNK_NAME mapping`);\n }\n return null;\n }\n\n // Step 3: Find chunk file in manifest by name property\n const chunkEntry = Object.entries(this.manifest).find(\n ([key, entry]) =>\n (entry as any).name === chunkName || key.includes(chunkName)\n );\n\n if (!chunkEntry) {\n if (this.debug) {\n console.log(` ❌ Chunk name ${chunkName} not found in manifest`);\n }\n return null;\n }\n\n const chunkFile = (chunkEntry[1] as any).file;\n if (this.debug) {\n console.log(\n ` βœ… Via-Name Strategy: ${route} β†’ ${componentName} β†’ ${chunkName} β†’ ${chunkFile}`\n );\n }\n\n return chunkFile;\n }\n\n /**\n * Map route to chunk file using Vite manifest\n * Tries multiple strategies to find the correct chunk\n */\n private routeToChunk(route: string): string | null {\n // Strategy 0: Route β†’ Component β†’ Chunk Name mapping (NEW - MOST RELIABLE)\n const viaName = this.routeToChunkViaName(route);\n if (viaName) {\n return viaName;\n }\n\n // Strategy 1: Direct match (e.g., src/pages/orders/index.tsx)\n const directMatch = this.findDirectMatch(route);\n if (directMatch) {\n return directMatch;\n }\n\n // Strategy 2: Pattern match (e.g., orders β†’ src/pages/orders/*)\n const patternMatch = this.findPatternMatch(route);\n if (patternMatch) {\n return patternMatch;\n }\n\n // Strategy 3: Fuzzy match (e.g., /dispatch-order β†’ dispatchOrder)\n const fuzzyMatch = this.findFuzzyMatch(route);\n if (fuzzyMatch) {\n return fuzzyMatch;\n }\n\n return null;\n }\n\n /**\n * Strategy 1: Direct path match\n */\n private findDirectMatch(route: string): string | null {\n // Remove :id or $id parameters (React Router and TanStack Router) but keep the route structure\n const normalizedRoute = route.replace(/\\/[:$]\\w+/g, '');\n const cleanRoutePath = normalizedRoute.replace(/^\\//, ''); // Remove leading slash\n\n // Convert hyphenated routes to PascalCase for component name matching\n // e.g., /audit-logs β†’ AuditLogs, /api-docs β†’ ApiDocs, /dashboard β†’ Dashboard\n const routeSegments = normalizedRoute.split('/').filter(Boolean);\n const pascalCaseComponent = routeSegments\n .map(segment => {\n // Convert each segment: api-docs β†’ ApiDocs, dashboard β†’ Dashboard\n const words = segment.split('-');\n return words\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n })\n .join('/');\n\n // For single-segment routes like /dashboard, create both versions\n let singleSegmentPascal = null;\n if (routeSegments.length === 1) {\n const segment = routeSegments[0];\n const words = segment.split('-');\n singleSegmentPascal = words\n .map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())\n .join('');\n }\n\n // Try common patterns using normalized route (without :id or $id)\n // PRIORITIZE: Direct file names for pages first (e.g., Dashboard.tsx)\n const patterns = [\n // HIGHEST PRIORITY: Exact page component name matches\n singleSegmentPascal ? `src/pages/${singleSegmentPascal}.tsx` : null,\n singleSegmentPascal ? `src/pages/${singleSegmentPascal}.ts` : null,\n singleSegmentPascal ? `src/pages/${singleSegmentPascal}.jsx` : null,\n singleSegmentPascal ? `src/pages/${singleSegmentPascal}.js` : null,\n // For multi-segment routes with hyphens\n `src/pages/${pascalCaseComponent}.tsx`,\n `src/pages/${pascalCaseComponent}.ts`,\n `src/pages/${pascalCaseComponent}.jsx`,\n `src/pages/${pascalCaseComponent}.js`,\n // Features folder\n `src/features${normalizedRoute}/index.ts`,\n `src/features${normalizedRoute}/index.tsx`,\n `src/features${normalizedRoute}/index.js`,\n `src/features${normalizedRoute}/index.jsx`,\n // Pages folder - try both directory and file formats\n `src/pages${normalizedRoute}/index.tsx`,\n `src/pages${normalizedRoute}/index.ts`,\n `src/pages${normalizedRoute}/index.jsx`,\n `src/pages${normalizedRoute}/index.js`,\n `src/pages${normalizedRoute}.tsx`,\n `src/pages${normalizedRoute}.ts`,\n `src/pages${normalizedRoute}.jsx`,\n `src/pages${normalizedRoute}.js`,\n // Fallback to old capitalize method (single capital letter)\n `src/pages/${this.capitalize(cleanRoutePath)}.tsx`,\n `src/pages/${this.capitalize(cleanRoutePath)}.ts`,\n // Full paths with app prefix\n `apps/farmart-pro/src/features${normalizedRoute}/index.ts`,\n `apps/farmart-pro/src/features${normalizedRoute}/index.tsx`,\n `apps/farmart-pro/src/pages${normalizedRoute}/index.tsx`,\n ].filter(Boolean); // Remove null entries\n\n for (let i = 0; i < patterns.length; i++) {\n const pattern = patterns[i];\n if (!pattern) continue; // Skip null patterns\n const entry = this.manifest[pattern];\n if (entry) {\n return entry.file;\n }\n }\n\n return null;\n }\n\n /**\n * Capitalize first letter of string\n */\n private capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n /**\n * Strategy 2: Pattern matching with wildcards\n */\n private findPatternMatch(route: string): string | null {\n const routeSegments = route.split('/').filter(Boolean);\n if (routeSegments.length === 0) return null;\n\n // Find manifest entries that match route pattern\n const candidates = Object.entries(this.manifest)\n .filter(([path]) => {\n const pathSegments = path.split('/').filter(Boolean);\n\n // Check if path contains route segments (support both :id and $id)\n return routeSegments.every((segment) =>\n pathSegments.some((ps) =>\n ps.toLowerCase().includes(segment.replace(/[:$]\\w+/, '').toLowerCase())\n )\n );\n })\n .sort(([pathA], [pathB]) => {\n // Prioritize pages folder\n if (pathA.includes('/pages/') && !pathB.includes('/pages/')) return -1;\n if (!pathA.includes('/pages/') && pathB.includes('/pages/')) return 1;\n\n // Prioritize entry points\n const aIsEntry = pathA.includes('index.tsx') || pathA.includes('index.ts');\n const bIsEntry = pathB.includes('index.tsx') || pathB.includes('index.ts');\n if (aIsEntry && !bIsEntry) return -1;\n if (!aIsEntry && bIsEntry) return 1;\n\n // Prioritize tsx over other extensions\n if (pathA.includes('.tsx') && !pathB.includes('.tsx')) return -1;\n if (!pathA.includes('.tsx') && pathB.includes('.tsx')) return 1;\n\n return 0;\n });\n\n if (candidates.length > 0) {\n if (this.debug) {\n console.log(` βœ… Pattern match found: ${candidates[0][0]} β†’ ${candidates[0][1].file}`);\n }\n return candidates[0][1].file;\n }\n\n if (this.debug) {\n console.log(` No pattern match found`);\n }\n\n return null;\n }\n\n /**\n * Strategy 3: Fuzzy matching\n * Converts route to camelCase/PascalCase and searches\n */\n private findFuzzyMatch(route: string): string | null {\n // Remove parameters first\n const cleanRoute = route.replace(/\\/[:$]\\w+/g, '');\n\n // Convert /api-docs to ApiDocs (PascalCase for file names)\n const routeSegments = cleanRoute.split('/').filter(Boolean);\n const pascalCase = routeSegments\n .map((segment) => {\n const words = segment.split('-');\n return words\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n })\n .join('');\n\n // Also try camelCase (for method names)\n const camelCase = pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);\n\n if (this.debug) {\n console.log(` Fuzzy match - Route: ${route}`);\n console.log(` Trying PascalCase: ${pascalCase}, camelCase: ${camelCase}`);\n }\n\n // Search manifest for matching files - prioritize exact name matches\n // CRITICAL: Only match source files (pages/features), NOT dependency chunks\n const candidates = Object.entries(this.manifest)\n .filter(([path, entry]) => {\n // Skip dependency chunks (start with underscore or just contain 'chunk-' in the file name)\n if (path.startsWith('_') || path.startsWith('node_modules')) {\n return false;\n }\n\n const fileName = path.split('/').pop() || '';\n const fileNameWithoutExt = fileName.replace(/\\.[^.]+$/, '');\n\n // Exact match is best (exact file name)\n if (fileNameWithoutExt === pascalCase || fileNameWithoutExt === camelCase) {\n return true;\n }\n\n // Partial match (file name includes our component name)\n if (fileName.includes(pascalCase) || fileName.includes(camelCase)) {\n return true;\n }\n\n // Segment match (any path segment contains our component name)\n const pathSegments = path.toLowerCase().split('/');\n const lowerPascal = pascalCase.toLowerCase();\n const lowerCamel = camelCase.toLowerCase();\n\n return pathSegments.some(seg =>\n seg.includes(lowerPascal) || seg.includes(lowerCamel)\n );\n })\n .sort(([pathA, entryA], [pathB, entryB]) => {\n // Prioritize source files over chunk manifests\n const aHasSrc = (entryA as any).src ? 1 : 0;\n const bHasSrc = (entryB as any).src ? 1 : 0;\n if (aHasSrc !== bHasSrc) return bHasSrc - aHasSrc;\n\n // Prefer matches that have the exact file name\n const fileA = pathA.split('/').pop()?.replace(/\\.[^.]+$/, '') || '';\n const fileB = pathB.split('/').pop()?.replace(/\\.[^.]+$/, '') || '';\n\n // Exact match gets priority\n if (fileA === pascalCase) return -1;\n if (fileB === pascalCase) return 1;\n if (fileA === camelCase) return -1;\n if (fileB === camelCase) return 1;\n\n // Prefer files in pages folder\n if (pathA.includes('/pages/') && !pathB.includes('/pages/')) return -1;\n if (!pathA.includes('/pages/') && pathB.includes('/pages/')) return 1;\n\n return 0;\n });\n\n if (candidates.length > 0) {\n const result = candidates[0][1].file;\n if (this.debug) {\n console.log(` βœ… Fuzzy match found: ${candidates[0][0]} β†’ ${result}`);\n }\n return result;\n }\n\n if (this.debug) {\n console.log(` No fuzzy match found`);\n }\n\n return null;\n }\n\n /**\n * Get manifest entry by file name\n */\n private getManifestEntryByFile(fileName: string) {\n return Object.values(this.manifest).find((entry) => entry.file === fileName);\n }\n\n /**\n * Get all chunks referenced in config\n */\n getReferencedChunks(config: PrefetchConfig): string[] {\n return Object.values(config.chunks);\n }\n\n /**\n * Validate that all chunks exist in manifest\n */\n validateChunks(config: PrefetchConfig): {\n valid: boolean;\n missing: string[];\n } {\n const missing: string[] = [];\n const manifestFiles = new Set(Object.values(this.manifest).map((e) => e.file));\n\n Object.entries(config.chunks).forEach(([route, chunk]) => {\n if (!manifestFiles.has(chunk)) {\n missing.push(`${route} -> ${chunk}`);\n }\n });\n\n return {\n valid: missing.length === 0,\n missing,\n };\n }\n\n /**\n * Extract route patterns for dynamic route matching\n * Groups routes by their base path and includes pattern variants\n * E.g., /purchase-order and /purchase-order/:id become patterns for matching\n */\n private extractRoutePatterns(routes: string[]): Record<string, string[]> {\n const patterns: Record<string, string[]> = {};\n\n for (const route of routes) {\n // Check if route contains dynamic parameters (:param or $param for TanStack)\n if (route.includes(':') || route.includes('$')) {\n // This is a dynamic route pattern - keep as-is\n patterns[route] = [route];\n\n // Also add the base route if it exists and is different\n const base = route.split(/[:$]/)[0];\n if (base && base !== route) {\n // Ensure base route also gets patterns\n if (!patterns[base]) {\n patterns[base] = [base, route];\n } else if (!patterns[base].includes(route)) {\n patterns[base].push(route);\n }\n }\n } else {\n // Static route - just use itself\n patterns[route] = [route];\n }\n }\n\n if (this.debug && Object.keys(patterns).length > 0) {\n console.log(`\\nπŸ” Extracted route patterns for dynamic matching:`);\n Object.entries(patterns).forEach(([route, patternList]) => {\n if (patternList.length > 1) {\n console.log(` ${route} β†’ [${patternList.join(', ')}]`);\n }\n });\n }\n\n return patterns;\n }\n\n /**\n * Match a pathname against route patterns\n * Supports both static routes and dynamic routes with parameters\n */\n private matchRoutePattern(pathname: string, pattern: string): boolean {\n // Convert route pattern to regex\n // E.g., /purchase-order/:id β†’ /purchase-order/[^/]+\n const patternRegex = new RegExp(\n '^' + pattern\n .replace(/:[^/]+/g, '[^/]+') // Match :param style\n .replace(/\\$[^/]+/g, '[^/]+') // Match $param style (TanStack Router)\n .replace(/\\*/g, '.*') + // Match wildcard\n '$'\n );\n return patternRegex.test(pathname);\n }\n\n /**\n * Find matching route pattern for a given pathname\n * Used by hooks to match actual navigation paths to config routes\n */\n findMatchingPattern(\n pathname: string,\n routes: Record<string, any>\n ): string | null {\n for (const [route, config] of Object.entries(routes)) {\n const patterns = (config as any).patterns || [route];\n for (const pattern of patterns) {\n if (this.matchRoutePattern(pathname, pattern)) {\n return route;\n }\n }\n }\n return null;\n }\n\n /**\n * Generate segment-specific prefetch configurations\n * Creates one config per user segment/role\n */\n generateSegmentConfigs(\n segmentModels: Map<string, PrefetchModel>\n ): Map<string, PrefetchConfig> {\n const segmentConfigs = new Map<string, PrefetchConfig>();\n\n segmentModels.forEach((model, segment) => {\n if (this.debug) {\n console.log(`\\nπŸ“¦ Generating config for segment: \"${segment}\"`);\n }\n\n const config = this.generate(model);\n\n // Add segment metadata to config\n (config as any).segment = segment;\n\n segmentConfigs.set(segment, config);\n\n if (this.debug) {\n console.log(` βœ… Config generated for \"${segment}\"`);\n console.log(` Routes: ${Object.keys(config.routes).length}`);\n console.log(` Chunks: ${Object.keys(config.chunks).length}`);\n }\n });\n\n if (this.debug) {\n console.log(`\\nβœ… Generated ${segmentConfigs.size} segment-specific configurations`);\n }\n\n return segmentConfigs;\n }\n}\n","/**\n * Cache Manager\n * Manages caching of trained models to avoid redundant GA API calls\n * Uses Node.js fs to cache models locally during build time\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { PrefetchModel, CacheConfig } from '../types';\n\nexport class CacheManager {\n private cacheDir: string;\n private ttl: number;\n private enabled: boolean;\n private debug: boolean;\n\n constructor(config: CacheConfig = {}, debug = false) {\n this.enabled = config.enabled ?? true; // Enabled by default\n this.ttl = config.ttl ?? 24 * 60 * 60 * 1000; // Default: 24 hours\n this.cacheDir = config.path ?? path.join(process.cwd(), '.prefetch-cache');\n this.debug = debug;\n\n if (this.enabled && !fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n if (this.debug) {\n console.log(`πŸ“ Created cache directory: ${this.cacheDir}`);\n }\n }\n }\n\n /**\n * Get cached model for environment\n * Returns null if cache doesn't exist or is expired\n */\n async get(environment: string): Promise<PrefetchModel | null> {\n if (!this.enabled) {\n if (this.debug) console.log('⏭️ Cache disabled, skipping cache lookup');\n return null;\n }\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n if (this.debug) console.log(`πŸ“¦ Cache miss for environment: ${environment}`);\n return null;\n }\n\n const stats = fs.statSync(cacheFile);\n const cacheAge = Date.now() - stats.mtimeMs;\n\n if (cacheAge > this.ttl) {\n if (this.debug) console.log(`⏰ Cache expired for ${environment} (${Math.round(cacheAge / 1000 / 60)} minutes old)`);\n fs.unlinkSync(cacheFile);\n return null;\n }\n\n const cachedData = fs.readFileSync(cacheFile, 'utf-8');\n const model: PrefetchModel = JSON.parse(cachedData);\n\n if (this.debug) {\n console.log(`βœ… Cache hit for environment: ${environment} (${Math.round(cacheAge / 1000)} seconds old)`);\n console.log(` Cached model has ${Object.keys(model.routes).length} routes`);\n }\n\n return model;\n } catch (error) {\n console.error(`❌ Error reading cache for ${environment}:`, error);\n return null;\n }\n }\n\n /**\n * Save model to cache\n */\n async set(environment: string, model: PrefetchModel): Promise<void> {\n if (!this.enabled) {\n if (this.debug) console.log('⏭️ Cache disabled, skipping cache write');\n return;\n }\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n fs.writeFileSync(cacheFile, JSON.stringify(model, null, 2), 'utf-8');\n\n if (this.debug) {\n console.log(`πŸ’Ύ Cached model for ${environment}`);\n console.log(` Location: ${cacheFile}`);\n console.log(` Routes: ${Object.keys(model.routes).length}`);\n }\n } catch (error) {\n console.error(`❌ Error writing cache for ${environment}:`, error);\n }\n }\n\n /**\n * Invalidate cache for specific environment or all environments\n */\n async invalidate(environment?: string): Promise<void> {\n if (!this.enabled) return;\n\n try {\n if (environment) {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n if (fs.existsSync(cacheFile)) {\n fs.unlinkSync(cacheFile);\n if (this.debug) {\n console.log(`πŸ—‘οΈ Invalidated cache for ${environment}`);\n }\n }\n } else {\n // Clear all cache files\n const files = fs.readdirSync(this.cacheDir);\n files.forEach((file) => {\n if (file.endsWith('.json')) {\n fs.unlinkSync(path.join(this.cacheDir, file));\n }\n });\n if (this.debug) {\n console.log(`πŸ—‘οΈ Cleared all cache files`);\n }\n }\n } catch (error) {\n console.error(`❌ Error invalidating cache:`, error);\n }\n }\n\n /**\n * Get cache statistics\n */\n getStats(): {\n enabled: boolean;\n cacheDir: string;\n ttl: number;\n cachedEnvironments: string[];\n totalSize: number;\n } {\n const cachedEnvironments: string[] = [];\n let totalSize = 0;\n\n if (this.enabled && fs.existsSync(this.cacheDir)) {\n const files = fs.readdirSync(this.cacheDir);\n files.forEach((file) => {\n if (file.endsWith('.json')) {\n const filePath = path.join(this.cacheDir, file);\n const stats = fs.statSync(filePath);\n cachedEnvironments.push(file.replace('.json', ''));\n totalSize += stats.size;\n }\n });\n }\n\n return {\n enabled: this.enabled,\n cacheDir: this.cacheDir,\n ttl: this.ttl,\n cachedEnvironments,\n totalSize,\n };\n }\n\n /**\n * Check if cache exists and is valid for environment\n */\n async isValid(environment: string): Promise<boolean> {\n if (!this.enabled) return false;\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n return false;\n }\n\n const stats = fs.statSync(cacheFile);\n const cacheAge = Date.now() - stats.mtimeMs;\n\n return cacheAge <= this.ttl;\n } catch {\n return false;\n }\n }\n\n /**\n * Get cache age in milliseconds\n */\n async getCacheAge(environment: string): Promise<number | null> {\n if (!this.enabled) return null;\n\n try {\n const cacheFile = path.join(this.cacheDir, `${environment}.json`);\n\n if (!fs.existsSync(cacheFile)) {\n return null;\n }\n\n const stats = fs.statSync(cacheFile);\n return Date.now() - stats.mtimeMs;\n } catch {\n return null;\n }\n }\n}\n","/**\n * Main Vite Plugin\n * Integrates all components and provides Vite hooks\n */\n\nimport type { Plugin, ResolvedConfig } from 'vite';\nimport { BigQueryAnalyticsConnector } from './analytics/bigquery-connector';\nimport { GuessJSMLTrainer } from './model/guessjs-ml-trainer';\nimport { ConfigGenerator } from './config-generator';\nimport { CacheManager } from './cache-manager';\nimport type {\n PluginOptions,\n PrefetchModel,\n ViteManifest,\n} from '../types';\n\nexport function smartPrefetch(options: PluginOptions = {}): Plugin {\n const {\n framework = 'react',\n strategy = 'hybrid',\n analytics,\n manualRules = {},\n cache = {},\n advanced = {},\n } = options;\n\n const debug = advanced.debug ?? false;\n\n let config: ResolvedConfig;\n let cacheManager: CacheManager;\n let prefetchModel: PrefetchModel | null = null;\n let segmentModels: Map<string, PrefetchModel> | null = null;\n\n return {\n name: '@farmart/vite-plugin-smart-prefetch',\n enforce: 'post',\n\n async configResolved(resolvedConfig) {\n config = resolvedConfig;\n\n // Ensure Vite manifest is enabled\n if (!config.build.manifest) {\n config.build.manifest = true;\n if (debug) {\n console.log('βœ… Enabled Vite manifest generation');\n }\n }\n\n // Initialize cache manager\n cacheManager = new CacheManager(cache, debug);\n\n if (debug) {\n console.log('\\nπŸš€ Smart Prefetch Plugin Initialized');\n console.log(` Framework: ${framework}`);\n console.log(` Strategy: ${strategy}`);\n console.log(` Analytics: ${analytics ? 'enabled' : 'disabled'}`);\n console.log(` Manual rules: ${Object.keys(manualRules).length}`);\n console.log(` Cache: ${cache.enabled !== false ? 'enabled' : 'disabled'}`);\n }\n\n // In development mode, generate prefetch config for testing\n if (config.command === 'serve' && debug) {\n // Create a simple dev-time manifest for testing\n const devManifest: ViteManifest = {};\n\n // Create entries for all manual rules\n Object.keys(manualRules).forEach((route) => {\n const routeKey = `src/features${route}/index.tsx`;\n devManifest[routeKey] = {\n file: `features${route.replace(/\\//g, '-')}.js`,\n imports: [],\n };\n });\n\n // Also try to discover routes from src/pages directory\n const fs = await import('node:fs');\n const path = await import('node:path');\n const pagesDir = path.join(config.root, 'src/pages');\n\n if (fs.existsSync(pagesDir)) {\n const files = fs.readdirSync(pagesDir);\n files.forEach((file) => {\n if (file.endsWith('.tsx') || file.endsWith('.ts')) {\n const pageName = file.replace(/\\.(tsx|ts)$/, '');\n const routeKey = `src/pages/${file}`;\n devManifest[routeKey] = {\n file: `chunks/${pageName}-[hash].js`,\n imports: [],\n };\n }\n });\n }\n\n // Store for use in transformIndexHtml\n (config as any).__smartPrefetchDevManifest = devManifest;\n }\n },\n\n configureServer(server) {\n // In development mode, serve the prefetch-config.json dynamically\n // This ensures we always use the latest model instead of stale [hash] placeholders\n return () => {\n server.middlewares.use('/prefetch-config.json', async (req, res, next) => {\n if (req.method !== 'GET') {\n next();\n return;\n }\n\n try {\n // In dev mode, always generate a fresh config with current model\n if (!prefetchModel) {\n if (debug) {\n console.warn('⚠️ No prefetch model available yet');\n }\n res.statusCode = 503;\n res.end(JSON.stringify({ error: 'Prefetch model not ready, still loading analytics data...' }));\n return;\n }\n\n // Generate config dynamically on each request (dev only)\n // Create a minimal manifest for dev mode - just file paths without real hashes\n const devManifest: ViteManifest = {};\n\n // Map model routes to dev manifest entries\n Object.keys(prefetchModel.routes).forEach((route) => {\n // Create a fake but consistent manifest entry for dev\n const routeKey = `src/pages${route}/index.tsx`;\n const routeName = route.split('/').filter(Boolean).pop() || 'index';\n const devHash = 'dev-' + routeName.slice(0, 6).padEnd(8, '0');\n devManifest[routeKey] = {\n file: `chunks/${routeName}-${devHash}.js`,\n imports: [],\n };\n });\n\n // Generate final config with dev manifest and Vite server instance for chunk discovery\n const generator = new ConfigGenerator(devManifest as ViteManifest, manualRules, debug, server);\n const finalConfig = generator.generate(prefetchModel);\n\n res.setHeader('Content-Type', 'application/json');\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); // Never cache in dev\n res.end(JSON.stringify(finalConfig, null, 2));\n\n if (debug) {\n console.log('πŸ“€ Serving fresh prefetch-config.json from development server');\n }\n return;\n } catch (error) {\n if (debug) {\n console.error('Error serving prefetch-config.json:', error);\n }\n res.statusCode = 500;\n res.end(JSON.stringify({ error: 'Internal server error', details: String(error) }));\n }\n });\n };\n },\n\n async buildStart() {\n if (!analytics) {\n if (debug) {\n console.log('\\n⏭️ Analytics disabled, using manual rules only');\n }\n // Create model from manual rules only\n prefetchModel = createManualModel(manualRules, config.command === 'serve' ? 'development' : 'production');\n return;\n }\n\n const environment = analytics.environment || (config.command === 'serve' ? 'development' : 'production');\n\n // Check cache first\n const cached = await cacheManager.get(environment);\n if (cached) {\n prefetchModel = cached;\n return;\n }\n\n // Fetch and train model\n try {\n if (debug) {\n console.log(`\\nπŸ“Š Fetching ${analytics.provider} data and training model...`);\n }\n\n // Initialize BigQuery Analytics connector\n const bqConnector = new BigQueryAnalyticsConnector(\n (analytics.credentials as any).projectId,\n (analytics.credentials as any).datasetId,\n (analytics.credentials as any).region || 'asia-south1',\n debug\n );\n\n console.log('\\n🎯 Using real navigation data from BigQuery GA4 export...');\n\n // Fetch navigation data\n const navigationData = await bqConnector.fetchNavigationSequences(analytics.dataRange);\n\n if (navigationData.length === 0) {\n console.warn('⚠️ No navigation data found, using manual rules only');\n prefetchModel = createManualModel(manualRules, environment);\n return;\n }\n\n // Train model using Markov chain ML with Bayesian probability\n // Uses real navigation data to predict likely route transitions\n console.log(`\\nπŸ€– Training model using Markov Chain ML...`);\n const mlTrainer = new GuessJSMLTrainer(analytics.model, debug);\n const prefetchModelResult = mlTrainer.trainMLModel(navigationData, environment);\n prefetchModel = prefetchModelResult;\n\n // Cache model\n await cacheManager.set(environment, prefetchModel);\n\n // Try to train segment-specific models if segment data is available\n try {\n const navigationWithSegments = await bqConnector.fetchNavigationWithSegments(analytics.dataRange);\n\n if (navigationWithSegments.length > 0) {\n console.log(`\\nπŸ‘₯ Training segment-specific models...`);\n segmentModels = mlTrainer.trainSegmentedModels(navigationWithSegments, environment);\n\n if (debug && segmentModels.size > 0) {\n console.log(` βœ… Trained ${segmentModels.size} segment-specific models`);\n }\n }\n } catch (error) {\n if (debug) {\n console.warn(`⚠️ Could not train segment models:`, error instanceof Error ? error.message : 'Unknown error');\n }\n // Segment training is optional, don't fail the build\n }\n } catch (error) {\n console.error('❌ Failed to fetch analytics data:', error);\n console.log('⚠️ Falling back to manual rules only');\n\n // Fallback to manual rules\n prefetchModel = createManualModel(manualRules, environment);\n \n // Don't fail the build, just warn\n if (debug) {\n console.error('Error details:', error);\n }\n }\n },\n\n async writeBundle(outputOptions) {\n if (!prefetchModel) {\n console.warn('⚠️ No prefetch model available, skipping config generation');\n return;\n }\n\n // Read manifest from disk instead of bundle\n const fs = await import('node:fs');\n const path = await import('node:path');\n\n const outDir = outputOptions.dir || 'dist';\n const manifestPath = path.join(outDir, '.vite', 'manifest.json');\n\n if (!fs.existsSync(manifestPath)) {\n console.warn('⚠️ Vite manifest not found at:', manifestPath);\n return;\n }\n\n const manifestContent = fs.readFileSync(manifestPath, 'utf-8');\n const manifest: ViteManifest = JSON.parse(manifestContent);\n\n if (debug) {\n console.log(`\\nπŸ“¦ Vite manifest loaded: ${Object.keys(manifest).length} entries`);\n }\n\n // Generate final config with chunk mappings\n const generator = new ConfigGenerator(manifest, manualRules, debug);\n const finalConfig = generator.generate(prefetchModel);\n\n // Validate chunks\n const validation = generator.validateChunks(finalConfig);\n if (!validation.valid) {\n console.warn('⚠️ Some chunks could not be mapped:');\n validation.missing.forEach((m) => console.warn(` ${m}`));\n } else {\n console.log(`βœ… All ${Object.keys(finalConfig.chunks).length} chunks successfully mapped with real build hashes`);\n }\n\n // Write prefetch-config.json to disk\n const configPath = path.join(outDir, 'prefetch-config.json');\n fs.writeFileSync(configPath, JSON.stringify(finalConfig, null, 2));\n\n // Save model routes for testing purposes\n const modelRoutesPath = path.join(outDir, 'model-routes.json');\n fs.writeFileSync(modelRoutesPath, JSON.stringify(prefetchModel.routes, null, 2));\n\n if (debug) {\n console.log('βœ… Emitted prefetch-config.json with real chunk hashes');\n console.log('βœ… Emitted model-routes.json');\n console.log(`πŸ“Š Total routes configured: ${Object.keys(finalConfig.routes).length}`);\n console.log(`πŸ“¦ Total chunks: ${Object.keys(finalConfig.chunks).length}`);\n }\n\n // Generate and write segment-specific configs\n if (segmentModels && segmentModels.size > 0) {\n console.log(`\\nπŸ“ Generating segment-specific prefetch configurations...`);\n\n const segmentGenerator = new ConfigGenerator(manifest, manualRules, debug);\n const segmentConfigs = segmentGenerator.generateSegmentConfigs(segmentModels);\n\n // Create segment configs directory\n const segmentDir = path.join(outDir, 'prefetch-configs');\n if (!fs.existsSync(segmentDir)) {\n fs.mkdirSync(segmentDir, { recursive: true });\n }\n\n // Write each segment config\n segmentConfigs.forEach((segConfig, segment) => {\n const segmentPath = path.join(segmentDir, `${segment}.json`);\n fs.writeFileSync(segmentPath, JSON.stringify(segConfig, null, 2));\n\n if (debug) {\n console.log(` βœ… Emitted ${segment}.json (${Object.keys(segConfig.routes).length} routes)`);\n }\n });\n\n // Write segment index/manifest\n const segmentIndex = {\n generatedAt: new Date().toISOString(),\n environment: analytics?.environment || (config.command === 'serve' ? 'development' : 'production'),\n segments: Array.from(segmentConfigs.keys()),\n description: 'Segment-specific prefetch configurations. Use based on user role/segment.'\n };\n\n const segmentIndexPath = path.join(segmentDir, 'index.json');\n fs.writeFileSync(segmentIndexPath, JSON.stringify(segmentIndex, null, 2));\n\n if (debug) {\n console.log(`\\nβœ… Emitted ${segmentConfigs.size} segment-specific configurations`);\n console.log(` Location: ${segmentDir}`);\n console.log(` Segments: ${Array.from(segmentConfigs.keys()).join(', ')}`);\n }\n }\n\n // Generate analytics dashboard if requested\n if (analytics?.dashboard) {\n const dashboardHtml = generateDashboard(finalConfig);\n const dashboardPath = path.join(outDir, 'prefetch-report.html');\n fs.writeFileSync(dashboardPath, dashboardHtml);\n\n if (debug) {\n console.log('βœ… Emitted prefetch-report.html');\n }\n }\n },\n\n transformIndexHtml() {\n // Inject runtime configuration into HTML\n return [\n {\n tag: 'script',\n attrs: { type: 'module' },\n children: `\n // Smart Prefetch Plugin Runtime Config\n window.__SMART_PREFETCH__ = {\n strategy: '${strategy}',\n framework: '${framework}',\n debug: ${debug},\n };\n `,\n injectTo: 'head',\n },\n ];\n },\n };\n}\n\n/**\n * Create a model from manual rules only (no analytics)\n */\nfunction createManualModel(\n manualRules: Record<string, string[]>,\n environment: string\n): PrefetchModel {\n const model: PrefetchModel = {\n version: '1.0.0',\n generatedAt: new Date().toISOString(),\n environment,\n routes: {},\n dataSource: {\n provider: 'manual',\n dateRange: 'N/A',\n totalSessions: 0,\n totalRoutes: Object.keys(manualRules).length,\n },\n config: {\n type: 'probability',\n threshold: 1.0,\n maxPrefetch: 10,\n },\n };\n\n Object.entries(manualRules).forEach(([source, targets]) => {\n model.routes[source] = {\n prefetch: targets.map((target) => ({\n route: target,\n probability: 1.0,\n count: 0,\n priority: 'high',\n manual: true,\n })),\n };\n });\n\n return model;\n}\n\n/**\n * Generate analytics dashboard HTML\n */\nfunction generateDashboard(config: any): string {\n const totalRoutes = Object.keys(config.routes).length;\n const totalPrefetches = Object.values(config.routes).reduce(\n (sum: number, route: any) => sum + route.prefetch.length,\n 0\n );\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Smart Prefetch Report</title>\n <style>\n body {\n font-family: system-ui, -apple-system, sans-serif;\n max-width: 1200px;\n margin: 0 auto;\n padding: 2rem;\n background: #f5f5f5;\n }\n h1 { color: #333; }\n .stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1rem;\n margin: 2rem 0;\n }\n .stat-card {\n background: white;\n padding: 1.5rem;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n .stat-value { font-size: 2rem; font-weight: bold; color: #4CAF50; }\n .stat-label { color: #666; margin-top: 0.5rem; }\n .route-list {\n background: white;\n padding: 1.5rem;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n }\n .route-item {\n padding: 1rem;\n border-bottom: 1px solid #eee;\n }\n .route-item:last-child { border-bottom: none; }\n .route-source { font-weight: bold; color: #333; }\n .prefetch-target {\n margin-left: 2rem;\n padding: 0.5rem;\n color: #666;\n }\n .priority-high { color: #4CAF50; }\n .priority-medium { color: #FF9800; }\n .priority-low { color: #9E9E9E; }\n </style>\n</head>\n<body>\n <h1>πŸš€ Smart Prefetch Report</h1>\n <p>Generated: ${config.generatedAt}</p>\n <p>Environment: ${config.environment}</p>\n\n <div class=\"stats\">\n <div class=\"stat-card\">\n <div class=\"stat-value\">${totalRoutes}</div>\n <div class=\"stat-label\">Routes with Prefetch</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${totalPrefetches}</div>\n <div class=\"stat-label\">Total Prefetch Targets</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${config.dataSource?.totalSessions?.toLocaleString() || 'N/A'}</div>\n <div class=\"stat-label\">Sessions Analyzed</div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-value\">${(config.model.threshold * 100).toFixed(0)}%</div>\n <div class=\"stat-label\">Probability Threshold</div>\n </div>\n </div>\n\n <div class=\"route-list\">\n <h2>Prefetch Configuration</h2>\n ${Object.entries(config.routes)\n .map(\n ([source, data]: [string, any]) => `\n <div class=\"route-item\">\n <div class=\"route-source\">${source}</div>\n ${data.prefetch\n .map(\n (target: any) => `\n <div class=\"prefetch-target\">\n β†’ ${target.route}\n <span class=\"priority-${target.priority}\">\n (${(target.probability * 100).toFixed(1)}%, ${target.priority})\n </span>\n </div>\n `\n )\n .join('')}\n </div>\n `\n )\n .join('')}\n </div>\n</body>\n</html>`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKA,sBAAyB;AACzB,gBAAyC;AACzC,kBAAqB;AAGd,IAAM,6BAAN,MAAiC;AAAA,EAOtC,YAAY,WAAmB,WAAmB,WAAW,eAAe,QAAQ,OAAO;AACzF,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,WAAW;AAChB,SAAK,QAAQ;AAIb,SAAK,WAAW,IAAI,yBAAS;AAAA,MAC3B;AAAA,IACF,CAAC;AAED,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,iDAA4C;AACxD,cAAQ,IAAI,kBAAkB,SAAS,EAAE;AACzC,cAAQ,IAAI,kBAAkB,SAAS,EAAE;AACzC,cAAQ,IAAI,gBAAgB,QAAQ,EAAE;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,yBAAyB,SAA0B,CAAC,GAA8B;AACtF,UAAM,EAAE,OAAO,GAAG,IAAI;AACtB,UAAM,cAAc;AAEpB,YAAQ,IAAI,qDAA8C;AAC1D,YAAQ,IAAI,eAAe,KAAK,SAAS,EAAE;AAC3C,YAAQ,IAAI,uBAAuB,IAAI,OAAO;AAE9C,QAAI;AAIF,YAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAYD,KAAK,SAAS,IAAI,KAAK,SAAS;AAAA;AAAA;AAAA,gGAG6C,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyB9F,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,2BAAoB;AAChC,gBAAQ,IAAI,KAAK;AAAA,MACnB;AAEA,YAAM,CAAC,IAAI,IAAI,MAAM,KAAK,SAAS,MAAM;AAAA,QACvC;AAAA,QACA,UAAU,KAAK;AAAA,MACjB,CAAC;AAED,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,oCAA+B;AAC3C,gBAAQ,IAAI,qBAAqB,KAAK,MAAM,EAAE;AAAA,MAChD;AAEA,YAAM,iBAAmC,CAAC;AAG1C,YAAM,UAAU,KAAK,IAAI,CAAC,SAAc;AAAA,QACtC,oBAAoB,IAAI;AAAA,QACxB,WAAW,IAAI;AAAA,QACf,kBAAkB,IAAI;AAAA,MACxB,EAAE;AAGF,WAAK,QAAQ,CAAC,QAAa;AACzB,cAAM,eAAe,IAAI,sBAAsB;AAC/C,cAAM,cAAc,IAAI,aAAa;AACrC,cAAM,kBAAkB,SAAS,IAAI,oBAAoB,GAAG;AAG5D,cAAM,qBAAqB,iBAAiB,cAAc,iBAAiB,cAAc,aAAa,KAAK,eAAe,YAAY;AACtI,cAAM,oBAAoB,KAAK,eAAe,WAAW;AAGzD,YAAI,qBAAqB,mBAAmB,aAAa;AACvD,yBAAe,KAAK;AAAA,YAClB,MAAM;AAAA,YACN,IAAI;AAAA,YACJ,OAAO;AAAA,UACT,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAGD,WAAK,sBAAsB,SAAS,cAAc;AAElD,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,oBAAe,eAAe,MAAM,yBAAyB;AAGzE,YAAI,eAAe,SAAS,GAAG;AAC7B,kBAAQ,IAAI;AAAA,sBAAyB;AACrC,yBAAe,MAAM,GAAG,CAAC,EAAE,QAAQ,CAAC,KAAK,MAAM;AAC7C,oBAAQ,IAAI,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,WAAM,IAAI,EAAE,KAAK,IAAI,KAAK,eAAe;AAAA,UAC/E,CAAC;AAAA,QACH;AAGA,cAAM,eAAe,oBAAI,IAAY;AACrC,uBAAe,QAAQ,CAAC,QAAQ;AAC9B,cAAI,IAAI,SAAS,WAAY,cAAa,IAAI,IAAI,IAAI;AACtD,uBAAa,IAAI,IAAI,EAAE;AAAA,QACzB,CAAC;AACD,gBAAQ,IAAI;AAAA,8BAA0B,aAAa,IAAI,EAAE;AACzD,gBAAQ,IAAI,cAAc,MAAM,KAAK,YAAY,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE;AAEtE,gBAAQ,IAAI;AAAA,oDAAgD;AAAA,MAC9D;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU;AAG9D,UAAI,aAAa,SAAS,sBAAsB,KAAK,aAAa,SAAS,mBAAmB,GAAG;AAC/F,gBAAQ,MAAM,yDAAoD;AAClE,gBAAQ,MAAM,gEAAgE;AAC9E,gBAAQ,MAAM,qBAAqB,YAAY;AAAA,MACjD,OAAO;AACL,gBAAQ,MAAM,yCAAoC,KAAK;AAAA,MACzD;AAEA,YAAM,IAAI;AAAA,QACR,6BAA6B,YAAY;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,oBAAoB,MAAsB;AAEhD,UAAM,kBAA0C;AAAA;AAAA,MAE9C,qBAAqB;AAAA,MACrB,cAAc;AAAA,MACd,SAAS;AAAA,MACT,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,aAAa;AAAA;AAAA,MAGb,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,MACX,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,SAAS;AAAA,MACT,cAAc;AAAA,MACd,aAAa;AAAA,MACb,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,SAAS;AAAA,MACT,SAAS;AAAA,MACT,eAAe;AAAA,MACf,iBAAiB;AAAA,IACnB;AAGA,QAAI,gBAAgB,IAAI,GAAG;AACzB,aAAO,gBAAgB,IAAI;AAAA,IAC7B;AAGA,UAAM,YAAY,KAAK,YAAY;AACnC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC1D,UAAI,IAAI,YAAY,MAAM,WAAW;AACnC,eAAO;AAAA,MACT;AAAA,IACF;AAGA,QAAI,KAAK,WAAW,GAAG,GAAG;AACxB,UAAI,SAAS,KAAK;AAChB,eAAO;AAAA,MACT;AACA,aAAO,KAAK,YAAY;AAAA,IAC1B;AAGA,WAAO,MAAM;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAeA,OAAsB;AAE3C,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,eAAe,KAAK,CAAC,YAAY,QAAQ,KAAKA,KAAI,CAAC,GAAG;AACxD,aAAO;AAAA,IACT;AAIA,QAAI,aAAa,KAAK,oBAAoBA,KAAI;AAG9C,iBAAa,WAAW,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AAGlD,QAAI,WAAW,SAAS,KAAK,WAAW,SAAS,GAAG,GAAG;AACrD,mBAAa,WAAW,MAAM,GAAG,EAAE;AAAA,IACrC;AAGA,QAAI,eAAe,KAAK;AACtB,mBAAa,WAAW,YAAY,EAAE,QAAQ,OAAO,GAAG;AAAA,IAC1D;AAGA,iBAAa,WACV,QAAQ,4BAA4B,MAAM,EAC1C,QAAQ,4EAA4E,MAAM,EAC1F,QAAQ,kBAAkB,MAAM,EAChC,QAAQ,sCAAsC,SAAS,EACvD,QAAQ,gCAAgC,QAAQ;AAEnD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,sBAAsB,SAAgB,eAAuC;AACnF,QAAI;AACF,YAAM,YAAY;AAClB,YAAM,iBAAa,kBAAK,QAAQ,IAAI,GAAG,SAAS;AAGhD,+BAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAGzC,YAAM,cAAU,kBAAK,YAAY,4BAA4B;AAC7D,mCAAc,SAAS,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAGvD,YAAM,oBAAgB,kBAAK,YAAY,gCAAgC;AACvE,mCAAc,eAAe,KAAK,UAAU,eAAe,MAAM,CAAC,CAAC;AAGnE,YAAM,UAAU;AAAA,QACd,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC,aAAa,QAAQ;AAAA,QACrB,mBAAmB,cAAc;AAAA,QACjC,UAAU,QAAQ,SAAS,cAAc;AAAA,QACzC,sBAAsB,QAAQ,SAAS,cAAc,UAAU,QAAQ,SAAS,KAAK,QAAQ,CAAC,IAAI;AAAA,QAClG,kBAAkB,cAAc,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AAAA,QACnE,kBAAkB,IAAI,IAAI,cAAc,IAAI,OAAK,EAAE,IAAI,CAAC,EAAE;AAAA,QAC1D,gBAAgB,IAAI,IAAI,cAAc,IAAI,OAAK,EAAE,EAAE,CAAC,EAAE;AAAA,QACtD,gBAAgB,cAAc,MAAM,GAAG,EAAE;AAAA,MAC3C;AAEA,YAAM,kBAAc,kBAAK,YAAY,kCAAkC;AACvE,mCAAc,aAAa,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAE3D,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI;AAAA,mCAA+B;AAC3C,gBAAQ,IAAI,8BAA8B,QAAQ,WAAW,EAAE;AAC/D,gBAAQ,IAAI,wCAAwC,QAAQ,iBAAiB,EAAE;AAC/E,gBAAQ,IAAI,iBAAiB,QAAQ,QAAQ,UAAU,QAAQ,kBAAkB,GAAG;AACpF,gBAAQ,IAAI,+BAA+B,QAAQ,gBAAgB,EAAE;AACrE,gBAAQ,IAAI,4BAA4B,QAAQ,gBAAgB,EAAE;AAClE,gBAAQ,IAAI,iCAAiC,QAAQ,cAAc,EAAE;AACrE,gBAAQ,IAAI;AAAA,gBAAmB;AAC/B,gBAAQ,IAAI,aAAQ,OAAO,EAAE;AAC7B,gBAAQ,IAAI,aAAQ,aAAa,EAAE;AACnC,gBAAQ,IAAI,aAAQ,WAAW,EAAE;AAAA,MACnC;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,iDAAuC,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AAAA,IACpG;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,4BAA4B,SAA0B,CAAC,GAAmB;AAC9E,UAAM,EAAE,OAAO,GAAG,IAAI;AAEtB,YAAQ,IAAI,mEAA4D;AACxE,YAAQ,IAAI,eAAe,KAAK,SAAS,EAAE;AAC3C,YAAQ,IAAI,uBAAuB,IAAI,OAAO;AAE9C,QAAI;AAGF,YAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAaD,KAAK,SAAS,IAAI,KAAK,SAAS;AAAA;AAAA;AAAA,gGAG6C,IAAI;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;AA2B9F,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,gCAAyB;AACrC,gBAAQ,IAAI,KAAK;AAAA,MACnB;AAEA,YAAM,CAAC,IAAI,IAAI,MAAM,KAAK,SAAS,MAAM;AAAA,QACvC;AAAA,QACA,UAAU,KAAK;AAAA,MACjB,CAAC;AAED,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,oCAA+B;AAC3C,gBAAQ,IAAI,qBAAqB,KAAK,MAAM,EAAE;AAAA,MAChD;AAEA,YAAM,iBAAwB,CAAC;AAE/B,WAAK,QAAQ,CAAC,QAAa;AACzB,cAAM,eAAe,IAAI,sBAAsB;AAC/C,cAAM,cAAc,IAAI,aAAa;AACrC,cAAM,kBAAkB,SAAS,IAAI,oBAAoB,GAAG;AAC5D,cAAM,UAAU,IAAI,WAAW;AAE/B,cAAM,qBAAqB,iBAAiB,cAAc,iBAAiB,cAAc,aAAa,KAAK,eAAe,YAAY;AACtI,cAAM,oBAAoB,KAAK,eAAe,WAAW;AAEzD,YAAI,qBAAqB,mBAAmB,GAAG;AAC7C,yBAAe,KAAK;AAAA,YAClB,MAAM;AAAA,YACN,IAAI;AAAA,YACJ,OAAO;AAAA,YACP;AAAA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAED,UAAI,KAAK,SAAS,eAAe,SAAS,GAAG;AAC3C,gBAAQ,IAAI,oBAAe,eAAe,MAAM,gCAAgC;AAGhF,cAAM,iBAAiB,IAAI,IAAI,eAAe,IAAI,CAAC,MAAW,EAAE,OAAO,CAAC;AACxE,gBAAQ,IAAI;AAAA,wBAA2B,MAAM,KAAK,cAAc,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE;AAGrF,cAAM,YAAY,oBAAI,IAAI;AAC1B,uBAAe,QAAQ,CAAC,MAAW;AACjC,cAAI,CAAC,UAAU,IAAI,EAAE,OAAO,GAAG;AAC7B,sBAAU,IAAI,EAAE,SAAS,CAAC,CAAC;AAAA,UAC7B;AACA,oBAAU,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC;AAAA,QACjC,CAAC;AAED,kBAAU,QAAQ,CAAC,aAAoB,YAAoB;AACzD,kBAAQ,IAAI;AAAA,2BAA8B,OAAO,GAAG;AACpD,sBACG,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,MAAM,GAAG,CAAC,EACV,QAAQ,CAAC,KAAU,MAAc;AAChC,oBAAQ,IAAI,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,WAAM,IAAI,EAAE,KAAK,IAAI,KAAK,eAAe;AAAA,UAC/E,CAAC;AAAA,QACL,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU;AAC9D,cAAQ,KAAK,gEAAsD,YAAY,EAAE;AACjF,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBAAmC;AACvC,QAAI;AACF,YAAM,QAAQ;AACd,YAAM,KAAK,SAAS,MAAM;AAAA,QACxB;AAAA,QACA,UAAU,KAAK;AAAA,MACjB,CAAC;AAED,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,4CAAuC;AAAA,MACrD;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AAGd,UAAI,KAAK,OAAO;AACd,gBAAQ,KAAK,wFAA8E;AAAA,MAC7F;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AChfO,IAAM,qBAAN,MAAyB;AAAA,EAI9B,YAAY,QAAqB,QAAQ,OAAO;AAC9C,SAAK,SAAS;AACd,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aACE,gBACA,aACe;AACf,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI;AAAA,yCAAqC;AACjD,cAAQ,IAAI,kBAAkB,KAAK,OAAO,IAAI,EAAE;AAChD,cAAQ,IAAI,iBAAiB,KAAK,OAAO,YAAY,GAAG,GAAG;AAC3D,cAAQ,IAAI,8BAA8B,KAAK,OAAO,WAAW,EAAE;AACnE,cAAQ,IAAI,yBAAyB,eAAe,MAAM,EAAE;AAAA,IAC9D;AAGA,UAAM,kBAAkB,KAAK,qBAAqB,cAAc;AAChE,UAAM,SAAS,KAAK,cAAc,cAAc;AAEhD,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI;AAAA,uBAAmB;AAC/B,cAAQ,IAAI,qBAAqB,OAAO,IAAI,EAAE;AAC9C,cAAQ,IAAI,cAAc,MAAM,KAAK,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE;AAChE,cAAQ,IAAI,qBAAqB,gBAAgB,IAAI,EAAE;AAAA,IACzD;AAGA,UAAM,cAAc,KAAK,6BAA6B,eAAe;AAErE,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI;AAAA,0BAA6B;AACzC,cAAQ,IAAI,+BAA+B,YAAY,IAAI,EAAE;AAC7D,YAAM,eAAe,MAAM,KAAK,YAAY,OAAO,CAAC,EAAE;AAAA,QACpD,CAAC,KAAK,YAAY,MAAM,QAAQ;AAAA,QAChC;AAAA,MACF;AACA,cAAQ,IAAI,8BAA8B,YAAY,EAAE;AAAA,IAC1D;AAGA,UAAM,QAAuB;AAAA,MAC3B,SAAS;AAAA,MACT,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,YAAY;AAAA,QACV,UAAU;AAAA,QACV,WAAW,KAAK,aAAa,EAAE;AAAA,QAC/B,eAAe,eAAe,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AAAA,QACjE,aAAa,OAAO;AAAA,MACtB;AAAA,MACA,QAAQ,CAAC;AAAA,IACX;AAGA,gBAAY,QAAQ,CAAC,SAAS,WAAW;AACvC,YAAM,OAAO,MAAM,IAAI;AAAA,QACrB,UAAU;AAAA,QACV,UAAU,KAAK,kBAAkB,iBAAiB,MAAM;AAAA,MAC1D;AAAA,IACF,CAAC;AAED,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI;AAAA,qCAAmC;AAC/C,YAAM,eAAe,MAAM,KAAK,YAAY,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC;AACjE,UAAI,aAAa,SAAS,GAAG;AAC3B,gBAAQ,IAAI;AAAA,uBAA0B;AACtC,qBAAa,QAAQ,CAAC,CAAC,QAAQ,OAAO,MAAM;AAC1C,kBAAQ,IAAI,MAAM,MAAM,GAAG;AAC3B,kBAAQ,QAAQ,CAAC,WAAW;AAC1B,oBAAQ;AAAA,cACN,eAAU,OAAO,KAAK,MAAM,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ;AAAA,YACvF;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,MAAqC;AACzD,UAAM,SAAS,oBAAI,IAAY;AAE/B,SAAK,QAAQ,CAAC,MAAM;AAClB,aAAO,IAAI,EAAE,IAAI;AACjB,aAAO,IAAI,EAAE,EAAE;AAAA,IACjB,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,qBACN,MACkC;AAClC,UAAM,QAAQ,oBAAI,IAAiC;AAEnD,SAAK,QAAQ,CAAC,EAAE,MAAM,IAAI,MAAM,MAAM;AACpC,UAAI,CAAC,MAAM,IAAI,IAAI,GAAG;AACpB,cAAM,IAAI,MAAM,oBAAI,IAAI,CAAC;AAAA,MAC3B;AAEA,YAAM,UAAU,MAAM,IAAI,IAAI;AAC9B,cAAQ,IAAI,KAAK,QAAQ,IAAI,EAAE,KAAK,KAAK,KAAK;AAAA,IAChD,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,6BACN,iBAC+B;AAC/B,UAAM,cAAc,oBAAI,IAA8B;AAEtD,oBAAgB,QAAQ,CAAC,SAAS,WAAW;AAC3C,YAAM,cAAgC,CAAC;AAGvC,YAAM,kBAAkB,MAAM,KAAK,QAAQ,OAAO,CAAC,EAAE;AAAA,QACnD,CAAC,KAAK,UAAU,MAAM;AAAA,QACtB;AAAA,MACF;AAEA,UAAI,oBAAoB,EAAG;AAG3B,YAAM,gBAAgB,oBAAI,IAAoB;AAC9C,cAAQ,QAAQ,CAAC,OAAO,gBAAgB;AACtC,sBAAc,IAAI,aAAa,QAAQ,eAAe;AAAA,MACxD,CAAC;AAGD,YAAM,UAAU,KAAK,IAAI,GAAG,MAAM,KAAK,cAAc,OAAO,CAAC,CAAC;AAC9D,UAAI,UAAU,GAAG;AACf,sBAAc,QAAQ,CAAC,MAAM,SAAS;AACpC,wBAAc,IAAI,MAAM,OAAO,OAAO;AAAA,QACxC,CAAC;AAAA,MACH;AAGA,YAAM,SAAS,MAAM,KAAK,cAAc,QAAQ,CAAC,EAC9C,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,MAAM,GAAG,KAAK,OAAO,WAAW;AAGnC,aAAO,QAAQ,CAAC,CAAC,OAAO,WAAW,MAAM;AACvC,YAAI,eAAe,KAAK,OAAO,WAAW;AACxC,sBAAY,KAAK;AAAA,YACf;AAAA,YACA;AAAA,YACA,OAAO,QAAQ,IAAI,KAAK,KAAK;AAAA,YAC7B,UAAU,KAAK,YAAY,WAAW;AAAA,UACxC,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAED,UAAI,YAAY,SAAS,GAAG;AAC1B,oBAAY,IAAI,QAAQ,WAAW;AAAA,MACrC;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,OAA0C;AAC5D,QAAI,SAAS,IAAK,QAAO;AACzB,QAAI,SAAS,IAAK,QAAO;AACzB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,kBACN,iBACA,OACe;AACf,UAAM,UAAU,gBAAgB,IAAI,KAAK;AAEzC,QAAI,CAAC,WAAW,QAAQ,SAAS,GAAG;AAClC,aAAO;AAAA,QACL,kBAAkB;AAAA,QAClB,gBAAgB;AAAA,MAClB;AAAA,IACF;AAEA,UAAM,mBAAmB,MAAM,KAAK,QAAQ,OAAO,CAAC,EAAE;AAAA,MACpD,CAAC,KAAK,UAAU,MAAM;AAAA,MACtB;AAAA,IACF;AAGA,QAAI,iBAAiB;AACrB,QAAI,WAAW;AACf,YAAQ,QAAQ,CAAC,OAAO,gBAAgB;AACtC,UAAI,QAAQ,UAAU;AACpB,mBAAW;AACX,yBAAiB;AAAA,MACnB;AAAA,IACF,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,qBACE,4BACA,aAC4B;AAC5B,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI;AAAA,qDAAiD;AAAA,IAC/D;AAGA,UAAM,gBAAgB,oBAAI,IAA8B;AAExD,+BAA2B,QAAQ,CAAC,SAAS;AAC3C,YAAM,UAAU,KAAK,WAAW;AAChC,UAAI,CAAC,cAAc,IAAI,OAAO,GAAG;AAC/B,sBAAc,IAAI,SAAS,CAAC,CAAC;AAAA,MAC/B;AACA,oBAAc,IAAI,OAAO,EAAG,KAAK;AAAA,QAC/B,MAAM,KAAK;AAAA,QACX,IAAI,KAAK;AAAA,QACT,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAED,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI;AAAA,gCAA4B;AACxC,oBAAc,QAAQ,CAAC,MAAM,YAAY;AACvC,gBAAQ,IAAI,aAAQ,OAAO,KAAK,KAAK,MAAM,cAAc;AAAA,MAC3D,CAAC;AAAA,IACH;AAGA,UAAM,gBAAgB,oBAAI,IAA2B;AACrD,kBAAc,QAAQ,CAAC,gBAAgB,YAAY;AACjD,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI;AAAA,4CAAwC,OAAO,GAAG;AAAA,MAChE;AAEA,YAAM,QAAQ,KAAK,aAAa,gBAAgB,WAAW;AAG3D,YAAM,WAAY,WAAW,gBAAgB,OAAO;AAEpD,oBAAc,IAAI,SAAS,KAAK;AAEhC,UAAI,KAAK,OAAO;AACd,cAAM,eAAe,OAAO,OAAO,MAAM,MAAM,EAAE;AAAA,UAC/C,CAAC,KAAK,UAAU,OAAO,MAAM,UAAU,UAAU;AAAA,UACjD;AAAA,QACF;AACA,gBAAQ,IAAI,wBAAmB,OAAO,kBAAkB,YAAY,mBAAmB;AAAA,MACzF;AAAA,IACF,CAAC;AAED,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI;AAAA,gBAAc,cAAc,IAAI,sCAAsC;AAAA,IACpF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAa,MAAsB;AACzC,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,QAAQ,oBAAI,KAAK;AACvB,UAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI;AAEpC,WAAO,GAAG,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,OAAO,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,EACnF;AACF;;;ACnTO,IAAM,mBAAN,MAAM,iBAAgB;AAAA,EAwG3B,YAAY,UAAwB,cAA2B,CAAC,GAAG,QAAQ,OAAO,MAAY;AApG9F,SAAQ,OAAY;AACpB,SAAQ,QAAiB;AAoGvB,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,QAAQ;AACb,SAAK,OAAO,QAAQ;AACpB,SAAK,QAAQ,CAAC,CAAC;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,OAAsC;AAC7C,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI;AAAA,+CAA2C;AACvD,cAAQ,IAAI,wBAAwB,OAAO,KAAK,KAAK,QAAQ,EAAE,MAAM,EAAE;AACvE,cAAQ,IAAI,oBAAoB,OAAO,KAAK,MAAM,MAAM,EAAE,MAAM,EAAE;AAClE,cAAQ,IAAI,oBAAoB,OAAO,KAAK,KAAK,WAAW,EAAE,MAAM,EAAE;AACtE,UAAI,OAAO,OAAO,MAAM,MAAM,EAAE,KAAK,OAAK,EAAE,QAAQ,GAAG;AACrD,gBAAQ,IAAI,+CAAqC;AAAA,MACnD;AAAA,IACF;AAGA,UAAM,cAAc,KAAK,iBAAiB,KAAK;AAG/C,UAAM,gBAAgB,KAAK,qBAAqB,OAAO,KAAK,YAAY,MAAM,CAAC;AAG/E,UAAM,SAAyB;AAAA,MAC7B,SAAS,MAAM;AAAA,MACf,aAAa,MAAM;AAAA,MACnB,aAAa,MAAM;AAAA,MACnB,YAAY,MAAM;AAAA,MAClB,OAAO;AAAA,QACL,MAAM,MAAM,OAAQ;AAAA,QACpB,WAAW,MAAM,OAAQ;AAAA,QACzB,aAAa,MAAM,OAAQ;AAAA,MAC7B;AAAA,MACA;AAAA;AAAA,MACA,QAAQ,CAAC;AAAA,MACT,QAAQ,CAAC;AAAA,IACX;AAEA,QAAI,eAAe;AACnB,QAAI,iBAAiB;AACrB,QAAI,oBAAoB;AAGxB,WAAO,QAAQ,YAAY,MAAM,EAAE,QAAQ,CAAC,CAAC,aAAa,UAAU,MAAM;AACxE,YAAM,kBAA6D,CAAC;AACpE,YAAM,iBAA4E,CAAC;AAGnF,YAAM,cAAc,KAAK,aAAa,WAAW;AACjD,UAAI,eAAe,CAAC,OAAO,OAAO,WAAW,GAAG;AAC9C,eAAO,OAAO,WAAW,IAAI;AAAA,MAC/B;AAGA,iBAAW,SAAS,QAAQ,CAAC,WAAW;AACtC,cAAM,YAAY,KAAK,aAAa,OAAO,KAAK;AAEhD,YAAI,WAAW;AAEb,gBAAM,gBAAgB,KAAK,uBAAuB,SAAS;AAC3D,gBAAM,iBAAiB,eAAe,WAAW,CAAC;AAGlD,gBAAM,UAAU,eACb,IAAI,CAAC,YAAY;AAChB,kBAAM,QAAQ,KAAK,SAAS,OAAO;AACnC,mBAAO,OAAO;AAAA,UAChB,CAAC,EACA,OAAO,CAAC,SAAyB,CAAC,CAAC,IAAI;AAE1C,0BAAgB,KAAK;AAAA,YACnB,GAAG;AAAA,YACH,OAAO;AAAA,YACP,YAAY;AAAA;AAAA,YACZ;AAAA;AAAA,UACF,CAAC;AAGD,iBAAO,OAAO,OAAO,KAAK,IAAI;AAC9B;AAGA,cAAI,KAAK,OAAO;AACd,oBAAQ,IAAI,aAAQ,WAAW,WAAM,OAAO,KAAK,EAAE;AACnD,oBAAQ,IAAI,gBAAgB,SAAS,EAAE;AACvC,gBAAI,QAAQ,SAAS,GAAG;AACtB,sBAAQ,IAAI,uBAAuB,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,YACzD;AAAA,UACF;AAAA,QACF,OAAO;AACL,cAAI,KAAK,OAAO;AACd,oBAAQ,IAAI,8CAAoC,OAAO,KAAK,EAAE;AAC9D,oBAAQ,IAAI,6CAA6C;AAAA,UAC3D;AACA;AAAA,QACF;AAAA,MACF,CAAC;AAGD,UAAI,WAAW,UAAU;AACvB,eAAO,QAAQ,WAAW,QAAQ,EAAE,QAAQ,CAAC,CAAC,SAAS,cAAc,MAAM;AACzE,gBAAM,yBAAoE,CAAC;AAE3E,yBAAe,QAAQ,CAAC,WAAW;AACjC,kBAAM,YAAY,KAAK,aAAa,OAAO,KAAK;AAEhD,gBAAI,WAAW;AACb,oBAAM,gBAAgB,KAAK,uBAAuB,SAAS;AAC3D,oBAAM,iBAAiB,eAAe,WAAW,CAAC;AAElD,oBAAM,UAAU,eACb,IAAI,CAAC,YAAY;AAChB,sBAAM,QAAQ,KAAK,SAAS,OAAO;AACnC,uBAAO,OAAO;AAAA,cAChB,CAAC,EACA,OAAO,CAAC,SAAyB,CAAC,CAAC,IAAI;AAE1C,qCAAuB,KAAK;AAAA,gBAC1B,GAAG;AAAA,gBACH,OAAO;AAAA,gBACP,YAAY;AAAA;AAAA,gBACZ;AAAA,cACF,CAAC;AAED,qBAAO,OAAO,OAAO,KAAK,IAAI;AAC9B;AAAA,YACF;AAAA,UACF,CAAC;AAED,cAAI,uBAAuB,SAAS,GAAG;AACrC,2BAAe,OAAO,IAAI;AAAA,UAC5B;AAAA,QACF,CAAC;AAED,YAAI,KAAK,SAAS,OAAO,KAAK,cAAc,EAAE,SAAS,GAAG;AACxD,kBAAQ,IAAI,oCAA6B,WAAW,KAAK,OAAO,KAAK,cAAc,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,QACnG;AAAA,MACF;AAGA,YAAM,WAAW,cAAc,WAAW,KAAK,CAAC,WAAW;AAG3D,UAAI,gBAAgB,SAAS,KAAK,OAAO,KAAK,cAAc,EAAE,SAAS,GAAG;AACxE,eAAO,OAAO,WAAW,IAAI;AAAA,UAC3B;AAAA;AAAA,UACA,UAAU;AAAA,UACV,GAAI,OAAO,KAAK,cAAc,EAAE,SAAS,KAAK;AAAA,YAC5C,UAAU;AAAA,UACZ;AAAA,UACA,UAAU,WAAW;AAAA,QACvB;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,gCAA2B;AACvC,cAAQ,IAAI,4BAA4B,OAAO,KAAK,OAAO,MAAM,EAAE,MAAM,EAAE;AAC3E,cAAQ,IAAI,qBAAqB,YAAY,EAAE;AAC/C,cAAQ,IAAI,8BAA8B,iBAAiB,EAAE;AAC7D,cAAQ,IAAI,uBAAuB,cAAc,EAAE;AAAA,IACrD;AAGA,UAAM,cAAc,oBAAI,IAAY;AACpC,WAAO,OAAO,OAAO,MAAM,EAAE,QAAQ,WAAS;AAC5C,UAAI,MAAM,UAAU;AAClB,eAAO,KAAK,MAAM,QAAQ,EAAE,QAAQ,SAAO,YAAY,IAAI,GAAG,CAAC;AAAA,MACjE;AAAA,IACF,CAAC;AAED,QAAI,YAAY,OAAO,GAAG;AACxB,aAAO,cAAc;AAAA,QACnB,WAAW,MAAM,KAAK,WAAW;AAAA,QACjC,aAAa;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiB,OAAqC;AAC5D,UAAM,SAAS,EAAE,GAAG,OAAO,QAAQ,EAAE,GAAG,MAAM,OAAO,EAAE;AAEvD,WAAO,QAAQ,KAAK,WAAW,EAAE,QAAQ,CAAC,CAAC,aAAa,YAAY,MAAM;AACxE,UAAI,CAAC,OAAO,OAAO,WAAW,GAAG;AAC/B,eAAO,OAAO,WAAW,IAAI;AAAA,UAC3B,UAAU,CAAC;AAAA,QACb;AAAA,MACF;AAGA,mBAAa,QAAQ,CAAC,gBAAgB;AAEpC,cAAM,WAAW,OAAO,OAAO,WAAW,EAAE,SAAS;AAAA,UACnD,CAAC,MAAM,EAAE,UAAU;AAAA,QACrB;AAEA,YAAI,UAAU;AAEZ,mBAAS,SAAS;AAClB,mBAAS,WAAW;AACpB,mBAAS,cAAc;AAAA,QACzB,OAAO;AAEL,iBAAO,OAAO,WAAW,EAAE,SAAS,QAAQ;AAAA,YAC1C,OAAO;AAAA,YACP,aAAa;AAAA,YACb,OAAO;AAAA;AAAA,YACP,UAAU;AAAA,YACV,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAED,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,gCAA2B,WAAW,YAAO,aAAa,KAAK,IAAI,CAAC,GAAG;AAAA,MACrF;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,oBAAoB,OAA8B;AACxD,UAAM,kBAAkB,MAAM,YAAY;AAG1C,UAAM,gBAAgB,iBAAgB,wBAAwB,eAAe;AAC7E,QAAI,CAAC,eAAe;AAClB,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,sBAAiB,KAAK,yCAAyC;AAAA,MAC7E;AACA,aAAO;AAAA,IACT;AAGA,UAAM,YAAY,iBAAgB,wBAAwB,aAAa;AACvE,QAAI,CAAC,WAAW;AACd,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,0BAAqB,aAAa,yCAAyC;AAAA,MACzF;AACA,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,OAAO,QAAQ,KAAK,QAAQ,EAAE;AAAA,MAC/C,CAAC,CAAC,KAAK,KAAK,MACT,MAAc,SAAS,aAAa,IAAI,SAAS,SAAS;AAAA,IAC/D;AAEA,QAAI,CAAC,YAAY;AACf,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,2BAAsB,SAAS,wBAAwB;AAAA,MACrE;AACA,aAAO;AAAA,IACT;AAEA,UAAM,YAAa,WAAW,CAAC,EAAU;AACzC,QAAI,KAAK,OAAO;AACd,cAAQ;AAAA,QACN,mCAA8B,KAAK,WAAM,aAAa,WAAM,SAAS,WAAM,SAAS;AAAA,MACtF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,aAAa,OAA8B;AAEjD,UAAM,UAAU,KAAK,oBAAoB,KAAK;AAC9C,QAAI,SAAS;AACX,aAAO;AAAA,IACT;AAGA,UAAM,cAAc,KAAK,gBAAgB,KAAK;AAC9C,QAAI,aAAa;AACf,aAAO;AAAA,IACT;AAGA,UAAM,eAAe,KAAK,iBAAiB,KAAK;AAChD,QAAI,cAAc;AAChB,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,KAAK,eAAe,KAAK;AAC5C,QAAI,YAAY;AACd,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,OAA8B;AAEpD,UAAM,kBAAkB,MAAM,QAAQ,cAAc,EAAE;AACtD,UAAM,iBAAiB,gBAAgB,QAAQ,OAAO,EAAE;AAIxD,UAAM,gBAAgB,gBAAgB,MAAM,GAAG,EAAE,OAAO,OAAO;AAC/D,UAAM,sBAAsB,cACzB,IAAI,aAAW;AAEd,YAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,aAAO,MACJ,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACtE,KAAK,EAAE;AAAA,IACZ,CAAC,EACA,KAAK,GAAG;AAGX,QAAI,sBAAsB;AAC1B,QAAI,cAAc,WAAW,GAAG;AAC9B,YAAM,UAAU,cAAc,CAAC;AAC/B,YAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,4BAAsB,MACnB,IAAI,OAAK,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,EAC7D,KAAK,EAAE;AAAA,IACZ;AAIA,UAAM,WAAW;AAAA;AAAA,MAEf,sBAAsB,aAAa,mBAAmB,SAAS;AAAA,MAC/D,sBAAsB,aAAa,mBAAmB,QAAQ;AAAA,MAC9D,sBAAsB,aAAa,mBAAmB,SAAS;AAAA,MAC/D,sBAAsB,aAAa,mBAAmB,QAAQ;AAAA;AAAA,MAE9D,aAAa,mBAAmB;AAAA,MAChC,aAAa,mBAAmB;AAAA,MAChC,aAAa,mBAAmB;AAAA,MAChC,aAAa,mBAAmB;AAAA;AAAA,MAEhC,eAAe,eAAe;AAAA,MAC9B,eAAe,eAAe;AAAA,MAC9B,eAAe,eAAe;AAAA,MAC9B,eAAe,eAAe;AAAA;AAAA,MAE9B,YAAY,eAAe;AAAA,MAC3B,YAAY,eAAe;AAAA,MAC3B,YAAY,eAAe;AAAA,MAC3B,YAAY,eAAe;AAAA,MAC3B,YAAY,eAAe;AAAA,MAC3B,YAAY,eAAe;AAAA,MAC3B,YAAY,eAAe;AAAA,MAC3B,YAAY,eAAe;AAAA;AAAA,MAE3B,aAAa,KAAK,WAAW,cAAc,CAAC;AAAA,MAC5C,aAAa,KAAK,WAAW,cAAc,CAAC;AAAA;AAAA,MAE5C,gCAAgC,eAAe;AAAA,MAC/C,gCAAgC,eAAe;AAAA,MAC/C,6BAA6B,eAAe;AAAA,IAC9C,EAAE,OAAO,OAAO;AAEhB,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,YAAM,UAAU,SAAS,CAAC;AAC1B,UAAI,CAAC,QAAS;AACd,YAAM,QAAQ,KAAK,SAAS,OAAO;AACnC,UAAI,OAAO;AACT,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAW,KAAqB;AACtC,WAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,OAA8B;AACrD,UAAM,gBAAgB,MAAM,MAAM,GAAG,EAAE,OAAO,OAAO;AACrD,QAAI,cAAc,WAAW,EAAG,QAAO;AAGvC,UAAM,aAAa,OAAO,QAAQ,KAAK,QAAQ,EAC5C,OAAO,CAAC,CAACC,KAAI,MAAM;AAClB,YAAM,eAAeA,MAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAGnD,aAAO,cAAc;AAAA,QAAM,CAAC,YAC1B,aAAa;AAAA,UAAK,CAAC,OACjB,GAAG,YAAY,EAAE,SAAS,QAAQ,QAAQ,WAAW,EAAE,EAAE,YAAY,CAAC;AAAA,QACxE;AAAA,MACF;AAAA,IACF,CAAC,EACA,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,MAAM;AAE1B,UAAI,MAAM,SAAS,SAAS,KAAK,CAAC,MAAM,SAAS,SAAS,EAAG,QAAO;AACpE,UAAI,CAAC,MAAM,SAAS,SAAS,KAAK,MAAM,SAAS,SAAS,EAAG,QAAO;AAGpE,YAAM,WAAW,MAAM,SAAS,WAAW,KAAK,MAAM,SAAS,UAAU;AACzE,YAAM,WAAW,MAAM,SAAS,WAAW,KAAK,MAAM,SAAS,UAAU;AACzE,UAAI,YAAY,CAAC,SAAU,QAAO;AAClC,UAAI,CAAC,YAAY,SAAU,QAAO;AAGlC,UAAI,MAAM,SAAS,MAAM,KAAK,CAAC,MAAM,SAAS,MAAM,EAAG,QAAO;AAC9D,UAAI,CAAC,MAAM,SAAS,MAAM,KAAK,MAAM,SAAS,MAAM,EAAG,QAAO;AAE9D,aAAO;AAAA,IACT,CAAC;AAEH,QAAI,WAAW,SAAS,GAAG;AACzB,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,qCAAgC,WAAW,CAAC,EAAE,CAAC,CAAC,WAAM,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE;AAAA,MAC3F;AACA,aAAO,WAAW,CAAC,EAAE,CAAC,EAAE;AAAA,IAC1B;AAEA,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,8BAA8B;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAe,OAA8B;AAEnD,UAAM,aAAa,MAAM,QAAQ,cAAc,EAAE;AAGjD,UAAM,gBAAgB,WAAW,MAAM,GAAG,EAAE,OAAO,OAAO;AAC1D,UAAM,aAAa,cAChB,IAAI,CAAC,YAAY;AAChB,YAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,aAAO,MACJ,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACxE,KAAK,EAAE;AAAA,IACZ,CAAC,EACA,KAAK,EAAE;AAGV,UAAM,YAAY,WAAW,OAAO,CAAC,EAAE,YAAY,IAAI,WAAW,MAAM,CAAC;AAEzE,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,8BAA8B,KAAK,EAAE;AACjD,cAAQ,IAAI,4BAA4B,UAAU,gBAAgB,SAAS,EAAE;AAAA,IAC/E;AAIA,UAAM,aAAa,OAAO,QAAQ,KAAK,QAAQ,EAC5C,OAAO,CAAC,CAACA,OAAM,KAAK,MAAM;AAEzB,UAAIA,MAAK,WAAW,GAAG,KAAKA,MAAK,WAAW,cAAc,GAAG;AAC3D,eAAO;AAAA,MACT;AAEA,YAAM,WAAWA,MAAK,MAAM,GAAG,EAAE,IAAI,KAAK;AAC1C,YAAM,qBAAqB,SAAS,QAAQ,YAAY,EAAE;AAG1D,UAAI,uBAAuB,cAAc,uBAAuB,WAAW;AACzE,eAAO;AAAA,MACT;AAGA,UAAI,SAAS,SAAS,UAAU,KAAK,SAAS,SAAS,SAAS,GAAG;AACjE,eAAO;AAAA,MACT;AAGA,YAAM,eAAeA,MAAK,YAAY,EAAE,MAAM,GAAG;AACjD,YAAM,cAAc,WAAW,YAAY;AAC3C,YAAM,aAAa,UAAU,YAAY;AAEzC,aAAO,aAAa;AAAA,QAAK,SACvB,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,UAAU;AAAA,MACtD;AAAA,IACF,CAAC,EACA,KAAK,CAAC,CAAC,OAAO,MAAM,GAAG,CAAC,OAAO,MAAM,MAAM;AAE1C,YAAM,UAAW,OAAe,MAAM,IAAI;AAC1C,YAAM,UAAW,OAAe,MAAM,IAAI;AAC1C,UAAI,YAAY,QAAS,QAAO,UAAU;AAG1C,YAAM,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI,GAAG,QAAQ,YAAY,EAAE,KAAK;AACjE,YAAM,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI,GAAG,QAAQ,YAAY,EAAE,KAAK;AAGjE,UAAI,UAAU,WAAY,QAAO;AACjC,UAAI,UAAU,WAAY,QAAO;AACjC,UAAI,UAAU,UAAW,QAAO;AAChC,UAAI,UAAU,UAAW,QAAO;AAGhC,UAAI,MAAM,SAAS,SAAS,KAAK,CAAC,MAAM,SAAS,SAAS,EAAG,QAAO;AACpE,UAAI,CAAC,MAAM,SAAS,SAAS,KAAK,MAAM,SAAS,SAAS,EAAG,QAAO;AAEpE,aAAO;AAAA,IACT,CAAC;AAEH,QAAI,WAAW,SAAS,GAAG;AACzB,YAAM,SAAS,WAAW,CAAC,EAAE,CAAC,EAAE;AAChC,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,mCAA8B,WAAW,CAAC,EAAE,CAAC,CAAC,WAAM,MAAM,EAAE;AAAA,MAC1E;AACA,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI,4BAA4B;AAAA,IAC1C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAAuB,UAAkB;AAC/C,WAAO,OAAO,OAAO,KAAK,QAAQ,EAAE,KAAK,CAAC,UAAU,MAAM,SAAS,QAAQ;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,QAAkC;AACpD,WAAO,OAAO,OAAO,OAAO,MAAM;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,QAGb;AACA,UAAM,UAAoB,CAAC;AAC3B,UAAM,gBAAgB,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAE7E,WAAO,QAAQ,OAAO,MAAM,EAAE,QAAQ,CAAC,CAAC,OAAO,KAAK,MAAM;AACxD,UAAI,CAAC,cAAc,IAAI,KAAK,GAAG;AAC7B,gBAAQ,KAAK,GAAG,KAAK,OAAO,KAAK,EAAE;AAAA,MACrC;AAAA,IACF,CAAC;AAED,WAAO;AAAA,MACL,OAAO,QAAQ,WAAW;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,qBAAqB,QAA4C;AACvE,UAAM,WAAqC,CAAC;AAE5C,eAAW,SAAS,QAAQ;AAE1B,UAAI,MAAM,SAAS,GAAG,KAAK,MAAM,SAAS,GAAG,GAAG;AAE9C,iBAAS,KAAK,IAAI,CAAC,KAAK;AAGxB,cAAM,OAAO,MAAM,MAAM,MAAM,EAAE,CAAC;AAClC,YAAI,QAAQ,SAAS,OAAO;AAE1B,cAAI,CAAC,SAAS,IAAI,GAAG;AACnB,qBAAS,IAAI,IAAI,CAAC,MAAM,KAAK;AAAA,UAC/B,WAAW,CAAC,SAAS,IAAI,EAAE,SAAS,KAAK,GAAG;AAC1C,qBAAS,IAAI,EAAE,KAAK,KAAK;AAAA,UAC3B;AAAA,QACF;AAAA,MACF,OAAO;AAEL,iBAAS,KAAK,IAAI,CAAC,KAAK;AAAA,MAC1B;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,OAAO,KAAK,QAAQ,EAAE,SAAS,GAAG;AAClD,cAAQ,IAAI;AAAA,yDAAqD;AACjE,aAAO,QAAQ,QAAQ,EAAE,QAAQ,CAAC,CAAC,OAAO,WAAW,MAAM;AACzD,YAAI,YAAY,SAAS,GAAG;AAC1B,kBAAQ,IAAI,MAAM,KAAK,YAAO,YAAY,KAAK,IAAI,CAAC,GAAG;AAAA,QACzD;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAkB,UAAkB,SAA0B;AAGpE,UAAM,eAAe,IAAI;AAAA,MACvB,MAAM,QACH,QAAQ,WAAW,OAAO,EAC1B,QAAQ,YAAY,OAAO,EAC3B,QAAQ,OAAO,IAAI;AAAA,MACtB;AAAA,IACF;AACA,WAAO,aAAa,KAAK,QAAQ;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,oBACE,UACA,QACe;AACf,eAAW,CAAC,OAAO,MAAM,KAAK,OAAO,QAAQ,MAAM,GAAG;AACpD,YAAM,WAAY,OAAe,YAAY,CAAC,KAAK;AACnD,iBAAW,WAAW,UAAU;AAC9B,YAAI,KAAK,kBAAkB,UAAU,OAAO,GAAG;AAC7C,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBACE,eAC6B;AAC7B,UAAM,iBAAiB,oBAAI,IAA4B;AAEvD,kBAAc,QAAQ,CAAC,OAAO,YAAY;AACxC,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI;AAAA,4CAAwC,OAAO,GAAG;AAAA,MAChE;AAEA,YAAM,SAAS,KAAK,SAAS,KAAK;AAGlC,MAAC,OAAe,UAAU;AAE1B,qBAAe,IAAI,SAAS,MAAM;AAElC,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,mCAA8B,OAAO,GAAG;AACpD,gBAAQ,IAAI,iBAAiB,OAAO,KAAK,OAAO,MAAM,EAAE,MAAM,EAAE;AAChE,gBAAQ,IAAI,iBAAiB,OAAO,KAAK,OAAO,MAAM,EAAE,MAAM,EAAE;AAAA,MAClE;AAAA,IACF,CAAC;AAED,QAAI,KAAK,OAAO;AACd,cAAQ,IAAI;AAAA,mBAAiB,eAAe,IAAI,kCAAkC;AAAA,IACpF;AAEA,WAAO;AAAA,EACT;AACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAhyBa,iBAaa,0BAAkD;AAAA,EACxE,KAAK;AAAA,EACL,SAAS;AAAA,EACT,cAAc;AAAA,EAEd,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,aAAa;AAAA,EAEb,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,YAAY;AAAA,EAEZ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,eAAe;AAAA,EAEf,cAAc;AAAA,EACd,cAAc;AAAA,EACd,SAAS;AAAA,EACT,eAAe;AAAA,EAEf,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,sBAAsB;AAAA;AAAA,EACtB,YAAY;AAAA,EACZ,SAAS;AAAA,EAET,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,UAAU;AAAA,EAEV,gBAAgB;AAAA,EAChB,kBAAkB;AACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAlDW,iBA2Da,0BAAkD;AAAA;AAAA,EAExE,MAAM;AAAA;AAAA,EACN,WAAW;AAAA;AAAA,EAGX,SAAS;AAAA,EACT,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AAAA,EACT,UAAU;AAAA;AAAA,EAGV,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA;AAAA,EAGT,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AAAA;AAAA,EAGZ,WAAW;AAAA,EACX,WAAW;AAAA,EACX,MAAM;AAAA,EACN,WAAW;AAAA;AAAA,EAGX,cAAc;AAAA,EACd,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AAAA;AAAA,EAGN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AAAA;AAAA,EAGP,aAAa;AAAA,EACb,eAAe;AACjB;AAtGK,IAAM,kBAAN;;;ACPP,SAAoB;AACpB,WAAsB;AAGf,IAAM,eAAN,MAAmB;AAAA,EAMxB,YAAY,SAAsB,CAAC,GAAG,QAAQ,OAAO;AACnD,SAAK,UAAU,OAAO,WAAW;AACjC,SAAK,MAAM,OAAO,OAAO,KAAK,KAAK,KAAK;AACxC,SAAK,WAAW,OAAO,QAAa,UAAK,QAAQ,IAAI,GAAG,iBAAiB;AACzE,SAAK,QAAQ;AAEb,QAAI,KAAK,WAAW,CAAI,cAAW,KAAK,QAAQ,GAAG;AACjD,MAAG,aAAU,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC/C,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,sCAA+B,KAAK,QAAQ,EAAE;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAI,aAAoD;AAC5D,QAAI,CAAC,KAAK,SAAS;AACjB,UAAI,KAAK,MAAO,SAAQ,IAAI,qDAA2C;AACvE,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,YAAiB,UAAK,KAAK,UAAU,GAAG,WAAW,OAAO;AAEhE,UAAI,CAAI,cAAW,SAAS,GAAG;AAC7B,YAAI,KAAK,MAAO,SAAQ,IAAI,yCAAkC,WAAW,EAAE;AAC3E,eAAO;AAAA,MACT;AAEA,YAAM,QAAW,YAAS,SAAS;AACnC,YAAM,WAAW,KAAK,IAAI,IAAI,MAAM;AAEpC,UAAI,WAAW,KAAK,KAAK;AACvB,YAAI,KAAK,MAAO,SAAQ,IAAI,4BAAuB,WAAW,KAAK,KAAK,MAAM,WAAW,MAAO,EAAE,CAAC,eAAe;AAClH,QAAG,cAAW,SAAS;AACvB,eAAO;AAAA,MACT;AAEA,YAAM,aAAgB,gBAAa,WAAW,OAAO;AACrD,YAAM,QAAuB,KAAK,MAAM,UAAU;AAElD,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,qCAAgC,WAAW,KAAK,KAAK,MAAM,WAAW,GAAI,CAAC,eAAe;AACtG,gBAAQ,IAAI,uBAAuB,OAAO,KAAK,MAAM,MAAM,EAAE,MAAM,SAAS;AAAA,MAC9E;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,kCAA6B,WAAW,KAAK,KAAK;AAChE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,IAAI,aAAqB,OAAqC;AAClE,QAAI,CAAC,KAAK,SAAS;AACjB,UAAI,KAAK,MAAO,SAAQ,IAAI,oDAA0C;AACtE;AAAA,IACF;AAEA,QAAI;AACF,YAAM,YAAiB,UAAK,KAAK,UAAU,GAAG,WAAW,OAAO;AAChE,MAAG,iBAAc,WAAW,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,OAAO;AAEnE,UAAI,KAAK,OAAO;AACd,gBAAQ,IAAI,8BAAuB,WAAW,EAAE;AAChD,gBAAQ,IAAI,gBAAgB,SAAS,EAAE;AACvC,gBAAQ,IAAI,cAAc,OAAO,KAAK,MAAM,MAAM,EAAE,MAAM,EAAE;AAAA,MAC9D;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,kCAA6B,WAAW,KAAK,KAAK;AAAA,IAClE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,aAAqC;AACpD,QAAI,CAAC,KAAK,QAAS;AAEnB,QAAI;AACF,UAAI,aAAa;AACf,cAAM,YAAiB,UAAK,KAAK,UAAU,GAAG,WAAW,OAAO;AAChE,YAAO,cAAW,SAAS,GAAG;AAC5B,UAAG,cAAW,SAAS;AACvB,cAAI,KAAK,OAAO;AACd,oBAAQ,IAAI,0CAA8B,WAAW,EAAE;AAAA,UACzD;AAAA,QACF;AAAA,MACF,OAAO;AAEL,cAAM,QAAW,eAAY,KAAK,QAAQ;AAC1C,cAAM,QAAQ,CAAC,SAAS;AACtB,cAAI,KAAK,SAAS,OAAO,GAAG;AAC1B,YAAG,cAAgB,UAAK,KAAK,UAAU,IAAI,CAAC;AAAA,UAC9C;AAAA,QACF,CAAC;AACD,YAAI,KAAK,OAAO;AACd,kBAAQ,IAAI,0CAA8B;AAAA,QAC5C;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,oCAA+B,KAAK;AAAA,IACpD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAME;AACA,UAAM,qBAA+B,CAAC;AACtC,QAAI,YAAY;AAEhB,QAAI,KAAK,WAAc,cAAW,KAAK,QAAQ,GAAG;AAChD,YAAM,QAAW,eAAY,KAAK,QAAQ;AAC1C,YAAM,QAAQ,CAAC,SAAS;AACtB,YAAI,KAAK,SAAS,OAAO,GAAG;AAC1B,gBAAM,WAAgB,UAAK,KAAK,UAAU,IAAI;AAC9C,gBAAM,QAAW,YAAS,QAAQ;AAClC,6BAAmB,KAAK,KAAK,QAAQ,SAAS,EAAE,CAAC;AACjD,uBAAa,MAAM;AAAA,QACrB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,SAAS,KAAK;AAAA,MACd,UAAU,KAAK;AAAA,MACf,KAAK,KAAK;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,aAAuC;AACnD,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,QAAI;AACF,YAAM,YAAiB,UAAK,KAAK,UAAU,GAAG,WAAW,OAAO;AAEhE,UAAI,CAAI,cAAW,SAAS,GAAG;AAC7B,eAAO;AAAA,MACT;AAEA,YAAM,QAAW,YAAS,SAAS;AACnC,YAAM,WAAW,KAAK,IAAI,IAAI,MAAM;AAEpC,aAAO,YAAY,KAAK;AAAA,IAC1B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,aAA6C;AAC7D,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,QAAI;AACF,YAAM,YAAiB,UAAK,KAAK,UAAU,GAAG,WAAW,OAAO;AAEhE,UAAI,CAAI,cAAW,SAAS,GAAG;AAC7B,eAAO;AAAA,MACT;AAEA,YAAM,QAAW,YAAS,SAAS;AACnC,aAAO,KAAK,IAAI,IAAI,MAAM;AAAA,IAC5B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC1LO,SAAS,cAAc,UAAyB,CAAC,GAAW;AACjE,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,WAAW;AAAA,IACX;AAAA,IACA,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,IACT,WAAW,CAAC;AAAA,EACd,IAAI;AAEJ,QAAM,QAAQ,SAAS,SAAS;AAEhC,MAAI;AACJ,MAAI;AACJ,MAAI,gBAAsC;AAC1C,MAAI,gBAAmD;AAEvD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,MAAM,eAAe,gBAAgB;AACnC,eAAS;AAGT,UAAI,CAAC,OAAO,MAAM,UAAU;AAC1B,eAAO,MAAM,WAAW;AACxB,YAAI,OAAO;AACT,kBAAQ,IAAI,yCAAoC;AAAA,QAClD;AAAA,MACF;AAGA,qBAAe,IAAI,aAAa,OAAO,KAAK;AAE5C,UAAI,OAAO;AACT,gBAAQ,IAAI,+CAAwC;AACpD,gBAAQ,IAAI,iBAAiB,SAAS,EAAE;AACxC,gBAAQ,IAAI,gBAAgB,QAAQ,EAAE;AACtC,gBAAQ,IAAI,iBAAiB,YAAY,YAAY,UAAU,EAAE;AACjE,gBAAQ,IAAI,oBAAoB,OAAO,KAAK,WAAW,EAAE,MAAM,EAAE;AACjE,gBAAQ,IAAI,aAAa,MAAM,YAAY,QAAQ,YAAY,UAAU,EAAE;AAAA,MAC7E;AAGA,UAAI,OAAO,YAAY,WAAW,OAAO;AAEvC,cAAM,cAA4B,CAAC;AAGnC,eAAO,KAAK,WAAW,EAAE,QAAQ,CAAC,UAAU;AAC1C,gBAAM,WAAW,eAAe,KAAK;AACrC,sBAAY,QAAQ,IAAI;AAAA,YACtB,MAAM,WAAW,MAAM,QAAQ,OAAO,GAAG,CAAC;AAAA,YAC1C,SAAS,CAAC;AAAA,UACZ;AAAA,QACF,CAAC;AAGD,cAAMC,MAAK,MAAM,OAAO,IAAS;AACjC,cAAMC,QAAO,MAAM,OAAO,MAAW;AACrC,cAAM,WAAWA,MAAK,KAAK,OAAO,MAAM,WAAW;AAEnD,YAAID,IAAG,WAAW,QAAQ,GAAG;AAC3B,gBAAM,QAAQA,IAAG,YAAY,QAAQ;AACrC,gBAAM,QAAQ,CAAC,SAAS;AACtB,gBAAI,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,KAAK,GAAG;AACjD,oBAAM,WAAW,KAAK,QAAQ,eAAe,EAAE;AAC/C,oBAAM,WAAW,aAAa,IAAI;AAClC,0BAAY,QAAQ,IAAI;AAAA,gBACtB,MAAM,UAAU,QAAQ;AAAA,gBACxB,SAAS,CAAC;AAAA,cACZ;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAGA,QAAC,OAAe,6BAA6B;AAAA,MAC/C;AAAA,IACF;AAAA,IAEA,gBAAgB,QAAQ;AAGtB,aAAO,MAAM;AACX,eAAO,YAAY,IAAI,yBAAyB,OAAO,KAAK,KAAK,SAAS;AACxE,cAAI,IAAI,WAAW,OAAO;AACxB,iBAAK;AACL;AAAA,UACF;AAEA,cAAI;AAEF,gBAAI,CAAC,eAAe;AAClB,kBAAI,OAAO;AACT,wBAAQ,KAAK,+CAAqC;AAAA,cACpD;AACA,kBAAI,aAAa;AACjB,kBAAI,IAAI,KAAK,UAAU,EAAE,OAAO,4DAA4D,CAAC,CAAC;AAC9F;AAAA,YACF;AAIA,kBAAM,cAA4B,CAAC;AAGnC,mBAAO,KAAK,cAAc,MAAM,EAAE,QAAQ,CAAC,UAAU;AAEnD,oBAAM,WAAW,YAAY,KAAK;AAClC,oBAAM,YAAY,MAAM,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK;AAC5D,oBAAM,UAAU,SAAS,UAAU,MAAM,GAAG,CAAC,EAAE,OAAO,GAAG,GAAG;AAC5D,0BAAY,QAAQ,IAAI;AAAA,gBACtB,MAAM,UAAU,SAAS,IAAI,OAAO;AAAA,gBACpC,SAAS,CAAC;AAAA,cACZ;AAAA,YACF,CAAC;AAGD,kBAAM,YAAY,IAAI,gBAAgB,aAA6B,aAAa,OAAO,MAAM;AAC7F,kBAAM,cAAc,UAAU,SAAS,aAAa;AAEpD,gBAAI,UAAU,gBAAgB,kBAAkB;AAChD,gBAAI,UAAU,+BAA+B,GAAG;AAChD,gBAAI,UAAU,iBAAiB,qCAAqC;AACpE,gBAAI,IAAI,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAE5C,gBAAI,OAAO;AACT,sBAAQ,IAAI,sEAA+D;AAAA,YAC7E;AACA;AAAA,UACF,SAAS,OAAO;AACd,gBAAI,OAAO;AACT,sBAAQ,MAAM,uCAAuC,KAAK;AAAA,YAC5D;AACA,gBAAI,aAAa;AACjB,gBAAI,IAAI,KAAK,UAAU,EAAE,OAAO,yBAAyB,SAAS,OAAO,KAAK,EAAE,CAAC,CAAC;AAAA,UACpF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAEA,MAAM,aAAa;AACjB,UAAI,CAAC,WAAW;AACd,YAAI,OAAO;AACT,kBAAQ,IAAI,6DAAmD;AAAA,QACjE;AAEA,wBAAgB,kBAAkB,aAAa,OAAO,YAAY,UAAU,gBAAgB,YAAY;AACxG;AAAA,MACF;AAEA,YAAM,cAAc,UAAU,gBAAgB,OAAO,YAAY,UAAU,gBAAgB;AAG3F,YAAM,SAAS,MAAM,aAAa,IAAI,WAAW;AACjD,UAAI,QAAQ;AACV,wBAAgB;AAChB;AAAA,MACF;AAGA,UAAI;AACF,YAAI,OAAO;AACT,kBAAQ,IAAI;AAAA,qBAAiB,UAAU,QAAQ,6BAA6B;AAAA,QAC9E;AAGA,cAAM,cAAc,IAAI;AAAA,UACrB,UAAU,YAAoB;AAAA,UAC9B,UAAU,YAAoB;AAAA,UAC9B,UAAU,YAAoB,UAAU;AAAA,UACzC;AAAA,QACF;AAEA,gBAAQ,IAAI,oEAA6D;AAGzE,cAAM,iBAAiB,MAAM,YAAY,yBAAyB,UAAU,SAAS;AAErF,YAAI,eAAe,WAAW,GAAG;AAC/B,kBAAQ,KAAK,iEAAuD;AACpE,0BAAgB,kBAAkB,aAAa,WAAW;AAC1D;AAAA,QACF;AAIA,gBAAQ,IAAI;AAAA,kDAA8C;AAC1D,cAAM,YAAY,IAAI,mBAAiB,UAAU,OAAO,KAAK;AAC7D,cAAM,sBAAsB,UAAU,aAAa,gBAAgB,WAAW;AAC9E,wBAAgB;AAGhB,cAAM,aAAa,IAAI,aAAa,aAAa;AAGjD,YAAI;AACF,gBAAM,yBAAyB,MAAM,YAAY,4BAA4B,UAAU,SAAS;AAEhG,cAAI,uBAAuB,SAAS,GAAG;AACrC,oBAAQ,IAAI;AAAA,8CAA0C;AACtD,4BAAgB,UAAU,qBAAqB,wBAAwB,WAAW;AAElF,gBAAI,SAAS,cAAc,OAAO,GAAG;AACnC,sBAAQ,IAAI,qBAAgB,cAAc,IAAI,0BAA0B;AAAA,YAC1E;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AACd,cAAI,OAAO;AACT,oBAAQ,KAAK,iDAAuC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UAC9G;AAAA,QAEF;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,0CAAqC,KAAK;AACxD,gBAAQ,IAAI,iDAAuC;AAGnD,wBAAgB,kBAAkB,aAAa,WAAW;AAG1D,YAAI,OAAO;AACT,kBAAQ,MAAM,kBAAkB,KAAK;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,eAAe;AAC/B,UAAI,CAAC,eAAe;AAClB,gBAAQ,KAAK,uEAA6D;AAC1E;AAAA,MACF;AAGA,YAAMA,MAAK,MAAM,OAAO,IAAS;AACjC,YAAMC,QAAO,MAAM,OAAO,MAAW;AAErC,YAAM,SAAS,cAAc,OAAO;AACpC,YAAM,eAAeA,MAAK,KAAK,QAAQ,SAAS,eAAe;AAE/D,UAAI,CAACD,IAAG,WAAW,YAAY,GAAG;AAChC,gBAAQ,KAAK,6CAAmC,YAAY;AAC5D;AAAA,MACF;AAEA,YAAM,kBAAkBA,IAAG,aAAa,cAAc,OAAO;AAC7D,YAAM,WAAyB,KAAK,MAAM,eAAe;AAEzD,UAAI,OAAO;AACT,gBAAQ,IAAI;AAAA,kCAA8B,OAAO,KAAK,QAAQ,EAAE,MAAM,UAAU;AAAA,MAClF;AAGA,YAAM,YAAY,IAAI,gBAAgB,UAAU,aAAa,KAAK;AAClE,YAAM,cAAc,UAAU,SAAS,aAAa;AAGpD,YAAM,aAAa,UAAU,eAAe,WAAW;AACvD,UAAI,CAAC,WAAW,OAAO;AACrB,gBAAQ,KAAK,gDAAsC;AACnD,mBAAW,QAAQ,QAAQ,CAAC,MAAM,QAAQ,KAAK,MAAM,CAAC,EAAE,CAAC;AAAA,MAC3D,OAAO;AACL,gBAAQ,IAAI,cAAS,OAAO,KAAK,YAAY,MAAM,EAAE,MAAM,oDAAoD;AAAA,MACjH;AAGA,YAAM,aAAaC,MAAK,KAAK,QAAQ,sBAAsB;AAC3D,MAAAD,IAAG,cAAc,YAAY,KAAK,UAAU,aAAa,MAAM,CAAC,CAAC;AAGjE,YAAM,kBAAkBC,MAAK,KAAK,QAAQ,mBAAmB;AAC7D,MAAAD,IAAG,cAAc,iBAAiB,KAAK,UAAU,cAAc,QAAQ,MAAM,CAAC,CAAC;AAE/E,UAAI,OAAO;AACT,gBAAQ,IAAI,4DAAuD;AACnE,gBAAQ,IAAI,kCAA6B;AACzC,gBAAQ,IAAI,sCAA+B,OAAO,KAAK,YAAY,MAAM,EAAE,MAAM,EAAE;AACnF,gBAAQ,IAAI,2BAAoB,OAAO,KAAK,YAAY,MAAM,EAAE,MAAM,EAAE;AAAA,MAC1E;AAGA,UAAI,iBAAiB,cAAc,OAAO,GAAG;AAC3C,gBAAQ,IAAI;AAAA,iEAA6D;AAEzE,cAAM,mBAAmB,IAAI,gBAAgB,UAAU,aAAa,KAAK;AACzE,cAAM,iBAAiB,iBAAiB,uBAAuB,aAAa;AAG5E,cAAM,aAAaC,MAAK,KAAK,QAAQ,kBAAkB;AACvD,YAAI,CAACD,IAAG,WAAW,UAAU,GAAG;AAC9B,UAAAA,IAAG,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,QAC9C;AAGA,uBAAe,QAAQ,CAAC,WAAW,YAAY;AAC7C,gBAAM,cAAcC,MAAK,KAAK,YAAY,GAAG,OAAO,OAAO;AAC3D,UAAAD,IAAG,cAAc,aAAa,KAAK,UAAU,WAAW,MAAM,CAAC,CAAC;AAEhE,cAAI,OAAO;AACT,oBAAQ,IAAI,qBAAgB,OAAO,UAAU,OAAO,KAAK,UAAU,MAAM,EAAE,MAAM,UAAU;AAAA,UAC7F;AAAA,QACF,CAAC;AAGD,cAAM,eAAe;AAAA,UACnB,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,UACpC,aAAa,WAAW,gBAAgB,OAAO,YAAY,UAAU,gBAAgB;AAAA,UACrF,UAAU,MAAM,KAAK,eAAe,KAAK,CAAC;AAAA,UAC1C,aAAa;AAAA,QACf;AAEA,cAAM,mBAAmBC,MAAK,KAAK,YAAY,YAAY;AAC3D,QAAAD,IAAG,cAAc,kBAAkB,KAAK,UAAU,cAAc,MAAM,CAAC,CAAC;AAExE,YAAI,OAAO;AACT,kBAAQ,IAAI;AAAA,iBAAe,eAAe,IAAI,kCAAkC;AAChF,kBAAQ,IAAI,gBAAgB,UAAU,EAAE;AACxC,kBAAQ,IAAI,gBAAgB,MAAM,KAAK,eAAe,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,QAC5E;AAAA,MACF;AAGA,UAAI,WAAW,WAAW;AACxB,cAAM,gBAAgB,kBAAkB,WAAW;AACnD,cAAM,gBAAgBC,MAAK,KAAK,QAAQ,sBAAsB;AAC9D,QAAAD,IAAG,cAAc,eAAe,aAAa;AAE7C,YAAI,OAAO;AACT,kBAAQ,IAAI,qCAAgC;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAAA,IAEA,qBAAqB;AAEnB,aAAO;AAAA,QACL;AAAA,UACE,KAAK;AAAA,UACL,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,UAAU;AAAA;AAAA;AAAA,2BAGO,QAAQ;AAAA,4BACP,SAAS;AAAA,uBACd,KAAK;AAAA;AAAA;AAAA,UAGlB,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKA,SAAS,kBACP,aACA,aACe;AACf,QAAM,QAAuB;AAAA,IAC3B,SAAS;AAAA,IACT,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AAAA,IACA,QAAQ,CAAC;AAAA,IACT,YAAY;AAAA,MACV,UAAU;AAAA,MACV,WAAW;AAAA,MACX,eAAe;AAAA,MACf,aAAa,OAAO,KAAK,WAAW,EAAE;AAAA,IACxC;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,MACX,aAAa;AAAA,IACf;AAAA,EACF;AAEA,SAAO,QAAQ,WAAW,EAAE,QAAQ,CAAC,CAAC,QAAQ,OAAO,MAAM;AACzD,UAAM,OAAO,MAAM,IAAI;AAAA,MACrB,UAAU,QAAQ,IAAI,CAAC,YAAY;AAAA,QACjC,OAAO;AAAA,QACP,aAAa;AAAA,QACb,OAAO;AAAA,QACP,UAAU;AAAA,QACV,QAAQ;AAAA,MACV,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAKA,SAAS,kBAAkB,QAAqB;AAC9C,QAAM,cAAc,OAAO,KAAK,OAAO,MAAM,EAAE;AAC/C,QAAM,kBAAkB,OAAO,OAAO,OAAO,MAAM,EAAE;AAAA,IACnD,CAAC,KAAa,UAAe,MAAM,MAAM,SAAS;AAAA,IAClD;AAAA,EACF;AAEA,SAAO;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,kBAqDS,OAAO,WAAW;AAAA,oBAChB,OAAO,WAAW;AAAA;AAAA;AAAA;AAAA,gCAIN,WAAW;AAAA;AAAA;AAAA;AAAA,gCAIX,eAAe;AAAA;AAAA;AAAA;AAAA,gCAIf,OAAO,YAAY,eAAe,eAAe,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA,iCAI1D,OAAO,MAAM,YAAY,KAAK,QAAQ,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOnE,OAAO,QAAQ,OAAO,MAAM,EAC3B;AAAA,IACC,CAAC,CAAC,QAAQ,IAAI,MAAqB;AAAA;AAAA,oCAEP,MAAM;AAAA,UAChC,KAAK,SACJ;AAAA,MACC,CAAC,WAAgB;AAAA;AAAA,qBAEb,OAAO,KAAK;AAAA,oCACQ,OAAO,QAAQ;AAAA,kBACjC,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA,IAIjE,EACC,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA,EAGb,EACC,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA;AAIf;","names":["path","path","fs","path"]}