{"version":3,"sources":["../src/lib/dynamic-loaders.ts","../src/hooks/use-susurro.ts","../src/lib/chunk-middleware.ts","../src/hooks/use-latency-monitor.ts","../src/lib/latency-monitor.ts","../src/lib/ui-interfaces.ts","../src/hooks/use-model-cache.ts","../src/lib/audio-constants.ts","../src/lib/error-utils.ts"],"sourcesContent":["// Dynamic loaders for bundle size optimization\n// This file handles lazy loading of heavy dependencies\n\n// Cache for loaded modules to prevent multiple loads\nconst MODULE_CACHE = {\n  transformers: null as any,\n  murmubaraProcessing: null as any,\n};\n\n/**\n * Dynamically loads Transformers.js for Whisper processing\n * Reduces initial bundle size by ~45MB\n */\nexport const loadTransformers = async () => {\n  if (MODULE_CACHE.transformers) {\n    console.log('[loadTransformers] Using cached module');\n    return MODULE_CACHE.transformers;\n  }\n\n  const transformers = await import(\n    /* webpackChunkName: \"transformers-core\" */\n    /* webpackPreload: true */\n    '@huggingface/transformers'\n  );\n\n  MODULE_CACHE.transformers = transformers;\n  return transformers;\n};\n\n// Note: useMurmubaraEngine is now imported directly in use-susurro.ts\n// to avoid conditional hook calls which violate React's rules of hooks\n// Keeping this commented for reference\n// export const loadMurmubaraEngine = async () => {\n//   const { useMurmubaraEngine } = await import('murmuraba');\n//   return useMurmubaraEngine;\n// };\n\n/**\n * Dynamically loads Murmuraba processing functions\n * Separates heavy processing logic from core engine\n */\nexport const loadMurmubaraProcessing = async () => {\n  if (MODULE_CACHE.murmubaraProcessing) {\n    console.log('[loadMurmubaraProcessing] Using cached module');\n    return MODULE_CACHE.murmubaraProcessing;\n  }\n\n  const module = await import(\n    /* webpackChunkName: \"murmuraba-processing\" */\n    /* webpackPreload: true */\n    'murmuraba'\n  );\n\n  console.log('[loadMurmubaraProcessing] Module loaded for first time, keys:', Object.keys(module));\n  console.log('[loadMurmubaraProcessing] murmubaraVAD type:', typeof module.murmubaraVAD);\n\n  const processedModule = {\n    processFileWithMetrics: module.processFileWithMetrics || module.processFile, // Use processFileWithMetrics first, fallback to processFile\n    murmubaraVAD: module.murmubaraVAD, // No fallback - murmubaraVAD is a required export\n    extractAudioMetadata:\n      module.extractAudioMetadata || (() => ({ duration: 1.0, sampleRate: 44100, channels: 2 })), // Fallback metadata\n    // Add engine status check to ensure initialization\n    getEngineStatus: module.getEngineStatus,\n    initializeAudioEngine: module.initializeAudioEngine,\n  };\n\n  MODULE_CACHE.murmubaraProcessing = processedModule;\n  return processedModule;\n};\n\n/**\n * Preloads critical dependencies in the background\n * Call this after initial page load for better UX\n */\nexport const preloadCriticalDependencies = () => {\n  // Preload transformers.js in background\n  setTimeout(() => {\n    import(\n      /* webpackChunkName: \"transformers-core\" */\n      /* webpackPrefetch: true */\n      '@huggingface/transformers'\n    ).catch(() => {\n      // Ignore preload errors - will load when needed\n    });\n  }, 2000);\n\n  // Preload murmuraba in background\n  setTimeout(() => {\n    import(\n      /* webpackChunkName: \"murmuraba-engine\" */\n      /* webpackPrefetch: true */\n      'murmuraba'\n    ).catch(() => {\n      // Ignore preload errors - will load when needed\n    });\n  }, 3000);\n};\n","// useSusurro.ts — lean & mean: MediaRecorder 100% en murmuraba\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useMurmubaraEngine } from 'murmuraba';\nimport { ChunkMiddlewarePipeline } from '../lib/chunk-middleware';\nimport { useLatencyMonitor } from './use-latency-monitor';\n\nimport type {\n  AudioChunk,\n  ProcessingStatus,\n  TranscriptionResult,\n  SusurroChunk,\n  UseSusurroOptions as BaseUseSusurroOptions,\n  CompleteAudioResult,\n  StreamingSusurroChunk,\n  RecordingConfig,\n  AudioMetadata,\n} from '../lib/types';\n\n// —— Whisper thin wrapper (runtime download, 16k resample) ——\nconst WHISPER_ENV = {\n  useBrowserCache: true,\n  logLevel: 'error' as const,\n} as const;\n\n// Singleton cache for ASR pipelines to prevent multiple loads\nconst ASR_PIPELINE_CACHE = new Map<string, CallableFunction>();\n\nasync function ensureASR(model: string, quantized: boolean, onProgress: (p: number) => void) {\n  try {\n    // Create cache key based on model and quantization\n    const cacheKey = `${model}_${quantized ? 'q8' : 'fp32'}`;\n\n    // Check if pipeline already exists in cache\n    const cachedPipeline = ASR_PIPELINE_CACHE.get(cacheKey);\n    if (cachedPipeline) {\n      console.log(`[ensureASR] Using cached pipeline for ${cacheKey}`);\n      onProgress(100); // Immediately complete since it's cached\n      return cachedPipeline;\n    }\n\n    console.log(`[ensureASR] Creating new pipeline for ${cacheKey}`);\n\n    // Import @huggingface/transformers v3\n    const transformersModule = await import('@huggingface/transformers');\n\n    // Extract what we need\n    const { pipeline, env } = transformersModule;\n\n    // Configure transformers v3 environment\n    if (env) {\n      env.useBrowserCache = WHISPER_ENV.useBrowserCache;\n      // v3 uses allowRemoteModels (default true)\n      env.allowRemoteModels = true;\n    }\n\n    // Use Xenova ONNX models that work with v3\n    // Remove .en suffix to ensure multilingual support (needed for Spanish)\n    const modelName = `Xenova/${model.replace('.en', '')}`;\n    console.log(`[ensureASR] Loading model: ${modelName}`);\n\n    // Create pipeline with v3 API\n    const asr = await pipeline('automatic-speech-recognition', modelName, {\n      // v3 uses dtype instead of quantized\n      dtype: quantized ? 'q8' : 'fp32',\n      // Optional: use WebGPU if available (requires COEP/COOP headers)\n      // device: 'webgpu',\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      progress_callback: (p: any) => {\n        // v3 has different progress info structure\n        if (p?.progress !== undefined) {\n          const percent = p.progress <= 1 ? Math.round(p.progress * 100) : Math.round(p.progress);\n          onProgress(Math.min(100, Math.max(0, percent)));\n        } else if (p?.status) {\n          // Log status updates\n          console.log(`[ensureASR] Status: ${p.status}`);\n        }\n      },\n    });\n\n    // Store in cache for future use\n    ASR_PIPELINE_CACHE.set(cacheKey, asr);\n    console.log(`[ensureASR] Pipeline cached for ${cacheKey}`);\n\n    return asr;\n  } catch (error) {\n    console.error(`[ensureASR] Failed to load model:`, error);\n    throw error;\n  }\n}\n\nasync function resampleTo16k(buffer: AudioBuffer): Promise<Float32Array> {\n  if (buffer.sampleRate === 16000) return buffer.getChannelData(0).slice();\n  const length = Math.ceil(buffer.duration * 16000);\n  const offline = new OfflineAudioContext(1, length, 16000);\n  const mono = offline.createBuffer(1, buffer.length, buffer.sampleRate);\n  mono.copyToChannel(buffer.getChannelData(0), 0);\n  const src = offline.createBufferSource();\n  src.buffer = mono;\n  src.connect(offline.destination);\n  src.start(0);\n  const rendered = await offline.startRendering();\n  return rendered.getChannelData(0).slice();\n}\n\nasync function transcribeBlobWith(asr: CallableFunction, blob: Blob, language: string) {\n  const ab = await blob.arrayBuffer();\n  const ctx = new AudioContext();\n  const decoded = await ctx.decodeAudioData(ab);\n  const audioData = await resampleTo16k(decoded);\n  ctx.close();\n\n  // Ensure we have a Float32Array\n  const audioArray = audioData instanceof Float32Array ? audioData : new Float32Array(audioData);\n\n  console.log(\n    '[transcribeBlobWith] Audio array type:',\n    audioArray.constructor.name,\n    'Length:',\n    audioArray.length\n  );\n\n  // Whisper expects the audio directly as the first parameter\n  // Build options based on what the model supports\n  const options: any = {\n    return_timestamps: true,\n    chunk_length_s: 30,\n    stride_length_s: 5,\n  };\n\n  // Try with language/task first, if it fails, retry without them\n  try {\n    // First attempt with language and task (for multilingual models)\n    const out = await asr(audioArray, {\n      ...options,\n      language: language || 'es', // Default to Spanish\n      task: 'transcribe',\n    });\n    console.log('[transcribeBlobWith] Transcription successful with language:', language || 'es');\n    return processTranscriptionResult(out);\n  } catch (error: any) {\n    console.warn('[transcribeBlobWith] First attempt failed:', error?.message);\n\n    // If error mentions English-only model, retry without language/task\n    if (error?.message?.includes('English-only') || error?.message?.includes('Cannot specify')) {\n      console.log('[transcribeBlobWith] Retrying for English-only model...');\n      const out = await asr(audioArray, options);\n      return processTranscriptionResult(out);\n    }\n\n    // If it's a different error, throw it\n    throw error;\n  }\n}\n\nfunction processTranscriptionResult(out: any): TranscriptionResult {\n  const result: TranscriptionResult = {\n    text: out?.text ?? '',\n    chunkIndex: 0,\n    timestamp: Date.now(),\n    segments:\n      out?.chunks?.map((c: { timestamp?: [number, number]; text?: string }, index: number) => ({\n        id: index,\n        seek: c.timestamp?.[0] ?? 0,\n        start: c.timestamp?.[0] ?? 0,\n        end: c.timestamp?.[1] ?? 0,\n        text: c.text ?? '',\n        tokens: [],\n        temperature: 0,\n        avg_logprob: 0,\n        compression_ratio: 0,\n        no_speech_prob: 0,\n      })) ?? [],\n  };\n  return result;\n}\n\nasync function urlToBlob(url?: string): Promise<Blob> {\n  if (!url) return new Blob();\n  const r = await fetch(url);\n  return r.blob();\n}\n\n// —— Public API ——\nexport interface UseSusurroOptions extends BaseUseSusurroOptions {\n  onWhisperProgressLog?: (message: string, type?: 'info' | 'warning' | 'error' | 'success') => void;\n  initialModel?: 'tiny' | 'base' | 'small' | 'medium' | 'large';\n  engineConfig?: {\n    bufferSize?: number;\n    denoiseStrength?: number;\n    enableMetrics?: boolean;\n    noiseReductionLevel?: 'low' | 'medium' | 'high';\n    algorithm?: 'rnnoise';\n  };\n}\n\nexport interface UseSusurroReturn {\n  isRecording: boolean;\n  isProcessing: boolean;\n  transcriptions: TranscriptionResult[];\n  audioChunks: AudioChunk[];\n  processingStatus: ProcessingStatus;\n  averageVad: number;\n  startRecording: (config?: RecordingConfig) => Promise<void>;\n  stopRecording: () => void;\n  pauseRecording: () => void;\n  resumeRecording: () => void;\n  clearTranscriptions: () => void;\n\n  whisperReady: boolean;\n  whisperProgress: number;\n  whisperError: Error | string | null;\n  transcribeWithWhisper: (blob: Blob) => Promise<TranscriptionResult | null>;\n\n  exportChunkAsWav: (chunkId: string) => Promise<Blob>;\n\n  conversationalChunks: SusurroChunk[];\n  clearConversationalChunks: () => void;\n\n  middlewarePipeline: ChunkMiddlewarePipeline;\n\n  latencyReport: ReturnType<typeof useLatencyMonitor>['latencyReport'];\n  latencyStatus: ReturnType<typeof useLatencyMonitor>['latencyStatus'];\n\n  initializeAudioEngine: () => Promise<void>;\n  resetAudioEngine: () => Promise<void>;\n  isEngineInitialized: boolean;\n  engineError: string | null;\n  isInitializingEngine: boolean;\n\n  processAndTranscribeFile: (file: File) => Promise<CompleteAudioResult>;\n\n  startStreamingRecording: (\n    onChunk: (chunk: StreamingSusurroChunk) => void,\n    config?: RecordingConfig\n  ) => Promise<void>;\n  stopStreamingRecording: () => Promise<StreamingSusurroChunk[]>;\n\n  analyzeVAD: (buffer: ArrayBuffer) => Promise<{\n    averageVad: number;\n    vadScores: number[];\n    metrics: unknown[];\n    voiceSegments: Array<{\n      startTime: number;\n      endTime: number;\n      vadScore: number;\n      confidence: number;\n    }>;\n  }>;\n  convertBlobToBuffer: (blob: Blob) => Promise<ArrayBuffer>;\n\n  currentStream: MediaStream | null; // exposed from murmuraba\n}\n\n// —— Hook ——\nexport function useSusurro(options: UseSusurroOptions = {}): UseSusurroReturn {\n  const {\n    chunkDurationMs = 8000,\n    whisperConfig = {},\n    conversational,\n    onWhisperProgressLog,\n  } = options;\n\n  // — Murmuraba Engine: Direct integration with official hook —\n  const murmubaraConfig = {\n    bufferSize: (options.engineConfig?.bufferSize ?? 1024) as 256 | 512 | 1024 | 2048 | 4096,\n    denoiseStrength: options.engineConfig?.denoiseStrength ?? 0.5,\n    enableMetrics: options.engineConfig?.enableMetrics ?? true,\n    noiseReductionLevel: options.engineConfig?.noiseReductionLevel ?? 'medium',\n    algorithm: options.engineConfig?.algorithm ?? 'rnnoise',\n    chunkDurationMs: chunkDurationMs,\n    autoCleanup: true,\n    useAudioWorklet: true,\n    logLevel: 'error' as const,  // Changed from 'info' to 'error' to reduce logs\n    enableDebugLogs: false,  // Explicitly disable debug logs\n  };\n\n  const {\n    isInitialized: engineReady,\n    error: engineError,\n    recordingState,\n    currentStream: engineStream,\n    startRecording: murmubaraStartRecording,\n    stopRecording: murmubaraStopRecording,\n    pauseRecording: murmurbaraPauseRecording,\n    resumeRecording: murmubaraResumeRecording,\n    exportChunkAsWav: murmubaraExportChunkAsWav,\n    initialize: murmubaraInitializeEngine,\n    destroy: murmubaraDestroyEngine,\n  } = useMurmubaraEngine(murmubaraConfig);\n\n  // Derive isInitializing from engine state\n  const [engineInitializing, setEngineInitializing] = useState(false);\n\n  // — Whisper state —\n  const [whisperReady, setWhisperReady] = useState(false);\n  const [whisperProgress, setWhisperProgress] = useState(0);\n  const [whisperError, setWhisperError] = useState<Error | string | null>(null);\n  const asrRef = useRef<CallableFunction | null>(null);\n\n  // Use Xenova ONNX multilingual models for Spanish support\n  // Removed .en suffix to support multiple languages including Spanish\n  const modelMap: Record<string, string> = {\n    tiny: 'whisper-tiny',\n    base: 'whisper-base',\n    medium: 'whisper-medium',\n    small: 'whisper-small',\n    large: 'whisper-large-v3',\n  };\n  const whisperModel = modelMap[options.initialModel || 'tiny'] || 'whisper-tiny';\n  const whisperLanguage = whisperConfig?.language || 'es'; // Default to Spanish\n  const whisperQuantized = true;\n\n  useEffect(() => {\n    let cancelled = false;\n    (async () => {\n      try {\n        // Log initial state\n\n        const asr = await ensureASR(whisperModel, whisperQuantized, (p: number) => {\n          setWhisperProgress(p);\n          if (onWhisperProgressLog) {\n            if (p === 100) {\n              onWhisperProgressLog(\n                `✅ Modelo Whisper ${whisperModel} cargado correctamente`,\n                'success'\n              );\n              onWhisperProgressLog('🎙️ Sistema de transcripción listo para usar', 'success');\n            } else if (p === 0) {\n              onWhisperProgressLog(`📥 Iniciando descarga del modelo ${whisperModel}...`, 'info');\n            } else if (p > 0 && p < 25) {\n              onWhisperProgressLog(`📥 Descargando modelo Whisper... ${p}%`, 'info');\n            } else if (p >= 25 && p < 50) {\n              onWhisperProgressLog(`⚙️ Procesando modelo de IA... ${p}%`, 'info');\n            } else if (p >= 50 && p < 75) {\n              onWhisperProgressLog(`🔧 Configurando neural network... ${p}%`, 'info');\n            } else if (p >= 75 && p < 100) {\n              onWhisperProgressLog(`🚀 Finalizando inicialización... ${p}%`, 'info');\n            }\n          }\n        });\n        if (!cancelled) {\n          asrRef.current = asr;\n          setWhisperReady(true);\n        }\n      } catch (e) {\n        if (!cancelled) {\n          const errorMessage = (e as Error)?.message ?? 'Failed to load Whisper';\n\n          setWhisperError(errorMessage);\n          onWhisperProgressLog?.(`❌ Error al cargar Whisper: ${errorMessage}`, 'error');\n        }\n      }\n    })();\n    return () => {\n      cancelled = true;\n      asrRef.current = null;\n      setWhisperReady(false);\n      setWhisperProgress(0);\n    };\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [whisperModel]);\n\n  // — App state —\n  const [audioChunks, setAudioChunks] = useState<AudioChunk[]>([]);\n  const [transcriptions, setTranscriptions] = useState<TranscriptionResult[]>([]);\n  const [processingStatus, setProcessingStatus] = useState<ProcessingStatus>({\n    isProcessing: false,\n    currentChunk: 0,\n    totalChunks: 0,\n    stage: 'idle',\n  });\n  const [averageVad, setAverageVad] = useState(0);\n\n  const [conversationalChunks, setConversationalChunks] = useState<SusurroChunk[]>([]);\n  const processedAudioUrls = useRef(new Map<string, string>());\n  const chunkTranscriptions = useRef(new Map<string, string>());\n  const chunkProcessingTimes = useRef(new Map<string, number>());\n\n  // Engine state is now managed by AudioEngineManager - no local state needed\n  const [isStreamingRecording, setIsStreamingRecording] = useState(false);\n  const streamingCallbackRef = useRef<((c: StreamingSusurroChunk) => void) | null>(null);\n  const streamingSessionRef = useRef<{ stop: () => Promise<void> } | null>(null);\n  const lastProcessedChunkIndexRef = useRef(0);\n\n  const { latencyReport, latencyStatus, recordMetrics } = useLatencyMonitor(300);\n\n  const [middlewarePipeline] = useState(() => new ChunkMiddlewarePipeline());\n\n  // — Engine init/reset — Now using Murmuraba directly\n  const initializeAudioEngine = useCallback(async () => {\n    if (engineReady || engineInitializing) return;\n    setEngineInitializing(true);\n    try {\n      await murmubaraInitializeEngine();\n    } finally {\n      setEngineInitializing(false);\n    }\n  }, [engineReady, engineInitializing, murmubaraInitializeEngine]);\n\n  // Move clearConversationalChunks declaration before resetAudioEngine\n  const clearConversationalChunks = useCallback(() => {\n    setConversationalChunks([]);\n    processedAudioUrls.current.clear();\n    chunkTranscriptions.current.clear();\n    chunkProcessingTimes.current.clear();\n  }, []);\n\n  const resetAudioEngine = useCallback(async () => {\n    // Stop any ongoing recordings first\n    if (recordingState?.isRecording) {\n      murmubaraStopRecording();\n    }\n\n    if (streamingSessionRef.current) {\n      await streamingSessionRef.current.stop();\n      streamingSessionRef.current = null;\n    }\n    setIsStreamingRecording(false);\n    streamingCallbackRef.current = null;\n\n    setAudioChunks([]);\n    setTranscriptions([]);\n    clearConversationalChunks();\n\n    // Proper engine reset through Murmuraba\n    await murmubaraDestroyEngine();\n    setEngineInitializing(true);\n    try {\n      await murmubaraInitializeEngine();\n    } finally {\n      setEngineInitializing(false);\n    }\n  }, [\n    recordingState,\n    murmubaraStopRecording,\n    murmubaraDestroyEngine,\n    murmubaraInitializeEngine,\n    clearConversationalChunks,\n  ]);\n\n  // Engine state synchronization is now handled by AudioEngineManager - no manual sync needed\n\n  // — Recording controls (using Murmuraba directly) —\n  const startRecording = useCallback(\n    async (config?: RecordingConfig) => {\n      // Ensure engine is ready\n      if (!engineReady) {\n        await initializeAudioEngine();\n      }\n\n      const seconds = (config?.chunkDuration ?? chunkDurationMs / 1000) | 0;\n      await murmubaraStartRecording(seconds);\n    },\n    [engineReady, initializeAudioEngine, murmubaraStartRecording, chunkDurationMs]\n  );\n\n  const stopRecording = useCallback(() => {\n    murmubaraStopRecording();\n  }, [murmubaraStopRecording]);\n\n  const pauseRecording = useCallback(() => {\n    murmurbaraPauseRecording();\n  }, [murmurbaraPauseRecording]);\n\n  const resumeRecording = useCallback(() => {\n    murmubaraResumeRecording();\n  }, [murmubaraResumeRecording]);\n\n  const clearTranscriptions = useCallback(() => {\n    setTranscriptions([]);\n    setAudioChunks([]);\n    chunkTranscriptions.current.clear();\n    processedAudioUrls.current.clear();\n    chunkProcessingTimes.current.clear();\n    setConversationalChunks([]);\n  }, []);\n\n  // — Whisper call —\n  const transcribeWithWhisper = useCallback(\n    async (blob: Blob): Promise<TranscriptionResult | null> => {\n      if (!asrRef.current || !whisperReady) return null;\n      const t0 = performance.now();\n      const out = await transcribeBlobWith(asrRef.current, blob, whisperLanguage);\n      // latency metrics (best-effort)\n      recordMetrics({\n        chunkId: 'file',\n        audioToEmitLatency: performance.now() - t0,\n        audioProcessingLatency: 0,\n        transcriptionLatency: performance.now() - t0,\n        middlewareLatency: 0,\n        vadScore: 0,\n        audioSize: blob.size,\n      });\n      return out;\n    },\n    [whisperReady, whisperLanguage, recordMetrics]\n  );\n\n  // — VAD / metadata vía murmuraba processing helpers —\n  const analyzeVAD = useCallback(async (buffer: ArrayBuffer) => {\n    try {\n      const { loadMurmubaraProcessing } = await import('../lib/dynamic-loaders');\n      const { murmubaraVAD } = await loadMurmubaraProcessing();\n\n      if (!murmubaraVAD) {\n        console.warn('murmubaraVAD function not available in murmuraba module');\n        return { averageVad: 0, vadScores: [], metrics: [], voiceSegments: [] };\n      }\n\n      // Log for debugging\n      console.log('[analyzeVAD] Buffer type:', buffer.constructor.name, 'Size:', buffer.byteLength);\n      console.log('[analyzeVAD] murmubaraVAD type:', typeof murmubaraVAD);\n\n      const r = await murmubaraVAD(buffer);\n\n      console.log('[analyzeVAD] Result type:', typeof r, 'Keys:', r ? Object.keys(r) : 'null');\n\n      return {\n        averageVad: r.average || 0,\n        vadScores: r.scores || [],\n        metrics: r.metrics || [],\n        voiceSegments: (r.voiceSegments || []).map(\n          (s: {\n            startTime?: number;\n            endTime?: number;\n            vadScore?: number;\n            confidence?: number;\n          }) => ({\n            startTime: s.startTime || 0,\n            endTime: s.endTime || 0,\n            vadScore: s.vadScore || 0,\n            confidence: s.confidence || 0,\n          })\n        ),\n      };\n    } catch (error) {\n      console.error('VAD analysis failed:', error);\n      console.error('Error stack:', error instanceof Error ? error.stack : 'No stack');\n      return { averageVad: 0, vadScores: [], metrics: [], voiceSegments: [] };\n    }\n  }, []);\n\n  const convertBlobToBuffer = useCallback((blob: Blob) => blob.arrayBuffer(), []);\n\n  const calculateDuration = useCallback(async (buffer: ArrayBuffer): Promise<number> => {\n    try {\n      const { loadMurmubaraProcessing } = await import('../lib/dynamic-loaders');\n      const { extractAudioMetadata } = await loadMurmubaraProcessing();\n      const metadata = extractAudioMetadata(buffer);\n      return metadata.duration;\n    } catch {\n      const bytes = buffer.byteLength;\n      return Math.max(0.1, bytes / (44100 * 2 * 2));\n    }\n  }, []);\n\n  // — Streaming API (callback por chunk) —\n  const startStreamingRecording = useCallback(\n    async (onChunk: (chunk: StreamingSusurroChunk) => void, config?: RecordingConfig) => {\n      if (isStreamingRecording) throw new Error('Already recording. Stop first.');\n\n      // Ensure engine is ready\n      if (!engineReady) {\n        await initializeAudioEngine();\n      }\n\n      setIsStreamingRecording(true);\n      streamingCallbackRef.current = onChunk;\n      lastProcessedChunkIndexRef.current = recordingState?.chunks?.length ?? 0;\n\n      // Clear previous streaming chunks\n      streamingChunksRef.current = [];\n\n      const seconds = (config?.chunkDuration ?? chunkDurationMs / 1000) | 0;\n\n      // Start recording with Murmuraba\n      await murmubaraStartRecording(seconds);\n\n      // Set up cleanup session\n      streamingSessionRef.current = {\n        stop: async () => {\n          murmubaraStopRecording();\n          setIsStreamingRecording(false);\n          streamingCallbackRef.current = null;\n        },\n      };\n    },\n    [\n      isStreamingRecording,\n      engineReady,\n      initializeAudioEngine,\n      murmubaraStartRecording,\n      murmubaraStopRecording,\n      chunkDurationMs,\n      recordingState?.chunks?.length,\n    ]\n  );\n\n  // Track streaming chunks separately\n  const streamingChunksRef = useRef<StreamingSusurroChunk[]>([]);\n\n  const stopStreamingRecording = useCallback(async (): Promise<StreamingSusurroChunk[]> => {\n    console.log('[stopStreamingRecording] Stopping recording...');\n\n    if (streamingSessionRef.current) {\n      await streamingSessionRef.current.stop();\n      streamingSessionRef.current = null;\n    }\n    setIsStreamingRecording(false);\n    streamingCallbackRef.current = null;\n\n    // Return the chunks that were processed during streaming\n    const chunks = [...streamingChunksRef.current];\n    console.log('[stopStreamingRecording] Returning', chunks.length, 'chunks');\n\n    // Clear for next recording session\n    streamingChunksRef.current = [];\n    lastProcessedChunkIndexRef.current = 0;\n\n    return chunks;\n  }, []);\n\n  // — Observa y consume chunks de murmuraba (REACTIVO Y LIMPIO) —\n  useEffect(() => {\n    if (!engineReady || !recordingState?.chunks) {\n      return;\n    }\n\n    const chunks = recordingState.chunks;\n\n    // Process new chunks for regular recording\n    const newOnes: AudioChunk[] = [];\n    for (let i = audioChunks.length; i < chunks.length; i++) {\n      const src = chunks[i];\n\n      const id = src.id || `chunk-${Date.now()}-${i}`;\n      const startTime = src.startTime ?? i * chunkDurationMs;\n      const endTime = src.endTime ?? (i + 1) * chunkDurationMs;\n      const vadScore = src.averageVad ?? 0;\n\n      newOnes.push({\n        id,\n        blob: undefined as unknown as Blob, // lo traemos on-demand al transcribir\n        startTime,\n        endTime,\n        vadScore,\n        duration: src.duration ?? chunkDurationMs,\n      });\n\n      if (src.processedAudioUrl) {\n        processedAudioUrls.current.set(id, src.processedAudioUrl);\n      }\n    }\n\n    if (newOnes.length) {\n      setAudioChunks((prev) => [...prev, ...newOnes]);\n    }\n\n    // promedio de VAD del último\n    const last = chunks[chunks.length - 1];\n    if (last?.averageVad != null) setAverageVad(last.averageVad);\n  }, [engineReady, recordingState?.chunks, audioChunks.length, chunkDurationMs]);\n\n  // — Streaming Transcription: Monitoreo reactivo separado —\n  useEffect(() => {\n    if (!isStreamingRecording || !streamingCallbackRef.current || !recordingState?.chunks) {\n      return;\n    }\n\n    const chunks = recordingState.chunks;\n    const newChunks = chunks.slice(lastProcessedChunkIndexRef.current);\n\n    if (newChunks.length === 0) return;\n\n    // Process new chunks for streaming\n    newChunks.forEach(async (chunk, relativeIndex) => {\n      const absoluteIndex = lastProcessedChunkIndexRef.current + relativeIndex;\n\n      try {\n        const audioBlob = await urlToBlob(chunk.processedAudioUrl);\n        const vadScore = chunk.averageVad ?? 0;\n        const isVoiceActive = vadScore > 0.3;\n\n        let transcriptionText = '';\n        if (whisperReady && isVoiceActive && audioBlob.size > 0) {\n          try {\n            const r = await transcribeWithWhisper(audioBlob);\n            transcriptionText = r?.text ?? '';\n          } catch (error) {\n            console.error('[STREAMING] Transcription error:', error);\n          }\n        }\n\n        const streamingChunk: StreamingSusurroChunk = {\n          id: chunk.id || `chunk-${Date.now()}-${absoluteIndex}`,\n          audioBlob,\n          vadScore,\n          timestamp: Date.now(),\n          transcriptionText,\n          duration: chunk.duration ?? chunkDurationMs,\n          isVoiceActive,\n        };\n\n        streamingChunksRef.current.push(streamingChunk);\n        streamingCallbackRef.current?.(streamingChunk);\n      } catch (error) {\n        console.error('[STREAMING] Error processing chunk:', error);\n      }\n    });\n\n    lastProcessedChunkIndexRef.current = chunks.length;\n  }, [\n    recordingState?.chunks,\n    isStreamingRecording,\n    whisperReady,\n    transcribeWithWhisper,\n    chunkDurationMs,\n  ]);\n\n  // — Conversational emit: cuando audio + transcripción están listos —\n  const tryEmitChunk = useCallback(\n    async (chunk: AudioChunk, forceEmit = false) => {\n      if (!conversational?.onChunk) return;\n\n      const audioUrl = processedAudioUrls.current.get(chunk.id);\n      const transcript = chunkTranscriptions.current.get(chunk.id);\n      const t0 = chunkProcessingTimes.current.get(chunk.id);\n\n      if (audioUrl && (transcript || forceEmit)) {\n        let emitted: SusurroChunk = {\n          id: chunk.id,\n          audioUrl,\n          transcript: transcript ?? '',\n          startTime: chunk.startTime,\n          endTime: chunk.endTime,\n          vadScore: chunk.vadScore ?? 0,\n          isComplete: Boolean(transcript),\n          processingLatency: t0 ? Date.now() - t0 : undefined,\n        };\n\n        const t1 = performance.now();\n        try {\n          emitted = await middlewarePipeline.process(emitted);\n        } catch {\n          /* ignore middleware errors */\n        }\n        const middlewareLatency = performance.now() - t1;\n\n        if (emitted.processingLatency != null) {\n          recordMetrics({\n            chunkId: chunk.id,\n            audioToEmitLatency: emitted.processingLatency,\n            audioProcessingLatency: Math.max(0, emitted.processingLatency - middlewareLatency),\n            transcriptionLatency: 0,\n            middlewareLatency,\n            vadScore: chunk.vadScore,\n            audioSize: 0,\n          });\n        }\n\n        setConversationalChunks((prev) => [...prev, emitted]);\n        conversational.onChunk(emitted);\n        chunkProcessingTimes.current.delete(chunk.id);\n      }\n    },\n    [conversational, middlewarePipeline, recordMetrics]\n  );\n\n  // — Auto-procesa al terminar la grabación (batch) —\n  const processChunks = useCallback(\n    async (chunks: AudioChunk[]) => {\n      if (!chunks.length) return;\n      setProcessingStatus({\n        isProcessing: true,\n        currentChunk: 0,\n        totalChunks: chunks.length,\n        stage: 'processing',\n      });\n\n      for (let i = 0; i < chunks.length; i++) {\n        setProcessingStatus((p: any) => ({ ...p, currentChunk: i + 1 }));\n        const id = chunks[i].id;\n        const processedUrl = processedAudioUrls.current.get(id);\n        if (!processedUrl) continue;\n        try {\n          const blob = await urlToBlob(processedUrl);\n          const r = await transcribeWithWhisper(blob);\n          if (r) {\n            setTranscriptions((prev: any[]) => [\n              ...prev,\n              { ...r, chunkIndex: i, timestamp: Date.now() },\n            ]);\n            chunkTranscriptions.current.set(id, r.text);\n            await tryEmitChunk(chunks[i]);\n          }\n        } catch {\n          /* ignore chunk fail */\n        }\n      }\n\n      setProcessingStatus({\n        isProcessing: false,\n        currentChunk: 0,\n        totalChunks: 0,\n        stage: 'complete',\n      });\n    },\n    [transcribeWithWhisper, tryEmitChunk]\n  );\n\n  useEffect(() => {\n    // si hay chunks y no estamos grabando → procesar batch\n    if (audioChunks.length > 0 && engineReady && whisperReady) {\n      const isRecording = recordingState?.isRecording ?? false;\n\n      if (!isRecording) {\n        setTimeout(() => {\n          if (!conversational?.onChunk || conversational.enableInstantTranscription) {\n            processChunks(audioChunks);\n          }\n        }, 50);\n      }\n    }\n  }, [\n    audioChunks,\n    engineReady,\n    whisperReady,\n    recordingState?.isRecording,\n    conversational,\n    processChunks,\n  ]);\n\n  // — Limpieza — (already moved before resetAudioEngine)\n\n  useEffect(() => {\n    return () => {\n      clearConversationalChunks();\n      if (streamingSessionRef.current) {\n        streamingSessionRef.current.stop().catch(() => {});\n      }\n    };\n  }, [clearConversationalChunks]);\n\n  // — Export chunk as WAV (using Murmuraba's export) —\n  const exportChunkAsWav = useCallback(\n    async (chunkId: string) => {\n      if (!murmubaraExportChunkAsWav) {\n        console.warn('Export chunk feature not available');\n        return new Blob();\n      }\n      return murmubaraExportChunkAsWav(chunkId, 'processed');\n    },\n    [murmubaraExportChunkAsWav]\n  );\n\n  // — File pipeline end-to-end —\n  const processAndTranscribeFile = useCallback(\n    async (file: File): Promise<CompleteAudioResult> => {\n      const t0 = performance.now();\n      if (!whisperReady) throw new Error('Whisper model not ready');\n\n      await initializeAudioEngine();\n\n      const originalBuffer = await file.arrayBuffer();\n      const originalAudioUrl = URL.createObjectURL(file);\n\n      const { loadMurmubaraProcessing } = await import('../lib/dynamic-loaders');\n      const {\n        processFileWithMetrics,\n        getEngineStatus,\n        initializeAudioEngine: initProc,\n      } = await loadMurmubaraProcessing();\n\n      try {\n        const status = getEngineStatus?.() ?? 'uninitialized';\n        if (status === 'uninitialized' && initProc) {\n          await initProc({\n            noiseReductionLevel: 'medium',\n            bufferSize: 1024,\n            algorithm: 'rnnoise',\n            logLevel: 'info',\n            autoCleanup: true,\n            useAudioWorklet: true,\n          });\n        }\n      } catch {\n        /* ignore */\n      }\n\n      const processed = await processFileWithMetrics(originalBuffer, () => {});\n      const processedBlob = new Blob([processed.processedBuffer], { type: 'audio/wav' });\n      const processedAudioUrl = URL.createObjectURL(processedBlob);\n\n      const vadAnalysis = await analyzeVAD(originalBuffer);\n      const tr = await transcribeWithWhisper(processedBlob);\n      if (!tr) throw new Error('Transcription failed');\n\n      const metadata: AudioMetadata = {\n        duration: await calculateDuration(originalBuffer),\n        sampleRate: 44100,\n        channels: 2,\n        fileSize: file.size,\n        processedSize: processed.processedBuffer.byteLength,\n      };\n\n      return {\n        originalAudioUrl,\n        processedAudioUrl,\n        transcriptionText: tr.text,\n        transcriptionSegments: tr.segments,\n        vadAnalysis,\n        metadata,\n        processingTime: performance.now() - t0,\n      };\n    },\n    [whisperReady, initializeAudioEngine, analyzeVAD, transcribeWithWhisper, calculateDuration]\n  );\n\n  return {\n    // Recording (managed by Murmuraba directly)\n    isRecording: recordingState?.isRecording ?? false,\n    isProcessing: processingStatus.isProcessing,\n    transcriptions,\n    audioChunks,\n    processingStatus,\n    averageVad,\n\n    startRecording,\n    stopRecording,\n    pauseRecording,\n    resumeRecording,\n    clearTranscriptions,\n\n    exportChunkAsWav,\n\n    whisperReady,\n    whisperProgress,\n    whisperError,\n    transcribeWithWhisper,\n\n    conversationalChunks,\n    clearConversationalChunks,\n\n    middlewarePipeline,\n\n    latencyReport,\n    latencyStatus,\n\n    initializeAudioEngine,\n    resetAudioEngine,\n    isEngineInitialized: engineReady,\n    engineError: engineError ? String(engineError) : null,\n    isInitializingEngine: engineInitializing,\n\n    processAndTranscribeFile,\n\n    startStreamingRecording,\n    stopStreamingRecording,\n\n    analyzeVAD,\n    convertBlobToBuffer,\n\n    currentStream: engineStream,\n  };\n}\n","// Chunk Middleware Pipeline - Extensible processing for SusurroChunks\n// Part of Murmuraba v3 Conversational Evolution\n\nimport type { SusurroChunk } from './types';\n\nexport interface ChunkMiddleware {\n  name: string;\n  process: (chunk: SusurroChunk) => Promise<SusurroChunk>;\n  enabled: boolean;\n  priority: number; // Lower number = higher priority\n}\n\nexport interface MiddlewareContext {\n  startTime: number;\n  processingStage: 'pre-emit' | 'post-emit';\n  metadata: Record<string, unknown>;\n}\n\n// Translation Middleware\nexport const translationMiddleware: ChunkMiddleware = {\n  name: 'translation',\n  enabled: false,\n  priority: 1,\n  async process(chunk: SusurroChunk): Promise<SusurroChunk> {\n    // Future: Integrate with translation API\n    const translatedText = chunk.transcript; // Placeholder\n\n    return {\n      ...chunk,\n      metadata: {\n        ...chunk.metadata,\n        originalLanguage: 'en',\n        translatedText,\n        translationConfidence: 0.95,\n      },\n    };\n  },\n};\n\n// Sentiment Analysis Middleware\nexport const sentimentMiddleware: ChunkMiddleware = {\n  name: 'sentiment',\n  enabled: false,\n  priority: 2,\n  async process(chunk: SusurroChunk): Promise<SusurroChunk> {\n    // Future: Integrate with sentiment analysis\n    const sentiment = analyzeSentiment(chunk.transcript);\n\n    return {\n      ...chunk,\n      metadata: {\n        ...chunk.metadata,\n        sentiment: sentiment.label,\n        sentimentScore: sentiment.score,\n        emotion: sentiment.emotion,\n      },\n    };\n  },\n};\n\n// Intent Detection Middleware\nexport const intentMiddleware: ChunkMiddleware = {\n  name: 'intent',\n  enabled: false,\n  priority: 3,\n  async process(chunk: SusurroChunk): Promise<SusurroChunk> {\n    // Future: Integrate with intent detection\n    const intent = detectIntent(chunk.transcript);\n\n    return {\n      ...chunk,\n      metadata: {\n        ...chunk.metadata,\n        intent: intent.name,\n        intentConfidence: intent.confidence,\n        entities: intent.entities,\n      },\n    };\n  },\n};\n\n// Quality Enhancement Middleware\nexport const qualityMiddleware: ChunkMiddleware = {\n  name: 'quality',\n  enabled: true,\n  priority: 0, // Highest priority\n  async process(chunk: SusurroChunk): Promise<SusurroChunk> {\n    // Audio quality validation and enhancement\n    const qualityMetrics = analyzeAudioQuality(chunk);\n\n    return {\n      ...chunk,\n      metadata: {\n        ...chunk.metadata,\n        audioQuality: qualityMetrics.score,\n        noiseLevel: qualityMetrics.noiseLevel,\n        clarity: qualityMetrics.clarity,\n        enhancement: qualityMetrics.applied,\n      },\n    };\n  },\n};\n\n// Middleware Pipeline Manager\nexport class ChunkMiddlewarePipeline {\n  private middlewares: ChunkMiddleware[] = [];\n  // private context: MiddlewareContext; // Context stored for future middleware extensions\n\n  constructor() {\n    // Ready for middleware registration\n\n    // Register default middlewares\n    this.register(qualityMiddleware);\n    this.register(translationMiddleware);\n    this.register(sentimentMiddleware);\n    this.register(intentMiddleware);\n  }\n\n  register(middleware: ChunkMiddleware): void {\n    this.middlewares.push(middleware);\n    this.middlewares.sort((a, b) => a.priority - b.priority);\n  }\n\n  unregister(name: string): void {\n    this.middlewares = this.middlewares.filter((m) => m.name !== name);\n  }\n\n  enable(name: string): void {\n    const middleware = this.middlewares.find((m) => m.name === name);\n    if (middleware) {\n      middleware.enabled = true;\n    }\n  }\n\n  disable(name: string): void {\n    const middleware = this.middlewares.find((m) => m.name === name);\n    if (middleware) {\n      middleware.enabled = false;\n    }\n  }\n\n  async process(chunk: SusurroChunk): Promise<SusurroChunk> {\n    let processedChunk = { ...chunk };\n    const processingLatencies: Record<string, number> = {};\n\n    for (const middleware of this.middlewares) {\n      if (!middleware.enabled) continue;\n\n      const startTime = performance.now();\n\n      try {\n        processedChunk = await middleware.process(processedChunk);\n\n        const latency = performance.now() - startTime;\n        processingLatencies[middleware.name] = latency;\n      } catch (error) {\n        // Continue processing with other middlewares\n      }\n    }\n\n    // Add processing metadata\n    return {\n      ...processedChunk,\n      metadata: {\n        ...processedChunk.metadata,\n        middlewareLatencies: processingLatencies,\n        totalMiddlewareTime: Object.values(processingLatencies).reduce((a, b) => a + b, 0),\n      },\n    };\n  }\n\n  getStatus(): { name: string; enabled: boolean; priority: number }[] {\n    return this.middlewares.map((m) => ({\n      name: m.name,\n      enabled: m.enabled,\n      priority: m.priority,\n    }));\n  }\n}\n\n// Helper functions for middleware implementations\nfunction analyzeSentiment(text: string): { label: string; score: number; emotion: string } {\n  // Placeholder implementation - Future: integrate with sentiment API\n  const positiveWords = ['good', 'great', 'awesome', 'excellent', 'amazing'];\n  const negativeWords = ['bad', 'terrible', 'awful', 'horrible', 'worst'];\n\n  const words = text.toLowerCase().split(' ');\n  const positiveCount = words.filter((w) => positiveWords.includes(w)).length;\n  const negativeCount = words.filter((w) => negativeWords.includes(w)).length;\n\n  if (positiveCount > negativeCount) {\n    return { label: 'positive', score: 0.7, emotion: 'happy' };\n  } else if (negativeCount > positiveCount) {\n    return { label: 'negative', score: 0.7, emotion: 'sad' };\n  }\n\n  return { label: 'neutral', score: 0.5, emotion: 'neutral' };\n}\n\nfunction detectIntent(text: string): { name: string; confidence: number; entities: string[] } {\n  // Placeholder implementation - Future: integrate with NLU API\n  const questionWords = ['what', 'how', 'when', 'where', 'why', 'who'];\n  const commandWords = ['play', 'stop', 'start', 'open', 'close', 'send'];\n\n  const words = text.toLowerCase().split(' ');\n\n  if (words.some((w) => questionWords.includes(w))) {\n    return { name: 'question', confidence: 0.8, entities: [] };\n  } else if (words.some((w) => commandWords.includes(w))) {\n    return { name: 'command', confidence: 0.8, entities: [] };\n  }\n\n  return { name: 'statement', confidence: 0.6, entities: [] };\n}\n\nfunction analyzeAudioQuality(chunk: SusurroChunk): {\n  score: number;\n  noiseLevel: number;\n  clarity: number;\n  applied: string[];\n} {\n  // Placeholder implementation - Future: integrate with audio analysis\n  return {\n    score: chunk.vadScore || 0.8,\n    noiseLevel: 0.1, // Low noise thanks to neural processing\n    clarity: 0.9,\n    applied: ['neural_denoising', 'voice_enhancement'],\n  };\n}\n","import { useState, useCallback, useEffect, useRef } from 'react';\nimport { LatencyMonitor, type LatencyMetrics, type LatencyReport } from '../lib/latency-monitor';\n\ninterface UseLatencyMonitorReturn {\n  latencyReport: LatencyReport;\n  latencyStatus: {\n    isHealthy: boolean;\n    currentLatency: number;\n    trend: 'improving' | 'degrading' | 'stable';\n    lastOptimization?: string;\n  };\n  recordMetrics: (metrics: Omit<LatencyMetrics, 'timestamp'>) => void;\n  exportMetrics: (format?: 'json' | 'csv') => string;\n  clear: () => void;\n  getMetricsCount: () => number;\n  onOptimization: (listener: (data: unknown) => void) => void;\n  offOptimization: (listener: (data: unknown) => void) => void;\n}\n\n/**\n * Hook-based latency monitor\n * Replaces the singleton latencyMonitor with modern React patterns\n */\nexport function useLatencyMonitor(targetLatency = 300): UseLatencyMonitorReturn {\n  const monitorRef = useRef<LatencyMonitor | null>(null);\n  const [latencyReport, setLatencyReport] = useState<LatencyReport>(() => {\n    if (!monitorRef.current) {\n      monitorRef.current = new LatencyMonitor(targetLatency);\n    }\n    return monitorRef.current.generateReport();\n  });\n  const [latencyStatus, setLatencyStatus] = useState(() => {\n    if (!monitorRef.current) {\n      monitorRef.current = new LatencyMonitor(targetLatency);\n    }\n    return monitorRef.current.getRealtimeStatus();\n  });\n\n  // Initialize monitor if not already done\n  useEffect(() => {\n    if (!monitorRef.current) {\n      monitorRef.current = new LatencyMonitor(targetLatency);\n    }\n  }, [targetLatency]);\n\n  // Record metrics\n  const recordMetrics = useCallback((metrics: Omit<LatencyMetrics, 'timestamp'>) => {\n    if (monitorRef.current) {\n      monitorRef.current.recordMetrics(metrics);\n      // Update status immediately after recording\n      setLatencyStatus(monitorRef.current.getRealtimeStatus());\n    }\n  }, []);\n\n  // Export metrics\n  const exportMetrics = useCallback((format: 'json' | 'csv' = 'json'): string => {\n    if (monitorRef.current) {\n      return monitorRef.current.exportMetrics(format);\n    }\n    return format === 'json' ? '[]' : '';\n  }, []);\n\n  // Clear metrics\n  const clear = useCallback(() => {\n    if (monitorRef.current) {\n      monitorRef.current.clear();\n      setLatencyReport(monitorRef.current.generateReport());\n      setLatencyStatus(monitorRef.current.getRealtimeStatus());\n    }\n  }, []);\n\n  // Get metrics count\n  const getMetricsCount = useCallback((): number => {\n    if (monitorRef.current) {\n      return monitorRef.current.getMetricsCount();\n    }\n    return 0;\n  }, []);\n\n  // Optimization event listeners\n  const onOptimization = useCallback((listener: (data: unknown) => void) => {\n    if (monitorRef.current) {\n      monitorRef.current.on('optimization-trigger', listener);\n    }\n  }, []);\n\n  const offOptimization = useCallback((listener: (data: unknown) => void) => {\n    if (monitorRef.current) {\n      monitorRef.current.off('optimization-trigger', listener);\n    }\n  }, []);\n\n  // Periodic report updates\n  useEffect(() => {\n    const updateLatencyReport = () => {\n      if (monitorRef.current) {\n        setLatencyReport(monitorRef.current.generateReport());\n        setLatencyStatus(monitorRef.current.getRealtimeStatus());\n      }\n    };\n\n    // Update every 10 seconds for real-time monitoring\n    const interval = setInterval(updateLatencyReport, 10000);\n\n    return () => clearInterval(interval);\n  }, []);\n\n  return {\n    latencyReport,\n    latencyStatus,\n    recordMetrics,\n    exportMetrics,\n    clear,\n    getMetricsCount,\n    onOptimization,\n    offOptimization,\n  };\n}\n","// Latency Monitor - High-precision latency measurement and optimization\n// Part of Murmuraba v3 Conversational Evolution - Phase 3\n\nexport interface LatencyMetrics {\n  audioToEmitLatency: number; // Total audio-to-emit latency\n  audioProcessingLatency: number; // Murmuraba processing time\n  transcriptionLatency: number; // Whisper transcription time\n  middlewareLatency: number; // Middleware processing time\n  chunkId: string;\n  timestamp: number;\n  vadScore?: number;\n  audioSize?: number; // Blob size in bytes\n}\n\nexport interface LatencyReport {\n  averageLatency: number;\n  medianLatency: number;\n  p95Latency: number;\n  p99Latency: number;\n  minLatency: number;\n  maxLatency: number;\n  targetMet: boolean; // <300ms achieved?\n  sampleCount: number;\n  timeRange: { start: number; end: number };\n  breakdown: {\n    audioProcessing: number;\n    transcription: number;\n    middleware: number;\n  };\n}\n\nexport interface PerformanceOptimization {\n  name: string;\n  description: string;\n  expectedLatencyReduction: number; // Expected reduction in ms\n  condition: (metrics: LatencyMetrics) => boolean;\n  apply: () => Promise<void>;\n}\n\nexport class LatencyMonitor {\n  private metrics: LatencyMetrics[] = [];\n  private maxMetrics = 1000; // Keep last 1000 measurements\n  private target = 300; // Target latency in ms\n  private optimizations: PerformanceOptimization[] = [];\n\n  constructor(targetLatency = 300) {\n    this.target = targetLatency;\n    this.setupOptimizations();\n  }\n\n  recordMetrics(metrics: Omit<LatencyMetrics, 'timestamp'>): void {\n    const fullMetrics: LatencyMetrics = {\n      ...metrics,\n      timestamp: performance.now(),\n    };\n\n    this.metrics.push(fullMetrics);\n\n    // Keep only recent metrics to prevent memory bloat\n    if (this.metrics.length > this.maxMetrics) {\n      this.metrics = this.metrics.slice(-this.maxMetrics);\n    }\n\n    // Real-time optimization triggers\n    this.checkForOptimizations(fullMetrics);\n  }\n\n  generateReport(lastNMinutes = 5): LatencyReport {\n    const cutoffTime = performance.now() - lastNMinutes * 60 * 1000;\n    const recentMetrics = this.metrics.filter((m) => m.timestamp > cutoffTime);\n\n    if (recentMetrics.length === 0) {\n      return this.getEmptyReport();\n    }\n\n    const latencies = recentMetrics.map((m) => m.audioToEmitLatency).sort((a, b) => a - b);\n    const avgLatency = latencies.reduce((a, b) => a + b, 0) / latencies.length;\n\n    return {\n      averageLatency: avgLatency,\n      medianLatency: this.getPercentile(latencies, 50),\n      p95Latency: this.getPercentile(latencies, 95),\n      p99Latency: this.getPercentile(latencies, 99),\n      minLatency: latencies[0],\n      maxLatency: latencies[latencies.length - 1],\n      targetMet: avgLatency < this.target,\n      sampleCount: recentMetrics.length,\n      timeRange: {\n        start: recentMetrics[0].timestamp,\n        end: recentMetrics[recentMetrics.length - 1].timestamp,\n      },\n      breakdown: {\n        audioProcessing: this.calculateAverageBreakdown(recentMetrics, 'audioProcessingLatency'),\n        transcription: this.calculateAverageBreakdown(recentMetrics, 'transcriptionLatency'),\n        middleware: this.calculateAverageBreakdown(recentMetrics, 'middlewareLatency'),\n      },\n    };\n  }\n\n  getRealtimeStatus(): {\n    isHealthy: boolean;\n    currentLatency: number;\n    trend: 'improving' | 'degrading' | 'stable';\n    lastOptimization?: string;\n  } {\n    if (this.metrics.length < 5) {\n      return {\n        isHealthy: true,\n        currentLatency: 0,\n        trend: 'stable',\n      };\n    }\n\n    const recent = this.metrics.slice(-5);\n    const currentLatency = recent[recent.length - 1].audioToEmitLatency;\n    const previousLatency = recent[0].audioToEmitLatency;\n\n    let trend: 'improving' | 'degrading' | 'stable' = 'stable';\n    const trendThreshold = 50; // ms\n\n    if (currentLatency < previousLatency - trendThreshold) {\n      trend = 'improving';\n    } else if (currentLatency > previousLatency + trendThreshold) {\n      trend = 'degrading';\n    }\n\n    return {\n      isHealthy: currentLatency < this.target,\n      currentLatency,\n      trend,\n    };\n  }\n\n  private setupOptimizations(): void {\n    // Optimization 1: Disable expensive middleware when latency is high\n    this.optimizations.push({\n      name: 'middleware-reduction',\n      description: 'Disable non-essential middleware when latency > 400ms',\n      expectedLatencyReduction: 100,\n      condition: (metrics) => metrics.middlewareLatency > 100,\n      apply: async () => {\n        // Signal to disable non-essential middleware\n        this.emit('optimization-trigger', {\n          type: 'disable-middleware',\n          target: ['sentiment', 'intent', 'translation'],\n        });\n      },\n    });\n\n    // Optimization 2: Reduce chunk size when transcription is slow\n    this.optimizations.push({\n      name: 'chunk-size-reduction',\n      description: 'Reduce chunk size when transcription latency > 200ms',\n      expectedLatencyReduction: 80,\n      condition: (metrics) => metrics.transcriptionLatency > 200,\n      apply: async () => {\n        this.emit('optimization-trigger', {\n          type: 'reduce-chunk-size',\n          newSize: 6000, // Reduce from 8s to 6s\n        });\n      },\n    });\n\n    // Optimization 3: Parallel processing when audio processing is slow\n    this.optimizations.push({\n      name: 'parallel-processing',\n      description: 'Enable parallel processing when audio processing > 150ms',\n      expectedLatencyReduction: 60,\n      condition: (metrics) => metrics.audioProcessingLatency > 150,\n      apply: async () => {\n        this.emit('optimization-trigger', {\n          type: 'enable-parallel-processing',\n        });\n      },\n    });\n  }\n\n  private checkForOptimizations(metrics: LatencyMetrics): void {\n    if (metrics.audioToEmitLatency <= this.target) return;\n\n    for (const optimization of this.optimizations) {\n      if (optimization.condition(metrics)) {\n        optimization.apply().catch(() => {});\n        break; // Apply only one optimization at a time\n      }\n    }\n  }\n\n  private getPercentile(sortedArray: number[], percentile: number): number {\n    const index = Math.ceil((percentile / 100) * sortedArray.length) - 1;\n    return sortedArray[Math.max(0, index)];\n  }\n\n  private calculateAverageBreakdown(\n    metrics: LatencyMetrics[],\n    field: keyof LatencyMetrics\n  ): number {\n    const values = metrics.map((m) => m[field] as number).filter((v) => typeof v === 'number');\n    return values.length > 0 ? values.reduce((a, b) => a + b, 0) / values.length : 0;\n  }\n\n  private getEmptyReport(): LatencyReport {\n    return {\n      averageLatency: 0,\n      medianLatency: 0,\n      p95Latency: 0,\n      p99Latency: 0,\n      minLatency: 0,\n      maxLatency: 0,\n      targetMet: true,\n      sampleCount: 0,\n      timeRange: { start: 0, end: 0 },\n      breakdown: {\n        audioProcessing: 0,\n        transcription: 0,\n        middleware: 0,\n      },\n    };\n  }\n\n  // Simple event emitter for optimization triggers\n  private listeners: { [event: string]: ((data: unknown) => void)[] } = {};\n\n  private emit(event: string, data: unknown): void {\n    if (this.listeners[event]) {\n      this.listeners[event].forEach((listener) => listener(data));\n    }\n  }\n\n  on(event: string, listener: (data: unknown) => void): void {\n    if (!this.listeners[event]) {\n      this.listeners[event] = [];\n    }\n    this.listeners[event].push(listener);\n  }\n\n  off(event: string, listener: (data: unknown) => void): void {\n    if (this.listeners[event]) {\n      this.listeners[event] = this.listeners[event].filter((l) => l !== listener);\n    }\n  }\n\n  // Export metrics for analysis\n  exportMetrics(format: 'json' | 'csv' = 'json'): string {\n    if (format === 'csv') {\n      const headers = [\n        'chunkId',\n        'audioToEmitLatency',\n        'audioProcessingLatency',\n        'transcriptionLatency',\n        'middlewareLatency',\n        'timestamp',\n        'vadScore',\n        'audioSize',\n      ].join(',');\n\n      const rows = this.metrics.map((m) =>\n        [\n          m.chunkId,\n          m.audioToEmitLatency,\n          m.audioProcessingLatency,\n          m.transcriptionLatency,\n          m.middlewareLatency,\n          m.timestamp,\n          m.vadScore || '',\n          m.audioSize || '',\n        ].join(',')\n      );\n\n      return [headers, ...rows].join('\\n');\n    }\n\n    return JSON.stringify(this.metrics, null, 2);\n  }\n\n  // Clear metrics (useful for testing)\n  clear(): void {\n    this.metrics = [];\n  }\n\n  // Get current metrics count\n  getMetricsCount(): number {\n    return this.metrics.length;\n  }\n}\n\n// Deprecated singleton removed - use useLatencyMonitor hook instead\n","export interface AlertHandle {\n  update: (config: Partial<AlertConfig>) => void;\n  close: () => void;\n}\n\nexport interface AlertConfig {\n  title: string;\n  message: string;\n  type: 'loading' | 'error' | 'success' | 'warning' | 'info';\n  progress?: number;\n}\n\nexport interface ToastService {\n  success: (message: string) => void;\n  error: (message: string) => void;\n  warning: (message: string) => void;\n  info: (message: string) => void;\n}\n\nexport interface AlertService {\n  show: (config: AlertConfig) => AlertHandle;\n}\n\n// Default implementations (no-op)\nexport const defaultAlertService: AlertService = {\n  show: () => ({\n    update: () => {},\n    close: () => {},\n  }),\n};\n\nexport const defaultToastService: ToastService = {\n  success: () => {},\n  error: () => {},\n  warning: () => {},\n  info: () => {},\n};\n","import { useState, useCallback, useEffect } from 'react';\n\ninterface CacheStatus {\n  hasCache: boolean;\n  cacheSize?: number;\n  lastUpdated?: Date;\n}\n\ninterface UseModelCacheReturn {\n  cacheStatus: CacheStatus;\n  storeModel: (modelId: string, data: ArrayBuffer) => Promise<void>;\n  getModel: (modelId: string) => Promise<ArrayBuffer | null>;\n  hasModel: (modelId: string) => Promise<boolean>;\n  clearCache: () => Promise<void>;\n  getStorageInfo: () => Promise<{ usage: number; quota: number } | null>;\n  requestPersistentStorage: () => Promise<boolean>;\n  refreshCacheStatus: () => Promise<void>;\n}\n\n/**\n * Hook-based model cache manager\n * Replaces the singleton ModelCacheManager with modern React patterns\n */\nexport function useModelCache(): UseModelCacheReturn {\n  const [cacheStatus, setCacheStatus] = useState<CacheStatus>({ hasCache: false });\n\n  const dbName = 'whisper-models-cache';\n  const storeName = 'models';\n  const cacheVersion = 1;\n\n  // Initialize IndexedDB for model storage\n  const initDB = useCallback(async (): Promise<IDBDatabase> => {\n    return new Promise((resolve, reject) => {\n      const request = indexedDB.open(dbName, cacheVersion);\n\n      request.onerror = () => reject(request.error);\n      request.onsuccess = () => resolve(request.result);\n\n      request.onupgradeneeded = (event) => {\n        const db = (event.target as IDBOpenDBRequest).result;\n        if (!db.objectStoreNames.contains(storeName)) {\n          db.createObjectStore(storeName, { keyPath: 'id' });\n        }\n      };\n    });\n  }, [dbName, storeName, cacheVersion]);\n\n  // Store model data in IndexedDB\n  const storeModel = useCallback(\n    async (modelId: string, data: ArrayBuffer): Promise<void> => {\n      const db = await initDB();\n      const transaction = db.transaction([storeName], 'readwrite');\n      const store = transaction.objectStore(storeName);\n\n      return new Promise((resolve, reject) => {\n        const request = store.put({\n          id: modelId,\n          data: data,\n          timestamp: Date.now(),\n          size: data.byteLength,\n        });\n\n        request.onsuccess = () => {\n          resolve();\n          // Refresh cache status after storing\n          refreshCacheStatus();\n        };\n        request.onerror = () => reject(request.error);\n      });\n    },\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    [initDB, storeName]\n  );\n\n  // Retrieve model from IndexedDB\n  const getModel = useCallback(\n    async (modelId: string): Promise<ArrayBuffer | null> => {\n      try {\n        const db = await initDB();\n        const transaction = db.transaction([storeName], 'readonly');\n        const store = transaction.objectStore(storeName);\n\n        return new Promise((resolve) => {\n          const request = store.get(modelId);\n          request.onsuccess = () => {\n            const result = request.result;\n            if (result && result.data) {\n              resolve(result.data);\n            } else {\n              resolve(null);\n            }\n          };\n          request.onerror = () => resolve(null);\n        });\n      } catch (error) {\n        return null;\n      }\n    },\n    [initDB, storeName]\n  );\n\n  // Check if model exists in cache\n  const hasModel = useCallback(\n    async (modelId: string): Promise<boolean> => {\n      const model = await getModel(modelId);\n      return model !== null;\n    },\n    [getModel]\n  );\n\n  // Get cache status\n  const refreshCacheStatus = useCallback(async (): Promise<void> => {\n    try {\n      const db = await initDB();\n      const transaction = db.transaction([storeName], 'readonly');\n      const store = transaction.objectStore(storeName);\n\n      return new Promise((resolve) => {\n        const request = store.getAll();\n        request.onsuccess = () => {\n          const models = request.result;\n\n          if (models.length > 0) {\n            const totalSize = models.reduce(\n              (sum: number, model: any) => sum + (model.size || 0),\n              0\n            );\n            const lastUpdated = new Date(Math.max(...models.map((m: any) => m.timestamp || 0)));\n\n            setCacheStatus({\n              hasCache: true,\n              cacheSize: totalSize,\n              lastUpdated: lastUpdated,\n            });\n          } else {\n            setCacheStatus({ hasCache: false });\n          }\n          resolve();\n        };\n        request.onerror = () => {\n          setCacheStatus({ hasCache: false });\n          resolve();\n        };\n      });\n    } catch (error) {\n      setCacheStatus({ hasCache: false });\n    }\n  }, [initDB, storeName]);\n\n  // Clear all cached models\n  const clearCache = useCallback(async (): Promise<void> => {\n    try {\n      const db = await initDB();\n      const transaction = db.transaction([storeName], 'readwrite');\n      const store = transaction.objectStore(storeName);\n\n      return new Promise((resolve, reject) => {\n        const request = store.clear();\n        request.onsuccess = () => {\n          setCacheStatus({ hasCache: false });\n          resolve();\n        };\n        request.onerror = () => reject(request.error);\n      });\n    } catch (error) {\n      // Silently fail but update cache status\n      setCacheStatus({ hasCache: false });\n    }\n  }, [initDB, storeName]);\n\n  // Get storage estimate\n  const getStorageInfo = useCallback(async (): Promise<{ usage: number; quota: number } | null> => {\n    if ('storage' in navigator && 'estimate' in navigator.storage) {\n      try {\n        const estimate = await navigator.storage.estimate();\n        return {\n          usage: estimate.usage || 0,\n          quota: estimate.quota || 0,\n        };\n      } catch (error) {\n        return null;\n      }\n    }\n    return null;\n  }, []);\n\n  // Request persistent storage\n  const requestPersistentStorage = useCallback(async (): Promise<boolean> => {\n    if ('storage' in navigator && 'persist' in navigator.storage) {\n      try {\n        // Check current persistence status\n        const currentlyPersisted = await navigator.storage.persisted();\n\n        if (currentlyPersisted) {\n          return true;\n        }\n\n        // Request persistence\n        const isPersisted = await navigator.storage.persist();\n\n        // Get storage estimate after persistence request\n        if ('estimate' in navigator.storage) {\n          await navigator.storage.estimate();\n        }\n\n        return isPersisted;\n      } catch (error) {\n        return false;\n      }\n    }\n\n    return false;\n  }, []);\n\n  // Initialize cache status on mount\n  useEffect(() => {\n    refreshCacheStatus();\n  }, [refreshCacheStatus]);\n\n  return {\n    cacheStatus,\n    storeModel,\n    getModel,\n    hasModel,\n    clearCache,\n    getStorageInfo,\n    requestPersistentStorage,\n    refreshCacheStatus,\n  };\n}\n","/**\n * Audio Processing Constants\n * Centralized configuration for all audio-related magic numbers\n */\n\nexport const AUDIO_CONFIG = {\n  // Sample rates\n  SAMPLE_RATE: 44100,\n  ALTERNATIVE_SAMPLE_RATE: 48000,\n\n  // VAD Configuration\n  VAD: {\n    FRAME_SAMPLES: 1536, // 32ms at 48kHz\n    POSITIVE_THRESHOLD: 0.6,\n    NEGATIVE_THRESHOLD: 0.4,\n    MIN_SPEECH_DURATION_MS: 250,\n    PRE_SPEECH_PAD_FRAMES: 1,\n    POST_SPEECH_PAD_FRAMES: 1,\n  },\n\n  // Recording Configuration\n  RECORDING: {\n    DEFAULT_CHUNK_DURATION_MS: 8000,\n    STREAMING_CHUNK_DURATION_MS: 3000,\n    MIN_CHUNK_DURATION_MS: 1000,\n    MAX_CHUNK_DURATION_MS: 30000,\n  },\n\n  // Timeouts\n  TIMEOUTS: {\n    MODEL_DOWNLOAD_MS: 180000, // 3 minutes\n    TRANSCRIPTION_MS: 120000, // 2 minutes\n    CHUNK_EMISSION_MS: 2000,\n    ENGINE_RESET_DELAY_MS: 100,\n    DEPENDENCY_PRELOAD_MS: 2000,\n  },\n\n  // Buffer sizes\n  BUFFERS: {\n    AUDIO_WORKLET_SIZE: 128,\n    PROCESSING_BUFFER_SIZE: 4096,\n    MAX_AUDIO_CHUNKS: 50,\n  },\n\n  // Thresholds\n  THRESHOLDS: {\n    MIN_AUDIO_LEVEL: 0.01,\n    SILENCE_THRESHOLD: 0.02,\n    NOISE_GATE: 0.001,\n  },\n\n  // WebGPU/Performance\n  PERFORMANCE: {\n    WEBGPU_PREFERRED: true,\n    QUANTIZATION_BITS: 4,\n    MAX_CONCURRENT_WORKERS: 4,\n  },\n} as const;\n\nexport const WHISPER_CONFIG = {\n  // Model configurations\n  MODELS: {\n    DISTIL_LARGE_V3: 'Xenova/distil-whisper/distil-large-v3',\n    FALLBACK: ['whisper-tiny', 'Xenova/whisper-base', 'Xenova/whisper-small'],\n  },\n\n  // Processing\n  CHUNK_LENGTH_S: 30,\n  STRIDE_LENGTH_S: 5,\n\n  // Cache\n  CACHE_DIR: 'transformers-cache',\n  USE_BROWSER_CACHE: true,\n} as const;\n\nexport const ERROR_MESSAGES = {\n  ENGINE_INIT_FAILED: 'Failed to initialize audio engine',\n  TRANSCRIPTION_FAILED: 'Transcription failed',\n  VAD_ANALYSIS_FAILED: 'VAD analysis failed',\n  RECORDING_FAILED: 'Failed to start recording',\n  STREAM_ACCESS_DENIED: 'Microphone access denied',\n  MODEL_LOAD_FAILED: 'Failed to load Whisper model',\n  AUDIO_CONTEXT_FAILED: 'Failed to create audio context',\n} as const;\n","/**\n * Error Handling Utilities\n * Centralized error handling for audio processing\n */\n\nimport { useState, useCallback } from 'react';\n\nexport class AudioProcessingError extends Error {\n  constructor(\n    message: string,\n    public readonly context: string,\n    public readonly originalError?: unknown,\n    public readonly recoverable: boolean = true\n  ) {\n    super(message);\n    this.name = 'AudioProcessingError';\n  }\n}\n\nexport class TranscriptionError extends AudioProcessingError {\n  constructor(message: string, originalError?: unknown) {\n    super(message, 'transcription', originalError);\n    this.name = 'TranscriptionError';\n  }\n}\n\nexport class RecordingError extends AudioProcessingError {\n  constructor(message: string, originalError?: unknown) {\n    super(message, 'recording', originalError, false);\n    this.name = 'RecordingError';\n  }\n}\n\nexport class VADError extends AudioProcessingError {\n  constructor(message: string, originalError?: unknown) {\n    super(message, 'vad', originalError);\n    this.name = 'VADError';\n  }\n}\n\n/**\n * Unified error handler for audio processing operations\n */\nexport const handleAudioError = (\n  error: unknown,\n  context: string,\n  fallbackMessage?: string\n): never => {\n  const errorMessage = error instanceof Error ? error.message : String(error);\n  const finalMessage = fallbackMessage || errorMessage;\n\n  throw new AudioProcessingError(finalMessage, context, error);\n};\n\n/**\n * Safe error handler that logs but doesn't throw\n */\nexport const logAudioError = (\n  error: unknown,\n  context: string,\n  logger?: (message: string, type: string) => void\n): void => {\n  const errorMessage = error instanceof Error ? error.message : String(error);\n  const logMessage = `[${context.toUpperCase()}] Error: ${errorMessage}`;\n\n  if (logger) {\n    logger(logMessage, 'error');\n  }\n};\n\n/**\n * Extract error message from unknown error type\n */\nexport const getErrorMessage = (error: unknown): string => {\n  if (error instanceof Error) {\n    return error.message;\n  }\n  if (typeof error === 'string') {\n    return error;\n  }\n  if (error && typeof error === 'object' && 'message' in error) {\n    return String(error.message);\n  }\n  return 'Unknown error occurred';\n};\n\n/**\n * Retry handler for transient failures\n */\nexport const retryWithBackoff = async <T>(\n  operation: () => Promise<T>,\n  maxRetries: number = 3,\n  initialDelay: number = 1000,\n  context: string = 'operation'\n): Promise<T> => {\n  let lastError: unknown;\n\n  for (let attempt = 0; attempt < maxRetries; attempt++) {\n    try {\n      return await operation();\n    } catch (error) {\n      lastError = error;\n\n      if (attempt < maxRetries - 1) {\n        const delay = initialDelay * Math.pow(2, attempt);\n        await new Promise((resolve) => setTimeout(resolve, delay));\n      }\n    }\n  }\n\n  throw new AudioProcessingError(`Failed after ${maxRetries} attempts`, context, lastError, false);\n};\n\n/**\n * Error boundary hook for React components\n */\nexport const useErrorHandler = () => {\n  const [error, setError] = useState<AudioProcessingError | null>(null);\n\n  const handleError = useCallback((error: unknown, context: string) => {\n    const audioError =\n      error instanceof AudioProcessingError\n        ? error\n        : new AudioProcessingError(getErrorMessage(error), context, error);\n\n    setError(audioError);\n  }, []);\n\n  const resetError = useCallback(() => {\n    setError(null);\n  }, []);\n\n  return { error, handleError, resetError };\n};\n"],"mappings":"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","names":["useCallback","useEffect","useRef","useState","useState","useRef","useEffect","useCallback","loadMurmubaraProcessing","useState","useCallback","useEffect","useState","useCallback","error"]}