{"version":3,"file":"performance-monitor.mjs","sources":["../../../src/lib/performance/performance-monitor.ts"],"sourcesContent":["/**\n * @file Enhanced Performance Monitor\n * @description Comprehensive real-time performance monitoring system with:\n * - Performance budgets enforcement\n * - Long task detection and reporting\n * - Memory pressure monitoring\n * - Frame rate monitoring\n * - Resource timing analysis\n *\n * This module serves as the central orchestrator for all performance monitoring\n * capabilities, providing a unified API for tracking and reporting performance\n * metrics across the application.\n *\n * @example\n * ```typescript\n * import { PerformanceMonitor } from '@/lib/performance';\n *\n * const monitor = PerformanceMonitor.getInstance();\n * monitor.start();\n *\n * // Subscribe to events\n * monitor.on('longTask', (task) => console.log('Long task detected:', task));\n * monitor.on('budgetViolation', (violation) => console.warn('Budget exceeded:', violation));\n * ```\n */\n\nimport {\n  performanceConfig,\n  type PerformanceConfig,\n  VITAL_THRESHOLDS,\n  meetsVitalThreshold,\n  formatDuration,\n} from '../../config/performance.config';\n\n/**\n * Type for valid vital metric names\n */\ntype VitalMetricName = keyof typeof VITAL_THRESHOLDS;\n\n/**\n * Type guard to check if a string is a valid vital metric name\n */\nfunction isVitalMetricName(metric: string): metric is VitalMetricName {\n  return metric in VITAL_THRESHOLDS;\n}\nimport {\n  isMemoryApiSupported as isMemoryApiAvailable,\n  getPerformanceMemory,\n} from './utils/memory';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Performance monitor event types\n */\nexport type PerformanceEventType =\n  | 'longTask'\n  | 'frameDrop'\n  | 'memoryPressure'\n  | 'budgetViolation'\n  | 'resourceSlow'\n  | 'vitalUpdate'\n  | 'monitorStart'\n  | 'monitorStop';\n\n/**\n * Long task entry with attribution\n */\nexport interface LongTaskEntry {\n  readonly id: string;\n  readonly name: string;\n  readonly startTime: number;\n  readonly duration: number;\n  readonly attribution: LongTaskAttribution[];\n  readonly isCritical: boolean;\n  readonly timestamp: number;\n}\n\n/**\n * Long task attribution (script/container info)\n */\nexport interface LongTaskAttribution {\n  readonly name: string;\n  readonly entryType: string;\n  readonly startTime: number;\n  readonly duration: number;\n  readonly containerType?: string;\n  readonly containerName?: string;\n  readonly containerId?: string;\n  readonly containerSrc?: string;\n}\n\n/**\n * Frame timing entry\n */\nexport interface FrameTimingEntry {\n  readonly timestamp: number;\n  readonly duration: number;\n  readonly dropped: boolean;\n  readonly fps: number;\n}\n\n/**\n * Memory snapshot\n */\nexport interface MemorySnapshot {\n  readonly timestamp: number;\n  readonly usedJSHeapSize: number;\n  readonly totalJSHeapSize: number;\n  readonly jsHeapSizeLimit: number;\n  readonly usagePercentage: number;\n  readonly pressure: 'normal' | 'warning' | 'critical';\n}\n\n/**\n * Budget violation entry\n */\nexport interface BudgetViolation {\n  readonly id: string;\n  readonly budgetType: string;\n  readonly metricName: string;\n  readonly actualValue: number;\n  readonly budgetValue: number;\n  readonly overage: number;\n  readonly overagePercentage: number;\n  readonly severity: 'warning' | 'critical';\n  readonly timestamp: number;\n  readonly url: string;\n}\n\n/**\n * Slow resource entry\n */\nexport interface SlowResourceEntry {\n  readonly name: string;\n  readonly initiatorType: string;\n  readonly duration: number;\n  readonly transferSize: number;\n  readonly startTime: number;\n  readonly threshold: number;\n}\n\n/**\n * Aggregated performance metrics\n */\nexport interface PerformanceMetrics {\n  readonly longTasks: LongTaskEntry[];\n  readonly totalLongTaskTime: number;\n  readonly longTaskCount: number;\n  readonly criticalLongTaskCount: number;\n  readonly frameDrops: number;\n  readonly averageFps: number;\n  readonly memorySnapshots: MemorySnapshot[];\n  readonly currentMemoryPressure: 'normal' | 'warning' | 'critical';\n  readonly budgetViolations: BudgetViolation[];\n  readonly slowResources: SlowResourceEntry[];\n  readonly timestamp: number;\n}\n\n/**\n * Event callback type\n */\nexport type PerformanceEventCallback<T = unknown> = (data: T) => void;\n\n/**\n * Event subscription\n */\ninterface EventSubscription {\n  readonly id: string;\n  readonly type: PerformanceEventType;\n  readonly callback: PerformanceEventCallback;\n}\n\n/**\n * Monitor configuration options\n */\nexport interface PerformanceMonitorOptions {\n  readonly config?: Partial<PerformanceConfig>;\n  readonly autoStart?: boolean;\n  readonly enableLongTaskMonitoring?: boolean;\n  readonly enableMemoryMonitoring?: boolean;\n  readonly enableFrameMonitoring?: boolean;\n  readonly enableResourceMonitoring?: boolean;\n  readonly slowResourceThreshold?: number;\n  readonly debug?: boolean;\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Generate unique ID\n */\nfunction generateId(): string {\n  return `perf_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * Check if PerformanceObserver is supported\n */\nfunction isPerformanceObserverSupported(): boolean {\n  return typeof PerformanceObserver !== 'undefined';\n}\n\n// ============================================================================\n// Performance Monitor Class\n// ============================================================================\n\n/**\n * Comprehensive performance monitoring system\n *\n * Singleton class that orchestrates all performance monitoring activities\n * including long task detection, memory pressure monitoring, frame rate\n * tracking, and budget enforcement.\n */\nexport class PerformanceMonitor {\n  private static instance: PerformanceMonitor | null = null;\n\n  private readonly config: PerformanceConfig;\n  private readonly options: Required<PerformanceMonitorOptions>;\n  private readonly subscriptions: Map<string, EventSubscription> = new Map();\n\n  private isRunning = false;\n  private longTaskObserver: PerformanceObserver | null = null;\n  private resourceObserver: PerformanceObserver | null = null;\n  private frameMonitorId: number | null = null;\n  private memoryMonitorId: ReturnType<typeof setInterval> | null = null;\n\n  private longTasks: LongTaskEntry[] = [];\n  private frameTimings: FrameTimingEntry[] = [];\n  private memorySnapshots: MemorySnapshot[] = [];\n  private budgetViolations: BudgetViolation[] = [];\n  private slowResources: SlowResourceEntry[] = [];\n\n  private lastFrameTime = 0;\n  private frameCount = 0;\n  private droppedFrames = 0;\n\n  /**\n   * Private constructor for singleton pattern\n   */\n  private constructor(options: PerformanceMonitorOptions = {}) {\n    this.config = { ...performanceConfig, ...options.config };\n    this.options = {\n      config: this.config,\n      autoStart: options.autoStart ?? false,\n      enableLongTaskMonitoring: options.enableLongTaskMonitoring ?? true,\n      enableMemoryMonitoring: options.enableMemoryMonitoring ?? true,\n      enableFrameMonitoring: options.enableFrameMonitoring ?? true,\n      enableResourceMonitoring: options.enableResourceMonitoring ?? true,\n      slowResourceThreshold: options.slowResourceThreshold ?? 1000,\n      debug: options.debug ?? this.config.monitoring.debug,\n    };\n\n    if (this.options.autoStart) {\n      this.start();\n    }\n  }\n\n  /**\n   * Get singleton instance\n   */\n  public static getInstance(options?: PerformanceMonitorOptions): PerformanceMonitor {\n    PerformanceMonitor.instance ??= new PerformanceMonitor(options);\n    return PerformanceMonitor.instance;\n  }\n\n  /**\n   * Reset singleton instance (mainly for testing)\n   */\n  public static resetInstance(): void {\n    if (PerformanceMonitor.instance) {\n      PerformanceMonitor.instance.stop();\n      PerformanceMonitor.instance = null;\n    }\n  }\n\n  // ==========================================================================\n  // Lifecycle Methods\n  // ==========================================================================\n\n  /**\n   * Start all performance monitoring\n   */\n  public start(): void {\n    if (this.isRunning) {\n      this.log('Monitor already running');\n      return;\n    }\n\n    this.log('Starting performance monitor');\n    this.isRunning = true;\n\n    if (this.options.enableLongTaskMonitoring) {\n      this.startLongTaskMonitoring();\n    }\n\n    if (this.options.enableMemoryMonitoring) {\n      this.startMemoryMonitoring();\n    }\n\n    if (this.options.enableFrameMonitoring) {\n      this.startFrameMonitoring();\n    }\n\n    if (this.options.enableResourceMonitoring) {\n      this.startResourceMonitoring();\n    }\n\n    this.emit('monitorStart', { timestamp: Date.now() });\n  }\n\n  /**\n   * Stop all performance monitoring\n   */\n  public stop(): void {\n    if (!this.isRunning) {\n      return;\n    }\n\n    this.log('Stopping performance monitor');\n    this.isRunning = false;\n\n    this.stopLongTaskMonitoring();\n    this.stopMemoryMonitoring();\n    this.stopFrameMonitoring();\n    this.stopResourceMonitoring();\n\n    this.emit('monitorStop', { timestamp: Date.now() });\n  }\n\n  /**\n   * Reset all collected metrics\n   */\n  public reset(): void {\n    this.longTasks = [];\n    this.frameTimings = [];\n    this.memorySnapshots = [];\n    this.budgetViolations = [];\n    this.slowResources = [];\n    this.frameCount = 0;\n    this.droppedFrames = 0;\n    this.lastFrameTime = 0;\n\n    this.log('Metrics reset');\n  }\n\n  // ==========================================================================\n  // Long Task Monitoring\n  // ==========================================================================\n\n  /**\n   * Get current memory pressure level\n   */\n  public getMemoryPressure(): 'normal' | 'warning' | 'critical' {\n    const snapshot = this.captureMemorySnapshot();\n    return snapshot?.pressure ?? 'normal';\n  }\n\n  /**\n   * Get current FPS\n   */\n  public getCurrentFps(): number {\n    if (this.frameTimings.length === 0) return 60;\n    const recent = this.frameTimings.slice(-10);\n    const avgFps = recent.reduce((sum, f) => sum + f.fps, 0) / recent.length;\n    return Math.round(avgFps);\n  }\n\n  /**\n   * Check a custom budget\n   */\n  public checkBudget(\n    budgetType: string,\n    metricName: string,\n    actualValue: number,\n    budgetValue: number,\n    severity: 'warning' | 'critical' = 'warning'\n  ): boolean {\n    const isViolated = actualValue > budgetValue;\n\n    if (isViolated) {\n      this.recordBudgetViolation({\n        budgetType,\n        metricName,\n        actualValue,\n        budgetValue,\n        severity,\n      });\n    }\n\n    return !isViolated;\n  }\n\n  // ==========================================================================\n  // Memory Monitoring\n  // ==========================================================================\n\n  /**\n   * Check Core Web Vital against threshold\n   */\n  public checkVitalBudget(metric: string, value: number): 'good' | 'needs-improvement' | 'poor' {\n    // Validate metric is a known vital threshold\n    if (!isVitalMetricName(metric)) {\n      this.log(`Unknown vital metric: ${String(metric)}`);\n      return 'poor';\n    }\n\n    const rating = meetsVitalThreshold(metric as import('./vitals').VitalMetricName, value);\n    const vitalThreshold = VITAL_THRESHOLDS[metric as import('./vitals').VitalMetricName];\n    const budgetValue = vitalThreshold?.good ?? 0;\n\n    if (rating === 'poor') {\n      this.recordBudgetViolation({\n        budgetType: 'vital',\n        metricName: metric,\n        actualValue: value,\n        budgetValue,\n        severity: 'critical',\n      });\n    } else if (rating === 'needs-improvement') {\n      this.recordBudgetViolation({\n        budgetType: 'vital',\n        metricName: metric,\n        actualValue: value,\n        budgetValue,\n        severity: 'warning',\n      });\n    }\n\n    this.emit('vitalUpdate', { metric, value, rating });\n    return rating;\n  }\n\n  /**\n   * Subscribe to performance events\n   */\n  public on<T = unknown>(\n    type: PerformanceEventType,\n    callback: PerformanceEventCallback<T>\n  ): () => void {\n    const id = generateId();\n    const subscription: EventSubscription = {\n      id,\n      type,\n      callback: callback as PerformanceEventCallback,\n    };\n\n    this.subscriptions.set(id, subscription);\n\n    // Return unsubscribe function\n    return () => {\n      this.subscriptions.delete(id);\n    };\n  }\n\n  /**\n   * Get aggregated performance metrics\n   */\n  public getMetrics(): PerformanceMetrics {\n    const totalLongTaskTime = this.longTasks.reduce((sum, t) => sum + t.duration, 0);\n    const criticalLongTaskCount = this.longTasks.filter((t) => t.isCritical).length;\n\n    return {\n      longTasks: [...this.longTasks],\n      totalLongTaskTime,\n      longTaskCount: this.longTasks.length,\n      criticalLongTaskCount,\n      frameDrops: this.droppedFrames,\n      averageFps: this.getCurrentFps(),\n      memorySnapshots: [...this.memorySnapshots],\n      currentMemoryPressure: this.getMemoryPressure(),\n      budgetViolations: [...this.budgetViolations],\n      slowResources: [...this.slowResources],\n      timestamp: Date.now(),\n    };\n  }\n\n  /**\n   * Get long tasks\n   */\n  public getLongTasks(): LongTaskEntry[] {\n    return [...this.longTasks];\n  }\n\n  // ==========================================================================\n  // Frame Rate Monitoring\n  // ==========================================================================\n\n  /**\n   * Get budget violations\n   */\n  public getBudgetViolations(): BudgetViolation[] {\n    return [...this.budgetViolations];\n  }\n\n  /**\n   * Get slow resources\n   */\n  public getSlowResources(): SlowResourceEntry[] {\n    return [...this.slowResources];\n  }\n\n  /**\n   * Get memory snapshots\n   */\n  public getMemorySnapshots(): MemorySnapshot[] {\n    return [...this.memorySnapshots];\n  }\n\n  /**\n   * Check if monitoring is running\n   */\n  public isMonitoring(): boolean {\n    return this.isRunning;\n  }\n\n  // ==========================================================================\n  // Resource Monitoring\n  // ==========================================================================\n\n  /**\n   * Generate performance report\n   */\n  public generateReport(): string {\n    const metrics = this.getMetrics();\n\n    const lines = [\n      '='.repeat(60),\n      'PERFORMANCE MONITOR REPORT',\n      '='.repeat(60),\n      '',\n      `Generated: ${new Date().toISOString()}`,\n      `URL: ${typeof window !== 'undefined' ? window.location.href : 'N/A'}`,\n      '',\n      '--- Long Tasks ---',\n      `Total Count: ${metrics.longTaskCount}`,\n      `Critical Count: ${metrics.criticalLongTaskCount}`,\n      `Total Blocking Time: ${formatDuration(metrics.totalLongTaskTime)}`,\n      '',\n      '--- Frame Rate ---',\n      `Average FPS: ${metrics.averageFps}`,\n      `Dropped Frames: ${metrics.frameDrops}`,\n      '',\n      '--- Memory ---',\n      `Current Pressure: ${metrics.currentMemoryPressure}`,\n      `Snapshots: ${metrics.memorySnapshots.length}`,\n      '',\n      '--- Budget Violations ---',\n      `Total Violations: ${metrics.budgetViolations.length}`,\n      ...metrics.budgetViolations.slice(-5).map(\n        (v) => `  - ${v.metricName}: ${v.actualValue} (budget: ${v.budgetValue})`\n      ),\n      '',\n      '--- Slow Resources ---',\n      `Total: ${metrics.slowResources.length}`,\n      ...metrics.slowResources.slice(-5).map(\n        (r) => `  - ${r.name.split('/').pop()}: ${formatDuration(r.duration)}`\n      ),\n      '',\n      '='.repeat(60),\n    ];\n\n    return lines.join('\\n');\n  }\n\n  /**\n   * Start long task monitoring\n   */\n  private startLongTaskMonitoring(): void {\n    if (!isPerformanceObserverSupported()) {\n      this.log('PerformanceObserver not supported, skipping long task monitoring');\n      return;\n    }\n\n    try {\n      this.longTaskObserver = new PerformanceObserver((list) => {\n        const entries = list.getEntries();\n\n        entries.forEach((entry) => {\n          const taskEntry = this.processLongTask(entry);\n          if (taskEntry) {\n            this.longTasks.push(taskEntry);\n            this.trimBuffer(this.longTasks, this.config.longTask.historyBufferSize);\n            this.emit('longTask', taskEntry);\n\n            // Check if budget is exceeded\n            if (this.longTasks.length > this.config.longTask.maxPerPageLoad) {\n              this.recordBudgetViolation({\n                budgetType: 'longTask',\n                metricName: 'longTaskCount',\n                actualValue: this.longTasks.length,\n                budgetValue: this.config.longTask.maxPerPageLoad,\n                severity: 'warning',\n              });\n            }\n          }\n        });\n      });\n\n      this.longTaskObserver.observe({ entryTypes: ['longtask'] });\n      this.log('Long task monitoring started');\n    } catch (error) {\n      this.log('Failed to start long task monitoring:', error);\n    }\n  }\n\n  // ==========================================================================\n  // Budget Enforcement\n  // ==========================================================================\n\n  /**\n   * Stop long task monitoring\n   */\n  private stopLongTaskMonitoring(): void {\n    if (this.longTaskObserver) {\n      this.longTaskObserver.disconnect();\n      this.longTaskObserver = null;\n    }\n  }\n\n  /**\n   * Process a long task entry\n   */\n  private processLongTask(entry: PerformanceEntry): LongTaskEntry | null {\n    const {duration} = entry;\n    const isCritical = duration >= this.config.longTask.criticalThreshold;\n\n    // Extract attribution if available\n    const attribution: LongTaskAttribution[] = [];\n    const entryWithAttribution = entry as PerformanceEntry & {\n      attribution?: Array<{\n        name?: string;\n        entryType?: string;\n        startTime?: number;\n        duration?: number;\n        containerType?: string;\n        containerName?: string;\n        containerId?: string;\n        containerSrc?: string;\n      }>;\n    };\n\n    if (entryWithAttribution.attribution) {\n      entryWithAttribution.attribution.forEach((attr) => {\n        attribution.push({\n          name: attr.name ?? 'unknown',\n          entryType: attr.entryType ?? 'unknown',\n          startTime: attr.startTime ?? 0,\n          duration: attr.duration ?? 0,\n          containerType: attr.containerType,\n          containerName: attr.containerName,\n          containerId: attr.containerId,\n          containerSrc: attr.containerSrc,\n        });\n      });\n    }\n\n    return {\n      id: generateId(),\n      name: entry.name,\n      startTime: entry.startTime,\n      duration,\n      attribution,\n      isCritical,\n      timestamp: Date.now(),\n    };\n  }\n\n  /**\n   * Start memory monitoring\n   */\n  private startMemoryMonitoring(): void {\n    if (!isMemoryApiAvailable()) {\n      this.log('Memory API not available, skipping memory monitoring');\n      return;\n    }\n\n    this.memoryMonitorId = setInterval(() => {\n      const snapshot = this.captureMemorySnapshot();\n      if (snapshot) {\n        this.memorySnapshots.push(snapshot);\n        this.trimBuffer(this.memorySnapshots, 100);\n\n        if (snapshot.pressure !== 'normal') {\n          this.emit('memoryPressure', snapshot);\n\n          if (snapshot.pressure === 'critical') {\n            this.recordBudgetViolation({\n              budgetType: 'memory',\n              metricName: 'heapUsage',\n              actualValue: snapshot.usagePercentage,\n              budgetValue: this.config.memory.criticalThreshold,\n              severity: 'critical',\n            });\n          }\n        }\n      }\n    }, this.config.memory.pollingInterval);\n\n    this.log('Memory monitoring started');\n  }\n\n  // ==========================================================================\n  // Event System\n  // ==========================================================================\n\n  /**\n   * Stop memory monitoring\n   */\n  private stopMemoryMonitoring(): void {\n    if (this.memoryMonitorId) {\n      clearInterval(this.memoryMonitorId);\n      this.memoryMonitorId = null;\n    }\n  }\n\n  /**\n   * Capture memory snapshot\n   */\n  private captureMemorySnapshot(): MemorySnapshot | null {\n    const memory = getPerformanceMemory();\n    if (!memory) return null;\n\n    const usagePercentage = memory.usedJSHeapSize / memory.jsHeapSizeLimit;\n    let pressure: 'normal' | 'warning' | 'critical' = 'normal';\n\n    if (usagePercentage >= this.config.memory.criticalThreshold) {\n      pressure = 'critical';\n    } else if (usagePercentage >= this.config.memory.warningThreshold) {\n      pressure = 'warning';\n    }\n\n    return {\n      timestamp: Date.now(),\n      usedJSHeapSize: memory.usedJSHeapSize,\n      totalJSHeapSize: memory.totalJSHeapSize,\n      jsHeapSizeLimit: memory.jsHeapSizeLimit,\n      usagePercentage,\n      pressure,\n    };\n  }\n\n  // ==========================================================================\n  // Metrics Access\n  // ==========================================================================\n\n  /**\n   * Start frame rate monitoring\n   */\n  private startFrameMonitoring(): void {\n    if (typeof requestAnimationFrame === 'undefined') {\n      this.log('requestAnimationFrame not available, skipping frame monitoring');\n      return;\n    }\n\n    this.lastFrameTime = performance.now();\n    this.frameLoop();\n    this.log('Frame monitoring started');\n  }\n\n  /**\n   * Stop frame rate monitoring\n   */\n  private stopFrameMonitoring(): void {\n    if (this.frameMonitorId !== null) {\n      cancelAnimationFrame(this.frameMonitorId);\n      this.frameMonitorId = null;\n    }\n  }\n\n  /**\n   * Frame loop for FPS monitoring\n   */\n  private frameLoop = (): void => {\n    if (!this.isRunning) return;\n\n    const now = performance.now();\n    const delta = now - this.lastFrameTime;\n    this.lastFrameTime = now;\n\n    this.frameCount++;\n\n    // Detect dropped frames (> 2x frame budget indicates dropped frame)\n    const dropped = delta > this.config.runtime.frameBudget * 2;\n    if (dropped) {\n      this.droppedFrames++;\n      this.emit('frameDrop', {\n        duration: delta,\n        expected: this.config.runtime.frameBudget,\n        timestamp: now,\n      });\n    }\n\n    // Record frame timing periodically (every 60 frames)\n    if (this.frameCount % 60 === 0) {\n      const fps = 1000 / delta;\n      const entry: FrameTimingEntry = {\n        timestamp: now,\n        duration: delta,\n        dropped,\n        fps: Math.round(fps),\n      };\n      this.frameTimings.push(entry);\n      this.trimBuffer(this.frameTimings, 100);\n    }\n\n    this.frameMonitorId = requestAnimationFrame(this.frameLoop);\n  };\n\n  /**\n   * Start resource monitoring\n   */\n  private startResourceMonitoring(): void {\n    if (!isPerformanceObserverSupported()) {\n      return;\n    }\n\n    try {\n      this.resourceObserver = new PerformanceObserver((list) => {\n        const entries = list.getEntries() as PerformanceResourceTiming[];\n\n        entries.forEach((entry) => {\n          if (entry.duration > this.options.slowResourceThreshold) {\n            const slowEntry: SlowResourceEntry = {\n              name: entry.name,\n              initiatorType: entry.initiatorType,\n              duration: entry.duration,\n              transferSize: entry.transferSize,\n              startTime: entry.startTime,\n              threshold: this.options.slowResourceThreshold,\n            };\n\n            this.slowResources.push(slowEntry);\n            this.trimBuffer(this.slowResources, 50);\n            this.emit('resourceSlow', slowEntry);\n          }\n        });\n      });\n\n      this.resourceObserver.observe({ entryTypes: ['resource'] });\n      this.log('Resource monitoring started');\n    } catch (error) {\n      this.log('Failed to start resource monitoring:', error);\n    }\n  }\n\n  /**\n   * Stop resource monitoring\n   */\n  private stopResourceMonitoring(): void {\n    if (this.resourceObserver) {\n      this.resourceObserver.disconnect();\n      this.resourceObserver = null;\n    }\n  }\n\n  /**\n   * Record a budget violation\n   */\n  private recordBudgetViolation(violation: Omit<BudgetViolation, 'id' | 'overage' | 'overagePercentage' | 'timestamp' | 'url'>): void {\n    const entry: BudgetViolation = {\n      id: generateId(),\n      ...violation,\n      overage: violation.actualValue - violation.budgetValue,\n      overagePercentage: ((violation.actualValue - violation.budgetValue) / violation.budgetValue) * 100,\n      timestamp: Date.now(),\n      url: typeof window !== 'undefined' ? window.location.href : '',\n    };\n\n    this.budgetViolations.push(entry);\n    this.trimBuffer(this.budgetViolations, 100);\n    this.emit('budgetViolation', entry);\n  }\n\n  // ==========================================================================\n  // Utilities\n  // ==========================================================================\n\n  /**\n   * Emit performance event\n   */\n  private emit<T>(type: PerformanceEventType, data: T): void {\n    this.subscriptions.forEach((subscription) => {\n      if (subscription.type === type) {\n        try {\n          subscription.callback(data);\n        } catch (error) {\n          this.log(`Error in event handler for ${type}:`, error);\n        }\n      }\n    });\n  }\n\n  /**\n   * Trim buffer to max size\n   */\n  private trimBuffer<T>(buffer: T[], maxSize: number): void {\n    if (buffer.length > maxSize) {\n      buffer.splice(0, buffer.length - maxSize);\n    }\n  }\n\n  /**\n   * Debug logging\n   */\n  private log(message: string, ...args: unknown[]): void {\n    if (this.options.debug) {\n      console.info(`[PerformanceMonitor] ${message}`, ...args);\n    }\n  }\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Get the singleton PerformanceMonitor instance\n */\nexport function getPerformanceMonitor(\n  options?: PerformanceMonitorOptions\n): PerformanceMonitor {\n  return PerformanceMonitor.getInstance(options);\n}\n\n/**\n * Start performance monitoring with default options\n */\nexport function startPerformanceMonitoring(\n  options?: PerformanceMonitorOptions\n): PerformanceMonitor {\n  const monitor = getPerformanceMonitor(options);\n  monitor.start();\n  return monitor;\n}\n\n/**\n * Stop performance monitoring\n */\nexport function stopPerformanceMonitoring(): void {\n  const monitor = getPerformanceMonitor();\n  monitor.stop();\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n"],"names":["isVitalMetricName","metric","VITAL_THRESHOLDS","generateId","isPerformanceObserverSupported","PerformanceMonitor","options","performanceConfig","recent","avgFps","sum","f","budgetType","metricName","actualValue","budgetValue","severity","isViolated","value","rating","meetsVitalThreshold","type","callback","id","subscription","totalLongTaskTime","t","criticalLongTaskCount","metrics","formatDuration","v","r","list","entry","taskEntry","error","duration","isCritical","attribution","entryWithAttribution","attr","isMemoryApiAvailable","snapshot","memory","getPerformanceMemory","usagePercentage","pressure","now","delta","dropped","fps","slowEntry","violation","data","buffer","maxSize","message","args","getPerformanceMonitor","startPerformanceMonitoring","monitor","stopPerformanceMonitoring"],"mappings":";;AA0CA,SAASA,EAAkBC,GAA2C;AACpE,SAAOA,KAAUC;AACnB;AAwJA,SAASC,IAAqB;AAC5B,SAAO,QAAQ,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC;AACtE;AAKA,SAASC,IAA0C;AACjD,SAAO,OAAO,sBAAwB;AACxC;AAaO,MAAMC,EAAmB;AAAA,EAC9B,OAAe,WAAsC;AAAA,EAEpC;AAAA,EACA;AAAA,EACA,oCAAoD,IAAA;AAAA,EAE7D,YAAY;AAAA,EACZ,mBAA+C;AAAA,EAC/C,mBAA+C;AAAA,EAC/C,iBAAgC;AAAA,EAChC,kBAAyD;AAAA,EAEzD,YAA6B,CAAA;AAAA,EAC7B,eAAmC,CAAA;AAAA,EACnC,kBAAoC,CAAA;AAAA,EACpC,mBAAsC,CAAA;AAAA,EACtC,gBAAqC,CAAA;AAAA,EAErC,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAKhB,YAAYC,IAAqC,IAAI;AAC3D,SAAK,SAAS,EAAE,GAAGC,GAAmB,GAAGD,EAAQ,OAAA,GACjD,KAAK,UAAU;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,WAAWA,EAAQ,aAAa;AAAA,MAChC,0BAA0BA,EAAQ,4BAA4B;AAAA,MAC9D,wBAAwBA,EAAQ,0BAA0B;AAAA,MAC1D,uBAAuBA,EAAQ,yBAAyB;AAAA,MACxD,0BAA0BA,EAAQ,4BAA4B;AAAA,MAC9D,uBAAuBA,EAAQ,yBAAyB;AAAA,MACxD,OAAOA,EAAQ,SAAS,KAAK,OAAO,WAAW;AAAA,IAAA,GAG7C,KAAK,QAAQ,aACf,KAAK,MAAA;AAAA,EAET;AAAA;AAAA;AAAA;AAAA,EAKA,OAAc,YAAYA,GAAyD;AACjF,WAAAD,EAAmB,aAAa,IAAIA,EAAmBC,CAAO,GACvDD,EAAmB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAc,gBAAsB;AAClC,IAAIA,EAAmB,aACrBA,EAAmB,SAAS,KAAA,GAC5BA,EAAmB,WAAW;AAAA,EAElC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,QAAc;AACnB,QAAI,KAAK,WAAW;AAClB,WAAK,IAAI,yBAAyB;AAClC;AAAA,IACF;AAEA,SAAK,IAAI,8BAA8B,GACvC,KAAK,YAAY,IAEb,KAAK,QAAQ,4BACf,KAAK,wBAAA,GAGH,KAAK,QAAQ,0BACf,KAAK,sBAAA,GAGH,KAAK,QAAQ,yBACf,KAAK,qBAAA,GAGH,KAAK,QAAQ,4BACf,KAAK,wBAAA,GAGP,KAAK,KAAK,gBAAgB,EAAE,WAAW,KAAK,IAAA,GAAO;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKO,OAAa;AAClB,IAAK,KAAK,cAIV,KAAK,IAAI,8BAA8B,GACvC,KAAK,YAAY,IAEjB,KAAK,uBAAA,GACL,KAAK,qBAAA,GACL,KAAK,oBAAA,GACL,KAAK,uBAAA,GAEL,KAAK,KAAK,eAAe,EAAE,WAAW,KAAK,IAAA,GAAO;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKO,QAAc;AACnB,SAAK,YAAY,CAAA,GACjB,KAAK,eAAe,CAAA,GACpB,KAAK,kBAAkB,CAAA,GACvB,KAAK,mBAAmB,CAAA,GACxB,KAAK,gBAAgB,CAAA,GACrB,KAAK,aAAa,GAClB,KAAK,gBAAgB,GACrB,KAAK,gBAAgB,GAErB,KAAK,IAAI,eAAe;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,oBAAuD;AAE5D,WADiB,KAAK,sBAAA,GACL,YAAY;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKO,gBAAwB;AAC7B,QAAI,KAAK,aAAa,WAAW,EAAG,QAAO;AAC3C,UAAMG,IAAS,KAAK,aAAa,MAAM,GAAG,GACpCC,IAASD,EAAO,OAAO,CAACE,GAAKC,MAAMD,IAAMC,EAAE,KAAK,CAAC,IAAIH,EAAO;AAClE,WAAO,KAAK,MAAMC,CAAM;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKO,YACLG,GACAC,GACAC,GACAC,GACAC,IAAmC,WAC1B;AACT,UAAMC,IAAaH,IAAcC;AAEjC,WAAIE,KACF,KAAK,sBAAsB;AAAA,MACzB,YAAAL;AAAA,MACA,YAAAC;AAAA,MACA,aAAAC;AAAA,MACA,aAAAC;AAAA,MACA,UAAAC;AAAA,IAAA,CACD,GAGI,CAACC;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,iBAAiBhB,GAAgBiB,GAAsD;AAE5F,QAAI,CAAClB,EAAkBC,CAAM;AAC3B,kBAAK,IAAI,yBAAyB,OAAOA,CAAM,CAAC,EAAE,GAC3C;AAGT,UAAMkB,IAASC,EAAoBnB,GAA8CiB,CAAK,GAEhFH,IADiBb,EAAiBD,CAA4C,GAChD,QAAQ;AAE5C,WAAIkB,MAAW,SACb,KAAK,sBAAsB;AAAA,MACzB,YAAY;AAAA,MACZ,YAAYlB;AAAA,MACZ,aAAaiB;AAAA,MACb,aAAAH;AAAA,MACA,UAAU;AAAA,IAAA,CACX,IACQI,MAAW,uBACpB,KAAK,sBAAsB;AAAA,MACzB,YAAY;AAAA,MACZ,YAAYlB;AAAA,MACZ,aAAaiB;AAAA,MACb,aAAAH;AAAA,MACA,UAAU;AAAA,IAAA,CACX,GAGH,KAAK,KAAK,eAAe,EAAE,QAAAd,GAAQ,OAAAiB,GAAO,QAAAC,GAAQ,GAC3CA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,GACLE,GACAC,GACY;AACZ,UAAMC,IAAKpB,EAAA,GACLqB,IAAkC;AAAA,MACtC,IAAAD;AAAA,MACA,MAAAF;AAAA,MACA,UAAAC;AAAA,IAAA;AAGF,gBAAK,cAAc,IAAIC,GAAIC,CAAY,GAGhC,MAAM;AACX,WAAK,cAAc,OAAOD,CAAE;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,aAAiC;AACtC,UAAME,IAAoB,KAAK,UAAU,OAAO,CAACf,GAAKgB,MAAMhB,IAAMgB,EAAE,UAAU,CAAC,GACzEC,IAAwB,KAAK,UAAU,OAAO,CAACD,MAAMA,EAAE,UAAU,EAAE;AAEzE,WAAO;AAAA,MACL,WAAW,CAAC,GAAG,KAAK,SAAS;AAAA,MAC7B,mBAAAD;AAAA,MACA,eAAe,KAAK,UAAU;AAAA,MAC9B,uBAAAE;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,YAAY,KAAK,cAAA;AAAA,MACjB,iBAAiB,CAAC,GAAG,KAAK,eAAe;AAAA,MACzC,uBAAuB,KAAK,kBAAA;AAAA,MAC5B,kBAAkB,CAAC,GAAG,KAAK,gBAAgB;AAAA,MAC3C,eAAe,CAAC,GAAG,KAAK,aAAa;AAAA,MACrC,WAAW,KAAK,IAAA;AAAA,IAAI;AAAA,EAExB;AAAA;AAAA;AAAA;AAAA,EAKO,eAAgC;AACrC,WAAO,CAAC,GAAG,KAAK,SAAS;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,sBAAyC;AAC9C,WAAO,CAAC,GAAG,KAAK,gBAAgB;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKO,mBAAwC;AAC7C,WAAO,CAAC,GAAG,KAAK,aAAa;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKO,qBAAuC;AAC5C,WAAO,CAAC,GAAG,KAAK,eAAe;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKO,eAAwB;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,iBAAyB;AAC9B,UAAMC,IAAU,KAAK,WAAA;AAsCrB,WApCc;AAAA,MACZ,IAAI,OAAO,EAAE;AAAA,MACb;AAAA,MACA,IAAI,OAAO,EAAE;AAAA,MACb;AAAA,MACA,eAAc,oBAAI,KAAA,GAAO,aAAa;AAAA,MACtC,QAAQ,OAAO,SAAW,MAAc,OAAO,SAAS,OAAO,KAAK;AAAA,MACpE;AAAA,MACA;AAAA,MACA,gBAAgBA,EAAQ,aAAa;AAAA,MACrC,mBAAmBA,EAAQ,qBAAqB;AAAA,MAChD,wBAAwBC,EAAeD,EAAQ,iBAAiB,CAAC;AAAA,MACjE;AAAA,MACA;AAAA,MACA,gBAAgBA,EAAQ,UAAU;AAAA,MAClC,mBAAmBA,EAAQ,UAAU;AAAA,MACrC;AAAA,MACA;AAAA,MACA,qBAAqBA,EAAQ,qBAAqB;AAAA,MAClD,cAAcA,EAAQ,gBAAgB,MAAM;AAAA,MAC5C;AAAA,MACA;AAAA,MACA,qBAAqBA,EAAQ,iBAAiB,MAAM;AAAA,MACpD,GAAGA,EAAQ,iBAAiB,MAAM,EAAE,EAAE;AAAA,QACpC,CAACE,MAAM,OAAOA,EAAE,UAAU,KAAKA,EAAE,WAAW,aAAaA,EAAE,WAAW;AAAA,MAAA;AAAA,MAExE;AAAA,MACA;AAAA,MACA,UAAUF,EAAQ,cAAc,MAAM;AAAA,MACtC,GAAGA,EAAQ,cAAc,MAAM,EAAE,EAAE;AAAA,QACjC,CAACG,MAAM,OAAOA,EAAE,KAAK,MAAM,GAAG,EAAE,IAAA,CAAK,KAAKF,EAAeE,EAAE,QAAQ,CAAC;AAAA,MAAA;AAAA,MAEtE;AAAA,MACA,IAAI,OAAO,EAAE;AAAA,IAAA,EAGF,KAAK;AAAA,CAAI;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKQ,0BAAgC;AACtC,QAAI,CAAC3B,KAAkC;AACrC,WAAK,IAAI,kEAAkE;AAC3E;AAAA,IACF;AAEA,QAAI;AACF,WAAK,mBAAmB,IAAI,oBAAoB,CAAC4B,MAAS;AAGxD,QAFgBA,EAAK,WAAA,EAEb,QAAQ,CAACC,MAAU;AACzB,gBAAMC,IAAY,KAAK,gBAAgBD,CAAK;AAC5C,UAAIC,MACF,KAAK,UAAU,KAAKA,CAAS,GAC7B,KAAK,WAAW,KAAK,WAAW,KAAK,OAAO,SAAS,iBAAiB,GACtE,KAAK,KAAK,YAAYA,CAAS,GAG3B,KAAK,UAAU,SAAS,KAAK,OAAO,SAAS,kBAC/C,KAAK,sBAAsB;AAAA,YACzB,YAAY;AAAA,YACZ,YAAY;AAAA,YACZ,aAAa,KAAK,UAAU;AAAA,YAC5B,aAAa,KAAK,OAAO,SAAS;AAAA,YAClC,UAAU;AAAA,UAAA,CACX;AAAA,QAGP,CAAC;AAAA,MACH,CAAC,GAED,KAAK,iBAAiB,QAAQ,EAAE,YAAY,CAAC,UAAU,GAAG,GAC1D,KAAK,IAAI,8BAA8B;AAAA,IACzC,SAASC,GAAO;AACd,WAAK,IAAI,yCAAyCA,CAAK;AAAA,IACzD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,yBAA+B;AACrC,IAAI,KAAK,qBACP,KAAK,iBAAiB,WAAA,GACtB,KAAK,mBAAmB;AAAA,EAE5B;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgBF,GAA+C;AACrE,UAAM,EAAC,UAAAG,MAAYH,GACbI,IAAaD,KAAY,KAAK,OAAO,SAAS,mBAG9CE,IAAqC,CAAA,GACrCC,IAAuBN;AAa7B,WAAIM,EAAqB,eACvBA,EAAqB,YAAY,QAAQ,CAACC,MAAS;AACjD,MAAAF,EAAY,KAAK;AAAA,QACf,MAAME,EAAK,QAAQ;AAAA,QACnB,WAAWA,EAAK,aAAa;AAAA,QAC7B,WAAWA,EAAK,aAAa;AAAA,QAC7B,UAAUA,EAAK,YAAY;AAAA,QAC3B,eAAeA,EAAK;AAAA,QACpB,eAAeA,EAAK;AAAA,QACpB,aAAaA,EAAK;AAAA,QAClB,cAAcA,EAAK;AAAA,MAAA,CACpB;AAAA,IACH,CAAC,GAGI;AAAA,MACL,IAAIrC,EAAA;AAAA,MACJ,MAAM8B,EAAM;AAAA,MACZ,WAAWA,EAAM;AAAA,MACjB,UAAAG;AAAA,MACA,aAAAE;AAAA,MACA,YAAAD;AAAA,MACA,WAAW,KAAK,IAAA;AAAA,IAAI;AAAA,EAExB;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAA8B;AACpC,QAAI,CAACI,KAAwB;AAC3B,WAAK,IAAI,sDAAsD;AAC/D;AAAA,IACF;AAEA,SAAK,kBAAkB,YAAY,MAAM;AACvC,YAAMC,IAAW,KAAK,sBAAA;AACtB,MAAIA,MACF,KAAK,gBAAgB,KAAKA,CAAQ,GAClC,KAAK,WAAW,KAAK,iBAAiB,GAAG,GAErCA,EAAS,aAAa,aACxB,KAAK,KAAK,kBAAkBA,CAAQ,GAEhCA,EAAS,aAAa,cACxB,KAAK,sBAAsB;AAAA,QACzB,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,aAAaA,EAAS;AAAA,QACtB,aAAa,KAAK,OAAO,OAAO;AAAA,QAChC,UAAU;AAAA,MAAA,CACX;AAAA,IAIT,GAAG,KAAK,OAAO,OAAO,eAAe,GAErC,KAAK,IAAI,2BAA2B;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,uBAA6B;AACnC,IAAI,KAAK,oBACP,cAAc,KAAK,eAAe,GAClC,KAAK,kBAAkB;AAAA,EAE3B;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAA+C;AACrD,UAAMC,IAASC,EAAA;AACf,QAAI,CAACD,EAAQ,QAAO;AAEpB,UAAME,IAAkBF,EAAO,iBAAiBA,EAAO;AACvD,QAAIG,IAA8C;AAElD,WAAID,KAAmB,KAAK,OAAO,OAAO,oBACxCC,IAAW,aACFD,KAAmB,KAAK,OAAO,OAAO,qBAC/CC,IAAW,YAGN;AAAA,MACL,WAAW,KAAK,IAAA;AAAA,MAChB,gBAAgBH,EAAO;AAAA,MACvB,iBAAiBA,EAAO;AAAA,MACxB,iBAAiBA,EAAO;AAAA,MACxB,iBAAAE;AAAA,MACA,UAAAC;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,uBAA6B;AACnC,QAAI,OAAO,wBAA0B,KAAa;AAChD,WAAK,IAAI,gEAAgE;AACzE;AAAA,IACF;AAEA,SAAK,gBAAgB,YAAY,IAAA,GACjC,KAAK,UAAA,GACL,KAAK,IAAI,0BAA0B;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAA4B;AAClC,IAAI,KAAK,mBAAmB,SAC1B,qBAAqB,KAAK,cAAc,GACxC,KAAK,iBAAiB;AAAA,EAE1B;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,MAAY;AAC9B,QAAI,CAAC,KAAK,UAAW;AAErB,UAAMC,IAAM,YAAY,IAAA,GAClBC,IAAQD,IAAM,KAAK;AACzB,SAAK,gBAAgBA,GAErB,KAAK;AAGL,UAAME,IAAUD,IAAQ,KAAK,OAAO,QAAQ,cAAc;AAW1D,QAVIC,MACF,KAAK,iBACL,KAAK,KAAK,aAAa;AAAA,MACrB,UAAUD;AAAA,MACV,UAAU,KAAK,OAAO,QAAQ;AAAA,MAC9B,WAAWD;AAAA,IAAA,CACZ,IAIC,KAAK,aAAa,OAAO,GAAG;AAC9B,YAAMG,IAAM,MAAOF,GACbf,IAA0B;AAAA,QAC9B,WAAWc;AAAA,QACX,UAAUC;AAAA,QACV,SAAAC;AAAA,QACA,KAAK,KAAK,MAAMC,CAAG;AAAA,MAAA;AAErB,WAAK,aAAa,KAAKjB,CAAK,GAC5B,KAAK,WAAW,KAAK,cAAc,GAAG;AAAA,IACxC;AAEA,SAAK,iBAAiB,sBAAsB,KAAK,SAAS;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKQ,0BAAgC;AACtC,QAAK7B;AAIL,UAAI;AACF,aAAK,mBAAmB,IAAI,oBAAoB,CAAC4B,MAAS;AAGxD,UAFgBA,EAAK,WAAA,EAEb,QAAQ,CAACC,MAAU;AACzB,gBAAIA,EAAM,WAAW,KAAK,QAAQ,uBAAuB;AACvD,oBAAMkB,IAA+B;AAAA,gBACnC,MAAMlB,EAAM;AAAA,gBACZ,eAAeA,EAAM;AAAA,gBACrB,UAAUA,EAAM;AAAA,gBAChB,cAAcA,EAAM;AAAA,gBACpB,WAAWA,EAAM;AAAA,gBACjB,WAAW,KAAK,QAAQ;AAAA,cAAA;AAG1B,mBAAK,cAAc,KAAKkB,CAAS,GACjC,KAAK,WAAW,KAAK,eAAe,EAAE,GACtC,KAAK,KAAK,gBAAgBA,CAAS;AAAA,YACrC;AAAA,UACF,CAAC;AAAA,QACH,CAAC,GAED,KAAK,iBAAiB,QAAQ,EAAE,YAAY,CAAC,UAAU,GAAG,GAC1D,KAAK,IAAI,6BAA6B;AAAA,MACxC,SAAShB,GAAO;AACd,aAAK,IAAI,wCAAwCA,CAAK;AAAA,MACxD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAA+B;AACrC,IAAI,KAAK,qBACP,KAAK,iBAAiB,WAAA,GACtB,KAAK,mBAAmB;AAAA,EAE5B;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAAsBiB,GAAsG;AAClI,UAAMnB,IAAyB;AAAA,MAC7B,IAAI9B,EAAA;AAAA,MACJ,GAAGiD;AAAA,MACH,SAASA,EAAU,cAAcA,EAAU;AAAA,MAC3C,oBAAqBA,EAAU,cAAcA,EAAU,eAAeA,EAAU,cAAe;AAAA,MAC/F,WAAW,KAAK,IAAA;AAAA,MAChB,KAAK,OAAO,SAAW,MAAc,OAAO,SAAS,OAAO;AAAA,IAAA;AAG9D,SAAK,iBAAiB,KAAKnB,CAAK,GAChC,KAAK,WAAW,KAAK,kBAAkB,GAAG,GAC1C,KAAK,KAAK,mBAAmBA,CAAK;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,KAAQZ,GAA4BgC,GAAe;AACzD,SAAK,cAAc,QAAQ,CAAC7B,MAAiB;AAC3C,UAAIA,EAAa,SAASH;AACxB,YAAI;AACF,UAAAG,EAAa,SAAS6B,CAAI;AAAA,QAC5B,SAASlB,GAAO;AACd,eAAK,IAAI,8BAA8Bd,CAAI,KAAKc,CAAK;AAAA,QACvD;AAAA,IAEJ,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAcmB,GAAaC,GAAuB;AACxD,IAAID,EAAO,SAASC,KAClBD,EAAO,OAAO,GAAGA,EAAO,SAASC,CAAO;AAAA,EAE5C;AAAA;AAAA;AAAA;AAAA,EAKQ,IAAIC,MAAoBC,GAAuB;AACrD,IAAI,KAAK,QAAQ,SACf,QAAQ,KAAK,wBAAwBD,CAAO,IAAI,GAAGC,CAAI;AAAA,EAE3D;AACF;AASO,SAASC,EACdpD,GACoB;AACpB,SAAOD,EAAmB,YAAYC,CAAO;AAC/C;AAKO,SAASqD,EACdrD,GACoB;AACpB,QAAMsD,IAAUF,EAAsBpD,CAAO;AAC7C,SAAAsD,EAAQ,MAAA,GACDA;AACT;AAKO,SAASC,IAAkC;AAEhD,EADgBH,EAAA,EACR,KAAA;AACV;"}