{"version":3,"sources":["../src/engines/mlc-engine-wrapper.ts","../src/libs/transformers/env.ts","../src/libs/transformers/utils/generic.ts","../src/libs/transformers/utils/core.ts","../src/libs/transformers/utils/hub.ts","../src/libs/transformers/utils/maths.ts","../src/libs/transformers/backends/onnx.ts","../src/libs/transformers/ops/registry.ts","../src/libs/transformers/utils/tensor.ts","../src/libs/transformers/utils/data-structures.ts","../src/libs/transformers/tokenizers.ts","../src/libs/transformers/models/whisper/common_whisper.ts","../src/libs/transformers/configs.ts","../src/libs/transformers/utils/devices.ts","../src/libs/transformers/utils/dtypes.ts","../src/libs/transformers/utils/constants.ts","../src/libs/transformers/generation/logits_process.ts","../src/libs/transformers/generation/configuration_utils.ts","../src/libs/transformers/utils/image.ts","../src/libs/transformers/generation/stopping_criteria.ts","../src/libs/transformers/generation/logits_sampler.ts","../src/libs/transformers/models/whisper/generation_whisper.ts","../src/libs/transformers/models.ts","../src/libs/transformers/base/processing_utils.ts","../src/libs/transformers/models/processors.ts","../src/libs/transformers/base/image_processors_utils.ts","../src/libs/transformers/models/janus/image_processing_janus.ts","../src/libs/transformers/models/auto/image_processing_auto.ts","../src/libs/transformers/models/florence2/processing_florence2.ts","../src/libs/transformers/models/idefics3/processing_idefics3.ts","../src/libs/transformers/models/mgp_str/processing_mgp_str.ts","../src/libs/transformers/models/feature_extractors.ts","../src/libs/transformers/base/feature_extraction_utils.ts","../src/libs/transformers/utils/audio.ts","../src/libs/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.ts","../src/libs/transformers/models/clap/feature_extraction_clap.ts","../src/libs/transformers/models/moonshine/feature_extraction_moonshine.ts","../src/libs/transformers/models/pyannote/feature_extraction_pyannote.ts","../src/libs/transformers/models/seamless_m4t/feature_extraction_seamless_m4t.ts","../src/libs/transformers/models/speecht5/feature_extraction_speecht5.ts","../src/libs/transformers/models/wav2vec2/feature_extraction_wav2vec2.ts","../src/libs/transformers/models/wespeaker/feature_extraction_wespeaker.ts","../src/libs/transformers/models/whisper/feature_extraction_whisper.ts","../src/libs/transformers/models/auto/feature_extraction_auto.ts","../src/libs/transformers/models/moonshine/processing_moonshine.ts","../src/libs/transformers/models/janus/processing_janus.ts","../src/libs/transformers/models/jina_clip/processing_jina_clip.ts","../src/libs/transformers/models/phi3_v/processing_phi3_v.ts","../src/libs/transformers/models/paligemma/processing_paligemma.ts","../src/libs/transformers/models/pyannote/processing_pyannote.ts","../src/libs/transformers/models/qwen2_vl/processing_qwen2_vl.ts","../src/libs/transformers/models/sam/processing_sam.ts","../src/libs/transformers/models/speecht5/processing_speecht5.ts","../src/libs/transformers/models/wav2vec2/processing_wav2vec2.ts","../src/libs/transformers/models/whisper/processing_whisper.ts","../src/libs/transformers/models/image_processors.ts","../src/libs/transformers/models/bit/image_processing_bit.ts","../src/libs/transformers/models/chinese_clip/image_processing_chinese_clip.ts","../src/libs/transformers/models/clip/image_processing_clip.ts","../src/libs/transformers/models/convnext/image_processing_convnext.ts","../src/libs/transformers/models/deit/image_processing_deit.ts","../src/libs/transformers/models/idefics3/image_processing_idefics3.ts","../src/libs/transformers/models/jina_clip/image_processing_jina_clip.ts","../src/libs/transformers/models/llava_onevision/image_processing_llava_onevision.ts","../src/libs/transformers/models/phi3_v/image_processing_phi3_v.ts","../src/libs/transformers/models/qwen2_vl/image_processing_qwen2_vl.ts","../src/libs/transformers/models/sam/image_processing_sam.ts","../src/libs/transformers/models/siglip/image_processing_siglip.ts","../src/libs/transformers/models/swin2sr/image_processing_swin2sr.ts","../src/libs/transformers/models/vitmatte/image_processing_vitmatte.ts","../src/libs/transformers/models/vitpose/image_processing_vitpose.ts","../src/libs/transformers/models/auto/processing_auto.ts","../src/libs/transformers/pipelines.ts","../src/libs/transformers/generation/streamers.ts","../src/libs/transformers/utils/phonemize.ts","../src/libs/transformers/utils/voices.ts","../src/engines/tts-engine.ts","../src/engines/transformer-engine-wrapper.ts","../src/config/models/mlc-models.json","../src/config/models/transformers-models.json","../src/core/llm/index.ts","../src/core/database/implementation/indexeddb.ts","../src/core/database/implementation/sqlite.ts","../src/core/database/index.ts","../src/core/agent/html-cleaner.ts","../src/core/agent/content-identifier.ts","../src/core/agent/types.ts","../src/core/agent/browser-agent.ts","../src/core/agent/dom-analyzer.ts","../src/core/agent/browser-actions.ts","../src/core/parsers/pdf.ts","../src/core/parsers/csv.ts","../src/core/parsers/docx.ts","../src/core/parsers/image.ts"],"sourcesContent":["// src/engines/mlc-engine-wrapper.ts\nimport { \n  CreateMLCEngine, \n  MLCEngineInterface, \n  AppConfig, \n  modelLibURLPrefix, \n  modelVersion, \n  prebuiltAppConfig,\n  CreateWebWorkerMLCEngine\n} from '@mlc-ai/web-llm';\nimport { ModelConfig } from '../config/models/types';\n\n// Add this worker code as a string at the top of the file\nconst workerCode = `\n  // Ensure we're in a worker context\n  if (typeof self === 'undefined') {\n    throw new Error('This script must be run in a Web Worker');\n  }\n\n  console.log('[Worker] Starting initialization...');\n\n  // Wrap the entire worker code in a try-catch\n  try {\n    // Wait for the main thread to send us the module URL\n    self.onmessage = async (msg) => {\n      if (msg.data.type === 'init') {\n        console.log('[Worker] Received init message');\n        const moduleURL = msg.data.moduleURL;\n        \n        try {\n          const module = await import(moduleURL);\n          console.log('[Worker] Module loaded successfully');\n          const handler = new module.WebWorkerMLCEngineHandler();\n          \n          // Replace onmessage handler with the actual handler\n          self.onmessage = (msg) => {\n            console.log('[Worker] Received message:', msg.data);\n            try {\n              handler.onmessage(msg);\n            } catch (error) {\n              console.error('[Worker] Handler error:', error);\n              self.postMessage({\n                type: 'error',\n                error: error instanceof Error ? error.message : String(error)\n              });\n            }\n          };\n          \n          self.postMessage({ type: 'ready' });\n          console.log('[Worker] Handler initialized successfully');\n        } catch (error) {\n          console.error('[Worker] Failed to load module:', error);\n          self.postMessage({\n            type: 'error',\n            error: 'Failed to initialize worker: ' + (error instanceof Error ? error.message : String(error))\n          });\n        }\n      }\n    };\n  } catch (error) {\n    console.error('[Worker] Initialization error:', error);\n    self.postMessage({\n      type: 'error',\n      error: 'Worker initialization failed: ' + (error instanceof Error ? error.message : String(error))\n    });\n  }\n\n  self.onerror = (error) => {\n    console.error('[Worker] Global error:', error);\n    self.postMessage({\n      type: 'error',\n      error: error instanceof ErrorEvent ? error.message : 'Unknown worker error'\n    });\n  };\n\n  self.onmessageerror = (error) => {\n    console.error('[Worker] Message error:', error);\n    self.postMessage({\n      type: 'error',\n      error: 'Message error: ' + (error instanceof Error ? error.message : String(error))\n    });\n  };\n\n  console.log('[Worker] Basic initialization complete');\n`;\n\ninterface MLCLoadModelOptions {\n  useWorker?: boolean;\n  onProgress?: (progress: any) => void;\n  quantization?: string;\n  [key: string]: any;\n}\n\n// Add a helper class to manage the model cache with LRU strategy\nclass MLCModelCacheManager {\n  private static instance: MLCModelCacheManager;\n  private modelQueue: string[] = [];\n  private modelSizes: Map<string, number> = new Map(); // Track size of each model\n  private maxCacheSize = 1024 * 1024 * 1024; // 1GB max cache size (adjust as needed)\n  private readonly cacheThreshold = 0.8; // 80% threshold for cleanup\n  private currentCacheSize = 0;\n\n  private constructor() {\n    // Calculate the current cache size\n    this.calculateCacheSizeAsync();\n    \n    // Also estimate available storage and adjust max cache size\n    this.estimateAvailableStorageAndSetLimit();\n  }\n\n  public static getInstance(): MLCModelCacheManager {\n    if (!MLCModelCacheManager.instance) {\n      MLCModelCacheManager.instance = new MLCModelCacheManager();\n    }\n    return MLCModelCacheManager.instance;\n  }\n\n  // Scan all caches to calculate total size\n  private async calculateCacheSizeAsync(): Promise<void> {\n    try {\n      const cacheNames = ['webllm/config', 'webllm/wasm', 'webllm/model'];\n      this.currentCacheSize = 0;\n      this.modelSizes.clear();\n      \n      // Map to collect all URLs by model ID for debugging\n      const modelUrlMap: Map<string, string[]> = new Map();\n      \n      // Map to track original model IDs to normalized ones\n      const normalizedModelMap: Map<string, string> = new Map();\n      \n      console.log('Beginning cache calculation...');\n      \n      for (const cacheName of cacheNames) {\n        console.log(`Scanning cache: ${cacheName}`);\n        const cache = await caches.open(cacheName);\n        const keys = await cache.keys();\n        \n        console.log(`Found ${keys.length} entries in ${cacheName}`);\n        \n        for (const key of keys) {\n          const response = await cache.match(key);\n          if (!response) continue;\n          \n          const blob = await response.blob();\n          const size = blob.size;\n          this.currentCacheSize += size;\n          \n          // Try to determine which model this entry belongs to\n          const url = key.url;\n          \n          // Extract the raw model ID from the URL\n          let rawModelId = this.extractRawModelId(url);\n          \n          if (rawModelId) {\n            // Normalize the model ID to avoid duplicates\n            let normalizedModelId = this.normalizeModelId(rawModelId);\n            \n            // Track the normalization for debugging\n            if (!normalizedModelMap.has(rawModelId)) {\n              normalizedModelMap.set(rawModelId, normalizedModelId);\n            }\n            \n            // Track URLs for debugging\n            if (!modelUrlMap.has(normalizedModelId)) {\n              modelUrlMap.set(normalizedModelId, []);\n            }\n            modelUrlMap.get(normalizedModelId)?.push(url);\n            \n            if (!this.modelSizes.has(normalizedModelId)) {\n              this.modelSizes.set(normalizedModelId, 0);\n              if (!this.modelQueue.includes(normalizedModelId)) {\n                this.modelQueue.push(normalizedModelId);\n              }\n            }\n            this.modelSizes.set(normalizedModelId, (this.modelSizes.get(normalizedModelId) || 0) + size);\n          } else {\n            console.log(`Couldn't determine model for URL: ${url}`);\n          }\n        }\n      }\n      \n      // Print detailed debug info\n      console.log('--- MODEL CACHE DEBUG INFO ---');\n      console.log(`Total cache size: ${this.formatBytes(this.currentCacheSize)}`);\n      console.log(`Models in modelQueue: ${this.modelQueue.length}`);\n      console.log(`Models in modelSizes map: ${this.modelSizes.size}`);\n      \n      // Normalize the model queue to ensure consistency\n      this.normalizeModelQueue();\n      \n      console.log('Raw to normalized model mapping:');\n      for (const [raw, normalized] of normalizedModelMap.entries()) {\n        console.log(`- ${raw} → ${normalized}`);\n      }\n      \n      console.log('Detected models:');\n      for (const [modelId, size] of this.modelSizes.entries()) {\n        console.log(`- ${modelId}: ${this.formatBytes(size)} (${modelUrlMap.get(modelId)?.length || 0} files)`);\n      }\n      \n      console.log('LRU Queue order (oldest to newest):');\n      this.modelQueue.forEach((id, index) => {\n        console.log(`${index + 1}. ${id}`);\n      });\n      \n      console.log(`Cache calculated. Total size: ${this.formatBytes(this.currentCacheSize)}, Models: ${this.modelQueue.length}`);\n    } catch (error) {\n      console.error('Error calculating cache size:', error);\n    }\n  }\n  \n  // Extract raw model ID from URL using patterns based on the model config\n  private extractRawModelId(url: string): string | null {\n    // Special cases for specific model families to maintain version numbers\n    \n    // Llama models (llama-3.2-1b-instruct, llama-3.2-3b-instruct)\n    const llamaPattern = /\\/(Llama-3\\.2-\\d+[Bb]-Instruct)/i;\n    const llamaMatch = url.match(llamaPattern);\n    if (llamaMatch && llamaMatch[1]) {\n      return llamaMatch[1];\n    }\n    \n    // Hermes models (hermes-llama-3.2-3b)\n    const hermesPattern = /\\/(Hermes-\\d+-Llama-\\d+\\.\\d+-\\d+[Bb])/i;\n    const hermesMatch = url.match(hermesPattern);\n    if (hermesMatch && hermesMatch[1]) {\n      return hermesMatch[1];\n    }\n    \n    // Qwen models (qwen2.5-0.5b-instruct, qwen2.5-1.5b-instruct, qwen2.5-3b-instruct)\n    const qwenPattern = /\\/(Qwen2(?:\\.5)?-\\d+\\.?\\d*[Bb]-Instruct)/i;\n    const qwenMatch = url.match(qwenPattern);\n    if (qwenMatch && qwenMatch[1]) {\n      return qwenMatch[1];\n    }\n    \n    // SmolLM models (smollm2-135m-instruct, smollm2-360m-instruct, smollm2-1.7b-instruct)\n    const smolLMPattern = /\\/(SmolLM2-\\d+\\.?\\d*[BbMG]-Instruct)/i;\n    const smolLMMatch = url.match(smolLMPattern);\n    if (smolLMMatch && smolLMMatch[1]) {\n      return smolLMMatch[1];\n    }\n    \n    // Gemma models (gemma-2b-it)\n    const gemmaPattern = /\\/(gemma-\\d+[Bb]-it)/i;\n    const gemmaMatch = url.match(gemmaPattern);\n    if (gemmaMatch && gemmaMatch[1]) {\n      return gemmaMatch[1];\n    }\n    \n    // TinyLlama models (tinyllama-1.1b-chat-v0.4)\n    const tinyLlamaPattern = /\\/(TinyLlama-\\d+\\.?\\d*[Bb]-Chat-v[\\d\\.]+)/i;\n    const tinyLlamaMatch = url.match(tinyLlamaPattern);\n    if (tinyLlamaMatch && tinyLlamaMatch[1]) {\n      return tinyLlamaMatch[1];\n    }\n    \n    // Phi models (phi-3.5-mini-instruct)\n    const phiPattern = /\\/(Phi-\\d+\\.?\\d+-\\w+-\\w+)/i;\n    const phiMatch = url.match(phiPattern);\n    if (phiMatch && phiMatch[1]) {\n      return phiMatch[1];\n    }\n    \n    // DeepSeek models (deepseek-r1-distill-qwen-1.5b, deepseek-r1-distill-qwen-7b, deepseek-r1-distill-llama-8b)\n    const deepSeekPattern = /\\/(DeepSeek-R1-Distill-(?:Qwen|Llama)-\\d+\\.?\\d*[Bb])/i;\n    const deepSeekMatch = url.match(deepSeekPattern);\n    if (deepSeekMatch && deepSeekMatch[1]) {\n      return deepSeekMatch[1];\n    }\n    \n    // Snowflake arctic embed models (snowflake-arctic-embed-m-b4, snowflake-arctic-embed-s-b4, etc.)\n    const snowflakePattern = /\\/(snowflake-arctic-embed-[ms])(?:-b\\d+)?/i;\n    const snowflakeMatch = url.match(snowflakePattern);\n    if (snowflakeMatch && snowflakeMatch[1]) {\n      return snowflakeMatch[1];\n    }\n    \n    // Fallback for models with quantization and MLC suffix\n    const mlcPattern = /\\/([A-Za-z0-9\\.\\-]+(?:-\\d+\\.?\\d*[BbMG])(?:-[A-Za-z0-9\\.\\-]+)?)-[qQ]\\d[fF]\\d+(?:_\\d+)?-MLC/;\n    const mlcMatch = url.match(mlcPattern);\n    if (mlcMatch && mlcMatch[1]) {\n      return mlcMatch[1];\n    }\n    \n    // Fallback for models with just quantization\n    const quantPattern = /\\/([A-Za-z0-9\\.\\-]+(?:-\\d+\\.?\\d*[BbMG])(?:-[A-Za-z0-9\\.\\-]+)?)-[qQ]\\d[fF]\\d+(?:_\\d+)?/;\n    const quantMatch = url.match(quantPattern);\n    if (quantMatch && quantMatch[1]) {\n      return quantMatch[1];\n    }\n    \n    // Fallback for any other model pattern\n    const genericPattern = /\\/([A-Za-z0-9\\.\\-]+(?:-\\d+\\.?\\d*[BbMG])(?:-[A-Za-z0-9\\.\\-]+)?)/;\n    const genericMatch = url.match(genericPattern);\n    if (genericMatch && genericMatch[1]) {\n      return genericMatch[1];\n    }\n    \n    return null;\n  }\n\n  // Normalize model ID while preserving all important version information\n  private normalizeModelId(rawModelId: string): string {\n    // First, make case-insensitive\n    const lowerCaseId = rawModelId.toLowerCase();\n    \n    // Handle specific model families\n    \n    // Llama models\n    if (lowerCaseId.includes('llama-3.2') && lowerCaseId.includes('instruct')) {\n      const match = rawModelId.match(/(Llama-3\\.2-\\d+[Bb])-Instruct/i);\n      if (match) return match[1] + '-Instruct';\n    }\n    \n    // Hermes models\n    if (lowerCaseId.includes('hermes') && lowerCaseId.includes('llama')) {\n      const match = rawModelId.match(/(Hermes-\\d+-Llama-\\d+\\.\\d+-\\d+[Bb])/i);\n      if (match) return match[1];\n    }\n    \n    // Qwen models - CRUCIAL to maintain version differences\n    if (lowerCaseId.includes('qwen')) {\n      // Preserve the full Qwen version\n      if (lowerCaseId.includes('qwen2.5')) {\n        const match = rawModelId.match(/(Qwen2\\.5-\\d+\\.?\\d*[Bb])-Instruct/i);\n        if (match) return match[1] + '-Instruct';\n      } else if (lowerCaseId.includes('qwen2')) {\n        const match = rawModelId.match(/(Qwen2-\\d+\\.?\\d*[Bb])-Instruct/i);\n        if (match) return match[1] + '-Instruct';\n      }\n    }\n    \n    // SmolLM models\n    if (lowerCaseId.includes('smollm')) {\n      const match = rawModelId.match(/(SmolLM2-\\d+\\.?\\d*[BbMG])(-Instruct)?/i);\n      if (match) return match[1] + (match[2] || '');\n    }\n    \n    // Gemma models\n    if (lowerCaseId.includes('gemma')) {\n      const match = rawModelId.match(/(gemma-\\d+[Bb])-it/i);\n      if (match) return match[1] + '-it';\n    }\n    \n    // TinyLlama models\n    if (lowerCaseId.includes('tinyllama')) {\n      const match = rawModelId.match(/(TinyLlama-\\d+\\.?\\d*[Bb]-Chat-v[\\d\\.]+)/i);\n      if (match) return match[1];\n    }\n    \n    // Phi models\n    if (lowerCaseId.includes('phi')) {\n      const match = rawModelId.match(/(Phi-\\d+\\.?\\d+-\\w+-\\w+)/i);\n      if (match) return match[1];\n    }\n    \n    // DeepSeek models\n    if (lowerCaseId.includes('deepseek')) {\n      const match = rawModelId.match(/(DeepSeek-R1-Distill-(?:Qwen|Llama)-\\d+\\.?\\d*[Bb])/i);\n      if (match) return match[1];\n    }\n    \n    // Snowflake models - keep base model but remove batch size\n    if (lowerCaseId.includes('snowflake')) {\n      const match = rawModelId.match(/(snowflake-arctic-embed-[ms])/i);\n      if (match) return match[1];\n    }\n    \n    // Generic fallback: remove quantization and other suffixes\n    let normalizedId = rawModelId\n      .replace(/-q\\d+f\\d+(_\\d+)?(-MLC)?$/i, '')  // Remove quantization\n      .replace(/-MLC$/i, '');                    // Remove MLC suffix\n    \n    // Remove batch size suffixes\n    normalizedId = normalizedId.replace(/-b\\d+$/i, '');\n    \n    return normalizedId;\n  }\n\n  // Format bytes to human-readable format\n  private formatBytes(bytes: number): string {\n    if (bytes === 0) return '0 Bytes';\n    const k = 1024;\n    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n    const i = Math.floor(Math.log(bytes) / Math.log(k));\n    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n  }\n\n  // Mark a model as recently used or add it to the queue\n  public touchModel(modelIdentifier: string): void {\n    // Normalize the model identifier\n    const normalizedId = this.normalizeModelId(modelIdentifier);\n    \n    // Remove the model if it's already in the queue (using normalized ID)\n    this.modelQueue = this.modelQueue.filter(id => this.normalizeModelId(id) !== normalizedId);\n    \n    // Add to the end (most recently used position)\n    this.modelQueue.push(normalizedId);\n    \n    // Schedule a cache check (but don't await it to avoid blocking)\n    setTimeout(() => {\n      this.checkCacheSizeAndCleanup();\n    }, 0);\n  }\n  \n  // Check if cache exceeds threshold and clean up if needed\n  private async checkCacheSizeAndCleanup(): Promise<void> {\n    await this.calculateCacheSizeAsync();\n    \n    if (this.currentCacheSize > this.maxCacheSize * this.cacheThreshold) {\n      console.log(`Cache size (${this.formatBytes(this.currentCacheSize)}) exceeds ${this.cacheThreshold * 100}% threshold (${this.formatBytes(this.maxCacheSize * this.cacheThreshold)})`);\n      \n      // If we have more than one model, remove oldest until we're under threshold\n      while (this.modelQueue.length > 1 && this.currentCacheSize > this.maxCacheSize * this.cacheThreshold) {\n        const oldestModel = this.modelQueue.shift();\n        if (oldestModel) {\n          // Ensure we're using the normalized ID\n          const normalizedId = this.normalizeModelId(oldestModel);\n          console.log(`Removing least recently used model: ${normalizedId}`);\n          await this.removeModelFromCache(normalizedId);\n          await this.calculateCacheSizeAsync();\n        }\n      }\n    }\n  }\n\n  // Delete a specific model from cache\n  public async removeModelFromCache(modelIdentifier: string): Promise<void> {\n    try {\n      const cacheNames = ['webllm/config', 'webllm/wasm', 'webllm/model'];\n      \n      // Normalize the input model identifier\n      const normalizedModelId = this.normalizeModelId(modelIdentifier);\n      console.log(`Removing model: ${modelIdentifier} (normalized: ${normalizedModelId})`);\n      \n      for (const cacheName of cacheNames) {\n        const cache = await caches.open(cacheName);\n        const keys = await cache.keys();\n        \n        const modelKeys = keys.filter(request => {\n          const url = request.url;\n          const rawModelId = this.extractRawModelId(url);\n          if (rawModelId) {\n            const urlNormalizedId = this.normalizeModelId(rawModelId);\n            return urlNormalizedId === normalizedModelId;\n          }\n          return false;\n        });\n        \n        console.log(`Found ${modelKeys.length} entries to remove from ${cacheName}`);\n        \n        // Delete all entries for this model from the current cache\n        await Promise.all(modelKeys.map(key => cache.delete(key)));\n      }\n      \n      console.log(`Successfully removed model ${normalizedModelId} from cache`);\n      \n      // Also remove from our tracking data structures\n      this.modelSizes.delete(normalizedModelId);\n      this.modelQueue = this.modelQueue.filter(id => id !== normalizedModelId);\n    } catch (error) {\n      console.error(`Error removing model ${modelIdentifier} from cache:`, error);\n      throw error;\n    }\n  }\n  \n  // Get current cache statistics with additional debug info\n  public async getCacheInfo(): Promise<{\n    totalSize: number,\n    maxSize: number,\n    usedPercent: number,\n    models: {id: string, size: number, position: number}[],\n    debug: {\n      modelQueueLength: number,\n      modelSizesLength: number,\n      modelQueue: string[]\n    }\n  }> {\n    await this.calculateCacheSizeAsync();\n    \n    return {\n      totalSize: this.currentCacheSize,\n      maxSize: this.maxCacheSize,\n      usedPercent: (this.currentCacheSize / this.maxCacheSize) * 100,\n      models: Array.from(this.modelSizes.entries()).map(([id, size]) => ({\n        id,\n        size,\n        position: this.modelQueue.indexOf(id) + 1\n      })),\n      debug: {\n        modelQueueLength: this.modelQueue.length,\n        modelSizesLength: this.modelSizes.size,\n        modelQueue: [...this.modelQueue]\n      }\n    };\n  }\n\n  // Normalize the entire model queue to ensure consistency\n  private normalizeModelQueue(): void {\n    // Create a new queue with normalized IDs\n    const normalizedQueue: string[] = [];\n    const seenNormalizedIds = new Set<string>();\n    \n    // Process from oldest to newest to maintain LRU order\n    for (const id of this.modelQueue) {\n      const normalizedId = this.normalizeModelId(id);\n      \n      // Only add each normalized ID once (most recent position)\n      if (!seenNormalizedIds.has(normalizedId)) {\n        normalizedQueue.push(normalizedId);\n        seenNormalizedIds.add(normalizedId);\n      }\n    }\n    \n    // Replace the queue with the normalized version\n    this.modelQueue = normalizedQueue;\n    \n    console.log(`Normalized model queue. New length: ${this.modelQueue.length}`);\n  }\n\n  // Estimate available storage and set the cache limit\n  private async estimateAvailableStorageAndSetLimit(): Promise<void> {\n    try {\n      // Check if the Storage API is available\n      if ('storage' in navigator && 'estimate' in navigator.storage) {\n        const estimate = await navigator.storage.estimate();\n        const quota = estimate.quota || 0;\n        const usage = estimate.usage || 0;\n        \n        // Available space is quota minus usage\n        const availableBytes = quota - usage;\n        \n        // Log the storage information\n        console.log(`Storage quota: ${this.formatBytes(quota)}`);\n        console.log(`Current storage usage: ${this.formatBytes(usage)}`);\n        console.log(`Available storage: ${this.formatBytes(availableBytes)}`);\n        \n        // Set our max cache size to 60% of available space, but cap it at 5GB\n        const calculatedMax = Math.min(availableBytes * 0.6, 5 * 1024 * 1024 * 1024);\n        \n        // Ensure we have at least 500MB cache size\n        this.maxCacheSize = Math.max(calculatedMax, 500 * 1024 * 1024);\n        \n        console.log(`Set max cache size to ${this.formatBytes(this.maxCacheSize)} (60% of available space)`);\n      } else {\n        // If Storage API isn't available, use a reasonable default\n        this.maxCacheSize = 1024 * 1024 * 1024; // 1GB default\n        console.log(`Storage API not available. Using default max cache size: ${this.formatBytes(this.maxCacheSize)}`);\n      }\n    } catch (error) {\n      // If there's an error, fall back to a default size\n      this.maxCacheSize = 1024 * 1024 * 1024; // 1GB default\n      console.error('Error estimating storage:', error);\n      console.log(`Using default max cache size: ${this.formatBytes(this.maxCacheSize)}`);\n    }\n  }\n}\n\nexport class MLCEngineWrapper {\n  private mlcEngine: MLCEngineInterface | null = null;\n  private appConfig: AppConfig | null = null;\n  private worker: Worker | null = null;\n  private cacheManager = MLCModelCacheManager.getInstance();\n\n  constructor() {\n    this.mlcEngine = null;\n  }\n\n  async loadModel(modelConfig: ModelConfig, options: MLCLoadModelOptions = {}) {\n    try {\n      if (this.worker) {\n        this.worker.terminate();\n        this.worker = null;\n      }\n\n      if (options.useWorker) {\n        // console.log('[MLCEngine] Creating new worker');\n        \n        const blob = new Blob([workerCode], { type: 'text/javascript' });\n        const workerUrl = URL.createObjectURL(blob);\n        \n        this.worker = new Worker(workerUrl, { \n          type: 'module',\n          name: 'mlc-worker' \n        });\n        \n        URL.revokeObjectURL(workerUrl);\n\n        this.worker.onerror = (error) => {\n          console.error('[MLCEngine] Worker error:', error);\n          throw new Error(`Worker error: ${error.message}`);\n        };\n\n        this.worker.onmessageerror = (error) => {\n          console.error('[MLCEngine] Worker message error:', error);\n        };\n\n        // Wait for worker to be ready\n        await new Promise<void>((resolve, reject) => {\n          if (!this.worker) return reject(new Error('Worker not initialized'));\n\n          const timeout = setTimeout(() => {\n            reject(new Error('Worker initialization timeout'));\n          }, 10000);\n\n          this.worker.onmessage = (msg) => {\n            // console.log('[MLCEngine] Received worker message:', msg.data);\n            if (msg.data.type === 'ready') {\n              clearTimeout(timeout);\n              resolve();\n            } else if (msg.data.type === 'error') {\n              clearTimeout(timeout);\n              reject(new Error(msg.data.error));\n            }\n          };\n\n          // Fix for import.meta.url in CJS environment\n          let moduleURL;\n          try {\n            // Try the ESM approach first\n            moduleURL = new URL('@mlc-ai/web-llm', import.meta.url).href;\n          } catch (e) {\n            // Fallback for CJS environment\n            moduleURL = '@mlc-ai/web-llm';\n            console.log('[MLCEngine] Using module name as fallback for CJS environment');\n          }\n          \n          // Send init message with module URL\n          this.worker.postMessage({\n            type: 'init',\n            moduleURL\n          });\n        });\n\n        // console.log('[MLCEngine] Worker initialized successfully');\n      }\n\n      const quantization = options.quantization || modelConfig.defaultQuantization;\n      const modelIdentifier = modelConfig.repo.replace('{quantization}', quantization).split('/')[1];\n      \n      // Mark this model as recently used in our LRU cache\n      this.cacheManager.touchModel(modelIdentifier);\n      \n      console.log('[MLCEngine] Loading model:', modelIdentifier, 'with worker:', !!this.worker);\n\n      if (modelConfig.modelLibrary) {\n        this.appConfig = {\n          model_list: [\n            {\n              model: \"https://huggingface.co/\" + modelConfig.repo.replace('{quantization}', quantization),\n              model_id: modelIdentifier,\n              model_lib:\n                modelConfig?.modelLibrary?.startsWith('http') ? modelConfig.modelLibrary : (modelLibURLPrefix + '/' +\n                  modelVersion + '/' + modelConfig.modelLibrary),\n            },\n          ],\n        };\n      }\n      else {\n        this.appConfig = prebuiltAppConfig;\n      }\n\n      if (this.worker) {\n        // console.log('[MLCEngine] Creating web worker engine');\n        this.mlcEngine = await CreateWebWorkerMLCEngine(\n          this.worker,\n          modelIdentifier,\n          {\n            initProgressCallback: (progress: any) => {\n              // console.log('[MLCEngine] Loading progress:', progress);\n              options.onProgress?.(progress);\n            },\n            appConfig: this.appConfig,\n            ...options,\n          }\n        );\n        // console.log('[MLCEngine] Web worker engine created successfully');\n      } else {\n        this.mlcEngine = await CreateMLCEngine(modelIdentifier, {\n          initProgressCallback: options.onProgress,\n          appConfig: this.appConfig,\n          ...options,\n        });\n      }\n    } catch (error) {\n      // Clean up worker if initialization failed\n      if (this.worker) {\n        // console.error('[MLCEngine] Error with worker, cleaning up');\n        this.worker.terminate();\n        this.worker = null;\n      }\n      // console.error('[MLCEngine] Error loading model:', error);\n      const message = error instanceof Error ? error.message : String(error);\n      throw new Error(`Failed to load MLC model \"${modelConfig}\": ${message}`);\n    }\n  }\n\n  async generateText(input: string | Record<string, any>[], options: any = {}) {\n    if (!this.mlcEngine) {\n      throw new Error('MLC Engine not initialized.');\n    }\n\n    // Start with system messages\n    let messages: Record<string, any>[] = [];\n    \n    // Combine system prompts into a single message\n    let systemContent = '';\n    \n    if (options.json_schema) {\n      systemContent += 'You must respond with valid JSON that matches the provided schema. Do not include any explanations or additional text.\\n\\n';\n    }\n    \n    if (options.system_prompt) {\n      systemContent += options.system_prompt;\n    }\n\n    // Add combined system message if we have any system content\n    if (systemContent) {\n      messages.push({\n        role: 'system',\n        content: systemContent.trim()\n      });\n    }\n\n    // Then add the user input\n    if (Array.isArray(input)) {\n      messages.push(...input);\n    } else {\n      messages.push({ role: 'user', content: input });\n    }\n\n    // Set default options\n    const defaultOptions = {\n      max_tokens: 300,\n      temperature: 0.6,\n      top_p: 0.95,\n      frequency_penalty: 0.5,\n      presence_penalty: 0.5\n    };\n\n    // Handle JSON schema\n    if (options.json_schema) {\n      // Ensure the schema is properly stringified\n      const schema = typeof options.json_schema === 'string' \n        ? options.json_schema \n        : JSON.stringify(options.json_schema);\n\n      options.response_format = {\n        type: \"json_object\",\n        schema: schema\n      };\n    }\n\n    const finalOptions = {\n      ...defaultOptions,\n      ...options,\n      messages\n    };\n\n    if (options.stream) {\n      finalOptions.stream_options = { include_usage: true };\n      return this.mlcEngine.chat.completions.create(finalOptions);\n    }\n\n    const result = await this.mlcEngine.chat.completions.create(finalOptions);\n    return result;\n  }\n\n  async embed(input: string, options: any = {}) {\n    if (!this.mlcEngine) {\n      throw new Error('MLC Engine not initialized.');\n    }\n    const result = await this.mlcEngine.embeddings.create({ input, ...options });\n    return result.data[0].embedding;\n  }\n\n  dispose() {\n    if (this.worker) {\n      this.worker.terminate();\n      this.worker = null;\n    }\n    this.mlcEngine = null;\n  }\n\n  async clearModelCache(): Promise<void> {\n    return new Promise<void>(async (resolve, reject) => {\n      try {\n        // MLC models are stored in Cache Storage with specific prefixes\n        const cacheNames = ['webllm/config', 'webllm/wasm', 'webllm/model'];\n        \n        // Get all cache names\n        const existingCacheNames = await caches.keys();\n        \n        // Filter caches that match our MLC prefixes\n        const mlcCaches = existingCacheNames.filter(name => \n          cacheNames.some(prefix => name.includes(prefix))\n        );\n        \n        // Delete all matching caches\n        await Promise.all(mlcCaches.map(name => caches.delete(name)));\n        \n        console.log('Successfully cleared MLC model cache');\n        resolve();\n      } catch (error) {\n        console.error('Error clearing model cache:', error);\n        reject(error);\n      }\n    });\n  }\n  \n  async clearSpecificModel(modelIdentifier: string): Promise<void> {\n    if (!modelIdentifier) {\n      throw new Error('Model identifier is required');\n    }\n    return this.cacheManager.removeModelFromCache(modelIdentifier);\n  }\n\n  // Add this new method to the MLCEngineWrapper class\n  async getCacheInfo(): Promise<any> {\n    return this.cacheManager.getCacheInfo();\n  }\n\n  async printCacheInfo(): Promise<void> {\n    const info = await this.cacheManager.getCacheInfo();\n    \n    console.log('=== MLC MODEL CACHE INFORMATION ===');\n    console.log(`Total cache size: ${this.formatBytes(info.totalSize)} of ${this.formatBytes(info.maxSize)} (${info.usedPercent.toFixed(2)}%)`);\n    console.log(`Number of models: ${info.models.length}`);\n    \n    console.log('\\nModels by LRU order (most recently used last):');\n    const sortedModels = [...info.models].sort((a, b) => a.position - b.position);\n    \n    sortedModels.forEach((model, index) => {\n      console.log(`${index + 1}. ${model.id}: ${this.formatBytes(model.size)}`);\n    });\n    \n    console.log('\\nDebug info:');\n    console.log(`Model queue length: ${info.debug.modelQueueLength}`);\n    console.log(`Model sizes map length: ${info.debug.modelSizesLength}`);\n    console.log('LRU Queue order:', info.debug.modelQueue);\n  }\n\n  // Helper method for formatting bytes\n  private formatBytes(bytes: number): string {\n    if (bytes === 0) return '0 Bytes';\n    const k = 1024;\n    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n    const i = Math.floor(Math.log(bytes) / Math.log(k));\n    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n  }\n}\n","/**\n * @file Module used to configure Transformers.js.\n *\n * **Example:** Disable remote models.\n * ```javascript\n * import { env } from '@huggingface/transformers';\n * env.allowRemoteModels = false;\n * ```\n *\n * **Example:** Set local model path.\n * ```javascript\n * import { env } from '@huggingface/transformers';\n * env.localModelPath = '/path/to/local/models/';\n * ```\n *\n * **Example:** Set cache directory.\n * ```javascript\n * import { env } from '@huggingface/transformers';\n * env.cacheDir = '/path/to/cache/directory/';\n * ```\n *\n * @module env\n */\n\nimport path from 'path';\nimport url from 'url';\n\nconst VERSION = '3.3.3';\n\n// Check if various APIs are available (depends on environment)\nconst IS_BROWSER_ENV = typeof window !== 'undefined' && typeof window.document !== 'undefined';\nconst IS_WEBWORKER_ENV = typeof self !== 'undefined' && self.constructor?.name === 'DedicatedWorkerGlobalScope';\nconst IS_WEB_CACHE_AVAILABLE = typeof self !== 'undefined' && 'caches' in self;\nconst IS_WEBGPU_AVAILABLE = typeof navigator !== 'undefined' && 'gpu' in navigator;\nconst IS_WEBNN_AVAILABLE = typeof navigator !== 'undefined' && 'ml' in navigator;\n\nconst IS_PROCESS_AVAILABLE = typeof process !== 'undefined';\nconst IS_NODE_ENV = IS_PROCESS_AVAILABLE && process?.release?.name === 'node';\nconst IS_FS_AVAILABLE = false;\nconst IS_PATH_AVAILABLE = !isEmpty(path);\n\n/**\n * A read-only object containing information about the APIs available in the current environment.\n */\nexport const apis = Object.freeze({\n  /** Whether we are running in a browser environment (and not a web worker) */\n  IS_BROWSER_ENV,\n\n  /** Whether we are running in a web worker environment */\n  IS_WEBWORKER_ENV,\n\n  /** Whether the Cache API is available */\n  IS_WEB_CACHE_AVAILABLE,\n\n  /** Whether the WebGPU API is available */\n  IS_WEBGPU_AVAILABLE,\n\n  /** Whether the WebNN API is available */\n  IS_WEBNN_AVAILABLE,\n\n  /** Whether the Node.js process API is available */\n  IS_PROCESS_AVAILABLE,\n\n  /** Whether we are running in a Node.js environment */\n  IS_NODE_ENV,\n\n  /** Whether the filesystem API is available */\n  IS_FS_AVAILABLE,\n\n  /** Whether the path API is available */\n  IS_PATH_AVAILABLE,\n});\n\nconst RUNNING_LOCALLY = IS_FS_AVAILABLE && IS_PATH_AVAILABLE;\n\nlet dirname__ = './';\nif (RUNNING_LOCALLY) {\n  // NOTE: We wrap `import.meta` in a call to `Object` to prevent Webpack from trying to bundle it in CommonJS.\n  // Although we get the warning: \"Accessing import.meta directly is unsupported (only property access or destructuring is supported)\",\n  // it is safe to ignore since the bundled value (`{}`) isn't used for CommonJS environments (we use __dirname instead).\n  const _import_meta_url = Object(import.meta).url;\n\n  if (_import_meta_url) {\n    dirname__ = path.dirname(path.dirname(url.fileURLToPath(_import_meta_url))); // ESM\n  } else if (typeof __dirname !== 'undefined') {\n    dirname__ = path.dirname(__dirname); // CommonJS\n  }\n}\n\n// Only used for environments with access to file system\nconst DEFAULT_CACHE_DIR = RUNNING_LOCALLY ? path.join(dirname__, '/.cache/') : null;\n\n// Set local model path, based on available APIs\nconst DEFAULT_LOCAL_MODEL_PATH = '/models/';\nconst localModelPath = RUNNING_LOCALLY ? path.join(dirname__, DEFAULT_LOCAL_MODEL_PATH) : DEFAULT_LOCAL_MODEL_PATH;\n\n/**\n * Global variable given visible to users to control execution. This provides users a simple way to configure Transformers.js.\n * @typedef {Object} TransformersEnvironment\n * @property {string} version This version of Transformers.js.\n * @property {{onnx: Partial<import('onnxruntime-common').Env>}} backends Expose environment variables of different backends,\n * allowing users to set these variables if they want to.\n * @property {boolean} allowRemoteModels Whether to allow loading of remote files, defaults to `true`.\n * If set to `false`, it will have the same effect as setting `local_files_only=true` when loading pipelines, models, tokenizers, processors, etc.\n * @property {string} remoteHost Host URL to load models from. Defaults to the Hugging Face Hub.\n * @property {string} remotePathTemplate Path template to fill in and append to `remoteHost` when loading models.\n * @property {boolean} allowLocalModels Whether to allow loading of local files, defaults to `false` if running in-browser, and `true` otherwise.\n * If set to `false`, it will skip the local file check and try to load the model from the remote host.\n * @property {string} localModelPath Path to load local models from. Defaults to `/models/`.\n * @property {boolean} useFS Whether to use the file system to load files. By default, it is `true` if available.\n * @property {boolean} useBrowserCache Whether to use Cache API to cache models. By default, it is `true` if available.\n * @property {boolean} useFSCache Whether to use the file system to cache files. By default, it is `true` if available.\n * @property {string} cacheDir The directory to use for caching files with the file system. By default, it is `./.cache`.\n * @property {boolean} useCustomCache Whether to use a custom cache system (defined by `customCache`), defaults to `false`.\n * @property {Object} customCache The custom cache to use. Defaults to `null`. Note: this must be an object which\n * implements the `match` and `put` functions of the Web Cache API. For more information, see https://developer.mozilla.org/en-US/docs/Web/API/Cache\n */\n\nexport interface Environment {\n  customCache: {\n    match: (request: string) => Promise<Response | undefined>;\n    put: (request: string, response: Response) => Promise<void>;\n  } | null;\n}\n\n/** @type {TransformersEnvironment} */\nexport const env = {\n  version: VERSION,\n\n  /////////////////// Backends settings ///////////////////\n  // NOTE: These will be populated later by the backends themselves.\n  backends: {\n    // onnxruntime-web/onnxruntime-node\n    onnx: {},\n  },\n\n  /////////////////// Model settings ///////////////////\n  allowRemoteModels: true,\n  remoteHost: 'https://huggingface.co/',\n  remotePathTemplate: '{model}/resolve/{revision}/',\n\n  allowLocalModels: !(IS_BROWSER_ENV || IS_WEBWORKER_ENV),\n  localModelPath: localModelPath,\n  useFS: IS_FS_AVAILABLE,\n\n  /////////////////// Cache settings ///////////////////\n  useBrowserCache: IS_WEB_CACHE_AVAILABLE,\n\n  useFSCache: IS_FS_AVAILABLE,\n  cacheDir: DEFAULT_CACHE_DIR,\n\n  useCustomCache: false,\n  customCache: null,\n  //////////////////////////////////////////////////////\n};\n\n/**\n * @param {Object} obj\n * @private\n */\nfunction isEmpty(obj: any) {\n  return Object.keys(obj).length === 0;\n}\n","export const Callable = /** @type {any} */ class {\n  constructor() {\n    let closure = function (this: any, ...args: any[]): any {\n      return (closure as any)._call(...args);\n    };\n    return Object.setPrototypeOf(closure, new.target.prototype);\n  }\n\n  _call(...args: any[]) {\n    throw Error('Must implement _call method in subclass');\n  }\n};\n","interface InitiateProgressInfo {\n  status: 'initiate';\n  name: string;\n  file: string;\n}\n\ninterface DownloadProgressInfo {\n  status: 'download';\n  name: string;\n  file: string;\n}\n\ninterface ProgressStatusInfo {\n  status: 'progress';\n  name: string;\n  file: string;\n  progress: number;\n  loaded: number;\n  total: number;\n}\n\ninterface DoneProgressInfo {\n  status: 'done';\n  name: string;\n  file: string;\n}\n\ninterface ReadyProgressInfo {\n  status: 'ready';\n  task: string;\n  model: string;\n}\n\nexport type ProgressInfo =\n  | InitiateProgressInfo\n  | DownloadProgressInfo\n  | ProgressStatusInfo\n  | DoneProgressInfo\n  | ReadyProgressInfo;\nexport type ProgressCallback = (progressInfo: ProgressInfo) => void;\n\nexport function dispatchCallback(progress_callback: ProgressCallback | null | undefined, data: ProgressInfo): void {\n  if (progress_callback) progress_callback(data);\n}\n\nexport function reverseDictionary(data: Record<string, any>): Record<string, any> {\n  return Object.fromEntries(Object.entries(data).map(([key, value]) => [value, key]));\n}\n\nexport function escapeRegExp(string: string): string {\n  return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function isTypedArray(val: any): boolean {\n  return val?.prototype?.__proto__?.constructor?.name === 'TypedArray';\n}\n\nexport function isIntegralNumber(x: any): boolean {\n  return Number.isInteger(x) || typeof x === 'bigint';\n}\n\nexport function isNullishDimension(x: any): boolean {\n  return x === null || x === undefined || x === -1;\n}\n\nexport function calculateDimensions(arr: any[]): number[] {\n  const dimensions: number[] = [];\n  let current: any = arr;\n  while (Array.isArray(current)) {\n    dimensions.push(current.length);\n    current = current[0];\n  }\n  return dimensions;\n}\n\nexport function pop<T>(obj: Record<string, T>, key: string, defaultValue?: T): T {\n  const value = obj[key];\n  if (value !== undefined) {\n    delete obj[key];\n    return value;\n  }\n  if (defaultValue === undefined) {\n    throw Error(`Key ${key} does not exist in object.`);\n  }\n  return defaultValue;\n}\n\nexport function mergeArrays<T>(...arrs: T[][]): T[] {\n  return Array.prototype.concat.apply([], arrs);\n}\n\nexport function product<T>(...a: T[][]): T[][] {\n  return a.reduce<T[][]>(\n    (acc, curr) => acc.flatMap((d) => curr.map((e) => [...(Array.isArray(d) ? (d as T[]) : [d]), e])),\n    [[]],\n  );\n}\n\nexport function calculateReflectOffset(i: number, w: number): number {\n  return Math.abs(((i + w) % (2 * w)) - w);\n}\n\n// export function pick<T>(obj: T, keys: Array<keyof T>) {\n//   return Object.fromEntries(keys.map((k) => [k, obj[k as keyof T]]));\n// }\nexport function pick(o: any, props: string[]) {\n    return Object.assign(\n        {},\n        ...props.map((prop: string) => {\n            if (o[prop] !== undefined) {\n        return { [prop]: o[prop] };\n      }\n    }),\n  );\n}\n\nexport function len(s: string): number {\n  let length = 0;\n  for (const c of s) ++length;\n  return length;\n}\n\nexport function count<T>(arr: T[] | string, value: T): number {\n  let count = 0;\n  for (const v of arr) {\n    if (v === value) ++count;\n  }\n  return count;\n}\n\n/**\n * Save blob file on the web.\n * @param {string} path The path to save the blob to\n * @param {Blob} blob The blob to save\n */\nexport function saveBlob(path: string, blob: Blob){\n  // Convert the canvas content to a data URL\n  const dataURL = URL.createObjectURL(blob);\n\n  // Create an anchor element with the data URL as the href attribute\n  const downloadLink = document.createElement('a');\n  downloadLink.href = dataURL;\n\n  // Set the download attribute to specify the desired filename for the downloaded image\n  downloadLink.download = path;\n\n  // Trigger the download\n  downloadLink.click();\n\n  // Clean up: remove the anchor element from the DOM\n  downloadLink.remove();\n\n  // Revoke the Object URL to free up memory\n  URL.revokeObjectURL(dataURL);\n}\n\n","/**\n * @file Utility functions to interact with the Hugging Face Hub (https://huggingface.co/models)\n *\n * @module utils/hub\n */\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { env } from '../env.js';\nimport { dispatchCallback, ProgressCallback } from './core';\nimport { PretrainedConfig } from '../configs';\nexport interface PretrainedOptions {\n  progress_callback?: null | ProgressCallback;\n  config?: null | PretrainedConfig;\n  cache_dir?: null | string;\n  local_files_only?: boolean;\n  revision?: string;\n}\n\n/**\n * @typedef {Object} PretrainedOptions Options for loading a pretrained model.\n * @property {import('./core.js').ProgressCallback} [progress_callback=null] If specified, this function will be called during model construction, to provide the user with progress updates.\n * @property {import('../configs.js').PretrainedConfig} [config=null] Configuration for the model to use instead of an automatically loaded configuration. Configuration can be automatically loaded when:\n * - The model is a model provided by the library (loaded with the *model id* string of a pretrained model).\n * - The model is loaded by supplying a local directory as `pretrained_model_name_or_path` and a configuration JSON file named *config.json* is found in the directory.\n * @property {string} [cache_dir=null] Path to a directory in which a downloaded pretrained model configuration should be cached if the standard cache should not be used.\n * @property {boolean} [local_files_only=false] Whether or not to only look at local files (e.g., not try downloading the model).\n * @property {string} [revision='main'] The specific model version to use. It can be a branch name, a tag name, or a commit id,\n * since we use a git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any identifier allowed by git.\n * NOTE: This setting is ignored for local requests.\n */\n\n/**\n * @typedef {Object} ModelSpecificPretrainedOptions Options for loading a pretrained model.\n * @property {string} [subfolder='onnx'] In case the relevant files are located inside a subfolder of the model repo on huggingface.co,\n * you can specify the folder name here.\n * @property {string} [model_file_name=null] If specified, load the model with this name (excluding the .onnx suffix). Currently only valid for encoder- or decoder-only models.\n * @property {import(\"./devices.js\").DeviceType|Record<string, import(\"./devices.js\").DeviceType>} [device=null] The device to run the model on. If not specified, the device will be chosen from the environment settings.\n * @property {import(\"./dtypes.js\").DataType|Record<string, import(\"./dtypes.js\").DataType>} [dtype=null] The data type to use for the model. If not specified, the data type will be chosen from the environment settings.\n * @property {boolean|Record<string, boolean>} [use_external_data_format=false] Whether to load the model using the external data format (used for models >= 2GB in size).\n * @property {import('onnxruntime-common').InferenceSession.SessionOptions} [session_options] (Optional) User-specified session options passed to the runtime. If not provided, suitable defaults will be chosen.\n */\n\n/**\n * @typedef {PretrainedOptions & ModelSpecificPretrainedOptions} PretrainedModelOptions Options for loading a pretrained model.\n */\n\n/**\n * Mapping from file extensions to MIME types.\n */\nconst CONTENT_TYPE_MAP = {\n  txt: 'text/plain',\n  html: 'text/html',\n  css: 'text/css',\n  js: 'text/javascript',\n  json: 'application/json',\n  png: 'image/png',\n  jpg: 'image/jpeg',\n  jpeg: 'image/jpeg',\n  gif: 'image/gif',\n};\nclass FileResponse {\n  filePath: string | URL;\n  headers: Headers;\n  exists: boolean;\n  status: number;\n  statusText: string;\n  body: ReadableStream<Uint8Array> | null;\n\n  /**\n   * Creates a new `FileResponse` object.\n   * @param {string|URL} filePath\n   */\n  constructor(filePath: string | URL) {\n    this.filePath = filePath;\n    this.headers = new Headers();\n\n    this.exists = fs.existsSync(filePath);\n    if (this.exists) {\n      this.status = 200;\n      this.statusText = 'OK';\n\n      let stats = fs.statSync(filePath);\n      this.headers.set('content-length', stats.size.toString());\n\n      this.updateContentType();\n\n      let self = this;\n      this.body = new ReadableStream({\n        start(controller) {\n          self.arrayBuffer().then((buffer) => {\n            controller.enqueue(new Uint8Array(buffer));\n            controller.close();\n          });\n        },\n      });\n    } else {\n      this.status = 404;\n      this.statusText = 'Not Found';\n      this.body = null;\n    }\n  }\n\n  /**\n   * Updates the 'content-type' header property of the response based on the extension of\n   * the file specified by the filePath property of the current object.\n   * @returns {void}\n   */\n  updateContentType() {\n    // Set content-type header based on file extension\n    const extension = this.filePath.toString().split('.').pop()?.toLowerCase();\n    this.headers.set(\n      'content-type',\n      CONTENT_TYPE_MAP[extension as keyof typeof CONTENT_TYPE_MAP] ?? 'application/octet-stream',\n    );\n  }\n\n  /**\n   * Clone the current FileResponse object.\n   * @returns {FileResponse} A new FileResponse object with the same properties as the current object.\n   */\n  clone() {\n    let response = new FileResponse(this.filePath);\n    response.exists = this.exists;\n    response.status = this.status;\n    response.statusText = this.statusText;\n    response.headers = new Headers(this.headers);\n    return response;\n  }\n\n  /**\n   * Reads the contents of the file specified by the filePath property and returns a Promise that\n   * resolves with an ArrayBuffer containing the file's contents.\n   * @returns {Promise<ArrayBuffer>} A Promise that resolves with an ArrayBuffer containing the file's contents.\n   * @throws {Error} If the file cannot be read.\n   */\n  async arrayBuffer() {\n    const data = await fs.promises.readFile(this.filePath);\n    return /** @type {ArrayBuffer} */ data.buffer;\n  }\n\n  /**\n   * Reads the contents of the file specified by the filePath property and returns a Promise that\n   * resolves with a Blob containing the file's contents.\n   * @returns {Promise<Blob>} A Promise that resolves with a Blob containing the file's contents.\n   * @throws {Error} If the file cannot be read.\n   */\n  async blob() {\n    const data = await fs.promises.readFile(this.filePath);\n    return new Blob([data], { type: this.headers.get('content-type') as string });\n  }\n\n  /**\n   * Reads the contents of the file specified by the filePath property and returns a Promise that\n   * resolves with a string containing the file's contents.\n   * @returns {Promise<string>} A Promise that resolves with a string containing the file's contents.\n   * @throws {Error} If the file cannot be read.\n   */\n  async text() {\n    const data = await fs.promises.readFile(this.filePath, 'utf8');\n    return data;\n  }\n\n  /**\n   * Reads the contents of the file specified by the filePath property and returns a Promise that\n   * resolves with a parsed JavaScript object containing the file's contents.\n   *\n   * @returns {Promise<Object>} A Promise that resolves with a parsed JavaScript object containing the file's contents.\n   * @throws {Error} If the file cannot be read.\n   */\n  async json() {\n    return JSON.parse(await this.text());\n  }\n}\n\n/**\n * Determines whether the given string is a valid URL.\n * @param {string|URL} string The string to test for validity as an URL.\n * @param {string[]} [protocols=null] A list of valid protocols. If specified, the protocol must be in this list.\n * @param {string[]} [validHosts=null] A list of valid hostnames. If specified, the URL's hostname must be in this list.\n * @returns {boolean} True if the string is a valid URL, false otherwise.\n */\nfunction isValidUrl(string: string, protocols: string[] | null = null, validHosts: string[] | null = null) {\n  let url;\n  try {\n    url = new URL(string);\n  } catch (_) {\n    return false;\n  }\n  if (protocols && !protocols.includes(url.protocol)) {\n    return false;\n  }\n  if (validHosts && !validHosts.includes(url.hostname)) {\n    return false;\n  }\n  return true;\n}\n\n/**\n * Helper function to get a file, using either the Fetch API or FileSystem API.\n *\n * @param {URL|string} urlOrPath The URL/path of the file to get.\n * @returns {Promise<FileResponse|Response>} A promise that resolves to a FileResponse object (if the file is retrieved using the FileSystem API), or a Response object (if the file is retrieved using the Fetch API).\n */\nexport async function getFile(urlOrPath: URL | string) {\n  if (env.useFS && !isValidUrl(urlOrPath.toString(), ['http:', 'https:', 'blob:'])) {\n    return new FileResponse(urlOrPath);\n  } else if (typeof process !== 'undefined' && process?.release?.name === 'node') {\n    const IS_CI = false;\n    const version = env.version;\n\n    const headers = new Headers();\n    headers.set('User-Agent', `transformers.js/${version}; is_ci/${IS_CI};`);\n\n    // Check whether we are making a request to the Hugging Face Hub.\n    const isHFURL = isValidUrl(urlOrPath.toString(), ['http:', 'https:'], ['huggingface.co', 'hf.co']);\n    if (isHFURL) {\n      // If an access token is present in the environment variables,\n      // we add it to the request headers.\n      // NOTE: We keep `HF_ACCESS_TOKEN` for backwards compatibility (as a fallback).\n      const token = process.env?.HF_TOKEN ?? process.env?.HF_ACCESS_TOKEN;\n      if (token) {\n        headers.set('Authorization', `Bearer ${token}`);\n      }\n    }\n    return fetch(urlOrPath, { headers });\n  } else {\n    // Running in a browser-environment, so we use default headers\n    // NOTE: We do not allow passing authorization headers in the browser,\n    // since this would require exposing the token to the client.\n    return fetch(urlOrPath);\n  }\n}\n\nconst ERROR_MAPPING = {\n  // 4xx errors (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses)\n  400: 'Bad request error occurred while trying to load file',\n  401: 'Unauthorized access to file',\n  403: 'Forbidden access to file',\n  404: 'Could not locate file',\n  408: 'Request timeout error occurred while trying to load file',\n\n  // 5xx errors (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#server_error_responses)\n  500: 'Internal server error error occurred while trying to load file',\n  502: 'Bad gateway error occurred while trying to load file',\n  503: 'Service unavailable error occurred while trying to load file',\n  504: 'Gateway timeout error occurred while trying to load file',\n};\n/**\n * Helper method to handle fatal errors that occur while trying to load a file from the Hugging Face Hub.\n * @param {number} status The HTTP status code of the error.\n * @param {string} remoteURL The URL of the file that could not be loaded.\n * @param {boolean} fatal Whether to raise an error if the file could not be loaded.\n * @returns {null} Returns `null` if `fatal = true`.\n * @throws {Error} If `fatal = false`.\n */\nfunction handleError(status: number, remoteURL: string, fatal: boolean) {\n  if (!fatal) {\n    // File was not loaded correctly, but it is optional.\n    // TODO in future, cache the response?\n    return null;\n  }\n\n  const message =\n    ERROR_MAPPING[status as keyof typeof ERROR_MAPPING] ?? `Error (${status}) occurred while trying to load file`;\n  throw Error(`${message}: \"${remoteURL}\".`);\n}\n\nclass FileCache {\n  private path: string;\n  private cache:  Map<string, ArrayBuffer>;\n\n  /**\n   * Instantiate a `FileCache` object.\n   * @param {string} path\n   */\n  constructor(path: string) {\n    this.path = path;\n    this.cache = new Map();\n  }\n\n  /**\n   * Checks whether the given request is in the cache.\n   * @param {string} request\n   * @returns {Promise<FileResponse | undefined>}\n   */\n  async match(request: string) {\n    let filePath = path.join(this.path, request);\n    let file = new FileResponse(filePath);\n\n    if (file.exists) {\n      return file;\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * Adds the given response to the cache.\n   * @param {string} request\n   * @param {Response|FileResponse} response\n   * @returns {Promise<void>}\n   */\n  async put(request: string, response: Response | FileResponse) {\n    const buffer = Buffer.from(await response.arrayBuffer());\n\n    let outputPath = path.join(this.path, request);\n\n    try {\n      await fs.promises.mkdir(path.dirname(outputPath), { recursive: true });\n      await fs.promises.writeFile(outputPath, buffer);\n    } catch (err) {\n      console.warn('An error occurred while writing the file to cache:', err);\n    }\n  }\n\n  // TODO add the rest?\n  // addAll(requests: RequestInfo[]): Promise<void>;\n  // delete(request: RequestInfo | URL, options?: CacheQueryOptions): Promise<boolean>;\n  // keys(request?: RequestInfo | URL, options?: CacheQueryOptions): Promise<ReadonlyArray<Request>>;\n  // match(request: RequestInfo | URL, options?: CacheQueryOptions): Promise<Response | undefined>;\n  // matchAll(request?: RequestInfo | URL, options?: CacheQueryOptions): Promise<ReadonlyArray<Response>>;\n}\n\n/**\n *\n * @param {FileCache|Cache} cache The cache to search\n * @param {string[]} names The names of the item to search for\n * @returns {Promise<FileResponse|Response|undefined>} The item from the cache, or undefined if not found.\n */\nasync function tryCache(cache: FileCache | Cache, ...names: string[]) {\n  for (let name of names) {\n    try {\n      let result = await cache.match(name);\n      if (result) return result;\n    } catch (e) {\n      continue;\n    }\n  }\n  return undefined;\n}\n\n/**\n *\n * Retrieves a file from either a remote URL using the Fetch API or from the local file system using the FileSystem API.\n * If the filesystem is available and `env.useCache = true`, the file will be downloaded and cached.\n *\n * @param {string} path_or_repo_id This can be either:\n * - a string, the *model id* of a model repo on huggingface.co.\n * - a path to a *directory* potentially containing the file.\n * @param {string} filename The name of the file to locate in `path_or_repo`.\n * @param {boolean} [fatal=true] Whether to throw an error if the file is not found.\n * @param {PretrainedOptions} [options] An object containing optional parameters.\n *\n * @throws Will throw an error if the file is not found and `fatal` is true.\n * @returns {Promise<Uint8Array>} A Promise that resolves with the file content as a buffer.\n */\nexport async function getModelFile(\n  path_or_repo_id: string,\n  filename: string,\n  fatal = true,\n  options: PretrainedOptions = {},\n) {\n  if (!env.allowLocalModels) {\n    // User has disabled local models, so we just make sure other settings are correct.\n\n    if (options.local_files_only) {\n      throw Error(\n        'Invalid configuration detected: local models are disabled (`env.allowLocalModels=false`) but you have requested to only use local models (`local_files_only=true`).',\n      );\n    } else if (!env.allowRemoteModels) {\n      throw Error(\n        'Invalid configuration detected: both local and remote models are disabled. Fix by setting `env.allowLocalModels` or `env.allowRemoteModels` to `true`.',\n      );\n    }\n  }\n\n  // Initiate file retrieval\n  dispatchCallback(options.progress_callback, {\n    status: 'initiate',\n    name: path_or_repo_id,\n    file: filename,\n  });\n\n  // First, check if the a caching backend is available\n  // If no caching mechanism available, will download the file every time\n  let cache;\n  if (!cache && env.useBrowserCache) {\n    if (typeof caches === 'undefined') {\n      throw Error('Browser cache is not available in this environment.');\n    }\n    try {\n      // In some cases, the browser cache may be visible, but not accessible due to security restrictions.\n      // For example, when running an application in an iframe, if a user attempts to load the page in\n      // incognito mode, the following error is thrown: `DOMException: Failed to execute 'open' on 'CacheStorage':\n      // An attempt was made to break through the security policy of the user agent.`\n      // So, instead of crashing, we just ignore the error and continue without using the cache.\n      cache = await caches.open('transformers-cache');\n    } catch (e) {\n      console.warn('An error occurred while opening the browser cache:', e);\n    }\n  }\n\n  if (!cache && env.useFSCache) {\n    // TODO throw error if not available\n\n    // If `cache_dir` is not specified, use the default cache directory\n    cache = new FileCache(options.cache_dir ?? env.cacheDir ?? '');\n  }\n\n  if (!cache && env.useCustomCache) {\n    // Allow the user to specify a custom cache system.\n    if (!env.customCache) {\n      throw Error('`env.useCustomCache=true`, but `env.customCache` is not defined.');\n    }\n\n    // Check that the required methods are defined:\n    if (!(env.customCache as Cache).match || !(env.customCache as Cache).put) {\n      throw new Error(\n        '`env.customCache` must be an object which implements the `match` and `put` functions of the Web Cache API. ' +\n          'For more information, see https://developer.mozilla.org/en-US/docs/Web/API/Cache',\n      );\n    }\n    cache = env.customCache;\n  }\n\n  const revision = options.revision ?? 'main';\n\n  let requestURL = pathJoin(path_or_repo_id, filename);\n  let localPath = pathJoin(env.localModelPath, requestURL);\n\n  let remoteURL = pathJoin(\n    env.remoteHost,\n    env.remotePathTemplate\n      .replaceAll('{model}', path_or_repo_id)\n      .replaceAll('{revision}', encodeURIComponent(revision)),\n    filename,\n  );\n\n  // Choose cache key for filesystem cache\n  // When using the main revision (default), we use the request URL as the cache key.\n  // If a specific revision is requested, we account for this in the cache key.\n  let fsCacheKey = revision === 'main' ? requestURL : pathJoin(path_or_repo_id, revision, filename);\n\n  /** @type {string} */\n  let cacheKey;\n  let proposedCacheKey = cache instanceof FileCache ? fsCacheKey : remoteURL;\n\n  // Whether to cache the final response in the end.\n  let toCacheResponse = false;\n\n  /** @type {Response|FileResponse|undefined} */\n  let response;\n\n  if (cache) {\n    // A caching system is available, so we try to get the file from it.\n    //  1. We first try to get from cache using the local path. In some environments (like deno),\n    //     non-URL cache keys are not allowed. In these cases, `response` will be undefined.\n    //  2. If no response is found, we try to get from cache using the remote URL or file system cache.\n    response = await tryCache(cache, localPath, proposedCacheKey);\n  }\n\n  const cacheHit = response !== undefined;\n\n  if (response === undefined) {\n    // Caching not available, or file is not cached, so we perform the request\n\n    if (env.allowLocalModels) {\n      // Accessing local models is enabled, so we try to get the file locally.\n      // If request is a valid HTTP URL, we skip the local file check. Otherwise, we try to get the file locally.\n      const isURL = isValidUrl(requestURL, ['http:', 'https:']);\n      if (!isURL) {\n        try {\n          response = await getFile(localPath);\n          cacheKey = localPath; // Update the cache key to be the local path\n        } catch (e) {\n          // Something went wrong while trying to get the file locally.\n          // NOTE: error handling is done in the next step (since `response` will be undefined)\n          console.warn(`Unable to load from local path \"${localPath}\": \"${e}\"`);\n        }\n      } else if (options.local_files_only) {\n        throw new Error(`\\`local_files_only=true\\`, but attempted to load a remote file from: ${requestURL}.`);\n      } else if (!env.allowRemoteModels) {\n        throw new Error(`\\`env.allowRemoteModels=false\\`, but attempted to load a remote file from: ${requestURL}.`);\n      }\n    }\n\n    if (response === undefined || response.status === 404) {\n      // File not found locally. This means either:\n      // - The user has disabled local file access (`env.allowLocalModels=false`)\n      // - the path is a valid HTTP url (`response === undefined`)\n      // - the path is not a valid HTTP url and the file is not present on the file system or local server (`response.status === 404`)\n\n      if (options.local_files_only || !env.allowRemoteModels) {\n        // User requested local files only, but the file is not found locally.\n        if (fatal) {\n          throw Error(\n            `\\`local_files_only=true\\` or \\`env.allowRemoteModels=false\\` and file was not found locally at \"${localPath}\".`,\n          );\n        } else {\n          // File not found, but this file is optional.\n          // TODO in future, cache the response?\n          return null;\n        }\n      }\n\n      // File not found locally, so we try to download it from the remote server\n      response = await getFile(remoteURL);\n\n      if (response.status !== 200) {\n        return handleError(response.status, remoteURL, fatal);\n      }\n\n      // Success! We use the proposed cache key from earlier\n      cacheKey = proposedCacheKey;\n    }\n\n    // Only cache the response if:\n    toCacheResponse = !!(\n      cache && // 1. A caching system is available\n      typeof Response !== 'undefined' // 2. `Response` is defined (i.e., we are in a browser-like environment)\n    );\n  }\n\n  // Start downloading\n  dispatchCallback(options.progress_callback, {\n    status: 'download',\n    name: path_or_repo_id,\n    file: filename,\n  });\n\n  /** @type {Uint8Array} */\n  let buffer;\n\n  if (!options.progress_callback) {\n    // If no progress callback is specified, we can use the `.arrayBuffer()`\n    // method to read the response.\n    buffer = new Uint8Array(await response.arrayBuffer());\n  } else if (\n    cacheHit && // The item is being read from the cache\n    typeof navigator !== 'undefined' &&\n    /firefox/i.test(navigator.userAgent) // We are in Firefox\n  ) {\n    // Due to bug in Firefox, we cannot display progress when loading from cache.\n    // Fortunately, since this should be instantaneous, this should not impact users too much.\n    buffer = new Uint8Array(await response.arrayBuffer());\n\n    // For completeness, we still fire the final progress callback\n    dispatchCallback(options.progress_callback, {\n      status: 'progress',\n      name: path_or_repo_id,\n      file: filename,\n      progress: 100,\n      loaded: buffer.length,\n      total: buffer.length,\n    });\n  } else {\n    if (response instanceof FileResponse) {\n      throw new Error('FileResponse is not supported');\n    }\n    buffer = await readResponse(response, (data) => {\n      dispatchCallback(options.progress_callback, {\n        status: 'progress',\n        name: path_or_repo_id,\n        file: filename,\n        ...data,\n      });\n    });\n  }\n\n  if (\n    // Only cache web responses\n    // i.e., do not cache FileResponses (prevents duplication)\n    toCacheResponse &&\n    cacheKey &&\n    // Check again whether request is in cache. If not, we add the response to the cache\n    (await cache?.match(cacheKey)) === undefined\n  ) {\n    // NOTE: We use `new Response(buffer, ...)` instead of `response.clone()` to handle LFS files\n    await cache\n      ?.put(\n        cacheKey,\n        new Response(buffer, {\n          headers: response.headers,\n        }),\n      )\n      .catch((err) => {\n        // Do not crash if unable to add to cache (e.g., QuotaExceededError).\n        // Rather, log a warning and proceed with execution.\n        console.warn(`Unable to add response to browser cache: ${err}.`);\n      });\n  }\n\n  dispatchCallback(options.progress_callback, {\n    status: 'done',\n    name: path_or_repo_id,\n    file: filename,\n  });\n\n  return buffer;\n}\n\n/**\n * Fetches a JSON file from a given path and file name.\n *\n * @param {string} modelPath The path to the directory containing the file.\n * @param {string} fileName The name of the file to fetch.\n * @param {boolean} [fatal=true] Whether to throw an error if the file is not found.\n * @param {PretrainedOptions} [options] An object containing optional parameters.\n * @returns {Promise<Object>} The JSON data parsed into a JavaScript object.\n * @throws Will throw an error if the file is not found and `fatal` is true.\n */\nexport async function getModelJSON(modelPath: string, fileName: string, fatal = true, options = {}) {\n  let buffer = await getModelFile(modelPath, fileName, fatal, options);\n  if (buffer === null) {\n    // Return empty object\n    return {};\n  }\n\n  let decoder = new TextDecoder('utf-8');\n  let jsonData = decoder.decode(buffer);\n\n  return JSON.parse(jsonData);\n}\n/**\n * Read and track progress when reading a Response object\n *\n * @param {Response|FileResponse} response The Response object to read\n * @param {(data: {progress: number, loaded: number, total: number}) => void} progress_callback The function to call with progress updates\n * @returns {Promise<Uint8Array>} A Promise that resolves with the Uint8Array buffer\n */\nexport async function readResponse(\n  response: Response,\n  progress_callback: (data: { progress: number; loaded: number; total: number }) => void,\n) {\n  const contentLength = response.headers.get('Content-Length');\n  if (contentLength === null) {\n    console.warn('Unable to determine content-length from response headers. Will expand buffer when needed.');\n  }\n  let total = parseInt(contentLength ?? '0');\n  let buffer = new Uint8Array(total);\n  let loaded = 0;\n\n  const reader = response.body?.getReader();\n  if (!reader) throw new Error('Response body reader is undefined');\n\n  async function read() {\n    const { done, value } = await reader?.read()!;\n    if (done) return;\n\n    let newLoaded = loaded + value.length;\n    if (newLoaded > total) {\n      total = newLoaded;\n\n      // Adding the new data will overflow buffer.\n      // In this case, we extend the buffer\n      let newBuffer = new Uint8Array(total);\n\n      // copy contents\n      newBuffer.set(buffer);\n\n      buffer = newBuffer;\n    }\n    buffer.set(value, loaded);\n    loaded = newLoaded;\n\n    const progress = (loaded / total) * 100;\n\n    // Call your function here\n    progress_callback({\n      progress: progress,\n      loaded: loaded,\n      total: total,\n    });\n\n    return read();\n  }\n\n  // Actually read\n  await read();\n\n  return buffer;\n}\n\nexport function pathJoin(...parts: string[]) {\n  // https://stackoverflow.com/a/55142565\n  parts = parts.map((part, index) => {\n    if (index) {\n      part = part.replace(new RegExp('^/'), '');\n    }\n    if (index !== parts.length - 1) {\n      part = part.replace(new RegExp('/$'), '');\n    }\n    return part;\n  });\n  return parts.join('/');\n}\n","/**\n * @file Helper module for mathematical processing.\n *\n * These functions and classes are only used internally,\n * meaning an end-user shouldn't need to access anything here.\n *\n * @module utils/maths\n */\n\n/**\n * @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array} TypedArray\n * @typedef {BigInt64Array | BigUint64Array} BigTypedArray\n * @typedef {TypedArray | BigTypedArray} AnyTypedArray\n */\n\n/**\n * @param {TypedArray} input\n */\n\ntype TypedArray =\n  | Int8Array\n  | Uint8Array\n  | Uint8ClampedArray\n  | Int16Array\n  | Uint16Array\n  | Int32Array\n  | Uint32Array\n  | Float32Array\n  | Float64Array;\ntype BigTypedArray = BigInt64Array | BigUint64Array;\ntype AnyTypedArray = TypedArray | BigTypedArray;\n\nexport function interpolate_data(\n  input: TypedArray,\n  [in_channels, in_height, in_width]: [number, number, number],\n  [out_height, out_width]: [number, number],\n  mode = 'bilinear',\n  align_corners = false,\n) {\n  // TODO use mode and align_corners\n\n  // Output image dimensions\n  const x_scale = out_width / in_width;\n  const y_scale = out_height / in_height;\n\n  // Output image\n  // @ts-ignore\n  const out_img = new input.constructor(out_height * out_width * in_channels);\n\n  // Pre-calculate strides\n  const inStride = in_height * in_width;\n  const outStride = out_height * out_width;\n\n  for (let i = 0; i < out_height; ++i) {\n    for (let j = 0; j < out_width; ++j) {\n      // Calculate output offset\n      const outOffset = i * out_width + j;\n\n      // Calculate input pixel coordinates\n      const x = (j + 0.5) / x_scale - 0.5;\n      const y = (i + 0.5) / y_scale - 0.5;\n\n      // Calculate the four nearest input pixels\n      // We also check if the input pixel coordinates are within the image bounds\n      let x1 = Math.floor(x);\n      let y1 = Math.floor(y);\n      const x2 = Math.min(x1 + 1, in_width - 1);\n      const y2 = Math.min(y1 + 1, in_height - 1);\n\n      x1 = Math.max(x1, 0);\n      y1 = Math.max(y1, 0);\n\n      // Calculate the fractional distances between the input pixel and the four nearest pixels\n      const s = x - x1;\n      const t = y - y1;\n\n      // Perform bilinear interpolation\n      const w1 = (1 - s) * (1 - t);\n      const w2 = s * (1 - t);\n      const w3 = (1 - s) * t;\n      const w4 = s * t;\n\n      // Calculate the four nearest input pixel indices\n      const yStride = y1 * in_width;\n      const xStride = y2 * in_width;\n      const idx1 = yStride + x1;\n      const idx2 = yStride + x2;\n      const idx3 = xStride + x1;\n      const idx4 = xStride + x2;\n\n      for (let k = 0; k < in_channels; ++k) {\n        // Calculate channel offset\n        const cOffset = k * inStride;\n\n        out_img[k * outStride + outOffset] =\n          w1 * input[cOffset + idx1] +\n          w2 * input[cOffset + idx2] +\n          w3 * input[cOffset + idx3] +\n          w4 * input[cOffset + idx4];\n      }\n    }\n  }\n\n  return out_img;\n}\n\n/**\n * Helper method to permute a `AnyTypedArray` directly\n * @template {AnyTypedArray} T\n * @param {T} array\n * @param {number[]} dims\n * @param {number[]} axes\n * @returns {[T, number[]]} The permuted array and the new shape.\n */\nexport function permute_data(array: TypedArray, dims: number[], axes: number[]) {\n  // Calculate the new shape of the permuted array\n  // and the stride of the original array\n  const shape = new Array(axes.length);\n  const stride = new Array(axes.length);\n\n  for (let i = axes.length - 1, s = 1; i >= 0; --i) {\n    stride[i] = s;\n    shape[i] = dims[axes[i]];\n    s *= shape[i];\n  }\n\n  // Precompute inverse mapping of stride\n  const invStride = axes.map((_, i) => stride[axes.indexOf(i)]);\n\n  // Create the permuted array with the new shape\n  // @ts-ignore\n  const permutedData = new array.constructor(array.length);\n\n  // Permute the original array to the new array\n  for (let i = 0; i < array.length; ++i) {\n    let newIndex = 0;\n    for (let j = dims.length - 1, k = i; j >= 0; --j) {\n      newIndex += (k % dims[j]) * invStride[j];\n      k = Math.floor(k / dims[j]);\n    }\n    permutedData[newIndex] = array[i];\n  }\n\n  return [permutedData, shape];\n}\n\n/**\n * Compute the softmax of an array of numbers.\n * @template {TypedArray|number[]} T\n * @param {T} arr The array of numbers to compute the softmax of.\n * @returns {T} The softmax array.\n */\nexport function softmax(arr: TypedArray | number[]) {\n  // Compute the maximum value in the array\n  const maxVal = max(arr)[0];\n\n  // Compute the exponentials of the array values\n  const exps = arr.map((x) => {\n    if (typeof maxVal === 'bigint') {\n      // Convert to Number only if within safe integer range\n      if (maxVal <= BigInt(Number.MAX_SAFE_INTEGER)) {\n        return Math.exp(Number(x) - Number(maxVal));\n      }\n      throw new Error('BigInt value exceeds safe number range for exponential calculation');\n    }\n    return Math.exp(Number(x) - maxVal);\n  });\n\n  // Compute the sum of the exponentials\n  // @ts-ignore\n  const sumExps = exps.reduce((acc, val) => acc + val, 0);\n\n  // Compute the softmax values\n  const softmaxArr = exps.map((x) => x / sumExps);\n\n  return /** @type {T} */ softmaxArr;\n}\n\n/**\n * Calculates the logarithm of the softmax function for the input array.\n * @template {TypedArray|number[]} T\n * @param {T} arr The input array to calculate the log_softmax function for.\n * @returns {T} The resulting log_softmax array.\n */\nexport function log_softmax(arr: TypedArray | number[]) {\n  // Compute the maximum value in the array\n  const maxVal = max(arr)[0];\n\n  // Compute the sum of the exponentials\n  let sumExps = 0;\n  for (let i = 0; i < arr.length; ++i) {\n    if (typeof maxVal === 'bigint') {\n      if (maxVal <= BigInt(Number.MAX_SAFE_INTEGER)) {\n        sumExps += Math.exp(Number(arr[i]) - Number(maxVal));\n      }\n      throw new Error('BigInt value exceeds safe number range for exponential calculation');\n    }\n    sumExps += Math.exp(Number(arr[i]) - maxVal);\n  }\n\n  // Compute the log of the sum\n  const logSum = Math.log(sumExps);\n\n  // Compute the softmax values\n  const logSoftmaxArr = arr.map((x) => {\n    if (typeof maxVal === 'bigint') {\n      return Number(x) - Number(maxVal) - logSum;\n    }\n    return Number(x) - maxVal - logSum;\n  });\n\n  return /** @type {T} */ logSoftmaxArr;\n}\n\n/**\n * Calculates the dot product of two arrays.\n * @param {number[]} arr1 The first array.\n * @param {number[]} arr2 The second array.\n * @returns {number} The dot product of arr1 and arr2.\n */\nexport function dot(arr1: number[], arr2: number[]) {\n  let result = 0;\n  for (let i = 0; i < arr1.length; ++i) {\n    result += arr1[i] * arr2[i];\n  }\n  return result;\n}\n\n/**\n * Computes the cosine similarity between two arrays.\n *\n * @param {number[]} arr1 The first array.\n * @param {number[]} arr2 The second array.\n * @returns {number} The cosine similarity between the two arrays.\n */\nexport function cos_sim(arr1: number[], arr2: number[]) {\n  // Calculate dot product of the two arrays\n  const dotProduct = dot(arr1, arr2);\n\n  // Calculate the magnitude of the first array\n  const magnitudeA = magnitude(arr1);\n\n  // Calculate the magnitude of the second array\n  const magnitudeB = magnitude(arr2);\n\n  // Calculate the cosine similarity\n  const cosineSimilarity = dotProduct / (magnitudeA * magnitudeB);\n\n  return cosineSimilarity;\n}\n\n/**\n * Calculates the magnitude of a given array.\n * @param {number[]} arr The array to calculate the magnitude of.\n * @returns {number} The magnitude of the array.\n */\nexport function magnitude(arr: number[]) {\n  return Math.sqrt(arr.reduce((acc, val) => acc + val * val, 0));\n}\n\n/**\n * Returns the value and index of the minimum element in an array.\n * @template {number[]|bigint[]|AnyTypedArray} T\n * @param {T} arr array of numbers.\n * @returns {T extends bigint[]|BigTypedArray ? [bigint, number] : [number, number]} the value and index of the minimum element, of the form: [valueOfMin, indexOfMin]\n * @throws {Error} If array is empty.\n */\nexport function min(arr: number[] | bigint[] | TypedArray) {\n  if (arr.length === 0) throw Error('Array must not be empty');\n  let min = arr[0];\n  let indexOfMin = 0;\n  for (let i = 1; i < arr.length; ++i) {\n    if (arr[i] < min) {\n      min = arr[i];\n      indexOfMin = i;\n    }\n  }\n  return /** @type {T extends bigint[]|BigTypedArray ? [bigint, number] : [number, number]} */ [min, indexOfMin];\n}\n\n/**\n * Returns the value and index of the maximum element in an array.\n * @template {number[]|bigint[]|AnyTypedArray} T\n * @param {T} arr array of numbers.\n * @returns {T extends bigint[]|BigTypedArray ? [bigint, number] : [number, number]} the value and index of the maximum element, of the form: [valueOfMax, indexOfMax]\n * @throws {Error} If array is empty.\n */\nexport function max(arr: number[] | bigint[] | TypedArray) {\n  if (arr.length === 0) throw Error('Array must not be empty');\n  let max = arr[0];\n  let indexOfMax = 0;\n  for (let i = 1; i < arr.length; ++i) {\n    if (arr[i] > max) {\n      max = arr[i];\n      indexOfMax = i;\n    }\n  }\n  return /** @type {T extends bigint[]|BigTypedArray ? [bigint, number] : [number, number]} */ [max, indexOfMax];\n}\n\nfunction isPowerOfTwo(number: number) {\n  // Check if the number is greater than 0 and has only one bit set to 1\n  return number > 0 && (number & (number - 1)) === 0;\n}\n\n/**\n * Implementation of Radix-4 FFT.\n *\n * P2FFT class provides functionality for performing Fast Fourier Transform on arrays\n * which are a power of two in length.\n * Code adapted from https://www.npmjs.com/package/fft.js\n */\nclass P2FFT {\n  /**\n   * @param {number} size The size of the input array. Must be a power of two larger than 1.\n   * @throws {Error} FFT size must be a power of two larger than 1.\n   */\n  private size: number;\n  private _csize: number;\n  private _width: number;\n  private _bitrev: Int32Array;\n  private table: Float64Array;\n\n  constructor(size: number) {\n    this.size = size | 0; // convert to a 32-bit signed integer\n    if (this.size <= 1 || !isPowerOfTwo(this.size)) throw new Error('FFT size must be a power of two larger than 1');\n\n    this._csize = size << 1;\n\n    this.table = new Float64Array(this.size * 2);\n    for (let i = 0; i < this.table.length; i += 2) {\n      const angle = (Math.PI * i) / this.size;\n      this.table[i] = Math.cos(angle);\n      this.table[i + 1] = -Math.sin(angle);\n    }\n\n    // Find size's power of two\n    let power = 0;\n    for (let t = 1; this.size > t; t <<= 1) ++power;\n\n    // Calculate initial step's width:\n    //   * If we are full radix-4, it is 2x smaller to give inital len=8\n    //   * Otherwise it is the same as `power` to give len=4\n    this._width = power % 2 === 0 ? power - 1 : power;\n\n    // Pre-compute bit-reversal patterns\n    this._bitrev = new Int32Array(1 << this._width);\n    for (let j = 0; j < this._bitrev.length; ++j) {\n      this._bitrev[j] = 0;\n      for (let shift = 0; shift < this._width; shift += 2) {\n        const revShift = this._width - shift - 2;\n        this._bitrev[j] |= ((j >>> shift) & 3) << revShift;\n      }\n    }\n  }\n\n  /**\n   * Create a complex number array with size `2 * size`\n   *\n   * @returns {Float64Array} A complex number array with size `2 * size`\n   */\n  createComplexArray() {\n    return new Float64Array(this._csize);\n  }\n\n  /**\n   * Converts a complex number representation stored in a Float64Array to an array of real numbers.\n   *\n   * @param {Float64Array} complex The complex number representation to be converted.\n   * @param {number[]} [storage] An optional array to store the result in.\n   * @returns {number[]} An array of real numbers representing the input complex number representation.\n   */\n  fromComplexArray(complex: Float64Array, storage?: number[]) {\n    const res = storage || new Array(complex.length >>> 1);\n    for (let i = 0; i < complex.length; i += 2) res[i >>> 1] = complex[i];\n    return res;\n  }\n\n  /**\n   * Convert a real-valued input array to a complex-valued output array.\n   * @param {Float64Array} input The real-valued input array.\n   * @param {Float64Array} [storage] Optional buffer to store the output array.\n   * @returns {Float64Array} The complex-valued output array.\n   */\n  toComplexArray(input: number[], storage?: Float64Array) {\n    const res = storage || this.createComplexArray();\n    for (let i = 0; i < res.length; i += 2) {\n      res[i] = input[i >>> 1];\n      res[i + 1] = 0;\n    }\n    return res;\n  }\n\n  /**\n   * Performs a Fast Fourier Transform (FFT) on the given input data and stores the result in the output buffer.\n   *\n   * @param {Float64Array} out The output buffer to store the result.\n   * @param {Float64Array} data The input data to transform.\n   *\n   * @throws {Error} Input and output buffers must be different.\n   *\n   * @returns {void}\n   */\n  transform(out: Float64Array, data: Float64Array) {\n    if (out === data) throw new Error('Input and output buffers must be different');\n\n    this._transform4(out, data, 1 /* DONE */);\n  }\n\n  /**\n   * Performs a real-valued forward FFT on the given input buffer and stores the result in the given output buffer.\n   * The input buffer must contain real values only, while the output buffer will contain complex values. The input and\n   * output buffers must be different.\n   *\n   * @param {Float64Array} out The output buffer.\n   * @param {Float64Array} data The input buffer containing real values.\n   *\n   * @throws {Error} If the input and output buffers are the same.\n   */\n  realTransform(out: Float64Array, data: Float64Array) {\n    if (out === data) throw new Error('Input and output buffers must be different');\n\n    this._realTransform4(out, data, 1 /* DONE */);\n  }\n\n  /**\n   * Performs an inverse FFT transformation on the given `data` array, and stores the result in `out`.\n   * The `out` array must be a different buffer than the `data` array. The `out` array will contain the\n   * result of the transformation. The `data` array will not be modified.\n   *\n   * @param {Float64Array} out The output buffer for the transformed data.\n   * @param {Float64Array} data The input data to transform.\n   * @throws {Error} If `out` and `data` refer to the same buffer.\n   * @returns {void}\n   */\n  inverseTransform(out: Float64Array, data: Float64Array) {\n    if (out === data) throw new Error('Input and output buffers must be different');\n\n    this._transform4(out, data, -1 /* DONE */);\n    for (let i = 0; i < out.length; ++i) out[i] /= this.size;\n  }\n\n  /**\n   * Performs a radix-4 implementation of a discrete Fourier transform on a given set of data.\n   *\n   * @param {Float64Array} out The output buffer for the transformed data.\n   * @param {Float64Array} data The input buffer of data to be transformed.\n   * @param {number} inv A scaling factor to apply to the transform.\n   * @returns {void}\n   */\n  _transform4(out: Float64Array, data: Float64Array, inv: number) {\n    // radix-4 implementation\n\n    const size = this._csize;\n\n    // Initial step (permute and transform)\n    const width = this._width;\n    let step = 1 << width;\n    let len = (size / step) << 1;\n\n    let outOff;\n    let t;\n    const bitrev = this._bitrev;\n    if (len === 4) {\n      for (outOff = 0, t = 0; outOff < size; outOff += len, ++t) {\n        const off = bitrev[t];\n        this._singleTransform2(data, out, outOff, off, step);\n      }\n    } else {\n      // len === 8\n      for (outOff = 0, t = 0; outOff < size; outOff += len, ++t) {\n        const off = bitrev[t];\n        this._singleTransform4(data, out, outOff, off, step, inv);\n      }\n    }\n\n    // Loop through steps in decreasing order\n    const table = this.table;\n    for (step >>= 2; step >= 2; step >>= 2) {\n      len = (size / step) << 1;\n      const quarterLen = len >>> 2;\n\n      // Loop through offsets in the data\n      for (outOff = 0; outOff < size; outOff += len) {\n        // Full case\n        const limit = outOff + quarterLen - 1;\n        for (let i = outOff, k = 0; i < limit; i += 2, k += step) {\n          const A = i;\n          const B = A + quarterLen;\n          const C = B + quarterLen;\n          const D = C + quarterLen;\n\n          // Original values\n          const Ar = out[A];\n          const Ai = out[A + 1];\n          const Br = out[B];\n          const Bi = out[B + 1];\n          const Cr = out[C];\n          const Ci = out[C + 1];\n          const Dr = out[D];\n          const Di = out[D + 1];\n\n          const tableBr = table[k];\n          const tableBi = inv * table[k + 1];\n          const MBr = Br * tableBr - Bi * tableBi;\n          const MBi = Br * tableBi + Bi * tableBr;\n\n          const tableCr = table[2 * k];\n          const tableCi = inv * table[2 * k + 1];\n          const MCr = Cr * tableCr - Ci * tableCi;\n          const MCi = Cr * tableCi + Ci * tableCr;\n\n          const tableDr = table[3 * k];\n          const tableDi = inv * table[3 * k + 1];\n          const MDr = Dr * tableDr - Di * tableDi;\n          const MDi = Dr * tableDi + Di * tableDr;\n\n          // Pre-Final values\n          const T0r = Ar + MCr;\n          const T0i = Ai + MCi;\n          const T1r = Ar - MCr;\n          const T1i = Ai - MCi;\n          const T2r = MBr + MDr;\n          const T2i = MBi + MDi;\n          const T3r = inv * (MBr - MDr);\n          const T3i = inv * (MBi - MDi);\n\n          // Final values\n          out[A] = T0r + T2r;\n          out[A + 1] = T0i + T2i;\n          out[B] = T1r + T3i;\n          out[B + 1] = T1i - T3r;\n          out[C] = T0r - T2r;\n          out[C + 1] = T0i - T2i;\n          out[D] = T1r - T3i;\n          out[D + 1] = T1i + T3r;\n        }\n      }\n    }\n  }\n\n  /**\n   * Performs a radix-2 implementation of a discrete Fourier transform on a given set of data.\n   *\n   * @param {Float64Array} data The input buffer of data to be transformed.\n   * @param {Float64Array} out The output buffer for the transformed data.\n   * @param {number} outOff The offset at which to write the output data.\n   * @param {number} off The offset at which to begin reading the input data.\n   * @param {number} step The step size for indexing the input data.\n   * @returns {void}\n   */\n  _singleTransform2(data: Float64Array, out: Float64Array, outOff: number, off: number, step: number) {\n    // radix-2 implementation\n    // NOTE: Only called for len=4\n\n    const evenR = data[off];\n    const evenI = data[off + 1];\n    const oddR = data[off + step];\n    const oddI = data[off + step + 1];\n\n    out[outOff] = evenR + oddR;\n    out[outOff + 1] = evenI + oddI;\n    out[outOff + 2] = evenR - oddR;\n    out[outOff + 3] = evenI - oddI;\n  }\n\n  /**\n   * Performs radix-4 transformation on input data of length 8\n   *\n   * @param {Float64Array} data Input data array of length 8\n   * @param {Float64Array} out Output data array of length 8\n   * @param {number} outOff Index of output array to start writing from\n   * @param {number} off Index of input array to start reading from\n   * @param {number} step Step size between elements in input array\n   * @param {number} inv Scaling factor for inverse transform\n   *\n   * @returns {void}\n   */\n  _singleTransform4(data: Float64Array, out: Float64Array, outOff: number, off: number, step: number, inv: number) {\n    // radix-4\n    // NOTE: Only called for len=8\n    const step2 = step * 2;\n    const step3 = step * 3;\n\n    // Original values\n    const Ar = data[off];\n    const Ai = data[off + 1];\n    const Br = data[off + step];\n    const Bi = data[off + step + 1];\n    const Cr = data[off + step2];\n    const Ci = data[off + step2 + 1];\n    const Dr = data[off + step3];\n    const Di = data[off + step3 + 1];\n\n    // Pre-Final values\n    const T0r = Ar + Cr;\n    const T0i = Ai + Ci;\n    const T1r = Ar - Cr;\n    const T1i = Ai - Ci;\n    const T2r = Br + Dr;\n    const T2i = Bi + Di;\n    const T3r = inv * (Br - Dr);\n    const T3i = inv * (Bi - Di);\n\n    // Final values\n    out[outOff] = T0r + T2r;\n    out[outOff + 1] = T0i + T2i;\n    out[outOff + 2] = T1r + T3i;\n    out[outOff + 3] = T1i - T3r;\n    out[outOff + 4] = T0r - T2r;\n    out[outOff + 5] = T0i - T2i;\n    out[outOff + 6] = T1r - T3i;\n    out[outOff + 7] = T1i + T3r;\n  }\n\n  /**\n   * Real input radix-4 implementation\n   * @param {Float64Array} out Output array for the transformed data\n   * @param {Float64Array} data Input array of real data to be transformed\n   * @param {number} inv The scale factor used to normalize the inverse transform\n   */\n  _realTransform4(out: Float64Array, data: Float64Array, inv: number) {\n    // Real input radix-4 implementation\n    const size = this._csize;\n\n    // Initial step (permute and transform)\n    const width = this._width;\n    let step = 1 << width;\n    let len = (size / step) << 1;\n\n    let outOff;\n    let t;\n    const bitrev = this._bitrev;\n    if (len === 4) {\n      for (outOff = 0, t = 0; outOff < size; outOff += len, ++t) {\n        const off = bitrev[t];\n        this._singleRealTransform2(data, out, outOff, off >>> 1, step >>> 1);\n      }\n    } else {\n      // len === 8\n      for (outOff = 0, t = 0; outOff < size; outOff += len, ++t) {\n        const off = bitrev[t];\n        this._singleRealTransform4(data, out, outOff, off >>> 1, step >>> 1, inv);\n      }\n    }\n\n    // Loop through steps in decreasing order\n    const table = this.table;\n    for (step >>= 2; step >= 2; step >>= 2) {\n      len = (size / step) << 1;\n      const halfLen = len >>> 1;\n      const quarterLen = halfLen >>> 1;\n      const hquarterLen = quarterLen >>> 1;\n\n      // Loop through offsets in the data\n      for (outOff = 0; outOff < size; outOff += len) {\n        for (let i = 0, k = 0; i <= hquarterLen; i += 2, k += step) {\n          const A = outOff + i;\n          const B = A + quarterLen;\n          const C = B + quarterLen;\n          const D = C + quarterLen;\n\n          // Original values\n          const Ar = out[A];\n          const Ai = out[A + 1];\n          const Br = out[B];\n          const Bi = out[B + 1];\n          const Cr = out[C];\n          const Ci = out[C + 1];\n          const Dr = out[D];\n          const Di = out[D + 1];\n\n          // Middle values\n          const MAr = Ar;\n          const MAi = Ai;\n\n          const tableBr = table[k];\n          const tableBi = inv * table[k + 1];\n          const MBr = Br * tableBr - Bi * tableBi;\n          const MBi = Br * tableBi + Bi * tableBr;\n\n          const tableCr = table[2 * k];\n          const tableCi = inv * table[2 * k + 1];\n          const MCr = Cr * tableCr - Ci * tableCi;\n          const MCi = Cr * tableCi + Ci * tableCr;\n\n          const tableDr = table[3 * k];\n          const tableDi = inv * table[3 * k + 1];\n          const MDr = Dr * tableDr - Di * tableDi;\n          const MDi = Dr * tableDi + Di * tableDr;\n\n          // Pre-Final values\n          const T0r = MAr + MCr;\n          const T0i = MAi + MCi;\n          const T1r = MAr - MCr;\n          const T1i = MAi - MCi;\n          const T2r = MBr + MDr;\n          const T2i = MBi + MDi;\n          const T3r = inv * (MBr - MDr);\n          const T3i = inv * (MBi - MDi);\n\n          // Final values\n          out[A] = T0r + T2r;\n          out[A + 1] = T0i + T2i;\n          out[B] = T1r + T3i;\n          out[B + 1] = T1i - T3r;\n\n          // Output final middle point\n          if (i === 0) {\n            out[C] = T0r - T2r;\n            out[C + 1] = T0i - T2i;\n            continue;\n          }\n\n          // Do not overwrite ourselves\n          if (i === hquarterLen) continue;\n\n          const SA = outOff + quarterLen - i;\n          const SB = outOff + halfLen - i;\n\n          out[SA] = T1r - inv * T3i;\n          out[SA + 1] = -T1i - inv * T3r;\n          out[SB] = T0r - inv * T2r;\n          out[SB + 1] = -T0i + inv * T2i;\n        }\n      }\n    }\n\n    // Complete the spectrum by adding its mirrored negative frequency components.\n    const half = size >>> 1;\n    for (let i = 2; i < half; i += 2) {\n      out[size - i] = out[i];\n      out[size - i + 1] = -out[i + 1];\n    }\n  }\n\n  /**\n   * Performs a single real input radix-2 transformation on the provided data\n   *\n   * @param {Float64Array} data The input data array\n   * @param {Float64Array} out The output data array\n   * @param {number} outOff The output offset\n   * @param {number} off The input offset\n   * @param {number} step The step\n   *\n   * @returns {void}\n   */\n  _singleRealTransform2(data: Float64Array, out: Float64Array, outOff: number, off: number, step: number) {\n    // radix-2 implementation\n    // NOTE: Only called for len=4\n\n    const evenR = data[off];\n    const oddR = data[off + step];\n\n    out[outOff] = evenR + oddR;\n    out[outOff + 1] = 0;\n    out[outOff + 2] = evenR - oddR;\n    out[outOff + 3] = 0;\n  }\n\n  /**\n   * Computes a single real-valued transform using radix-4 algorithm.\n   * This method is only called for len=8.\n   *\n   * @param {Float64Array} data The input data array.\n   * @param {Float64Array} out The output data array.\n   * @param {number} outOff The offset into the output array.\n   * @param {number} off The offset into the input array.\n   * @param {number} step The step size for the input array.\n   * @param {number} inv The value of inverse.\n   */\n  _singleRealTransform4(data: Float64Array, out: Float64Array, outOff: number, off: number, step: number, inv: number) {\n    // radix-4\n    // NOTE: Only called for len=8\n    const step2 = step * 2;\n    const step3 = step * 3;\n\n    // Original values\n    const Ar = data[off];\n    const Br = data[off + step];\n    const Cr = data[off + step2];\n    const Dr = data[off + step3];\n\n    // Pre-Final values\n    const T0r = Ar + Cr;\n    const T1r = Ar - Cr;\n    const T2r = Br + Dr;\n    const T3r = inv * (Br - Dr);\n\n    // Final values\n    out[outOff] = T0r + T2r;\n    out[outOff + 1] = 0;\n    out[outOff + 2] = T1r;\n    out[outOff + 3] = -T3r;\n    out[outOff + 4] = T0r - T2r;\n    out[outOff + 5] = 0;\n    out[outOff + 6] = T1r;\n    out[outOff + 7] = T3r;\n  }\n}\n\n/**\n * NP2FFT class provides functionality for performing Fast Fourier Transform on arrays\n * which are not a power of two in length. In such cases, the chirp-z transform is used.\n *\n * For more information, see: https://math.stackexchange.com/questions/77118/non-power-of-2-ffts/77156#77156\n */\nclass NP2FFT {\n  private _f: P2FFT;\n  private bufferSize: number;\n  private _a: number;\n  private _chirpBuffer: Float64Array;\n  private _buffer1: Float64Array;\n  private _buffer2: Float64Array;\n  private _outBuffer1: Float64Array;\n  private _outBuffer2: Float64Array;\n  private _slicedChirpBuffer: Float64Array;\n\n  constructor(fft_length: number) {\n    // Helper variables\n    const a = 2 * (fft_length - 1);\n    const b = 2 * (2 * fft_length - 1);\n    const nextP2 = 2 ** Math.ceil(Math.log2(b));\n    this.bufferSize = nextP2;\n    this._a = a;\n\n    // Define buffers\n    // Compute chirp for transform\n    const chirp = new Float64Array(b);\n    const ichirp = new Float64Array(nextP2);\n    this._chirpBuffer = new Float64Array(nextP2);\n    this._buffer1 = new Float64Array(nextP2);\n    this._buffer2 = new Float64Array(nextP2);\n    this._outBuffer1 = new Float64Array(nextP2);\n    this._outBuffer2 = new Float64Array(nextP2);\n\n    // Compute complex exponentiation\n    const theta = (-2 * Math.PI) / fft_length;\n    const baseR = Math.cos(theta);\n    const baseI = Math.sin(theta);\n\n    // Precompute helper for chirp-z transform\n    for (let i = 0; i < b >> 1; ++i) {\n      // Compute complex power:\n      const e = (i + 1 - fft_length) ** 2 / 2.0;\n\n      // Compute the modulus and argument of the result\n      const result_mod = Math.sqrt(baseR ** 2 + baseI ** 2) ** e;\n      const result_arg = e * Math.atan2(baseI, baseR);\n\n      // Convert the result back to rectangular form\n      // and assign to chirp and ichirp\n      const i2 = 2 * i;\n      chirp[i2] = result_mod * Math.cos(result_arg);\n      chirp[i2 + 1] = result_mod * Math.sin(result_arg);\n\n      // conjugate\n      ichirp[i2] = chirp[i2];\n      ichirp[i2 + 1] = -chirp[i2 + 1];\n    }\n    this._slicedChirpBuffer = chirp.subarray(a, b);\n\n    // create object to perform Fast Fourier Transforms\n    // with `nextP2` complex numbers\n    this._f = new P2FFT(nextP2 >> 1);\n    this._f.transform(this._chirpBuffer, ichirp);\n  }\n\n  _transform(output: Float64Array, input: Float64Array, real: boolean) {\n    const ib1 = this._buffer1;\n    const ib2 = this._buffer2;\n    const ob2 = this._outBuffer1;\n    const ob3 = this._outBuffer2;\n    const cb = this._chirpBuffer;\n    const sb = this._slicedChirpBuffer;\n    const a = this._a;\n\n    if (real) {\n      // Real multiplication\n      for (let j = 0; j < sb.length; j += 2) {\n        const j2 = j + 1;\n        const j3 = j >> 1;\n\n        const a_real = input[j3];\n        ib1[j] = a_real * sb[j];\n        ib1[j2] = a_real * sb[j2];\n      }\n    } else {\n      // Complex multiplication\n      for (let j = 0; j < sb.length; j += 2) {\n        const j2 = j + 1;\n        ib1[j] = input[j] * sb[j] - input[j2] * sb[j2];\n        ib1[j2] = input[j] * sb[j2] + input[j2] * sb[j];\n      }\n    }\n    this._f.transform(ob2, ib1);\n\n    for (let j = 0; j < cb.length; j += 2) {\n      const j2 = j + 1;\n\n      ib2[j] = ob2[j] * cb[j] - ob2[j2] * cb[j2];\n      ib2[j2] = ob2[j] * cb[j2] + ob2[j2] * cb[j];\n    }\n    this._f.inverseTransform(ob3, ib2);\n\n    for (let j = 0; j < ob3.length; j += 2) {\n      const a_real = ob3[j + a];\n      const a_imag = ob3[j + a + 1];\n      const b_real = sb[j];\n      const b_imag = sb[j + 1];\n\n      output[j] = a_real * b_real - a_imag * b_imag;\n      output[j + 1] = a_real * b_imag + a_imag * b_real;\n    }\n  }\n\n  transform(output: Float64Array, input: Float64Array) {\n    this._transform(output, input, false);\n  }\n\n  realTransform(output: Float64Array, input: Float64Array) {\n    this._transform(output, input, true);\n  }\n\n  get size(): number {\n    return this.bufferSize;\n  }\n}\n\nexport class FFT {\n  fft_length: number;\n  isPowerOfTwo: boolean;\n  fft: P2FFT | NP2FFT;\n  outputBufferSize: number;\n\n  constructor(fft_length: number) {\n    this.fft_length = fft_length;\n    this.isPowerOfTwo = isPowerOfTwo(fft_length);\n    if (this.isPowerOfTwo) {\n      this.fft = new P2FFT(fft_length);\n      this.outputBufferSize = 2 * fft_length;\n    } else {\n      this.fft = new NP2FFT(fft_length);\n      this.outputBufferSize = this.fft.size;\n    }\n  }\n\n  realTransform(out: Float64Array, input: Float64Array) {\n    this.fft.realTransform(out, input);\n  }\n\n  transform(out: Float64Array, input: Float64Array) {\n    this.fft.transform(out, input);\n  }\n}\n\n/**\n * Performs median filter on the provided data. Padding is done by mirroring the data.\n * @param {AnyTypedArray} data The input array\n * @param {number} windowSize The window size\n */\nexport function medianFilter(data: AnyTypedArray, windowSize: number) {\n  if (windowSize % 2 === 0 || windowSize <= 0) {\n    throw new Error('Window size must be a positive odd number');\n  }\n\n  // @ts-ignore\n  const outputArray = new data.constructor(data.length);\n\n  // @ts-ignore\n  const buffer = new data.constructor(windowSize); // Reusable array for storing values\n\n  const halfWindowSize = Math.floor(windowSize / 2);\n\n  for (let i = 0; i < data.length; ++i) {\n    let valuesIndex = 0;\n\n    for (let j = -halfWindowSize; j <= halfWindowSize; ++j) {\n      let index = i + j;\n      if (index < 0) {\n        index = Math.abs(index);\n      } else if (index >= data.length) {\n        index = 2 * (data.length - 1) - index;\n      }\n\n      buffer[valuesIndex++] = data[index];\n    }\n\n    buffer.sort();\n    outputArray[i] = buffer[halfWindowSize];\n  }\n\n  return outputArray;\n}\n\n/**\n * Helper function to round a number to a given number of decimals\n * @param {number} num The number to round\n * @param {number} decimals The number of decimals\n * @returns {number} The rounded number\n */\nexport function round(num: number, decimals: number) {\n  const pow = Math.pow(10, decimals);\n  return Math.round(num * pow) / pow;\n}\n\n/**\n * Helper function to round a number to the nearest integer, with ties rounded to the nearest even number.\n * Also known as \"bankers' rounding\". This is the default rounding mode in python. For example:\n * 1.5 rounds to 2 and 2.5 rounds to 2.\n *\n * @param {number} x The number to round\n * @returns {number} The rounded number\n */\nexport function bankers_round(x: number) {\n  const r = Math.round(x);\n  const br = Math.abs(x) % 1 === 0.5 ? (r % 2 === 0 ? r : r - 1) : r;\n  return br;\n}\n\n/**\n * Measures similarity between two temporal sequences (e.g., input audio and output tokens\n * to generate token-level timestamps).\n * @param {number[][]} matrix\n * @returns {number[][]}\n */\nexport function dynamic_time_warping(matrix: number[][]) {\n  const output_length = matrix.length;\n  const input_length = matrix[0].length;\n\n  const outputShape = [output_length + 1, input_length + 1];\n\n  const cost = Array.from({ length: outputShape[0] }, () => Array(outputShape[1]).fill(Infinity));\n  cost[0][0] = 0;\n\n  const trace = Array.from({ length: outputShape[0] }, () => Array(outputShape[1]).fill(-1));\n\n  for (let j = 1; j < outputShape[1]; ++j) {\n    for (let i = 1; i < outputShape[0]; ++i) {\n      const c0 = cost[i - 1][j - 1];\n      const c1 = cost[i - 1][j];\n      const c2 = cost[i][j - 1];\n\n      let c, t;\n      if (c0 < c1 && c0 < c2) {\n        c = c0;\n        t = 0;\n      } else if (c1 < c0 && c1 < c2) {\n        c = c1;\n        t = 1;\n      } else {\n        c = c2;\n        t = 2;\n      }\n      cost[i][j] = matrix[i - 1][j - 1] + c;\n      trace[i][j] = t;\n    }\n  }\n\n  for (let i = 0; i < outputShape[1]; ++i) {\n    // trace[0, :] = 2\n    trace[0][i] = 2;\n  }\n  for (let i = 0; i < outputShape[0]; ++i) {\n    // trace[:, 0] = 1\n    trace[i][0] = 1;\n  }\n\n  // backtrace\n  let i = output_length;\n  let j = input_length;\n  let text_indices = [];\n  let time_indices = [];\n  while (i > 0 || j > 0) {\n    text_indices.push(i - 1);\n    time_indices.push(j - 1);\n\n    switch (trace[i][j]) {\n      case 0:\n        --i;\n        --j;\n        break;\n      case 1:\n        --i;\n        break;\n      case 2:\n        --j;\n        break;\n      default:\n        throw new Error(\n          `Internal error in dynamic time warping. Unexpected trace[${i}, ${j}]. Please file a bug report.`,\n        );\n    }\n  }\n\n  text_indices.reverse();\n  time_indices.reverse();\n\n  return [text_indices, time_indices];\n}\n","/**\n * @file Handler file for choosing the correct version of ONNX Runtime, based on the environment.\n * Ideally, we could import the `onnxruntime-web` and `onnxruntime-node` packages only when needed,\n * but dynamic imports don't seem to work with the current webpack version and/or configuration.\n * This is possibly due to the experimental nature of top-level await statements.\n * So, we just import both packages, and use the appropriate one based on the environment:\n *   - When running in node, we use `onnxruntime-node`.\n *   - When running in the browser, we use `onnxruntime-web` (`onnxruntime-node` is not bundled).\n *\n * This module is not directly exported, but can be accessed through the environment variables:\n * ```javascript\n * import { env } from '@huggingface/transformers';\n * console.log(env.backends.onnx);\n * ```\n *\n * @module backends/onnx\n */\n\nimport { env, apis } from '../env';\n\n// NOTE: Import order matters here. We need to import `onnxruntime-node` before `onnxruntime-web`.\n// In either case, we select the default export if it exists, otherwise we use the named export.\nimport * as ONNX from 'onnxruntime-web';\nexport { Tensor } from 'onnxruntime-common';\n\n/**\n * @typedef {import('onnxruntime-common').InferenceSession.ExecutionProviderConfig} ONNXExecutionProviders\n */\n\n/** @type {Record<import(\"../utils/devices.js\").DeviceType, ONNXExecutionProviders>} */\nconst DEVICE_TO_EXECUTION_PROVIDER_MAPPING = Object.freeze({\n  auto: null, // Auto-detect based on device and environment\n  gpu: null, // Auto-detect GPU\n  cpu: 'cpu', // CPU\n  wasm: 'wasm', // WebAssembly\n  webgpu: 'webgpu', // WebGPU\n  cuda: 'cuda', // CUDA\n  dml: 'dml', // DirectML\n\n  webnn: { name: 'webnn', deviceType: 'cpu' }, // WebNN (default)\n  'webnn-npu': { name: 'webnn', deviceType: 'npu' }, // WebNN NPU\n  'webnn-gpu': { name: 'webnn', deviceType: 'gpu' }, // WebNN GPU\n  'webnn-cpu': { name: 'webnn', deviceType: 'cpu' }, // WebNN CPU\n});\n\n/**\n * The list of supported devices, sorted by priority/performance.\n * @type {import(\"../utils/devices.js\").DeviceType[]}\n */\nconst supportedDevices: string[] = [];\n\n/** @type {ONNXExecutionProviders[]} */\nlet defaultDevices: string[] = [];\n\n\n// Then add WebNN support\nif (apis.IS_WEBNN_AVAILABLE) {\n  supportedDevices.push('webnn-gpu', 'webnn-cpu');\n}\n\n// Add WebGPU as an option if available\nif (apis.IS_WEBGPU_AVAILABLE) {\n  // Add WASM as fallback when WebGPU fails\n  supportedDevices.push('wasm', 'webgpu');\n}\n\n// Remove the previous \"Always keep WASM as fallback\" section since we've integrated it above\nif (defaultDevices.length === 0) {\n  defaultDevices = ['wasm'];\n}\n\nconst InferenceSession = ONNX.InferenceSession;\n\n/**\n * Map a device to the execution providers to use for the given device.\n * @param {import(\"../utils/devices.js\").DeviceType|\"auto\"|null} [device=null] (Optional) The device to run the inference on.\n * @returns {ONNXExecutionProviders[]} The execution providers to use for the given device.\n */\nexport function deviceToExecutionProviders(device = null) {\n  // Use the default execution providers if the user hasn't specified anything\n  if (!device) return defaultDevices;\n\n  // Handle overloaded cases\n  switch (device) {\n    case 'auto':\n      return supportedDevices;\n    case 'gpu':\n      return supportedDevices.filter((x) => ['webgpu', 'cuda', 'dml', 'webnn-gpu'].includes(x));\n  }\n\n  if (supportedDevices.includes(device)) {\n    return [DEVICE_TO_EXECUTION_PROVIDER_MAPPING[device] ?? device];\n  }\n\n  throw new Error(`Unsupported device: \"${device}\". Should be one of: ${supportedDevices.join(', ')}.`);\n}\n\n/**\n * To prevent multiple calls to `initWasm()`, we store the first call in a Promise\n * that is resolved when the first InferenceSession is created. Subsequent calls\n * will wait for this Promise to resolve before creating their own InferenceSession.\n * @type {Promise<any>|null}\n */\nlet wasmInitPromise: Promise<any> | null = null;\n\n/**\n * Create an ONNX inference session.\n * @param {Uint8Array} buffer The ONNX model buffer.\n * @param {import('onnxruntime-common').InferenceSession.SessionOptions} session_options ONNX inference session options.\n * @param {Object} session_config ONNX inference session configuration.\n * @returns {Promise<import('onnxruntime-common').InferenceSession & { config: Object}>} The ONNX inference session.\n */\nexport async function createInferenceSession(\n  buffer: Uint8Array,\n  session_options: any,\n  session_config: any\n) {\n  if (wasmInitPromise) {\n    // A previous session has already initialized the WASM runtime\n    // so we wait for it to resolve before creating this new session.\n    await wasmInitPromise;\n  }\n\n  const sessionPromise = InferenceSession.create(buffer, session_options);\n  wasmInitPromise ??= sessionPromise;\n  const session = await sessionPromise;\n  (session as any).config = session_config;\n  return session;\n}\n\n/**\n * Check if an object is an ONNX tensor.\n * @param {any} x The object to check\n * @returns {boolean} Whether the object is an ONNX tensor.\n */\nexport function isONNXTensor(x: any) {\n  return x instanceof ONNX.Tensor;\n}\n\n/** @type {import('onnxruntime-common').Env} */\n// @ts-ignore\nconst ONNX_ENV = ONNX?.env;\nif (ONNX_ENV?.wasm) {\n  // Initialize wasm backend with suitable default settings.\n\n  // (Optional) Set path to wasm files. This is needed when running in a web worker.\n  // https://onnxruntime.ai/docs/api/js/interfaces/Env.WebAssemblyFlags.html#wasmPaths\n  // We use remote wasm files by default to make it easier for newer users.\n  // In practice, users should probably self-host the necessary .wasm files.\n\n  ONNX_ENV.wasm.wasmPaths = {\n    wasm: `https://cdn.jsdelivr.net/npm/@huggingface/transformers@${env.version}/dist/ort-wasm-simd-threaded.jsep.wasm`,\n    mjs: `https://cdn.jsdelivr.net/npm/@huggingface/transformers@${env.version}/dist/ort-wasm-simd-threaded.jsep.mjs`,\n  };\n  // https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.2.4/dist/ort-wasm-simd-threaded.jsep.wasm\n  // console.log('ONNX_ENV.wasm.wasmPaths', ONNX_ENV.wasm.wasmPaths);\n  // TODO: Add support for loading WASM files from cached buffer when we upgrade to onnxruntime-web@1.19.0\n  // https://github.com/microsoft/onnxruntime/pull/21534\n\n  // Users may wish to proxy the WASM backend to prevent the UI from freezing,\n  // However, this is not necessary when using WebGPU, so we default to false.\n  ONNX_ENV.wasm.proxy = false;\n\n  // Disable threading to avoid potential issues\n  ONNX_ENV.wasm.numThreads = 1;\n  \n  // https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated\n  if (typeof crossOriginIsolated === 'undefined' || !crossOriginIsolated) {\n    ONNX_ENV.wasm.numThreads = 1;\n  }\n}\n\nif (ONNX_ENV?.webgpu) {\n  // console.log('ONNX_ENV.webgpu', ONNX_ENV.webgpu);\n  ONNX_ENV.webgpu.powerPreference = 'high-performance';\n}\n\n/**\n * Check if ONNX's WASM backend is being proxied.\n * @returns {boolean} Whether ONNX's WASM backend is being proxied.\n */\nexport function isONNXProxy() {\n  // TODO: Update this when allowing non-WASM backends.\n  return ONNX_ENV?.wasm?.proxy;\n}\n\n// Expose ONNX environment variables to `env.backends.onnx`\nenv.backends.onnx = ONNX_ENV;\n","import { createInferenceSession, isONNXProxy } from '../backends/onnx';\nimport { Tensor } from '../utils/tensor';\n\n/**\n * Asynchronously creates a wrapper function for running an ONNX inference session.\n *\n * @param {number[]} session_bytes The session data in bytes.\n * @param {import('onnxruntime-common').InferenceSession.SessionOptions} session_options The options for the ONNX session.\n * @template {string | [string] | string[]} T\n * @param {T} names The name(s) of the output tensor(s).\n *\n * @returns {Promise<function(Record<string, Tensor>): Promise<T extends string ? Tensor : T extends string[] ? { [K in keyof T]: Tensor } : never>>}\n * The wrapper function for running the ONNX inference session.\n */\nconst wrap = async (\n  session_bytes: number[],\n  session_options: import('onnxruntime-common').InferenceSession.SessionOptions,\n  names: string | string[],\n) => {\n  const session = await createInferenceSession(new Uint8Array(session_bytes), session_options, {});\n\n  let chain = Promise.resolve();\n\n  return /** @type {any} */ async (/** @type {Record<string, Tensor>} */ inputs: Record<string, Tensor>) => {\n    const proxied = isONNXProxy();\n    const ortFeed = Object.fromEntries(\n      Object.entries(inputs).map(([k, v]) => [k, (proxied ? v.clone() : v).ort_tensor]),\n    );\n    // When running in-browser via WASM, we need to chain calls to session.run to avoid \"Error: Session already started\"\n    const outputs = await (chain.then(() => session.run(ortFeed as any)));\n\n    if (Array.isArray(names)) {\n      return names.map((n) => new Tensor(outputs[n]));\n    } else {\n      return new Tensor(outputs[/** @type {string} */ names]);\n    }\n  };\n};\n\n// In-memory registry of initialized ONNX operators\nexport class TensorOpRegistry {\n  private static _nearest_interpolate_4d: any;\n  private static _bilinear_interpolate_4d: any;\n  private static _bicubic_interpolate_4d: any;\n  private static _matmul: any;\n  private static _stft: any;\n  private static _rfft: any;\n  private static _top_k: any;\n  private static _slice: any;\n\n  static session_options = {\n    // TODO: Allow for multiple execution providers\n    // executionProviders: ['webgpu'],\n  };\n\n  static get nearest_interpolate_4d() {\n    if (!this._nearest_interpolate_4d) {\n      this._nearest_interpolate_4d = wrap(\n        [\n          8, 10, 18, 0, 58, 129, 1, 10, 41, 10, 1, 120, 10, 0, 10, 0, 10, 1, 115, 18, 1, 121, 34, 6, 82, 101, 115, 105,\n          122, 101, 42, 18, 10, 4, 109, 111, 100, 101, 34, 7, 110, 101, 97, 114, 101, 115, 116, 160, 1, 3, 18, 1, 114,\n          90, 31, 10, 1, 120, 18, 26, 10, 24, 8, 1, 18, 20, 10, 3, 18, 1, 98, 10, 3, 18, 1, 99, 10, 3, 18, 1, 104, 10,\n          3, 18, 1, 119, 90, 15, 10, 1, 115, 18, 10, 10, 8, 8, 7, 18, 4, 10, 2, 8, 4, 98, 31, 10, 1, 121, 18, 26, 10,\n          24, 8, 1, 18, 20, 10, 3, 18, 1, 98, 10, 3, 18, 1, 99, 10, 3, 18, 1, 104, 10, 3, 18, 1, 119, 66, 2, 16, 21,\n        ],\n        this.session_options,\n        'y',\n      );\n    }\n    return this._nearest_interpolate_4d;\n  }\n  static get bilinear_interpolate_4d() {\n    if (!this._bilinear_interpolate_4d) {\n      this._bilinear_interpolate_4d = wrap(\n        [\n          8, 9, 18, 0, 58, 128, 1, 10, 40, 10, 1, 120, 10, 0, 10, 0, 10, 1, 115, 18, 1, 121, 34, 6, 82, 101, 115, 105,\n          122, 101, 42, 17, 10, 4, 109, 111, 100, 101, 34, 6, 108, 105, 110, 101, 97, 114, 160, 1, 3, 18, 1, 114, 90,\n          31, 10, 1, 120, 18, 26, 10, 24, 8, 1, 18, 20, 10, 3, 18, 1, 98, 10, 3, 18, 1, 99, 10, 3, 18, 1, 104, 10, 3,\n          18, 1, 119, 90, 15, 10, 1, 115, 18, 10, 10, 8, 8, 7, 18, 4, 10, 2, 8, 4, 98, 31, 10, 1, 121, 18, 26, 10, 24,\n          8, 1, 18, 20, 10, 3, 18, 1, 98, 10, 3, 18, 1, 99, 10, 3, 18, 1, 104, 10, 3, 18, 1, 119, 66, 2, 16, 20,\n        ],\n        this.session_options,\n        'y',\n      );\n    }\n    return this._bilinear_interpolate_4d;\n  }\n\n  static get bicubic_interpolate_4d() {\n    if (!this._bicubic_interpolate_4d) {\n      this._bicubic_interpolate_4d = wrap(\n        [\n          8, 9, 18, 0, 58, 127, 10, 39, 10, 1, 120, 10, 0, 10, 0, 10, 1, 115, 18, 1, 121, 34, 6, 82, 101, 115, 105, 122,\n          101, 42, 16, 10, 4, 109, 111, 100, 101, 34, 5, 99, 117, 98, 105, 99, 160, 1, 3, 18, 1, 114, 90, 31, 10, 1,\n          120, 18, 26, 10, 24, 8, 1, 18, 20, 10, 3, 18, 1, 98, 10, 3, 18, 1, 99, 10, 3, 18, 1, 104, 10, 3, 18, 1, 119,\n          90, 15, 10, 1, 115, 18, 10, 10, 8, 8, 7, 18, 4, 10, 2, 8, 4, 98, 31, 10, 1, 121, 18, 26, 10, 24, 8, 1, 18, 20,\n          10, 3, 18, 1, 98, 10, 3, 18, 1, 99, 10, 3, 18, 1, 104, 10, 3, 18, 1, 119, 66, 2, 16, 20,\n        ],\n        this.session_options,\n        'y',\n      );\n    }\n    return this._bicubic_interpolate_4d;\n  }\n\n  static get matmul() {\n    if (!this._matmul) {\n      this._matmul = wrap(\n        [\n          8, 9, 18, 0, 58, 55, 10, 17, 10, 1, 97, 10, 1, 98, 18, 1, 99, 34, 6, 77, 97, 116, 77, 117, 108, 18, 1, 114,\n          90, 9, 10, 1, 97, 18, 4, 10, 2, 8, 1, 90, 9, 10, 1, 98, 18, 4, 10, 2, 8, 1, 98, 9, 10, 1, 99, 18, 4, 10, 2, 8,\n          1, 66, 2, 16, 20,\n        ],\n        this.session_options,\n        'c',\n      );\n    }\n    return this._matmul;\n  }\n\n  static get stft() {\n    if (!this._stft) {\n      this._stft = wrap(\n        [\n          8, 7, 18, 0, 58, 148, 1, 10, 38, 10, 1, 115, 10, 1, 106, 10, 1, 119, 10, 1, 108, 18, 1, 111, 34, 4, 83, 84,\n          70, 84, 42, 15, 10, 8, 111, 110, 101, 115, 105, 100, 101, 100, 24, 1, 160, 1, 2, 18, 1, 115, 90, 26, 10, 1,\n          115, 18, 21, 10, 19, 8, 1, 18, 15, 10, 3, 18, 1, 98, 10, 3, 18, 1, 115, 10, 3, 18, 1, 99, 90, 11, 10, 1, 106,\n          18, 6, 10, 4, 8, 7, 18, 0, 90, 16, 10, 1, 119, 18, 11, 10, 9, 8, 1, 18, 5, 10, 3, 18, 1, 119, 90, 11, 10, 1,\n          108, 18, 6, 10, 4, 8, 7, 18, 0, 98, 31, 10, 1, 111, 18, 26, 10, 24, 8, 1, 18, 20, 10, 3, 18, 1, 98, 10, 3, 18,\n          1, 102, 10, 3, 18, 1, 100, 10, 3, 18, 1, 99, 66, 2, 16, 17,\n        ],\n        this.session_options,\n        'o',\n      );\n    }\n    return this._stft;\n  }\n\n  static get rfft() {\n    if (!this._rfft) {\n      this._rfft = wrap(\n        [\n          8, 9, 18, 0, 58, 97, 10, 33, 10, 1, 120, 10, 0, 10, 1, 97, 18, 1, 121, 34, 3, 68, 70, 84, 42, 15, 10, 8, 111,\n          110, 101, 115, 105, 100, 101, 100, 24, 1, 160, 1, 2, 18, 1, 100, 90, 21, 10, 1, 120, 18, 16, 10, 14, 8, 1, 18,\n          10, 10, 3, 18, 1, 115, 10, 3, 18, 1, 99, 90, 11, 10, 1, 97, 18, 6, 10, 4, 8, 7, 18, 0, 98, 21, 10, 1, 121, 18,\n          16, 10, 14, 8, 1, 18, 10, 10, 3, 18, 1, 115, 10, 3, 18, 1, 99, 66, 2, 16, 20,\n        ],\n        this.session_options,\n        'y',\n      );\n    }\n    return this._rfft;\n  }\n\n  static get top_k() {\n    if (!this._top_k) {\n      this._top_k = wrap(\n        [\n          8, 10, 18, 0, 58, 73, 10, 18, 10, 1, 120, 10, 1, 107, 18, 1, 118, 18, 1, 105, 34, 4, 84, 111, 112, 75, 18, 1,\n          116, 90, 9, 10, 1, 120, 18, 4, 10, 2, 8, 1, 90, 15, 10, 1, 107, 18, 10, 10, 8, 8, 7, 18, 4, 10, 2, 8, 1, 98,\n          9, 10, 1, 118, 18, 4, 10, 2, 8, 1, 98, 9, 10, 1, 105, 18, 4, 10, 2, 8, 7, 66, 2, 16, 21,\n        ],\n        this.session_options,\n        [/* Values */ 'v', /* Indices */ 'i'],\n      );\n    }\n    return this._top_k;\n  }\n\n  static get slice() {\n    if (!this._slice) {\n      this._slice = wrap(\n        [\n          8, 7, 18, 0, 58, 96, 10, 25, 10, 1, 120, 10, 1, 115, 10, 1, 101, 10, 1, 97, 10, 1, 116, 18, 1, 121, 34, 5, 83,\n          108, 105, 99, 101, 18, 1, 114, 90, 9, 10, 1, 120, 18, 4, 10, 2, 8, 1, 90, 9, 10, 1, 115, 18, 4, 10, 2, 8, 7,\n          90, 9, 10, 1, 101, 18, 4, 10, 2, 8, 7, 90, 9, 10, 1, 97, 18, 4, 10, 2, 8, 7, 90, 9, 10, 1, 116, 18, 4, 10, 2,\n          8, 7, 98, 9, 10, 1, 121, 18, 4, 10, 2, 8, 1, 66, 2, 16, 13,\n        ],\n        this.session_options,\n        'y',\n      );\n    }\n    return this._slice;\n  }\n}\n","/**\n * @file Helper module for `Tensor` processing.\n *\n * These functions and classes are only used internally,\n * meaning an end-user shouldn't need to access anything here.\n *\n * @module utils/tensor\n */\n\nimport { interpolate_data, max, min, permute_data } from './maths';\n\nimport { Tensor as ONNXTensor, isONNXTensor } from '../backends/onnx.js';\n\nimport { TensorOpRegistry } from '../ops/registry.js';\n\ntype TypedArray =\n  | Int8Array\n  | Uint8Array\n  | Uint8ClampedArray\n  | Int16Array\n  | Uint16Array\n  | Int32Array\n  | Uint32Array\n  | Float32Array\n  | Float64Array\n  | BigInt64Array\n  | BigUint64Array;\n\ntype DataArray = TypedArray | any[];\n\nconst DataTypeMap = Object.freeze({\n  float32: Float32Array,\n  float16: Uint16Array,\n  float64: Float64Array,\n  string: Array, // string[]\n  int8: Int8Array,\n  uint8: Uint8Array,\n  int16: Int16Array,\n  uint16: Uint16Array,\n  int32: Int32Array,\n  uint32: Uint32Array,\n  int64: BigInt64Array,\n  uint64: BigUint64Array,\n  bool: Uint8Array,\n  uint4: Uint8Array,\n  int4: Int8Array,\n});\n\ntype DataType = keyof typeof DataTypeMap;\n\n/**\n * @typedef {keyof typeof DataTypeMap} DataType\n * @typedef {import('./maths.js').AnyTypedArray | any[]} DataArray\n */\n\nexport class Tensor {\n  [index: number]: Tensor; // Add numeric index signature\n\n  /** @type {number[]} Dimensions of the tensor. */\n  get dims() {\n    // @ts-ignore\n    return this.ort_tensor.dims;\n  }\n  set dims(value) {\n    // FIXME: ONNXTensor declares dims as readonly so one needs to use the constructor() if dims change.\n    // @ts-ignore\n    this.ort_tensor.dims = value;\n  }\n\n  /** @type {DataType} Type of the tensor. */\n  get type(): DataType {\n    return (this.ort_tensor as { type: DataType }).type;\n  }\n\n  /** @type {DataArray} The data stored in the tensor. */\n  get data(): DataArray {\n    return (this.ort_tensor as { data: DataArray }).data;\n  }\n\n  /** @type {number} The number of elements in the tensor. */\n  get size() {\n    return (this.ort_tensor as { size: number }).size;\n  }\n\n  /** @type {string} The location of the tensor data. */\n  get location() {\n    return (this.ort_tensor as { location: string }).location;\n  }\n\n  ort_tensor;\n\n  /**\n   * Create a new Tensor or copy an existing Tensor.\n   * @param {[DataType, DataArray, number[]]|[ONNXTensor]} args\n   */\n  constructor(...args: [DataType, DataArray, number[]] | [ONNXTensor]) {\n    if (isONNXTensor(args[0])) {\n      this.ort_tensor = /** @type {ONNXTensor} */ args[0];\n    } else {\n      // Add debugging\n      // console.log('Creating new tensor:', {\n      //   type: args[0],\n      //   dataLength: (args[1] as DataArray).length,\n      //   dims: args[2]\n      // });\n      \n      try {\n        this.ort_tensor = new ONNXTensor(\n          args[0] as keyof typeof DataTypeMap,\n          args[1] as Exclude<TypedArray, Uint8ClampedArray>,\n          args[2],\n        );\n      } catch (error) {\n        console.error('Failed to create ONNXTensor:', {\n          error,\n          type: args[0],\n          dataLength: (args[1] as DataArray).length,\n          dims: args[2]\n        });\n        throw error;\n      }\n    }\n\n    return new Proxy(this, {\n      get: (obj, key) => {\n        if (typeof key === 'string') {\n          let index = Number(key);\n          if (Number.isInteger(index)) {\n            // key is an integer (i.e., index)\n            return obj._getitem(index);\n          }\n        }\n        // @ts-ignore\n        return obj[key];\n      },\n      set: (obj, key, value) => {\n        // TODO allow setting of data\n\n        // @ts-ignore\n        return (obj[key] = value);\n      },\n    });\n  }\n\n  dispose() {\n    (this.ort_tensor as ONNXTensor).dispose();\n    // this.ort_tensor = undefined;\n  }\n\n  /**\n   * Returns an iterator object for iterating over the tensor data in row-major order.\n   * If the tensor has more than one dimension, the iterator will yield subarrays.\n   * @returns {Iterator} An iterator object for iterating over the tensor data in row-major order.\n   */\n  *[Symbol.iterator]() {\n    const [iterLength, ...iterDims] = this.dims;\n\n    if (iterDims.length > 0) {\n      const iterSize = iterDims.reduce((a: number, b: number) => a * b);\n      for (let i = 0; i < iterLength; ++i) {\n        yield this._subarray(i, iterSize, iterDims);\n      }\n    } else {\n      yield* this.data;\n    }\n  }\n\n  /**\n   * Index into a Tensor object.\n   * @param {number} index The index to access.\n   * @returns {Tensor} The data at the specified index.\n   */\n  _getitem(index: number) {\n    const [iterLength, ...iterDims] = this.dims;\n\n    index = safeIndex(index, iterLength);\n\n    if (iterDims.length > 0) {\n      const iterSize = iterDims.reduce((a: number, b: number) => a * b);\n      return this._subarray(index, iterSize, iterDims);\n    } else {\n      return new Tensor(this.type, [this.data[index]], iterDims);\n    }\n  }\n\n  /**\n   * @param {number|bigint} item The item to search for in the tensor\n   * @returns {number} The index of the first occurrence of item in the tensor data.\n   */\n  indexOf(item: number | bigint) {\n    const this_data = this.data;\n    for (let index = 0; index < this_data.length; ++index) {\n      // Note: == instead of === so we can match Ints with BigInts\n      if (this_data[index] == item) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * @param {number} index\n   * @param {number} iterSize\n   * @param {any} iterDims\n   * @returns {Tensor}\n   */\n  _subarray(index: number, iterSize: number, iterDims: number[]) {\n    const o1 = index * iterSize;\n    const o2 = (index + 1) * iterSize;\n\n    // We use subarray if available (typed array), otherwise we use slice (normal array)\n    const data = 'subarray' in this.data ? this.data.subarray(o1, o2) : this.data.slice(o1, o2);\n    return new Tensor(this.type, data, iterDims);\n  }\n\n  /**\n   * Returns the value of this tensor as a standard JavaScript Number. This only works\n   * for tensors with one element. For other cases, see `Tensor.tolist()`.\n   * @returns {number|bigint} The value of this tensor as a standard JavaScript Number.\n   * @throws {Error} If the tensor has more than one element.\n   */\n  item() {\n    const this_data = this.data;\n    if (this_data.length !== 1) {\n      throw new Error(`a Tensor with ${this_data.length} elements cannot be converted to Scalar`);\n    }\n    return this_data[0];\n  }\n\n  /**\n   * Convert tensor data to a n-dimensional JS list\n   * @returns {Array}\n   */\n  tolist() {\n    return reshape(this.data, this.dims);\n  }\n\n  /**\n   * Return a new Tensor with the sigmoid function applied to each element.\n   * @returns {Tensor} The tensor with the sigmoid function applied.\n   */\n  sigmoid() {\n    return this.clone().sigmoid_();\n  }\n\n  /**\n   * Applies the sigmoid function to the tensor in place.\n   * @returns {Tensor} Returns `this`.\n   */\n  sigmoid_() {\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      this_data[i] = 1 / (1 + Math.exp(-this_data[i]));\n    }\n    return this;\n  }\n\n  /**\n   * Return a new Tensor with a callback function applied to each element.\n   * @param {Function} callback - The function to apply to each element. It should take three arguments:\n   *                              the current element, its index, and the tensor's data array.\n   * @returns {Tensor} A new Tensor with the callback function applied to each element.\n   */\n  map(callback: Function) {\n    return this.clone().map_(callback);\n  }\n\n  /**\n   * Apply a callback function to each element of the tensor in place.\n   * @param {Function} callback - The function to apply to each element. It should take three arguments:\n   *                              the current element, its index, and the tensor's data array.\n   * @returns {Tensor} Returns `this`.\n   */\n  map_(callback: Function) {\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      this_data[i] = callback(this_data[i], i, this_data);\n    }\n    return this;\n  }\n\n  /**\n   * Return a new Tensor with every element multiplied by a constant.\n   * @param {number} val The value to multiply by.\n   * @returns {Tensor} The new tensor.\n   */\n  mul(val: number) {\n    return this.clone().mul_(val);\n  }\n\n  /**\n   * Multiply the tensor by a constant in place.\n   * @param {number} val The value to multiply by.\n   * @returns {Tensor} Returns `this`.\n   */\n  mul_(val: number) {\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      this_data[i] *= val;\n    }\n    return this;\n  }\n\n  /**\n   * Return a new Tensor with every element divided by a constant.\n   * @param {number} val The value to divide by.\n   * @returns {Tensor} The new tensor.\n   */\n  div(val: number) {\n    return this.clone().div_(val);\n  }\n\n  /**\n   * Divide the tensor by a constant in place.\n   * @param {number} val The value to divide by.\n   * @returns {Tensor} Returns `this`.\n   */\n  div_(val: number) {\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      this_data[i] /= val;\n    }\n    return this;\n  }\n\n  /**\n   * Return a new Tensor with every element added by a constant.\n   * @param {number} val The value to add by.\n   * @returns {Tensor} The new tensor.\n   */\n  add(val: number) {\n    return this.clone().add_(val);\n  }\n\n  /**\n   * Add the tensor by a constant in place.\n   * @param {number} val The value to add by.\n   * @returns {Tensor} Returns `this`.\n   */\n  add_(val: number) {\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      this_data[i] += val;\n    }\n    return this;\n  }\n\n  /**\n   * Return a new Tensor with every element subtracted by a constant.\n   * @param {number} val The value to subtract by.\n   * @returns {Tensor} The new tensor.\n   */\n  sub(val: number) {\n    return this.clone().sub_(val);\n  }\n\n  /**\n   * Subtract the tensor by a constant in place.\n   * @param {number} val The value to subtract by.\n   * @returns {Tensor} Returns `this`.\n   */\n  sub_(val: number) {\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      this_data[i] -= val;\n    }\n    return this;\n  }\n\n  /**\n   * Creates a deep copy of the current Tensor.\n   * @returns {Tensor} A new Tensor with the same type, data, and dimensions as the original.\n   */\n  clone() {\n    return new Tensor(this.type, this.data.slice(), this.dims.slice());\n  }\n\n  /**\n   * Performs a slice operation on the Tensor along specified dimensions.\n   *\n   * Consider a Tensor that has a dimension of [4, 7]:\n   * ```\n   * [ 1,  2,  3,  4,  5,  6,  7]\n   * [ 8,  9, 10, 11, 12, 13, 14]\n   * [15, 16, 17, 18, 19, 20, 21]\n   * [22, 23, 24, 25, 26, 27, 28]\n   * ```\n   * We can slice against the two dims of row and column, for instance in this\n   * case we can start at the second element, and return to the second last,\n   * like this:\n   * ```\n   * tensor.slice([1, -1], [1, -1]);\n   * ```\n   * which would return:\n   * ```\n   * [  9, 10, 11, 12, 13 ]\n   * [ 16, 17, 18, 19, 20 ]\n   * ```\n   *\n   * @param {...(number|number[]|null)} slices The slice specifications for each dimension.\n   * - If a number is given, then a single element is selected.\n   * - If an array of two numbers is given, then a range of elements [start, end (exclusive)] is selected.\n   * - If null is given, then the entire dimension is selected.\n   * @returns {Tensor} A new Tensor containing the selected elements.\n   * @throws {Error} If the slice input is invalid.\n   */\n  slice(...slices: (number | number[] | null)[]) {\n    // This allows for slicing with ranges and numbers\n    const newTensorDims = [];\n    const newOffsets = [];\n\n    // slices is an array of numbers or arrays of numbers\n    // e.g., slices = [0, [1, 3], null, [0, 3]]\n    for (let sliceIndex = 0; sliceIndex < this.dims.length; ++sliceIndex) {\n      let slice = slices[sliceIndex];\n\n      if (slice === null || slice === undefined) {\n        // null or undefined means take the whole dimension\n        newOffsets.push([0, this.dims[sliceIndex]]);\n        newTensorDims.push(this.dims[sliceIndex]);\n      } else if (typeof slice === 'number') {\n        slice = safeIndex(slice, this.dims[sliceIndex], sliceIndex);\n\n        // A number means take a single element\n        newOffsets.push([slice, slice + 1]);\n      } else if (Array.isArray(slice) && slice.length === 2) {\n        // An array of length 2 means take a range of elements\n        let [start, end] = slice;\n        start = start === null ? 0 : safeIndex(start, this.dims[sliceIndex], sliceIndex, false);\n        end = end === null ? this.dims[sliceIndex] : safeIndex(end, this.dims[sliceIndex], sliceIndex, false);\n\n        if (start > end) {\n          throw new Error(`Invalid slice: ${slice}`);\n        }\n\n        const offsets = [Math.max(start, 0), Math.min(end, this.dims[sliceIndex])];\n\n        newOffsets.push(offsets);\n        newTensorDims.push(offsets[1] - offsets[0]);\n      } else {\n        throw new Error(`Invalid slice: ${slice}`);\n      }\n    }\n\n    const newDims = newOffsets.map(([start, end]) => end - start);\n    const newBufferSize = newDims.reduce((a, b) => a * b);\n\n    const this_data = this.data;\n    // Allocate memory\n    // @ts-ignore\n    const data = new this_data.constructor(newBufferSize);\n\n    // Precompute strides\n    const stride = this.stride();\n\n    for (let i = 0; i < newBufferSize; ++i) {\n      let originalIndex = 0;\n      for (let j = newDims.length - 1, num = i; j >= 0; --j) {\n        const size = newDims[j];\n        originalIndex += ((num % size) + newOffsets[j][0]) * stride[j];\n        num = Math.floor(num / size);\n      }\n      data[i] = this_data[originalIndex];\n    }\n    return new Tensor(this.type, data, newTensorDims);\n  }\n\n  /**\n   * Return a permuted version of this Tensor, according to the provided dimensions.\n   * @param  {...number} dims Dimensions to permute.\n   * @returns {Tensor} The permuted tensor.\n   */\n  permute(...dims: number[]) {\n    return permute(this, dims);\n  }\n\n  // TODO: implement transpose. For now (backwards compatibility), it's just an alias for permute()\n  transpose(...dims: number[]) {\n    return this.permute(...dims);\n  }\n\n  /**\n   * Returns the sum of each row of the input tensor in the given dimension dim.\n   *\n   * @param {number} [dim=null] The dimension or dimensions to reduce. If `null`, all dimensions are reduced.\n   * @param {boolean} keepdim Whether the output tensor has `dim` retained or not.\n   * @returns The summed tensor\n   */\n  sum(dim: number | null = null, keepdim: boolean = false) {\n    return this.norm(1 as any, dim, keepdim);\n  }\n\n  /**\n   * Returns the matrix norm or vector norm of a given tensor.\n   * @param {number|string} [p='fro'] The order of norm\n   * @param {number} [dim=null] Specifies which dimension of the tensor to calculate the norm across.\n   * If dim is None, the norm will be calculated across all dimensions of input.\n   * @param {boolean} [keepdim=false] Whether the output tensors have dim retained or not.\n   * @returns {Tensor} The norm of the tensor.\n   */\n  norm(p: number | string = 'fro', dim: number | null = null, keepdim = false) {\n    if (p === 'fro') {\n      // NOTE: Since we only support integer dims, Frobenius norm produces the same result as p=2.\n      p = 2;\n    } else if (typeof p === 'string') {\n      throw Error(`Unsupported norm: ${p}`);\n    }\n\n    const this_data = this.data;\n    const fn = (a: number, b: number) => a + (b ** p);\n\n    if (dim === null) {\n      // @ts-ignore\n      const val = this_data.reduce(fn, 0) ** (1 / p);\n      return new Tensor(this.type, [val], []);\n    }\n\n    const [type, result, resultDims] = reduce_helper(fn, this, dim, keepdim);\n\n\n    if (p !== 1) {\n      for (let i = 0; i < result.length; ++i) {\n        result[i] = result[i] ** (1 / p);\n      }\n    }\n\n    return new Tensor(type, result, resultDims);\n\n  }\n\n  /**\n   * Performs `L_p` normalization of inputs over specified dimension. Operates in place.\n   * @param {number} [p=2] The exponent value in the norm formulation\n   * @param {number} [dim=1] The dimension to reduce\n   * @returns {Tensor} `this` for operation chaining.\n   */\n  normalize_(p = 2.0, dim = 1) {\n    dim = safeIndex(dim, this.dims.length);\n\n    const norm = this.norm(p, dim, true);\n\n    const this_data = this.data;\n    const norm_data = norm.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      // Calculate the index in the resulting array\n      let resultIndex = 0;\n\n      for (let j = this.dims.length - 1, num = i, resultMultiplier = 1; j >= 0; --j) {\n        const size = this.dims[j];\n        if (j !== dim) {\n          const index = num % size;\n          resultIndex += index * resultMultiplier;\n          resultMultiplier *= this.dims[j];\n        }\n        num = Math.floor(num / size);\n      }\n\n      // Divide by normalized value\n      this_data[i] /= norm_data[resultIndex];\n    }\n\n    return this;\n  }\n\n  /**\n   * Performs `L_p` normalization of inputs over specified dimension.\n   * @param {number} [p=2] The exponent value in the norm formulation\n   * @param {number} [dim=1] The dimension to reduce\n   * @returns {Tensor} The normalized tensor.\n   */\n  normalize(p = 2.0, dim = 1) {\n    return this.clone().normalize_(p, dim);\n  }\n\n  /**\n   * Compute and return the stride of this tensor.\n   * Stride is the jump necessary to go from one element to the next one in the specified dimension dim.\n   * @returns {number[]} The stride of this tensor.\n   */\n  stride() {\n    return dimsToStride(this.dims);\n  }\n\n  /**\n   * Returns a tensor with all specified dimensions of input of size 1 removed.\n   *\n   * NOTE: The returned tensor shares the storage with the input tensor, so changing the contents of one will change the contents of the other.\n   * If you would like a copy, use `tensor.clone()` before squeezing.\n   *\n   * @param {number|number[]} [dim=null] If given, the input will be squeezed only in the specified dimensions.\n   * @returns {Tensor} The squeezed tensor\n   */\n  squeeze(dim: number | number[] | null = null) {\n    return new Tensor(this.type, this.data, calc_squeeze_dims(this.dims, dim));\n  }\n\n  /**\n   * In-place version of @see {@link Tensor.squeeze}\n   */\n  squeeze_(dim: number | null = null) {\n    this.dims = calc_squeeze_dims(this.dims, dim);\n    return this;\n  }\n\n  /**\n   * Returns a new tensor with a dimension of size one inserted at the specified position.\n   *\n   * NOTE: The returned tensor shares the same underlying data with this tensor.\n   *\n   * @param {number} dim The index at which to insert the singleton dimension\n   * @returns {Tensor} The unsqueezed tensor\n   */\n  unsqueeze(dim: number) {\n    return new Tensor(this.type, this.data, calc_unsqueeze_dims(this.dims, dim));\n  }\n\n  /**\n   * In-place version of @see {@link Tensor.unsqueeze}\n   */\n  unsqueeze_(dim: number) {\n    this.dims = calc_unsqueeze_dims(this.dims, dim);\n    return this;\n  }\n\n  /**\n   * In-place version of @see {@link Tensor.flatten}\n   */\n  flatten_(start_dim = 0, end_dim = -1) {\n    // TODO validate inputs\n    end_dim = (end_dim + this.dims.length) % this.dims.length;\n\n    let dimsToKeepBefore = this.dims.slice(0, start_dim);\n    let dimsToFlatten = this.dims.slice(start_dim, end_dim + 1);\n    let dimsToKeepAfter = this.dims.slice(end_dim + 1);\n\n    this.dims = [...dimsToKeepBefore, dimsToFlatten.reduce((a: number, b: number) => a * b, 1), ...dimsToKeepAfter];\n    return this;\n  }\n\n  /**\n   * Flattens input by reshaping it into a one-dimensional tensor.\n   * If `start_dim` or `end_dim` are passed, only dimensions starting with `start_dim`\n   * and ending with `end_dim` are flattened. The order of elements in input is unchanged.\n   * @param {number} start_dim the first dim to flatten\n   * @param {number} end_dim the last dim to flatten\n   * @returns {Tensor} The flattened tensor.\n   */\n  flatten(start_dim = 0, end_dim = -1) {\n    return this.clone().flatten_(start_dim, end_dim);\n  }\n\n  /**\n   * Returns a new tensor with the same data as the `self` tensor but of a different `shape`.\n   * @param  {...number} dims the desired size\n   * @returns {Tensor} The tensor with the same data but different shape\n   */\n  view(...dims: number[]) {\n    // TODO: validate dims\n    let inferredIndex = -1;\n    for (let i = 0; i < dims.length; ++i) {\n      if (dims[i] === -1) {\n        if (inferredIndex !== -1) {\n          throw new Error('Only one dimension can be inferred');\n        }\n        inferredIndex = i;\n      }\n    }\n\n    const this_data = this.data;\n    if (inferredIndex !== -1) {\n      // Some dimension must be inferred\n      const productOther = dims.reduce((product, curr, index) => {\n        return index !== inferredIndex ? product * curr : product;\n      }, 1);\n\n      dims[inferredIndex] = this_data.length / productOther;\n    }\n    return new Tensor(this.type, this_data, dims); // NOTE: uses same underlying storage\n  }\n\n  neg_() {\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      this_data[i] = -this_data[i];\n    }\n    return this;\n  }\n  neg() {\n    return this.clone().neg_();\n  }\n\n  /**\n  * Computes input > val element-wise.\n  * @param {number} val The value to compare with.\n  * @returns {Tensor} A boolean tensor that is `true` where input is greater than other and `false` elsewhere.\n  */\n  gt(val: number) {\n    const mask = new Uint8Array(this.data.length);\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      mask[i] = this_data[i] > val ? 1 : 0;\n    }\n    return new Tensor('bool', mask, this.dims);\n  }\n\n  /**\n   * Computes input < val element-wise.\n   * @param {number} val The value to compare with.\n   * @returns {Tensor} A boolean tensor that is `true` where input is less than other and `false` elsewhere.\n   */\n  lt(val: number) {\n    const mask = new Uint8Array(this.data.length);\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      mask[i] = this_data[i] < val ? 1 : 0;\n    }\n    return new Tensor('bool', mask, this.dims);\n  }\n\n  /**\n   * In-place version of @see {@link Tensor.clamp}\n   */\n  clamp_(min: number, max: number) {\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      this_data[i] = Math.min(Math.max(this_data[i], min), max);\n    }\n    return this;\n  }\n\n  /**\n   * Clamps all elements in input into the range [ min, max ]\n   * @param {number} min lower-bound of the range to be clamped to\n   * @param {number} max upper-bound of the range to be clamped to\n   * @returns {Tensor} the output tensor.\n   */\n  clamp(min: number, max: number) {\n    return this.clone().clamp_(min, max);\n  }\n\n  /**\n   * In-place version of @see {@link Tensor.round}\n   */\n  round_() {\n    const this_data = this.data;\n    for (let i = 0; i < this_data.length; ++i) {\n      this_data[i] = Math.round(this_data[i]);\n    }\n    return this;\n  }\n\n  /**\n   * Rounds elements of input to the nearest integer.\n   * @returns {Tensor} the output tensor.\n   */\n  round() {\n    return this.clone().round_();\n  }\n\n  mean(dim = null, keepdim = false) {\n    return mean(this, dim, keepdim);\n  }\n\n  min(dim = null, keepdim = false) {\n    if (dim !== null) {\n      const val = min(this.data as any)[0];\n      return new Tensor(this.type, [val], [/* scalar */]);\n    }\n    const [type, result, resultDims] = reduce_helper((a: any, b: any) => Math.min(a, b), this, dim, keepdim, Infinity);\n    return new Tensor(type, result, resultDims);\n  }\n  max(dim = null, keepdim = false) {\n    if (dim === null) {\n      // None to reduce over all dimensions.\n      const val = max(this.data as any)[0];\n      return new Tensor(this.type, [val], [/* scalar */]);\n    }\n    const [type, result, resultDims] = reduce_helper((a: any, b: any) => Math.max(a, b), this, dim, keepdim, -Infinity);\n    return new Tensor(type, result, resultDims);\n  }\n\n  argmin(dim = null, keepdim = false) {\n    if (dim !== null) {\n      throw new Error('`dim !== null` not yet implemented.');\n    }\n    const index = min(this.data as any)[1];\n    return new Tensor('int64', [BigInt(index)], []);\n  }\n  argmax(dim = null, keepdim = false) {\n    if (dim !== null) {\n      throw new Error('`dim !== null` not yet implemented.');\n    }\n    const index = max(this.data as any)[1];\n    return new Tensor('int64', [BigInt(index)], []);\n  }\n\n  /**\n   * Performs Tensor dtype conversion.\n   * @param {DataType} type The desired data type.\n   * @returns {Tensor} The converted tensor.\n   */\n  to(type: DataType) {\n    // If the self Tensor already has the correct dtype, then self is returned.\n    if (this.type === type) return this;\n\n    // Otherwise, the returned tensor is a copy of self with the desired dtype.\n    if (!DataTypeMap.hasOwnProperty(type)) {\n      throw new Error(`Unsupported type: ${type}`);\n    }\n\n    // Handle special cases where a mapping function is needed (e.g., where one type is a bigint and the other is a number)\n    let map_fn;\n    const is_source_bigint = ['int64', 'uint64'].includes(this.type);\n    const is_dest_bigint = ['int64', 'uint64'].includes(type);\n    if (is_source_bigint && !is_dest_bigint) {\n      // TypeError: Cannot convert a BigInt value to a number\n      map_fn = Number;\n    } else if (!is_source_bigint && is_dest_bigint) {\n      // TypeError: Cannot convert [x] to a BigInt\n      map_fn = BigInt;\n    }\n\n    // @ts-ignore\n    return new Tensor(type, DataTypeMap[type].from(this.data, map_fn), this.dims);\n  }\n}\n\n/**\n * This creates a nested array of a given type and depth (see examples).\n *\n * @example\n *   NestArray<string, 1>; // string[]\n * @example\n *   NestArray<number, 2>; // number[][]\n * @example\n *   NestArray<string, 3>; // string[][][] etc.\n * @template T\n * @template {number} Depth\n * @template {never[]} [Acc=[]]\n * @typedef {Acc['length'] extends Depth ? T : NestArray<T[], Depth, [...Acc, never]>} NestArray\n */\n\n/**\n * Reshapes a 1-dimensional array into an n-dimensional array, according to the provided dimensions.\n *\n * @example\n *   reshape([10                    ], [1      ]); // Type: number[]      Value: [10]\n *   reshape([1, 2, 3, 4            ], [2, 2   ]); // Type: number[][]    Value: [[1, 2], [3, 4]]\n *   reshape([1, 2, 3, 4, 5, 6, 7, 8], [2, 2, 2]); // Type: number[][][]  Value: [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]\n *   reshape([1, 2, 3, 4, 5, 6, 7, 8], [4, 2   ]); // Type: number[][]    Value: [[1, 2], [3, 4], [5, 6], [7, 8]]\n * @param {T[]|DataArray} data The input array to reshape.\n * @param {DIM} dimensions The target shape/dimensions.\n * @template T\n * @template {[number]|number[]} DIM\n * @returns {NestArray<T, DIM[\"length\"]>} The reshaped array.\n */\nfunction reshape(data: DataArray, dimensions: number[]) {\n  const totalElements = data.length;\n  const dimensionSize = dimensions.reduce((a, b) => a * b);\n\n  if (totalElements !== dimensionSize) {\n    throw Error(`cannot reshape array of size ${totalElements} into shape (${dimensions})`);\n  }\n\n  /** @type {any} */\n  let reshapedArray = data;\n\n  for (let i = dimensions.length - 1; i >= 0; i--) {\n    reshapedArray = (reshapedArray as any[]).reduce(\n      (acc: any[], val: any) => {\n        let lastArray = acc[acc.length - 1];\n\n        if (lastArray.length < dimensions[i]) {\n          lastArray.push(val);\n        } else {\n          acc.push([val]);\n        }\n\n        return acc;\n      },\n      [[]],\n    );\n  }\n\n  return reshapedArray[0];\n}\n\n/**\n * Permutes a tensor according to the provided axes.\n * @param {any} tensor The input tensor to permute.\n * @param {Array} axes The axes to permute the tensor along.\n * @returns {Tensor} The permuted tensor.\n */\nexport function permute(tensor: Tensor, axes: number[]) {\n  const [permutedData, shape] = permute_data(tensor.data as any, tensor.dims, axes);\n  return new Tensor(tensor.type, permutedData, shape);\n}\n\n/**\n * Interpolates an Tensor to the given size.\n * @param {Tensor} input The input tensor to interpolate. Data must be channel-first (i.e., [c, h, w])\n * @param {number[]} size The output size of the image\n * @param {string} mode The interpolation mode\n * @param {boolean} align_corners Whether to align corners.\n * @returns {Tensor} The interpolated tensor.\n */\nexport function interpolate(\n  input: Tensor,\n  [out_height, out_width]: number[],\n  mode: string = 'bilinear',\n  align_corners: boolean = false,\n) {\n  // Input image dimensions\n  const in_channels = input.dims.at(-3) ?? 1;\n  const in_height = input.dims.at(-2);\n  const in_width = input.dims.at(-1);\n\n  let output = interpolate_data(\n    /** @type {import('./maths.js').TypedArray}*/ input.data as any,\n    [in_channels, in_height, in_width],\n    [out_height, out_width],\n    mode,\n    align_corners,\n  );\n  return new Tensor(input.type, output, [in_channels, out_height, out_width]);\n}\n\n/**\n * Down/up samples the input.\n * Inspired by https://pytorch.org/docs/stable/generated/torch.nn.functional.interpolate.html.\n * @param {Tensor} input the input tensor\n * @param {Object} options the options for the interpolation\n * @param {[number, number]|[number, number, number]|[number, number, number, number]} [options.size=null] output spatial size.\n * @param {\"nearest\"|\"bilinear\"|\"bicubic\"} [options.mode='bilinear'] algorithm used for upsampling\n * @returns {Promise<Tensor>} The interpolated tensor.\n */\nexport async function interpolate_4d(input: Tensor, { size = null as number[] | null, mode = 'bilinear' } = {}) {\n  // Error checking\n  if (input.dims.length !== 4) {\n    throw new Error('`interpolate_4d` currently only supports 4D input.');\n  }\n  if (!size) {\n    // TODO: support scale_factor\n    throw new Error('`interpolate_4d` requires a `size` argument.');\n  }\n\n  // Fill in missing dimensions\n  let targetDims;\n  if (size.length === 2) {\n    targetDims = [...input.dims.slice(0, 2), ...size];\n  } else if (size.length === 3) {\n    targetDims = [input.dims[0], ...size];\n  } else if (size.length === 4) {\n    targetDims = size;\n  } else {\n    throw new Error('`size` must be of length 2, 3, or 4.');\n  }\n\n  let op;\n  if (mode === 'nearest') {\n    op = await TensorOpRegistry.nearest_interpolate_4d;\n  } else if (mode === 'bilinear') {\n    op = await TensorOpRegistry.bilinear_interpolate_4d;\n  } else if (mode === 'bicubic') {\n    op = await TensorOpRegistry.bicubic_interpolate_4d;\n  } else {\n    throw new Error(`Unsupported mode: ${mode}`);\n  }\n\n  const sizeTensor = new Tensor('int64', new BigInt64Array(targetDims.map(BigInt)), [targetDims.length]);\n  return await op({ x: input, s: sizeTensor });\n}\n\n/**\n * Matrix product of two tensors.\n * Inspired by https://pytorch.org/docs/stable/generated/torch.matmul.html\n * @param {Tensor} a the first tensor to be multiplied\n * @param {Tensor} b the second tensor to be multiplied\n * @returns {Promise<Tensor>} The matrix product of the two tensors.\n */\nexport async function matmul(a: Tensor, b: Tensor) {\n  const op = await TensorOpRegistry.matmul;\n  return await op({ a, b });\n}\n\n/**\n * Computes the one dimensional Fourier transform of real-valued input.\n * Inspired by https://pytorch.org/docs/stable/generated/torch.fft.rfft.html\n * @param {Tensor} x the real input tensor\n * @param {Tensor} a The dimension along which to take the one dimensional real FFT.\n * @returns {Promise<Tensor>} the output tensor.\n */\nexport async function rfft(x: Tensor, a: Tensor) {\n  const op = await TensorOpRegistry.rfft;\n  return await op({ x, a });\n}\n\n/**\n * Returns the k largest elements of the given input tensor.\n * Inspired by https://pytorch.org/docs/stable/generated/torch.topk.html\n * @param {Tensor} x the input tensor\n * @param {number} [k] the k in \"top-k\"\n * @returns {Promise<[Tensor, Tensor]>} the output tuple of (Tensor, LongTensor) of top-k elements and their indices.\n */\nexport async function topk(x: Tensor, k: number) {\n  const op = await TensorOpRegistry.top_k;\n\n  if (k == null) {\n    k = x.dims.at(-1);\n  } else {\n    k = Math.min(k, x.dims.at(-1));\n  }\n  return await op({\n    x,\n    k: new Tensor('int64', [BigInt(k)], [1]),\n  });\n}\n\nconst arrayToIndexTensor = (array: number[]) => new Tensor('int64', array, [array.length]);\n/**\n * Slice a multidimensional float32 tensor.\n * @param {Tensor} data: Tensor of data to extract slices from\n * @param {number[]} starts: 1-D array of starting indices of corresponding axis in axes\n * @param {number[]} ends: 1-D array of ending indices (exclusive) of corresponding axis in axes\n * @param {number[]} axes: 1-D array of axes that starts and ends apply to\n * @param {number[]} [steps]: 1-D array of slice step of corresponding axis in axes.\n * @returns {Promise<Tensor>} Sliced data tensor.\n */\nexport async function slice(\n  data: Tensor,\n  starts: number[],\n  ends: number[],\n  axes: number[],\n  steps: number[] | null = null,\n) {\n  const op = await TensorOpRegistry.slice;\n  return await op({\n    x: data,\n    s: arrayToIndexTensor(starts),\n    e: arrayToIndexTensor(ends),\n    a: arrayToIndexTensor(axes),\n    t: arrayToIndexTensor(steps ?? new Array(axes.length).fill(1)),\n  });\n}\n\n/**\n * Perform mean pooling of the last hidden state followed by a normalization step.\n * @param {Tensor} last_hidden_state Tensor of shape [batchSize, seqLength, embedDim]\n * @param {Tensor} attention_mask Tensor of shape [batchSize, seqLength]\n * @returns {Tensor} Returns a new Tensor of shape [batchSize, embedDim].\n */\nexport function mean_pooling(last_hidden_state: Tensor, attention_mask: Tensor) {\n  // last_hidden_state: [batchSize, seqLength, embedDim]\n  // attention_mask:    [batchSize, seqLength]\n  const lastHiddenStateData = last_hidden_state.data;\n  const attentionMaskData = attention_mask.data;\n\n  const shape = [last_hidden_state.dims[0], last_hidden_state.dims[2]];\n\n  // @ts-ignore\n  const returnedData = new lastHiddenStateData.constructor(shape[0] * shape[1]);\n  const [batchSize, seqLength, embedDim] = last_hidden_state.dims;\n\n  let outIndex = 0;\n  for (let i = 0; i < batchSize; ++i) {\n    const offset = i * embedDim * seqLength;\n\n    for (let k = 0; k < embedDim; ++k) {\n      let sum = 0;\n      let count = 0;\n\n      const attnMaskOffset = i * seqLength;\n      const offset2 = offset + k;\n      // Pool over all words in sequence\n      for (let j = 0; j < seqLength; ++j) {\n        // index into attention mask\n        const attn = Number(attentionMaskData[attnMaskOffset + j]);\n\n        count += attn;\n        sum += lastHiddenStateData[offset2 + j * embedDim] * attn;\n      }\n\n      const avg = sum / count;\n      returnedData[outIndex++] = avg;\n    }\n  }\n\n  return new Tensor(last_hidden_state.type, returnedData, shape);\n}\n\n/**\n * Apply Layer Normalization for last certain number of dimensions.\n * @param {Tensor} input The input tensor\n * @param {number[]} normalized_shape input shape from an expected input of size\n * @param {Object} options The options for the layer normalization\n * @param {number} [options.eps=1e-5] A value added to the denominator for numerical stability.\n * @returns {Tensor} The normalized tensor.\n */\nexport function layer_norm(input: Tensor, normalized_shape: number[], { eps = 1e-5 } = {}) {\n  if (input.dims.length !== 2) {\n    throw new Error('`layer_norm` currently only supports 2D input.');\n  }\n\n  const [batchSize, featureDim] = input.dims;\n\n  if (normalized_shape.length !== 1 && normalized_shape[0] !== featureDim) {\n    throw new Error('`normalized_shape` must be a 1D array with shape `[input.dims[1]]`.');\n  }\n\n  const [std, mean] = std_mean(input, 1, 0, true);\n  const stdData = /** @type {Float32Array} */ std.data;\n  const meanData = /** @type {Float32Array} */ mean.data;\n\n  const inputData = /** @type {Float32Array} */ input.data;\n\n  // @ts-ignore\n  const returnedData = new inputData.constructor(inputData.length);\n\n  for (let i = 0; i < batchSize; ++i) {\n    const offset = i * featureDim;\n    for (let j = 0; j < featureDim; ++j) {\n      const offset2 = offset + j;\n      returnedData[offset2] = (inputData[offset2] - meanData[i]) / (stdData[i] + eps);\n    }\n  }\n  return new Tensor(input.type, returnedData, input.dims);\n}\n\n/**\n * Helper function to calculate new dimensions when performing a squeeze operation.\n * @param {number[]} dims The dimensions of the tensor.\n * @param {number|number[]|null} dim The dimension(s) to squeeze.\n * @returns {number[]} The new dimensions.\n * @private\n */\nfunction calc_squeeze_dims(dims: number[], dim: number | number[] | null) {\n  dims = dims.slice();\n  if (dim === null) {\n    dims = dims.filter((d) => d !== 1);\n  } else if (typeof dim === 'number') {\n    if (dims[dim] === 1) {\n      dims.splice(dim, 1);\n    }\n  } else if (Array.isArray(dim)) {\n    dims = dims.filter((x, i) => {\n      return x !== 1 || !dim.includes(i);\n    });\n  }\n  return dims;\n}\n\n/**\n * Helper function to calculate new dimensions when performing an unsqueeze operation.\n * @param {number[]} dims The dimensions of the tensor.\n * @param {number} dim The dimension to unsqueeze.\n * @returns {number[]} The new dimensions.\n * @private\n */\nfunction calc_unsqueeze_dims(dims: number[], dim: number) {\n  // Dimension out of range (e.g., \"expected to be in range of [-4, 3], but got 4\")\n  // + 1 since we allow inserting at the end (i.e. dim = -1)\n  dim = safeIndex(dim, dims.length + 1);\n  dims = dims.slice();\n  // Insert 1 into specified dimension\n  dims.splice(dim, 0, 1);\n  return dims;\n}\n\n/**\n * Safely calculate the index for an array of a given size, allowing negative indexing.\n * @param {number} index The index that will be used.\n * @param {number} size The size of the array.\n * @param {number} [dimension=null] The dimension that the index is for (optional).\n * @returns {number} The index, guaranteed to be non-negative and less than `arrayLength`.\n *\n * @throws {Error} If the index is out of range.\n * @private\n */\nfunction safeIndex(index: number, size: number, dimension: number | null = null, boundsCheck: boolean = true) {\n  if (boundsCheck && (index < -size || index >= size)) {\n    throw new Error(\n      `IndexError: index ${index} is out of bounds for dimension${dimension === null ? '' : ' ' + dimension} with size ${size}`,\n    );\n  }\n\n  if (index < 0) {\n    // Negative indexing, ensuring positive index\n    index = ((index % size) + size) % size;\n  }\n  return index;\n}\n\n/**\n * Concatenates an array of tensors along a specified dimension.\n * @param {Tensor[]} tensors The array of tensors to concatenate.\n * @param {number} dim The dimension to concatenate along.\n * @returns {Tensor} The concatenated tensor.\n */\nexport function cat(tensors: Tensor[], dim: number = 0) {\n  dim = safeIndex(dim, tensors[0].dims.length);\n\n  // TODO do validation of shapes\n\n  const resultDims = tensors[0].dims.slice();\n  resultDims[dim] = tensors.reduce((a, b) => a + b.dims[dim], 0);\n\n  // Create a new array to store the accumulated values\n  const resultSize = resultDims.reduce((a: number, b: number) => a * b, 1);\n  // @ts-ignore\n  const result = new tensors[0].data.constructor(resultSize);\n\n  // Create output tensor of same type as first\n  const resultType = tensors[0].type;\n\n  if (dim === 0) {\n    // Handle special case for performance reasons\n\n    let offset = 0;\n    for (const tensor of tensors) {\n      const tensorData = tensor.data;\n      result.set(tensorData, offset);\n      offset += tensorData.length;\n    }\n  } else {\n    let currentDim = 0;\n\n    for (let t = 0; t < tensors.length; ++t) {\n      const { data, dims } = tensors[t];\n\n      // Iterate over the data array\n      for (let i = 0; i < data.length; ++i) {\n        // Calculate the index in the resulting array\n        let resultIndex = 0;\n\n        for (let j = dims.length - 1, num = i, resultMultiplier = 1; j >= 0; --j) {\n          const size = dims[j];\n          let index = num % size;\n          if (j === dim) {\n            index += currentDim;\n          }\n          resultIndex += index * resultMultiplier;\n          resultMultiplier *= resultDims[j];\n          num = Math.floor(num / size);\n        }\n        // Accumulate the value at the current index\n        result[resultIndex] = data[i];\n      }\n\n      currentDim += dims[dim];\n    }\n  }\n  return new Tensor(resultType, result, resultDims);\n}\n\n/**\n * Stack an array of tensors along a specified dimension.\n * @param {Tensor[]} tensors The array of tensors to stack.\n * @param {number} dim The dimension to stack along.\n * @returns {Tensor} The stacked tensor.\n */\nexport function stack(tensors: Tensor[], dim: number = 0) {\n  // TODO do validation of shapes\n  // NOTE: stack expects each tensor to be equal size\n  return cat(\n    tensors.map((t) => t.unsqueeze(dim)),\n    dim,\n  );\n}\n\n/**\n * @param {(previousValue: any, currentValue: any, currentIndex?: number, resultIndex?: number) => any} callbackfn\n * @param {Tensor} input the input tensor.\n * @param {number|null} dim the dimension to reduce.\n * @param {boolean} keepdim whether the output tensor has dim retained or not.\n * @returns {[DataType, any, number[]]} The reduced tensor data.\n */\nfunction reduce_helper(callbackfn: any, input: Tensor, dim: number | number[] | null = null, keepdim = false, initialValue: number | null = null) {\n  const inputData = input.data;\n  const inputDims = input.dims;\n\n  // Negative indexing\n  dim = safeIndex(dim as number, inputDims.length);\n\n  // Calculate the shape of the resulting array after summation\n  const resultDims = inputDims.slice(); // Copy the original dimensions\n  resultDims[dim] = 1; // Remove the specified axis\n\n  // Create a new array to store the accumulated values\n  // @ts-ignore\n  const result = new inputData.constructor(inputData.length / inputDims[dim]);\n  if (initialValue !== null) {\n    result.fill(initialValue);\n  }\n\n  // Iterate over the data array\n  for (let i = 0; i < inputData.length; ++i) {\n\n    // Calculate the index in the resulting array\n    let resultIndex = 0;\n\n    for (let j = inputDims.length - 1, num = i, resultMultiplier = 1; j >= 0; --j) {\n      const size = inputDims[j];\n      if (j !== dim) {\n        const index = num % size;\n        resultIndex += index * resultMultiplier;\n        resultMultiplier *= resultDims[j];\n      }\n      num = Math.floor(num / size);\n    }\n\n    // Accumulate the value at the current index\n    result[resultIndex] = callbackfn(result[resultIndex], inputData[i], i, resultIndex);\n  }\n\n  if (!keepdim) resultDims.splice(dim, 1);\n\n  return [input.type, result, resultDims];\n}\n\n/**\n * Calculates the standard deviation and mean over the dimensions specified by dim. dim can be a single dimension or `null` to reduce over all dimensions.\n * @param {Tensor} input the input tenso\n * @param {number|null} dim the dimension to reduce. If None, all dimensions are reduced.\n * @param {number} correction difference between the sample size and sample degrees of freedom. Defaults to Bessel's correction, correction=1.\n * @param {boolean} keepdim whether the output tensor has dim retained or not.\n * @returns {Tensor[]} A tuple of (std, mean) tensors.\n */\nexport function std_mean(input: Tensor, dim: number | null = null, correction = 1, keepdim = false) {\n  const inputData: any = /** @type {Float32Array} */(input.data);\n  const inputDims = input.dims;\n\n  if (dim === null) {\n      // None to reduce over all dimensions.\n      const sum = inputData.reduce((a: number, b: number) => a + b, 0);\n      const mean = sum / inputData.length;\n      const std = Math.sqrt(inputData.reduce((a: number, b: number) => a + (b - mean) ** 2, 0) / (inputData.length - correction));\n\n      const meanTensor = new Tensor(input.type, [mean], [/* scalar */]);\n      const stdTensor = new Tensor(input.type, [std], [/* scalar */]);\n\n      return [stdTensor, meanTensor];\n  }\n  dim = safeIndex(dim, inputDims.length);\n  const meanTensor = mean(input, dim, keepdim);\n  const meanTensorData = meanTensor.data;\n\n  // Compute squared sum\n  const [type, result, resultDims] = reduce_helper((a: any, b: any, i: any, j: any) => a + (b - meanTensorData[j]) ** 2, input, dim, keepdim);\n\n  // Square root of the squared sum\n  for (let i = 0; i < result.length; ++i) {\n      result[i] = Math.sqrt(result[i] / (inputDims[dim] - correction));\n  }\n\n  const stdTensor = new Tensor(type, result, resultDims);\n\n  return [stdTensor, meanTensor];\n}\n\n\n/**\n * Returns the mean value of each row of the input tensor in the given dimension dim.\n * @param {Tensor} input the input tensor.\n * @param {number|null} dim the dimension to reduce.\n * @param {boolean} keepdim whether the output tensor has dim retained or not.\n * @returns {Tensor} A new tensor with means taken along the specified dimension.\n */\nexport function mean(input: Tensor, dim: number | null = null, keepdim: boolean = false) {\n  const inputData = /** @type {Float32Array} */ input.data;\n  const inputDims = input.dims;\n\n  if (dim === null) {\n    // None to reduce over all dimensions.\n    // @ts-ignore\n    const val = inputData.reduce((a: number, b: number) => a + b, 0);\n    return new Tensor(\n      input.type,\n      [val / inputData.length],\n      [\n        /* scalar */\n      ],\n    );\n  }\n\n  // Negative indexing\n  dim = safeIndex(dim, inputDims.length);\n\n  const [type, result, resultDims] = reduce_helper((a: any, b: any) => a + b, input, dim, keepdim);\n\n  return new Tensor(type, result, resultDims);\n}\n\nfunction dimsToStride(dims: number[]) {\n  const stride = new Array(dims.length);\n  for (let i = dims.length - 1, s2 = 1; i >= 0; --i) {\n    stride[i] = s2;\n    s2 *= dims[i];\n  }\n  return stride;\n}\n\nfunction fullHelper(\n  size: number[],\n  fill_value: number | bigint | boolean,\n  dtype: string,\n  cls: new (length: number) => TypedArray,\n) {\n  const numElements = size.reduce((a, b) => a * b, 1);\n  return new Tensor(\n    dtype as keyof typeof DataTypeMap,\n    new cls(numElements).fill(fill_value as number & bigint & boolean) as TypedArray,\n    size,\n  );\n}\n\n/**\n * Creates a tensor of size size filled with fill_value. The tensor's dtype is inferred from fill_value.\n * @param {number[]} size A sequence of integers defining the shape of the output tensor.\n * @param {number|bigint|boolean} fill_value The value to fill the output tensor with.\n * @returns {Tensor} The filled tensor.\n */\nexport function full(size: number[], fill_value: number | bigint | boolean) {\n  let dtype;\n  let typedArrayCls;\n  if (typeof fill_value === 'number') {\n    dtype = 'float32';\n    typedArrayCls = Float32Array;\n  } else if (typeof fill_value === 'bigint') {\n    dtype = 'int64';\n    typedArrayCls = BigInt64Array;\n  } else if (typeof fill_value === 'boolean') {\n    dtype = 'bool';\n    typedArrayCls = Uint8Array;\n  } else {\n    // TODO: support other dtypes\n    throw new Error(`Unsupported data type: ${typeof fill_value}`);\n  }\n  return fullHelper(size, fill_value, dtype, typedArrayCls);\n}\n\nexport function full_like(tensor: Tensor, fill_value: number | bigint | boolean) {\n  return full(tensor.dims, fill_value);\n}\n\n/**\n * Returns a tensor filled with the scalar value 1, with the shape defined by the variable argument size.\n * @param {number[]} size A sequence of integers defining the shape of the output tensor.\n * @returns {Tensor} The ones tensor.\n */\nexport function ones(size: number[]) {\n  return fullHelper(size, 1n, 'int64', BigInt64Array);\n}\n\n/**\n * Returns a tensor filled with the scalar value 1, with the same size as input.\n * @param {Tensor} tensor The size of input will determine size of the output tensor.\n * @returns {Tensor} The ones tensor.\n */\nexport function ones_like(tensor: Tensor) {\n  return ones(tensor.dims);\n}\n\n/**\n * Returns a tensor filled with the scalar value 0, with the shape defined by the variable argument size.\n * @param {number[]} size A sequence of integers defining the shape of the output tensor.\n * @returns {Tensor} The zeros tensor.\n */\nexport function zeros(size: number[]) {\n  return fullHelper(size, 0n, 'int64', BigInt64Array);\n}\n\n/**\n * Returns a tensor filled with the scalar value 0, with the same size as input.\n * @param {Tensor} tensor The size of input will determine size of the output tensor.\n * @returns {Tensor} The zeros tensor.\n */\nexport function zeros_like(tensor: Tensor) {\n  return zeros(tensor.dims);\n}\n\n/**\n * Returns a tensor filled with random numbers from a uniform distribution on the interval [0, 1)\n * @param {number[]} size A sequence of integers defining the shape of the output tensor.\n * @returns {Tensor} The random tensor.\n */\nexport function rand(size: number[]) {\n  const length = size.reduce((a, b) => a * b, 1);\n  return new Tensor(\n    'float32',\n    Float32Array.from({ length }, () => Math.random()),\n    size,\n  );\n}\n\n/**\n * Quantizes the embeddings tensor to binary or unsigned binary precision.\n * @param {Tensor} tensor The tensor to quantize.\n * @param {'binary'|'ubinary'} precision The precision to use for quantization.\n * @returns {Tensor} The quantized tensor.\n */\nexport function quantize_embeddings(tensor: Tensor, precision: 'binary' | 'ubinary') {\n  if (tensor.dims.length !== 2) {\n    throw new Error('The tensor must have 2 dimensions');\n  }\n  if (tensor.dims.at(-1) % 8 !== 0) {\n    throw new Error('The last dimension of the tensor must be a multiple of 8');\n  }\n  if (!['binary', 'ubinary'].includes(precision)) {\n    throw new Error(\"The precision must be either 'binary' or 'ubinary'\");\n  }\n\n  const signed = precision === 'binary';\n  const dtype = signed ? 'int8' : 'uint8';\n\n  // Create a typed array to store the packed bits\n  const cls = signed ? Int8Array : Uint8Array;\n  const inputData = tensor.data;\n  const outputData = new cls(inputData.length / 8);\n\n  // Iterate over each number in the array\n  for (let i = 0; i < inputData.length; ++i) {\n    // Determine if the number is greater than 0\n    const bit = inputData[i] > 0 ? 1 : 0;\n\n    // Calculate the index in the typed array and the position within the byte\n    const arrayIndex = Math.floor(i / 8);\n    const bitPosition = i % 8;\n\n    // Pack the bit into the typed array\n    outputData[arrayIndex] |= bit << (7 - bitPosition);\n    if (signed && bitPosition === 0) {\n      outputData[arrayIndex] -= 128;\n    }\n  }\n\n  return new Tensor(dtype, outputData, [tensor.dims[0], tensor.dims[1] / 8]);\n}\n","/**\n * @file Custom data structures.\n *\n * These are only used internally, meaning an end-user shouldn't\n * need to access anything here.\n *\n * @module utils/data-structures\n */\n\n/**\n * Efficient Heap-based Implementation of a Priority Queue.\n * It uses an array-based binary heap, where the root is at index `0`, and the\n * children of node `i` are located at indices `2i + 1` and `2i + 2`, respectively.\n *\n * Adapted from the following sources:\n * - https://stackoverflow.com/a/42919752/13989043 (original)\n * - https://github.com/belladoreai/llama-tokenizer-js (minor improvements)\n */\nexport class PriorityQueue {\n  /**\n   * Create a new PriorityQueue.\n   * @param {function(any, any): boolean} comparator Comparator function to determine priority. Defaults to a MaxHeap.\n   */\n  _comparator: (a: any, b: any) => boolean;\n  _maxSize: number;\n  _heap: any[];\n\n  constructor(comparator = (a: any, b: any) => a > b, maxSize = Infinity) {\n    this._heap = [];\n    this._comparator = comparator;\n    this._maxSize = maxSize;\n  }\n\n  /**\n   * The size of the queue\n   */\n  get size() {\n    return this._heap.length;\n  }\n\n  /**\n   * Check if the queue is empty.\n   * @returns {boolean} `true` if the queue is empty, `false` otherwise.\n   */\n  isEmpty() {\n    return this.size === 0;\n  }\n\n  /**\n   * Return the element with the highest priority in the queue.\n   * @returns {any} The highest priority element in the queue.\n   */\n  peek() {\n    return this._heap[0];\n  }\n\n  /**\n   * Add one or more elements to the queue.\n   * @param  {...any} values The values to push into the queue.\n   * @returns {number} The new size of the queue.\n   */\n  push(...values: any[]) {\n    return this.extend(values);\n  }\n\n  /**\n   * Add multiple elements to the queue.\n   * @param {any[]} values The values to push into the queue.\n   * @returns {number} The new size of the queue.\n   */\n  extend(values: any[]) {\n    for (const value of values) {\n      if (this.size < this._maxSize) {\n        this._heap.push(value);\n        this._siftUp();\n      } else {\n        // Get index of value with the lowest priority\n        const smallest = this._smallest();\n\n        // If the new value has higher priority than the smallest value in the heap\n        // then replace the smallest value with the new value and update the heap\n        if (this._comparator(value, this._heap[smallest])) {\n          this._heap[smallest] = value;\n          this._siftUpFrom(smallest);\n        }\n      }\n    }\n    return this.size;\n  }\n\n  /**\n   * Remove and return the element with the highest priority in the queue.\n   * @returns {any} The element with the highest priority in the queue.\n   */\n  pop() {\n    const poppedValue = this.peek();\n    const bottom = this.size - 1;\n    if (bottom > 0) {\n      this._swap(0, bottom);\n    }\n    this._heap.pop();\n    this._siftDown();\n    return poppedValue;\n  }\n\n  /**\n   * Replace the element with the highest priority in the queue with a new value.\n   * @param {*} value The new value.\n   * @returns {*} The replaced value.\n   */\n  replace(value: any) {\n    const replacedValue = this.peek();\n    this._heap[0] = value;\n    this._siftDown();\n    return replacedValue;\n  }\n\n  /**\n   * Compute the index for the parent of the node at index `i`.\n   * @param {number} i The index of the node to get the parent of.\n   * @returns {number} The index of the parent node.\n   * @private\n   */\n  _parent(i: number) {\n    return ((i + 1) >>> 1) - 1;\n  }\n\n  /**\n   * Compute the index for the left child of the node at index `i`.\n   * @param {number} i The index of the node to get the left child of.\n   * @returns {number} The index of the left child.\n   * @private\n   */\n  _left(i: number) {\n    return (i << 1) + 1;\n  }\n\n  /**\n   * Compute the index for the right child of the node at index `i`.\n   * @param {number} i The index of the node to get the right child of.\n   * @returns {number} The index of the right child.\n   * @private\n   */\n  _right(i: number) {\n    return (i + 1) << 1;\n  }\n\n  /**\n   * Check if the element at index `i` is greater than the element at index `j`.\n   * @param {number} i The index of the first element to compare.\n   * @param {number} j The index of the second element to compare.\n   * @returns {boolean} `true` if the element at index `i` is greater than the element at index `j`, `false` otherwise.\n   * @private\n   */\n  _greater(i: number, j: number) {\n    return this._comparator(this._heap[i], this._heap[j]);\n  }\n\n  /**\n   * Swap the elements at indices `i` and `j`.\n   * @param {number} i The index of the first element to swap.\n   * @param {number} j The index of the second element to swap.\n   * @private\n   */\n  _swap(i: number, j: number) {\n    const temp = this._heap[i];\n    this._heap[i] = this._heap[j];\n    this._heap[j] = temp;\n  }\n\n  /**\n   * Maintain the heap property by updating positions in the heap,\n   * starting at the last element and moving up the heap.\n   * @private\n   */\n  _siftUp() {\n    this._siftUpFrom(this.size - 1);\n  }\n\n  /**\n   * Helper function to sift up from a given node.\n   * @param {number} node The index of the node to start sifting up from.\n   */\n  _siftUpFrom(node: number) {\n    while (node > 0 && this._greater(node, this._parent(node))) {\n      this._swap(node, this._parent(node));\n      node = this._parent(node);\n    }\n  }\n\n  /**\n   * Maintain the heap property by updating positions in the heap,\n   * starting at the first element and moving down the heap.\n   * @private\n   */\n  _siftDown() {\n    let node = 0;\n    while (\n      (this._left(node) < this.size && this._greater(this._left(node), node)) ||\n      (this._right(node) < this.size && this._greater(this._right(node), node))\n    ) {\n      const maxChild =\n        this._right(node) < this.size && this._greater(this._right(node), this._left(node))\n          ? this._right(node)\n          : this._left(node);\n      this._swap(node, maxChild);\n      node = maxChild;\n    }\n  }\n\n  /**\n   * Get the index of the smallest element in the heap. Since we use an array-based heap,\n   * the index can be computed without needing to traverse the heap.\n   * @private\n   */\n  _smallest() {\n    return 2 ** Math.floor(Math.log2(this.size)) - 1;\n  }\n}\n\n/**\n * A trie structure to efficiently store and search for strings.\n */\nexport class CharTrie {\n  _root: CharTrieNode;\n\n  constructor() {\n    this._root = CharTrieNode.default();\n  }\n\n  /**\n   * Adds one or more `texts` to the trie.\n   * @param {string[]} texts The strings to add to the trie.\n   */\n  extend(texts: string[]) {\n    for (const text of texts) {\n      this.push(text);\n    }\n  }\n\n  /**\n   * Adds text to the trie.\n   * @param {string} text The string to add to the trie.\n   */\n  push(text: string) {\n    let node = this._root;\n    for (const ch of text) {\n      let child = node.children.get(ch);\n      if (child === undefined) {\n        child = CharTrieNode.default();\n        node.children.set(ch, child);\n      }\n      node = child;\n    }\n    node.isLeaf = true;\n  }\n\n  /**\n   * Searches the trie for all strings with a common prefix of `text`.\n   * @param {string} text The common prefix to search for.\n   * @yields {string} Each string in the trie that has `text` as a prefix.\n   */\n  *commonPrefixSearch(text: string) {\n    let node = this._root;\n    if (node === undefined) return;\n\n    let prefix = '';\n    for (const ch of text) {\n      prefix += ch;\n      const nextNode = node.children.get(ch);\n      if (nextNode === undefined) return;\n      node = nextNode;\n      if (node.isLeaf) {\n        yield prefix;\n      }\n    }\n  }\n}\n\n/**\n * Represents a node in a character trie.\n */\nclass CharTrieNode {\n  /**\n   * Create a new CharTrieNode.\n   * @param {boolean} isLeaf Whether the node is a leaf node or not.\n   * @param {Map<string, CharTrieNode>} children A map containing the node's children, where the key is a character and the value is a `CharTrieNode`.\n   */\n  isLeaf: boolean;\n  children: Map<string, CharTrieNode>;\n\n  constructor(isLeaf: boolean, children: Map<string, CharTrieNode>) {\n    this.isLeaf = isLeaf;\n    this.children = children;\n  }\n\n  /**\n   * Returns a new `CharTrieNode` instance with default values.\n   * @returns {CharTrieNode} A new `CharTrieNode` instance with `isLeaf` set to `false` and an empty `children` map.\n   */\n  static default() {\n    return new CharTrieNode(false, new Map());\n  }\n}\n\n/**\n * A lattice data structure to be used for tokenization.\n */\nexport class TokenLattice {\n  /**\n   * Creates a new TokenLattice instance.\n   *\n   * @param {string} sentence The input sentence to be tokenized.\n   * @param {number} bosTokenId The beginning-of-sequence token ID.\n   * @param {number} eosTokenId The end-of-sequence token ID.\n   */\n  _sentence: string;\n  _bosTokenId: number;\n  _eosTokenId: number;\n  _chars: string[];\n  _len: number;\n  _nodes: TokenLatticeNode[];\n  beginNodes: TokenLatticeNode[][];\n  endNodes: TokenLatticeNode[][];\n\n  constructor(sentence: string, bosTokenId: number, eosTokenId: number) {\n    this._sentence = sentence;\n    this._chars = Array.from(sentence);\n    this._len = this._chars.length;\n    this._bosTokenId = bosTokenId;\n    this._eosTokenId = eosTokenId;\n    this._nodes = [];\n    this.beginNodes = Array.from({ length: this._len + 1 }, () => []);\n    this.endNodes = Array.from({ length: this._len + 1 }, () => []);\n\n    const bos = new TokenLatticeNode(this._bosTokenId, 0, 0, 0, 0.0);\n    const eos = new TokenLatticeNode(this._eosTokenId, 1, this._len, 0, 0.0);\n    this._nodes.push(bos.clone());\n    this._nodes.push(eos.clone());\n    this.beginNodes[this._len].push(eos);\n    this.endNodes[0].push(bos);\n  }\n\n  /**\n   * Inserts a new token node into the token lattice.\n   *\n   * @param {number} pos The starting position of the token.\n   * @param {number} length The length of the token.\n   * @param {number} score The score of the token.\n   * @param {number} tokenId The token ID of the token.\n   */\n  insert(pos: number, length: number, score: number, tokenId: number) {\n    const nodeId = this._nodes.length;\n    const node = new TokenLatticeNode(tokenId, nodeId, pos, length, score);\n    this.beginNodes[pos].push(node);\n    this.endNodes[pos + length].push(node);\n    this._nodes.push(node);\n  }\n\n  /**\n   * Implements the Viterbi algorithm to compute the most likely sequence of tokens.\n   *\n   * @returns {TokenLatticeNode[]} The most likely sequence of tokens.\n   */\n  viterbi() {\n    const len = this._len;\n    let pos = 0;\n    while (pos <= len) {\n      if (this.beginNodes[pos].length == 0) {\n        return [];\n      }\n      for (let rnode of this.beginNodes[pos]) {\n        rnode.prev = null;\n        let bestScore = 0.0;\n        let bestNode = null;\n        for (let lnode of this.endNodes[pos]) {\n          const score = lnode.backtraceScore + rnode.score;\n          if (bestNode === null || score > bestScore) {\n            bestNode = lnode.clone();\n            bestScore = score;\n          }\n        }\n\n        if (bestNode !== null) {\n          rnode.prev = bestNode;\n          rnode.backtraceScore = bestScore;\n        } else {\n          return [];\n        }\n      }\n      ++pos;\n    }\n\n    const results = [];\n    const root = this.beginNodes[len][0];\n    const prev = root.prev;\n    if (prev === null) {\n      return [];\n    }\n\n    let node = prev.clone();\n    while (node.prev !== null) {\n      results.push(node.clone());\n      const n = node.clone();\n      if (!n.prev) break;\n      node = n.prev.clone();\n    }\n\n    results.reverse();\n    return results;\n  }\n\n  /**\n   * @param {TokenLatticeNode} node\n   * @returns {string} The array of nodes representing the most likely sequence of tokens.\n   */\n  piece(node: TokenLatticeNode) {\n    return this._chars.slice(node.pos, node.pos + node.length).join('');\n  }\n\n  /**\n   * @returns {string[]} The most likely sequence of tokens.\n   */\n  tokens() {\n    const nodes = this.viterbi();\n    return nodes.map((x) => this.piece(x));\n  }\n\n  /**\n   * @returns {number[]} The most likely sequence of token ids.\n   */\n  tokenIds() {\n    const nodes = this.viterbi();\n    return nodes.map((x) => x.tokenId);\n  }\n}\nclass TokenLatticeNode {\n  /**\n   * Represents a node in a token lattice for a given sentence.\n   * @param {number} tokenId The ID of the token associated with this node.\n   * @param {number} nodeId The ID of this node.\n   * @param {number} pos The starting position of the token in the sentence.\n   * @param {number} length The length of the token.\n   * @param {number} score The score associated with the token.\n   */\n  tokenId: number;\n  nodeId: number;\n  pos: number;\n  length: number;\n  score: number;\n  prev: TokenLatticeNode | null;\n  backtraceScore: number;\n\n  constructor(tokenId: number, nodeId: number, pos: number, length: number, score: number) {\n    this.tokenId = tokenId;\n    this.nodeId = nodeId;\n    this.pos = pos;\n    this.length = length;\n    this.score = score;\n    this.prev = null;\n    this.backtraceScore = 0.0;\n  }\n\n  /**\n   * Returns a clone of this node.\n   * @returns {TokenLatticeNode} A clone of this node.\n   */\n  clone() {\n    const n = new TokenLatticeNode(this.tokenId, this.nodeId, this.pos, this.length, this.score);\n    n.prev = this.prev;\n    n.backtraceScore = this.backtraceScore;\n    return n;\n  }\n}\n","import { Callable } from './utils/generic';\n\nimport { reverseDictionary, escapeRegExp, isIntegralNumber, mergeArrays, len, ProgressCallback } from './utils/core';\n\nimport { getModelJSON } from './utils/hub';\n\nimport { max, min, round } from './utils/maths';\nimport { Tensor } from './utils/tensor';\n\nimport { PriorityQueue, TokenLattice, CharTrie } from './utils/data-structures';\n\nimport { Template } from '@huggingface/jinja';\nimport { PretrainedOptions } from './utils/hub';\nimport { WHISPER_LANGUAGE_MAPPING } from './models/whisper/common_whisper';\nimport { PretrainedConfig } from './configs';\n\ntype TokenizerProperties = {\n    legacy?: boolean;\n};\ntype PretrainedTokenizerOptions = PretrainedOptions & TokenizerProperties;\n/**\n * @typedef {Object} TokenizerProperties Additional tokenizer-specific properties.\n * @property {boolean} [legacy=false] Whether or not the `legacy` behavior of the tokenizer should be used.\n * @typedef {import('./utils/hub.js').PretrainedOptions & TokenizerProperties} PretrainedTokenizerOptions\n */\n\n/**\n * Loads a tokenizer from the specified path.\n * @param {string} pretrained_model_name_or_path The path to the tokenizer directory.\n * @param {PretrainedTokenizerOptions} options Additional options for loading the tokenizer.\n * @returns {Promise<any[]>} A promise that resolves with information about the loaded tokenizer.\n */\nasync function loadTokenizer(pretrained_model_name_or_path: string, options: PretrainedTokenizerOptions) {\n    const info = await Promise.all([\n        getModelJSON(pretrained_model_name_or_path, 'tokenizer.json', true, options),\n        getModelJSON(pretrained_model_name_or_path, 'tokenizer_config.json', true, options),\n    ]);\n\n    // Override legacy option if `options.legacy` is not null\n    if (options.legacy !== null) {\n        info[1].legacy = options.legacy;\n    }\n    return info;\n}\n\n/**\n * Helper function to split a string on a regex, but keep the delimiters.\n * This is required, because the JavaScript `.split()` method does not keep the delimiters,\n * and wrapping in a capturing group causes issues with existing capturing groups (due to nesting).\n * @param {string} text The text to split.\n * @param {RegExp} regex The regex to split on.\n * @returns {string[]} The split string.\n */\nfunction regexSplit(text: string, regex: RegExp) {\n    const result = [];\n    let prev = 0;\n    for (const match of text.matchAll(regex)) {\n        const fullMatch = match[0];\n        if (prev < match.index) {\n            result.push(text.slice(prev, match.index));\n        }\n        if (fullMatch.length > 0) {\n            result.push(fullMatch);\n        }\n        prev = match.index + fullMatch.length;\n    }\n    if (prev < text.length) {\n        result.push(text.slice(prev));\n    }\n    return result;\n}\n\n/**\n * Helper method to construct a pattern from a config object.\n * @param {Object} pattern The pattern object.\n * @param {boolean} invert Whether to invert the pattern.\n * @returns {RegExp|null} The compiled pattern.\n */\nfunction createPattern(pattern: { Regex: string; String: string }, invert = true) {\n    if (pattern.Regex !== undefined) {\n        // In certain cases, the pattern may contain unnecessary escape sequences (e.g., \\# or \\& or \\~).\n        // i.e., valid in Python (where the patterns are exported from) but invalid in JavaScript (where the patterns are parsed).\n        // This isn't an issue when creating the regex w/o the 'u' flag, but it is when the 'u' flag is used.\n        // For this reason, it is necessary to remove these backslashes before creating the regex.\n        // See https://stackoverflow.com/a/63007777/13989043 for more information\n        let regex = pattern.Regex.replace(/\\\\([#&~])/g, '$1'); // TODO: add more characters to this list if necessary\n\n        // We also handle special cases where the regex contains invalid (non-JS compatible) syntax.\n        for (const [key, value] of PROBLEMATIC_REGEX_MAP) {\n            regex = regex.replaceAll(key, value);\n        }\n\n        return new RegExp(regex, 'gu');\n    } else if (pattern.String !== undefined) {\n        const escaped = escapeRegExp(pattern.String);\n        // NOTE: if invert is true, we wrap the pattern in a group so that it is kept when performing .split()\n        return new RegExp(invert ? escaped : `(${escaped})`, 'gu');\n    } else {\n        console.warn('Unknown pattern type:', pattern);\n        return null;\n    }\n}\n\n/**\n * Helper function to convert an Object to a Map\n * @param {Object} obj The object to convert.\n * @returns {Map<string, any>} The map.\n */\nfunction objectToMap(obj: object) {\n    return new Map(Object.entries(obj));\n}\n\n/**\n * Helper function to convert a tensor to a list before decoding.\n * @param {Tensor} tensor The tensor to convert.\n * @returns {number[]} The tensor as a list.\n */\nfunction prepareTensorForDecode(tensor: Tensor) {\n    const dims = tensor.dims;\n    switch (dims.length) {\n        case 1:\n            return tensor.tolist();\n        case 2:\n            if (dims[0] !== 1) {\n                throw new Error(\n                    'Unable to decode tensor with `batch size !== 1`. Use `tokenizer.batch_decode(...)` for batched inputs.',\n                );\n            }\n            return tensor.tolist()[0];\n        default:\n            throw new Error(`Expected tensor to have 1-2 dimensions, got ${dims.length}.`);\n    }\n}\n\n/**\n * Clean up a list of simple English tokenization artifacts like spaces before punctuations and abbreviated forms\n * @param {string} text The text to clean up.\n * @returns {string} The cleaned up text.\n */\nfunction clean_up_tokenization(text: string) {\n    // Clean up a list of simple English tokenization artifacts\n    // like spaces before punctuations and abbreviated forms\n    return text\n        .replace(/ \\./g, '.')\n        .replace(/ \\?/g, '?')\n        .replace(/ \\!/g, '!')\n        .replace(/ ,/g, ',')\n        .replace(/ \\' /g, \"'\")\n        .replace(/ n\\'t/g, \"n't\")\n        .replace(/ \\'m/g, \"'m\")\n        .replace(/ \\'s/g, \"'s\")\n        .replace(/ \\'ve/g, \"'ve\")\n        .replace(/ \\'re/g, \"'re\");\n}\n\n/**\n * Helper function to remove accents from a string.\n * @param {string} text The text to remove accents from.\n * @returns {string} The text with accents removed.\n */\nfunction remove_accents(text: string) {\n    return text.replace(/\\p{M}/gu, '');\n}\n\n/**\n * Helper function to lowercase a string and remove accents.\n * @param {string} text The text to lowercase and remove accents from.\n * @returns {string} The lowercased text with accents removed.\n */\nfunction lowercase_and_remove_accent(text: string) {\n    return remove_accents(text.toLowerCase());\n}\n\n/**\n * Checks whether the given Unicode codepoint represents a CJK (Chinese, Japanese, or Korean) character.\n *\n * A \"chinese character\" is defined as anything in the CJK Unicode block:\n * https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block)\n *\n * Note that the CJK Unicode block is NOT all Japanese and Korean characters, despite its name.\n * The modern Korean Hangul alphabet is a different block, as is Japanese Hiragana and Katakana.\n * Those alphabets are used to write space-separated words, so they are not treated specially\n * and are handled like all other languages.\n *\n * @param {number|bigint} cp The Unicode codepoint to check.\n * @returns {boolean} True if the codepoint represents a CJK character, false otherwise.\n */\nexport function is_chinese_char(cp: number | bigint) {\n    return (\n        (cp >= 0x4e00 && cp <= 0x9fff) ||\n        (cp >= 0x3400 && cp <= 0x4dbf) ||\n        (cp >= 0x20000 && cp <= 0x2a6df) ||\n        (cp >= 0x2a700 && cp <= 0x2b73f) ||\n        (cp >= 0x2b740 && cp <= 0x2b81f) ||\n        (cp >= 0x2b820 && cp <= 0x2ceaf) ||\n        (cp >= 0xf900 && cp <= 0xfaff) ||\n        (cp >= 0x2f800 && cp <= 0x2fa1f)\n    );\n}\n\n/**\n * Helper function to fuse consecutive unknown tokens.\n * @param {string[]} arr The list of input tokens\n * @param {Map<string, any>} tokens_to_ids The mapping from tokens to token ids.\n * @param {number} unk_token_id The value to fuse on.\n * @private\n */\nfunction fuse_unk(arr: string[], tokens_to_ids: Map<string, any>, unk_token_id: number) {\n    const fused = [];\n    let i = 0;\n    while (i < arr.length) {\n        fused.push(arr[i]);\n        if ((tokens_to_ids.get(arr[i]) ?? unk_token_id) !== unk_token_id) {\n            ++i;\n            continue;\n        }\n\n        while (++i < arr.length && (tokens_to_ids.get(arr[i]) ?? unk_token_id) === unk_token_id) {\n            if (tokens_to_ids.get(fused.at(-1)!) !== unk_token_id) {\n                fused[fused.length - 1] += arr[i];\n            }\n        }\n    }\n\n    return fused;\n}\n\n/**\n * Split a string on whitespace.\n * @param {string} text The text to split.\n * @returns {string[]} The split string.\n */\nfunction whitespace_split(text: string) {\n    return text.match(/\\S+/g) || [];\n}\n\nconst PUNCTUATION_REGEX = '\\\\p{P}\\\\u0021-\\\\u002F\\\\u003A-\\\\u0040\\\\u005B-\\\\u0060\\\\u007B-\\\\u007E';\nconst PUNCTUATION_ONLY_REGEX = new RegExp(`^[${PUNCTUATION_REGEX}]+$`, 'gu');\nconst BLOOM_SPLIT_CHARS = '.,!?\\u2026\\u3002\\uff0c\\u3001\\u0964\\u06d4\\u060c';\n\n// A mapping of regex patterns to their equivalent (but possibly longer) JS-compatible versions.\nconst PROBLEMATIC_REGEX_MAP = new Map([\n    // This uses the case insensitive group modifier, which is not supported in JavaScript.\n    // When parsing the regex, an \"Invalid group\" error is thrown.\n    [\"(?i:'s|'t|'re|'ve|'m|'ll|'d)\", \"(?:'([sS]|[tT]|[rR][eE]|[vV][eE]|[mM]|[lL][lL]|[dD]))\"],\n\n    // Used to override the default (invalid) regex of the bloom pretokenizer.\n    // For more information, see https://github.com/huggingface/transformers.js/issues/94\n    [` ?[^(\\\\s|[${BLOOM_SPLIT_CHARS}])]+`, ` ?[^\\\\s${BLOOM_SPLIT_CHARS}]+`],\n]);\n\n/**\n * Represent a token added by the user on top of the existing Model vocabulary.\n * AddedToken can be configured to specify the behavior they should have in various situations like:\n *   - Whether they should only match single words\n *   - Whether to include any whitespace on its left or right\n */\nclass AddedToken {\n    /**\n     * Creates a new instance of AddedToken.\n     * @param {Object} config Added token configuration object.\n     * @param {string} config.content The content of the added token.\n     * @param {number} config.id The id of the added token.\n     * @param {boolean} [config.single_word=false] Whether this token must be a single word or can break words.\n     * @param {boolean} [config.lstrip=false] Whether this token should strip whitespaces on its left.\n     * @param {boolean} [config.rstrip=false] Whether this token should strip whitespaces on its right.\n     * @param {boolean} [config.normalized=false] Whether this token should be normalized.\n     * @param {boolean} [config.special=false] Whether this token is special.\n     */\n    content: string;\n    id: number;\n    single_word?: boolean;\n    lstrip?: boolean;\n    rstrip?: boolean;\n    special?: boolean;\n    normalized?: boolean;\n    constructor(config: {\n        content: string;\n        id: number;\n        single_word?: boolean;\n        lstrip?: boolean;\n        rstrip?: boolean;\n        special?: boolean;\n        normalized?: boolean;\n    }) {\n        this.content = config.content;\n        this.id = config.id;\n        this.single_word = config.single_word ?? false;\n        this.lstrip = config.lstrip ?? false;\n        this.rstrip = config.rstrip ?? false;\n        this.special = config.special ?? false;\n        this.normalized = config.normalized ?? false;\n    }\n}\n\n/**\n * Abstract base class for tokenizer models.\n *\n * @extends Callable\n */\nexport class TokenizerModel extends Callable {\n    /**\n     * Creates a new instance of TokenizerModel.\n     * @param {Object} config The configuration object for the TokenizerModel.\n     */\n    vocab: string[];\n    tokens_to_ids: Map<string, number>;\n    unk_token_id: number | undefined;\n    unk_token: string | undefined;\n    end_of_word_suffix: string | undefined;\n    fuse_unk: boolean;\n    config: {\n        vocab: string[];\n        tokens_to_ids: Map<string, number>;\n        unk_token_id: number | undefined;\n        unk_token: string | undefined;\n        end_of_word_suffix: string | undefined;\n        fuse_unk: boolean;\n    };\n\n    constructor(config: {\n        vocab: string[];\n        tokens_to_ids: Map<string, number>;\n        unk_token_id: number | undefined;\n        unk_token: string | undefined;\n        end_of_word_suffix: string | undefined;\n        fuse_unk: boolean;\n    }) {\n        super();\n        this.config = config;\n\n        /** @type {string[]} */\n        this.vocab = [];\n\n        /**\n         * A mapping of tokens to ids.\n         * @type {Map<string, number>}\n         */\n        this.tokens_to_ids = new Map();\n\n        this.unk_token_id = undefined;\n        this.unk_token = undefined;\n        this.end_of_word_suffix = undefined;\n\n        /** @type {boolean} Whether to fuse unknown tokens when encoding. Defaults to false. */\n        this.fuse_unk = this.config.fuse_unk ?? false;\n    }\n\n    /**\n     * Instantiates a new TokenizerModel instance based on the configuration object provided.\n     * @param {Object} config The configuration object for the TokenizerModel.\n     * @param {...*} args Optional arguments to pass to the specific TokenizerModel constructor.\n     * @returns {TokenizerModel} A new instance of a TokenizerModel.\n     * @throws Will throw an error if the TokenizerModel type in the config is not recognized.\n     */\n    static fromConfig(\n        config: {\n            type: string;\n            vocab: string[];\n            tokens_to_ids: Map<string, number>;\n            unk_token_id: number | undefined;\n            unk_token: string | undefined;\n            end_of_word_suffix: string | undefined;\n            fuse_unk: boolean;\n        },\n        ...args: any[]\n    ) {\n        switch (config.type) {\n            case 'WordPiece':\n                return new WordPieceTokenizer(config);\n            case 'Unigram':\n                // @ts-ignore\n                return new Unigram(config, ...args);\n            case 'BPE':\n                return new BPE(config as any);\n\n            default:\n                // Some tokenizers, like for google-t5/t5-small, do not have a `type` field.\n                // In this case, we can infer the tokenizer type based on the structure of the `vocab` field.\n                if (config.vocab) {\n                    if (Array.isArray(config.vocab)) {\n                        // config.vocab is of type `[string, number][]`\n                        // @ts-ignore\n                        return new Unigram(config, ...args);\n                    } else {\n                        // @ts-ignore\n                        return new LegacyTokenizerModel(config, ...args);\n                    }\n                }\n                throw new Error(`Unknown TokenizerModel type: ${config.type}`);\n        }\n    }\n\n    /**\n     * Internal function to call the TokenizerModel instance.\n     * @param {string[]} tokens The tokens to encode.\n     * @returns {string[]} The encoded tokens.\n     */\n    _call(tokens: string[]) {\n        tokens = this.encode(tokens);\n        if (this.fuse_unk) {\n            // Fuse unknown tokens\n            tokens = fuse_unk(tokens, this.tokens_to_ids, this.unk_token_id!);\n        }\n        return tokens;\n    }\n\n    /**\n     * Encodes a list of tokens into a list of token IDs.\n     * @param {string[]} tokens The tokens to encode.\n     * @returns {string[]} The encoded tokens.\n     * @throws Will throw an error if not implemented in a subclass.\n     */\n    encode(tokens: string[]): string[] {\n        throw Error('encode should be implemented in subclass.');\n    }\n\n    /**\n     * Converts a list of tokens into a list of token IDs.\n     * @param {string[]} tokens The tokens to convert.\n     * @returns {number[]} The converted token IDs.\n     */\n    convert_tokens_to_ids(tokens: string[]) {\n        return tokens.map((t) => this.tokens_to_ids.get(t) ?? this.unk_token_id);\n    }\n\n    /**\n     * Converts a list of token IDs into a list of tokens.\n     * @param {number[]|bigint[]} ids The token IDs to convert.\n     * @returns {string[]} The converted tokens.\n     */\n    convert_ids_to_tokens(ids: number[] | bigint[]) {\n        return ids.map((i: number | bigint) => this.vocab[i as number] ?? this.unk_token);\n    }\n}\n\n/**\n * A subclass of TokenizerModel that uses WordPiece encoding to encode tokens.\n * @extends TokenizerModel\n */\nclass WordPieceTokenizer extends TokenizerModel {\n    /**\n     * @param {Object} config The configuration object.\n     * @param {Object} config.vocab A mapping of tokens to ids.\n     * @param {string} config.unk_token The unknown token string.\n     * @param {string} config.continuing_subword_prefix The prefix to use for continuing subwords.\n     * @param {number} [config.max_input_chars_per_word=100] The maximum number of characters per word.\n     */\n    max_input_chars_per_word: number;\n    constructor(config: any) {\n        super(config as any);\n        /**\n         * A mapping of tokens to ids.\n         * @type {Map<string, number>}\n         */\n        this.tokens_to_ids = objectToMap(config.vocab);\n\n        /**\n         * The id of the unknown token.\n         * @type {number}\n         */\n        this.unk_token_id = this.tokens_to_ids.get(config.unk_token);\n\n        /**\n         * The unknown token string.\n         * @type {string}\n         */\n        this.unk_token = config.unk_token;\n\n        /**\n         * The maximum number of characters allowed per word.\n         * @type {number}\n         */\n        this.max_input_chars_per_word = config.max_input_chars_per_word ?? 100;\n\n        /**\n         * An array of tokens.\n         * @type {string[]}\n         */\n        this.vocab = new Array(this.tokens_to_ids.size);\n        for (const [key, value] of this.tokens_to_ids) {\n            this.vocab[value] = key;\n        }\n    }\n\n    /**\n     * Encodes an array of tokens using WordPiece encoding.\n     * @param {string[]} tokens The tokens to encode.\n     * @returns {string[]} An array of encoded tokens.\n     */\n    encode(tokens: string[]): string[] {\n        const outputTokens: string[] = [];\n        for (const token of tokens) {\n            const chars = [...token];\n            if (chars.length > this.max_input_chars_per_word) {\n                outputTokens.push(this.unk_token as string);\n                continue;\n            }\n\n            let isUnknown = false;\n            let start = 0;\n            const subTokens = [];\n\n            while (start < chars.length) {\n                let end = chars.length;\n                let currentSubstring = null;\n                while (start < end) {\n                    let substr = chars.slice(start, end).join('');\n\n                    if (start > 0) {\n                        substr = (this as any).config.continuing_subword_prefix + substr;\n                    }\n                    if (this.tokens_to_ids.has(substr)) {\n                        currentSubstring = substr;\n                        break;\n                    }\n\n                    --end;\n                }\n                if (currentSubstring === null) {\n                    isUnknown = true;\n                    break;\n                }\n                subTokens.push(currentSubstring);\n                start = end;\n            }\n            if (isUnknown) {\n                outputTokens.push(this.unk_token as string);\n            } else {\n                outputTokens.push(...subTokens);\n            }\n        }\n\n        return outputTokens;\n    }\n}\n\n/**\n * Class representing a Unigram tokenizer model.\n * @extends TokenizerModel\n */\nclass Unigram extends TokenizerModel {\n    /**\n     * Create a new Unigram tokenizer model.\n     * @param {Object} config The configuration object for the Unigram model.\n     * @param {number} config.unk_id The ID of the unknown token\n     * @param {[string, number][]} config.vocab A 2D array representing a mapping of tokens to scores.\n     * @param {Object} moreConfig Additional configuration object for the Unigram model.\n     */\n    unk_token_id: number | undefined;\n    scores: number[];\n    bos_token: string;\n    eos_token: string;\n    bos_token_id: number | undefined;\n    eos_token_id: number | undefined;\n    minScore: number | BigInt;\n    unk_score: number | BigInt;\n    trie: CharTrie;\n    fuse_unk: boolean;\n\n    constructor(\n        config: {\n            unk_id: number;\n            vocab: [string, number][];\n        },\n        moreConfig: {\n            eos_token: string;\n        },\n    ) {\n        super(config as any);\n\n        const vocabSize = config.vocab.length;\n        this.vocab = new Array(vocabSize);\n        /** @type {number[]} */\n        this.scores = new Array(vocabSize);\n        for (let i = 0; i < vocabSize; ++i) {\n            [this.vocab[i], this.scores[i]] = config.vocab[i];\n        }\n\n        this.unk_token_id = config.unk_id;\n        this.unk_token = this.vocab[config.unk_id];\n\n        this.tokens_to_ids = new Map(this.vocab.map((x, i) => [x, i]));\n        this.bos_token = ' '; // beginning of a sentence token\n\n        this.bos_token_id = this.tokens_to_ids.get(this.bos_token); // NOTE: may be undefined\n        this.eos_token = moreConfig.eos_token;\n\n        this.eos_token_id = this.tokens_to_ids.get(this.eos_token);\n        this.unk_token = this.vocab[this.unk_token_id];\n\n        this.minScore = min(this.scores)[0];\n\n        this.unk_score = Number(this.minScore) - 10.0;\n        this.scores[this.unk_token_id] = this.unk_score;\n\n        this.trie = new CharTrie();\n        this.trie.extend(this.vocab);\n\n        // NOTE: `fuse_unk` is hardcoded to true for Unigram models\n        // See: https://github.com/huggingface/tokenizers/blob/b58227c7f1ccf8b73ee2268354336da56d91e492/tokenizers/src/models/unigram/model.rs#L119\n        this.fuse_unk = true;\n    }\n\n    /**\n     * Populates lattice nodes.\n     * @param {TokenLattice} lattice The token lattice to populate with nodes.\n     */\n    populateNodes(lattice: TokenLattice) {\n        const chars = lattice._chars;\n        const mblen = 1;\n        let beginPos = 0;\n        while (beginPos < chars.length) {\n            let hasSingleNode = false;\n\n            const tokens = [];\n            const sliced = chars.slice(beginPos).join('');\n            const prefixedTokens = this.trie.commonPrefixSearch(sliced);\n            for (const token of prefixedTokens) {\n                tokens.push(token);\n                const tokenId = this.tokens_to_ids.get(token);\n                const tokenScore = this.scores[tokenId as number];\n                const n = len(token);\n                lattice.insert(beginPos, n, tokenScore, tokenId as number);\n                if (!hasSingleNode && n === mblen) {\n                    hasSingleNode = true;\n                }\n            }\n            if (!hasSingleNode) {\n                lattice.insert(beginPos, mblen, Number(this.unk_score), this.unk_token_id as number);\n            }\n            beginPos += mblen;\n        }\n    }\n\n    /**\n     * Encodes an array of tokens into an array of subtokens using the unigram model.\n     *\n     * @param {string} normalized The normalized string.\n     * @returns {string[]} An array of subtokens obtained by encoding the input tokens using the unigram model.\n     */\n    tokenize(normalized: string) {\n        const lattice = new TokenLattice(normalized, this.bos_token_id as number, this.eos_token_id as number);\n        this.populateNodes(lattice);\n        return lattice.tokens();\n    }\n\n    /**\n     * Encodes an array of tokens using Unigram encoding.\n     * @param {string[]} tokens The tokens to encode.\n     * @returns {string[]} An array of encoded tokens.\n     */\n    encode(tokens: string[]) {\n        const toReturn = [];\n        for (const token of tokens) {\n            const tokenized = this.tokenize(token);\n            toReturn.push(...tokenized);\n        }\n        return toReturn;\n    }\n}\n\n/**\n * Returns list of utf-8 byte and a mapping to unicode strings.\n * Specifically avoids mapping to whitespace/control characters the BPE code barfs on.\n * @returns {Object} Object with utf-8 byte keys and unicode string values.\n */\nconst BYTES_TO_UNICODE = (() => {\n    // Returns list of utf-8 byte and a mapping to unicode strings.\n    // We specifically avoids mapping to whitespace/control characters\n    // the bpe code barfs on.\n\n    const bs = [\n        ...Array.from({ length: '~'.charCodeAt(0) - '!'.charCodeAt(0) + 1 }, (_, i) => i + '!'.charCodeAt(0)),\n        ...Array.from({ length: '¬'.charCodeAt(0) - '¡'.charCodeAt(0) + 1 }, (_, i) => i + '¡'.charCodeAt(0)),\n        ...Array.from({ length: 'ÿ'.charCodeAt(0) - '®'.charCodeAt(0) + 1 }, (_, i) => i + '®'.charCodeAt(0)),\n    ];\n    const cs = bs.slice();\n    let n = 0;\n    for (let b = 0; b < 256; ++b) {\n        if (!bs.includes(b)) {\n            bs.push(b);\n            cs.push(256 + n);\n            n += 1;\n        }\n    }\n    const ccs = cs.map((n) => String.fromCharCode(n));\n    return Object.fromEntries(bs.map((b, i) => [b, ccs[i]]));\n})();\n\nconst UNICODE_TO_BYTES = reverseDictionary(BYTES_TO_UNICODE);\n\n/**\n * @typedef {Object} BPENode\n * @property {string} token The token associated with the node\n * @property {number} bias A positional bias for the node.\n * @property {number} [score] The score of the node.\n * @property {BPENode} [prev] The previous node in the linked list.\n * @property {BPENode} [next] The next node in the linked list.\n */\n\n/**\n * BPE class for encoding text into Byte-Pair-Encoding (BPE) tokens.\n * @extends TokenizerModel\n */\nclass BPE extends TokenizerModel {\n    /**\n     * Create a BPE instance.\n     * @param {Object} config The configuration object for BPE.\n     * @param {Object} config.vocab A mapping of tokens to ids.\n     * @param {string[]|[string, string][]} config.merges An array of BPE merges as strings.\n     * @param {string} config.unk_token The unknown token used for out of vocabulary words.\n     * @param {string} config.end_of_word_suffix The suffix to place at the end of each word.\n     * @param {string} [config.continuing_subword_suffix] The suffix to insert between words.\n     * @param {boolean} [config.byte_fallback=false] Whether to use spm byte-fallback trick (defaults to False)\n     * @param {boolean} [config.ignore_merges=false] Whether or not to match tokens with the vocab before using merges.\n     */\n    ignore_merges: boolean;\n    merges: [string, string][];\n    bpe_ranks: Map<string, number>;\n    end_of_word_suffix: string;\n    continuing_subword_suffix: string | null;\n    byte_fallback: boolean;\n    cache: Map<string, string[]>;\n    text_encoder: any;\n    constructor(config: {\n        vocab: string[];\n        merges: string[] | [string, string][];\n        unk_token: string;\n        end_of_word_suffix: string;\n        continuing_subword_suffix?: string;\n        byte_fallback?: boolean;\n        ignore_merges?: boolean;\n    }) {\n        super(config as any);\n\n        /** @type {Map<string, number>} */\n        this.tokens_to_ids = objectToMap(config.vocab);\n\n        this.unk_token_id = this.tokens_to_ids.get(config.unk_token);\n        this.unk_token = config.unk_token;\n\n        this.vocab = new Array(this.tokens_to_ids.size);\n        for (const [key, value] of this.tokens_to_ids) {\n            this.vocab[value] = key;\n        }\n\n        // Tokenizers >= 0.20.0 serializes BPE merges as a [string, string][] instead of a string[],\n        // which resolves the ambiguity for merges containing spaces.\n        const use_new_merge_format = Array.isArray(config.merges[0]);\n\n        /** @type {[string, string][]} */\n        this.merges = use_new_merge_format\n            ? /** @type {[string, string][]} */ config.merges\n            : config/** @type {string[]} */.merges\n                .map((x) => /** @type {[string, string]} */(x as any).split(' ', 2));\n        this.bpe_ranks = new Map(this.merges.map((x, i) => [JSON.stringify(x), i]));\n\n        this.end_of_word_suffix = config.end_of_word_suffix;\n\n        // NOTE: `continuing_subword_suffix` is custom (to support `BlenderbotSmallTokenizer`)\n        this.continuing_subword_suffix = config.continuing_subword_suffix ?? null;\n\n        this.byte_fallback = (this.config as any).byte_fallback ?? false;\n\n        if (this.byte_fallback) {\n            this.text_encoder = new TextEncoder();\n        }\n\n        this.ignore_merges = (this as any).config.ignore_merges ?? false;\n\n        /** @type {Map<string, string[]>} */\n        this.cache = new Map();\n    }\n\n    /**\n     * Apply Byte-Pair-Encoding (BPE) to a given token. Efficient heap-based priority\n     * queue implementation adapted from https://github.com/belladoreai/llama-tokenizer-js.\n     * @param {string} token The token to encode.\n     * @returns {string[]} The BPE encoded tokens.\n     */\n    bpe(token: string) {\n        if (token.length === 0) {\n            return [];\n        }\n\n        const cached = (this as any).cache.get(token);\n        if (cached !== undefined) {\n            return cached;\n        }\n\n        const word = Array.from(token);\n        if (this.end_of_word_suffix) {\n            word[word.length - 1] += this.end_of_word_suffix;\n        }\n\n        let result = [];\n        if (word.length > 1) {\n            // Create a priority queue to store the nodes that will be merged.\n            // The comparator function compares the scores of the nodes.\n            const queue = new PriorityQueue((a, b) => a.score < b.score);\n\n            // Construct a doubly-linked list of nodes that will be inserted into the priority queue,\n            // starting with the individual characters. We also populate each node with a positional\n            // bias to break ties in the priority queue.\n            let startingNode = {\n                token: word[0],\n                bias: 0,\n                prev: null,\n                next: null,\n            };\n\n            let previousNode: any = startingNode;\n            for (let i = 1; i < word.length; ++i) {\n                const currentNode = {\n                    bias: i / word.length, // Add fractional component to break ties\n                    token: word[i],\n                    prev: previousNode,\n                    next: null,\n                };\n                previousNode.next = currentNode;\n                this._add_node(queue, previousNode);\n                previousNode = currentNode;\n            }\n\n            while (!queue.isEmpty()) {\n                // Get the next node with the highest priority\n                const node = queue.pop();\n\n                // Check that this merge is still possible\n                if (node.deleted || !node.next || node.next.deleted) continue;\n\n                // Here, we mark the current node (left side of the merge) and the next node (right side of the merge) as deleted.\n                // This is because they will both be replaced by a new node representing the merge result.\n                node.deleted = true;\n                node.next.deleted = true;\n\n                // Next, we fix the node that comes before the current node (i.e., left side of the merge).\n                if (node.prev) {\n                    // Make a shallow copy of the previous node\n                    const newPreviousNode = { ...node.prev };\n\n                    // Mark the old previous node as deleted. This avoids erroneous merges later,\n                    // because there may still be references to this node in the priority queue.\n                    node.prev.deleted = true;\n                    node.prev = newPreviousNode;\n\n                    // Update the reference of the previous node, by pointing its previous node to this new previous node.\n                    if (newPreviousNode.prev) {\n                        newPreviousNode.prev.next = newPreviousNode;\n                    } else {\n                        // If the previous of the previous node does not exist, it means that\n                        // `newPreviousNode` must be the new `startingNode`.\n                        startingNode = newPreviousNode;\n                    }\n                }\n\n                // Create a new node which represents the result of the merge.\n                const merged = {\n                    token: node.token + node.next.token,\n                    bias: node.bias,\n                    prev: node.prev,\n                    next: node.next.next,\n                };\n\n                // We now consider where we can add the new merged node to the priority queue:\n                // 1. prev <-> merged\n                if (merged.prev) {\n                    merged.prev.next = merged;\n                    this._add_node(queue, merged.prev);\n                } else {\n                    // If `merged.prev` does not exist, then `merged` must be the new `startingNode`.\n                    startingNode = merged;\n                }\n\n                // 2. merged <-> next\n                if (merged.next) {\n                    merged.next.prev = merged;\n                    this._add_node(queue, merged);\n                }\n            }\n\n            // Traverse the linked list, starting from the `startingNode`, and collect the tokens.\n            for (let currentNode: any = startingNode; currentNode !== null; currentNode = currentNode.next) {\n                result.push(currentNode.token);\n            }\n        } else {\n            result = word;\n        }\n\n        // Possibly append suffix\n        if (this.continuing_subword_suffix) {\n            // Do not append suffix to the last token\n            for (let i = 0; i < result.length - 1; ++i) {\n                result[i] += this.continuing_subword_suffix;\n            }\n        }\n\n        // Save the result to the cache\n        this.cache.set(token, result);\n\n        return result;\n    }\n\n    /**\n     * Helper function to add a node to the priority queue.\n     * @param {PriorityQueue} queue\n     * @param {BPENode} node\n     * @private\n     */\n    _add_node(queue: any, node: any) {\n        // `score` is a measure of the merge priority: lower means higher priority\n        // We use the BPE rank as a measure of priority (i.e., the local of the merge in the merges list)\n        // We also add a fractional component to the score to break ties (with the earlier character having higher priority)\n        const rank = this.bpe_ranks.get(JSON.stringify([node.token, node.next.token]));\n        if (rank !== undefined) {\n            node.score = rank + node.bias;\n            queue.push(node);\n        }\n    }\n\n    /**\n     * Encodes the input sequence of tokens using the BPE algorithm and returns the resulting subword tokens.\n     * @param {string[]} tokens The input sequence of tokens to encode.\n     * @returns {string[]} The resulting subword tokens after applying the BPE algorithm to the input sequence of tokens.\n     */\n    encode(tokens: string[]) {\n        const outputTokens = [];\n\n        for (const token of tokens) {\n            if (this.ignore_merges && this.tokens_to_ids.has(token)) {\n                outputTokens.push(token);\n                continue;\n            }\n            const bpe_token_list = this.bpe(token);\n\n            for (const t of bpe_token_list) {\n                if (this.tokens_to_ids.has(t)) {\n                    outputTokens.push(t);\n                } else if (this.byte_fallback) {\n                    const byteTokens = Array.from(this.text_encoder.encode(t)).map(\n                        (x: any) => `<0x${x.toString(16).toUpperCase().padStart(2, '0')}>`,\n                    );\n                    if (byteTokens.every((x) => this.tokens_to_ids.has(x))) {\n                        // Ensure the byte tokens are actually in the vocabulary, otherwise\n                        // we fall back to the unknown token. For more information, see\n                        // https://github.com/huggingface/transformers/issues/28096.\n                        outputTokens.push(...byteTokens);\n                    } else {\n                        outputTokens.push(this.unk_token);\n                    }\n                } else {\n                    outputTokens.push(this.unk_token);\n                }\n            }\n        }\n\n        return outputTokens;\n    }\n}\n\n/**\n * Legacy tokenizer class for tokenizers with only a vocabulary.\n */\nclass LegacyTokenizerModel extends TokenizerModel {\n    /**\n     * Create a LegacyTokenizerModel instance.\n     * @param {Object} config The configuration object for LegacyTokenizerModel.\n     * @param {Object} config.vocab A (possibly nested) mapping of tokens to ids.\n     * @param {Object} moreConfig Additional configuration object for the LegacyTokenizerModel model.\n     */\n    bos_token: string;\n    eos_token: string;\n    pad_token: string;\n    unk_token: string;\n    bos_token_id: number | undefined;\n    eos_token_id: number | undefined;\n    pad_token_id: number | undefined;\n    unk_token_id: number | undefined;\n    vocab: string[];\n    constructor(\n        config: {\n            vocab: string[];\n            target_lang?: string;\n        },\n        moreConfig: {\n            bos_token: string;\n            eos_token: string;\n            target_lang?: any;\n            pad_token?: any;\n            unk_token?: any;\n        },\n    ) {\n        super(config as any);\n\n        /**@type {Map<string, number>} */\n        this.tokens_to_ids = objectToMap(\n            (moreConfig.target_lang ? config.vocab[moreConfig.target_lang] : config.vocab) as any,\n        );\n\n        this.bos_token = moreConfig.bos_token;\n        this.bos_token_id = this.tokens_to_ids.get(this.bos_token);\n\n        this.eos_token = moreConfig.eos_token;\n        this.eos_token_id = this.tokens_to_ids.get(this.eos_token);\n\n        this.pad_token = moreConfig.pad_token;\n        this.pad_token_id = this.tokens_to_ids.get(this.pad_token);\n\n        this.unk_token = moreConfig.unk_token;\n        this.unk_token_id = this.tokens_to_ids.get(this.unk_token);\n\n        this.vocab = new Array(this.tokens_to_ids.size);\n        for (const [key, value] of this.tokens_to_ids) {\n            this.vocab[value] = key;\n        }\n    }\n\n    encode(tokens: string[]) {\n        return tokens;\n    }\n}\n\n/**\n * A base class for text normalization.\n * @abstract\n */\nclass Normalizer extends Callable {\n    /**\n     * @param {Object} config The configuration object for the normalizer.\n     */\n    config: any;\n    constructor(config: { type: string }) {\n        super();\n        this.config = config;\n    }\n\n    /**\n     * Factory method for creating normalizers from config objects.\n     * @static\n     * @param {Object} config The configuration object for the normalizer.\n     * @returns {Normalizer} A Normalizer object.\n     * @throws {Error} If an unknown Normalizer type is specified in the config.\n     */\n    static fromConfig(config: { type: string }) {\n        if (config === null) return null;\n        switch (config.type) {\n            case 'BertNormalizer':\n                return new BertNormalizer(config);\n            case 'Precompiled':\n                return new Precompiled(config);\n            case 'Sequence':\n                return new NormalizerSequence(config as any);\n            case 'Replace':\n                return new Replace(config);\n            case 'NFC':\n                return new NFC(config);\n            case 'NFKC':\n                return new NFKC(config);\n            case 'NFKD':\n                return new NFKD(config);\n            case 'Strip':\n                return new StripNormalizer(config);\n            case 'StripAccents':\n                return new StripAccents(config);\n            case 'Lowercase':\n                return new Lowercase(config);\n            case 'Prepend':\n                return new Prepend(config);\n            default:\n                throw new Error(`Unknown Normalizer type: ${config.type}`);\n        }\n    }\n\n    /**\n     * Normalize the input text.\n     * @abstract\n     * @param {string} text The text to normalize.\n     * @returns {string} The normalized text.\n     * @throws {Error} If this method is not implemented in a subclass.\n     */\n    normalize(text: string) {\n        throw Error('normalize should be implemented in subclass.');\n    }\n\n    /**\n     * Alias for {@link Normalizer#normalize}.\n     * @param {string} text The text to normalize.\n     * @returns {string} The normalized text.\n     */\n    _call(text: string) {\n        return this.normalize(text);\n    }\n}\n\n/**\n * Replace normalizer that replaces occurrences of a pattern with a given string or regular expression.\n * @extends Normalizer\n */\nclass Replace extends Normalizer {\n    /**\n     * Normalize the input text by replacing the pattern with the content.\n     * @param {string} text The input text to be normalized.\n     * @returns {string} The normalized text after replacing the pattern with the content.\n     */\n    normalize(text: string) {\n        const pattern = createPattern(this.config.pattern);\n        return pattern === null ? text : text.replaceAll(pattern, this.config.content);\n    }\n}\n\n/**\n * A normalizer that applies Unicode normalization form C (NFC) to the input text.\n * @extends Normalizer\n */\nclass NFC extends Normalizer {\n    /**\n     * Normalize the input text by applying Unicode normalization form C (NFC).\n     * @param {string} text The input text to be normalized.\n     * @returns {string} The normalized text.\n     */\n    normalize(text: string) {\n        text = text.normalize('NFC');\n        return text;\n    }\n}\n\n/**\n * NFKC Normalizer.\n * @extends Normalizer\n */\nclass NFKC extends Normalizer {\n    /**\n     * Normalize text using NFKC normalization.\n     * @param {string} text The text to be normalized.\n     * @returns {string} The normalized text.\n     */\n    normalize(text: string) {\n        text = text.normalize('NFKC');\n        return text;\n    }\n}\n/**\n * NFKD Normalizer.\n * @extends Normalizer\n */\nclass NFKD extends Normalizer {\n    /**\n     * Normalize text using NFKD normalization.\n     * @param {string} text The text to be normalized.\n     * @returns {string} The normalized text.\n     */\n    normalize(text: string) {\n        text = text.normalize('NFKD');\n        return text;\n    }\n}\n\n\n/**\n * A normalizer that strips leading and/or trailing whitespace from the input text.\n */\nclass StripNormalizer extends Normalizer {\n    /**\n     * Strip leading and/or trailing whitespace from the input text.\n     * @param {string} text The input text.\n     * @returns {string} The normalized text.\n     */\n    normalize(text: string) {\n        if (this.config.strip_left && this.config.strip_right) {\n            // Fast path to avoid an extra trim call\n            text = text.trim();\n        } else {\n            if (this.config.strip_left) {\n                text = text.trimStart();\n            }\n            if (this.config.strip_right) {\n                text = text.trimEnd();\n            }\n        }\n        return text;\n    }\n}\n\n/**\n * StripAccents normalizer removes all accents from the text.\n * @extends Normalizer\n */\nclass StripAccents extends Normalizer {\n    /**\n     * Remove all accents from the text.\n     * @param {string} text The input text.\n     * @returns {string} The normalized text without accents.\n     */\n    normalize(text: string) {\n        text = remove_accents(text);\n        return text;\n    }\n}\n\n/**\n * A Normalizer that lowercases the input string.\n * @extends Normalizer\n */\nclass Lowercase extends Normalizer {\n    /**\n     * Lowercases the input string.\n     * @param {string} text The text to normalize.\n     * @returns {string} The normalized text.\n     */\n    normalize(text: string) {\n        text = text.toLowerCase();\n        return text;\n    }\n}\n\n/**\n * A Normalizer that prepends a string to the input string.\n * @extends Normalizer\n */\nclass Prepend extends Normalizer {\n    /**\n     * Prepends the input string.\n     * @param {string} text The text to normalize.\n     * @returns {string} The normalized text.\n     */\n    normalize(text: string) {\n        text = this.config.prepend + text;\n        return text;\n    }\n}\n\n/**\n * A Normalizer that applies a sequence of Normalizers.\n * @extends Normalizer\n */\nclass NormalizerSequence extends Normalizer {\n    /**\n     * Create a new instance of NormalizerSequence.\n     * @param {Object} config The configuration object.\n     * @param {Object[]} config.normalizers An array of Normalizer configuration objects.\n     */\n    normalizers: any;\n    constructor(config: {\n        normalizers: {\n            type: string;\n        }[];\n    }) {\n        super(config as any);\n        this.normalizers = config.normalizers.map((x: any) => Normalizer.fromConfig(x));\n    }\n    /**\n     * Apply a sequence of Normalizers to the input text.\n     * @param {string} text The text to normalize.\n     * @returns {string} The normalized text.\n     */\n    normalize(text: string) {\n        return this.normalizers.reduce((t: string, normalizer: any) => {\n            return normalizer.normalize(t);\n        }, text);\n    }\n}\n\n/**\n * A class representing a normalizer used in BERT tokenization.\n * @extends Normalizer\n */\nclass BertNormalizer extends Normalizer {\n    /**\n     * Adds whitespace around any CJK (Chinese, Japanese, or Korean) character in the input text.\n     *\n     * @param {string} text The input text to tokenize.\n     * @returns {string} The tokenized text with whitespace added around CJK characters.\n     */\n    _tokenize_chinese_chars(text: string) {\n        /* Adds whitespace around any CJK character. */\n        const output = [];\n        for (let i = 0; i < text.length; ++i) {\n            const char = text[i];\n            const cp = char.charCodeAt(0);\n            if (is_chinese_char(cp)) {\n                output.push(' ');\n                output.push(char);\n                output.push(' ');\n            } else {\n                output.push(char);\n            }\n        }\n        return output.join('');\n    }\n\n    /**\n     * Strips accents from the given text.\n     * @param {string} text The text to strip accents from.\n     * @returns {string} The text with accents removed.\n     */\n    stripAccents(text: string) {\n        // \"Mark, Nonspacing\" (Mn)\n        return text.normalize('NFD').replace(/\\p{Mn}/gu, '');\n    }\n\n    /**\n     * Checks whether `char` is a control character.\n     * @param {string} char The character to check.\n     * @returns {boolean} Whether `char` is a control character.\n     * @private\n     */\n    _is_control(char: string) {\n        switch (char) {\n            case '\\t':\n            case '\\n':\n            case '\\r':\n                // These are technically control characters but we count them as whitespace characters.\n                return false;\n\n            default:\n                // Check if unicode category starts with C:\n                // Cc - Control\n                // Cf - Format\n                // Co - Private Use\n                // Cs - Surrogate\n                return /^\\p{Cc}|\\p{Cf}|\\p{Co}|\\p{Cs}$/u.test(char);\n        }\n    }\n\n    /**\n     * Performs invalid character removal and whitespace cleanup on text.\n     * @param {string} text The text to clean.\n     * @returns {string} The cleaned text.\n     * @private\n     */\n    _clean_text(text: string) {\n        const output = [];\n        for (const char of text) {\n            const cp = char.charCodeAt(0);\n            if (cp === 0 || cp === 0xfffd || this._is_control(char)) {\n                continue;\n            }\n            if (/^\\s$/.test(char)) {\n                // is whitespace\n                output.push(' ');\n            } else {\n                output.push(char);\n            }\n        }\n        return output.join('');\n    }\n    /**\n     * Normalizes the given text based on the configuration.\n     * @param {string} text The text to normalize.\n     * @returns {string} The normalized text.\n     */\n    normalize(text: string) {\n        if (this.config.clean_text) {\n            text = this._clean_text(text);\n        }\n\n        if (this.config.handle_chinese_chars) {\n            text = this._tokenize_chinese_chars(text);\n        }\n\n        if (this.config.lowercase) {\n            text = text.toLowerCase();\n\n            if (this.config.strip_accents !== false) {\n                text = this.stripAccents(text);\n            }\n        } else if (this.config.strip_accents) {\n            text = this.stripAccents(text);\n        }\n\n        return text;\n    }\n}\n\n/**\n * A callable class representing a pre-tokenizer used in tokenization. Subclasses\n * should implement the `pre_tokenize_text` method to define the specific pre-tokenization logic.\n * @extends Callable\n */\nclass PreTokenizer extends Callable {\n    /**\n     * Factory method that returns an instance of a subclass of `PreTokenizer` based on the provided configuration.\n     *\n     * @static\n     * @param {Object} config A configuration object for the pre-tokenizer.\n     * @returns {PreTokenizer} An instance of a subclass of `PreTokenizer`.\n     * @throws {Error} If the provided configuration object does not correspond to any known pre-tokenizer.\n     */\n    static fromConfig(config: any) {\n        if (config === null) return null;\n\n        switch (config.type) {\n            case 'BertPreTokenizer':\n                return new BertPreTokenizer(config);\n            case 'Sequence':\n                return new PreTokenizerSequence(config);\n            case 'Whitespace':\n                return new WhitespacePreTokenizer(config);\n            case 'WhitespaceSplit':\n                return new WhitespaceSplit(config);\n            case 'Metaspace':\n                return new MetaspacePreTokenizer(config);\n\n            case 'ByteLevel':\n                return new ByteLevelPreTokenizer(config);\n            case 'Split':\n                return new SplitPreTokenizer(config);\n            case 'Punctuation':\n                return new PunctuationPreTokenizer(config);\n            case 'Digits':\n                return new DigitsPreTokenizer(config);\n            case 'Replace':\n                return new ReplacePreTokenizer(config);\n            default:\n                throw new Error(`Unknown PreTokenizer type: ${config.type}`);\n        }\n    }\n\n    /**\n     * Method that should be implemented by subclasses to define the specific pre-tokenization logic.\n     *\n     * @abstract\n     * @param {string} text The text to pre-tokenize.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} The pre-tokenized text.\n     * @throws {Error} If the method is not implemented in the subclass.\n     */\n    pre_tokenize_text(text: string, options: any) {\n        throw Error('pre_tokenize_text should be implemented in subclass.');\n    }\n\n    /**\n     * Tokenizes the given text into pre-tokens.\n     * @param {string|string[]} text The text or array of texts to pre-tokenize.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} An array of pre-tokens.\n     */\n    pre_tokenize(text: string | string[], options: any) {\n        return (\n            Array.isArray(text) ? text.map((x) => this.pre_tokenize_text(x, options)) : [this.pre_tokenize_text(text, options)]\n        ).flat();\n    }\n\n    /**\n     * Alias for {@link PreTokenizer#pre_tokenize}.\n     * @param {string|string[]} text The text or array of texts to pre-tokenize.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} An array of pre-tokens.\n     */\n    _call(text: string | string[], options: any) {\n        return this.pre_tokenize(text, options);\n    }\n}\n\n/**\n * @extends PreTokenizer\n */\nclass BertPreTokenizer extends PreTokenizer {\n    /**\n     * A PreTokenizer that splits text into wordpieces using a basic tokenization scheme\n     * similar to that used in the original implementation of BERT.\n     *\n     * @param {Object} config The configuration object.\n     */\n    pattern: RegExp;\n    constructor(config: {\n        clean_text: boolean;\n        handle_chinese_chars: boolean;\n        lowercase: boolean;\n        strip_accents: boolean;\n    }) {\n        super();\n        // Construct a pattern which matches the rust implementation:\n        // https://github.com/huggingface/tokenizers/blob/b4fcc9ce6e4ad5806e82826f816acfdfdc4fcc67/tokenizers/src/pre_tokenizers/bert.rs#L11\n        // Equivalent to removing whitespace and splitting on punctuation (both \\p{P} and other ascii characters)\n        this.pattern = new RegExp(`[^\\\\s${PUNCTUATION_REGEX}]+|[${PUNCTUATION_REGEX}]`, 'gu');\n    }\n    /**\n     * Tokenizes a single text using the BERT pre-tokenization scheme.\n     *\n     * @param {string} text The text to tokenize.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} An array of tokens.\n     */\n    pre_tokenize_text(text: string, options: any) {\n        return text.trim().match(this.pattern) || [];\n    }\n}\n\n/**\n * A pre-tokenizer that splits text into Byte-Pair-Encoding (BPE) subwords.\n * @extends PreTokenizer\n */\nclass ByteLevelPreTokenizer extends PreTokenizer {\n    /**\n     * Creates a new instance of the `ByteLevelPreTokenizer` class.\n     * @param {Object} config The configuration object.\n     */\n    config: any;\n    add_prefix_space: boolean;\n    trim_offsets: boolean;\n    use_regex: boolean;\n    pattern: RegExp;\n    byte_encoder: any;\n    text_encoder: any;\n    constructor(config: { add_prefix_space: boolean; trim_offsets: boolean }) {\n        super();\n        this.config = config;\n\n        /**\n         * @type {boolean} Whether to add a leading space to the first word.\n         * This allows to treat the leading word just as any other word.\n         */\n        this.add_prefix_space = this.config.add_prefix_space;\n\n        /**\n         * @type {boolean} Whether the post processing step should trim offsets\n         * to avoid including whitespaces.\n         * @todo Use this in the pretokenization step.\n         */\n        this.trim_offsets = this.config.trim_offsets;\n\n        /**\n         * @type {boolean} Whether to use the standard GPT2 regex for whitespace splitting.\n         * Set it to False if you want to use your own splitting. Defaults to true.\n         */\n        this.use_regex = this.config.use_regex ?? true;\n        this.pattern = /'s|'t|'re|'ve|'m|'ll|'d| ?\\p{L}+| ?\\p{N}+| ?[^\\s\\p{L}\\p{N}]+|\\s+(?!\\S)|\\s+/gu;\n\n        this.byte_encoder = BYTES_TO_UNICODE;\n        this.text_encoder = new TextEncoder();\n    }\n\n    /**\n     * Tokenizes a single piece of text using byte-level tokenization.\n     * @param {string} text The text to tokenize.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} An array of tokens.\n     */\n    pre_tokenize_text(text: string, options: any) {\n        // Add a leading space if the option is enabled\n        if (this.add_prefix_space && !text.startsWith(' ')) {\n            text = ' ' + text;\n        }\n\n        // Split on whitespace and punctuation\n        const tokens = this.use_regex ? text.match(this.pattern) || [] : [text];\n\n        // Maps all our bytes to unicode strings, avoiding control tokens of the BPE (spaces in our case)\n        return tokens.map((token) =>\n            Array.from(this.text_encoder.encode(token), (byte) => this.byte_encoder[(byte as any)]).join(''),\n        );\n    }\n}\n\n/**\n * @typedef {'removed'|'isolated'|'mergedWithPrevious'|'mergedWithNext'|'contiguous'} SplitDelimiterBehavior\n */\ntype SplitDelimiterBehavior = 'removed' | 'isolated' | 'mergedWithPrevious' | 'mergedWithNext' | 'contiguous';\n/**\n * Splits text using a given pattern.\n * @extends PreTokenizer\n */\nclass SplitPreTokenizer extends PreTokenizer {\n    /**\n     * @param {Object} config The configuration options for the pre-tokenizer.\n     * @param {Object} config.pattern The pattern used to split the text. Can be a string or a regex object.\n     * @param {string|undefined} config.pattern.String The string to use for splitting. Only defined if the pattern is a string.\n     * @param {string|undefined} config.pattern.Regex The regex to use for splitting. Only defined if the pattern is a regex.\n     * @param {SplitDelimiterBehavior} config.behavior The behavior to use when splitting.\n     * @param {boolean} config.invert Whether to split (invert=false) or match (invert=true) the pattern.\n     */\n    config: any;\n    pattern: any;\n    constructor(config: { pattern: string | RegExp; behavior: SplitDelimiterBehavior; invert: boolean }) {\n        super();\n        this.config = config;\n        // TODO support all behaviours (config.behavior)\n\n        this.pattern = createPattern(this.config.pattern, this.config.invert);\n    }\n\n    /**\n     * Tokenizes text by splitting it using the given pattern.\n     * @param {string} text The text to tokenize.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} An array of tokens.\n     */\n    pre_tokenize_text(text: string, options: any) {\n        if (this.pattern === null) {\n            return [];\n        }\n\n        if (this.config.invert) {\n            return text.match(this.pattern) || [];\n        } else if (this.config.behavior?.toLowerCase() === 'removed') {\n            return text.split(this.pattern).filter((x) => x);\n        } else {\n            return regexSplit(text, this.pattern);\n        }\n    }\n}\n\n/**\n * Splits text based on punctuation.\n * @extends PreTokenizer\n */\nclass PunctuationPreTokenizer extends PreTokenizer {\n    /**\n     * @param {Object} config The configuration options for the pre-tokenizer.\n     * @param {SplitDelimiterBehavior} config.behavior The behavior to use when splitting.\n     */\n    config: any;\n    pattern: RegExp;\n    constructor(config: { behavior: SplitDelimiterBehavior }) {\n        super();\n        this.config = config;\n        this.pattern = new RegExp(`[^${PUNCTUATION_REGEX}]+|[${PUNCTUATION_REGEX}]+`, 'gu');\n    }\n\n    /**\n     * Tokenizes text by splitting it using the given pattern.\n     * @param {string} text The text to tokenize.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} An array of tokens.\n     */\n    pre_tokenize_text(text: string, options: any) {\n        return text.match(this.pattern) || [];\n    }\n}\n\n/**\n * Splits text based on digits.\n * @extends PreTokenizer\n */\nclass DigitsPreTokenizer extends PreTokenizer {\n    /**\n     * @param {Object} config The configuration options for the pre-tokenizer.\n     * @param {boolean} config.individual_digits Whether to split on individual digits.\n     */\n    config: any;\n    pattern: RegExp;\n    constructor(config: any) {\n        super();\n        this.config = config;\n\n        // Construct a pattern which matches the rust implementation:\n        const digit_pattern = `[^\\\\d]+|\\\\d${this.config.individual_digits ? '' : '+'}`;\n        this.pattern = new RegExp(digit_pattern, 'gu');\n    }\n\n    /**\n     * Tokenizes text by splitting it using the given pattern.\n     * @param {string} text The text to tokenize.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} An array of tokens.\n     */\n    pre_tokenize_text(text: string, options: any) {\n        return text.match(this.pattern) || [];\n    }\n}\n\n/**\n * @typedef {Object} PostProcessedOutput\n * @property {string[]} tokens List of token produced by the post-processor.\n * @property {number[]} [token_type_ids] List of token type ids produced by the post-processor.\n */\n\n/**\n * @typedef {Object} EncodingSingle\n * @property {number[]} input_ids List of token ids to be fed to a model.\n * @property {number[]} attention_mask List of token type ids to be fed to a model\n * @property {number[]} [token_type_ids] List of indices specifying which tokens should be attended to by the model\n */\n\n/**\n * @extends Callable\n */\nclass PostProcessor extends Callable {\n    /**\n     * @param {Object} config The configuration for the post-processor.\n     */\n    config: any;\n    constructor(config: any) {\n        if (!config) {\n            throw new Error('config is required');\n        }\n        super();\n        this.config = config;\n    }\n\n    /**\n     * Factory method to create a PostProcessor object from a configuration object.\n     *\n     * @param {Object} config Configuration object representing a PostProcessor.\n     * @returns {PostProcessor} A PostProcessor object created from the given configuration.\n     * @throws {Error} If an unknown PostProcessor type is encountered.\n     */\n    static fromConfig(config: any) {\n        if (config === null) return null;\n        switch (config.type) {\n            case 'TemplateProcessing':\n                return new TemplateProcessing(config);\n            case 'ByteLevel':\n                return new ByteLevelPostProcessor(config);\n            case 'Sequence':\n                return new PostProcessorSequence(config);\n            default:\n                throw new Error(`Unknown PostProcessor type: ${config.type}`);\n        }\n    }\n\n    /**\n     * Method to be implemented in subclass to apply post-processing on the given tokens.\n     *\n     * @param {Array} tokens The input tokens to be post-processed.\n     * @param {...*} args Additional arguments required by the post-processing logic.\n     * @returns {PostProcessedOutput} The post-processed tokens.\n     * @throws {Error} If the method is not implemented in subclass.\n     */\n    post_process(tokens: string[], ...args: any[]) {\n        throw Error('post_process should be implemented in subclass.');\n    }\n\n    /**\n     * Alias for {@link PostProcessor#post_process}.\n     * @param {Array} tokens The text or array of texts to post-process.\n     * @param {...*} args Additional arguments required by the post-processing logic.\n     * @returns {PostProcessedOutput} The post-processed tokens.\n     */\n    _call(tokens: string[], ...args: any[]) {\n        return this.post_process(tokens, ...args);\n    }\n}\n\n\n/**\n * A class representing a post processor used in tokenization.\n * @extends PostProcessor\n */\nclass TemplateProcessing extends PostProcessor {\n    /**\n     * Creates a new instance of `TemplateProcessing`.\n     * @param {Object} config The configuration options for the post processor.\n     * @param {Array} config.single The template for a single sequence of tokens.\n     * @param {Array} config.pair The template for a pair of sequences of tokens.\n     */\n    single: Array<any>;\n    pair: Array<any>;\n    constructor(config: {\n        single: Array<any>;\n        pair: Array<any>;\n    }) {\n        super(config);\n\n        this.single = config.single;\n        this.pair = config.pair;\n    }\n\n    /**\n     * Replaces special tokens in the template with actual tokens.\n     * @param {string[]} tokens The list of tokens for the first sequence.\n     * @param {string[]} [tokens_pair=null] The list of tokens for the second sequence (optional).\n     * @returns {PostProcessedOutput} An object containing the list of tokens with the special tokens replaced with actual tokens.\n     */\n    post_process(tokens: string[], tokens_pair: string[] | null, {\n        add_special_tokens = true,\n    } = {}) {\n        const type = tokens_pair === null ? this.single : this.pair\n\n        let processedTokens: string[] = [];\n        let types: number[] = [];\n        for (const item of type) {\n            if ('SpecialToken' in item) {\n                if (add_special_tokens) {\n                    processedTokens.push(item.SpecialToken.id);\n                    types.push(item.SpecialToken.type_id);\n                }\n            } else if ('Sequence' in item) {\n                if (item.Sequence.id === 'A') {\n                    processedTokens = mergeArrays(processedTokens, tokens);\n                    types = mergeArrays(types, new Array(tokens.length).fill(item.Sequence.type_id));\n\n                } else if (item.Sequence.id === 'B') {\n                    processedTokens = mergeArrays(processedTokens, (tokens_pair as string[]));\n                    types = mergeArrays(types, new Array((tokens_pair as string[]).length).fill(item.Sequence.type_id));\n                }\n            }\n        }\n        return { tokens: processedTokens, token_type_ids: types };\n    }\n}\n\n\n/**\n * A PostProcessor that returns the given tokens as is.\n * @extends PostProcessor\n */\nclass ByteLevelPostProcessor extends PostProcessor {\n    /**\n     * Post process the given tokens.\n     * @param {string[]} tokens The list of tokens for the first sequence.\n     * @param {string[]} [tokens_pair=null] The list of tokens for the second sequence (optional).\n     * @returns {PostProcessedOutput} An object containing the post-processed tokens.\n     */\n    post_process(tokens: string[], tokens_pair = null) {\n        if (tokens_pair) {\n            tokens = mergeArrays(tokens, tokens_pair);\n        }\n        return { tokens };\n    }\n}\n\n/**\n * A post-processor that applies multiple post-processors in sequence.\n */\nclass PostProcessorSequence extends PostProcessor {\n    /**\n     * Creates a new instance of PostProcessorSequence.\n     * @param {Object} config The configuration object.\n     * @param {Object[]} config.processors The list of post-processors to apply.\n     */\n    processors: any;\n    constructor(config: any) {\n        super(config as any);\n\n        this.processors = config.processors.map((x: any) => PostProcessor.fromConfig(x));\n    }\n\n    /**\n     * Post process the given tokens.\n     * @param {string[]} tokens The list of tokens for the first sequence.\n     * @param {string[]} [tokens_pair=null] The list of tokens for the second sequence (optional).\n     * @returns {PostProcessedOutput} An object containing the post-processed tokens.\n     */\n    post_process(tokens: string[], tokens_pair: string[] | null = null, options: any = {}) {\n        let token_type_ids;\n        for (const processor of this.processors) {\n            if (processor instanceof ByteLevelPostProcessor) {\n                // Special case where we need to pass the tokens_pair to the post-processor\n                const output = processor.post_process(tokens);\n                tokens = output.tokens;\n                if (tokens_pair) {\n                    const pair_output = processor.post_process(tokens_pair);\n                    tokens_pair = pair_output.tokens;\n                }\n            } else {\n                const output = processor.post_process(tokens, tokens_pair, options);\n                tokens = output.tokens;\n                token_type_ids = output.token_type_ids;\n            }\n        }\n        return { tokens, token_type_ids };\n    }\n}\n\n/**\n * The base class for token decoders.\n * @extends Callable\n */\nclass Decoder extends Callable {\n    /**\n     * Creates an instance of `Decoder`.\n     *\n     * @param {Object} config The configuration object.\n     */\n    added_tokens: AddedToken[];\n    end_of_word_suffix: string | null;\n    trim_offsets: boolean;\n    config: any;\n    // x: any;\n    constructor(config: any) {\n        super();\n        this.config = config;\n\n        /** @type {AddedToken[]} */\n        this.added_tokens = [];\n        this.end_of_word_suffix = null;\n        this.trim_offsets = config.trim_offsets;\n    }\n\n    /**\n     * Creates a decoder instance based on the provided configuration.\n     *\n     * @param {Object} config The configuration object.\n     * @returns {Decoder} A decoder instance.\n     * @throws {Error} If an unknown decoder type is provided.\n     */\n    static fromConfig(config: any) {\n        if (config === null) return null;\n        switch (config.type) {\n            case 'WordPiece':\n                return new WordPieceDecoder(config);\n            case 'Metaspace':\n                return new MetaspaceDecoder(config);\n            case 'ByteLevel':\n                return new ByteLevelDecoder(config);\n\n            case 'Replace':\n                return new ReplaceDecoder(config);\n            case 'ByteFallback':\n                return new ByteFallback(config);\n            case 'Fuse':\n                return new FuseDecoder(config);\n            case 'Strip':\n                return new StripDecoder(config);\n\n            case 'Sequence':\n                return new DecoderSequence(config);\n\n            case 'CTC':\n                return new CTCDecoder(config);\n            case 'BPEDecoder':\n                return new BPEDecoder(config);\n            default:\n                throw new Error(`Unknown Decoder type: ${config.type}`);\n        }\n    }\n\n    /**\n     * Calls the `decode` method.\n     *\n     * @param {string[]} tokens The list of tokens.\n     * @returns {string} The decoded string.\n     */\n    _call(tokens: string[]) {\n        return this.decode(tokens);\n    }\n\n    /**\n     * Decodes a list of tokens.\n     * @param {string[]} tokens The list of tokens.\n     * @returns {string} The decoded string.\n     */\n    decode(tokens: string[]) {\n        return this.decode_chain(tokens).join('');\n    }\n\n    /**\n     * Apply the decoder to a list of tokens.\n     *\n     * @param {string[]} tokens The list of tokens.\n     * @returns {string[]} The decoded list of tokens.\n     * @throws {Error} If the `decode_chain` method is not implemented in the subclass.\n     */\n    decode_chain(tokens: string[]) {\n        throw Error('`decode_chain` should be implemented in subclass.');\n    }\n}\n\nclass ReplaceDecoder extends Decoder {\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        const pattern = createPattern(this.config.pattern);\n        return pattern === null ? tokens : tokens.map((token) => token.replaceAll(pattern, this.config.content));\n    }\n}\n\nclass ByteFallback extends Decoder {\n    text_decoder: TextDecoder;\n\n    constructor(config: any) {\n        super(config as any);\n\n        this.text_decoder = new TextDecoder();\n    }\n\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        const new_tokens = [];\n        let previous_byte_tokens = [];\n\n        for (const token of tokens) {\n            let bytes = null;\n            if (token.length === 6 && token.startsWith('<0x') && token.endsWith('>')) {\n                const byte = parseInt(token.slice(3, 5), 16);\n                if (!isNaN(byte)) {\n                    bytes = byte;\n                }\n            }\n            if (bytes !== null) {\n                previous_byte_tokens.push(bytes);\n            } else {\n                if (previous_byte_tokens.length > 0) {\n                    const string = this.text_decoder.decode(Uint8Array.from(previous_byte_tokens));\n                    new_tokens.push(string);\n                    previous_byte_tokens = [];\n                }\n                new_tokens.push(token);\n            }\n        }\n        if (previous_byte_tokens.length > 0) {\n            const string = this.text_decoder.decode(Uint8Array.from(previous_byte_tokens));\n            new_tokens.push(string);\n            previous_byte_tokens = [];\n        }\n\n        return new_tokens;\n    }\n}\n\n/**\n * Fuse simply fuses all tokens into one big string.\n * It's usually the last decoding step anyway, but this decoder\n * exists incase some decoders need to happen after that step\n */\nclass FuseDecoder extends Decoder {\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        return [tokens.join('')];\n    }\n}\n\nclass StripDecoder extends Decoder {\n    content: string;\n    start: number;\n    stop: number;\n\n    constructor(config: any) {\n        super(config as any);\n\n        this.content = this.config.content;\n        this.start = this.config.start;\n        this.stop = this.config.stop;\n    }\n\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        return tokens.map((token) => {\n            let start_cut = 0;\n            for (let i = 0; i < this.start; ++i) {\n                if (token[i] === this.content) {\n                    start_cut = i + 1;\n                    continue;\n                } else {\n                    break;\n                }\n            }\n\n            let stop_cut = token.length;\n            for (let i = 0; i < this.stop; ++i) {\n                const index = token.length - i - 1;\n                if (token[index] === this.content) {\n                    stop_cut = index;\n                    continue;\n                } else {\n                    break;\n                }\n            }\n\n            return token.slice(start_cut, stop_cut);\n        });\n    }\n}\n\n/**\n * A decoder that decodes a list of WordPiece tokens into a single string.\n * @extends Decoder\n */\nclass WordPieceDecoder extends Decoder {\n    /**\n     * Creates a new instance of WordPieceDecoder.\n     * @param {Object} config The configuration object.\n     * @param {string} config.prefix The prefix used for WordPiece encoding.\n     * @param {boolean} config.cleanup Whether to cleanup the decoded string.\n     */\n    cleanup: boolean;\n    constructor(config: any) {\n        super(config as any);\n        this.cleanup = config.cleanup;\n    }\n\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        return tokens.map((token, i) => {\n            if (i !== 0) {\n                if (token.startsWith(this.config.prefix)) {\n                    // NOTE: .replace() is intended; only replace first occurrence\n                    token = token.replace(this.config.prefix, '');\n                } else {\n                    token = ' ' + token;\n                }\n            }\n            if (this.cleanup) {\n                token = clean_up_tokenization(token);\n            }\n\n            return token;\n        });\n    }\n}\n\n/**\n * Byte-level decoder for tokenization output. Inherits from the `Decoder` class.\n * @extends Decoder\n */\nclass ByteLevelDecoder extends Decoder {\n    /**\n     * Create a `ByteLevelDecoder` object.\n     * @param {Object} config Configuration object.\n     */\n    byte_decoder: Record<string, any>;\n    text_decoder: TextDecoder;\n    end_of_word_suffix: string | null;\n\n    constructor(config: any) {\n        super(config as any);\n\n        this.byte_decoder = UNICODE_TO_BYTES;\n        this.text_decoder = new TextDecoder('utf-8', {\n            fatal: false,\n            ignoreBOM: true,\n        });\n\n        this.end_of_word_suffix = null;\n    }\n\n    /**\n     * Convert an array of tokens to string by decoding each byte.\n     * @param {string[]} tokens Array of tokens to be decoded.\n     * @returns {string} The decoded string.\n     */\n    convert_tokens_to_string(tokens: string[]) {\n        const text = tokens.join('');\n        const byteArray = new Uint8Array([...text].map((c) => this.byte_decoder[c]));\n        const decoded_text = this.text_decoder.decode(byteArray);\n        return decoded_text;\n    }\n\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        // TODO move to base class (like HF)\n        // tokens === filtered_tokens\n\n        // To avoid mixing byte-level and unicode for byte-level BPT\n        // we need to build string separately for added tokens and byte-level tokens\n        // cf. https://github.com/huggingface/transformers/issues/1133\n        const sub_texts = [];\n        let current_sub_text = [];\n        for (const token of tokens) {\n            // tokens sent here are already filtered, so we don't need to do this\n            // if (skip_special_tokens && this.all_special_ids.includes(token)) {\n            //     continue;\n            // }\n\n            if (this.added_tokens.find((x) => x.content === token) !== undefined) {\n                if (current_sub_text.length > 0) {\n                    sub_texts.push(this.convert_tokens_to_string(current_sub_text));\n                    current_sub_text = [];\n                }\n                sub_texts.push(token);\n            } else {\n                current_sub_text.push(token);\n            }\n        }\n        if (current_sub_text.length > 0) {\n            sub_texts.push(this.convert_tokens_to_string(current_sub_text));\n        }\n\n        // TODO add spaces_between_special_tokens and clean_up_tokenization_spaces options\n\n        return sub_texts;\n    }\n}\n\n/**\n * The CTC (Connectionist Temporal Classification) decoder.\n * See https://github.com/huggingface/tokenizers/blob/bb38f390a61883fc2f29d659af696f428d1cda6b/tokenizers/src/decoders/ctc.rs\n */\nclass CTCDecoder extends Decoder {\n    pad_token: string;\n    word_delimiter_token: string;\n    cleanup: boolean;\n\n    constructor(config: any) {\n        super(config as any);\n\n        this.pad_token = this.config.pad_token;\n        this.word_delimiter_token = this.config.word_delimiter_token;\n        this.cleanup = this.config.cleanup;\n    }\n    /**\n     * Converts a connectionist-temporal-classification (CTC) output tokens into a single string.\n     * @param {string[]} tokens Array of tokens to be decoded.\n     * @returns {string} The decoded string.\n     */\n    convert_tokens_to_string(tokens: string[]) {\n        if (tokens.length === 0) return '';\n\n        // group same tokens into non-repeating tokens in CTC style decoding\n        const grouped_tokens = [tokens[0]];\n        for (let i = 1; i < tokens.length; ++i) {\n            if (tokens[i] !== grouped_tokens.at(-1)) {\n                grouped_tokens.push(tokens[i]);\n            }\n        }\n\n        // filter self.pad_token which is used as CTC-blank token\n        const filtered_tokens = grouped_tokens.filter((token) => token !== this.pad_token);\n\n        let text = filtered_tokens.join('');\n        if (this.cleanup) {\n            // cleanup and replace delimiter token\n            text = clean_up_tokenization(text).replaceAll(this.word_delimiter_token, ' ').trim();\n        }\n        return text;\n    }\n\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        return [this.convert_tokens_to_string(tokens)];\n    }\n}\n\n/**\n * Apply a sequence of decoders.\n * @extends Decoder\n */\nclass DecoderSequence extends Decoder {\n    decoders: Decoder[];\n    /**\n     * Creates a new instance of DecoderSequence.\n     * @param {Object} config The configuration object.\n     * @param {Object[]} config.decoders The list of decoders to apply.\n     */\n    constructor(config: any) {\n        super(config as any);\n        this.decoders = config.decoders.map((x: any) => Decoder.fromConfig(x));\n    }\n\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        // Use reduce to apply each decoder to the tokens\n        return this.decoders.reduce((toks: any, decoder: any) => {\n            return decoder.decode_chain(toks);\n        }, tokens);\n    }\n}\n\nclass BPEDecoder extends Decoder {\n    suffix: string;\n    constructor(config: any) {\n        super(config as any);\n\n        this.suffix = this.config.suffix;\n    }\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        return tokens.map((token, i) => {\n            return token.replaceAll(this.suffix, i === tokens.length - 1 ? '' : ' ');\n        });\n    }\n}\n\n// Custom decoder for VITS\nclass VitsDecoder extends Decoder {\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        let decoded = '';\n        for (let i = 1; i < tokens.length; i += 2) {\n            decoded += tokens[i];\n        }\n        return [decoded];\n    }\n}\n\n/**\n * This PreTokenizer replaces spaces with the given replacement character, adds a prefix space if requested,\n * and returns a list of tokens.\n * @extends PreTokenizer\n */\nclass MetaspacePreTokenizer extends PreTokenizer {\n    /**\n     * @param {Object} config The configuration object for the MetaspacePreTokenizer.\n     * @param {boolean} config.add_prefix_space Whether to add a prefix space to the first token.\n     * @param {string} config.replacement The character to replace spaces with.\n     * @param {string} [config.str_rep=config.replacement] An optional string representation of the replacement character.\n     * @param {'first'|'never'|'always'} [config.prepend_scheme='always'] The metaspace prepending scheme.\n     */\n    addPrefixSpace: boolean;\n    replacement: string;\n    strRep: string;\n    prepend_scheme: string;\n    constructor(config: any) {\n        super();\n\n        this.addPrefixSpace = config.add_prefix_space;\n        this.replacement = config.replacement;\n        this.strRep = config.str_rep || this.replacement;\n        this.prepend_scheme = config.prepend_scheme ?? 'always';\n    }\n\n    /**\n     * This method takes a string, replaces spaces with the replacement character,\n     * adds a prefix space if requested, and returns a new list of tokens.\n     * @param {string} text The text to pre-tokenize.\n     * @param {Object} [options] The options for the pre-tokenization.\n     * @param {number} [options.section_index] The index of the section to pre-tokenize.\n     * @returns {string[]} A new list of pre-tokenized tokens.\n     */\n    pre_tokenize_text(text: string, { section_index = undefined } = {}) {\n        let normalized = text.replaceAll(' ', this.strRep);\n\n        if (\n            // We add a prefix space if:\n            //  (1) The addPrefixSpace option is enabled and the normalized\n            //      token does not already start with the replacement character.\n            this.addPrefixSpace &&\n            !normalized.startsWith(this.replacement) &&\n            // and (2) either:\n            //  (a) prepend_scheme is 'always'\n            //  (b) prepend_scheme is 'first' and this is the first section\n            (this.prepend_scheme === 'always' || (this.prepend_scheme === 'first' && section_index === 0))\n        ) {\n            normalized = this.strRep + normalized;\n        }\n        return [normalized];\n    }\n}\n\n/**\n * MetaspaceDecoder class extends the Decoder class and decodes Metaspace tokenization.\n * @extends Decoder\n */\nclass MetaspaceDecoder extends Decoder {\n    /**\n     * Constructs a new MetaspaceDecoder object.\n     * @param {Object} config The configuration object for the MetaspaceDecoder.\n     * @param {boolean} config.add_prefix_space Whether to add a prefix space to the decoded string.\n     * @param {string} config.replacement The string to replace spaces with.\n     */\n    addPrefixSpace: boolean;\n    replacement: string;\n    constructor(config: any) {\n        super(config as any);\n\n        this.addPrefixSpace = config.add_prefix_space;\n        this.replacement = config.replacement;\n    }\n\n    /** @type {Decoder['decode_chain']} */\n    decode_chain(tokens: string[]) {\n        const result = [];\n        for (let i = 0; i < tokens.length; ++i) {\n            let normalized = tokens[i].replaceAll(this.replacement, ' ');\n            if (this.addPrefixSpace && i == 0 && normalized.startsWith(' ')) {\n                normalized = normalized.substring(1);\n            }\n            result.push(normalized);\n        }\n        return result;\n    }\n}\n\n/**\n * A normalizer that applies a precompiled charsmap.\n * This is useful for applying complex normalizations in C++ and exposing them to JavaScript.\n * @extends Normalizer\n * @param {Object} config The configuration object for the Precompiled normalizer.\n * @param {Object} config.precompiled_charsmap The precompiled charsmap object.\n */\nclass Precompiled extends Normalizer {\n    charsmap: any;\n    /**\n     * Create a new instance of Precompiled normalizer.\n     * @param {Object} config The configuration object.\n     * @param {any} config.precompiled_charsmap Precompiled chars mapping.\n     */\n    constructor(config: any) {\n        super(config as any);\n        this.charsmap = config.precompiled_charsmap;\n    }\n\n    /**\n     * Normalizes the given text by applying the precompiled charsmap.\n     * @param {string} text The text to normalize.\n     * @returns {string} The normalized text.\n     */\n    normalize(text: string) {\n        // As stated in the sentencepiece normalization docs (https://github.com/google/sentencepiece/blob/master/doc/normalization.md#use-pre-defined-normalization-rule),\n        // there are 5 pre-defined normalization rules:\n        //  1. nmt_nfkc: NFKC normalization with some additional normalization around spaces. (default)\n        //  2. nfkc: original NFKC normalization.\n        //  3. nmt_nfkc_cf: nmt_nfkc + Unicode case folding (mostly lower casing)\n        //  4. nfkc_cf: nfkc + Unicode case folding.\n        //  5. identity: no normalization\n        //\n        // For now, we only implement the default (nmt_nfkc).\n        // See https://raw.githubusercontent.com/google/sentencepiece/master/data/nmt_nfkc.tsv for the full list of rules.\n        // TODO: detect when a different `this.charsmap` is used.\n\n        text = text.replace(/[\\u0001-\\u0008\\u000B\\u000E-\\u001F\\u007F\\u008F\\u009F]/gm, ''); // Remove control characters\n        text = text.replace(\n            /[\\u0009\\u000A\\u000C\\u000D\\u00A0\\u1680\\u2000-\\u200F\\u2028\\u2029\\u202F\\u205F\\u2581\\u3000\\uFEFF\\uFFFD]/gm,\n            '\\u0020',\n        ); // Replace certain characters with a space\n\n        if (text.includes('\\uFF5E')) {\n            // To match the sentencepiece implementation 100%, we must handle a very strange edge-case.\n            // For some reason, the \"Fullwidth Tilde\" character (\\uFF5E) should not be converted to the standard Tilde character (\\u007E).\n            // However, NFKC normalization does do this conversion. As a result, we split the string on the Fullwidth Tilde character,\n            // perform NFKC normalization on each substring, and then join them back together with the Fullwidth Tilde character.\n            const parts = text.split('\\uFF5E');\n            text = parts.map((part) => part.normalize('NFKC')).join('\\uFF5E');\n        } else {\n            text = text.normalize('NFKC');\n        }\n\n        return text;\n    }\n}\n\n/**\n * A pre-tokenizer that applies a sequence of pre-tokenizers to the input text.\n * @extends PreTokenizer\n */\nclass PreTokenizerSequence extends PreTokenizer {\n    /**\n     * Creates an instance of PreTokenizerSequence.\n     * @param {Object} config The configuration object for the pre-tokenizer sequence.\n     * @param {Object[]} config.pretokenizers An array of pre-tokenizer configurations.\n     */\n    tokenizers: any[];\n    config: any;\n    constructor(config: any) {\n        super();\n        this.tokenizers = config.pretokenizers.map((x: any) => PreTokenizer.fromConfig(x));\n        this.config = config;\n    }\n\n    /**\n     * Applies each pre-tokenizer in the sequence to the input text in turn.\n     * @param {string} text The text to pre-tokenize.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} The pre-tokenized text.\n     */\n    pre_tokenize_text(text: string, options: any) {\n        // Use reduce to apply each tokenizer to the text\n        return this.tokenizers.reduce(\n            (preTokenizedText: any, tokenizer: any) => {\n                return tokenizer.pre_tokenize(preTokenizedText, options);\n            },\n            [text],\n        );\n    }\n}\n\n/**\n * Splits on word boundaries (using the following regular expression: `\\w+|[^\\w\\s]+`).\n */\nclass WhitespacePreTokenizer extends PreTokenizer {\n    /**\n     * Creates an instance of WhitespacePreTokenizer.\n     * @param {Object} config The configuration object for the pre-tokenizer.\n     */\n    constructor(config: any) {\n        super();\n    }\n    /**\n     * Pre-tokenizes the input text by splitting it on word boundaries.\n     * @param {string} text The text to be pre-tokenized.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} An array of tokens produced by splitting the input text on whitespace.\n     */\n    pre_tokenize_text(text: string, options: any) {\n        return text.match(/\\w+|[^\\w\\s]+/g) || [];\n    }\n}\n\n/**\n * Splits a string of text by whitespace characters into individual tokens.\n * @extends PreTokenizer\n */\nclass WhitespaceSplit extends PreTokenizer {\n    /**\n     * Creates an instance of WhitespaceSplit.\n     * @param {Object} config The configuration object for the pre-tokenizer.\n     */\n    constructor(config: any) {\n        super();\n    }\n    /**\n     * Pre-tokenizes the input text by splitting it on whitespace characters.\n     * @param {string} text The text to be pre-tokenized.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} An array of tokens produced by splitting the input text on whitespace.\n     */\n    pre_tokenize_text(text: string, options: any) {\n        return whitespace_split(text);\n    }\n}\n\n// NOTE: `ReplacePreTokenizer` is custom (to support `BlenderbotSmallTokenizer`)\nclass ReplacePreTokenizer extends PreTokenizer {\n    /**\n     * @param {Object} config The configuration options for the pre-tokenizer.\n     * @param {Object} config.pattern The pattern used to split the text. Can be a string or a regex object.\n     * @param {string} config.content What to replace the pattern with.\n     */\n    pattern: any;\n    content: string;\n    config: {\n        pattern: any;\n        content: string;\n    };\n    constructor(config: any) {\n        super();\n        this.config = config;\n        this.pattern = createPattern(this.config.pattern);\n        this.content = this.config.content;\n    }\n\n    /**\n     * Pre-tokenizes the input text by replacing certain characters.\n     * @param {string} text The text to be pre-tokenized.\n     * @param {Object} [options] Additional options for the pre-tokenization logic.\n     * @returns {string[]} An array of tokens produced by replacing certain characters.\n     */\n    pre_tokenize_text(text: string, options: any) {\n        if (this.pattern === null) {\n            return [text];\n        }\n        return [text.replaceAll(this.pattern, this.config.content)];\n    }\n}\n\nconst SPECIAL_TOKEN_ATTRIBUTES = [\n    'bos_token',\n    'eos_token',\n    'unk_token',\n    'sep_token',\n    'pad_token',\n    'cls_token',\n    'mask_token',\n    // additional_special_tokens (TODO)\n];\n\n/**\n *\n * Helper function for padding values of an object, which are each arrays.\n * NOTE: No additional checks are made here for validity of arguments.\n * @param {Record<string, any[]>} item The input object.\n * @param {number} length The length to pad to.\n * @param {(key: string) => any} value_fn Determine the value to fill the array, based on its key.\n * @param {string} side Which side to pad the array.\n * @private\n */\nfunction padHelper(item: Record<string, any[]>, length: number, value_fn: (key: string) => any, side: string) {\n    for (const key of Object.keys(item)) {\n        const diff = length - item[key].length;\n        const value = value_fn(key);\n\n        const padData = new Array(diff).fill(value);\n        item[key] = side === 'right' ? mergeArrays(item[key], padData) : mergeArrays(padData, item[key]);\n    }\n}\n\n/**\n * Helper function for truncating values of an object, which are each arrays.\n * NOTE: No additional checks are made here for validity of arguments.\n * @param {Record<string, any[]>} item The input object.\n * @param {number} length The length to truncate to.\n * @private\n */\nfunction truncateHelper(item: Record<string, any[]>, length: number) {\n    // Setting .length to a lower value truncates the array in-place:\n    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length\n    for (const key of Object.keys(item)) {\n        item[key].length = length;\n    }\n}\n\n/**\n * @typedef {Object} Message\n * @property {string} role The role of the message (e.g., \"user\" or \"assistant\" or \"system\").\n * @property {string} content The content of the message.\n */\n\ntype Message = {\n    role: string;\n    content: string;\n};\n\nexport class PreTrainedTokenizer extends Callable {\n    return_token_type_ids = false;\n\n    padding_side = 'right';\n    /**\n     * Create a new PreTrainedTokenizer instance.\n     * @param {Object} tokenizerJSON The JSON of the tokenizer.\n     * @param {Object} tokenizerConfig The config of the tokenizer.\n     */\n    _tokenizer_config: any;\n    pre_tokenizer: any;\n    normalizer: any;\n    model: any;\n    post_processor: any;\n    decoder: any;\n    config: any;\n    special_tokens: string[];\n    added_tokens_regex: RegExp | null;\n    mask_token: string | undefined;\n    mask_token_id: number | undefined;\n    pad_token: string | undefined;\n    pad_token_id: number | undefined;\n    sep_token: string | undefined;\n    sep_token_id: number | undefined;\n    unk_token: string | undefined;\n    unk_token_id: number | undefined;\n    bos_token: string | undefined;\n    bos_token_id: number | undefined;\n    eos_token: string | undefined;\n    eos_token_id: number | undefined;\n    model_max_length: number | undefined;\n    remove_space: boolean;\n    clean_up_tokenization_spaces: boolean;\n    legacy: boolean;\n    chat_template: any;\n    _compiled_template_cache: Map<string, any>;\n    all_special_ids: number[];\n    added_tokens: AddedToken[];\n    additional_special_tokens: string[];\n    do_lowercase_and_remove_accent: boolean;\n    constructor(tokenizerJSON: any, tokenizerConfig: any) {\n        super();\n\n        this._tokenizer_config = tokenizerConfig;\n        // Construct parts of the tokenizer from the JSON\n        this.normalizer = Normalizer.fromConfig(tokenizerJSON.normalizer);\n        this.pre_tokenizer = PreTokenizer.fromConfig(tokenizerJSON.pre_tokenizer);\n        this.model = TokenizerModel.fromConfig(tokenizerJSON.model, tokenizerConfig);\n        this.post_processor = PostProcessor.fromConfig(tokenizerJSON.post_processor);\n        this.decoder = Decoder.fromConfig(tokenizerJSON.decoder);\n\n        // Add added_tokens to model\n        this.special_tokens = [];\n        this.all_special_ids = [];\n\n        /** @type {AddedToken[]} */\n        this.added_tokens = [];\n        for (const addedToken of tokenizerJSON.added_tokens) {\n            const token = new AddedToken(addedToken);\n            this.added_tokens.push(token);\n\n            this.model.tokens_to_ids.set(token.content, token.id);\n            this.model.vocab[token.id] = token.content;\n\n            if (token.special) {\n                this.special_tokens.push(token.content);\n                this.all_special_ids.push(token.id);\n            }\n        }\n\n        // Update additional_special_tokens\n        this.additional_special_tokens = tokenizerConfig.additional_special_tokens ?? [];\n        this.special_tokens.push(...this.additional_special_tokens);\n        this.special_tokens = [...new Set(this.special_tokens)]; // Remove duplicates\n\n        if (this.decoder) {\n            // Slight hack, but it prevents code duplication:\n            this.decoder.added_tokens = this.added_tokens;\n\n            // Another slight hack to add `end_of_word_suffix` (if present) to the decoder\n            // This is needed for cases where BPE model and ByteLevel decoder are used\n            // For more information, see https://github.com/huggingface/transformers.js/issues/74\n            // TODO: save this to the decoder when exporting?\n            this.decoder.end_of_word_suffix = this.model.end_of_word_suffix;\n        }\n\n        this.added_tokens_regex =\n            this.added_tokens.length > 0\n                ? new RegExp(\n                    this.added_tokens\n                        .slice()\n                        // Sort by length (desc) to avoid early partial matches\n                        .sort((a: any, b: any) => b.content.length - a.content.length)\n                        .map((x: any) => `${x.lstrip ? '\\\\s*' : ''}(${escapeRegExp(x.content)})${x.rstrip ? '\\\\s*' : ''}`)\n                        .join('|'),\n                )\n                : null;\n\n        // Set mask token if present (otherwise will be undefined, which is fine)\n        this.mask_token = this.getToken('mask_token');\n        this.mask_token_id = this.model.tokens_to_ids.get(this.mask_token);\n\n        this.pad_token = this.getToken('pad_token', 'eos_token');\n        this.pad_token_id = this.model.tokens_to_ids.get(this.pad_token);\n\n        this.sep_token = this.getToken('sep_token');\n        this.sep_token_id = this.model.tokens_to_ids.get(this.sep_token);\n\n        this.unk_token = this.getToken('unk_token');\n        this.unk_token_id = this.model.tokens_to_ids.get(this.unk_token);\n\n        this.bos_token = this.getToken('bos_token');\n        this.bos_token_id = this.model.tokens_to_ids.get(this.bos_token);\n\n        this.eos_token = this.getToken('eos_token');\n        this.eos_token_id = this.model.tokens_to_ids.get(this.eos_token);\n\n        this.model_max_length = tokenizerConfig.model_max_length;\n\n        /** @type {boolean} Whether or not to strip the text when tokenizing (removing excess spaces before and after the string). */\n        this.remove_space = tokenizerConfig.remove_space;\n\n        this.clean_up_tokenization_spaces = tokenizerConfig.clean_up_tokenization_spaces ?? true;\n        this.do_lowercase_and_remove_accent = tokenizerConfig.do_lowercase_and_remove_accent ?? false;\n\n        if (tokenizerConfig.padding_side) {\n            this.padding_side = tokenizerConfig.padding_side;\n        }\n\n        this.legacy = false;\n\n        this.chat_template = tokenizerConfig.chat_template ?? null;\n        if (Array.isArray(this.chat_template)) {\n            // Chat templates are stored as lists of dicts with fixed key names,\n            // we reconstruct that into a single dict while loading them.\n            const chat_template = Object.create(null);\n            for (const { name, template } of this.chat_template) {\n                if (typeof name !== 'string' || typeof template !== 'string') {\n                    throw new Error('Chat template must be a list of objects with \"name\" and \"template\" properties');\n                }\n                chat_template[name] = template;\n            }\n            this.chat_template = chat_template;\n        }\n        this._compiled_template_cache = new Map();\n    }\n\n    /**\n     * Returns the value of the first matching key in the tokenizer config object.\n     * @param {...string} keys One or more keys to search for in the tokenizer config object.\n     * @returns {string|null} The value associated with the first matching key, or null if no match is found.\n     * @throws {Error} If an object is found for a matching key and its __type property is not \"AddedToken\".\n     * @private\n     */\n    getToken(...keys: string[]) {\n        for (const key of keys) {\n            const item = this._tokenizer_config[key];\n\n            if (!item) continue;\n\n            if (typeof item === 'object') {\n                if (item.__type === 'AddedToken') {\n                    return item.content;\n                } else {\n                    throw Error(`Unknown token: ${item}`);\n                }\n            } else {\n                return item;\n            }\n        }\n        return null;\n    }\n\n    /**\n     * Loads a pre-trained tokenizer from the given `pretrained_model_name_or_path`.\n     *\n     * @param {string} pretrained_model_name_or_path The path to the pre-trained tokenizer.\n     * @param {PretrainedTokenizerOptions} options Additional options for loading the tokenizer.\n     *\n     * @throws {Error} Throws an error if the tokenizer.json or tokenizer_config.json files are not found in the `pretrained_model_name_or_path`.\n     * @returns {Promise<PreTrainedTokenizer>} A new instance of the `PreTrainedTokenizer` class.\n     */\n    static async from_pretrained(\n        pretrained_model_name_or_path: string,\n        {\n            progress_callback = null,\n            config = null,\n            cache_dir = null,\n            local_files_only = false,\n            revision = 'main',\n            legacy: boolean = false,\n        } = {},\n    ) {\n        const info = await loadTokenizer(pretrained_model_name_or_path, {\n            progress_callback,\n            config,\n            cache_dir,\n            local_files_only,\n            revision,\n            legacy: false,\n        });\n\n        // @ts-ignore\n        return new this(...info);\n    }\n\n    /**\n     * @typedef {number[]|number[][]|Tensor} BatchEncodingItem\n     *\n     * @typedef {Object} BatchEncoding Holds the output of the tokenizer's call function.\n     * @property {BatchEncodingItem} input_ids List of token ids to be fed to a model.\n     * @property {BatchEncodingItem} attention_mask List of indices specifying which tokens should be attended to by the model.\n     * @property {BatchEncodingItem} [token_type_ids] List of token type ids to be fed to a model.\n     */\n\n    /**\n     * Encode/tokenize the given text(s).\n     * @param {string|string[]} text The text to tokenize.\n     * @param {Object} options An optional object containing the following properties:\n     * @param {string|string[]} [options.text_pair=null] Optional second sequence to be encoded. If set, must be the same type as text.\n     * @param {boolean|'max_length'} [options.padding=false] Whether to pad the input sequences.\n     * @param {boolean} [options.add_special_tokens=true] Whether or not to add the special tokens associated with the corresponding model.\n     * @param {boolean} [options.truncation=null] Whether to truncate the input sequences.\n     * @param {number} [options.max_length=null] Maximum length of the returned list and optionally padding length.\n     * @param {boolean} [options.return_tensor=true] Whether to return the results as Tensors or arrays.\n     * @param {boolean} [options.return_token_type_ids=null] Whether to return the token type ids.\n     * @returns {BatchEncoding} Object to be passed to the model.\n     */\n    _call(\n        // Required positional arguments\n        text: string | string[],\n\n        // Optional keyword arguments\n        {\n            text_pair = null,\n            add_special_tokens = true,\n            padding = false,\n            truncation = null,\n            max_length = null,\n            return_tensor = true, // Different to HF\n            return_token_type_ids = null,\n        }: {\n            text_pair?: string | string[] | null;\n            add_special_tokens?: boolean;\n            padding?: boolean | 'max_length';\n            truncation?: boolean | null;\n            max_length?: number | null;\n            return_tensor?: boolean;\n            return_token_type_ids?: boolean | null;\n        } = {},\n    ) {\n        const isBatched = Array.isArray(text);\n\n        /** @type {EncodingSingle[]} */\n        let encodedTokens;\n\n        if (isBatched) {\n            if (text.length === 0) {\n                throw Error('text array must be non-empty');\n            }\n\n            if (text_pair !== null) {\n                if (!Array.isArray(text_pair)) {\n                    throw Error('text_pair must also be an array');\n                } else if (text.length !== text_pair.length) {\n                    throw Error('text and text_pair must have the same length');\n                }\n\n                encodedTokens = text.map((t, i) =>\n                    this._encode_plus(t, { text_pair: text_pair[i] as string | null, add_special_tokens, return_token_type_ids }),\n                );\n            } else {\n                encodedTokens = text.map((x: string) => this._encode_plus(x, { add_special_tokens, return_token_type_ids }));\n            }\n        } else {\n            if (text === null || text === undefined) {\n                throw Error('text may not be null or undefined');\n            }\n\n            if (Array.isArray(text_pair)) {\n                throw Error(\n                    'When specifying `text_pair`, since `text` is a string, `text_pair` must also be a string (i.e., not an array).',\n                );\n            }\n\n            // For single input, we just wrap in an array, and then unwrap later.\n            encodedTokens = [this._encode_plus(text, { text_pair, add_special_tokens, return_token_type_ids })];\n        }\n        // At this point, tokens is batched: [batch_size, tokens]\n        // However, array may be jagged. So, we pad to max_length\n\n        if (max_length === null) {\n            if (padding === 'max_length') {\n                (max_length as any) = this.model_max_length;\n            } else {\n                // Calculate max length from sequences\n                (max_length as any) = max(encodedTokens.map((x) => x.input_ids.length))[0];\n            }\n        } else {\n            if (!truncation) {\n                console.warn(\n                    `Truncation was not explicitly activated but \\`max_length\\` is provided a specific value, please use \\`truncation=true\\` to explicitly truncate examples to max length.`,\n                );\n            }\n        }\n\n        // Ensure it is less than model max length\n        max_length = Math.min((max_length as any), this.model_max_length ?? Infinity);\n\n        if (padding || truncation) {\n            // Perform padding and/or truncation\n            for (let i = 0; i < encodedTokens.length; ++i) {\n                if (encodedTokens[i].input_ids.length === max_length) {\n                    continue;\n                } else if (encodedTokens[i].input_ids.length > max_length) {\n                    // possibly truncate\n                    if (truncation) {\n                        truncateHelper((encodedTokens[i] as any), max_length);\n                    }\n                } else {\n                    // t.length < max_length\n                    // possibly pad\n                    if (padding) {\n                        padHelper(\n                            (encodedTokens[i] as any),\n                            max_length,\n                            (key) => (key === 'input_ids' ? this.pad_token_id : 0),\n                            this.padding_side,\n                        );\n                    }\n                }\n            }\n        }\n\n        const result: any = {};\n\n        if (return_tensor) {\n            if (!(padding && truncation)) {\n                // Not, guaranteed that all items have same length, so\n                // we perform additional check\n\n                if (\n                    encodedTokens.some((x: any) => {\n                        for (const key of Object.keys(x)) {\n                            if (x[key].length !== (encodedTokens as any)[0][key]?.length) {\n                                return true;\n                            }\n                        }\n                        return false;\n                    })\n                ) {\n                    throw Error(\n                        'Unable to create tensor, you should probably activate truncation and/or padding ' +\n                        \"with 'padding=true' and 'truncation=true' to have batched tensors with the same length.\",\n                    );\n                }\n            }\n\n            // Now we actually convert to tensor\n            // NOTE: In the same way as the python library, we return a batched tensor, regardless of\n            // whether we have a single input or multiple inputs.\n            const dims = [encodedTokens.length, encodedTokens[0].input_ids.length];\n            for (const key of Object.keys(encodedTokens[0])) {\n                result[key] = new Tensor(\n                    'int64',\n                    BigInt64Array.from((encodedTokens as any).flatMap((x: any) => x[key]).map(BigInt)),\n                    dims,\n                );\n            }\n        } else {\n            for (const key of Object.keys(encodedTokens[0])) {\n                result[key] = encodedTokens.map((x: any) => x[key]);\n            }\n\n            // If not returning a tensor, we match the input type\n            if (!isBatched) {\n                // Input was not batched, so we unwrap\n                for (const key of Object.keys(result)) {\n                    result[key] = result[key][0];\n                }\n            }\n        }\n\n        return /** @type {BatchEncoding} */ result;\n    }\n\n    /**\n     * Encodes a single text using the preprocessor pipeline of the tokenizer.\n     *\n     * @param {string|null} text The text to encode.\n     * @returns {string[]|null} The encoded tokens.\n     */\n    _encode_text(text: string | null): any[] | null {\n        if (text === null) return null;\n\n        // Actual function which does encoding, for a single text\n        // First, we take care of special tokens. Needed to avoid issues arising from\n        // normalization and/or pretokenization (which may not preserve special tokens)\n        const sections = this.added_tokens_regex ? text.split(this.added_tokens_regex).filter((x) => x) : [text];\n\n        const tokens = sections\n            .map((x: string, section_index: number) => {\n                const addedToken = this.added_tokens.find((t: AddedToken) => t.content === x);\n                if (addedToken !== undefined) {\n                    // Ignore added tokens\n                    return x;\n                } else {\n                    if (this.remove_space === true) {\n                        x = x.trim().split(/\\s+/).join(' ');\n                    }\n                    if (this.do_lowercase_and_remove_accent) {\n                        x = lowercase_and_remove_accent(x);\n                    }\n\n                    if (this.normalizer !== null) {\n                        x = this.normalizer(x);\n                    }\n\n                    // If, after normalization, this section is empty (e.g., trimming whitespace),\n                    // we return an empty array\n                    if (x.length === 0) {\n                        return [];\n                    }\n\n                    const sectionTokens =\n                        this.pre_tokenizer !== null\n                            ? this.pre_tokenizer(x, {\n                                section_index,\n                            })\n                            : [x];\n\n                    const tokens = this.model(sectionTokens);\n\n                    return tokens;\n                }\n            })\n            .flat();\n\n        return tokens;\n    }\n\n    /**\n     * Encodes a single text or a pair of texts using the model's tokenizer.\n     *\n     * @param {string} text The text to encode.\n     * @param {Object} options An optional object containing the following properties:\n     * @param {string} [options.text_pair=null] The optional second text to encode.\n     * @param {boolean} [options.add_special_tokens=true] Whether or not to add the special tokens associated with the corresponding model.\n     * @param {boolean} [options.return_token_type_ids=null] Whether to return token_type_ids.\n     * @returns {EncodingSingle} An object containing the encoded text.\n     * @private\n     */\n    _encode_plus(\n        text: string,\n        {\n            text_pair = null,\n            add_special_tokens = true,\n            return_token_type_ids = null,\n        }: {\n            text_pair?: string | null;\n            add_special_tokens?: boolean;\n            return_token_type_ids?: boolean | null;\n        } = {},\n    ) {\n        const { tokens, token_type_ids } = this._tokenize_helper(text, { pair: text_pair, add_special_tokens });\n\n        const input_ids = this.model.convert_tokens_to_ids(tokens);\n\n        const result: any = {\n            input_ids,\n            attention_mask: new Array(input_ids.length).fill(1),\n        };\n        if ((return_token_type_ids ?? this.return_token_type_ids) && token_type_ids) {\n            result.token_type_ids = token_type_ids;\n        }\n        return result;\n    }\n\n    /**\n     * Internal helper function to tokenize a text, and optionally a pair of texts.\n     * @param {string} text The text to tokenize.\n     * @param {Object} options An optional object containing the following properties:\n     * @param {string} [options.pair=null] The optional second text to tokenize.\n     * @param {boolean} [options.add_special_tokens=false] Whether or not to add the special tokens associated with the corresponding model.\n     * @returns {{tokens: string[], token_type_ids?: number[]}} An object containing the tokens and optionally the token type IDs.\n     */\n    _tokenize_helper(\n        text: string,\n        {\n            pair = null,\n            add_special_tokens = false,\n        }: {\n            pair?: string | null;\n            add_special_tokens?: boolean;\n        } = {},\n    ) {\n        const tokens = this._encode_text(text);\n        const tokens2 = this._encode_text(pair);\n\n        return this.post_processor\n            ? this.post_processor(tokens, tokens2, { add_special_tokens })\n            : { tokens: mergeArrays(tokens ?? [], tokens2 ?? []) };\n    }\n\n    /**\n     * Converts a string into a sequence of tokens.\n     * @param {string} text The sequence to be encoded.\n     * @param {Object} options An optional object containing the following properties:\n     * @param {string} [options.pair] A second sequence to be encoded with the first.\n     * @param {boolean} [options.add_special_tokens=false] Whether or not to add the special tokens associated with the corresponding model.\n     * @returns {string[]} The list of tokens.\n     */\n    tokenize(text: string, { pair = null, add_special_tokens = false } = {}) {\n        return this._tokenize_helper(text, { pair, add_special_tokens }).tokens;\n    }\n\n    /**\n     * Encodes a single text or a pair of texts using the model's tokenizer.\n     *\n     * @param {string} text The text to encode.\n     * @param {Object} options An optional object containing the following properties:\n     * @param {string} [options.text_pair=null] The optional second text to encode.\n     * @param {boolean} [options.add_special_tokens=true] Whether or not to add the special tokens associated with the corresponding model.\n     * @param {boolean} [options.return_token_type_ids=null] Whether to return token_type_ids.\n     * @returns {number[]} An array of token IDs representing the encoded text(s).\n     */\n    encode(text: string, { text_pair = null, add_special_tokens = true, return_token_type_ids = null } = {}) {\n        return this._encode_plus(text, {\n            text_pair,\n            add_special_tokens,\n            return_token_type_ids,\n        }).input_ids;\n    }\n\n    /**\n     * Decode a batch of tokenized sequences.\n     * @param {number[][]|Tensor} batch List/Tensor of tokenized input sequences.\n     * @param {Object} decode_args (Optional) Object with decoding arguments.\n     * @returns {string[]} List of decoded sequences.\n     */\n    batch_decode(batch: number[][] | Tensor, decode_args = {}) {\n        if (batch instanceof Tensor) {\n            batch = batch.tolist();\n        }\n        return batch.map((x) => this.decode(x, decode_args));\n    }\n\n    /**\n     * Decodes a sequence of token IDs back to a string.\n     *\n     * @param {number[]|bigint[]|Tensor} token_ids List/Tensor of token IDs to decode.\n     * @param {Object} [decode_args={}]\n     * @param {boolean} [decode_args.skip_special_tokens=false] If true, special tokens are removed from the output string.\n     * @param {boolean} [decode_args.clean_up_tokenization_spaces=true] If true, spaces before punctuations and abbreviated forms are removed.\n     *\n     * @returns {string} The decoded string.\n     * @throws {Error} If `token_ids` is not a non-empty array of integers.\n     */\n    decode(token_ids: number[] | bigint[] | Tensor, decode_args = {}) {\n        if (token_ids instanceof Tensor) {\n            token_ids = prepareTensorForDecode(token_ids);\n        }\n\n        if (!Array.isArray(token_ids) || token_ids.length === 0 || !isIntegralNumber(token_ids[0])) {\n            throw Error('token_ids must be a non-empty array of integers.');\n        }\n\n        return this.decode_single(token_ids, decode_args);\n    }\n\n    /**\n     * Decode a single list of token ids to a string.\n     * @param {number[]|bigint[]} token_ids List of token ids to decode\n     * @param {Object} decode_args Optional arguments for decoding\n     * @param {boolean} [decode_args.skip_special_tokens=false] Whether to skip special tokens during decoding\n     * @param {boolean} [decode_args.clean_up_tokenization_spaces=null] Whether to clean up tokenization spaces during decoding.\n     * If null, the value is set to `this.decoder.cleanup` if it exists, falling back to `this.clean_up_tokenization_spaces` if it exists, falling back to `true`.\n     * @returns {string} The decoded string\n     */\n    decode_single(\n        token_ids: number[] | bigint[] | Tensor,\n        { skip_special_tokens = false, clean_up_tokenization_spaces = null },\n    ) {\n        let tokens = this.model.convert_ids_to_tokens(token_ids);\n        if (skip_special_tokens) {\n            tokens = tokens.filter((x: string) => !this.special_tokens.includes(x));\n        }\n\n        // If `this.decoder` is null, we just join tokens with a space:\n        // https://github.com/huggingface/tokenizers/blob/8edec536a737cb04494b454805be16c020abb14f/tokenizers/src/tokenizer/mod.rs#L835\n        /** @type {string} */\n        let decoded = this.decoder ? this.decoder(tokens) : tokens.join(' ');\n\n        // Slight hack, but prevents having to pass `skip_special_tokens` to\n        // each call to `decode`, which would lead to code duplication.\n        if (this.decoder && this.decoder.end_of_word_suffix) {\n            decoded = decoded.replaceAll(this.decoder.end_of_word_suffix, ' ');\n            if (skip_special_tokens) {\n                decoded = decoded.trim();\n            }\n        }\n\n        if (clean_up_tokenization_spaces ?? this.clean_up_tokenization_spaces) {\n            decoded = clean_up_tokenization(decoded);\n        }\n\n        return decoded;\n    }\n\n    /**\n     * Retrieve the chat template string used for tokenizing chat messages. This template is used\n     * internally by the `apply_chat_template` method and can also be used externally to retrieve the model's chat\n     * template for better generation tracking.\n     *\n     * @param {Object} options An optional object containing the following properties:\n     * @param {string} [options.chat_template=null]\n     * A Jinja template or the name of a template to use for this conversion.\n     * It is usually not necessary to pass anything to this argument,\n     * as the model's template will be used by default.\n     * @param {Object[]} [options.tools=null]\n     * A list of tools (callable functions) that will be accessible to the model. If the template does not\n     * support function calling, this argument will have no effect. Each tool should be passed as a JSON Schema,\n     * giving the name, description and argument types for the tool. See our\n     * [chat templating guide](https://huggingface.co/docs/transformers/main/en/chat_templating#automated-function-conversion-for-tool-use)\n     * for more information.\n     * @returns {string} The chat template string.\n     */\n    get_chat_template({ chat_template = null, tools = null } = {}) {\n        // First, handle the cases when the model has a dict of multiple templates\n        if (this.chat_template && typeof this.chat_template === 'object') {\n            const template_dict = this.chat_template;\n\n            if (chat_template !== null && Object.hasOwn(template_dict, chat_template)) {\n                // The user can pass the name of a template to the chat template argument instead of an entire template\n                chat_template = template_dict[chat_template];\n            } else if (chat_template === null) {\n                if (tools !== null && 'tool_use' in template_dict) {\n                    chat_template = template_dict['tool_use'];\n                } else if ('default' in template_dict) {\n                    chat_template = template_dict['default'];\n                } else {\n                    throw Error(\n                        `This model has multiple chat templates with no default specified! Please either pass a chat ` +\n                        `template or the name of the template you wish to use to the 'chat_template' argument. Available ` +\n                        `template names are ${Object.keys(template_dict).sort()}.`,\n                    );\n                }\n            }\n        } else if (chat_template === null) {\n            // These are the cases when the model has a single template\n            // priority: `chat_template` argument > `tokenizer.chat_template`\n            if (this.chat_template) {\n                chat_template = this.chat_template;\n            } else {\n                throw Error(\n                    'Cannot use apply_chat_template() because tokenizer.chat_template is not set and no template ' +\n                    'argument was passed! For information about writing templates and setting the ' +\n                    'tokenizer.chat_template attribute, please see the documentation at ' +\n                    'https://huggingface.co/docs/transformers/main/en/chat_templating',\n                );\n            }\n        }\n        return chat_template;\n    }\n\n    /**\n     * Converts a list of message objects with `\"role\"` and `\"content\"` keys to a list of token\n     * ids. This method is intended for use with chat models, and will read the tokenizer's chat_template attribute to\n     * determine the format and control tokens to use when converting.\n     *\n     * See [here](https://huggingface.co/docs/transformers/chat_templating) for more information.\n     *\n     * **Example:** Applying a chat template to a conversation.\n     *\n     * ```javascript\n     * import { AutoTokenizer } from \"@huggingface/transformers\";\n     *\n     * const tokenizer = await AutoTokenizer.from_pretrained(\"Xenova/mistral-tokenizer-v1\");\n     *\n     * const chat = [\n     *   { \"role\": \"user\", \"content\": \"Hello, how are you?\" },\n     *   { \"role\": \"assistant\", \"content\": \"I'm doing great. How can I help you today?\" },\n     *   { \"role\": \"user\", \"content\": \"I'd like to show off how chat templating works!\" },\n     * ]\n     *\n     * const text = tokenizer.apply_chat_template(chat, { tokenize: false });\n     * // \"<s>[INST] Hello, how are you? [/INST]I'm doing great. How can I help you today?</s> [INST] I'd like to show off how chat templating works! [/INST]\"\n     *\n     * const input_ids = tokenizer.apply_chat_template(chat, { tokenize: true, return_tensor: false });\n     * // [1, 733, 16289, 28793, 22557, 28725, 910, 460, 368, 28804, 733, 28748, 16289, 28793, 28737, 28742, 28719, 2548, 1598, 28723, 1602, 541, 315, 1316, 368, 3154, 28804, 2, 28705, 733, 16289, 28793, 315, 28742, 28715, 737, 298, 1347, 805, 910, 10706, 5752, 1077, 3791, 28808, 733, 28748, 16289, 28793]\n     * ```\n     *\n     * @param {Message[]} conversation A list of message objects with `\"role\"` and `\"content\"` keys,\n     * representing the chat history so far.\n     * @param {Object} options An optional object containing the following properties:\n     * @param {string} [options.chat_template=null] A Jinja template to use for this conversion. If\n     * this is not passed, the model's chat template will be used instead.\n     * @param {Object[]} [options.tools=null]\n     * A list of tools (callable functions) that will be accessible to the model. If the template does not\n     * support function calling, this argument will have no effect. Each tool should be passed as a JSON Schema,\n     * giving the name, description and argument types for the tool. See our\n     * [chat templating guide](https://huggingface.co/docs/transformers/main/en/chat_templating#automated-function-conversion-for-tool-use)\n     * for more information.\n     * @param {Record<string, string>[]} [options.documents=null]\n     * A list of dicts representing documents that will be accessible to the model if it is performing RAG\n     * (retrieval-augmented generation). If the template does not support RAG, this argument will have no\n     * effect. We recommend that each document should be a dict containing \"title\" and \"text\" keys. Please\n     * see the RAG section of the [chat templating guide](https://huggingface.co/docs/transformers/main/en/chat_templating#arguments-for-RAG)\n     * for examples of passing documents with chat templates.\n     * @param {boolean} [options.add_generation_prompt=false] Whether to end the prompt with the token(s) that indicate\n     * the start of an assistant message. This is useful when you want to generate a response from the model.\n     * Note that this argument will be passed to the chat template, and so it must be supported in the\n     * template for this argument to have any effect.\n     * @param {boolean} [options.tokenize=true] Whether to tokenize the output. If false, the output will be a string.\n     * @param {boolean} [options.padding=false] Whether to pad sequences to the maximum length. Has no effect if tokenize is false.\n     * @param {boolean} [options.truncation=false] Whether to truncate sequences to the maximum length. Has no effect if tokenize is false.\n     * @param {number} [options.max_length=null] Maximum length (in tokens) to use for padding or truncation. Has no effect if tokenize is false.\n     * If not specified, the tokenizer's `max_length` attribute will be used as a default.\n     * @param {boolean} [options.return_tensor=true] Whether to return the output as a Tensor or an Array. Has no effect if tokenize is false.\n     * @param {boolean} [options.return_dict=true] Whether to return a dictionary with named outputs. Has no effect if tokenize is false.\n     * @param {Object} [options.tokenizer_kwargs={}] Additional options to pass to the tokenizer.\n     * @returns {string | Tensor | number[]| number[][]|BatchEncoding} The tokenized output.\n     */\n    apply_chat_template(\n        conversation: Message[],\n        {\n            tools = null,\n            documents = null,\n            chat_template = null,\n            add_generation_prompt = false,\n            tokenize = true,\n            padding = false,\n            truncation = false,\n            max_length = null,\n            return_tensor = true,\n            return_dict = false,\n            tokenizer_kwargs = {},\n            ...kwargs\n        } = {},\n    ) {\n        chat_template = this.get_chat_template({ chat_template, tools });\n\n        if (typeof chat_template !== 'string') {\n            throw Error(`chat_template must be a string, but got ${typeof chat_template}`);\n        }\n\n        // Compilation function uses a cache to avoid recompiling the same template\n        let compiledTemplate = this._compiled_template_cache.get(chat_template);\n        if (compiledTemplate === undefined) {\n            compiledTemplate = new Template(chat_template);\n            this._compiled_template_cache.set(chat_template, compiledTemplate);\n        }\n\n        const special_tokens_map = Object.create(null);\n        for (const key of SPECIAL_TOKEN_ATTRIBUTES) {\n            const value = this.getToken(key);\n            if (value) {\n                special_tokens_map[key] = value;\n            }\n        }\n\n        const rendered = compiledTemplate.render({\n            messages: conversation,\n            add_generation_prompt,\n            tools,\n            documents,\n            ...special_tokens_map,\n            ...kwargs,\n        });\n\n        if (tokenize) {\n            const out = this._call(rendered, {\n                add_special_tokens: false,\n                padding,\n                truncation,\n                max_length,\n                return_tensor,\n                ...tokenizer_kwargs,\n            });\n            return return_dict ? out : (out as { input_ids: any }).input_ids;\n        }\n\n        return rendered;\n    }\n}\n\n/**\n * BertTokenizer is a class used to tokenize text for BERT models.\n * @extends PreTrainedTokenizer\n */\nexport class BertTokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n}\n/**\n * Albert tokenizer\n * @extends PreTrainedTokenizer\n */\nexport class AlbertTokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n}\nexport class MobileBertTokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n}\nexport class SqueezeBertTokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n}\nexport class DebertaTokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n}\nexport class DebertaV2Tokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n}\nexport class HerbertTokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n}\nexport class ConvBertTokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n}\nexport class RoFormerTokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n}\nexport class DistilBertTokenizer extends PreTrainedTokenizer { }\nexport class CamembertTokenizer extends PreTrainedTokenizer { }\nexport class XLMTokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n\n    constructor(tokenizerJSON: any, tokenizerConfig: any) {\n        super(tokenizerJSON, tokenizerConfig);\n        console.warn(\n            'WARNING: `XLMTokenizer` is not yet supported by Hugging Face\\'s \"fast\" tokenizers library. Therefore, you may experience slightly inaccurate results.',\n        );\n    }\n}\nexport class ElectraTokenizer extends PreTrainedTokenizer {\n    return_token_type_ids = true;\n}\n\nexport class T5Tokenizer extends PreTrainedTokenizer { }\nexport class GPT2Tokenizer extends PreTrainedTokenizer { }\nexport class BartTokenizer extends PreTrainedTokenizer { }\nexport class MBartTokenizer extends PreTrainedTokenizer {\n    languageRegex: RegExp;\n    language_codes: string[];\n    lang_to_token: (x: string) => string;\n\n    constructor(tokenizerJSON: any, tokenizerConfig: any) {\n        super(tokenizerJSON, tokenizerConfig);\n\n        this.languageRegex = /^[a-z]{2}_[A-Z]{2}$/;\n        this.language_codes = this.special_tokens.filter((x) => this.languageRegex.test(x));\n        this.lang_to_token = (x) => x; // Identity function\n    }\n\n    /**\n     * Helper function to build translation inputs for an `MBartTokenizer`.\n     * @param {string|string[]} raw_inputs The text to tokenize.\n     * @param {Object} tokenizer_options Options to be sent to the tokenizer\n     * @param {Object} generate_kwargs Generation options.\n     * @returns {Object} Object to be passed to the model.\n     */\n    _build_translation_inputs(raw_inputs: string | string[], tokenizer_options: any, generate_kwargs: any) {\n        return _build_translation_inputs(this, raw_inputs, tokenizer_options, generate_kwargs);\n    }\n}\nexport class MBart50Tokenizer extends MBartTokenizer { } // NOTE: extends MBartTokenizer\n\nexport class RobertaTokenizer extends PreTrainedTokenizer { }\n\nexport class BloomTokenizer extends PreTrainedTokenizer { }\n\nconst SPIECE_UNDERLINE = '▁';\n\nexport class LlamaTokenizer extends PreTrainedTokenizer {\n    padding_side = 'left';\n\n    constructor(tokenizerJSON: any, tokenizerConfig: any) {\n        super(tokenizerJSON, tokenizerConfig);\n\n        this.legacy = tokenizerConfig.legacy ?? true;\n        if (!this.legacy) {\n            // See https://github.com/huggingface/transformers/pull/24565 for more information\n            this.normalizer = null;\n            this.pre_tokenizer = new MetaspacePreTokenizer({\n                replacement: SPIECE_UNDERLINE,\n                add_prefix_space: true,\n                prepend_scheme: 'first',\n            });\n        }\n    }\n\n    /**\n     * Helper function to handle legacy encoding of SPM tokenizers.\n     * Adapted from https://github.com/huggingface/transformers/blob/e6dcf8abd6f65bb4b6dfc1831b20d9ba49ce00e2/src/transformers/models/t5/tokenization_t5.py#L374-L387\n     * @param {string} text The text to encode.\n     * @returns {string[]} The encoded tokens.\n     */\n    _encode_text(text: string | null) {\n        if (text === null) return null;\n\n        if (this.legacy || text.length === 0) {\n            return super._encode_text(text);\n        }\n\n        let tokens = super._encode_text(SPIECE_UNDERLINE + text.replaceAll(SPIECE_UNDERLINE, ' ')) ?? [];\n        if (tokens.length > 1 && tokens[0] === SPIECE_UNDERLINE && this.special_tokens.includes(tokens[1])) {\n            tokens = tokens.slice(1);\n        }\n        return tokens;\n    }\n}\nexport class CodeLlamaTokenizer extends PreTrainedTokenizer { }\n\nexport class XLMRobertaTokenizer extends PreTrainedTokenizer { }\nexport class MPNetTokenizer extends PreTrainedTokenizer { }\n\nexport class FalconTokenizer extends PreTrainedTokenizer { }\n\nexport class GPTNeoXTokenizer extends PreTrainedTokenizer { }\n\nexport class EsmTokenizer extends PreTrainedTokenizer { }\n\nexport class Qwen2Tokenizer extends PreTrainedTokenizer { }\n\nexport class GemmaTokenizer extends PreTrainedTokenizer { }\n\nexport class Grok1Tokenizer extends PreTrainedTokenizer { }\n\n/**\n * Helper function to build translation inputs for an `NllbTokenizer` or `M2M100Tokenizer`.\n * @param {PreTrainedTokenizer} self The tokenizer instance.\n * @param {string|string[]} raw_inputs The text to tokenize.\n * @param {Object} tokenizer_options Options to be sent to the tokenizer\n * @param {Object} generate_kwargs Generation options.\n * @returns {Object} Object to be passed to the model.\n * @private\n */\nfunction _build_translation_inputs(self: any, raw_inputs: any, tokenizer_options: any, generate_kwargs: any) {\n    if (!('language_codes' in self) || !Array.isArray(self.language_codes)) {\n        throw new Error('Tokenizer must have `language_codes` attribute set and it should be an array of language ids.');\n    }\n    if (!('languageRegex' in self) || !(self.languageRegex instanceof RegExp)) {\n        throw new Error('Tokenizer must have `languageRegex` attribute set and it should be a regular expression.');\n    }\n    if (!('lang_to_token' in self) || typeof self.lang_to_token !== 'function') {\n        throw new Error('Tokenizer must have `lang_to_token` attribute set and it should be a function.');\n    }\n    const src_lang_token = generate_kwargs.src_lang;\n    const tgt_lang_token = generate_kwargs.tgt_lang;\n\n    // Check that the target language is valid:\n    if (!self.language_codes.includes(tgt_lang_token)) {\n        throw new Error(\n            `Target language code \"${tgt_lang_token}\" is not valid. Must be one of: {${self.language_codes.join(', ')}}`,\n        );\n    }\n\n    // Allow `src_lang` to be optional. If not set, we'll use the tokenizer's default.\n    if (src_lang_token !== undefined) {\n        // Check that the source language is valid:\n        if (!self.language_codes.includes(src_lang_token)) {\n            throw new Error(\n                `Source language code \"${src_lang_token}\" is not valid. Must be one of: {${self.language_codes.join(', ')}}`,\n            );\n        }\n\n        // In the same way as the Python library, we override the post-processor\n        // to force the source language to be first:\n        for (const item of self.post_processor.config.single) {\n            if ('SpecialToken' in item && self.languageRegex.test(item.SpecialToken.id)) {\n                item.SpecialToken.id = self.lang_to_token(src_lang_token);\n                break;\n            }\n        }\n        // TODO: Do the same for pair?\n    }\n\n    // Override the `forced_bos_token_id` to force the correct language\n    generate_kwargs.forced_bos_token_id = self.model.convert_tokens_to_ids([self.lang_to_token(tgt_lang_token)])[0];\n\n    return self._call(raw_inputs, tokenizer_options);\n}\n\n/**\n * The NllbTokenizer class is used to tokenize text for NLLB (\"No Language Left Behind\") models.\n *\n * No Language Left Behind (NLLB) is a first-of-its-kind, AI breakthrough project\n * that open-sources models capable of delivering high-quality translations directly\n * between any pair of 200+ languages — including low-resource languages like Asturian,\n * Luganda, Urdu and more. It aims to help people communicate with anyone, anywhere,\n * regardless of their language preferences. For more information, check out their\n * [paper](https://arxiv.org/abs/2207.04672).\n *\n * For a list of supported languages (along with their language codes),\n * @see {@link https://github.com/facebookresearch/flores/blob/main/flores200/README.md#languages-in-flores-200}\n */\nexport class NllbTokenizer extends PreTrainedTokenizer {\n    languageRegex: RegExp;\n    language_codes: string[];\n    lang_to_token: (x: string) => string;\n\n    constructor(tokenizerJSON: any, tokenizerConfig: any) {\n        super(tokenizerJSON, tokenizerConfig);\n\n        this.languageRegex = /^[a-z]{3}_[A-Z][a-z]{3}$/;\n        this.language_codes = (this as any).special_tokens.filter((x: string) => this.languageRegex.test(x));\n        this.lang_to_token = (x) => x; // Identity function\n    }\n\n    /**\n     * Helper function to build translation inputs for an `NllbTokenizer`.\n     * @param {string|string[]} raw_inputs The text to tokenize.\n     * @param {Object} tokenizer_options Options to be sent to the tokenizer\n     * @param {Object} generate_kwargs Generation options.\n     * @returns {Object} Object to be passed to the model.\n     */\n    _build_translation_inputs(raw_inputs: any, tokenizer_options: any, generate_kwargs: any) {\n        return _build_translation_inputs(this, raw_inputs, tokenizer_options, generate_kwargs);\n    }\n}\n\n/**\n * The M2M100Tokenizer class is used to tokenize text for M2M100 (\"Many-to-Many\") models.\n *\n * M2M100 is a multilingual encoder-decoder (seq-to-seq) model trained for Many-to-Many\n * multilingual translation. It was introduced in this [paper](https://arxiv.org/abs/2010.11125)\n * and first released in [this](https://github.com/pytorch/fairseq/tree/master/examples/m2m_100) repository.\n *\n * For a list of supported languages (along with their language codes),\n * @see {@link https://huggingface.co/facebook/m2m100_418M#languages-covered}\n */\nexport class M2M100Tokenizer extends PreTrainedTokenizer {\n    languageRegex: RegExp;\n    language_codes: string[];\n    lang_to_token: (x: string) => string;\n\n    constructor(tokenizerJSON: any, tokenizerConfig: any) {\n        super(tokenizerJSON, tokenizerConfig);\n\n        this.languageRegex = /^__[a-z]{2,3}__$/;\n        this.language_codes = (this as any).special_tokens\n            .filter((x: string) => this.languageRegex.test(x))\n            .map((x: string) => x.slice(2, -2));\n        this.lang_to_token = (x: string) => `__${x}__`;\n    }\n\n    /**\n     * Helper function to build translation inputs for an `M2M100Tokenizer`.\n     * @param {string|string[]} raw_inputs The text to tokenize.\n     * @param {Object} tokenizer_options Options to be sent to the tokenizer\n     * @param {Object} generate_kwargs Generation options.\n     * @returns {Object} Object to be passed to the model.\n     */\n    _build_translation_inputs(raw_inputs: any, tokenizer_options: any, generate_kwargs: any) {\n        return _build_translation_inputs(this, raw_inputs, tokenizer_options, generate_kwargs);\n    }\n}\n\n/**\n * WhisperTokenizer tokenizer\n * @extends PreTrainedTokenizer\n */\nexport class WhisperTokenizer extends PreTrainedTokenizer {\n    get timestamp_begin() {\n        return (this as any).model.convert_tokens_to_ids(['<|notimestamps|>'])[0] + 1;\n    }\n\n    /**\n     * Decodes automatic speech recognition (ASR) sequences.\n     * @param {Array<{tokens: bigint[], token_timestamps?: number[], stride: number[]}>} sequences The sequences to decode.\n     * @param {Object} options The options to use for decoding.\n     * @returns {Array<string|{chunks?: undefined|Array<{language: string|null, timestamp: Array<number|null>, text: string}>}>} The decoded sequences.\n     */\n    _decode_asr(\n        sequences: { tokens: bigint[]; token_timestamps?: number[]; stride: number[] }[],\n        {\n            return_timestamps = null,\n            return_language = false,\n            time_precision = null,\n            force_full_sequences = true,\n        }: any = {},\n    ) {\n        // Set force_full_sequences=false if you want streaming\n        // TODO add support for `return_language`\n\n        // Internal method meant to only be used by asr pipeline.\n        // Handles all the little quirks specific to whisper to handle\n        // the various options not allowed in other seq2seq models\n\n        // =========== Overview ============\n        // - iterate over all outputs\n        // - all tokens within output\n        // - Each token can be\n        //   - language token\n        //   - special token\n        //   - timestamp token\n        //   - text token\n        // - We accumulate the text tokens.\n        // - We split on end timestamps\n        // - Lots of complexity comes from stride and timestamps\n\n        if (time_precision === null) {\n            throw Error('Must specify time_precision');\n        }\n        let last_language: string | null = null;\n\n        const returnWordTimestamps = return_timestamps === 'word';\n\n        function new_chunk() {\n            return { language: last_language, 'timestamp': [null, null], text: '', words: [] };\n        }\n\n        // Welcome to the state machine!\n        const chunks: any = [];\n        let chunk = new_chunk();\n        let time_offset = 0.0;\n        const timestamp_begin = this.timestamp_begin;\n        // Whisper timestamp tokens start from 0.00 and go to timestamp 30.00 in 0.02 increments.\n        // We can calculate the last time stamp token as timestamp_begin plus the number of tokens\n        // tokens from 0.00 to 30.00 which is 1500.\n        const total_timestamp_tokens = 1500; // (30.00 - 0.00) / 0.02\n        const timestamp_end = timestamp_begin + total_timestamp_tokens;\n\n        let previous_tokens: number[] = [];\n        let previous_token_timestamps: number[] = [];\n\n        let skip = false;\n        let right_stride_start = null;\n\n        const all_special_ids = new Set((this as any).all_special_ids);\n\n        for (const output of sequences) {\n            // NOTE: python version has batches, so it uses [0]\n            const token_ids = output.tokens;\n            const token_timestamps = returnWordTimestamps ? output.token_timestamps : null;\n\n            // These keep track of timestamps within strides, which need\n            // to be skipped and resolve all tokens in a single chunk.\n            let last_timestamp = null;\n            let first_timestamp = timestamp_begin;\n\n            if ('stride' in output) {\n                const [chunk_len, stride_left, stride_right] = output.stride;\n\n                // Offset the timings to account for the other `model_outputs`.\n                time_offset -= stride_left;\n                right_stride_start = chunk_len - stride_right;\n\n                // Keeping track of timestamps within strides\n                // We're going to NOT split on those, and delay until we're\n                // out of BOTH stride. Otherwise lots of issues occur and\n                // corner cases\n                if (stride_left) {\n                    first_timestamp = stride_left / time_precision + timestamp_begin;\n                }\n\n                if (stride_right) {\n                    for (let i = token_ids.length - 1; i >= 0; --i) {\n                        const token = Number(token_ids[i]);\n                        if (token >= timestamp_begin) {\n                            // There can be several token in the right stride\n                            // But the last one is ALWAYS going to be skipped\n                            if (last_timestamp !== null && (token - timestamp_begin) * time_precision < right_stride_start) {\n                                break;\n                            }\n                            last_timestamp = token;\n                        }\n                    }\n                }\n            }\n\n            let current_tokens: number[] = [];\n            let current_token_timestamps: any | null = null;\n\n            // - all tokens within output\n            for (let i = 0; i < token_ids.length; ++i) {\n                const token = Number(token_ids[i]);\n                // 4 possible states for each token\n                // - 1/ Language code\n                // - 2/ all other special tokens (which we ignore)\n                // - 3/ Timestamp\n                // - 4/ Regular text\n\n                if (all_special_ids.has(token)) {\n                    const text = this.decode([token]);\n                    const language = WHISPER_LANGUAGE_MAPPING.get(text.slice(2, -2));\n\n                    if (language !== undefined) {\n                        // 1/ Indeed some language\n                        // TODO Handle when language is different from the previous\n                        // one, and we cannot use timestamped tokens to create chunks\n                        if (last_language !== null && language !== last_language && !return_timestamps) {\n                            previous_tokens.push(...current_tokens);\n                            const resolved_tokens = this.findLongestCommonSequence([previous_tokens], null)[0];\n                            const resolved_text = this.decode(resolved_tokens ?? [], {});\n                            chunk.text = resolved_text;\n                            chunks.push(chunk);\n\n                            // Flush all our temporary context\n                            previous_tokens = [];\n                            current_tokens = [];\n                            chunk = new_chunk();\n                        }\n\n                        last_language = chunk.language = language as string;\n                    } else {\n                        // 2/ This is a regular special token, ignoring it\n                    }\n                } else if (token >= timestamp_begin && token <= timestamp_end) {\n                    // 3/ Timestamp token\n                    const time = (token - timestamp_begin) * time_precision + time_offset;\n                    const rounded_time = round(time, 2);\n\n                    if (last_timestamp !== null && token >= last_timestamp) {\n                        // Whisper outputted a timestamp token, but it falls within\n                        // our stride, so we're going to skip it for the time being\n                        // and resolve this later\n                        // Skip is necessary because timestamp tokens always come\n                        // by pair, so we need to skip the next one too (which would mark the start of another chunk).\n                        skip = true;\n                    } else if (skip || (previous_tokens.length > 0 && token < first_timestamp)) {\n                        skip = false;\n                    } else if (chunk.timestamp[0] === null) {\n                        chunk.timestamp[0] = rounded_time as any;\n                    } else {\n                        // This is the end of the timestamp chunk\n                        if (rounded_time === chunk.timestamp[0]) {\n                            // This is a bug in timestamp token output\n                            // where we're taking the duplicate token\n                            // as a stop where it should be a start.\n                            // This is an issue in the underlying model output\n                            // Let's just skip it so it becomes de-factor a start agin\n                        } else {\n                            chunk.timestamp[1] = rounded_time as any;\n\n                            // Handling merges\n                            previous_tokens.push(...current_tokens);\n\n                            if (returnWordTimestamps && current_token_timestamps) {\n                                previous_token_timestamps.push(...current_token_timestamps);\n                            }\n                            const [resolved_tokens, resolved_token_timestamps] = this.findLongestCommonSequence(\n                                [previous_tokens],\n                                [previous_token_timestamps],\n                            );\n\n                            const resolved_text = this.decode(resolved_tokens ?? [], {});\n                            chunk.text = resolved_text;\n\n                            if (returnWordTimestamps) {\n                                chunk.words = this.collateWordTimestamps(resolved_tokens ?? [], [resolved_token_timestamps ?? []], last_language as string);\n                            }\n\n                            chunks.push(chunk);\n\n                            // Flush all our temporary context\n                            previous_tokens = [];\n                            current_tokens = [];\n                            previous_token_timestamps = [];\n                            current_token_timestamps = [];\n                            chunk = new_chunk();\n                        }\n                    }\n                } else {\n                    // 4/ Regular token\n                    // We just append to the list of all tokens so we can handle\n                    // merges later and decode into text.\n                    current_tokens.push(token);\n\n                    if (returnWordTimestamps) {\n                        let start_time: number = round((token_timestamps as any)[i] + time_offset, 2);\n\n                        let end_time: number | null = null;\n                        if (i + 1 < (token_timestamps as any).length) {\n                            end_time = round((token_timestamps as any)[i + 1] + time_offset, 2);\n\n                            // Do not allow punctuation-only tokens to have a duration.\n                            // This prevents long pauses from messing up the timestamps.\n                            const decoded_text = this.decode([token], {});\n                            if (PUNCTUATION_ONLY_REGEX.test(decoded_text)) {\n                                // Add `time_precision` to avoid overlapping timestamps\n                                end_time = round(Math.min(start_time + time_precision, end_time), 2);\n                            }\n                        } else {\n                            // should never happen\n                            end_time = null;\n                        }\n                        current_token_timestamps.push([(start_time), end_time]);\n                    }\n                }\n            }\n\n            if ('stride' in output) {\n                const [chunk_len, stride_left, stride_right] = output.stride;\n                time_offset += chunk_len - stride_right;\n            }\n\n            // Leftover tokens\n            if (current_tokens.length > 0) {\n                previous_tokens.push(...current_tokens);\n                if (returnWordTimestamps && current_token_timestamps) {\n                    previous_token_timestamps.push(...current_token_timestamps);\n                }\n            } else if (previous_tokens.every((p) => (p as any).length === 0)) {\n                // Flushing previous tokens (END)\"\n                chunk = new_chunk();\n                previous_tokens = [];\n                current_tokens = [];\n                previous_token_timestamps = [];\n                current_token_timestamps = [];\n            }\n        }\n\n        if (previous_tokens.length > 0) {\n            if (force_full_sequences && return_timestamps) {\n                // Last token should always be timestamps, so there shouldn't be\n                // leftover\n                throw new Error(\n                    'Whisper did not predict an ending timestamp, which can happen if audio is cut off in the middle of a word. ' +\n                    'Also make sure WhisperTimeStampLogitsProcessor was used during generation.',\n                );\n            }\n\n            // Happens when we don't use timestamps\n            const [resolved_tokens, resolved_token_timestamps] = this.findLongestCommonSequence(\n                [previous_tokens],\n                [previous_token_timestamps],\n            );\n\n            // Flushing previous tokens (FINAL)\n            const resolved_text = this.decode((resolved_tokens as any), {});\n            chunk.text = resolved_text;\n            if (returnWordTimestamps) {\n                chunk.words = this.collateWordTimestamps((resolved_tokens as any), (resolved_token_timestamps as any), last_language as any);\n            }\n            chunks.push(chunk);\n        }\n\n        let optional = Object.create(null);\n\n        // Preparing and cleaning up the pipeline output\n        const full_text = chunks.map(((chunk: any) => chunk.text)).join('');\n        if (return_timestamps || return_language) {\n            for (let i = 0; i < chunks.length; ++i) {\n                const chunk = chunks[i];\n                if (!return_timestamps) {\n                    delete chunk['timestamp'];\n                }\n\n                if (!return_language) {\n                    delete chunk['language'];\n                }\n            }\n            if (returnWordTimestamps) {\n                const new_chunks: any = [];\n                for (const chunk of chunks) {\n                    for (const word of chunk.words) {\n                        new_chunks.push(word);\n                    }\n                }\n                optional = { chunks: new_chunks };\n            } else {\n                optional = { chunks: chunks };\n            }\n        }\n        return [full_text, optional];\n    }\n\n    /**\n     * Finds the longest common sequence among the provided sequences.\n     * @param {number[][]} sequences An array of sequences of token ids to compare.\n     * @returns {number[][]} The longest common sequence found.\n     * @throws {Error} If there is a bug within the function.\n     * @private\n     */\n    findLongestCommonSequence(sequences: number[][], token_timestamp_sequences: number[][] | null = null) {\n        // It would be much harder to do O(n) because of fault tolerance.\n        // We actually have a really good property which is that the total sequence\n        // MUST be those subsequences in order.\n        // If token_timestamp_sequences is provided, will split those sequences in\n        // exactly the same way.\n        let leftSequence = sequences[0];\n        let leftLength = leftSequence.length;\n        let totalSequence = [];\n\n        const use_token_timestamp_sequences =\n            Array.isArray(token_timestamp_sequences) && token_timestamp_sequences.length > 0;\n        let total_token_timestamp_sequence = use_token_timestamp_sequences ? [] : null;\n        let left_token_timestamp_sequence = use_token_timestamp_sequences ? token_timestamp_sequences[0] : null;\n        for (let i = 1; i < sequences.length; ++i) {\n            const rightSequence = sequences[i];\n            let max = 0.0;\n            let maxIndices = [leftLength, leftLength, 0, 0];\n            // Here we're sliding matches\n            // [a, b, c, d]\n            //          [c, d, f]\n            // =        [c] == [d]\n\n            // [a, b, c, d]\n            //       [c, d, f]\n            // =     [c, d] == [c, d]\n\n            // [a, b, c, d]\n            //    [c, d, f]\n\n            // =  [b, c, d] == [c, d, f]\n\n            // [a, b, c, d]\n            // [c, d, f]\n\n            // [a, b, c] == [c, d, f]\n\n            // [a, b, c, d]\n            // [d, f]\n\n            // [a, b] == [d, f]\n\n            // [a, b, c, d]\n            // [f]\n\n            // [a] == [f]\n\n            const rightLength = rightSequence.length;\n            for (let j = 1; j < leftLength + rightLength; ++j) {\n                // Slightly convoluted because we don't want out of bound indices\n                // This will be necessary for a small conflict resolution optimization\n                // later\n                const leftStart = Math.max(0, leftLength - j);\n                const leftStop = Math.min(leftLength, leftLength + rightLength - j);\n                const left = leftSequence.slice(leftStart, leftStop);\n                const rightStart = Math.max(0, j - leftLength);\n                const rightStop = Math.min(rightLength, j);\n                const right = rightSequence.slice(rightStart, rightStop);\n                if (left.length !== right.length) {\n                    throw new Error(\n                        'There is a bug within whisper `decode_asr` function, please report it. Dropping to prevent bad inference.',\n                    );\n                }\n\n                let matches;\n                if (use_token_timestamp_sequences) {\n                    // Get length of longest subsequence of tokens that match\n                    // and have timestamps that are in order\n                    matches = left.filter(\n                        (elem, idx) =>\n                            elem === right[idx] &&\n                            (left_token_timestamp_sequence as any)[leftStart + idx] <= (token_timestamp_sequences as any)[i][rightStart + idx],\n                    ).length;\n                } else {\n                    matches = left.filter((elem, idx) => elem === right[idx]).length;\n                }\n\n                // epsilon to favor long perfect matches\n                const eps = j / 10000.0;\n                const matching = matches / j + eps;\n                if (matches > 1 && matching > max) {\n                    max = matching;\n                    maxIndices = [leftStart, leftStop, rightStart, rightStop];\n                }\n            }\n            const [leftStart, leftStop, rightStart, rightStop] = maxIndices;\n            const leftMid = Math.floor((leftStop + leftStart) / 2);\n            const rightMid = Math.floor((rightStop + rightStart) / 2);\n            totalSequence.push(...leftSequence.slice(0, leftMid));\n            leftSequence = rightSequence.slice(rightMid);\n            leftLength = leftSequence.length;\n\n            if (use_token_timestamp_sequences) {\n                (total_token_timestamp_sequence as number[][]).push(...[left_token_timestamp_sequence?.slice(0, leftMid) ?? []]);\n                left_token_timestamp_sequence = token_timestamp_sequences[i].slice(rightMid);\n            }\n        }\n        totalSequence.push(...leftSequence);\n\n        if (use_token_timestamp_sequences) {\n            // Major change here\n            (total_token_timestamp_sequence as number[][]).push(...[left_token_timestamp_sequence ?? []]);\n            return [totalSequence, total_token_timestamp_sequence];\n        } else {\n            return [totalSequence, []];\n        }\n    }\n\n    /** @private */\n    collateWordTimestamps(tokens: number[], token_timestamps: number[][], language: string): any {\n        const [words, _, token_indices] = this.combineTokensIntoWords(tokens, language);\n\n        const timings = [];\n        for (let i = 0; i < words.length; ++i) {\n            const indices = token_indices[i];\n            timings.push({\n                text: words[i],\n                timestamp: [token_timestamps[(indices as any).at(0)][0], token_timestamps[(indices as any).at(-1)][1]],\n            });\n        }\n        return timings;\n    }\n\n    /**\n     * Groups tokens by word. Returns a tuple containing a list of strings with the words,\n     * and a list of `token_id` sequences with the tokens making up each word.\n     * @param {number[]} tokens\n     * @param {string} [language]\n     * @param {string} prepend_punctionations\n     * @param {string} append_punctuations\n     *\n     * @private\n     */\n    combineTokensIntoWords(\n        tokens: number[],\n        language: string,\n        prepend_punctionations = '\"\\'\"¡¿([{-',\n        append_punctuations = '\"\\'.。,，!！?？:：\"\")]}、',\n    ) {\n        language = language ?? 'english';\n\n        let words, word_tokens, token_indices;\n\n        if (['chinese', 'japanese', 'thai', 'lao', 'myanmar'].includes(language)) {\n            // These languages don't typically use spaces.\n            [words, word_tokens, token_indices] = this.splitTokensOnUnicode(tokens);\n        } else {\n            [words, word_tokens, token_indices] = this.splitTokensOnSpaces(tokens);\n        }\n\n        return this.mergePunctuations(words, word_tokens, token_indices, prepend_punctionations, append_punctuations);\n    }\n\n    /** @type {PreTrainedTokenizer['decode']} */\n    decode(token_ids: number[] | bigint[] | Tensor, decode_args: any = {}) {\n        let text;\n        // @ts-ignore\n        if (decode_args?.decode_with_timestamps) {\n            if (token_ids instanceof Tensor) {\n                token_ids = prepareTensorForDecode(token_ids);\n            }\n            text = this.decodeWithTimestamps(token_ids as number[], decode_args);\n        } else {\n            text = super.decode(token_ids, decode_args);\n        }\n        // TODO: implement offsets\n        // if (decode_args.output_offsets) {\n        //     let offsets = this.computeOffsets\n        // }\n        return text;\n    }\n\n    /**\n     * @param {number[]|bigint[]} token_ids List of token IDs to decode.\n     * @param {Object} decode_args Optional arguments for decoding\n     * @private\n     */\n    decodeWithTimestamps(token_ids: number[] | bigint[], decode_args: any) {\n        const time_precision = decode_args?.time_precision ?? 0.02;\n\n        const timestamp_begin = (Array.from(this.all_special_ids).at(-1) ?? 0) + 1;\n        /**@type {Array} */\n        let outputs = Array<any>();\n        for (let token of token_ids) {\n            token = Number(token);\n            if (token >= timestamp_begin) {\n                const timestamp = ((token - timestamp_begin) * time_precision).toFixed(2);\n                outputs.push(`<|${timestamp}|>`);\n                outputs.push([]);\n            } else {\n                outputs[outputs.length - 1].push(token);\n            }\n        }\n        outputs = outputs.map((s) => (typeof s === 'string' ? s : super.decode(s, decode_args)));\n\n        return outputs.join('');\n    }\n\n    /**\n     * Combine tokens into words by splitting at any position where the tokens are decoded as valid unicode points.\n     * @param {number[]} tokens\n     * @returns {*}\n     * @private\n     */\n    splitTokensOnUnicode(tokens: number[]) {\n        const decoded_full = this.decode(tokens, {\n            // @ts-ignore\n            decode_with_timestamps: true,\n        });\n        const replacement_char = '\\uFFFD';\n\n        const words = [];\n        const word_tokens = [];\n        const token_indices = [];\n        let current_tokens = [];\n        let current_indices = [];\n        let unicode_offset = 0;\n\n        for (let token_idx = 0; token_idx < tokens.length; ++token_idx) {\n            const token = tokens[token_idx];\n\n            current_tokens.push(token);\n            current_indices.push(token_idx);\n\n            const decoded = this.decode(current_tokens, {\n                // @ts-ignore\n                decode_with_timestamps: true,\n            });\n\n            if (\n                !decoded.includes(replacement_char) ||\n                decoded_full[unicode_offset + decoded.indexOf(replacement_char)] === replacement_char\n            ) {\n                words.push(decoded);\n                word_tokens.push(current_tokens);\n                token_indices.push(current_indices);\n                current_tokens = [];\n                current_indices = [];\n                unicode_offset += decoded.length;\n            }\n        }\n\n        return [words, word_tokens, token_indices];\n    }\n\n    /**\n     * Combine tokens into words by splitting at whitespace and punctuation tokens.\n     * @param {number[]} tokens\n     * @private\n     */\n    splitTokensOnSpaces(tokens: number[]) {\n        const [subwords, subword_tokens_list, subword_indices_list] = this.splitTokensOnUnicode(tokens);\n\n        const words = [];\n        const word_tokens = [];\n        const token_indices = [];\n\n        const punctuationRegex = new RegExp(`^[${PUNCTUATION_REGEX}]$`, 'gu');\n\n        for (let i = 0; i < subwords.length; ++i) {\n            const subword = subwords[i];\n            const subword_tokens = subword_tokens_list[i];\n            const subword_indices = subword_indices_list[i];\n\n            // @ts-ignore\n            const special = subword_tokens[0] >= this.model.tokens_to_ids.get('<|endoftext|>');\n            const with_space = subword.startsWith(' ');\n            const trimmed = subword.trim();\n            const punctuation = punctuationRegex.test(trimmed);\n\n            if (special || with_space || punctuation || words.length === 0) {\n                words.push(subword);\n                word_tokens.push(subword_tokens);\n                token_indices.push(subword_indices);\n            } else {\n                const ix = words.length - 1;\n                words[ix] += subword;\n                word_tokens[ix].push(...subword_tokens);\n                token_indices[ix].push(...subword_indices);\n            }\n        }\n\n        return [words, word_tokens, token_indices];\n    }\n\n    /**\n     * Merges punctuation tokens with neighboring words.\n     * @param {string[]} words\n     * @param {number[][]} tokens\n     * @param {number[][]} indices\n     * @param {string} prepended\n     * @param {string} appended\n     * @private\n     */\n    mergePunctuations(words: string[], tokens: number[][], indices: number[][], prepended: string, appended: string) {\n        const newWords = structuredClone(words);\n        const newTokens = structuredClone(tokens);\n        const newIndices = structuredClone(indices);\n\n        // prepend punctuations\n        let i = newWords.length - 2;\n        let j = newWords.length - 1;\n\n        while (i >= 0) {\n            if (newWords[i].startsWith(' ') && prepended.includes(newWords[i].trim())) {\n                newWords[j] = newWords[i] + newWords[j];\n                newTokens[j] = mergeArrays(newTokens[i], newTokens[j]);\n                newIndices[j] = mergeArrays(newIndices[i], newIndices[j]);\n                newWords[i] = '';\n                newTokens[i] = [];\n                newIndices[i] = [];\n            } else {\n                j = i;\n            }\n            --i;\n        }\n\n        // append punctuations\n        i = 0;\n        j = 1;\n        while (j < newWords.length) {\n            if (!newWords[i].endsWith(' ') && appended.includes(newWords[j])) {\n                newWords[i] += newWords[j];\n                newTokens[i] = mergeArrays(newTokens[i], newTokens[j]);\n                newIndices[i] = mergeArrays(newIndices[i], newIndices[j]);\n                newWords[j] = '';\n                newTokens[j] = [];\n                newIndices[j] = [];\n            } else {\n                i = j;\n            }\n            ++j;\n        }\n\n        return [newWords.filter((x) => x), newTokens.filter((x) => x.length > 0), newIndices.filter((x) => x.length > 0)];\n    }\n}\nexport class CodeGenTokenizer extends PreTrainedTokenizer { }\nexport class CLIPTokenizer extends PreTrainedTokenizer { }\nexport class SiglipTokenizer extends PreTrainedTokenizer { }\n\n/**\n * @todo This model is not yet supported by Hugging Face's \"fast\" tokenizers library (https://github.com/huggingface/tokenizers).\n * Therefore, this implementation (which is based on fast tokenizers) may produce slightly inaccurate results.\n */\nexport class MarianTokenizer extends PreTrainedTokenizer {\n    /**\n     * Create a new MarianTokenizer instance.\n     * @param {Object} tokenizerJSON The JSON of the tokenizer.\n     * @param {Object} tokenizerConfig The config of the tokenizer.\n     */\n    supported_language_codes: string[];\n    languageRegex: RegExp;\n    constructor(tokenizerJSON: any, tokenizerConfig: any) {\n        super(tokenizerJSON, tokenizerConfig);\n\n        this.languageRegex = /^(>>\\w+<<)\\s*/g;\n\n        this.supported_language_codes = this.model.vocab.filter((x: string) => this.languageRegex.test(x));\n\n        console.warn(\n            'WARNING: `MarianTokenizer` is not yet supported by Hugging Face\\'s \"fast\" tokenizers library. Therefore, you may experience slightly inaccurate results.',\n        );\n    }\n\n    /**\n     * Encodes a single text. Overriding this method is necessary since the language codes\n     * must be removed before encoding with sentencepiece model.\n     * @see https://github.com/huggingface/transformers/blob/12d51db243a00726a548a43cc333390ebae731e3/src/transformers/models/marian/tokenization_marian.py#L204-L213\n     *\n     * @param {string|null} text The text to encode.\n     * @returns {Array} The encoded tokens.\n     */\n    _encode_text(text: string | null): any {\n        if (text === null) return null;\n\n        // Check if text starts with language code:\n        const [matchInfo, ...remainder] = text.trim().split(this.languageRegex);\n\n        if (remainder.length === 0) {\n            // No language code, encode normally\n            return super._encode_text(matchInfo);\n        } else if (remainder.length === 2) {\n            // Text starts with language code, so we do not encode it with sentencepiece.\n            const [language, text] = remainder;\n\n            if (!this.supported_language_codes.includes(language)) {\n                console.warn(\n                    `Unsupported language code \"${language}\" detected, which may lead to unexpected behavior. Should be one of: ${JSON.stringify(this.supported_language_codes)}`,\n                );\n            }\n            return mergeArrays([language], (super._encode_text as any)(text));\n        }\n    }\n}\n\nexport class Wav2Vec2CTCTokenizer extends PreTrainedTokenizer { }\n\nexport class BlenderbotTokenizer extends PreTrainedTokenizer { }\nexport class BlenderbotSmallTokenizer extends PreTrainedTokenizer { }\n\nexport class SpeechT5Tokenizer extends PreTrainedTokenizer { }\n\nexport class NougatTokenizer extends PreTrainedTokenizer { }\n\nexport class VitsTokenizer extends PreTrainedTokenizer {\n    constructor(tokenizerJSON: any, tokenizerConfig: any) {\n        super(tokenizerJSON, tokenizerConfig);\n\n        // Custom decoder function\n        this.decoder = new VitsDecoder({});\n    }\n}\n\nexport class CohereTokenizer extends PreTrainedTokenizer { }\n\nexport class MgpstrTokenizer extends PreTrainedTokenizer { }\n\n/**\n * Helper class which is used to instantiate pretrained tokenizers with the `from_pretrained` function.\n * The chosen tokenizer class is determined by the type specified in the tokenizer config.\n *\n * @example\n * const tokenizer = await AutoTokenizer.from_pretrained('Xenova/bert-base-uncased');\n */\nexport class AutoTokenizer {\n    static TOKENIZER_CLASS_MAPPING = {\n        T5Tokenizer,\n        DistilBertTokenizer,\n        CamembertTokenizer,\n        DebertaTokenizer,\n        DebertaV2Tokenizer,\n        BertTokenizer,\n        HerbertTokenizer,\n        ConvBertTokenizer,\n        RoFormerTokenizer,\n        XLMTokenizer,\n        ElectraTokenizer,\n        MobileBertTokenizer,\n        SqueezeBertTokenizer,\n        AlbertTokenizer,\n        GPT2Tokenizer,\n        BartTokenizer,\n        MBartTokenizer,\n        MBart50Tokenizer,\n        RobertaTokenizer,\n        WhisperTokenizer,\n        CodeGenTokenizer,\n        CLIPTokenizer,\n        SiglipTokenizer,\n        MarianTokenizer,\n        BloomTokenizer,\n        NllbTokenizer,\n        M2M100Tokenizer,\n        LlamaTokenizer,\n        CodeLlamaTokenizer,\n        XLMRobertaTokenizer,\n        MPNetTokenizer,\n        FalconTokenizer,\n        GPTNeoXTokenizer,\n        EsmTokenizer,\n        Wav2Vec2CTCTokenizer,\n        BlenderbotTokenizer,\n        BlenderbotSmallTokenizer,\n        SpeechT5Tokenizer,\n        NougatTokenizer,\n        VitsTokenizer,\n        Qwen2Tokenizer,\n        GemmaTokenizer,\n        Grok1Tokenizer,\n        CohereTokenizer,\n        MgpstrTokenizer,\n\n        // Base case:\n        PreTrainedTokenizer,\n    };\n\n    /**\n     * Instantiate one of the tokenizer classes of the library from a pretrained model.\n     *\n     * The tokenizer class to instantiate is selected based on the `tokenizer_class` property of the config object\n     * (either passed as an argument or loaded from `pretrained_model_name_or_path` if possible)\n     *\n     * @param {string} pretrained_model_name_or_path The name or path of the pretrained model. Can be either:\n     * - A string, the *model id* of a pretrained tokenizer hosted inside a model repo on huggingface.co.\n     *   Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a\n     *   user or organization name, like `dbmdz/bert-base-german-cased`.\n     * - A path to a *directory* containing tokenizer files, e.g., `./my_model_directory/`.\n     * @param {PretrainedTokenizerOptions} options Additional options for loading the tokenizer.\n     *\n     * @returns {Promise<PreTrainedTokenizer>} A new instance of the PreTrainedTokenizer class.\n     */\n    static async from_pretrained(\n        pretrained_model_name_or_path: string,\n        {\n            progress_callback = null,\n            config = null,\n            cache_dir = null,\n            local_files_only = false,\n            revision = 'main',\n            legacy = undefined,\n        }: {\n            progress_callback?: null | ProgressCallback;\n            config?: null | PretrainedConfig;\n            cache_dir?: null | string;\n            local_files_only?: boolean;\n            revision?: string;\n            legacy?: boolean;\n        } = {},\n    ) {\n        const [tokenizerJSON, tokenizerConfig] = await loadTokenizer(pretrained_model_name_or_path, {\n            progress_callback,\n            config,\n            cache_dir,\n            local_files_only,\n            revision,\n            legacy,\n        });\n\n        // Some tokenizers are saved with the \"Fast\" suffix, so we remove that if present.\n        const tokenizerName = tokenizerConfig.tokenizer_class?.replace(/Fast$/, '') ?? 'PreTrainedTokenizer';\n\n        let cls = this.TOKENIZER_CLASS_MAPPING[tokenizerName as keyof typeof this.TOKENIZER_CLASS_MAPPING];\n        if (!cls) {\n            console.warn(`Unknown tokenizer class \"${tokenizerName}\", attempting to construct from base class.`);\n            cls = PreTrainedTokenizer;\n        }\n        return new cls(tokenizerJSON, tokenizerConfig);\n    }\n}\n","const WHISPER_LANGUAGES = [\n  ['en', 'english'],\n  ['zh', 'chinese'],\n  ['de', 'german'],\n  ['es', 'spanish'],\n  ['ru', 'russian'],\n  ['ko', 'korean'],\n  ['fr', 'french'],\n  ['ja', 'japanese'],\n  ['pt', 'portuguese'],\n  ['tr', 'turkish'],\n  ['pl', 'polish'],\n  ['ca', 'catalan'],\n  ['nl', 'dutch'],\n  ['ar', 'arabic'],\n  ['sv', 'swedish'],\n  ['it', 'italian'],\n  ['id', 'indonesian'],\n  ['hi', 'hindi'],\n  ['fi', 'finnish'],\n  ['vi', 'vietnamese'],\n  ['he', 'hebrew'],\n  ['uk', 'ukrainian'],\n  ['el', 'greek'],\n  ['ms', 'malay'],\n  ['cs', 'czech'],\n  ['ro', 'romanian'],\n  ['da', 'danish'],\n  ['hu', 'hungarian'],\n  ['ta', 'tamil'],\n  ['no', 'norwegian'],\n  ['th', 'thai'],\n  ['ur', 'urdu'],\n  ['hr', 'croatian'],\n  ['bg', 'bulgarian'],\n  ['lt', 'lithuanian'],\n  ['la', 'latin'],\n  ['mi', 'maori'],\n  ['ml', 'malayalam'],\n  ['cy', 'welsh'],\n  ['sk', 'slovak'],\n  ['te', 'telugu'],\n  ['fa', 'persian'],\n  ['lv', 'latvian'],\n  ['bn', 'bengali'],\n  ['sr', 'serbian'],\n  ['az', 'azerbaijani'],\n  ['sl', 'slovenian'],\n  ['kn', 'kannada'],\n  ['et', 'estonian'],\n  ['mk', 'macedonian'],\n  ['br', 'breton'],\n  ['eu', 'basque'],\n  ['is', 'icelandic'],\n  ['hy', 'armenian'],\n  ['ne', 'nepali'],\n  ['mn', 'mongolian'],\n  ['bs', 'bosnian'],\n  ['kk', 'kazakh'],\n  ['sq', 'albanian'],\n  ['sw', 'swahili'],\n  ['gl', 'galician'],\n  ['mr', 'marathi'],\n  ['pa', 'punjabi'],\n  ['si', 'sinhala'],\n  ['km', 'khmer'],\n  ['sn', 'shona'],\n  ['yo', 'yoruba'],\n  ['so', 'somali'],\n  ['af', 'afrikaans'],\n  ['oc', 'occitan'],\n  ['ka', 'georgian'],\n  ['be', 'belarusian'],\n  ['tg', 'tajik'],\n  ['sd', 'sindhi'],\n  ['gu', 'gujarati'],\n  ['am', 'amharic'],\n  ['yi', 'yiddish'],\n  ['lo', 'lao'],\n  ['uz', 'uzbek'],\n  ['fo', 'faroese'],\n  ['ht', 'haitian creole'],\n  ['ps', 'pashto'],\n  ['tk', 'turkmen'],\n  ['nn', 'nynorsk'],\n  ['mt', 'maltese'],\n  ['sa', 'sanskrit'],\n  ['lb', 'luxembourgish'],\n  ['my', 'myanmar'],\n  ['bo', 'tibetan'],\n  ['tl', 'tagalog'],\n  ['mg', 'malagasy'],\n  ['as', 'assamese'],\n  ['tt', 'tatar'],\n  ['haw', 'hawaiian'],\n  ['ln', 'lingala'],\n  ['ha', 'hausa'],\n  ['ba', 'bashkir'],\n  ['jw', 'javanese'],\n  ['su', 'sundanese'],\n];\n\n// @ts-ignore\nexport const WHISPER_LANGUAGE_MAPPING = new Map(WHISPER_LANGUAGES);\n// @ts-ignore\nexport const WHISPER_TO_LANGUAGE_CODE_MAPPING = new Map([\n  ...WHISPER_LANGUAGES.map(([k, v]) => [v, k]),\n  ...[\n    ['burmese', 'my'],\n    ['valencian', 'ca'],\n    ['flemish', 'nl'],\n    ['haitian', 'ht'],\n    ['letzeburgesch', 'lb'],\n    ['pushto', 'ps'],\n    ['panjabi', 'pa'],\n    ['moldavian', 'ro'],\n    ['moldovan', 'ro'],\n    ['sinhalese', 'si'],\n    ['castilian', 'es'],\n  ],\n]);\n\n/**\n * @param {string} language The language name or code\n * @returns {string} The language code\n */\nexport function whisper_language_to_code(language) {\n  language = language.toLowerCase();\n\n  // Map to code from user-friendly name (e.g., \"english\" -> \"en\")\n  let language_code = WHISPER_TO_LANGUAGE_CODE_MAPPING.get(language);\n\n  if (language_code === undefined) {\n    // User provided something that is not a language name\n\n    if (WHISPER_LANGUAGE_MAPPING.has(language)) {\n      // User provided the language code directly (e.g., \"en\")\n      language_code = language;\n    } else {\n      // User provided something that is not a language code or name\n      const is_language_code = language.length === 2;\n      const langs = is_language_code ? WHISPER_LANGUAGE_MAPPING.keys() : WHISPER_LANGUAGE_MAPPING.values();\n\n      throw new Error(`Language \"${language}\" is not supported. Must be one of: ${JSON.stringify(langs)}`);\n    }\n  }\n  return language_code;\n}\n","/**\n * @file Helper module for using model configs. For more information, see the corresponding\n * [Python documentation](https://huggingface.co/docs/transformers/main/en/model_doc/auto#transformers.AutoConfig).\n *\n * **Example:** Load an `AutoConfig`.\n *\n * ```javascript\n * import { AutoConfig } from '@huggingface/transformers';\n * const config = await AutoConfig.from_pretrained('bert-base-uncased');\n * console.log(config);\n * // PretrainedConfig {\n * //   \"model_type\": \"bert\",\n * //   \"is_encoder_decoder\": false,\n * //   \"architectures\": [\n * //       \"BertForMaskedLM\"\n * //   ],\n * //   \"vocab_size\": 30522\n * //   \"num_attention_heads\": 12,\n * //   \"num_hidden_layers\": 12,\n * //   \"hidden_size\": 768,\n * //   \"max_position_embeddings\": 512,\n * //   ...\n * // }\n * ```\n *\n * @module configs\n */\n\nimport { pick } from './utils/core';\nimport { getModelJSON, PretrainedOptions } from './utils/hub';\nimport { DataType, DeviceType } from './utils/dtypes';\n/**\n * @typedef {import('./utils/hub.js').PretrainedOptions} PretrainedOptions\n */\n\n/**\n * @typedef {import('./utils/core.js').ProgressCallback} ProgressCallback\n */\n\n/**\n * @typedef {import('./utils/core.js').ProgressInfo} ProgressInfo\n */\n\n/**\n * Loads a config from the specified path.\n * @param {string} pretrained_model_name_or_path The path to the config directory.\n * @param {PretrainedOptions} options Additional options for loading the config.\n * @returns {Promise<Object>} A promise that resolves with information about the loaded config.\n */\nasync function loadConfig(pretrained_model_name_or_path: string, options: PretrainedOptions) {\n  return await getModelJSON(pretrained_model_name_or_path, 'config.json', true, options);\n}\n\n/**\n *\n * @param {PretrainedConfig} config\n * @returns {Object} The normalized configuration.\n */\nfunction getNormalizedConfig(config: PretrainedConfig) {\n  const mapping: { [key: string]: string } = {};\n\n  let init_normalized_config = {};\n  switch (config.model_type as unknown as string) {\n    // Sub-configs\n    case 'llava':\n    case 'paligemma':\n    case 'florence2':\n    case 'llava_onevision':\n    case 'idefics3':\n      // @ts-expect-error TS2339\n      init_normalized_config = getNormalizedConfig(config.text_config);\n      break;\n    case 'moondream1':\n      // @ts-expect-error TS2339\n      init_normalized_config = getNormalizedConfig(config.phi_config);\n      break;\n    case 'musicgen':\n      // @ts-expect-error TS2339\n      init_normalized_config = getNormalizedConfig(config.decoder);\n      break;\n    case 'multi_modality':\n      // @ts-expect-error TS2339\n      init_normalized_config = getNormalizedConfig(config.language_config);\n      break;\n\n    // Decoder-only models\n    case 'gpt2':\n    case 'gptj':\n    case 'jais':\n    case 'codegen':\n    case 'gpt_bigcode':\n      mapping['num_heads'] = 'n_head';\n      mapping['num_layers'] = 'n_layer';\n      mapping['hidden_size'] = 'n_embd';\n      break;\n    case 'gpt_neox':\n    case 'stablelm':\n    case 'opt':\n    case 'falcon':\n      mapping['num_heads'] = 'num_attention_heads';\n      mapping['num_layers'] = 'num_hidden_layers';\n      mapping['hidden_size'] = 'hidden_size';\n      break;\n    case 'llama':\n    case 'olmo':\n    case 'olmo2':\n    case 'mobilellm':\n    case 'granite':\n    case 'cohere':\n    case 'mistral':\n    case 'starcoder2':\n    case 'qwen2':\n    case 'qwen2_vl':\n    case 'phi':\n    case 'phi3':\n    case 'phi3_v':\n      mapping['num_heads'] = 'num_key_value_heads';\n      mapping['num_layers'] = 'num_hidden_layers';\n      mapping['hidden_size'] = 'hidden_size';\n      mapping['num_attention_heads'] = 'num_attention_heads';\n      break;\n    case 'gemma':\n    case 'gemma2':\n      mapping['num_heads'] = 'num_key_value_heads';\n      mapping['num_layers'] = 'num_hidden_layers';\n      mapping['dim_kv'] = 'head_dim';\n      break;\n    case 'openelm':\n      mapping['num_heads'] = 'num_kv_heads';\n      mapping['num_layers'] = 'num_transformer_layers';\n      mapping['dim_kv'] = 'head_dim';\n      break;\n    case 'gpt_neo':\n    case 'donut-swin':\n      mapping['num_heads'] = 'num_heads';\n      mapping['num_layers'] = 'num_layers';\n      mapping['hidden_size'] = 'hidden_size';\n      break;\n    case 'bloom':\n      mapping['num_heads'] = 'n_head';\n      mapping['num_layers'] = 'n_layer';\n      mapping['hidden_size'] = 'hidden_size';\n      break;\n    case 'mpt':\n      mapping['num_heads'] = 'n_heads';\n      mapping['num_layers'] = 'n_layers';\n      mapping['hidden_size'] = 'd_model';\n      break;\n    case 'exaone':\n      mapping['num_heads'] = 'num_key_value_heads';\n      mapping['num_layers'] = 'num_layers';\n      mapping['dim_kv'] = 'head_dim';\n      mapping['num_attention_heads'] = 'num_attention_heads';\n      break;\n\n    // Encoder-decoder models\n    case 't5':\n    case 'mt5':\n    case 'longt5':\n      mapping['num_decoder_layers'] = 'num_decoder_layers';\n      mapping['num_decoder_heads'] = 'num_heads';\n      mapping['decoder_dim_kv'] = 'd_kv';\n      mapping['num_encoder_layers'] = 'num_layers';\n      mapping['num_encoder_heads'] = 'num_heads';\n      mapping['encoder_dim_kv'] = 'd_kv';\n      break;\n    case 'bart':\n    case 'mbart':\n    case 'marian':\n    case 'whisper':\n    case 'm2m_100':\n    case 'blenderbot':\n    case 'blenderbot-small':\n    case 'florence2_language':\n      mapping['num_decoder_layers'] = 'decoder_layers';\n      mapping['num_decoder_heads'] = 'decoder_attention_heads';\n      mapping['decoder_hidden_size'] = 'd_model';\n      mapping['num_encoder_layers'] = 'encoder_layers';\n      mapping['num_encoder_heads'] = 'encoder_attention_heads';\n      mapping['encoder_hidden_size'] = 'd_model';\n      break;\n    case 'speecht5':\n      mapping['num_decoder_layers'] = 'decoder_layers';\n      mapping['num_decoder_heads'] = 'decoder_attention_heads';\n      mapping['decoder_hidden_size'] = 'hidden_size';\n      mapping['num_encoder_layers'] = 'encoder_layers';\n      mapping['num_encoder_heads'] = 'encoder_attention_heads';\n      mapping['encoder_hidden_size'] = 'hidden_size';\n      break;\n    case 'trocr':\n      mapping['num_encoder_layers'] = mapping['num_decoder_layers'] = 'decoder_layers';\n      mapping['num_encoder_heads'] = mapping['num_decoder_heads'] = 'decoder_attention_heads';\n      mapping['encoder_hidden_size'] = mapping['decoder_hidden_size'] = 'd_model';\n      break;\n    case 'musicgen_decoder':\n    case 'moonshine':\n      mapping['num_encoder_layers'] = mapping['num_decoder_layers'] = 'num_hidden_layers';\n      mapping['num_encoder_heads'] = mapping['num_decoder_heads'] = 'num_attention_heads';\n      mapping['encoder_hidden_size'] = mapping['decoder_hidden_size'] = 'hidden_size';\n      break;\n\n    case 'vision-encoder-decoder':\n      // @ts-expect-error TS2339\n      const decoderConfig = getNormalizedConfig(config.decoder);\n\n      const add_encoder_pkv = 'num_decoder_layers' in decoderConfig;\n      const result: Record<string, unknown> = pick(config, ['model_type', 'is_encoder_decoder']);\n      if (add_encoder_pkv) {\n        // Decoder is part of an encoder-decoder model\n        result.num_decoder_layers = (decoderConfig as Record<string, unknown>).num_decoder_layers;\n        result.num_decoder_heads = (decoderConfig as Record<string, unknown>).num_decoder_heads;\n        result.decoder_hidden_size = (decoderConfig as Record<string, unknown>).decoder_hidden_size;\n\n        result.num_encoder_layers = (decoderConfig as Record<string, unknown>).num_encoder_layers;\n        result.num_encoder_heads = (decoderConfig as Record<string, unknown>).num_encoder_heads;\n        result.encoder_hidden_size = (decoderConfig as Record<string, unknown>).encoder_hidden_size;\n      } else {\n        // Decoder is a decoder-only model\n        result.num_layers = (decoderConfig as Record<string, unknown>).num_layers;\n        result.num_heads = (decoderConfig as Record<string, unknown>).num_heads;\n        result.hidden_size = (decoderConfig as Record<string, unknown>).hidden_size;\n      }\n      return result;\n  }\n\n  // NOTE: If `num_attention_heads` is not set, it is assumed to be equal to `num_heads`\n  const normalized_config: Record<string, any> = {\n    ...init_normalized_config,\n    ...pick(config, ['model_type', 'multi_query', 'is_encoder_decoder']),\n  };\n  for (const key in mapping) {\n    normalized_config[key] = (config as Record<string, any>)[mapping[key]];\n  }\n  return normalized_config;\n}\n\n/**\n *\n * @param {PretrainedConfig} config\n * @returns {Record<string, number[]>}\n */\nexport function getKeyValueShapes(config: PretrainedConfig, { prefix = 'past_key_values', batch_size = 1 } = {}) {\n  /** @type {Record<string, number[]>} */\n  const decoderFeeds: Record<string, number[]> = {};\n  const normalized_config = config.normalized_config;\n\n  if (\n    normalized_config.is_encoder_decoder &&\n    'num_encoder_heads' in normalized_config &&\n    'num_decoder_heads' in normalized_config\n  ) {\n    const encoder_dim_kv =\n      normalized_config.encoder_dim_kv ?? normalized_config.encoder_hidden_size / normalized_config.num_encoder_heads;\n    const decoder_dim_kv =\n      normalized_config.decoder_dim_kv ?? normalized_config.decoder_hidden_size / normalized_config.num_decoder_heads;\n\n    const encoder_dims = [batch_size, normalized_config.num_encoder_heads, 0, encoder_dim_kv];\n    const decoder_dims = [batch_size, normalized_config.num_decoder_heads, 0, decoder_dim_kv];\n    for (let i = 0; i < normalized_config.num_decoder_layers; ++i) {\n      decoderFeeds[`${prefix}.${i}.encoder.key`] = encoder_dims;\n      decoderFeeds[`${prefix}.${i}.encoder.value`] = encoder_dims;\n      decoderFeeds[`${prefix}.${i}.decoder.key`] = decoder_dims;\n      decoderFeeds[`${prefix}.${i}.decoder.value`] = decoder_dims;\n    }\n  } else {\n    // Decoders\n    const num_heads = normalized_config.num_heads;\n    const num_layers = normalized_config.num_layers;\n    const dim_kv =\n      normalized_config.dim_kv ?? normalized_config.hidden_size / (normalized_config.num_attention_heads ?? num_heads);\n\n    if (normalized_config.model_type === 'falcon') {\n      // NOTE: Custom implementation for Falcon\n      const dims = [batch_size * num_heads, 0, dim_kv];\n      for (let i = 0; i < num_layers; ++i) {\n        decoderFeeds[`${prefix}.${i}.key`] = dims;\n        decoderFeeds[`${prefix}.${i}.value`] = dims;\n      }\n    } else if (normalized_config.multi_query) {\n      // e.g., for `gpt_bigcode`\n      const dims = [batch_size * num_heads, 0, 2 * dim_kv];\n\n      for (let i = 0; i < num_layers; ++i) {\n        decoderFeeds[`${prefix}.${i}.key_value`] = dims;\n      }\n    } else if (normalized_config.model_type === 'bloom') {\n      // NOTE: Custom implementation for Bloom\n\n      const keyDims = [batch_size * num_heads, dim_kv, 0]; // [batch_size x num_heads,64,past_sequence_length]\n      const valueDims = [batch_size * num_heads, 0, dim_kv]; // [batch_size x num_heads,past_sequence_length,64]\n      for (let i = 0; i < num_layers; ++i) {\n        decoderFeeds[`${prefix}.${i}.key`] = keyDims;\n        decoderFeeds[`${prefix}.${i}.value`] = valueDims;\n      }\n    } else if (normalized_config.model_type === 'openelm') {\n      for (let i = 0; i < num_layers; ++i) {\n        const dims = [batch_size, num_heads[i], 0, dim_kv];\n\n        decoderFeeds[`${prefix}.${i}.key`] = dims;\n        decoderFeeds[`${prefix}.${i}.value`] = dims;\n      }\n    } else {\n      // Decoder-only\n      const dims = [batch_size, num_heads, 0, dim_kv];\n      for (let i = 0; i < num_layers; ++i) {\n        decoderFeeds[`${prefix}.${i}.key`] = dims;\n        decoderFeeds[`${prefix}.${i}.value`] = dims;\n      }\n    }\n  }\n\n  return decoderFeeds;\n}\n/**\n * Base class for all configuration classes. For more information, see the corresponding\n * [Python documentation](https://huggingface.co/docs/transformers/main/en/main_classes/configuration#transformers.PretrainedConfig).\n */\nexport class PretrainedConfig {\n  /** @type {string|null} */\n  model_type: string | null = null;\n\n  /** @type {boolean} */\n  is_encoder_decoder = false;\n\n  /** @type {boolean|undefined} */\n  multi_query?: boolean;\n\n  /** @type {number} */\n  max_position_embeddings!: number;\n\n  /** @type {TransformersJSConfig} */\n  transformers_js_config!: TransformersJSConfig;\n\n  /** @type {Record<string, any>} */\n  normalized_config!: Record<string, any>;\n\n  /**\n   * Create a new PreTrainedTokenizer instance.\n   * @param {Record<string, any>} configJSON The JSON of the config.\n   */\n  constructor(configJSON: Record<string, any>) {\n    Object.assign(this, configJSON);\n    this.normalized_config = getNormalizedConfig(this);\n  }\n\n  /**\n   * Loads a pre-trained config from the given `pretrained_model_name_or_path`.\n   *\n   * @param {string} pretrained_model_name_or_path The path to the pre-trained config.\n   * @param {PretrainedOptions} options Additional options for loading the config.\n   * @throws {Error} Throws an error if the config.json is not found in the `pretrained_model_name_or_path`.\n   *\n   * @returns {Promise<PretrainedConfig>} A new instance of the `PretrainedConfig` class.\n   */\n  static async from_pretrained(\n    pretrained_model_name_or_path: string,\n    {\n      progress_callback = null,\n      config = null as any,\n      cache_dir = null,\n      local_files_only = false,\n      revision = 'main',\n    } = {},\n  ) {\n    if (config && !(config instanceof PretrainedConfig)) {\n      config = new PretrainedConfig(config);\n    }\n\n    const data =\n      config ??\n      (await loadConfig(pretrained_model_name_or_path, {\n        progress_callback,\n        config,\n        cache_dir,\n        local_files_only,\n        revision,\n      }));\n    return new this(data);\n  }\n}\n\n/**\n * Helper class which is used to instantiate pretrained configs with the `from_pretrained` function.\n *\n * @example\n * const config = await AutoConfig.from_pretrained('Xenova/bert-base-uncased');\n */\nexport class AutoConfig {\n  /** @type {typeof PretrainedConfig.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any) {\n    return PretrainedConfig.from_pretrained(pretrained_model_name_or_path, options);\n  }\n}\n\n/**\n * Transformers.js-specific configuration, possibly present in config.json under the key `transformers.js_config`.\n * @typedef {Object} TransformersJSConfig\n * @property {import('./utils/tensor.js').DataType|Record<import('./utils/dtypes.js').DataType, import('./utils/tensor.js').DataType>} [kv_cache_dtype] The data type of the key-value cache.\n * @property {Record<string, number>} [free_dimension_overrides] Override the free dimensions of the model.\n * See https://onnxruntime.ai/docs/tutorials/web/env-flags-and-session-options.html#freedimensionoverrides\n * for more information.\n * @property {import('./utils/devices.js').DeviceType} [device] The default device to use for the model.\n * @property {import('./utils/dtypes.js').DataType|Record<string, import('./utils/dtypes.js').DataType>} [dtype] The default data type to use for the model.\n * @property {boolean|Record<string, boolean>} [use_external_data_format=false] Whether to load the model using the external data format (used for models >= 2GB in size).\n */\nexport type TransformersJSConfig = {\n  kv_cache_dtype?: Record<string, DataType> | DataType;\n  free_dimension_overrides?: Record<string, number>;\n  device?: DeviceType;\n  dtype?: DataType | Record<string, DataType>;\n  use_external_data_format?: boolean | Record<string, boolean>;\n};\n","/**\n * The list of devices supported by Transformers.js\n */\nexport const DEVICE_TYPES = Object.freeze({\n  auto: 'auto', // Auto-detect based on device and environment\n  gpu: 'gpu', // Auto-detect GPU\n  cpu: 'cpu', // CPU\n  wasm: 'wasm', // WebAssembly\n  webgpu: 'webgpu', // WebGPU\n  cuda: 'cuda', // CUDA\n  dml: 'dml', // DirectML\n\n  webnn: 'webnn', // WebNN (default)\n  'webnn-npu': 'webnn-npu', // WebNN NPU\n  'webnn-gpu': 'webnn-gpu', // WebNN GPU\n  'webnn-cpu': 'webnn-cpu', // WebNN CPU\n});\n\n/**\n * @typedef {keyof typeof DEVICE_TYPES} DeviceType\n */\n","/// <reference types=\"@webgpu/types\" />\n\nimport { apis } from '../env';\n\nimport { DEVICE_TYPES } from './devices';\n\n// TODO: Use the adapter from `env.backends.onnx.webgpu.adapter` to check for `shader-f16` support,\n// when available in https://github.com/microsoft/onnxruntime/pull/19940.\n// For more information, see https://github.com/microsoft/onnxruntime/pull/19857#issuecomment-1999984753\n\n/**\n * Checks if WebGPU fp16 support is available in the current environment.\n */\nexport const isWebGpuFp16Supported = (function () {\n  /** @type {boolean} */\n  let cachedResult: boolean | undefined;\n\n  return async function () {\n    if (cachedResult === undefined) {\n      if (!apis.IS_WEBGPU_AVAILABLE) {\n        cachedResult = false;\n      } else {\n        try {\n          const adapter = await navigator.gpu.requestAdapter();\n          if (!adapter) {\n            cachedResult = false;\n          } else {\n            cachedResult = adapter.features.has('shader-f16');\n          }\n        } catch (e) {\n          cachedResult = false;\n        }\n      }\n    }\n    return cachedResult;\n  };\n})();\n\nexport const DATA_TYPES = Object.freeze({\n  auto: 'auto', // Auto-detect based on environment\n  fp32: 'fp32',\n  fp16: 'fp16',\n  q8: 'q8',\n  int8: 'int8',\n  uint8: 'uint8',\n  q4: 'q4',\n  bnb4: 'bnb4',\n  q4f16: 'q4f16', // fp16 model with int4 block weight quantization\n});\n/** @typedef {keyof typeof DATA_TYPES} DataType */\n\nexport const DEFAULT_DEVICE_DTYPE_MAPPING = Object.freeze({\n  // NOTE: If not specified, will default to fp32\n  [DEVICE_TYPES.wasm]: DATA_TYPES.q8,\n});\n\n/** @type {Record<Exclude<DataType, \"auto\">, string>} */\nexport const DEFAULT_DTYPE_SUFFIX_MAPPING = Object.freeze({\n  [DATA_TYPES.fp32]: '',\n  [DATA_TYPES.fp16]: '_fp16',\n  [DATA_TYPES.int8]: '_int8',\n  [DATA_TYPES.uint8]: '_uint8',\n  [DATA_TYPES.q8]: '_quantized',\n  [DATA_TYPES.q4]: '_q4',\n  [DATA_TYPES.q4f16]: '_q4f16',\n  [DATA_TYPES.bnb4]: '_bnb4',\n});\n\nexport type DeviceType = keyof typeof DEVICE_TYPES;\nexport type DataType = keyof typeof DATA_TYPES;","export const GITHUB_ISSUE_URL = 'https://github.com/sauravpanda/browserai/issues';\n\nexport const CONFIG_NAME = 'config.json';\nexport const FEATURE_EXTRACTOR_NAME = 'preprocessor_config.json';\nexport const IMAGE_PROCESSOR_NAME = 'preprocessor_config.json';\n\nexport const PROCESSOR_NAME = 'processor_config.json';\nexport const CHAT_TEMPLATE_NAME = 'chat_template.json';\nexport const GENERATION_CONFIG_NAME = 'generation_config.json';\n","/**\n * @module generation/logits_process\n */\n\nimport { Callable } from '../utils/generic';\nimport { Tensor } from '../utils/tensor';\n\nimport { max, log_softmax } from '../utils/maths';\nimport { GenerationConfig } from './configuration_utils';\nimport { WhisperGenerationConfig } from '../models/whisper/generation_whisper';\n\n/**\n * Abstract base class for all logit processors that can be applied during generation.\n */\nexport class LogitsProcessor extends Callable {\n  /**\n   * Apply the processor to the input logits.\n   *\n   * @abstract\n   * @param {bigint[][]} input_ids The input ids.\n   * @param {Tensor} logits The logits to process.\n   * @throws {Error} Throws an error if `_call` is not implemented in the subclass.\n   */\n  _call(input_ids: bigint[][], logits: Tensor): Tensor {\n    throw Error('`_call` should be implemented in a subclass');\n  }\n}\n\n/**\n * Abstract base class for all logit warpers that can be applied during generation with multinomial sampling.\n */\nexport class LogitsWarper extends Callable {\n  /**\n   * Apply the processor to the input logits.\n   *\n   * @abstract\n   * @param {bigint[][]} input_ids The input ids.\n   * @param {Tensor} logits The logits to process.\n   * @throws {Error} Throws an error if `_call` is not implemented in the subclass.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    throw Error('`_call` should be implemented in a subclass');\n  }\n}\n\n/**\n * A class representing a list of logits processors. A logits processor is a function that modifies the logits\n * output of a language model. This class provides methods for adding new processors and applying all processors to a\n * batch of logits.\n */\nexport class LogitsProcessorList extends Callable {\n  /**\n   * Constructs a new instance of `LogitsProcessorList`.\n   */\n  private processors: LogitsProcessor[] = [];\n  constructor() {\n    super();\n    this.processors = [];\n  }\n\n  /**\n   * Adds a new logits processor to the list.\n   *\n   * @param {LogitsProcessor} item The logits processor function to add.\n   */\n  push(item: LogitsProcessor) {\n    this.processors.push(item);\n  }\n\n  /**\n   * Adds multiple logits processors to the list.\n   *\n   * @param {LogitsProcessor[]} items The logits processor functions to add.\n   */\n  extend(items: LogitsProcessor[]) {\n    this.processors.push(...items);\n  }\n\n  /**\n   * Applies all logits processors in the list to a batch of logits, modifying them in-place.\n   *\n   * @param {bigint[][]} input_ids The input IDs for the language model.\n   * @param {Tensor} logits\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    let toReturn = logits;\n    // NOTE: Most processors modify logits inplace\n    for (const processor of this.processors) {\n      toReturn = processor._call(input_ids, toReturn);\n    }\n    return toReturn;\n  }\n\n  [Symbol.iterator]() {\n    return this.processors.values();\n  }\n}\n\n// DEPRECATED: https://github.com/huggingface/transformers/pull/29485\n// /**\n//  * A logits processor that forces a specific token to be generated by the decoder.\n//  */\n// export class ForceTokensLogitsProcessor extends LogitsProcessor {\n//     /**\n//      * Constructs a new instance of `ForceTokensLogitsProcessor`.\n//      *\n//      * @param {[number, number][]} forced_decoder_ids The ids of tokens that should be forced.\n//      */\n//     constructor(forced_decoder_ids) {\n//         super();\n//         // TODO: convert to `new Map(forced_decoder_ids)`\n//         this.force_token_map = Object.fromEntries(forced_decoder_ids ?? []);\n//     }\n\n//     /**\n//      * Apply the processor to the input logits.\n//      *\n//      * @param {bigint[][]} input_ids The input ids.\n//      * @param {Tensor} logits The logits to process.\n//      * @returns {Tensor} The processed logits.\n//      */\n//     _call(input_ids, logits) {\n//         console.log('this.force_token_map', this.force_token_map)\n//         console.log('call ForceTokensLogitsProcessor', input_ids, logits)\n//         console.log('input_ids.length', input_ids.length)\n//         let map = this.force_token_map[input_ids.length];\n//         if (map) { // There exists a mapping\n//             logits.data.fill(-Infinity)\n//             logits.data[map] = 0;\n//         }\n//         console.log('map', map)\n//         // throw Error(\"Not implemented\")\n//         return logits;\n//     }\n// }\n\n/**\n * A LogitsProcessor that forces a BOS token at the beginning of the generated sequence.\n */\nexport class ForcedBOSTokenLogitsProcessor extends LogitsProcessor {\n  /**\n   * Create a ForcedBOSTokenLogitsProcessor.\n   * @param {number} bos_token_id The ID of the beginning-of-sequence token to be forced.\n   */\n  bos_token_id: number;\n  constructor(bos_token_id: number) {\n    super();\n    this.bos_token_id = bos_token_id;\n  }\n\n  /**\n   * Apply the BOS token forcing to the logits.\n   * @param {bigint[][]} input_ids The input IDs.\n   * @param {Tensor} logits The logits.\n   * @returns {Tensor} The logits with BOS token forcing.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    for (let i = 0; i < input_ids.length; ++i) {\n      if (input_ids[i].length === 1) {\n        const batch_logits_data = /** @type {Float32Array} */ logits[i].data;\n        (batch_logits_data as Float32Array).fill(-Infinity);\n        (batch_logits_data as Float32Array)[this.bos_token_id] = 0;\n      }\n    }\n    return logits;\n  }\n}\n\n/**\n * A logits processor that enforces the specified token as the last generated token when `max_length` is reached.\n */\nexport class ForcedEOSTokenLogitsProcessor extends LogitsProcessor {\n  max_length: number;\n  eos_token_id: number | number[];\n  /**\n   * Create a ForcedEOSTokenLogitsProcessor.\n   * @param {number} max_length The maximum length of the sequence to be generated.\n   * @param {number|number[]} eos_token_id The id(s) of the *end-of-sequence* token.\n   */\n  constructor(max_length: number, eos_token_id: number | number[]) {\n    super();\n    this.max_length = max_length;\n    this.eos_token_id = Array.isArray(eos_token_id) ? eos_token_id : [eos_token_id];\n  }\n\n  /**\n   * Apply the processor to input_ids and logits.\n   *\n   * @param {bigint[][]} input_ids The input ids.\n   * @param {Tensor} logits The logits tensor.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    for (let i = 0; i < input_ids.length; ++i) {\n      if (input_ids[i].length === this.max_length - 1) {\n        const batch_logits_data = /** @type {Float32Array} */ logits[i].data;\n        (batch_logits_data as Float32Array).fill(-Infinity);\n        for (const eos_token of Array.isArray(this.eos_token_id) ? this.eos_token_id : [this.eos_token_id]) {\n          (batch_logits_data as Float32Array)[eos_token] = 0;\n        }\n      }\n    }\n    return logits;\n  }\n}\n\n/**\n * A LogitsProcessor that suppresses a list of tokens as soon as the `generate` function starts\n * generating using `begin_index` tokens. This should ensure that the tokens defined by\n * `begin_suppress_tokens` at not sampled at the begining of the generation.\n */\nexport class SuppressTokensAtBeginLogitsProcessor extends LogitsProcessor {\n  begin_suppress_tokens: number[];\n  begin_index: number;\n\n  /**\n   * Create a SuppressTokensAtBeginLogitsProcessor.\n   * @param {number[]} begin_suppress_tokens The IDs of the tokens to suppress.\n   * @param {number} begin_index The number of tokens to generate before suppressing tokens.\n   */\n  constructor(begin_suppress_tokens: number[], begin_index: number) {\n    super();\n    this.begin_suppress_tokens = begin_suppress_tokens;\n    this.begin_index = begin_index;\n  }\n\n  /**\n   * Apply the BOS token forcing to the logits.\n   * @param {bigint[][]} input_ids The input IDs.\n   * @param {Tensor} logits The logits.\n   * @returns {Tensor} The logits with BOS token forcing.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    for (let i = 0; i < input_ids.length; ++i) {\n      if (input_ids[i].length === this.begin_index) {\n        const batch_logits_data = /** @type {Float32Array} */ logits[i].data;\n        for (const token_id of this.begin_suppress_tokens) {\n          batch_logits_data[token_id] = -Infinity;\n        }\n      }\n    }\n    return logits;\n  }\n}\n\n/**\n * A LogitsProcessor that handles adding timestamps to generated text.\n */\nexport class WhisperTimeStampLogitsProcessor extends LogitsProcessor {\n  /**\n   * Constructs a new WhisperTimeStampLogitsProcessor.\n   * @param {import('../models/whisper/generation_whisper.js').WhisperGenerationConfig} generate_config The config object passed to the `generate()` method of a transformer model.\n   * @param {number[]} init_tokens The initial tokens of the input sequence.\n   */\n  eos_token_id: number | number[];\n  no_timestamps_token_id: number | null;\n  timestamp_begin: number;\n  begin_index: number;\n  max_initial_timestamp_index: number;\n  constructor(generate_config: WhisperGenerationConfig, init_tokens: number[]) {\n    super();\n    this.eos_token_id = Array.isArray(generate_config.eos_token_id)\n      ? (generate_config.eos_token_id[0] ?? 0)\n      : (generate_config.eos_token_id ?? 0);\n\n    this.no_timestamps_token_id = generate_config.no_timestamps_token_id;\n    this.timestamp_begin = this.no_timestamps_token_id ? this.no_timestamps_token_id + 1 : 0;\n\n    this.begin_index = init_tokens.length;\n    if (init_tokens.at(-1) === this.no_timestamps_token_id) {\n      this.begin_index -= 1;\n    }\n    this.max_initial_timestamp_index = generate_config.max_initial_timestamp_index;\n  }\n\n  /**\n   * Modify the logits to handle timestamp tokens.\n   * @param {bigint[][]} input_ids The input sequence of tokens.\n   * @param {Tensor} logits The logits output by the model.\n   * @returns {Tensor} The modified logits.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    for (let i = 0; i < input_ids.length; ++i) {\n      const batch_logits_data = /** @type {Float32Array} */ logits[i].data;\n\n      // suppress <|notimestamps|> which is handled by without_timestamps\n      if (this.no_timestamps_token_id !== null) {\n        batch_logits_data[this.no_timestamps_token_id] = -Infinity;\n      }\n\n      if (input_ids[i].length === this.begin_index - 1) {\n        (batch_logits_data as Float32Array).fill(-Infinity);\n        (batch_logits_data as Float32Array)[this.timestamp_begin] = 0;\n        continue;\n      }\n\n      // timestamps have to appear in pairs, except directly before eos_token; mask logits accordingly\n      const seq = input_ids[i].slice(this.begin_index);\n      const last_was_timestamp = seq.length >= 1 && seq[seq.length - 1] >= this.timestamp_begin;\n      const penultimate_was_timestamp = seq.length < 2 || seq[seq.length - 2] >= this.timestamp_begin;\n\n      if (last_was_timestamp) {\n        if (penultimate_was_timestamp) {\n          // has to be non-timestamp\n          (batch_logits_data as Float32Array).subarray(this.timestamp_begin).fill(-Infinity);\n        } else {\n          // cannot be normal text tokens\n          const endToken = Array.isArray(this.eos_token_id) ? this.eos_token_id[0] : this.eos_token_id;\n          (batch_logits_data as Float32Array).subarray(0, endToken).fill(-Infinity);\n        }\n      }\n\n      // apply the `max_initial_timestamp` option\n      if (input_ids[i].length === this.begin_index && this.max_initial_timestamp_index !== null) {\n        const last_allowed = this.timestamp_begin + this.max_initial_timestamp_index;\n        (batch_logits_data as Float32Array).subarray(last_allowed + 1).fill(-Infinity);\n      }\n\n      // if sum of probability over timestamps is above any other token, sample timestamp\n      const logprobs = log_softmax(batch_logits_data as Float32Array);\n      const timestamp_logprob = Math.log(\n        (batch_logits_data as Float32Array)\n          .subarray(this.timestamp_begin)\n          .map(Math.exp)\n          .reduce((a, b) => a + b),\n      );\n      const max_text_token_logprob = max((logprobs as Float32Array).subarray(0, this.timestamp_begin))[0];\n\n      if (timestamp_logprob > max_text_token_logprob) {\n        (batch_logits_data as Float32Array).subarray(0, this.timestamp_begin).fill(-Infinity);\n      }\n    }\n\n    return logits;\n  }\n}\n\n/**\n * A logits processor that disallows ngrams of a certain size to be repeated.\n */\nexport class NoRepeatNGramLogitsProcessor extends LogitsProcessor {\n  /**\n   * Create a NoRepeatNGramLogitsProcessor.\n   * @param {number} no_repeat_ngram_size The no-repeat-ngram size. All ngrams of this size can only occur once.\n   */\n  no_repeat_ngram_size: number;\n  constructor(no_repeat_ngram_size: number) {\n    super();\n    this.no_repeat_ngram_size = no_repeat_ngram_size;\n  }\n\n  /**\n   * Generate n-grams from a sequence of token ids.\n   * @param {bigint[]} prevInputIds List of previous input ids\n   * @returns {Map<string, number[]>} Map of generated n-grams\n   */\n  getNgrams(prevInputIds: bigint[]) {\n    const curLen = prevInputIds.length;\n\n    /**@type {number[][]} */\n    const ngrams = [];\n    for (let j = 0; j < curLen + 1 - this.no_repeat_ngram_size; ++j) {\n      const ngram = [];\n      for (let k = 0; k < this.no_repeat_ngram_size; ++k) {\n        ngram.push(prevInputIds[j + k]);\n      }\n      ngrams.push(ngram.map(Number));\n    }\n\n    /** @type {Map<string, number[]>} */\n    const generatedNgram = new Map();\n    for (const ngram of ngrams) {\n      const prevNgram = ngram.slice(0, ngram.length - 1);\n      const prevNgramKey = JSON.stringify(prevNgram);\n      const prevNgramValue = generatedNgram.get(prevNgramKey) ?? [];\n      prevNgramValue.push(ngram[ngram.length - 1]);\n      generatedNgram.set(prevNgramKey, prevNgramValue);\n    }\n    return generatedNgram;\n  }\n\n  /**\n   * Generate n-grams from a sequence of token ids.\n   * @param {Map<string, number[]>} bannedNgrams Map of banned n-grams\n   * @param {bigint[]} prevInputIds List of previous input ids\n   * @returns {number[]} Map of generated n-grams\n   */\n  getGeneratedNgrams(bannedNgrams: Map<string, number[]>, prevInputIds: bigint[]) {\n    const ngramIdx = prevInputIds.slice(prevInputIds.length + 1 - this.no_repeat_ngram_size, prevInputIds.length);\n    const banned = bannedNgrams.get(JSON.stringify(ngramIdx.map(Number))) ?? [];\n    return banned;\n  }\n\n  /**\n   * Calculate banned n-gram tokens\n   * @param {bigint[]} prevInputIds List of previous input ids\n   * @returns {number[]} Map of generated n-grams\n   */\n  calcBannedNgramTokens(prevInputIds: bigint[]) {\n    const bannedTokens: number[] = [];\n    if (prevInputIds.length + 1 < this.no_repeat_ngram_size) {\n      // return no banned tokens if we haven't generated no_repeat_ngram_size tokens yet\n      return bannedTokens;\n    } else {\n      const generatedNgrams = this.getNgrams(prevInputIds);\n      const bannedTokens = this.getGeneratedNgrams(generatedNgrams, prevInputIds);\n      return bannedTokens;\n    }\n  }\n\n  /**\n   * Apply the no-repeat-ngram processor to the logits.\n   * @param {bigint[][]} input_ids The input IDs.\n   * @param {Tensor} logits The logits.\n   * @returns {Tensor} The logits with no-repeat-ngram processing.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    for (let i = 0; i < input_ids.length; ++i) {\n      const batch_logits_data = /** @type {Float32Array} */ logits[i].data;\n      const bannedTokens = this.calcBannedNgramTokens(input_ids[i]);\n      for (const token of bannedTokens) {\n        batch_logits_data[token] = -Infinity;\n      }\n    }\n    return logits;\n  }\n}\n\n/**\n * A logits processor that prevents the repetition of previous tokens through a penalty.\n * This penalty is applied at most once per token. Note that, for decoder-only models like most LLMs,\n * the considered tokens include the prompt.\n *\n * In the original [paper](https://arxiv.org/pdf/1909.05858.pdf), the authors suggest the use of a\n * penalty of around 1.2 to achieve a good balance between truthful generation and lack of repetition.\n * To penalize and reduce repetition, use `penalty` values above 1.0, where a higher value penalizes\n * more strongly. To reward and encourage repetition, use `penalty` values between 0.0 and 1.0, where\n * a lower value rewards more strongly.\n */\nexport class RepetitionPenaltyLogitsProcessor extends LogitsProcessor {\n  /**\n   * Create a RepetitionPenaltyLogitsProcessor.\n   * @param {number} penalty The parameter for repetition penalty.\n   * - 1.0 means no penalty. Above 1.0 penalizes previously generated tokens.\n   * - Between 0.0 and 1.0 rewards previously generated tokens.\n   */\n  penalty: number;\n  constructor(penalty: number) {\n    super();\n    this.penalty = penalty;\n  }\n\n  /**\n   * Apply the repetition penalty to the logits.\n   * @param {bigint[][]} input_ids The input IDs.\n   * @param {Tensor} logits The logits.\n   * @returns {Tensor} The logits with repetition penalty processing.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    for (let i = 0; i < input_ids.length; ++i) {\n      const batch_logits_data = /** @type {Float32Array} */ logits[i].data;\n      for (const input_id of new Set(input_ids[i])) {\n        const token = Number(input_id);\n        if (batch_logits_data[token] < 0) {\n          batch_logits_data[token] *= this.penalty;\n        } else {\n          batch_logits_data[token] /= this.penalty;\n        }\n      }\n    }\n\n    return logits;\n  }\n}\n\n/**\n * A logits processor that enforces a minimum number of tokens.\n */\nexport class MinLengthLogitsProcessor extends LogitsProcessor {\n  /**\n   * Create a MinLengthLogitsProcessor.\n   * @param {number} min_length The minimum length below which the score of `eos_token_id` is set to negative infinity.\n   * @param {number|number[]} eos_token_id The ID/IDs of the end-of-sequence token.\n   */\n  min_length: number;\n  eos_token_id: number | number[];\n  constructor(min_length: number, eos_token_id: number | number[]) {\n    super();\n    this.min_length = min_length;\n    this.eos_token_id = Array.isArray(eos_token_id) ? eos_token_id : [eos_token_id];\n  }\n\n  /**\n   * Apply logit processor.\n   * @param {bigint[][]} input_ids The input IDs.\n   * @param {Tensor} logits The logits.\n   * @returns {Tensor} The processed logits.\n   */\n\n  _call(input_ids: bigint[][], logits: Tensor) {\n    for (let i = 0; i < input_ids.length; ++i) {\n      if (input_ids[i].length < this.min_length) {\n        const batch_logits_data = /** @type {Float32Array} */ logits[i].data;\n\n        for (const eos_token of Array.isArray(this.eos_token_id) ? this.eos_token_id : [this.eos_token_id]) {\n          batch_logits_data[eos_token] = -Infinity;\n        }\n      }\n    }\n\n    return logits;\n  }\n}\n\n/**\n * A logits processor that enforces a minimum number of new tokens.\n */\nexport class MinNewTokensLengthLogitsProcessor extends LogitsProcessor {\n  /**\n   * Create a MinNewTokensLengthLogitsProcessor.\n   * @param {number} prompt_length_to_skip The input tokens length.\n   * @param {number} min_new_tokens The minimum *new* tokens length below which the score of `eos_token_id` is set to negative infinity.\n   * @param {number|number[]} eos_token_id The ID/IDs of the end-of-sequence token.\n   */\n  prompt_length_to_skip: number;\n  min_new_tokens: number;\n  eos_token_id: number | number[];\n  constructor(prompt_length_to_skip: number, min_new_tokens: number, eos_token_id: number | number[]) {\n    super();\n    this.prompt_length_to_skip = prompt_length_to_skip;\n    this.min_new_tokens = min_new_tokens;\n    this.eos_token_id = Array.isArray(eos_token_id) ? eos_token_id : [eos_token_id];\n  }\n\n  /**\n   * Apply logit processor.\n   * @param {bigint[][]} input_ids The input IDs.\n   * @param {Tensor} logits The logits.\n   * @returns {Tensor} The processed logits.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    for (let i = 0; i < input_ids.length; ++i) {\n      const new_tokens_length = input_ids[i].length - this.prompt_length_to_skip;\n      if (new_tokens_length < this.min_new_tokens) {\n        const batch_logits_data = /** @type {Float32Array} */ logits[i].data;\n\n        for (const eos_token of Array.isArray(this.eos_token_id) ? this.eos_token_id : [this.eos_token_id]) {\n          batch_logits_data[eos_token] = -Infinity;\n        }\n      }\n    }\n    return logits;\n  }\n}\n\nexport class NoBadWordsLogitsProcessor extends LogitsProcessor {\n  /**\n   * Create a `NoBadWordsLogitsProcessor`.\n   * @param {number[][]} bad_words_ids List of list of token ids that are not allowed to be generated.\n   * @param {number|number[]} eos_token_id The id of the *end-of-sequence* token. Optionally, use a list to set multiple *end-of-sequence* tokens.\n   */\n  bad_words_ids: number[][];\n  eos_token_id: number | number[];\n  constructor(bad_words_ids: number[][], eos_token_id: number | number[]) {\n    super();\n    this.bad_words_ids = bad_words_ids;\n    this.eos_token_id = Array.isArray(eos_token_id) ? eos_token_id : [eos_token_id];\n  }\n\n  /**\n   * Apply logit processor.\n   * @param {bigint[][]} input_ids The input IDs.\n   * @param {Tensor} logits The logits.\n   * @returns {Tensor} The processed logits.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    for (let i = 0; i < input_ids.length; ++i) {\n      const batch_logits_data = /** @type {Float32Array} */ logits[i].data;\n      const ids = input_ids[i];\n      for (const bad_word_ids of this.bad_words_ids) {\n        // Whether to modify the logits of the last token in the bad word id sequence\n        let mark = true;\n\n        // For each bad word in the list, if the current sequence of input ids ends with this sequence (excluding the last),\n        // then we set the logits of the last bad word id to -Infinity.\n        for (let j = 1; j <= bad_word_ids.length - 1 && bad_word_ids.length < ids.length; ++j) {\n          // NOTE: We use != instead of !== to compare bigint and number\n          // @ts-ignore\n          if (bad_word_ids.at(-j - 1) != ids.at(-j)) {\n            // We have found a mismatch\n            mark = false;\n            break;\n          }\n        }\n        if (mark) {\n          const lastId = bad_word_ids.at(-1);\n          if (lastId !== undefined) {\n            batch_logits_data[lastId] = -Infinity;\n          }\n        }\n      }\n    }\n    return logits;\n  }\n}\n\n/**\n * [`LogitsProcessor`] for classifier free guidance (CFG). The scores are split over the batch dimension,\n * where the first half correspond to the conditional logits (predicted from the input prompt) and the second half\n * correspond to the unconditional logits (predicted from an empty or 'null' prompt). The processor computes a\n * weighted average across the conditional and unconditional logits, parameterised by the `guidance_scale`.\n *\n * See [the paper](https://arxiv.org/abs/2306.05284) for more information.\n */\nexport class ClassifierFreeGuidanceLogitsProcessor extends LogitsProcessor {\n  /**\n   * Create a `ClassifierFreeGuidanceLogitsProcessor`.\n   * @param {number} guidance_scale The guidance scale for classifier free guidance (CFG). CFG is enabled by setting `guidance_scale > 1`.\n   * Higher guidance scale encourages the model to generate samples that are more closely linked to the input\n   * prompt, usually at the expense of poorer quality.\n   */\n  guidance_scale: number;\n  constructor(guidance_scale: number) {\n    super();\n    if (guidance_scale <= 1) {\n      throw new Error(\n        `Require guidance scale >1 to use the classifier free guidance processor, got guidance scale ${guidance_scale}.`,\n      );\n    }\n    this.guidance_scale = guidance_scale;\n  }\n\n  /**\n   * Apply logit processor.\n   * @param {bigint[][]} input_ids The input IDs.\n   * @param {Tensor} logits The logits.\n   * @returns {Tensor} The processed logits.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    if (logits.dims[0] !== 2 * input_ids.length) {\n      throw new Error(\n        `Logits should have twice the batch size of the input ids, the first half of batches corresponding to ` +\n          `the conditional inputs, and the second half of batches corresponding to the unconditional inputs. Got ` +\n          `batch size ${logits.dims[0]} for the logits and ${input_ids.length} for the input ids.`,\n      );\n    }\n\n    const unguided_bsz = input_ids.length;\n    const cond_logits = logits.slice([0, unguided_bsz], null);\n    const uncond_logits = logits.slice([unguided_bsz, logits.dims[0]], null);\n\n    // Merge into uncond_logits (to save memory). This is equivalent to the following:\n    // scores = uncond_logits + (cond_logits - uncond_logits) * guidance_scale\n    for (let i = 0; i < uncond_logits.data.length; ++i) {\n      uncond_logits.data[i] += (cond_logits.data[i] - uncond_logits.data[i]) * this.guidance_scale;\n    }\n\n    return uncond_logits;\n  }\n}\n\n/**\n * [`LogitsWarper`] for temperature (exponential scaling output probability distribution), which effectively means\n * that it can control the randomness of the predicted tokens. Often used together with [`TopPLogitsWarper`] and [`TopKLogitsWarper`].\n */\nexport class TemperatureLogitsWarper extends LogitsWarper {\n  /**\n   * Create a `TemperatureLogitsWarper`.\n   * @param {number} temperature Strictly positive float value used to modulate the logits distribution.\n   * A value smaller than `1` decreases randomness (and vice versa), with `0` being equivalent to shifting\n   * all probability mass to the most likely token.\n   */\n  temperature: number;\n  constructor(temperature: number) {\n    super();\n\n    if (typeof temperature !== 'number' || temperature <= 0) {\n      let errorMessage = `\\`temperature\\` (=${temperature}) must be a strictly positive float, otherwise your next token scores will be invalid.`;\n\n      if (temperature === 0) {\n        errorMessage += \" If you're looking for greedy decoding strategies, set `do_sample=false`.\";\n      }\n    }\n    this.temperature = temperature;\n  }\n\n  /**\n   * Apply logit warper.\n   * @param {bigint[][]} input_ids The input IDs.\n   * @param {Tensor} logits The logits.\n   * @returns {Tensor} The processed logits.\n   */\n  _call(input_ids: bigint[][], logits: Tensor) {\n    const batch_logits_data = /** @type {Float32Array} */ logits.data;\n    for (let i = 0; i < batch_logits_data.length; ++i) {\n      batch_logits_data[i] /= this.temperature;\n    }\n    return logits;\n  }\n}\n\n/**\n * [`LogitsWarper`] that performs top-p, i.e. restricting to top tokens summing to prob_cut_off <= prob_cut_off.\n * Often used together with [`TemperatureLogitsWarper`] and [`TopKLogitsWarper`].\n */\nexport class TopPLogitsWarper extends LogitsWarper {\n  /**\n   * Create a `TopPLogitsWarper`.\n   * @param {number} top_p If set to < 1, only the smallest set of most probable tokens with\n   * probabilities that add up to `top_p` or higher are kept for generation.\n   * @param {Object} options Additional options for the top-p sampling.\n   * @param {number} [options.filter_value=-Infinity] All filtered values will be set to this float value.\n   * @param {number} [options.min_tokens_to_keep=1] Minimum number of tokens that cannot be filtered.\n   */\n  top_p: number;\n  filter_value: number;\n  min_tokens_to_keep: number;\n  constructor(top_p: number, { filter_value = -Infinity, min_tokens_to_keep = 1 } = {}) {\n    super();\n    if (top_p < 0 || top_p > 1.0) {\n      throw new Error(`\\`top_p\\` must be a float > 0 and < 1, but is ${top_p}`);\n    }\n    if (!Number.isInteger(min_tokens_to_keep) || min_tokens_to_keep < 1) {\n      throw new Error(`\\`min_tokens_to_keep\\` must be a positive integer, but is ${min_tokens_to_keep}`);\n    }\n\n    this.top_p = top_p;\n    this.filter_value = filter_value;\n    this.min_tokens_to_keep = min_tokens_to_keep;\n  }\n}\n\n/**\n * [`LogitsWarper`] that performs top-k, i.e. restricting to the k highest probability elements.\n * Often used together with [`TemperatureLogitsWarper`] and [`TopPLogitsWarper`].\n */\nexport class TopKLogitsWarper extends LogitsWarper {\n  /**\n   * Create a `TopKLogitsWarper`.\n   * @param {number} top_k If set to > 0, only the top `top_k` tokens are kept for generation.\n   * @param {Object} options Additional options for the top-k sampling.\n   * @param {number} [options.filter_value=-Infinity] All filtered values will be set to this float value.\n   * @param {number} [options.min_tokens_to_keep=1] Minimum number of tokens that cannot be filtered.\n   */\n  top_k: number;\n  filter_value: number;\n  constructor(top_k: number, { filter_value = -Infinity, min_tokens_to_keep = 1 } = {}) {\n    super();\n    if (!Number.isInteger(top_k) || top_k < 0) {\n      throw new Error(`\\`top_k\\` must be a positive integer, but is ${top_k}`);\n    }\n\n    this.top_k = Math.max(top_k, min_tokens_to_keep);\n    this.filter_value = filter_value;\n  }\n}\n","/**\n * @module generation/configuration_utils\n */\n\nimport { PretrainedConfig } from '../configs';\nimport { pick } from '../utils/core';\nimport { TextStreamer } from './streamers';\n\n/**\n * Class that holds a configuration for a generation task.\n */\nexport class GenerationConfig {\n  // Parameters that control the length of the output\n  /**\n   * The maximum length the generated tokens can have.\n   * Corresponds to the length of the input prompt + `max_new_tokens`.\n   * Its effect is overridden by `max_new_tokens`, if also set.\n   * @type {number}\n   * @default 20\n   */\n  max_length: number = 20;\n\n  /**\n   * The maximum numbers of tokens to generate, ignoring the number of tokens in the prompt.\n   * @type {number}\n   * @default null\n   */\n  max_new_tokens: number | null = null;\n\n  /**\n   * The minimum length of the sequence to be generated.\n   * Corresponds to the length of the input prompt + `min_new_tokens`.\n   * Its effect is overridden by `min_new_tokens`, if also set.\n   * @type {number}\n   * @default 0\n   */\n  min_length: number = 0;\n\n  /**\n   * The minimum numbers of tokens to generate, ignoring the number of tokens in the prompt.\n   * @type {number}\n   * @default null\n   */\n  min_new_tokens: number | null = null;\n\n  /**\n   * Controls the stopping condition for beam-based methods, like beam-search. It accepts the following values:\n   * - `true`, where the generation stops as soon as there are `num_beams` complete candidates;\n   * - `false`, where an heuristic is applied and the generation stops when is it very unlikely to find better candidates;\n   * - `\"never\"`, where the beam search procedure only stops when there cannot be better candidates (canonical beam search algorithm).\n   * @type {boolean|\"never\"}\n   * @default false\n   */\n  early_stopping: boolean | 'never' = false;\n\n  /**\n   * The maximum amount of time you allow the computation to run for in seconds.\n   * Generation will still finish the current pass after allocated time has been passed.\n   * @type {number}\n   * @default null\n   */\n  max_time: number | null = null;\n\n  // Parameters that control the generation strategy used\n  /**\n   * Whether or not to use sampling; use greedy decoding otherwise.\n   * @type {boolean}\n   * @default false\n   */\n  do_sample: boolean = false;\n\n  /**\n   * Number of beams for beam search. 1 means no beam search.\n   * @type {number}\n   * @default 1\n   */\n  num_beams: number = 1;\n\n  /**\n   * Number of groups to divide `num_beams` into in order to ensure diversity among different groups of beams.\n   * See [this paper](https://arxiv.org/pdf/1610.02424.pdf) for more details.\n   * @type {number}\n   * @default 1\n   */\n  num_beam_groups: number = 1;\n\n  /**\n   * The values balance the model confidence and the degeneration penalty in contrastive search decoding.\n   * @type {number}\n   * @default null\n   */\n  penalty_alpha: number | null = null;\n\n  /**\n   * Whether or not the model should use the past last key/values attentions (if applicable to the model) to speed up decoding.\n   * @type {boolean}\n   * @default true\n   */\n  use_cache: boolean = true;\n\n  // Parameters for manipulation of the model output logits\n  /**\n   * The value used to modulate the next token probabilities.\n   * @type {number}\n   * @default 1.0\n   */\n  temperature: number = 1.0;\n\n  /**\n   * The number of highest probability vocabulary tokens to keep for top-k-filtering.\n   * @type {number}\n   * @default 50\n   */\n  top_k: number = 50;\n\n  /**\n   * If set to float < 1, only the smallest set of most probable tokens with probabilities that add up to `top_p` or higher are kept for generation.\n   * @type {number}\n   * @default 1.0\n   */\n  top_p: number = 1.0;\n\n  /**\n   * Local typicality measures how similar the conditional probability of predicting a target token next is to the expected conditional probability of predicting a random token next, given the partial text already generated.\n   * If set to float < 1, the smallest set of the most locally typical tokens with probabilities that add up to `typical_p` or higher are kept for generation.\n   * See [this paper](https://arxiv.org/pdf/2202.00666.pdf) for more details.\n   * @type {number}\n   * @default 1.0\n   */\n  typical_p: number = 1.0;\n\n  /**\n   * If set to float strictly between 0 and 1, only tokens with a conditional probability greater than `epsilon_cutoff` will be sampled.\n   * In the paper, suggested values range from 3e-4 to 9e-4, depending on the size of the model.\n   * See [Truncation Sampling as Language Model Desmoothing](https://arxiv.org/abs/2210.15191) for more details.\n   * @type {number}\n   * @default 0.0\n   */\n  epsilon_cutoff: number = 0.0;\n\n  /**\n   * Eta sampling is a hybrid of locally typical sampling and epsilon sampling.\n   * If set to float strictly between 0 and 1, a token is only considered if it is greater than either `eta_cutoff` or `sqrt(eta_cutoff) * exp(-entropy(softmax(next_token_logits)))`.\n   * The latter term is intuitively the expected next token probability, scaled by `sqrt(eta_cutoff)`. In the paper, suggested values range from 3e-4 to 2e-3, depending on the size of the model.\n   * See [Truncation Sampling as Language Model Desmoothing](https://arxiv.org/abs/2210.15191) for more details.\n   * @type {number}\n   * @default 0.0\n   */\n  eta_cutoff: number = 0.0;\n\n  /**\n   * This value is subtracted from a beam's score if it generates a token same as any beam from other group at a particular time.\n   * Note that `diversity_penalty` is only effective if `group beam search` is enabled.\n   * @type {number}\n   * @default 0.0\n   */\n  diversity_penalty: number = 0.0;\n\n  /**\n   * The parameter for repetition penalty. 1.0 means no penalty.\n   * See [this paper](https://arxiv.org/pdf/1909.05858.pdf) for more details.\n   * @type {number}\n   * @default 1.0\n   */\n  repetition_penalty: number = 1.0;\n\n  /**\n   * The paramater for encoder_repetition_penalty.\n   * An exponential penalty on sequences that are not in the original input.\n   * 1.0 means no penalty.\n   * @type {number}\n   * @default 1.0\n   */\n  encoder_repetition_penalty: number = 1.0;\n\n  /**\n   * Exponential penalty to the length that is used with beam-based generation.\n   * It is applied as an exponent to the sequence length, which in turn is used to divide the score of the sequence.\n   * Since the score is the log likelihood of the sequence (i.e. negative), `length_penalty` > 0.0 promotes longer sequences, while `length_penalty` < 0.0 encourages shorter sequences.\n   * @type {number}\n   * @default 1.0\n   */\n  length_penalty: number = 1.0;\n\n  /**\n   * If set to int > 0, all ngrams of that size can only occur once.\n   * @type {number}\n   * @default 0\n   */\n  no_repeat_ngram_size: number = 0;\n\n  /**\n   * List of token ids that are not allowed to be generated.\n   * In order to get the token ids of the words that should not appear in the generated text, use\n   * `tokenizer(bad_words, { add_prefix_space: true, add_special_tokens: false }).input_ids`.\n   * @type {number[][]}\n   * @default null\n   */\n  bad_words_ids: number[][] | null = null;\n\n  /**\n   * List of token ids that must be generated.\n   * If given a `number[][]`, this is treated as a simple list of words that must be included, the opposite to `bad_words_ids`.\n   * If given `number[][][]`, this triggers a [disjunctive constraint](https://github.com/huggingface/transformers/issues/14081), where one can allow different forms of each word.\n   * @type {number[][]|number[][][]}\n   * @default null\n   */\n  force_words_ids: number[][] | number[][][] | null  = null;\n\n  /**\n   * Whether to renormalize the logits after applying all the logits processors or warpers (including the custom ones).\n   * It's highly recommended to set this flag to `true` as the search algorithms suppose the score logits are normalized but some logit processors or warpers break the normalization.\n   * @type {boolean}\n   * @default false\n   */\n  renormalize_logits: boolean = false;\n\n  /**\n   * Custom constraints that can be added to the generation to ensure that the output will contain the use of certain tokens as defined by `Constraint` objects, in the most sensible way possible.\n   * @type {Object[]}\n   * @default null\n   */\n  constraints: Object[] | null = null;\n\n  /**\n   * The id of the token to force as the first generated token after the `decoder_start_token_id`.\n   * Useful for multilingual models like mBART where the first generated token needs to be the target language token.\n   * @type {number}\n   * @default null\n   */\n  forced_bos_token_id: number | null = null;\n\n  /**\n   * The id of the token to force as the last generated token when `max_length` is reached.\n   * Optionally, use a list to set multiple *end-of-sequence* tokens.\n   * @type {number|number[]}\n   * @default null\n   */\n  forced_eos_token_id: number | number[] | null = null;\n\n  /**\n   * Whether to remove possible *nan* and *inf* outputs of the model to prevent the generation method to crash. Note that using `remove_invalid_values` can slow down generation.\n   * @type {boolean}\n   */\n  remove_invalid_values: boolean = false;\n\n  /**\n   * This Tuple adds an exponentially increasing length penalty, after a certain amount of tokens have been generated.\n   * The tuple shall consist of: `(start_index, decay_factor)` where `start_index` indicates where penalty starts and `decay_factor` represents the factor of exponential decay.\n   * @type {[number, number]}\n   * @default null\n   */\n  exponential_decay_length_penalty: [number, number] | null = null;\n\n  /**\n   * A list of tokens that will be suppressed at generation.\n   * The `SuppressTokens` logit processor will set their log probs to `-inf` so that they are not sampled.\n   * @type {number[]}\n   * @default null\n   */\n  suppress_tokens: number[] | null = null;\n\n  /**\n   * A streamer that will be used to stream the generation.\n   * @type {import('./streamers.js').TextStreamer}\n   * @default null\n   */\n  streamer: TextStreamer | null = null;\n\n  /**\n   * A list of tokens that will be suppressed at the beginning of the generation.\n   * The `SuppressBeginTokens` logit processor will set their log probs to `-inf` so that they are not sampled.\n   * @type {number[]}\n   * @default null\n   */\n  begin_suppress_tokens: number[] | null = null;\n\n  /**\n   * A list of pairs of integers which indicates a mapping from generation indices to token indices that will be forced before sampling.\n   * For example, `[[1, 123]]` means the second generated token will always be a token of index 123.\n   * @type {[number, number][]}\n   * @default null\n   */\n  forced_decoder_ids: [number, number][] | null = null;\n\n  /**\n   * The guidance scale for classifier free guidance (CFG). CFG is enabled by setting `guidance_scale > 1`.\n   * Higher guidance scale encourages the model to generate samples that are more closely linked to the input\n   * prompt, usually at the expense of poorer quality.\n   * @type {number}\n   * @default null\n   */\n  guidance_scale: number | null = null;\n\n  // Parameters that define the output variables of `generate`\n  /**\n   * The number of independently computed returned sequences for each element in the batch.\n   * @type {number}\n   * @default 1\n   */\n  num_return_sequences: number = 1;\n\n  /**\n   * Whether or not to return the attentions tensors of all attention layers.\n   * See `attentions` under returned tensors for more details.\n   * @type {boolean}\n   * @default false\n   */\n  output_attentions: boolean = false;\n\n  /**\n   * Whether or not to return the hidden states of all layers.\n   * See `hidden_states` under returned tensors for more details.\n   * @type {boolean}\n   * @default false\n   */\n  output_hidden_states: boolean = false;\n\n  /**\n   * Whether or not to return the prediction scores.\n   * See `scores` under returned tensors for more details.\n   * @type {boolean}\n   * @default false\n   */\n  output_scores: boolean = false;\n\n  /**\n   * Whether or not to return a `ModelOutput` instead of a plain tuple.\n   * @type {boolean}\n   * @default false\n   */\n  return_dict_in_generate: boolean = false;\n\n  // Special tokens that can be used at generation time\n  /**\n   * The id of the *padding* token.\n   * @type {number}\n   * @default null\n   */\n  pad_token_id: number | null = null;\n\n  /**\n   * The id of the *beginning-of-sequence* token.\n   * @type {number}\n   * @default null\n   */\n  bos_token_id: number | null = null;\n\n  /**\n   * The id of the *end-of-sequence* token.\n   * Optionally, use a list to set multiple *end-of-sequence* tokens.\n   * @type {number|number[]}\n   * @default null\n   */\n  eos_token_id: number | number[] | null = null;\n\n  // Generation parameters exclusive to encoder-decoder models\n  /**\n   * If set to int > 0, all ngrams of that size that occur in the `encoder_input_ids` cannot occur in the `decoder_input_ids`.\n   * @type {number}\n   * @default 0\n   */\n  encoder_no_repeat_ngram_size: number = 0;\n\n  /**\n   * If an encoder-decoder model starts decoding with a different token than *bos*, the id of that token.\n   * @type {number}\n   * @default null\n   */\n  decoder_start_token_id: number | null = null;\n\n  // Wild card\n  /**\n   * Additional generation kwargs will be forwarded to the `generate` function of the model.\n   * Kwargs that are not present in `generate`'s signature will be used in the model forward pass.\n   * @type {Object}\n   * @default {}\n   */\n  generation_kwargs: Object = {};\n\n  /**\n   *\n   * @param {GenerationConfig|import('../configs.js').PretrainedConfig} config\n   */\n  constructor(config: GenerationConfig | PretrainedConfig) {\n    Object.assign(this, pick(config, Object.getOwnPropertyNames(this) as any));\n  }\n}\n","import { isNullishDimension, saveBlob } from './core';\nimport { getFile } from './hub';\nimport { env, apis } from '../env';\nimport { Tensor } from './tensor';\n\n// // Will be empty (or not used) if running in browser or web-worker\n// import sharp from 'sharp';\n\nlet createCanvasFunction: any;\nlet ImageDataClass: any;\nlet loadImageFunction: any;\nconst IS_BROWSER_OR_WEBWORKER = apis.IS_BROWSER_ENV || apis.IS_WEBWORKER_ENV;\nif (IS_BROWSER_OR_WEBWORKER) {\n  // Running in browser or web-worker\n  createCanvasFunction = (width: number, height: number) => {\n    if (!self.OffscreenCanvas) {\n      throw new Error('OffscreenCanvas not supported by this browser.');\n    }\n    return new self.OffscreenCanvas(width, height);\n  };\n  loadImageFunction = self.createImageBitmap;\n  ImageDataClass = self.ImageData;\n} else {\n  throw new Error('Unable to load image processing library.');\n}\n\n// Defined here: https://github.com/python-pillow/Pillow/blob/a405e8406b83f8bfb8916e93971edc7407b8b1ff/src/libImaging/Imaging.h#L262-L268\nconst RESAMPLING_MAPPING = {\n  0: 'nearest',\n  1: 'lanczos',\n  2: 'bilinear',\n  3: 'bicubic',\n  4: 'box',\n  5: 'hamming',\n};\n\n/**\n * Mapping from file extensions to MIME types.\n */\nconst CONTENT_TYPE_MAP = new Map([\n  ['png', 'image/png'],\n  ['jpg', 'image/jpeg'],\n  ['jpeg', 'image/jpeg'],\n  ['gif', 'image/gif'],\n]);\n\nexport class RawImage {\n  data: Uint8ClampedArray | Uint8Array;\n  width: number;\n  height: number;\n  channels: 1 | 2 | 3 | 4;\n\n  /**\n   * Create a new `RawImage` object.\n   * @param {Uint8ClampedArray|Uint8Array} data The pixel data.\n   * @param {number} width The width of the image.\n   * @param {number} height The height of the image.\n   * @param {1|2|3|4} channels The number of channels.\n   */\n  constructor(data: Uint8ClampedArray | Uint8Array, width: number, height: number, channels: 1 | 2 | 3 | 4) {\n    this.data = data;\n    this.width = width;\n    this.height = height;\n    this.channels = channels;\n  }\n\n  /**\n   * Returns the size of the image (width, height).\n   * @returns {[number, number]} The size of the image (width, height).\n   */\n  get size() {\n    return [this.width, this.height];\n  }\n\n  /**\n   * Helper method for reading an image from a variety of input types.\n   * @param {RawImage|string|URL} input\n   * @returns The image object.\n   *\n   * **Example:** Read image from a URL.\n   * ```javascript\n   * let image = await RawImage.read('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/football-match.jpg');\n   * // RawImage {\n   * //   \"data\": Uint8ClampedArray [ 25, 25, 25, 19, 19, 19, ... ],\n   * //   \"width\": 800,\n   * //   \"height\": 533,\n   * //   \"channels\": 3\n   * // }\n   * ```\n   */\n  static async read(input: RawImage | string | URL) {\n    if (input instanceof RawImage) {\n      return input;\n    } else if (typeof input === 'string' || input instanceof URL) {\n      return await this.fromURL(input);\n    } else {\n      throw new Error(`Unsupported input type: ${typeof input}`);\n    }\n  }\n\n  /**\n   * Read an image from a canvas.\n   * @param {HTMLCanvasElement|OffscreenCanvas} canvas The canvas to read the image from.\n   * @returns {RawImage} The image object.\n   */\n  static fromCanvas(canvas: HTMLCanvasElement | OffscreenCanvas) {\n    if (!IS_BROWSER_OR_WEBWORKER) {\n      throw new Error('fromCanvas() is only supported in browser environments.');\n    }\n\n    const ctx = canvas.getContext('2d');\n    if (!ctx) {\n      throw new Error('Failed to get 2D context from canvas');\n    }\n    const data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;\n    return new RawImage(data, canvas.width, canvas.height, 4);\n  }\n\n  /**\n   * Read an image from a URL or file path.\n   * @param {string|URL} url The URL or file path to read the image from.\n   * @returns {Promise<RawImage>} The image object.\n   */\n  static async fromURL(url: string | URL) {\n    const response = await getFile(url);\n    if (response.status !== 200) {\n      throw new Error(`Unable to read image from \"${url}\" (${response.status} ${response.statusText})`);\n    }\n    const blob = await response.blob();\n    return this.fromBlob(blob);\n  }\n\n  /**\n   * Helper method to create a new Image from a blob.\n   * @param {Blob} blob The blob to read the image from.\n   * @returns {Promise<RawImage>} The image object.\n   */\n  static async fromBlob(blob: Blob) {\n      // Running in environment with canvas\n      const img = await loadImageFunction(blob);\n\n      const ctx = createCanvasFunction(img.width, img.height).getContext('2d');\n\n      // Draw image to context\n      ctx.drawImage(img, 0, 0);\n\n      return new this(ctx.getImageData(0, 0, img.width, img.height).data, img.width, img.height, 4);\n  }\n\n  /**\n   * Helper method to create a new Image from a tensor\n   * @param {Tensor} tensor\n   */\n  static fromTensor(tensor: Tensor, channel_format: 'CHW' | 'HWC' = 'CHW') {\n    if (tensor.dims.length !== 3) {\n      throw new Error(`Tensor should have 3 dimensions, but has ${tensor.dims.length} dimensions.`);\n    }\n\n    if (channel_format === 'CHW') {\n      tensor = tensor.transpose(1, 2, 0);\n    } else if (channel_format === 'HWC') {\n      // Do nothing\n    } else {\n      throw new Error(`Unsupported channel format: ${channel_format}`);\n    }\n    if (!(tensor.data instanceof Uint8ClampedArray || tensor.data instanceof Uint8Array)) {\n      throw new Error(`Unsupported tensor type: ${tensor.type}`);\n    }\n    switch (tensor.dims[2]) {\n      case 1:\n      case 2:\n      case 3:\n      case 4:\n        return new RawImage(tensor.data, tensor.dims[1], tensor.dims[0], tensor.dims[2]);\n      default:\n        throw new Error(`Unsupported number of channels: ${tensor.dims[2]}`);\n    }\n  }\n\n  /**\n   * Convert the image to grayscale format.\n   * @returns {RawImage} `this` to support chaining.\n   */\n  grayscale() {\n    if (this.channels === 1) {\n      return this;\n    }\n\n    const newData = new Uint8ClampedArray(this.width * this.height * 1);\n    switch (this.channels) {\n      case 3: // rgb to grayscale\n      case 4: // rgba to grayscale\n        for (let i = 0, offset = 0; i < this.data.length; i += this.channels) {\n          const red = this.data[i];\n          const green = this.data[i + 1];\n          const blue = this.data[i + 2];\n\n          newData[offset++] = Math.round(0.2989 * red + 0.587 * green + 0.114 * blue);\n        }\n        break;\n      default:\n        throw new Error(`Conversion failed due to unsupported number of channels: ${this.channels}`);\n    }\n    return this._update(newData, this.width, this.height, 1);\n  }\n\n  /**\n   * Convert the image to RGB format.\n   * @returns {RawImage} `this` to support chaining.\n   */\n  rgb() {\n    if (this.channels === 3) {\n      return this;\n    }\n\n    const newData = new Uint8ClampedArray(this.width * this.height * 3);\n\n    switch (this.channels) {\n      case 1: // grayscale to rgb\n        for (let i = 0, offset = 0; i < this.data.length; ++i) {\n          newData[offset++] = this.data[i];\n          newData[offset++] = this.data[i];\n          newData[offset++] = this.data[i];\n        }\n        break;\n      case 4: // rgba to rgb\n        for (let i = 0, offset = 0; i < this.data.length; i += 4) {\n          newData[offset++] = this.data[i];\n          newData[offset++] = this.data[i + 1];\n          newData[offset++] = this.data[i + 2];\n        }\n        break;\n      default:\n        throw new Error(`Conversion failed due to unsupported number of channels: ${this.channels}`);\n    }\n    return this._update(newData, this.width, this.height, 3);\n  }\n\n  /**\n   * Convert the image to RGBA format.\n   * @returns {RawImage} `this` to support chaining.\n   */\n  rgba() {\n    if (this.channels === 4) {\n      return this;\n    }\n\n    const newData = new Uint8ClampedArray(this.width * this.height * 4);\n\n    switch (this.channels) {\n      case 1: // grayscale to rgba\n        for (let i = 0, offset = 0; i < this.data.length; ++i) {\n          newData[offset++] = this.data[i];\n          newData[offset++] = this.data[i];\n          newData[offset++] = this.data[i];\n          newData[offset++] = 255;\n        }\n        break;\n      case 3: // rgb to rgba\n        for (let i = 0, offset = 0; i < this.data.length; i += 3) {\n          newData[offset++] = this.data[i];\n          newData[offset++] = this.data[i + 1];\n          newData[offset++] = this.data[i + 2];\n          newData[offset++] = 255;\n        }\n        break;\n      default:\n        throw new Error(`Conversion failed due to unsupported number of channels: ${this.channels}`);\n    }\n\n    return this._update(newData, this.width, this.height, 4);\n  }\n\n  /**\n   * Apply an alpha mask to the image. Operates in place.\n   * @param {RawImage} mask The mask to apply. It should have a single channel.\n   * @returns {RawImage} The masked image.\n   * @throws {Error} If the mask is not the same size as the image.\n   * @throws {Error} If the image does not have 4 channels.\n   * @throws {Error} If the mask is not a single channel.\n   */\n  putAlpha(mask: RawImage) {\n    if (mask.width !== this.width || mask.height !== this.height) {\n      throw new Error(`Expected mask size to be ${this.width}x${this.height}, but got ${mask.width}x${mask.height}`);\n    }\n    if (mask.channels !== 1) {\n      throw new Error(`Expected mask to have 1 channel, but got ${mask.channels}`);\n    }\n\n    const this_data = this.data;\n    const mask_data = mask.data;\n    const num_pixels = this.width * this.height;\n    if (this.channels === 3) {\n      // Convert to RGBA and simultaneously apply mask to alpha channel\n      const newData = new Uint8ClampedArray(num_pixels * 4);\n      for (let i = 0, in_offset = 0, out_offset = 0; i < num_pixels; ++i) {\n        newData[out_offset++] = this_data[in_offset++];\n        newData[out_offset++] = this_data[in_offset++];\n        newData[out_offset++] = this_data[in_offset++];\n        newData[out_offset++] = mask_data[i];\n      }\n      return this._update(newData, this.width, this.height, 4);\n    } else if (this.channels === 4) {\n      // Apply mask to alpha channel in place\n      for (let i = 0; i < num_pixels; ++i) {\n        this_data[4 * i + 3] = mask_data[i];\n      }\n      return this;\n    }\n    throw new Error(`Expected image to have 3 or 4 channels, but got ${this.channels}`);\n  }\n\n  /**\n   * Resize the image to the given dimensions. This method uses the canvas API to perform the resizing.\n   * @param {number} width The width of the new image. `null` or `-1` will preserve the aspect ratio.\n   * @param {number} height The height of the new image. `null` or `-1` will preserve the aspect ratio.\n   * @param {Object} options Additional options for resizing.\n   * @param {0|1|2|3|4|5|string} [options.resample] The resampling method to use.\n   * @returns {Promise<RawImage>} `this` to support chaining.\n   */\n  async resize(width: number, height: number, { resample = 2 } = {}) {\n    // Do nothing if the image already has the desired size\n    if (this.width === width && this.height === height) {\n      return this;\n    }\n\n    // Ensure resample method is a string\n    let resampleMethod = RESAMPLING_MAPPING[resample as keyof typeof RESAMPLING_MAPPING] ?? resample;\n\n    // Calculate width / height to maintain aspect ratio, in the event that\n    // the user passed a null value in.\n    // This allows users to pass in something like `resize(320, null)` to\n    // resize to 320 width, but maintain aspect ratio.\n    const nullish_width = isNullishDimension(width);\n    const nullish_height = isNullishDimension(height);\n    if (nullish_width && nullish_height) {\n      return this;\n    } else if (nullish_width) {\n      width = (height / this.height) * this.width;\n    } else if (nullish_height) {\n      height = (width / this.width) * this.height;\n    }\n\n    if (IS_BROWSER_OR_WEBWORKER) {\n      // TODO use `resample` in browser environment\n\n      // Store number of channels before resizing\n      const numChannels = this.channels;\n\n      // Create canvas object for this image\n      const canvas = this.toCanvas();\n\n      // Actually perform resizing using the canvas API\n      const ctx = createCanvasFunction(width, height).getContext('2d');\n\n      // Draw image to context, resizing in the process\n      ctx.drawImage(canvas, 0, 0, width, height);\n\n      // Create image from the resized data\n      const resizedImage = new RawImage(ctx.getImageData(0, 0, width, height).data, width, height, 4);\n\n      // Convert back so that image has the same number of channels as before\n      return resizedImage.convert(numChannels as 1 | 3 | 4);\n    } else {\n      // Create sharp image from raw data, and resize\n      let img = this.toSharp();\n\n      switch (resampleMethod) {\n        case 'box':\n        case 'hamming':\n          if (resampleMethod === 'box' || resampleMethod === 'hamming') {\n            console.warn(`Resampling method ${resampleMethod} is not yet supported. Using bilinear instead.`);\n            resampleMethod = 'bilinear';\n          }\n\n        case 'nearest':\n        case 'bilinear':\n        case 'bicubic':\n          // Perform resizing using affine transform.\n          // This matches how the python Pillow library does it.\n          img = img.affine([width / this.width, 0, 0, height / this.height], {\n            interpolator: resampleMethod as 'nearest' | 'bilinear' | 'bicubic' | 'nohalo' | 'lbb' | 'vsqbs' | undefined,\n          });\n          break;\n\n        case 'lanczos':\n          // https://github.com/python-pillow/Pillow/discussions/5519\n          // https://github.com/lovell/sharp/blob/main/docs/api-resize.md\n          img = img.resize({\n            width,\n            height,\n            fit: 'fill',\n            kernel: 'lanczos3', // PIL Lanczos uses a kernel size of 3\n          });\n          break;\n\n        default:\n          throw new Error(`Resampling method ${resampleMethod} is not supported.`);\n      }\n\n      return await loadImageFunction(img);\n    }\n  }\n\n  async pad([left, right, top, bottom]: [number, number, number, number]) {\n    left = Math.max(left, 0);\n    right = Math.max(right, 0);\n    top = Math.max(top, 0);\n    bottom = Math.max(bottom, 0);\n\n    if (left === 0 && right === 0 && top === 0 && bottom === 0) {\n      // No padding needed\n      return this;\n    }\n\n    if (IS_BROWSER_OR_WEBWORKER) {\n      // Store number of channels before padding\n      const numChannels = this.channels;\n\n      // Create canvas object for this image\n      const canvas = this.toCanvas();\n\n      const newWidth = this.width + left + right;\n      const newHeight = this.height + top + bottom;\n\n      // Create a new canvas of the desired size.\n      const ctx = createCanvasFunction(newWidth, newHeight).getContext('2d');\n\n      // Draw image to context, padding in the process\n      ctx.drawImage(canvas, 0, 0, this.width, this.height, left, top, this.width, this.height);\n\n      // Create image from the padded data\n      const paddedImage = new RawImage(ctx.getImageData(0, 0, newWidth, newHeight).data, newWidth, newHeight, 4);\n\n      // Convert back so that image has the same number of channels as before\n      return paddedImage.convert(numChannels as 1 | 3 | 4);\n    } \n  }\n\n  async crop([x_min, y_min, x_max, y_max]: [number, number, number, number]) {\n    // Ensure crop bounds are within the image\n    x_min = Math.max(x_min, 0);\n    y_min = Math.max(y_min, 0);\n    x_max = Math.min(x_max, this.width - 1);\n    y_max = Math.min(y_max, this.height - 1);\n\n    // Do nothing if the crop is the entire image\n    if (x_min === 0 && y_min === 0 && x_max === this.width - 1 && y_max === this.height - 1) {\n      return this;\n    }\n\n    const crop_width = x_max - x_min + 1;\n    const crop_height = y_max - y_min + 1;\n\n    if (IS_BROWSER_OR_WEBWORKER) {\n      // Store number of channels before resizing\n      const numChannels = this.channels;\n\n      // Create canvas object for this image\n      const canvas = this.toCanvas();\n\n      // Create a new canvas of the desired size. This is needed since if the\n      // image is too small, we need to pad it with black pixels.\n      const ctx = createCanvasFunction(crop_width, crop_height).getContext('2d');\n\n      // Draw image to context, cropping in the process\n      ctx.drawImage(canvas, x_min, y_min, crop_width, crop_height, 0, 0, crop_width, crop_height);\n\n      // Create image from the resized data\n      const resizedImage = new RawImage(\n        ctx.getImageData(0, 0, crop_width, crop_height).data,\n        crop_width,\n        crop_height,\n        4,\n      );\n\n      // Convert back so that image has the same number of channels as before\n      return resizedImage.convert(numChannels as 1 | 3 | 4);\n    }\n  }\n\n  async center_crop(crop_width: number, crop_height: number) {\n    // If the image is already the desired size, return it\n    if (this.width === crop_width && this.height === crop_height) {\n      return this;\n    }\n\n    // Determine bounds of the image in the new canvas\n    const width_offset = (this.width - crop_width) / 2;\n    const height_offset = (this.height - crop_height) / 2;\n\n    if (IS_BROWSER_OR_WEBWORKER) {\n      // Store number of channels before resizing\n      const numChannels = this.channels;\n\n      // Create canvas object for this image\n      const canvas = this.toCanvas();\n\n      // Create a new canvas of the desired size. This is needed since if the\n      // image is too small, we need to pad it with black pixels.\n      const ctx = createCanvasFunction(crop_width, crop_height).getContext('2d');\n\n      let sourceX = 0;\n      let sourceY = 0;\n      let destX = 0;\n      let destY = 0;\n\n      if (width_offset >= 0) {\n        sourceX = width_offset;\n      } else {\n        destX = -width_offset;\n      }\n\n      if (height_offset >= 0) {\n        sourceY = height_offset;\n      } else {\n        destY = -height_offset;\n      }\n\n      // Draw image to context, cropping in the process\n      ctx.drawImage(canvas, sourceX, sourceY, crop_width, crop_height, destX, destY, crop_width, crop_height);\n\n      // Create image from the resized data\n      const resizedImage = new RawImage(\n        ctx.getImageData(0, 0, crop_width, crop_height).data,\n        crop_width,\n        crop_height,\n        4,\n      );\n\n      // Convert back so that image has the same number of channels as before\n      return resizedImage.convert(numChannels as 1 | 3 | 4);\n    }\n  }\n\n  async toBlob(type = 'image/png', quality = 1) {\n    if (!IS_BROWSER_OR_WEBWORKER) {\n      throw new Error('toBlob() is only supported in browser environments.');\n    }\n\n    const canvas = this.toCanvas();\n    return await canvas.convertToBlob({ type, quality });\n  }\n\n  toTensor(channel_format = 'CHW') {\n    let tensor = new Tensor('uint8', new Uint8Array(this.data), [this.height, this.width, this.channels]);\n\n    if (channel_format === 'HWC') {\n      // Do nothing\n    } else if (channel_format === 'CHW') {\n      // hwc -> chw\n      tensor = tensor.permute(2, 0, 1);\n    } else {\n      throw new Error(`Unsupported channel format: ${channel_format}`);\n    }\n    return tensor;\n  }\n\n  toCanvas() {\n    if (!IS_BROWSER_OR_WEBWORKER) {\n      throw new Error('toCanvas() is only supported in browser environments.');\n    }\n\n    // Clone, and convert data to RGBA before drawing to canvas.\n    // This is because the canvas API only supports RGBA\n    const cloned = this.clone().rgba();\n\n    // Create canvas object for the cloned image\n    const clonedCanvas = createCanvasFunction(cloned.width, cloned.height);\n\n    // Draw image to context\n    const data = new ImageDataClass(cloned.data, cloned.width, cloned.height);\n    clonedCanvas.getContext('2d').putImageData(data, 0, 0);\n\n    return clonedCanvas;\n  }\n\n  /**\n   * Split this image into individual bands. This method returns an array of individual image bands from an image.\n   * For example, splitting an \"RGB\" image creates three new images each containing a copy of one of the original bands (red, green, blue).\n   *\n   * Inspired by PIL's `Image.split()` [function](https://pillow.readthedocs.io/en/latest/reference/Image.html#PIL.Image.Image.split).\n   * @returns {RawImage[]} An array containing bands.\n   */\n  split() {\n    const { data, width, height, channels } = this;\n\n    /** @type {typeof Uint8Array | typeof Uint8ClampedArray} */\n    const data_type = /** @type {any} */ data.constructor;\n    const per_channel_length = data.length / channels;\n\n    // Pre-allocate buffers for each channel\n    const split_data = Array.from(\n      { length: channels },\n      () => new (data_type as new (length: number) => Uint8Array | Uint8ClampedArray)(per_channel_length),\n    );\n\n    // Write pixel data\n    for (let i = 0; i < per_channel_length; ++i) {\n      const data_offset = channels * i;\n      for (let j = 0; j < channels; ++j) {\n        split_data[j][i] = data[data_offset + j];\n      }\n    }\n    return split_data.map((data) => new RawImage(data, width, height, 1));\n  }\n\n  /**\n   * Helper method to update the image data.\n   * @param {Uint8ClampedArray} data The new image data.\n   * @param {number} width The new width of the image.\n   * @param {number} height The new height of the image.\n   * @param {1|2|3|4|null} [channels] The new number of channels of the image.\n   * @private\n   */\n  _update(data: Uint8ClampedArray | Uint8Array, width: number, height: number, channels: 1 | 2 | 3 | 4 | null = null) {\n    this.data = data;\n    this.width = width;\n    this.height = height;\n    if (channels !== null) {\n      this.channels = channels;\n    }\n    return this;\n  }\n\n  /**\n   * Clone the image\n   * @returns {RawImage} The cloned image\n   */\n  clone() {\n    return new RawImage(this.data.slice(), this.width, this.height, this.channels);\n  }\n\n  /**\n   * Helper method for converting image to have a certain number of channels\n   * @param {number} numChannels The number of channels. Must be 1, 3, or 4.\n   * @returns {RawImage} `this` to support chaining.\n   */\n  convert(numChannels: 1 | 3 | 4) {\n    if (this.channels === numChannels) return this; // Already correct number of channels\n\n    switch (numChannels) {\n      case 1:\n        this.grayscale();\n        break;\n      case 3:\n        this.rgb();\n        break;\n      case 4:\n        this.rgba();\n        break;\n      default:\n        throw new Error(`Conversion failed due to unsupported number of channels: ${this.channels}`);\n    }\n    return this;\n  }\n\n  /**\n   * Save the image to the given path.\n   * @param {string} path The path to save the image to.\n   */\n  async save(path: string) {\n    if (IS_BROWSER_OR_WEBWORKER) {\n      if (apis.IS_WEBWORKER_ENV) {\n        throw new Error('Unable to save an image from a Web Worker.');\n      }\n\n      const extension = path.split('.').pop()?.toLowerCase();\n      const mime = CONTENT_TYPE_MAP.get(extension as string) ?? 'image/png';\n\n      // Convert image to Blob\n      const blob = await this.toBlob(mime);\n\n      // Convert the canvas content to a data URL\n      const dataURL = URL.createObjectURL(blob);\n\n      // Create an anchor element with the data URL as the href attribute\n      const downloadLink = document.createElement('a');\n      downloadLink.href = dataURL;\n\n      // Set the download attribute to specify the desired filename for the downloaded image\n      downloadLink.download = path;\n\n      // Trigger the download\n      downloadLink.click();\n\n      // Clean up: remove the anchor element from the DOM\n      downloadLink.remove();\n    } else if (!env.useFS) {\n      throw new Error('Unable to save the image because filesystem is disabled in this environment.');\n    }\n  }\n\n  toSharp() {\n    if (IS_BROWSER_OR_WEBWORKER) {\n      throw new Error('toSharp() is only supported in server-side environments.');\n    }\n  }\n}\n\n/**\n * Helper function to load an image from a URL, path, etc.\n */\nexport const load_image = RawImage.read.bind(RawImage);\n","/**\n * @module generation/stopping_criteria\n */\n\nimport { Callable } from '../utils/generic.js';\n\n// NOTE:\n// Stopping Criteria returns a list of `batch_size` booleans, indicating whether each sequence in the batch should be stopped.\n\n/**\n * Abstract base class for all stopping criteria that can be applied during generation.\n */\nexport class StoppingCriteria extends Callable {\n  /**\n   *\n   * @param {number[][]} input_ids (`number[][]` of shape `(batch_size, sequence_length)`):\n   * Indices of input sequence tokens in the vocabulary.\n   * @param {number[][]} scores scores (`number[][]` of shape `(batch_size, config.vocab_size)`):\n   * Prediction scores of a language modeling head. These can be scores for each vocabulary token before SoftMax\n   * or scores for each vocabulary token after SoftMax.\n   * @returns {boolean[]} A list of booleans indicating whether each sequence should be stopped.\n   */\n  _call(input_ids: number[][], scores: number[][]) {\n    throw Error('StoppingCriteria needs to be subclassed');\n  }\n}\n/**\n */\nexport class StoppingCriteriaList extends Callable {\n  /**\n   * Constructs a new instance of `StoppingCriteriaList`.\n   */\n  criteria: StoppingCriteria[];\n  constructor() {\n    super();\n    this.criteria = [];\n  }\n\n  /**\n   * Adds a new stopping criterion to the list.\n   *\n   * @param {StoppingCriteria} item The stopping criterion to add.\n   */\n  push(item: StoppingCriteria) {\n    this.criteria.push(item);\n  }\n\n  /**\n   * Adds multiple stopping criteria to the list.\n   *\n   * @param {StoppingCriteria|StoppingCriteriaList|StoppingCriteria[]} items The stopping criteria to add.\n   */\n  extend(items: StoppingCriteria | StoppingCriteriaList | StoppingCriteria[]) {\n    if (items instanceof StoppingCriteriaList) {\n      items = items.criteria;\n    } else if (items instanceof StoppingCriteria) {\n      items = [items];\n    }\n    this.criteria.push(...items);\n  }\n\n  _call(input_ids: number[][], scores: number[][]) {\n    const is_done = new Array(input_ids.length).fill(false);\n    for (const criterion of this.criteria) {\n      const criterion_done = criterion._call(input_ids, scores);\n      for (let i = 0; i < is_done.length; ++i) {\n        is_done[i] ||= (criterion_done as any)[i];\n      }\n    }\n    return is_done;\n  }\n\n  [Symbol.iterator]() {\n    return this.criteria.values();\n  }\n}\n\n/**\n * This class can be used to stop generation whenever the full generated number of tokens exceeds `max_length`.\n * Keep in mind for decoder-only type of transformers, this will include the initial prompted tokens.\n */\nexport class MaxLengthCriteria extends StoppingCriteria {\n  /**\n   *\n   * @param {number} max_length The maximum length that the output sequence can have in number of tokens.\n   * @param {number} [max_position_embeddings=null] The maximum model length, as defined by the model's `config.max_position_embeddings` attribute.\n   */\n  max_length: number;\n  max_position_embeddings: number | null;\n  constructor(max_length: number, max_position_embeddings: number | null = null) {\n    super();\n    this.max_length = max_length;\n    this.max_position_embeddings = max_position_embeddings;\n  }\n\n  _call(input_ids: number[][]) {\n    return input_ids.map((ids) => ids.length >= this.max_length);\n  }\n}\n\n// TODO: add MaxTimeCriteria\n\n/**\n * This class can be used to stop generation whenever the \"end-of-sequence\" token is generated.\n * By default, it uses the `model.generation_config.eos_token_id`.\n */\nexport class EosTokenCriteria extends StoppingCriteria {\n  /**\n   *\n   * @param {number|number[]} eos_token_id The id of the *end-of-sequence* token.\n   * Optionally, use a list to set multiple *end-of-sequence* tokens.\n   */\n  eos_token_id: number | number[];\n  constructor(eos_token_id: number | number[]) {\n    super();\n    if (!Array.isArray(eos_token_id)) {\n      eos_token_id = [eos_token_id];\n    }\n    this.eos_token_id = eos_token_id;\n  }\n\n  /**\n   *\n   * @param {number[][]} input_ids\n   * @param {number[][]} scores\n   * @returns {boolean[]}\n   */\n  _call(input_ids: number[][], scores: number[][]) {\n    return input_ids.map((ids) => {\n      const last = ids.at(-1);\n      // NOTE: We use == instead of === to allow for number/bigint comparison\n      if (Array.isArray(this.eos_token_id)) {\n        return this.eos_token_id.some((eos_id: number) => last == eos_id);\n      } else {\n        return last == this.eos_token_id;\n      }\n    });\n  }\n}\n\n/**\n * This class can be used to stop generation whenever the user interrupts the process.\n */\nexport class InterruptableStoppingCriteria extends StoppingCriteria {\n  interrupted: boolean;\n  constructor() {\n    super();\n    this.interrupted = false;\n  }\n\n  interrupt() {\n    this.interrupted = true;\n  }\n\n  reset() {\n    this.interrupted = false;\n  }\n\n  _call(input_ids: number[][], scores: number[][]) {\n    return new Array(input_ids.length).fill(this.interrupted);\n  }\n}\n","/**\n * @module generation/logits_sampler\n */\n\nimport { Callable } from '../utils/generic';\nimport { Tensor, topk } from '../utils/tensor';\n\nimport { max, softmax } from '../utils/maths';\nimport { GenerationConfig } from './configuration_utils.js';\n\ntype TypedArray =\n  | Int8Array\n  | Uint8Array\n  | Uint8ClampedArray\n  | Int16Array\n  | Uint16Array\n  | Int32Array\n  | Uint32Array\n  | Float32Array\n  | Float64Array;\n\n/**\n * Sampler is a base class for all sampling methods used for text generation.\n */\nexport class LogitsSampler extends Callable {\n  /**\n   * Creates a new Sampler object with the specified generation config.\n   * @param {GenerationConfig} generation_config The generation config.\n   */\n  generation_config: GenerationConfig;\n  constructor(generation_config: GenerationConfig) {\n    super();\n    this.generation_config = generation_config;\n  }\n\n  /**\n   * Executes the sampler, using the specified logits.\n   * @param {Tensor} logits\n   * @returns {Promise<[bigint, number][]>}\n   */\n  async _call(logits: Tensor) {\n    // Sample from logits, of dims [batch, sequence_length, vocab_size].\n    // If index is specified, sample from [batch, index, vocab_size].\n    return this.sample(logits);\n  }\n\n  /**\n   * Abstract method for sampling the logits.\n   * @param {Tensor} logits\n   * @throws {Error} If not implemented in subclass.\n   * @returns {Promise<[bigint, number][]>}\n   */\n  async sample(logits: Tensor): Promise<[bigint, number][]> {\n    throw Error('sample should be implemented in subclasses.');\n  }\n\n  /**\n   * Returns the specified logits as an array, with temperature applied.\n   * @param {Tensor} logits\n   * @param {number} index\n   * @returns {Float32Array}\n   */\n  getLogits(logits: Tensor, index: number) {\n    let vocabSize = logits.dims.at(-1);\n\n    let logs = /** @type {Float32Array} */ logits.data;\n\n    if (index === -1) {\n      logs = logs.slice(-vocabSize);\n    } else {\n      let startIndex = index * vocabSize;\n      logs = logs.slice(startIndex, startIndex + vocabSize);\n    }\n    return logs;\n  }\n\n  /**\n   * Selects an item randomly based on the specified probabilities.\n   * @param {import(\"../transformers.js\").DataArray} probabilities An array of probabilities to use for selection.\n   * @returns {number} The index of the selected item.\n   */\n  randomSelect(probabilities: Float32Array) {\n    // Return index of chosen item\n    let sumProbabilities = 0;\n    for (let i = 0; i < probabilities.length; ++i) {\n      sumProbabilities += probabilities[i];\n    }\n\n    let r = Math.random() * sumProbabilities;\n    for (let i = 0; i < probabilities.length; ++i) {\n      r -= probabilities[i];\n      if (r <= 0) {\n        return i;\n      }\n    }\n    return 0; // return first (most probable) as a fallback\n  }\n\n  /**\n   * Returns a Sampler object based on the specified options.\n   * @param {GenerationConfig} generation_config An object containing options for the sampler.\n   * @returns {LogitsSampler} A Sampler object.\n   */\n  static getSampler(generation_config: GenerationConfig) {\n    // - *greedy decoding*: `num_beams=1` and `do_sample=False`\n    // - *contrastive search*: `penalty_alpha>0` and `top_k>1`\n    // - *multinomial sampling*: `num_beams=1` and `do_sample=True`\n    // - *beam-search decoding*: `num_beams>1` and `do_sample=False`\n    // - *beam-search multinomial sampling*: `num_beams>1` and `do_sample=True`\n    // - *diverse beam-search decoding*: `num_beams>1` and `num_beam_groups>1`\n    // - *constrained beam-search decoding*: `constraints!=None` or `force_words_ids!=None`\n\n    // NOTE: beam search is implemented directly into the generation function\n    if (generation_config.do_sample) {\n      return new MultinomialSampler(generation_config);\n    } else if (generation_config.num_beams > 1) {\n      return new BeamSearchSampler(generation_config);\n    } else {\n      if (generation_config.num_return_sequences > 1) {\n        throw Error(\n          `num_return_sequences has to be 1 when doing greedy search, but is ${generation_config.num_return_sequences}.`,\n        );\n      }\n      return new GreedySampler(generation_config);\n    }\n  }\n}\n\n/**\n * Class representing a Greedy Sampler.\n */\nclass GreedySampler extends LogitsSampler {\n  /**\n   * Sample the maximum probability of a given logits tensor.\n   * @param {Tensor} logits\n   * @returns {Promise<[bigint, number][]>} An array with a single tuple, containing the index of the maximum value and a meaningless score (since this is a greedy search).\n   */\n  async sample(logits: Tensor): Promise<[bigint, number][]> {\n    // NOTE: no need to do log_softmax here since we only take the maximum\n    const argmax = max(logits.data as TypedArray)[1];\n\n    // Note: score is meaningless in this context, since we are performing\n    // greedy search (p = 1 => log(p) = 0)\n    return [[BigInt(argmax), 0]];\n  }\n}\n\n/**\n * Class representing a MultinomialSampler.\n */\nclass MultinomialSampler extends LogitsSampler {\n  /**\n   * Sample from the logits.\n   * @param {Tensor} logits\n   * @returns {Promise<[bigint, number][]>}\n   */\n  async sample(logits: Tensor): Promise<[bigint, number][]> {\n    let k = logits.dims.at(-1); // defaults to vocab size\n    if (this.generation_config.top_k > 0) {\n      k = Math.min(this.generation_config.top_k, k);\n    }\n\n    // Get top k tokens\n    const [v, i] = await topk(logits, k);\n\n    // Compute softmax over logits\n    const probabilities = softmax(/** @type {Float32Array} */ v.data);\n\n    return Array.from({ length: this.generation_config.num_beams }, () => {\n      const sampledIndex = this.randomSelect(probabilities as Float32Array);\n      return [\n        i.data[sampledIndex], // token id\n        Math.log(probabilities[sampledIndex]), // score\n      ];\n    });\n  }\n}\n\n/**\n * Class representing a BeamSearchSampler.\n */\nclass BeamSearchSampler extends LogitsSampler {\n  /**\n   * Sample from the logits.\n   * @param {Tensor} logits\n   * @returns {Promise<[bigint, number][]>}\n   */\n  async sample(logits: Tensor): Promise<[bigint, number][]> {\n    let k = logits.dims.at(-1); // defaults to vocab size\n    if (this.generation_config.top_k > 0) {\n      k = Math.min(this.generation_config.top_k, k);\n    }\n\n    // Get top k tokens\n    const [v, i] = await topk(logits, k);\n\n    // Compute softmax over logits\n    const probabilities = softmax(/** @type {Float32Array} */ v.data);\n\n    return Array.from({ length: this.generation_config.num_beams }, (_, x) => {\n      return [\n        i.data[x], // token id\n        Math.log(probabilities[x]), // score\n      ];\n    });\n  }\n}\n","import { GenerationConfig } from '../../generation/configuration_utils.js';\nimport { GenerationFunctionParameters } from '../../generation/parameters';\nexport class WhisperGenerationConfig extends GenerationConfig {\n  /**\n   * Whether to return the timestamps with the text. This enables the `WhisperTimestampsLogitsProcessor`.\n   * @type {boolean}\n   */\n  return_timestamps = null;\n\n  /**\n   * Whether to return token-level timestamps\n   * with the text. This can be used with or without the `return_timestamps` option. To get word-level\n   * timestamps, use the tokenizer to group the tokens into words.\n   * @type {boolean}\n   */\n  return_token_timestamps = null;\n\n  /**\n   * The number of audio frames available in this chunk. This is only used generating word-level timestamps.\n   * @type {number}\n   */\n  num_frames = null;\n\n  /**\n   * Alignment heads to predict word-level timestamps. This is a list of [layer, head] pairs that\n   * select the cross-attention heads that are highly correlated to word-level timing.\n   * @type {[number, number][]}\n   */\n  alignment_heads = null;\n\n  /**\n   * Task to use for generation, either \"translate\" or \"transcribe\".\n   * @type {string}\n   */\n  task = null;\n\n  /**\n   * Language token to use for generation, can be either in the form of `<|en|>`, `en` or `english`.\n   * You can find all the possible language tokens in the `model.generation_config.lang_to_id` dictionary.\n   * @type {string}\n   */\n  language = null;\n\n  /**\n   * The id of the `\"<|notimestamps|>\"` token.\n   * @type {number}\n   */\n  no_timestamps_token_id = null;\n\n  /**\n   * Rank-1 list of token IDs created by passing text to [`~WhisperProcessor.get_prompt_ids`] that is\n   * provided as a prompt to each chunk. This can be used to provide or \"prompt-engineer\" a context for\n   * transcription, e.g. custom vocabularies or proper nouns to make it more likely to predict those words\n   * correctly. It cannot be used in conjunction with `decoder_start_token_id` as it overwrites this value.\n   * @type {number[]}\n   */\n  prompt_ids = null;\n\n  /**\n   * Whether the model is multilingual or not.\n   * @type {boolean}\n   */\n  is_multilingual = null;\n\n  /**\n   * (Optional) A mapping from language tokens to their corresponding IDs.\n   * Only required if the model is multilingual.\n   * @type {Record<string, number>|null}\n   */\n  lang_to_id = null;\n\n  /**\n   * (Optional) A mapping from task tokens to their corresponding IDs.\n   * @type {Record<string, number>|null}\n   */\n  task_to_id = null;\n\n  /**\n   * Used to set the maximum value of the initial timestamp. This is used to prevent the model from\n   * predicting timestamps that are too far in the future.\n   * @type {number}\n   */\n  max_initial_timestamp_index = 1;\n}\n\n/**\n * @typedef {import('../../generation/parameters.js').GenerationFunctionParameters & {generation_config: WhisperGenerationConfig} & WhisperGenerationConfig} WhisperGenerationFunctionParameters\n */\n\nexport type WhisperGenerationFunctionParameters = GenerationFunctionParameters & {generation_config: WhisperGenerationConfig} & WhisperGenerationConfig;","/**\n * @file Definitions of all models available in Transformers.js.\n *\n * **Example:** Load and run an `AutoModel`.\n *\n * ```javascript\n * import { AutoModel, AutoTokenizer } from '@huggingface/transformers';\n *\n * let tokenizer = await AutoTokenizer.from_pretrained('Xenova/bert-base-uncased');\n * let model = await AutoModel.from_pretrained('Xenova/bert-base-uncased');\n *\n * let inputs = await tokenizer('I love transformers!');\n * let { logits } = await model(inputs);\n * // Tensor {\n * //     data: Float32Array(183132) [-7.117443084716797, -7.107812881469727, -7.092104911804199, ...]\n * //     dims: (3) [1, 6, 30522],\n * //     type: \"float32\",\n * //     size: 183132,\n * // }\n * ```\n *\n * We also provide other `AutoModel`s (listed below), which you can use in the same way as the Python library. For example:\n *\n * **Example:** Load and run an `AutoModelForSeq2SeqLM`.\n * ```javascript\n * import { AutoModelForSeq2SeqLM, AutoTokenizer } from '@huggingface/transformers';\n *\n * let tokenizer = await AutoTokenizer.from_pretrained('Xenova/t5-small');\n * let model = await AutoModelForSeq2SeqLM.from_pretrained('Xenova/t5-small');\n *\n * let { input_ids } = await tokenizer('translate English to German: I love transformers!');\n * let outputs = await model.generate(input_ids);\n * let decoded = tokenizer.decode(outputs[0], { skip_special_tokens: true });\n * // 'Ich liebe Transformatoren!'\n * ```\n *\n * @module models\n */\n\nimport { AutoConfig, getKeyValueShapes, PretrainedConfig, TransformersJSConfig } from './configs';\n\nimport { deviceToExecutionProviders, createInferenceSession, isONNXTensor, isONNXProxy } from './backends/onnx';\nimport {\n  DATA_TYPES,\n  DEFAULT_DEVICE_DTYPE_MAPPING,\n  DEFAULT_DTYPE_SUFFIX_MAPPING,\n  isWebGpuFp16Supported,\n} from './utils/dtypes';\n\nimport { Callable } from './utils/generic';\n\nimport { mergeArrays, pick, ProgressCallback } from './utils/core';\n\nimport { getModelFile, getModelJSON } from './utils/hub';\n\nimport { GITHUB_ISSUE_URL } from './utils/constants';\n\nimport {\n  LogitsProcessorList,\n  ForcedBOSTokenLogitsProcessor,\n  ForcedEOSTokenLogitsProcessor,\n  SuppressTokensAtBeginLogitsProcessor,\n  WhisperTimeStampLogitsProcessor,\n  NoRepeatNGramLogitsProcessor,\n  RepetitionPenaltyLogitsProcessor,\n  NoBadWordsLogitsProcessor,\n  MinLengthLogitsProcessor,\n  MinNewTokensLengthLogitsProcessor,\n  TemperatureLogitsWarper,\n  TopKLogitsWarper,\n  TopPLogitsWarper,\n  ClassifierFreeGuidanceLogitsProcessor,\n  LogitsProcessor,\n} from './generation/logits_process';\n\nimport { GenerationConfig } from './generation/configuration_utils';\n\nimport {\n  cat,\n  mean,\n  zeros,\n  zeros_like,\n  ones,\n  ones_like,\n  full,\n  full_like,\n  stack,\n  std_mean,\n  Tensor,\n} from './utils/tensor';\nimport { RawImage } from './utils/image';\n\nimport { dynamic_time_warping, max, medianFilter } from './utils/maths';\nimport { EosTokenCriteria, MaxLengthCriteria, StoppingCriteriaList } from './generation/stopping_criteria';\nimport { LogitsSampler } from './generation/logits_sampler';\nimport { apis } from './env';\n\nimport { WhisperGenerationConfig, WhisperGenerationFunctionParameters } from './models/whisper/generation_whisper';\nimport { whisper_language_to_code } from './models/whisper/common_whisper';\nimport { GenerationFunctionParameters } from './generation/parameters';\n\n//////////////////////////////////////////////////\n// Model types: used internally\nconst MODEL_TYPES = {\n  EncoderOnly: 0,\n  EncoderDecoder: 1,\n  Seq2Seq: 2,\n  Vision2Seq: 3,\n  DecoderOnly: 4,\n  MaskGeneration: 5,\n  ImageTextToText: 6,\n  Musicgen: 7,\n  MultiModality: 8,\n  Phi3V: 9,\n};\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Helper functions\n\n// NOTE: These will be populated fully later\nconst MODEL_TYPE_MAPPING = new Map();\nconst MODEL_NAME_TO_CLASS_MAPPING = new Map();\nconst MODEL_CLASS_TO_NAME_MAPPING = new Map();\n\n/**\n * Constructs an InferenceSession using a model file located at the specified path.\n * @param {string} pretrained_model_name_or_path The path to the directory containing the model file.\n * @param {string} fileName The name of the model file.\n * @param {import('./utils/hub.js').PretrainedModelOptions} options Additional options for loading the model.\n * @returns {Promise<{buffer: Uint8Array, session_options: Object, session_config: Object}>} A Promise that resolves to the data needed to create an InferenceSession object.\n * @private\n */\nasync function getSession(pretrained_model_name_or_path: string, fileName: string, options: any) {\n  const custom_config = options.config?.['transformers.js_config'] ?? {};\n  let device = options.device ?? custom_config.device;\n  if (device && typeof device !== 'string') {\n    if (device.hasOwnProperty(fileName)) {\n      device = device[fileName];\n    } else {\n      console.warn(`device not specified for \"${fileName}\". Using the default device.`);\n      device = null;\n    }\n  }\n\n  // If the device is not specified, we use the default (supported) execution providers.\n  const selectedDevice =\n    /** @type {import(\"./utils/devices.js\").DeviceType} */ device ?? (apis.IS_NODE_ENV ? 'cpu' : 'wasm');\n  const executionProviders = deviceToExecutionProviders(selectedDevice);\n\n  // If options.dtype is specified, we use it to choose the suffix for the model file.\n  // Otherwise, we use the default dtype for the device.\n  let dtype = options.dtype ?? custom_config.dtype;\n  if (typeof dtype !== 'string') {\n    if (dtype && dtype.hasOwnProperty(fileName)) {\n      dtype = dtype[fileName];\n    } else {\n      dtype =\n        DEFAULT_DEVICE_DTYPE_MAPPING[selectedDevice as keyof typeof DEFAULT_DEVICE_DTYPE_MAPPING] ?? DATA_TYPES.fp32;\n      console.warn(\n        `dtype not specified for \"${fileName}\". Using the default dtype (${dtype}) for this device (${selectedDevice}).`,\n      );\n    }\n  }\n\n  if (dtype === DATA_TYPES.auto) {\n    // Try to choose the auto dtype based on the custom config\n    let config_dtype = custom_config.dtype;\n    if (typeof config_dtype !== 'string') {\n      config_dtype = config_dtype[fileName];\n    }\n\n    if (config_dtype && config_dtype !== DATA_TYPES.auto && DATA_TYPES.hasOwnProperty(config_dtype)) {\n      // Defined by the custom config, and is not \"auto\"\n      dtype = config_dtype;\n    } else {\n      // Choose default dtype based on device, falling back to fp32\n      dtype =\n        DEFAULT_DEVICE_DTYPE_MAPPING[selectedDevice as keyof typeof DEFAULT_DEVICE_DTYPE_MAPPING] ?? DATA_TYPES.fp32;\n    }\n  }\n\n  const selectedDtype = /** @type {import(\"./utils/dtypes.js\").DataType} */ dtype;\n\n  if (!DEFAULT_DTYPE_SUFFIX_MAPPING.hasOwnProperty(selectedDtype)) {\n    throw new Error(`Invalid dtype: ${selectedDtype}. Should be one of: ${Object.keys(DATA_TYPES).join(', ')}`);\n  } else if (selectedDtype === DATA_TYPES.fp16 && selectedDevice === 'webgpu' && !(await isWebGpuFp16Supported())) {\n    throw new Error(`The device (${selectedDevice}) does not support fp16.`);\n  }\n\n  // Only valid for models with a decoder\n  const kv_cache_dtype = custom_config.kv_cache_dtype\n    ? typeof custom_config.kv_cache_dtype === 'string'\n      ? custom_config.kv_cache_dtype\n      : (custom_config.kv_cache_dtype[selectedDtype] ?? 'float32')\n    : undefined;\n\n  if (kv_cache_dtype && !['float32', 'float16'].includes(kv_cache_dtype)) {\n    throw new Error(`Invalid kv_cache_dtype: ${kv_cache_dtype}. Should be one of: float32, float16`);\n  }\n\n  const session_config = {\n    dtype: selectedDtype,\n    kv_cache_dtype,\n  };\n\n  // Construct the model file name\n  const suffix = DEFAULT_DTYPE_SUFFIX_MAPPING[selectedDtype as keyof typeof DEFAULT_DTYPE_SUFFIX_MAPPING];\n  const modelFileName = `${options.subfolder ?? ''}/${fileName}${suffix}.onnx`;\n\n  const session_options = { ...options.session_options };\n\n  // Overwrite `executionProviders` if not specified\n  session_options.executionProviders ??= executionProviders;\n\n  // Overwrite `freeDimensionOverrides` if specified in config and not set in session options\n  const free_dimension_overrides = custom_config.free_dimension_overrides;\n  if (free_dimension_overrides) {\n    session_options.freeDimensionOverrides ??= free_dimension_overrides;\n  } else if (selectedDevice.startsWith('webnn') && !session_options.freeDimensionOverrides) {\n    console.warn(\n      'WebNN does not currently support dynamic shapes and requires `free_dimension_overrides` to be set in config.json as a field within \"transformers.js_config\". ' +\n      'When `free_dimension_overrides` is not set, you may experience significant performance degradation.',\n    );\n  }\n\n  const bufferPromise = getModelFile(pretrained_model_name_or_path, modelFileName, true, options);\n\n  // handle onnx external data files\n  const use_external_data_format = options.use_external_data_format ?? custom_config.use_external_data_format;\n  /** @type {Promise<{path: string, data: Uint8Array}>[]} */\n  let externalDataPromises = [];\n  if (\n    use_external_data_format &&\n    (use_external_data_format === true ||\n      (typeof use_external_data_format === 'object' &&\n        use_external_data_format.hasOwnProperty(fileName) &&\n        use_external_data_format[fileName] === true))\n  ) {\n    if (apis.IS_NODE_ENV) {\n      throw new Error('External data format is not yet supported in Node.js');\n    }\n    const path = `${fileName}${suffix}.onnx_data`;\n    const fullPath = `${options.subfolder ?? ''}/${path}`;\n    externalDataPromises.push(\n      new Promise(async (resolve, reject) => {\n        const data = await getModelFile(pretrained_model_name_or_path, fullPath, true, options);\n        resolve({ path, data });\n      }),\n    );\n  } else if (session_options.externalData !== undefined) {\n    externalDataPromises = session_options.externalData.map(async (ext: any) => {\n      if (typeof ext.data === 'string') {\n        const ext_buffer = await getModelFile(pretrained_model_name_or_path, ext.data, true, options);\n        return { ...ext, data: ext_buffer };\n      }\n      return ext;\n    });\n  }\n\n  if (externalDataPromises.length > 0) {\n    session_options.externalData = await Promise.all(externalDataPromises);\n  }\n\n  if (selectedDevice === 'webgpu') {\n    const shapes = getKeyValueShapes(options.config, {\n      prefix: 'present',\n    });\n    if (Object.keys(shapes).length > 0 && !isONNXProxy()) {\n      // Only set preferredOutputLocation if shapes are present and we aren't proxying ONNX\n      /** @type {Record<string, import('onnxruntime-common').Tensor.DataLocation>} */\n      const preferredOutputLocation: Record<string, any> = {};\n      for (const key in shapes) {\n        preferredOutputLocation[key] = 'gpu-buffer';\n      }\n      session_options.preferredOutputLocation = preferredOutputLocation;\n    }\n  }\n\n  const buffer = (await bufferPromise) as Uint8Array;\n\n  return { buffer, session_options, session_config };\n}\n\n/**\n * Helper function to create multiple InferenceSession objects.\n *\n * @param {string} pretrained_model_name_or_path The path to the directory containing the model file.\n * @param {Record<string, string>} names The names of the model files to load.\n * @param {import('./utils/hub.js').PretrainedModelOptions} options Additional options for loading the model.\n * @returns {Promise<Record<string, any>>} A Promise that resolves to a dictionary of InferenceSession objects.\n * @private\n */\nasync function constructSessions(pretrained_model_name_or_path: string, names: Record<string, string>, options: any) {\n  return Object.fromEntries(\n    await Promise.all(\n      Object.keys(names).map(async (name) => {\n        const { buffer, session_options, session_config } = await getSession(\n          pretrained_model_name_or_path,\n          names[name],\n          options,\n        );\n        const session = await createInferenceSession(buffer, session_options, session_config);\n        return [name, session];\n      }),\n    ),\n  );\n}\n\n/**\n * Helper function to load multiple optional configuration files\n * @param {string} pretrained_model_name_or_path The path to the directory containing the config file.\n * @param {Record<string, string>} names The names of the config files to load.\n * @param {import('./utils/hub.js').PretrainedModelOptions} options Additional options for loading the configs.\n * @returns {Promise<Record<string, any>>} A Promise that resolves to a dictionary of configuration objects.\n * @private\n */\nasync function getOptionalConfigs(pretrained_model_name_or_path: string, names: Record<string, string>, options: any) {\n  return Object.fromEntries(\n    await Promise.all(\n      Object.keys(names).map(async (name) => {\n        const config = await getModelJSON(pretrained_model_name_or_path, names[name], false, options);\n        return [name, config];\n      }),\n    ),\n  );\n}\n\n/**\n * Validate model inputs\n * @param {Object} session The InferenceSession object that will be run.\n * @param {Object} inputs The inputs to check.\n * @returns {Record<string, Tensor>} The checked inputs.\n * @throws {Error} If any inputs are missing.\n * @private\n */\nfunction validateInputs(session: any, inputs: any) {\n  /**\n   * NOTE: Create either a shallow or deep copy based on `onnx.wasm.proxy`\n   * @type {Record<string, Tensor>}\n   */\n  const checkedInputs = Object.create(null);\n  const missingInputs = [];\n  for (const inputName of session.inputNames) {\n    const tensor = inputs[inputName];\n    // Rare case where one of the model's input names corresponds to a built-in\n    // object name (e.g., toString), which would cause a simple (!tensor) check to fail,\n    // because it's not undefined but a function.\n    if (!(tensor instanceof Tensor)) {\n      missingInputs.push(inputName);\n      continue;\n    }\n    // NOTE: When `env.wasm.proxy is true` the tensor is moved across the Worker\n    // boundary, transferring ownership to the worker and invalidating the tensor.\n    // So, in this case, we simply sacrifice a clone for it.\n    checkedInputs[inputName] = isONNXProxy() ? tensor.clone() : tensor;\n  }\n  if (missingInputs.length > 0) {\n    throw new Error(\n      `An error occurred during model execution: \"Missing the following inputs: ${missingInputs.join(', ')}.`,\n    );\n  }\n\n  const numInputsProvided = Object.keys(inputs).length;\n  const numInputsNeeded = session.inputNames.length;\n  if (numInputsProvided > numInputsNeeded) {\n    // No missing inputs, but too many inputs were provided.\n    // Warn the user and ignore the extra inputs.\n    let ignored = Object.keys(inputs).filter((inputName) => !session.inputNames.includes(inputName));\n    console.warn(\n      `WARNING: Too many inputs were provided (${numInputsProvided} > ${numInputsNeeded}). The following inputs will be ignored: \"${ignored.join(', ')}\".`,\n    );\n  }\n\n  return checkedInputs;\n}\n\n/**\n * Executes an InferenceSession using the specified inputs.\n * NOTE: `inputs` must contain at least the input names of the model.\n *  - If additional inputs are passed, they will be ignored.\n *  - If inputs are missing, an error will be thrown.\n *\n * @param {Object} session The InferenceSession object to run.\n * @param {Object} inputs An object that maps input names to input tensors.\n * @returns {Promise<Object>} A Promise that resolves to an object that maps output names to output tensors.\n * @private\n */\nasync function sessionRun(session: any, inputs: any) {\n  console.log(`Running session ${session.path || 'unknown'}:`, {\n    inputNames: session.inputNames,\n    inputShapes: Object.fromEntries(\n      Object.entries(inputs).map(([k, v]) => [k, (v as any).dims])\n    )\n  });\n  const checkedInputs = validateInputs(session, inputs);\n  try {\n    // pass the original ort tensor\n    const ortFeed = Object.fromEntries(\n      Object.entries(checkedInputs).map(([k, v]) => [k, (v as Tensor).ort_tensor]),\n    );\n    let output = await session.run(ortFeed);\n    console.log('Session run successful:', {\n      outputNames: Object.keys(output)\n    });\n    output = replaceTensors(output);\n    return output;\n  } catch (e) {\n    // Error messages can be long (nested) and uninformative. For this reason,\n    // we apply minor formatting to show the most important information\n    const formatted = Object.fromEntries(\n      Object.entries(checkedInputs).map(([k, v]) => [\n        k,\n        {\n          // Extract these properties from the underlying ORT tensor\n          type: (v as Tensor).type,\n          dims: (v as Tensor).dims,\n          data: (v as Tensor).data,\n        },\n      ]),\n    );\n\n    console.error('Session run failed:', {\n      e,\n      session: session.path,\n      inputNames: session.inputNames,\n      inputShapes: Object.fromEntries(\n        Object.entries(inputs).map(([k, v]) => [k, (v as any).dims])\n      )\n    });\n\n    // This usually occurs when the inputs are of the wrong type.\n    console.error(`An error occurred during model execution: \"${e}\".`);\n    console.error('Inputs given to model:', formatted);\n    throw e;\n  }\n}\n\n/**\n * Replaces ONNX Tensor objects with custom Tensor objects to support additional functions.\n * @param {Object} obj The object to replace tensor objects in.\n * @returns {Object} The object with tensor objects replaced by custom Tensor objects.\n * @private\n */\nfunction replaceTensors(obj: any) {\n  for (let prop in obj) {\n    if (isONNXTensor(obj[prop])) {\n      obj[prop] = new Tensor(obj[prop]);\n    } else if (typeof obj[prop] === 'object') {\n      replaceTensors(obj[prop]);\n    }\n  }\n  return obj;\n}\n\n/**\n * Converts an array or Tensor of integers to an int64 Tensor.\n * @param {any[]|Tensor} items The input integers to be converted.\n * @returns {Tensor} The int64 Tensor with the converted values.\n * @throws {Error} If the input array is empty or the input is a batched Tensor and not all sequences have the same length.\n * @private\n */\nfunction toI64Tensor(items: any) {\n  if (items instanceof Tensor) {\n    return items;\n  }\n  // items is an array\n  if (items.length === 0) {\n    throw Error('items must be non-empty');\n  }\n\n  if (Array.isArray(items[0])) {\n    // batched\n    if (items.some((x: any) => x.length !== items[0].length)) {\n      throw Error(\n        \"Unable to create tensor, you should probably activate truncation and/or padding with 'padding=True' and/or 'truncation=True' to have batched tensors with the same length.\",\n      );\n    }\n\n    return new Tensor('int64', BigInt64Array.from(items.flat().map((x: any) => BigInt(x))), [\n      items.length,\n      items[0].length,\n    ]);\n  } else {\n    //flat\n    return new Tensor('int64', BigInt64Array.from(items.map((x: any) => BigInt(x))), [1, items.length]);\n  }\n}\n\n/**\n * Creates a boolean tensor with a single value.\n * @param {boolean} value The value of the tensor.\n * @returns {Tensor} The boolean tensor.\n * @private\n */\nfunction boolTensor(value: boolean) {\n  return new Tensor('bool', [value], [1]);\n}\n\n// JS doesn't support mixins, so we define some reused functions here, and allow \"this\" to be passed in\n/**\n * Perform forward pass on the seq2seq model (both encoder and decoder).\n * @param {Object} self The seq2seq model object.\n * @param {Object} model_inputs The input object for the model containing encoder and decoder inputs.\n * @returns {Promise<Seq2SeqLMOutput>} Promise that resolves with the output of the seq2seq model.\n * @private\n */\nasync function seq2seqForward(self: any, model_inputs: any) {\n  let { encoder_outputs, input_ids, decoder_input_ids, ...other_decoder_inputs } = model_inputs;\n  // Encode if needed\n  if (!encoder_outputs) {\n    const encoder_inputs = pick(model_inputs, self.sessions['model'].inputNames);\n    // Encoder outputs are not given, so we must compute them.\n    encoder_outputs = (await encoderForward(self, encoder_inputs)).last_hidden_state;\n  }\n\n  other_decoder_inputs.input_ids = decoder_input_ids;\n  other_decoder_inputs.encoder_hidden_states = encoder_outputs;\n\n  if (self.sessions['decoder_model_merged'].inputNames.includes('encoder_attention_mask')) {\n    other_decoder_inputs.encoder_attention_mask = model_inputs.attention_mask;\n  }\n\n  const decoderResults = await decoderForward(self, other_decoder_inputs, true);\n\n  return decoderResults;\n}\n\n/**\n * Forward pass of an encoder model.\n * @param {Object} self The encoder model.\n * @param {Object} model_inputs The input data to be used for the forward pass.\n * @returns {Promise<Object>} The model's outputs.\n * @private\n */\nasync function encoderForward(self: any, model_inputs: any) {\n  const session = self.sessions['model'];\n  const encoderFeeds = pick(model_inputs, session.inputNames);\n  if (session.inputNames.includes('inputs_embeds') && !encoderFeeds.inputs_embeds) {\n    if (!model_inputs.input_ids) {\n      throw new Error('Both `input_ids` and `inputs_embeds` are missing in the model inputs.');\n    }\n    encoderFeeds.inputs_embeds = await self.encode_text({ input_ids: model_inputs.input_ids });\n  }\n  if (session.inputNames.includes('token_type_ids') && !encoderFeeds.token_type_ids) {\n    // Assign default `token_type_ids` (all zeroes) to the `encoderFeeds` if the model expects it,\n    // but they weren't created by the tokenizer.\n    // encoderFeeds.token_type_ids = new Tensor(\n    //   'int64',\n    //   new BigInt64Array(encoderFeeds.input_ids.data.length),\n    //   encoderFeeds.input_ids.dims,\n    // );\n\n    if (!encoderFeeds.input_ids) {\n      throw new Error('Both `input_ids` and `token_type_ids` are missing in the model inputs.');\n    }\n    // Assign default `token_type_ids` (all zeroes) to the `encoderFeeds` if the model expects it,\n    // but they weren't created by the tokenizer.\n    encoderFeeds.token_type_ids = zeros_like(encoderFeeds.input_ids);\n  }\n\n  if (session.inputNames.includes('pixel_mask') && !encoderFeeds.pixel_mask) {\n    if (!encoderFeeds.pixel_values) {\n      throw new Error('Both `pixel_values` and `pixel_mask` are missing in the model inputs.');\n    }\n    // Assign default `pixel_mask` (all ones) to the `encoderFeeds` if the model expects it,\n    // but they weren't created by the processor.\n    const dims = encoderFeeds.pixel_values.dims;\n    encoderFeeds.pixel_mask = ones([dims[0], dims[2], dims[3]]);\n  }\n  // console.log(\"encoder forward running here: \", session, encoderFeeds)\n  return await sessionRun(session, encoderFeeds);\n}\n\n/**\n * Forward pass of a decoder model.\n * @param {Object} self The decoder model.\n * @param {Object} model_inputs The input data to be used for the forward pass.\n * @returns {Promise<Object>} The logits and past key values.\n * @private\n */\nasync function decoderForward(self: any, model_inputs: any, is_encoder_decoder = false) {\n  const session = self.sessions[is_encoder_decoder ? 'decoder_model_merged' : 'model'];\n\n  // Add debugging\n  console.log('Decoder inputs:', model_inputs);\n  console.log('Session config:', session.config);\n\n  const { past_key_values, ...new_model_inputs } = model_inputs;\n\n  if (session.inputNames.includes('use_cache_branch')) {\n    new_model_inputs.use_cache_branch = boolTensor(!!past_key_values);\n  }\n  if (\n    session.inputNames.includes('position_ids') &&\n    new_model_inputs.attention_mask &&\n    !new_model_inputs.position_ids\n  ) {\n    // NOTE: Handle a special case for paligemma models, where positions are 1-indexed\n    const start_index = self.config?.model_type === 'paligemma' ? 1 : 0;\n    new_model_inputs.position_ids = createPositionIds(new_model_inputs, past_key_values, start_index);\n  }\n\n  // Unpack the `past_key_values` object into model inputs\n  self.addPastKeyValues(new_model_inputs, past_key_values);\n\n  // Select only the inputs that are needed for the current session\n  const fixed = pick(new_model_inputs, session.inputNames);\n  return await sessionRun(session, fixed);\n}\n\nfunction default_merge_input_ids_with_image_features({\n  image_token_id,\n  inputs_embeds,\n  image_features,\n  input_ids,\n  attention_mask,\n}: {\n  image_token_id: number;\n  inputs_embeds: Tensor;\n  image_features: Tensor;\n  input_ids: Tensor;\n  attention_mask: Tensor;\n}) {\n  const image_tokens = input_ids.tolist().map((ids: any) =>\n    ids.reduce((acc: any, x: any, idx: any) => {\n      if (x == image_token_id) acc.push(idx);\n      return acc;\n    }, []),\n  );\n  const n_image_tokens = image_tokens.reduce((acc: any, x: any) => acc + x.length, 0);\n  const n_image_features = image_features.dims[0];\n  if (n_image_tokens !== n_image_features) {\n    throw new Error(\n      `Image features and image tokens do not match: tokens: ${n_image_tokens}, features ${n_image_features}`,\n    );\n  }\n\n  // Equivalent to performing a masked_scatter\n  let img = 0;\n  for (let i = 0; i < image_tokens.length; ++i) {\n    const tokens = image_tokens[i];\n    const embeds = inputs_embeds[i];\n    for (let j = 0; j < tokens.length; ++j) {\n      (embeds[tokens[j]].data as any).set(image_features[img++].data);\n    }\n  }\n  return { inputs_embeds, attention_mask };\n}\n\n/**\n * Forward pass of an image-text-to-text model.\n * @param {Object} self The image-text-to-text model model.\n * @param {Object} model_inputs The input data to be used for the forward pass.\n * @param {Tensor} [model_inputs.input_ids=null]\n * @param {Tensor} [model_inputs.attention_mask=null]\n * @param {Tensor} [model_inputs.pixel_values=null]\n * @param {Tensor} [model_inputs.position_ids=null]\n * @param {Tensor} [model_inputs.inputs_embeds=null]\n * @param {Tensor} [model_inputs.past_key_values=null]\n * @param {Object} [model_inputs.generation_config=null]\n * @param {Object} [model_inputs.logits_processor=null]\n * @returns {Promise<Tensor>} The model's output tensor\n * @private\n */\nasync function imageTextToTextForward(\n  self: any,\n  {\n    // Produced by the tokenizer/processor:\n    input_ids = null,\n    attention_mask = null,\n    pixel_values = null,\n\n    // Used during generation:\n    position_ids = null,\n    inputs_embeds = null,\n    past_key_values = null,\n\n    // Generic generation parameters\n    generation_config = null,\n    logits_processor = null,\n\n    // TODO: needed?\n    ...kwargs\n  },\n) {\n  if (!inputs_embeds) {\n    // 1. Extract the input embeddings\n    inputs_embeds = await self.encode_text({ input_ids, ...kwargs });\n\n    // 2. Possibly, merge text and images\n    if (pixel_values && (input_ids as any)?.dims[1] !== 1) {\n      const image_features = await self.encode_image({ pixel_values, ...kwargs });\n\n      ({ inputs_embeds, attention_mask } = self._merge_input_ids_with_image_features({\n        image_features,\n        inputs_embeds,\n        input_ids,\n        attention_mask,\n      }));\n    } else if (past_key_values && pixel_values && (input_ids as any)?.dims[1] === 1) {\n      // This is the case when we are generating with cache\n      const target_length = (input_ids as any)?.dims[1] ?? 1; // always 1\n      const past_length = (Object.values(past_key_values)[0] as any).dims.at(-2);\n\n      attention_mask = cat(\n        [\n          ones([(input_ids as any).dims[0], past_length]),\n          (attention_mask as any)?.slice(null, [(attention_mask as any).dims[1] - target_length, (attention_mask as any).dims[1]]),\n        ],\n        1,\n      ) as any;\n    }\n  }\n\n  if (!position_ids) {\n    if (self.config.model_type === 'qwen2_vl') {\n      // Special case for qwen2_vl models\n      // @ts-ignore\n      const { image_grid_thw, video_grid_thw } = kwargs;\n      [position_ids] = self.get_rope_index(input_ids, image_grid_thw, video_grid_thw, attention_mask);\n    }\n  }\n\n  const outputs = await decoderForward(\n    self,\n    {\n      inputs_embeds,\n      past_key_values,\n      attention_mask,\n      position_ids,\n      generation_config,\n      logits_processor,\n    },\n    true,\n  );\n  return outputs;\n}\n\n/**\n * Helper function to perform the following:\n * ```python\n * x = attention_mask.long().cumsum(-1) - 1\n * x.masked_fill_(attention_mask == 0, 1)\n * ```\n * @param {Tensor} attention_mask\n * @returns {{data: BigInt64Array, dims: number[]}}\n */\nfunction cumsum_masked_fill(attention_mask: Tensor, start_index = 0) {\n  const [bz, seq_len] = attention_mask.dims;\n  const attn_mask_data = attention_mask.data;\n\n  const data = new BigInt64Array(attn_mask_data.length);\n  for (let i = 0; i < bz; ++i) {\n    const start = i * seq_len;\n    let sum = BigInt(start_index);\n    for (let j = 0; j < seq_len; ++j) {\n      const index = start + j;\n      if (attn_mask_data[index] === 0n) {\n        data[index] = BigInt(1);\n      } else {\n        // === 1n\n        data[index] = sum;\n        sum += attn_mask_data[index];\n      }\n    }\n  }\n  return { data, dims: attention_mask.dims };\n}\n\n/**\n * If the model supports providing position_ids, we create position_ids on the fly for batch generation,\n * by computing the cumulative sum of the attention mask along the sequence length dimension.\n *\n * Equivalent to:\n * ```python\n * position_ids = attention_mask.long().cumsum(-1) - 1\n * position_ids.masked_fill_(attention_mask == 0, 1)\n * if past_key_values:\n *     position_ids = position_ids[:, -input_ids.shape[1] :]\n * ```\n */\nfunction createPositionIds(model_inputs: Record<string, any>, past_key_values = null, start_index = 0) {\n  const { input_ids, inputs_embeds, attention_mask } = model_inputs;\n\n  const { data, dims } = cumsum_masked_fill(attention_mask, start_index);\n  let position_ids = new Tensor('int64', data, dims);\n  if (past_key_values) {\n    const offset = -(input_ids ?? inputs_embeds).dims.at(1);\n    // position_ids = position_ids.slice(null, [offset, null]);\n    position_ids = position_ids.slice(null, [offset]);\n  }\n  return position_ids;\n}\n\nfunction decoder_prepare_inputs_for_generation(\n  self: PreTrainedModel,\n  input_ids: Tensor,\n  model_inputs: Record<string, any>,\n  generation_config: GenerationConfig,\n) {\n  if (model_inputs.past_key_values) {\n    const past_length = (Object.values(model_inputs.past_key_values)[0] as any).dims.at(-2);\n    const { input_ids, attention_mask } = model_inputs;\n\n    // Keep only the unprocessed tokens:\n    // 1 - If the length of the attention_mask exceeds the length of input_ids, then we are in a setting where\n    // some of the inputs are exclusively passed as part of the cache (e.g. when passing input_embeds as\n    // input)\n    if (attention_mask && attention_mask.dims[1] > input_ids.dims[1]) {\n      // NOTE: not needed since we only pass the generated tokens to the next forward pass\n      // const offset = -(attention_mask.dims[1] - past_length);\n      // model_inputs.input_ids = input_ids.slice(null, [offset, null]);\n    }\n    // 2 - If the past_length is smaller than input_ids', then input_ids holds all input tokens.\n    // We can discard input_ids based on the past_length.\n    else if (past_length < input_ids.dims[1]) {\n      // NOTE: Required for phi models.\n      // See https://github.com/huggingface/transformers/issues/30809#issuecomment-2111918479 for more information.\n      model_inputs.input_ids = input_ids.slice(null, [past_length, null]);\n    }\n    // 3 - Otherwise (past_length >= input_ids.shape[1]), let's assume input_ids only has unprocessed tokens.\n    else {\n      if (\n        // NOTE: Only used by VLMs (!= so that null matches undefined)\n        (self.config as any).image_token_index != null &&\n        // Equivalent to `self.config.image_token_index in input_ids` (== so that int matches bigint)\n        input_ids.data.some((x: any) => x == (self.config as any).image_token_index)\n      ) {\n        // TODO: Support multiple image tokens\n        const num_image_tokens = (self.config as any).num_image_tokens;\n        if (!num_image_tokens) {\n          throw new Error('`num_image_tokens` is missing in the model configuration.');\n        }\n\n        const num_new_tokens = input_ids.dims[1] - (past_length - num_image_tokens);\n        model_inputs.input_ids = input_ids.slice(null, [-num_new_tokens, null]);\n\n        // TODO: The attention mask should be formed from the attention mask passed in model_inputs\n        model_inputs.attention_mask = ones([1, past_length + num_new_tokens]);\n      }\n    }\n  }\n\n  return model_inputs;\n}\n\nfunction encoder_decoder_prepare_inputs_for_generation(\n  self: PreTrainedModel,\n  input_ids: Tensor,\n  model_inputs: Record<string, any>,\n  generation_config: GenerationConfig,\n) {\n  if (model_inputs.past_key_values) {\n    input_ids = input_ids.map((x: any) => [x.at(-1)]);\n  }\n\n  return {\n    ...model_inputs,\n    decoder_input_ids: toI64Tensor(input_ids),\n  };\n}\n\nfunction image_text_to_text_prepare_inputs_for_generation(\n  self: PreTrainedModel,\n  ...args: [Tensor, Record<string, any>, GenerationConfig]\n) {\n  if (self.config.is_encoder_decoder) {\n    return encoder_decoder_prepare_inputs_for_generation(self, ...args);\n  } else {\n    return decoder_prepare_inputs_for_generation(self, ...args);\n  }\n}\n\nfunction multimodality_prepare_inputs_for_generation(\n  self: PreTrainedModel,\n  input_ids: Tensor,\n  model_inputs: Record<string, any>,\n  generation_config: GenerationConfig,\n) {\n  const has_past_key_values = !!model_inputs.past_key_values;\n\n  if (generation_config.guidance_scale !== null && generation_config.guidance_scale > 1) {\n    if (has_past_key_values) {\n      model_inputs.input_ids = cat([model_inputs.input_ids, model_inputs.input_ids], 0);\n      // NOTE: attention_mask handled in generation\n    } else {\n      model_inputs.input_ids = cat(\n        [model_inputs.input_ids, full_like(model_inputs.input_ids, BigInt(generation_config.pad_token_id as number))],\n        0,\n      );\n      model_inputs.attention_mask = cat([model_inputs.attention_mask, full_like(model_inputs.attention_mask, 0n)], 0);\n    }\n  }\n\n  if (has_past_key_values || !model_inputs.pixel_values) {\n    model_inputs.pixel_values = full([0, 0, 3, 384, 384], 1.0);\n  }\n\n  if (has_past_key_values) {\n    const num_img_tokens = 0;\n    const num_text_tokens = 1;\n    const has_image = num_img_tokens > 0 ? 1 : 0;\n\n    const batch_size = 1;\n    model_inputs.images_seq_mask = new Tensor(\n      'bool',\n      new Array(num_img_tokens + num_text_tokens).fill(true).fill(false, 0, num_text_tokens),\n      [batch_size, num_img_tokens + num_text_tokens],\n    );\n    model_inputs.images_emb_mask = new Tensor('bool', new Array(num_img_tokens).fill(!!has_image), [\n      batch_size,\n      1,\n      num_img_tokens,\n    ]);\n  }\n  return model_inputs;\n}\n\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n/**\n * A base class for pre-trained models that provides the model configuration and an ONNX session.\n */\nexport class PreTrainedModel extends Callable {\n  main_input_name = 'input_ids';\n  forward_params = ['input_ids', 'attention_mask'];\n  /**\n   * Creates a new instance of the `PreTrainedModel` class.\n   * @param {import('./configs.js').PretrainedConfig} config The model configuration.\n   * @param {Record<string, any>} sessions The inference sessions for the model.\n   * @param {Record<string, Object>} configs Additional configuration files (e.g., generation_config.json).\n   */\n  config: PretrainedConfig;\n  sessions: Record<string, any>;\n  configs: Record<string, any>;\n  can_generate: boolean;\n  _forward: (self: PreTrainedModel, model_inputs: Record<string, any>) => Promise<any>;\n  _prepare_inputs_for_generation: (\n    self: PreTrainedModel,\n    input_ids: Tensor,\n    model_inputs: Record<string, any>,\n    generation_config: GenerationConfig,\n    ...args: any[]\n  ) => Record<string, any>;\n  custom_config: TransformersJSConfig;\n  constructor(config: PretrainedConfig, sessions: Record<string, any>, configs: Record<string, any>) {\n    super();\n\n    this.config = config;\n    this.sessions = sessions;\n    this.configs = configs;\n\n    const modelName = MODEL_CLASS_TO_NAME_MAPPING.get(this.constructor);\n    const modelType = MODEL_TYPE_MAPPING.get(modelName);\n\n    this.can_generate = false;\n    this._forward = PreTrainedModel.prototype._forward;\n\n    this._prepare_inputs_for_generation = PreTrainedModel.prototype._prepare_inputs_for_generation;\n    switch (modelType) {\n      case MODEL_TYPES.DecoderOnly:\n        this.can_generate = true;\n        this._forward = decoderForward;\n        this._prepare_inputs_for_generation = decoder_prepare_inputs_for_generation;\n        break;\n      case MODEL_TYPES.Seq2Seq:\n      case MODEL_TYPES.Vision2Seq:\n      case MODEL_TYPES.Musicgen:\n        this.can_generate = true;\n\n        this._forward = seq2seqForward;\n        this._prepare_inputs_for_generation = encoder_decoder_prepare_inputs_for_generation;\n        break;\n\n      case MODEL_TYPES.EncoderDecoder:\n        this._forward = seq2seqForward;\n        break;\n      case MODEL_TYPES.ImageTextToText:\n        this.can_generate = true;\n        this._forward = imageTextToTextForward;\n        this._prepare_inputs_for_generation = image_text_to_text_prepare_inputs_for_generation;\n        break;\n      case MODEL_TYPES.Phi3V:\n        this.can_generate = true;\n        this._prepare_inputs_for_generation = image_text_to_text_prepare_inputs_for_generation;\n        break;\n\n      case MODEL_TYPES.MultiModality:\n        this.can_generate = true;\n        this._prepare_inputs_for_generation = multimodality_prepare_inputs_for_generation;\n        break;\n\n      default:\n        // should be MODEL_TYPES.EncoderOnly\n        this._forward = encoderForward;\n        break;\n    }\n\n    if (this.can_generate) {\n      this.forward_params.push('past_key_values');\n    }\n\n    /** @type {import('./configs.js').TransformersJSConfig} */\n    this.custom_config = this.config['transformers_js_config'] ?? {};\n  }\n\n  /**\n   * Disposes of all the ONNX sessions that were created during inference.\n   * @returns {Promise<unknown[]>} An array of promises, one for each ONNX session that is being disposed.\n   * @todo Use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry\n   */\n  async dispose() {\n    const promises = [];\n    for (const session of Object.values(this.sessions)) {\n      if (session?.handler?.dispose) {\n        promises.push(session.handler.dispose());\n      }\n    }\n    return await Promise.all(promises);\n  }\n\n  /**\n   * Instantiate one of the model classes of the library from a pretrained model.\n   *\n   * The model class to instantiate is selected based on the `model_type` property of the config object\n   * (either passed as an argument or loaded from `pretrained_model_name_or_path` if possible)\n   *\n   * @param {string} pretrained_model_name_or_path The name or path of the pretrained model. Can be either:\n   * - A string, the *model id* of a pretrained model hosted inside a model repo on huggingface.co.\n   *   Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a\n   *   user or organization name, like `dbmdz/bert-base-german-cased`.\n   * - A path to a *directory* containing model weights, e.g., `./my_model_directory/`.\n   * @param {import('./utils/hub.js').PretrainedModelOptions} options Additional options for loading the model.\n   *\n   * @returns {Promise<PreTrainedModel>} A new instance of the `PreTrainedModel` class.\n   */\n  static async from_pretrained(\n    pretrained_model_name_or_path: string,\n    {\n      progress_callback = null,\n      config = null,\n      cache_dir = null,\n      local_files_only = false,\n      revision = 'main',\n      model_file_name = null,\n      subfolder = 'onnx',\n      device = null,\n      dtype = null,\n      use_external_data_format = null,\n      session_options = {},\n    }: ModelOptions = {},\n  ) {\n    let options = {\n      progress_callback,\n      config,\n      cache_dir,\n      local_files_only,\n      revision,\n      model_file_name,\n      subfolder,\n      device,\n      dtype,\n      use_external_data_format,\n      session_options,\n    };\n\n    const modelName = MODEL_CLASS_TO_NAME_MAPPING.get(this);\n    const modelType = MODEL_TYPE_MAPPING.get(modelName);\n\n    config = (options.config as any) = await AutoConfig.from_pretrained(pretrained_model_name_or_path, options);\n\n    let info;\n    if (modelType === MODEL_TYPES.DecoderOnly) {\n      info = await Promise.all([\n        constructSessions(\n          pretrained_model_name_or_path,\n          {\n            model: options.model_file_name ?? 'model',\n          },\n          options,\n        ),\n        getOptionalConfigs(\n          pretrained_model_name_or_path,\n          {\n            generation_config: 'generation_config.json',\n          },\n          options,\n        ),\n      ]);\n    } else if (modelType === MODEL_TYPES.Seq2Seq || modelType === MODEL_TYPES.Vision2Seq) {\n      info = await Promise.all([\n        constructSessions(\n          pretrained_model_name_or_path,\n          {\n            model: 'encoder_model',\n            decoder_model_merged: 'decoder_model_merged',\n          },\n          options,\n        ),\n        getOptionalConfigs(\n          pretrained_model_name_or_path,\n          {\n            generation_config: 'generation_config.json',\n          },\n          options,\n        ),\n      ]);\n    } else if (modelType === MODEL_TYPES.MaskGeneration) {\n      info = await Promise.all([\n        constructSessions(\n          pretrained_model_name_or_path,\n          {\n            model: 'vision_encoder',\n            prompt_encoder_mask_decoder: 'prompt_encoder_mask_decoder',\n          },\n          options,\n        ),\n      ]);\n    } else if (modelType === MODEL_TYPES.EncoderDecoder) {\n      info = await Promise.all([\n        constructSessions(\n          pretrained_model_name_or_path,\n          {\n            model: 'encoder_model',\n            decoder_model_merged: 'decoder_model_merged',\n          },\n          options,\n        ),\n      ]);\n    } else if (modelType === MODEL_TYPES.ImageTextToText) {\n      const sessions = {\n        embed_tokens: 'embed_tokens',\n        vision_encoder: 'vision_encoder',\n        decoder_model_merged: 'decoder_model_merged',\n      };\n      if ((config as any).is_encoder_decoder) {\n        (sessions as any)['model'] = 'encoder_model';\n      }\n      info = await Promise.all([\n        constructSessions(pretrained_model_name_or_path, sessions, options),\n        getOptionalConfigs(\n          pretrained_model_name_or_path,\n          {\n            generation_config: 'generation_config.json',\n          },\n          options,\n        ),\n      ]);\n    } else if (modelType === MODEL_TYPES.Musicgen) {\n      info = await Promise.all([\n        constructSessions(\n          pretrained_model_name_or_path,\n          {\n            model: 'text_encoder',\n            decoder_model_merged: 'decoder_model_merged',\n            encodec_decode: 'encodec_decode',\n          },\n          options,\n        ),\n        getOptionalConfigs(\n          pretrained_model_name_or_path,\n          {\n            generation_config: 'generation_config.json',\n          },\n          options,\n        ),\n      ]);\n    } else if (modelType === MODEL_TYPES.MultiModality) {\n      info = await Promise.all([\n        constructSessions(\n          pretrained_model_name_or_path,\n          {\n            prepare_inputs_embeds: 'prepare_inputs_embeds',\n            model: 'language_model',\n            lm_head: 'lm_head',\n            gen_head: 'gen_head',\n            gen_img_embeds: 'gen_img_embeds',\n            image_decode: 'image_decode',\n          },\n          options,\n        ),\n        getOptionalConfigs(\n          pretrained_model_name_or_path,\n          {\n            generation_config: 'generation_config.json',\n          },\n          options,\n        ),\n      ]);\n    } else if (modelType === MODEL_TYPES.Phi3V) {\n      info = await Promise.all([\n        constructSessions(\n          pretrained_model_name_or_path,\n          {\n            prepare_inputs_embeds: 'prepare_inputs_embeds',\n            model: 'model',\n            vision_encoder: 'vision_encoder',\n          },\n          options,\n        ),\n        getOptionalConfigs(\n          pretrained_model_name_or_path,\n          {\n            generation_config: 'generation_config.json',\n          },\n          options,\n        ),\n      ]);\n    } else {\n      // should be MODEL_TYPES.EncoderOnly\n      if (modelType !== MODEL_TYPES.EncoderOnly) {\n        const type = modelName ?? (config as any)?.model_type;\n        if (type !== 'custom') {\n          console.warn(\n            `Model type for '${type}' not found, assuming encoder-only architecture. Please report this at ${GITHUB_ISSUE_URL}.`,\n          );\n        }\n      }\n      info = await Promise.all([\n        constructSessions(\n          pretrained_model_name_or_path,\n          {\n            model: options.model_file_name ?? 'model',\n          },\n          options,\n        ),\n      ]);\n    }\n\n    // @ts-ignore\n    return new this(config, ...info);\n  }\n\n  /**\n   * Runs the model with the provided inputs\n   * @param {Object} model_inputs Object containing input tensors\n   * @returns {Promise<Object>} Object containing output tensors\n   */\n  async _call(model_inputs: Record<string, unknown>) {\n    return await this.forward(model_inputs);\n  }\n\n  /**\n   * Forward method for a pretrained model. If not overridden by a subclass, the correct forward method\n   * will be chosen based on the model type.\n   * @param {Object} model_inputs The input data to the model in the format specified in the ONNX model.\n   * @returns {Promise<Object>} The output data from the model in the format specified in the ONNX model.\n   * @throws {Error} This method must be implemented in subclasses.\n   */\n  async forward(model_inputs: Record<string, unknown>) {\n    return await this._forward(this, model_inputs);\n  }\n\n  /**\n   * Get the model's generation config, if it exists.\n   * @returns {GenerationConfig|null} The model's generation config if it exists, otherwise `null`.\n   */\n  get generation_config() {\n    return this.configs?.generation_config ?? null;\n  }\n\n  /**\n   * This function returns a [`LogitsProcessorList`] list object that contains all relevant [`LogitsWarper`]\n   * instances used for multinomial sampling.\n   * @param {GenerationConfig} generation_config The generation config.\n   * @returns {LogitsProcessorList} generation_config\n   */\n  _get_logits_warper(generation_config: GenerationConfig) {\n    // instantiate warpers list\n    const warpers = new LogitsProcessorList();\n\n    if (generation_config.temperature !== null && generation_config.temperature !== 1.0) {\n      warpers.push(new TemperatureLogitsWarper(generation_config.temperature));\n    }\n    if (generation_config.top_k !== null && generation_config.top_k !== 0) {\n      // TODO: add min_tokens_to_keep\n      warpers.push(new TopKLogitsWarper(generation_config.top_k) as any);\n    }\n    if (generation_config.top_p !== null && generation_config.top_p < 1.0) {\n      // TODO: add min_tokens_to_keep\n      warpers.push(new TopPLogitsWarper(generation_config.top_p) as any);\n    }\n\n    return warpers;\n  }\n\n  /**\n   * @param {GenerationConfig} generation_config\n   * @param {number} input_ids_seq_length The starting sequence length for the input ids.\n   * @returns {LogitsProcessorList}\n   * @private\n   */\n  _get_logits_processor(\n    generation_config: GenerationConfig,\n    input_ids_seq_length: number,\n    // encoder_input_ids, TODO\n    // prefix_allowed_tokens_fn, TODO\n    logits_processor: LogitsProcessorList | null = null,\n  ) {\n    const processors = new LogitsProcessorList();\n\n    // if (generation_config.diversity_penalty !== null && generation_config.diversity_penalty > 0.0) {\n    //     processors.push(new HammingDiversityLogitsProcessor(\n    //         generation_config.diversity_penalty,\n    //         generation_config.num_beams,\n    //         generation_config.num_beam_groups\n    //     ));\n    // }\n\n    // if (generation_config.encoder_repetition_penalty !== null && generation_config.encoder_repetition_penalty !== 1.0) {\n    //     processors.push(new EncoderRepetitionPenaltyLogitsProcessor(\n    //         generation_config.encoder_repetition_penalty,\n    //         encoder_input_ids\n    //     ));\n    // }\n\n    if (generation_config.repetition_penalty !== null && generation_config.repetition_penalty !== 1.0) {\n      processors.push(new RepetitionPenaltyLogitsProcessor(generation_config.repetition_penalty));\n    }\n\n    if (generation_config.no_repeat_ngram_size !== null && generation_config.no_repeat_ngram_size > 0) {\n      processors.push(new NoRepeatNGramLogitsProcessor(generation_config.no_repeat_ngram_size));\n    }\n\n    // if (generation_config.encoder_no_repeat_ngram_size !== null && generation_config.encoder_no_repeat_ngram_size > 0) {\n    //     if (this.config.is_encoder_decoder) {\n    //         processors.push(new EncoderNoRepeatNGramLogitsProcessor(\n    //             generation_config.encoder_no_repeat_ngram_size,\n    //             encoder_input_ids\n    //         ));\n    //     } else {\n    //         throw new Error(\"It's impossible to use `encoder_no_repeat_ngram_size` with decoder-only architecture\");\n    //     }\n    // }\n\n    if (generation_config.bad_words_ids !== null) {\n      processors.push(\n        new NoBadWordsLogitsProcessor(\n          generation_config.bad_words_ids,\n          (generation_config.eos_token_id as any),\n        ),\n      );\n    }\n\n    if (\n      generation_config.min_length !== null &&\n      generation_config.eos_token_id !== null &&\n      generation_config.min_length > 0\n    ) {\n      processors.push(new MinLengthLogitsProcessor(generation_config.min_length, generation_config.eos_token_id));\n    }\n\n    if (\n      generation_config.min_new_tokens !== null &&\n      generation_config.eos_token_id !== null &&\n      generation_config.min_new_tokens > 0\n    ) {\n      processors.push(\n        new MinNewTokensLengthLogitsProcessor(\n          input_ids_seq_length,\n          generation_config.min_new_tokens,\n          generation_config.eos_token_id,\n        ),\n      );\n    }\n\n    // if (prefix_allowed_tokens_fn !== null) {\n    //     processors.push(new PrefixConstrainedLogitsProcessor(\n    //         prefix_allowed_tokens_fn,\n    //         generation_config.num_beams / generation_config.num_beam_groups\n    //     ));\n    // }\n\n    if (generation_config.forced_bos_token_id !== null) {\n      processors.push(new ForcedBOSTokenLogitsProcessor(generation_config.forced_bos_token_id));\n    }\n\n    if (generation_config.forced_eos_token_id !== null) {\n      processors.push(\n        new ForcedEOSTokenLogitsProcessor(generation_config.max_length, generation_config.forced_eos_token_id),\n      );\n    }\n\n    // if (generation_config.remove_invalid_values === true) {\n    //     processors.push(new InfNanRemoveLogitsProcessor());\n    // }\n\n    // if (generation_config.exponential_decay_length_penalty !== null) {\n    //     processors.push(new ExponentialDecayLengthPenalty(\n    //         generation_config.exponential_decay_length_penalty,\n    //         generation_config.eos_token_id,\n    //         input_ids_seq_length\n    //     ));\n    // }\n\n    // if (generation_config.suppress_tokens !== null) {\n    //     processors.push(new SuppressTokensLogitsProcessor(generation_config.suppress_tokens));\n    // }\n\n    if (generation_config.begin_suppress_tokens !== null) {\n      const begin_index =\n        input_ids_seq_length > 1 || generation_config.forced_bos_token_id === null\n          ? input_ids_seq_length\n          : input_ids_seq_length + 1;\n\n      processors.push(new SuppressTokensAtBeginLogitsProcessor(generation_config.begin_suppress_tokens, begin_index));\n    }\n\n    // DEPRECATED: https://github.com/huggingface/transformers/pull/29485\n    // if (generation_config.forced_decoder_ids !== null) {\n    //     processors.push(new ForceTokensLogitsProcessor(generation_config.forced_decoder_ids));\n    // }\n\n    // 8. prepare batched CFG externally\n    if (generation_config.guidance_scale !== null && generation_config.guidance_scale > 1) {\n      processors.push(new ClassifierFreeGuidanceLogitsProcessor(generation_config.guidance_scale));\n    }\n\n    if (logits_processor !== null) {\n      processors.extend(logits_processor as any);\n    }\n\n    // `LogitNormalization` should always be the last logit processor, when present\n    // if (generation_config.renormalize_logits === true) {\n    //     processors.push(new LogitNormalization());\n    // }\n\n    return processors;\n  }\n\n  /**\n   * This function merges multiple generation configs together to form a final generation config to be used by the model for text generation.\n   * It first creates an empty `GenerationConfig` object, then it applies the model's own `generation_config` property to it. Finally, if a `generation_config` object was passed in the arguments, it overwrites the corresponding properties in the final config with those of the passed config object.\n   * @param {GenerationConfig|null} generation_config A `GenerationConfig` object containing generation parameters.\n   * @param {Object} kwargs Additional generation parameters to be used in place of those in the `generation_config` object.\n   * @returns {GenerationConfig} The final generation config object to be used by the model for text generation.\n   */\n  _prepare_generation_config(\n    generation_config: GenerationConfig | null,\n    kwargs: any,\n    cls = GenerationConfig,\n  ) {\n    // Create empty generation config (contains defaults)\n    // We pass `this.config` so that if `eos_token_id` or `bos_token_id` exist in the model's config, we will use them\n    const config = { ...this.config };\n    for (const key of ['decoder', 'generator', 'text_config']) {\n      // Special case: some models have generation attributes set in the decoder.\n      // Use them if still unset in the generation config.\n      if (key in config) {\n        Object.assign(config, (config as any)[key]);\n      }\n    }\n\n    const gen_config = new cls(config);\n\n    // Apply model's generation config, if it exists\n    Object.assign(gen_config, this.generation_config ?? {});\n\n    // Next, use any generation config specified by the user\n    // when calling `generate`\n    if (generation_config) {\n      Object.assign(gen_config, generation_config);\n    }\n\n    // Finally, if any kwargs were passed, use them to overwrite\n    if (kwargs) {\n      Object.assign(gen_config, pick(kwargs, Object.getOwnPropertyNames(gen_config)));\n    }\n\n    return gen_config;\n  }\n\n  /**\n   *\n   * @param {GenerationConfig} generation_config\n   * @param {StoppingCriteriaList} [stopping_criteria=null]\n   */\n  _get_stopping_criteria(generation_config: GenerationConfig, stopping_criteria = null) {\n    const criteria = new StoppingCriteriaList();\n\n    if (generation_config.max_length !== null) {\n      criteria.push(new MaxLengthCriteria(generation_config.max_length, this.config.max_position_embeddings ?? null));\n    }\n    // if (generation_config.max_time !== null) {\n    //     criteria.push(new MaxTimeCriteria(generation_config.max_time));\n    // }\n    if (generation_config.eos_token_id !== null) {\n      criteria.push(new EosTokenCriteria(generation_config.eos_token_id));\n    }\n\n    if (stopping_criteria) {\n      criteria.extend(stopping_criteria);\n    }\n    return criteria;\n  }\n\n  /**\n   * Confirms that the model class is compatible with generation.\n   * If not, raises an exception that points to the right class to use.\n   */\n  _validate_model_class() {\n    if (!this.can_generate) {\n      const generate_compatible_mappings = [\n        MODEL_FOR_CAUSAL_LM_MAPPING_NAMES,\n        // MODEL_FOR_CAUSAL_IMAGE_MODELING_MAPPING, // TODO\n        MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES,\n        MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES,\n      ];\n\n      const modelName = MODEL_CLASS_TO_NAME_MAPPING.get(this.constructor);\n\n      const generate_compatible_classes = new Set();\n      const modelType = this.config.model_type;\n      for (const model_mapping of generate_compatible_mappings) {\n        const supported_models = model_mapping.get(modelType ?? 'custom');\n        if (supported_models) {\n          generate_compatible_classes.add(supported_models[0]);\n        }\n      }\n\n      let errorMessage = `The current model class (${modelName}) is not compatible with \\`.generate()\\`, as it doesn't have a language model head.`;\n      if (generate_compatible_classes.size > 0) {\n        errorMessage += ` Please use the following class instead: ${[...generate_compatible_classes].join(', ')}`;\n      }\n      throw Error(errorMessage);\n    }\n  }\n\n  prepare_inputs_for_generation(\n    this: PreTrainedModel,\n    ...args: [Tensor, Record<string, unknown>, GenerationConfig]\n  ) {\n    return this._prepare_inputs_for_generation(this, ...args);\n  }\n\n  /**\n   *\n   * @param {Object} inputs\n   * @param {bigint[][]} inputs.generated_input_ids\n   * @param {Object} inputs.outputs\n   * @param {Object} inputs.model_inputs\n   * @param {boolean} inputs.is_encoder_decoder\n   * @returns {Object} The updated model inputs for the next generation iteration.\n   */\n  _update_model_kwargs_for_generation({\n    generated_input_ids,\n    outputs,\n    model_inputs,\n    is_encoder_decoder,\n  }: {\n    generated_input_ids: bigint[][];\n    outputs: Record<string, unknown>;\n    model_inputs: Record<string, unknown>;\n    is_encoder_decoder: boolean;\n  }) {\n    // update past_key_values\n    model_inputs['past_key_values'] = this.getPastKeyValues(outputs, (model_inputs.past_key_values as any));\n\n    // update inputs for next run\n    model_inputs['input_ids'] = new Tensor('int64', generated_input_ids.flat(), [generated_input_ids.length, 1]);\n\n    if (!is_encoder_decoder) {\n      // update attention mask\n      model_inputs.attention_mask = cat(\n        [(model_inputs.attention_mask as any), ones([(model_inputs.attention_mask as any).dims[0], 1])],\n        1,\n      );\n    } else if ('decoder_attention_mask' in model_inputs) {\n      // TODO: update decoder attention mask if the model requires it\n    }\n\n    // force recreate position_ids in next iteration\n    model_inputs['position_ids'] = null;\n\n    return model_inputs;\n  }\n\n  /**\n   * This function extracts the model-specific `inputs` for generation.\n   * @param {Object} params\n   * @param {Tensor} [params.inputs=null]\n   * @param {number} [params.bos_token_id=null]\n   * @param {Record<string, Tensor|number[]>} [params.model_kwargs]\n   * @returns {{inputs_tensor: Tensor, model_inputs: Record<string, Tensor>, model_input_name: string}} The model-specific inputs for generation.\n   */\n  _prepare_model_inputs({\n    inputs,\n    bos_token_id,\n    model_kwargs,\n  }: {\n    inputs: Tensor | null;\n    bos_token_id: number | null;\n    model_kwargs: Record<string, any>;\n  }) {\n    const model_inputs = pick(model_kwargs, this.forward_params);\n    const input_name = this.main_input_name;\n    if (input_name in model_inputs) {\n      if (inputs) {\n        throw new Error(\n          '`inputs`: {inputs}` were passed alongside {input_name} which is not allowed. ' +\n          'Make sure to either pass {inputs} or {input_name}=...',\n        );\n      }\n    } else {\n      model_inputs[input_name] = inputs;\n    }\n\n    const inputs_tensor = model_inputs[input_name];\n\n    return { inputs_tensor, model_inputs, model_input_name: input_name };\n  }\n\n  async _prepare_encoder_decoder_kwargs_for_generation({\n    inputs_tensor,\n    model_inputs,\n    model_input_name,\n    generation_config,\n  }: {\n    inputs_tensor: Tensor;\n    model_inputs: Record<string, unknown>;\n    model_input_name: string;\n    generation_config: GenerationConfig;\n  }) {\n    if (\n      this.sessions['model'].inputNames.includes('inputs_embeds') &&\n      !model_inputs.inputs_embeds &&\n      '_prepare_inputs_embeds' in this\n    ) {\n      // Encoder expects `inputs_embeds` instead of `input_ids`\n      const { input_ids, pixel_values, attention_mask, ...kwargs } = model_inputs;\n      // @ts-ignore\n      const prepared_inputs = await this._prepare_inputs_embeds(model_inputs);\n      model_inputs = {\n        ...kwargs,\n        ...pick(prepared_inputs, ['inputs_embeds', 'attention_mask']),\n      };\n    }\n    let { last_hidden_state } = await encoderForward(this, model_inputs);\n\n    // for classifier free guidance we need to add a 'null' input to our encoder hidden states\n    if (generation_config.guidance_scale !== null && generation_config.guidance_scale > 1) {\n      last_hidden_state = cat([last_hidden_state, full_like(last_hidden_state, 0.0)], 0);\n\n      if ('attention_mask' in model_inputs) {\n        model_inputs['attention_mask'] = cat(\n          [(model_inputs['attention_mask'] as any), zeros_like((model_inputs['attention_mask'] as any))],\n          0,\n        );\n      }\n    } else if (model_inputs.decoder_input_ids) {\n      // Ensure that the encoder outputs have the same batch size as the decoder inputs,\n      // allowing for more efficient batched generation for single inputs\n      const decoder_input_ids_batch_size = toI64Tensor(model_inputs.decoder_input_ids).dims[0];\n      if (decoder_input_ids_batch_size !== last_hidden_state.dims[0]) {\n        if (last_hidden_state.dims[0] !== 1) {\n          throw new Error(\n            `The encoder outputs have a different batch size (${last_hidden_state.dims[0]}) than the decoder inputs (${decoder_input_ids_batch_size}).`,\n          );\n        }\n        last_hidden_state = cat(\n          Array.from({ length: decoder_input_ids_batch_size }, () => last_hidden_state),\n          0,\n        );\n      }\n    }\n    model_inputs['encoder_outputs'] = last_hidden_state;\n\n    return model_inputs;\n  }\n\n  /**\n   * Prepares `decoder_input_ids` for generation with encoder-decoder models\n   * @param {*} param0\n   */\n  _prepare_decoder_input_ids_for_generation({\n    batch_size,\n    model_input_name,\n    model_kwargs,\n    decoder_start_token_id,\n    bos_token_id,\n    generation_config,\n  }: {\n    batch_size: number;\n    model_input_name: string;\n    model_kwargs: Record<string, unknown>;\n    decoder_start_token_id: number | null;\n    bos_token_id: number | null;\n    generation_config: GenerationConfig;\n  }) {\n    let { decoder_input_ids, ...model_inputs } = model_kwargs;\n\n    // Prepare input ids if the user has not defined `decoder_input_ids` manually.\n    if (!(decoder_input_ids instanceof Tensor)) {\n      if (!decoder_input_ids) {\n        decoder_start_token_id ??= bos_token_id;\n\n        if (this.config.model_type === 'musicgen') {\n          // Custom logic (TODO: move to Musicgen class)\n          decoder_input_ids = Array.from(\n            {\n              // @ts-expect-error TS2339\n              length: batch_size * this.config.decoder.num_codebooks,\n            },\n            () => [decoder_start_token_id],\n          );\n        } else if (Array.isArray(decoder_start_token_id)) {\n          if (decoder_start_token_id.length !== batch_size) {\n            throw new Error(\n              `\\`decoder_start_token_id\\` expcted to have length ${batch_size} but got ${decoder_start_token_id.length}`,\n            );\n          }\n          decoder_input_ids = decoder_start_token_id;\n        } else {\n          decoder_input_ids = Array.from(\n            {\n              length: batch_size,\n            },\n            () => [decoder_start_token_id],\n          );\n        }\n      } else if (!Array.isArray((decoder_input_ids as any)[0])) {\n        // Correct batch size\n        decoder_input_ids = Array.from(\n          {\n            length: batch_size,\n          },\n          () => decoder_input_ids,\n        );\n      }\n      decoder_input_ids = toI64Tensor(decoder_input_ids);\n    }\n\n    model_kwargs['decoder_attention_mask'] = ones_like((decoder_input_ids as any));\n\n    return { input_ids: decoder_input_ids, model_inputs };\n  }\n\n  /**\n   * Generates sequences of token ids for models with a language modeling head.\n   * @param {import('./generation/parameters.js').GenerationFunctionParameters} options\n   * @returns {Promise<ModelOutput|Tensor>} The output of the model, which can contain the generated token ids, attentions, and scores.\n   */\n  async generate({\n    inputs = null,\n    generation_config = null,\n    logits_processor = null,\n    stopping_criteria = null,\n    streamer = null,\n    ...kwargs\n  }: any) {\n    this._validate_model_class();\n\n    // Update generation config with defaults and kwargs\n    generation_config = this._prepare_generation_config(generation_config, kwargs);\n\n    // 3. Define model inputs\n    let { inputs_tensor, model_inputs, model_input_name } = this._prepare_model_inputs({\n      inputs: inputs,\n      bos_token_id: null,\n      model_kwargs: kwargs,\n    });\n\n    const is_encoder_decoder = this.config.is_encoder_decoder;\n\n    // 4. Define other model kwargs\n    if (!is_encoder_decoder) {\n      // decoder-only models should use left-padding for generation\n    } else if (!('encoder_outputs' in model_inputs)) {\n      // if model is encoder decoder encoder_outputs are created\n      // and added to `model_kwargs`\n      model_inputs = await this._prepare_encoder_decoder_kwargs_for_generation({\n        inputs_tensor: (inputs_tensor as Tensor),\n        model_inputs: (model_inputs as Record<string, unknown>),\n        model_input_name: (model_input_name as string),\n        generation_config: (generation_config as GenerationConfig),\n      });\n    }\n\n    // 5. Prepare `input_ids` which will be used for auto-regressive generation\n    // TODO: Update to align with HF transformers' implementation\n    let input_ids;\n    if (is_encoder_decoder) {\n      // Generating from the encoder outputs\n      ({ input_ids, model_inputs } = this._prepare_decoder_input_ids_for_generation({\n        batch_size: (model_inputs[model_input_name] as any).dims.at(0),\n        model_input_name,\n        model_kwargs: model_inputs,\n        decoder_start_token_id: (generation_config as any).decoder_start_token_id,\n        bos_token_id: (generation_config as any).bos_token_id,\n        generation_config,\n      }));\n    } else {\n      input_ids = model_inputs[model_input_name];\n    }\n\n    // 6. Prepare `max_length` depending on other stopping criteria.\n    let input_ids_length = input_ids.dims.at(-1);\n\n    if (generation_config && (generation_config as any).max_new_tokens !== null) {\n      (generation_config as any).max_length = input_ids_length + (generation_config as any).max_new_tokens;\n    }\n\n    // input_ids_length = model_inputs[model_input_name].dims.at(1);\n    // // inputs instanceof Tensor ?  : inputs.length;\n\n    // // decoder-only\n    // if (input_ids_length === 0) {\n    //     throw Error(\"Must supply a non-empty array of input token ids.\")\n    // }\n\n    // let decoder_input_ids =\n    // generation_config.decoder_input_ids\n    // ?? generation_config.decoder_start_token_id\n    // ?? generation_config.bos_token_id\n    // ?? generation_config.eos_token_id;\n\n    // Update logits processor\n    // 8. prepare distribution pre_processing samplers\n    const prepared_logits_processor = this._get_logits_processor(generation_config, input_ids_length, logits_processor as any);\n\n    // 9. prepare stopping criteria\n    const prepared_stopping_criteria = this._get_stopping_criteria(generation_config, stopping_criteria as any);\n\n    // /** @type {number[]} */\n    // let eos_token_ids = generation_config.eos_token_id;\n    // if (eos_token_ids !== null && !Array.isArray(eos_token_ids)) {\n    //     eos_token_ids = [eos_token_ids];\n    // }\n\n    const numInputs = model_inputs[model_input_name].dims.at(0);\n\n    // TODO:\n    // done is a list of booleans to keep track of which inputs are done\n    // const done = new Array(numInputs).fill(false);\n    // For efficiency purposes, we remove completed rows from model_inputs\n    // when the beam is complete, and we keep track of the row index\n    // const rowIndexToBatchIndex = new Map();\n\n    const sampler = LogitsSampler.getSampler(generation_config);\n\n    // TODO make > numInputs\n    const scores = new Array(numInputs).fill(0);\n    /** @type {bigint[][]} */\n    const all_input_ids = input_ids.tolist();\n    if (streamer) {\n      (streamer as any).put(all_input_ids);\n    }\n    // const all_generated_input_ids = Array.from({ length: numInputs }, () => []);\n\n    // NOTE: For now, we don't support spawning new beams\n    // TODO: when we do, we simply copy past key values and accumulate into single large tensor\n\n    ////////////////////////////////////////////////////\n    // Generic search which handles 4 generation modes:\n    // - GenerationMode.GREEDY_SEARCH\n    // - GenerationMode.SAMPLE\n    // - GenerationMode.BEAM_SEARCH\n    // - GenerationMode.BEAM_SAMPLE\n    ////////////////////////////////////////////////////\n    let outputs;\n    let attentions = {};\n    while (true) {\n      // prepare model inputs\n      model_inputs = this.prepare_inputs_for_generation(all_input_ids, model_inputs, generation_config);\n      outputs = await this.forward(model_inputs);\n\n      if ((generation_config as any).output_attentions && (generation_config as any).return_dict_in_generate) {\n        // Get attentions if they are present\n        const token_attentions = this.getAttentions(outputs);\n        for (const key in token_attentions) {\n          if (!(key in attentions)) {\n            (attentions as any)[key] = [];\n          }\n          (attentions as any)[key].push(token_attentions[key]);\n        }\n      }\n\n      // Logits are of the form [batch_size, out_seq_length, vocab_size]\n      // In most cases, this will be [batch_size, 1, vocab_size]\n      // So, we select the last token's logits:\n      // (equivalent to `logits = outputs.logits[:, -1, :]`)\n      const logits = outputs.logits.slice(null, -1, null);\n\n      const next_tokens_scores = prepared_logits_processor._call(all_input_ids, logits);\n\n      /** @type {[bigint][]} */\n      const generated_input_ids = [];\n      // const new_kv_cache = [];// NOTE: Only used for beam search when concatenating new kv\n      // Loop over each batch\n      for (let batch_idx = 0; batch_idx < next_tokens_scores.dims.at(0); ++batch_idx) {\n        const logs = next_tokens_scores[batch_idx];\n\n        const sampledTokens = await sampler.sample(logs);\n        for (const [newTokenId, logProb] of sampledTokens) {\n          const bigint = BigInt(newTokenId);\n          // TODO: If branching, use previous beam as a starting point\n          // update generated ids, model inputs, and length for next step\n          scores[batch_idx] += logProb;\n          all_input_ids[batch_idx].push(bigint);\n          generated_input_ids.push([bigint]);\n\n          // TODO: Support beam search\n          break;\n        }\n      }\n      if (streamer) {\n        (streamer as any).put(generated_input_ids);\n      }\n\n      const stop = prepared_stopping_criteria._call(all_input_ids, scores);\n      if (stop.every(((x: any) => x))) {\n        break;\n      }\n\n      model_inputs = this._update_model_kwargs_for_generation({\n        generated_input_ids,\n        outputs,\n        model_inputs,\n        is_encoder_decoder,\n      });\n    }\n\n    if (streamer) {\n      (streamer as any).end();\n    }\n\n    // Retrieve and dispose all final past key values (including encoder attentions)\n    const past_key_values = this.getPastKeyValues(outputs, (model_inputs as any).past_key_values, true);\n\n    // TODO: ensure all_input_ids is padded correctly...\n    const sequences = new Tensor('int64', all_input_ids.flat(), [all_input_ids.length, all_input_ids[0].length]);\n\n    if ((generation_config as any).return_dict_in_generate) {\n      return {\n        sequences,\n        past_key_values,\n        ...attentions,\n        // TODO:\n        // scores,\n        // logits,\n      };\n    } else {\n      // Dispose all remaining tensors\n      for (const tensor of Object.values(outputs)) {\n        if ((tensor as any).location === 'gpu-buffer') {\n          (tensor as any).dispose();\n        }\n      }\n      return sequences;\n    }\n  }\n\n  /**\n   * Returns an object containing past key values from the given decoder results object.\n   *\n   * @param {Object} decoderResults The decoder results object.\n   * @param {Object} pastKeyValues The previous past key values.\n   * @returns {Object} An object containing past key values.\n   */\n  getPastKeyValues(\n    decoderResults: Record<string, unknown>,\n    pastKeyValues: Record<string, unknown>,\n    disposeEncoderPKVs = false,\n  ) {\n    const pkvs = Object.create(null);\n\n    for (const name in decoderResults) {\n      if (name.startsWith('present')) {\n        const newName = name.replace('present', 'past_key_values');\n        const is_encoder_pkv = name.includes('encoder');\n        if (is_encoder_pkv && pastKeyValues) {\n          // Optimization introduced by optimum to reuse past key values.\n          // So, we just replace the constant outputs (`decoderResults[name]`) with the previous past key values.\n          // https://github.com/huggingface/optimum/blob/0bf2c05fb7e1182b52d21b703cfc95fd9e4ea3dc/optimum/onnxruntime/base.py#L677-L704\n          pkvs[newName] = pastKeyValues[newName];\n        } else {\n          // decoder or using first encoder PKVs\n          pkvs[newName] = decoderResults[name];\n        }\n\n        if (pastKeyValues && (!is_encoder_pkv || disposeEncoderPKVs)) {\n          // - Always dispose decoder PKVs\n          // - Only dispose encoder past key values when requested (after generation)\n          const t = pastKeyValues[newName];\n          if ((t as any).location === 'gpu-buffer') {\n            (t as any).dispose();\n          }\n        }\n      }\n    }\n    return pkvs;\n  }\n\n  /**\n   * Returns an object containing attentions from the given model output object.\n   *\n   * @param {Object} model_output The output of the model.\n   * @returns {{cross_attentions?: Tensor[]}} An object containing attentions.\n   */\n  getAttentions(model_output: Record<string, unknown>) {\n    const attentions: Record<string, unknown[]> = {};\n\n    for (const attnName of ['cross_attentions', 'encoder_attentions', 'decoder_attentions']) {\n      for (const name in model_output) {\n        if (name.startsWith(attnName)) {\n          if (!(attnName in attentions)) {\n            attentions[attnName] = [];\n          }\n          attentions[attnName].push(model_output[name]);\n        }\n      }\n    }\n    return attentions;\n  }\n\n  /**\n   * Adds past key values to the decoder feeds object. If pastKeyValues is null, creates new tensors for past key values.\n   *\n   * @param {Object} decoderFeeds The decoder feeds object to add past key values to.\n   * @param {Object} pastKeyValues An object containing past key values.\n   */\n  addPastKeyValues(decoderFeeds: Record<string, any>, pastKeyValues: Record<string, any>) {\n    if (pastKeyValues) {\n      Object.assign(decoderFeeds, pastKeyValues);\n    } else {\n      const session = this.sessions['decoder_model_merged'] ?? this.sessions['model'];\n      const dtype = session?.config?.kv_cache_dtype ?? 'float32';\n      const empty = dtype === 'float16' ? new Uint16Array() : [];\n\n      const batch_size = (decoderFeeds[this.main_input_name] ?? decoderFeeds.attention_mask)?.dims?.[0] ?? 1;\n      const shapes = getKeyValueShapes(this.config, { batch_size });\n\n      for (const name in shapes) {\n        decoderFeeds[name] = new Tensor(dtype, empty, shapes[name]);\n      }\n    }\n  }\n\n  async encode_image({ pixel_values }: { pixel_values: Tensor }) {\n    // image_inputs === { pixel_values }\n    const features = (await sessionRun(this.sessions['vision_encoder'], { pixel_values })).image_features;\n    // @ts-expect-error TS2339\n    if (!this.config.num_image_tokens) {\n      console.warn(\n        'The number of image tokens was not set in the model configuration. ' +\n        `Setting it to the number of features detected by the vision encoder (${features.dims[1]}).`,\n      );\n      // @ts-expect-error TS2339\n      this.config.num_image_tokens = features.dims[1];\n    }\n    return features;\n  }\n\n  async encode_text({ input_ids }: { input_ids: Tensor }) {\n    // text_inputs === { input_ids, attention_mask }\n    return (await sessionRun(this.sessions['embed_tokens'], { input_ids })).inputs_embeds;\n  }\n}\n\n//////////////////////////////////////////////////\n// Base model output class\nexport class ModelOutput { }\n\n/**\n * Base class for model's outputs, with potential hidden states and attentions.\n */\nexport class BaseModelOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.last_hidden_state Sequence of hidden-states at the output of the last layer of the model.\n   * @param {Tensor} [output.hidden_states] Hidden-states of the model at the output of each layer plus the optional initial embedding outputs.\n   * @param {Tensor} [output.attentions] Attentions weights after the attention softmax, used to compute the weighted average in the self-attention heads.\n   */\n  last_hidden_state: Tensor;\n  hidden_states: Tensor[] | null;\n  attentions: Tensor[] | null;\n\n  constructor({\n    last_hidden_state,\n    hidden_states = null,\n    attentions = null,\n  }: {\n    last_hidden_state: Tensor;\n    hidden_states?: Tensor[] | null;\n    attentions?: Tensor[] | null;\n  }) {\n    super();\n    this.last_hidden_state = last_hidden_state;\n    this.hidden_states = hidden_states;\n    this.attentions = attentions;\n  }\n}\n\n//////////////////////////////////////////////////\n// Audio Spectrogram Transformer (AST) models\nexport class ASTPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare AST Model transformer outputting raw hidden-states without any specific head on top.\n */\nexport class ASTModel extends ASTPreTrainedModel { }\n\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Whisper models\nexport class WhisperPreTrainedModel extends PreTrainedModel {\n  requires_attention_mask = false;\n  main_input_name = 'input_features';\n  forward_params = [\n    'input_features',\n    'attention_mask',\n    'decoder_input_ids',\n    'decoder_attention_mask',\n    'past_key_values',\n  ];\n}\n\n/**\n * WhisperModel class for training Whisper models without a language model head.\n */\nexport class WhisperModel extends WhisperPreTrainedModel { }\n\n/**\n * WhisperForConditionalGeneration class for generating conditional outputs from Whisper models.\n */\nexport class WhisperForConditionalGeneration extends WhisperPreTrainedModel {\n  _prepare_generation_config(generation_config: GenerationConfig, kwargs: Record<string, unknown>) {\n    return /** @type {WhisperGenerationConfig} */ super._prepare_generation_config(\n      generation_config,\n      kwargs,\n      WhisperGenerationConfig,\n    );\n  }\n\n  /**\n   *\n   * @param {WhisperGenerationConfig} generation_config\n   */\n  _retrieve_init_tokens(generation_config: WhisperGenerationConfig) {\n    // prefix tokens are of the form:\n    //  - Multilingual: <|startoftranscript|> <|lang_id|> <|task|> [<|notimestamps|>]\n    //  - English-only: <|startoftranscript|> [<|notimestamps|>]\n\n    // 1. Handle <|startoftranscript|> token\n    const init_tokens = [generation_config.decoder_start_token_id];\n\n    // 2. Handle <|lang_id|> and <|task> tokens\n    let language: string | null = generation_config.language;\n    const task = generation_config.task;\n    if (generation_config.is_multilingual) {\n      if (!language) {\n        // TODO: Implement language detection\n        console.warn('No language specified - defaulting to English (en).');\n        language = 'en';\n      }\n\n      // Add language token\n      const language_code = whisper_language_to_code(language);\n      const language_token = `<|${language_code}|>`;\n      if (generation_config.lang_to_id) {\n        init_tokens.push(generation_config.lang_to_id[language_token]);\n      }\n\n      // Add task token\n      // NOTE: Defaults to 'transcribe' if no task is specified\n      if (!generation_config.task_to_id) throw new Error('task_to_id mapping is required but was not provided');\n      init_tokens.push(generation_config.task_to_id[task ?? 'transcribe']);\n    } else if (language || task) {\n      throw new Error(\n        'Cannot specify `task` or `language` for an English-only model. If the model is intended to be multilingual, pass `is_multilingual=true` to generate, or update the generation config.',\n      );\n    }\n\n    // 3. Handle <|notimestamps|> token\n    if (\n      !generation_config.return_timestamps &&\n      generation_config.no_timestamps_token_id &&\n      init_tokens.at(-1) !== generation_config.no_timestamps_token_id\n    ) {\n      init_tokens.push(generation_config.no_timestamps_token_id);\n    } else if (generation_config.return_timestamps && init_tokens.at(-1) === generation_config.no_timestamps_token_id) {\n      console.warn(\n        '<|notimestamps|> prompt token is removed from generation_config since `return_timestamps` is set to `true`.',\n      );\n      init_tokens.pop();\n    }\n\n    // let's make sure we don't pass `null` tokens as prompt tokens\n    return init_tokens.filter((token) => token != null);\n  }\n\n  /**\n   * Transcribes or translates log-mel input features to a sequence of auto-regressively generated token ids.\n   * @param {import('./models/whisper/generation_whisper.js').WhisperGenerationFunctionParameters} options\n   * @returns {Promise<ModelOutput|Tensor>} The output of the model, which can contain the generated token ids, attentions, and scores.\n   */\n  async generate({\n    inputs = null,\n    generation_config = null,\n    logits_processor = null,\n    stopping_criteria = null,\n\n    // Whisper-specific options (passed to kwargs)\n    // prompt_ids = null,\n    // language = null,\n    // task = null,\n\n    ...kwargs\n  }: any) {\n    generation_config = this._prepare_generation_config(generation_config, kwargs);\n\n    const init_tokens = kwargs.decoder_input_ids ?? this._retrieve_init_tokens(generation_config);\n\n    if (generation_config.return_timestamps) {\n      logits_processor ??= new LogitsProcessorList();\n      logits_processor.push(new WhisperTimeStampLogitsProcessor(generation_config, init_tokens));\n    }\n\n    if (generation_config.begin_suppress_tokens) {\n      logits_processor ??= new LogitsProcessorList();\n      logits_processor.push(\n        new SuppressTokensAtBeginLogitsProcessor(generation_config.begin_suppress_tokens, init_tokens.length),\n      );\n    }\n\n    if (generation_config.return_token_timestamps) {\n      if (!generation_config.alignment_heads) {\n        throw new Error(\n          'Model generation config has no `alignment_heads`, token-level timestamps not available. ' +\n          'See https://gist.github.com/hollance/42e32852f24243b748ae6bc1f985b13a on how to add this property to the generation config.',\n        );\n      }\n\n      if (generation_config.task === 'translate') {\n        console.warn(\"Token-level timestamps may not be reliable for task 'translate'.\");\n      }\n\n      generation_config.output_attentions = true;\n      generation_config.return_dict_in_generate = true;\n    }\n\n    const outputs: any = await super.generate({\n      inputs,\n      generation_config,\n      logits_processor,\n      decoder_input_ids: init_tokens,\n      ...kwargs,\n    });\n\n    if (generation_config.return_token_timestamps) {\n      (outputs as any)['token_timestamps'] = this._extract_token_timestamps(\n        outputs,\n        generation_config.alignment_heads,\n        generation_config.num_frames,\n      );\n    }\n\n    return outputs;\n  }\n\n  /**\n   * Calculates token-level timestamps using the encoder-decoder cross-attentions and\n   * dynamic time-warping (DTW) to map each output token to a position in the input audio.\n   * If `num_frames` is specified, the encoder-decoder cross-attentions will be cropped before applying DTW.\n   * @param {Object} generate_outputs Outputs generated by the model\n   * @param {Tensor[][]} generate_outputs.cross_attentions The cross attentions output by the model\n   * @param {Tensor} generate_outputs.sequences The sequences output by the model\n   * @param {number[][]} alignment_heads Alignment heads of the model\n   * @param {number} [num_frames=null] Number of frames in the input audio.\n   * @param {number} [time_precision=0.02] Precision of the timestamps in seconds\n   * @returns {Tensor} tensor containing the timestamps in seconds for each predicted token\n   */\n  _extract_token_timestamps(\n    generate_outputs: Record<string, unknown>,\n    alignment_heads: number[][],\n    num_frames = null,\n    time_precision = 0.02,\n  ) {\n    if (!generate_outputs.cross_attentions) {\n      throw new Error(\n        'Model outputs must contain cross attentions to extract timestamps. ' +\n        'This is most likely because the model was not exported with `output_attentions=True`.',\n      );\n    }\n    if (num_frames == null) {\n      console.warn(\n        '`num_frames` has not been set, meaning the entire audio will be analyzed. ' +\n        'This may lead to inaccurate token-level timestamps for short audios (< 30 seconds).',\n      );\n    }\n\n    // @ts-expect-error TS2339\n    let median_filter_width = this.config.median_filter_width;\n    if (median_filter_width === undefined) {\n      console.warn('Model config has no `median_filter_width`, using default value of 7.');\n      median_filter_width = 7;\n    }\n\n    // TODO: Improve batch processing\n    const batch = generate_outputs.cross_attentions;\n    // Create a list with `decoder_layers` elements, each a tensor of shape\n    // (batch size, attention_heads, output length, input length).\n    const cross_attentions = Array.from(\n      { length: (this.config as any).decoder_layers },\n      // Concatenate the cross attentions for each layer across sequence length dimension.\n      (_, i) =>\n        cat(\n          (batch as any).map((x: any) => x[i]),\n          2,\n        ),\n    );\n\n    const weights = stack(\n      alignment_heads.map(([l, h]) => {\n        if (l >= cross_attentions.length) {\n          throw new Error(\n            `Layer index ${l} is out of bounds for cross attentions (length ${cross_attentions.length}).`,\n          );\n        }\n        return num_frames\n          ? cross_attentions[l].slice(null, h, null, [0, num_frames])\n          : cross_attentions[l].slice(null, h);\n      }),\n    ).transpose(1, 0, 2, 3);\n\n    const [std, calculatedMean] = std_mean(weights, -2, 0, true);\n\n    // Normalize and smoothen the weights.\n    const smoothedWeights = weights.clone(); // [1, 8, seqLength, 1500]\n\n    for (let a = 0; a < smoothedWeights.dims[0]; ++a) {\n      const aTensor = smoothedWeights[a]; // [8, seqLength, 1500]\n\n      for (let b = 0; b < aTensor.dims[0]; ++b) {\n        const bTensor = aTensor[b]; // [seqLength, 1500]\n\n        const stdTensorData = std[a][b][0].data; // [1500]\n        const meanTensorData = calculatedMean[a][b][0].data; // [1500]\n\n        for (let c = 0; c < bTensor.dims[0]; ++c) {\n          let cTensorData = bTensor[c].data; // [1500]\n          for (let d = 0; d < cTensorData.length; ++d) {\n            cTensorData[d] = (cTensorData[d] - meanTensorData[d]) / stdTensorData[d];\n          }\n\n          // Apply median filter.\n          (cTensorData as any).set(medianFilter((cTensorData as any), median_filter_width));\n        }\n      }\n    }\n\n    // Average the different cross-attention heads.\n    const batchedMatrices = [mean(smoothedWeights, 1)];\n\n    const timestampsShape = (generate_outputs.sequences as any).dims;\n\n    const timestamps = new Tensor(\n      'float32',\n      new Float32Array(timestampsShape[0] * timestampsShape[1]),\n      timestampsShape,\n    );\n\n    // Perform dynamic time warping on each element of the batch.\n    for (let batch_idx = 0; batch_idx < timestampsShape[0]; ++batch_idx) {\n      // NOTE: Since we run only one batch at a time, we can squeeze to get the same dimensions\n      // as the python implementation\n      const matrix = batchedMatrices[batch_idx].neg().squeeze_(0);\n      const [text_indices, time_indices] = dynamic_time_warping(matrix.tolist());\n\n      const diffs = Array.from({ length: text_indices.length - 1 }, (v, i) => text_indices[i + 1] - text_indices[i]);\n      const jumps = mergeArrays([1], diffs).map((x) => !!x); // convert to boolean\n\n      const jump_times = [];\n      for (let i = 0; i < jumps.length; ++i) {\n        if (jumps[i]) {\n          // NOTE: No point in rounding here, since we set to Float32Array later\n          jump_times.push(time_indices[i] * time_precision);\n        }\n      }\n      (timestamps[batch_idx].data as any).set(jump_times, 1);\n    }\n\n    return timestamps;\n  }\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Moonshine models\nexport class MoonshinePreTrainedModel extends PreTrainedModel {\n  requires_attention_mask = false;\n  main_input_name = 'input_values';\n  forward_params = ['input_values', 'decoder_input_ids', 'past_key_values'];\n}\n\n/**\n * MoonshineModel class for training Moonshine models without a language model head.\n */\nexport class MoonshineModel extends MoonshinePreTrainedModel { }\n\nexport class MoonshineForConditionalGeneration extends MoonshinePreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// LLaVa Models\nexport class LlavaPreTrainedModel extends PreTrainedModel {\n  forward_params = ['input_ids', 'attention_mask', 'pixel_values', 'position_ids', 'past_key_values'];\n}\n\n/**\n * The LLAVA model which consists of a vision backbone and a language model.\n */\nexport class LlavaForConditionalGeneration extends LlavaPreTrainedModel {\n  _merge_input_ids_with_image_features({ inputs_embeds, image_features, input_ids, attention_mask }: any) {\n    // @ts-expect-error TS2339\n    const image_token_index = this.config.image_token_index;\n\n    const idsList = input_ids.tolist();\n\n    // NOTE: we use .findIndex instead of .indexOf to perform weak comparison (==) between BigInt and Number\n    const indexOfImage = idsList.map((x: any) => x.findIndex((x: any) => x == image_token_index));\n\n    const noImages = indexOfImage.every((x: any) => x === -1);\n    const allImages = indexOfImage.every((x: any) => x !== -1);\n    if (!noImages && !allImages) {\n      // Check for padding reasons\n      throw new Error('Every input should contain either 0 or 1 image token.');\n    }\n\n    if (noImages) {\n      return {\n        inputs_embeds,\n        attention_mask,\n      };\n    }\n\n    const stacked = [];\n    const stacked_attention_mask = [];\n    for (let i = 0; i < indexOfImage.length; ++i) {\n      const index = indexOfImage[i];\n\n      const e = inputs_embeds[i];\n      const im = image_features[i];\n      const am = attention_mask[i];\n      stacked.push(cat([e.slice([0, index]), im, e.slice([index + 1, e.dims[0]])], 0));\n\n      stacked_attention_mask.push(\n        cat([am.slice([0, index]), ones([im.dims[0]]), am.slice([index + 1, am.dims[0]])], 0),\n      );\n    }\n\n    return {\n      inputs_embeds: stack(stacked, 0),\n      attention_mask: stack(stacked_attention_mask, 0),\n    };\n  }\n}\n//////////////////////////////////////////////////\n\nexport class LlavaOnevisionForConditionalGeneration extends LlavaForConditionalGeneration { } // NOTE: extends LlavaForConditionalGeneration\nexport class Moondream1ForConditionalGeneration extends LlavaForConditionalGeneration { } // NOTE: extends LlavaForConditionalGeneration\n\nexport class Florence2PreTrainedModel extends PreTrainedModel {\n  forward_params = [\n    // Encoder inputs\n    'input_ids',\n    'inputs_embeds',\n    'attention_mask',\n    'pixel_values',\n\n    // Decoder inputs\n    'encoder_outputs',\n    'decoder_input_ids',\n    'decoder_inputs_embeds',\n    'decoder_attention_mask',\n    'past_key_values',\n  ];\n  main_input_name = 'inputs_embeds';\n}\n\nexport class Florence2ForConditionalGeneration extends Florence2PreTrainedModel {\n  _merge_input_ids_with_image_features({\n    inputs_embeds,\n    image_features,\n    input_ids,\n    attention_mask,\n  }: {\n    inputs_embeds: Tensor;\n    image_features: Tensor;\n    input_ids: Tensor;\n    attention_mask: Tensor;\n  }) {\n    return {\n      inputs_embeds: cat(\n        [\n          image_features, // image embeds\n          inputs_embeds, // task prefix embeds\n        ],\n        1,\n      ),\n      attention_mask: cat(\n        [\n          ones(image_features.dims.slice(0, 2)), // image attention mask\n          attention_mask, // task prefix attention mask\n        ],\n        1,\n      ),\n    };\n  }\n\n  async _prepare_inputs_embeds({\n    input_ids,\n    pixel_values,\n    inputs_embeds,\n    attention_mask,\n  }: {\n    input_ids: Tensor | null;\n    pixel_values: Tensor | null;\n    inputs_embeds: Tensor | null;\n    attention_mask: Tensor | null;\n  }) {\n    if (!input_ids && !pixel_values) {\n      throw new Error('Either `input_ids` or `pixel_values` should be provided.');\n    }\n\n    // 1. Possibly, extract the input embeddings\n    let text_features, image_features;\n    if (input_ids) {\n      text_features = await this.encode_text({ input_ids });\n    }\n    if (pixel_values) {\n      image_features = await this.encode_image({ pixel_values });\n    }\n\n    // 2. Possibly, merge text and images\n    if (text_features && image_features) {\n      ({ inputs_embeds, attention_mask } = this._merge_input_ids_with_image_features({\n        inputs_embeds: text_features,\n        image_features,\n        input_ids: input_ids as Tensor,\n        attention_mask: attention_mask as Tensor,\n      }));\n    } else {\n      inputs_embeds = text_features || image_features;\n    }\n\n    return { inputs_embeds, attention_mask };\n  }\n\n  async forward({\n    input_ids,\n    pixel_values,\n    attention_mask,\n    decoder_input_ids,\n    decoder_attention_mask,\n    encoder_outputs,\n    past_key_values,\n\n    inputs_embeds,\n    decoder_inputs_embeds,\n  }: any) {\n    if (!inputs_embeds) {\n      ({ inputs_embeds, attention_mask } = await this._prepare_inputs_embeds({\n        input_ids,\n        pixel_values,\n        inputs_embeds,\n        attention_mask,\n      }));\n    }\n\n    if (!encoder_outputs) {\n      // Must compute encoder outputs\n      let { last_hidden_state } = await encoderForward(this, { inputs_embeds, attention_mask });\n      encoder_outputs = last_hidden_state;\n    }\n\n    if (!decoder_inputs_embeds) {\n      if (!decoder_input_ids) {\n        throw new Error('Either `decoder_input_ids` or `decoder_inputs_embeds` should be provided.');\n      }\n      decoder_inputs_embeds = await this.encode_text({ input_ids: decoder_input_ids });\n    }\n\n    const decoderFeeds = {\n      inputs_embeds: decoder_inputs_embeds,\n      attention_mask: decoder_attention_mask,\n      encoder_attention_mask: attention_mask,\n      encoder_hidden_states: encoder_outputs,\n      past_key_values,\n    };\n    const decoder_outputs = await decoderForward(this, decoderFeeds, true);\n    return decoder_outputs;\n  }\n}\n\nexport class PaliGemmaPreTrainedModel extends PreTrainedModel {\n  forward_params = [\n    'input_ids',\n    // 'inputs_embeds',\n    'attention_mask',\n    'pixel_values',\n    'position_ids',\n    'past_key_values',\n  ];\n}\n\nexport class PaliGemmaForConditionalGeneration extends PaliGemmaPreTrainedModel {\n  _merge_input_ids_with_image_features(kwargs: any) {\n    const vision_hidden_size = kwargs.image_features.dims.at(-1);\n    const reshaped_image_hidden_states = kwargs.image_features.view(-1, vision_hidden_size);\n\n    return default_merge_input_ids_with_image_features({\n      image_token_id: (this.config as any).image_token_index,\n      image_features: reshaped_image_hidden_states,\n      ...kwargs,\n    });\n  }\n}\n\n//////////////////////////////////////////////////\n// Idefics3 Models\nexport class Idefics3PreTrainedModel extends PreTrainedModel {\n  forward_params = [\n    'input_ids',\n    'attention_mask',\n    'pixel_values',\n    'pixel_attention_mask',\n    'position_ids',\n    'past_key_values',\n  ];\n}\n\n/**\n * The LLAVA model which consists of a vision backbone and a language model.\n */\nexport class Idefics3ForConditionalGeneration extends Idefics3PreTrainedModel {\n  async encode_image({ pixel_values, pixel_attention_mask }: { pixel_values: Tensor; pixel_attention_mask: Tensor }) {\n    const features = (await sessionRun(this.sessions['vision_encoder'], { pixel_values, pixel_attention_mask }))\n      .image_features;\n    return features;\n  }\n\n  _merge_input_ids_with_image_features(kwargs: any) {\n    const vision_hidden_size = kwargs.image_features.dims.at(-1);\n    const reshaped_image_hidden_states = kwargs.image_features.view(-1, vision_hidden_size);\n\n    return default_merge_input_ids_with_image_features({\n      image_token_id: (this.config as any).image_token_id,\n      ...kwargs,\n      image_features: reshaped_image_hidden_states,\n    });\n  }\n}\n//////////////////////////////////////////////////\n\nexport class Phi3VPreTrainedModel extends PreTrainedModel {\n  forward_params = [\n    'input_ids',\n    'inputs_embeds',\n    'attention_mask',\n    'position_ids',\n    'pixel_values',\n    'image_sizes',\n    'past_key_values',\n  ];\n}\nexport class Phi3VForCausalLM extends Phi3VPreTrainedModel {\n  async forward({\n    // Produced by the tokenizer/processor:\n    input_ids = null,\n    attention_mask = null,\n    pixel_values = null,\n    image_sizes = null,\n\n    // Used during generation:\n    position_ids = null,\n    inputs_embeds = null,\n    past_key_values = null,\n\n    // Generic generation parameters\n    generation_config = null,\n    logits_processor = null,\n\n    // TODO: needed?\n    ...kwargs\n  }) {\n    if (!inputs_embeds) {\n      let image_features;\n      if (pixel_values && (input_ids as any).dims[1] !== 1) {\n        if (!image_sizes) {\n          throw new Error('`image_sizes` must be provided when `pixel_values` is provided.');\n        }\n\n        // Encode the image\n        ({ image_features } = await sessionRun(this.sessions['vision_encoder'], {\n          pixel_values,\n          image_sizes,\n        }));\n      } else {\n        const hidden_size = this.config.normalized_config.hidden_size;\n        image_features = new Tensor('float32', [], [0, hidden_size]);\n      }\n\n      ({ inputs_embeds } = await sessionRun(this.sessions['prepare_inputs_embeds'], {\n        input_ids,\n        image_features,\n      }));\n    }\n\n    const outputs = await decoderForward(\n      this,\n      {\n        inputs_embeds,\n        past_key_values,\n        attention_mask,\n        position_ids,\n        generation_config,\n        logits_processor,\n      },\n      false,\n    );\n    return outputs;\n  }\n}\n\n//////////////////////////////////////////////////\nexport class CLIPPreTrainedModel extends PreTrainedModel { }\n\n/**\n * CLIP Text and Vision Model with a projection layers on top\n *\n * **Example:** Perform zero-shot image classification with a `CLIPModel`.\n *\n * ```javascript\n * import { AutoTokenizer, AutoProcessor, CLIPModel, RawImage } from '@huggingface/transformers';\n *\n * // Load tokenizer, processor, and model\n * let tokenizer = await AutoTokenizer.from_pretrained('Xenova/clip-vit-base-patch16');\n * let processor = await AutoProcessor.from_pretrained('Xenova/clip-vit-base-patch16');\n * let model = await CLIPModel.from_pretrained('Xenova/clip-vit-base-patch16');\n *\n * // Run tokenization\n * let texts = ['a photo of a car', 'a photo of a football match']\n * let text_inputs = tokenizer(texts, { padding: true, truncation: true });\n *\n * // Read image and run processor\n * let image = await RawImage.read('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/football-match.jpg');\n * let image_inputs = await processor(image);\n *\n * // Run model with both text and pixel inputs\n * let output = await model({ ...text_inputs, ...image_inputs });\n * // {\n * //   logits_per_image: Tensor {\n * //     dims: [ 1, 2 ],\n * //     data: Float32Array(2) [ 18.579734802246094, 24.31830596923828 ],\n * //   },\n * //   logits_per_text: Tensor {\n * //     dims: [ 2, 1 ],\n * //     data: Float32Array(2) [ 18.579734802246094, 24.31830596923828 ],\n * //   },\n * //   text_embeds: Tensor {\n * //     dims: [ 2, 512 ],\n * //     data: Float32Array(1024) [ ... ],\n * //   },\n * //   image_embeds: Tensor {\n * //     dims: [ 1, 512 ],\n * //     data: Float32Array(512) [ ... ],\n * //   }\n * // }\n * ```\n */\nexport class CLIPModel extends CLIPPreTrainedModel { }\n\n/**\n * The text model from CLIP without any head or projection on top.\n */\nexport class CLIPTextModel extends CLIPPreTrainedModel {\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any = {}) {\n    return super.from_pretrained(pretrained_model_name_or_path, {\n      ...options,\n      // Update default model file name if not provided\n      model_file_name: options.model_file_name ?? 'text_model',\n    });\n  }\n}\n\n/**\n * CLIP Text Model with a projection layer on top (a linear layer on top of the pooled output)\n *\n * **Example:** Compute text embeddings with `CLIPTextModelWithProjection`.\n *\n * ```javascript\n * import { AutoTokenizer, CLIPTextModelWithProjection } from '@huggingface/transformers';\n *\n * // Load tokenizer and text model\n * const tokenizer = await AutoTokenizer.from_pretrained('Xenova/clip-vit-base-patch16');\n * const text_model = await CLIPTextModelWithProjection.from_pretrained('Xenova/clip-vit-base-patch16');\n *\n * // Run tokenization\n * let texts = ['a photo of a car', 'a photo of a football match'];\n * let text_inputs = tokenizer(texts, { padding: true, truncation: true });\n *\n * // Compute embeddings\n * const { text_embeds } = await text_model(text_inputs);\n * // Tensor {\n * //   dims: [ 2, 512 ],\n * //   type: 'float32',\n * //   data: Float32Array(1024) [ ... ],\n * //   size: 1024\n * // }\n * ```\n */\nexport class CLIPTextModelWithProjection extends CLIPPreTrainedModel {\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any = {}) {\n    return super.from_pretrained(pretrained_model_name_or_path, {\n      ...options,\n      // Update default model file name if not provided\n      model_file_name: options.model_file_name ?? 'text_model',\n    });\n  }\n}\n\n/**\n * The vision model from CLIP without any head or projection on top.\n */\nexport class CLIPVisionModel extends CLIPPreTrainedModel {\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any = {}) {\n    return super.from_pretrained(pretrained_model_name_or_path, {\n      ...options,\n      // Update default model file name if not provided\n      model_file_name: options.model_file_name ?? 'vision_model',\n    });\n  }\n}\n\n/**\n * CLIP Vision Model with a projection layer on top (a linear layer on top of the pooled output)\n *\n * **Example:** Compute vision embeddings with `CLIPVisionModelWithProjection`.\n *\n * ```javascript\n * import { AutoProcessor, CLIPVisionModelWithProjection, RawImage} from '@huggingface/transformers';\n *\n * // Load processor and vision model\n * const processor = await AutoProcessor.from_pretrained('Xenova/clip-vit-base-patch16');\n * const vision_model = await CLIPVisionModelWithProjection.from_pretrained('Xenova/clip-vit-base-patch16');\n *\n * // Read image and run processor\n * let image = await RawImage.read('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/football-match.jpg');\n * let image_inputs = await processor(image);\n *\n * // Compute embeddings\n * const { image_embeds } = await vision_model(image_inputs);\n * // Tensor {\n * //   dims: [ 1, 512 ],\n * //   type: 'float32',\n * //   data: Float32Array(512) [ ... ],\n * //   size: 512\n * // }\n * ```\n */\nexport class CLIPVisionModelWithProjection extends CLIPPreTrainedModel {\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any = {}) {\n    return super.from_pretrained(pretrained_model_name_or_path, {\n      ...options,\n      // Update default model file name if not provided\n      model_file_name: options.model_file_name ?? 'vision_model',\n    });\n  }\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// SigLIP models\nexport class SiglipPreTrainedModel extends PreTrainedModel { }\n\n/**\n * SigLIP Text and Vision Model with a projection layers on top\n *\n * **Example:** Perform zero-shot image classification with a `SiglipModel`.\n *\n * ```javascript\n * import { AutoTokenizer, AutoProcessor, SiglipModel, RawImage } from '@huggingface/transformers';\n *\n * // Load tokenizer, processor, and model\n * const tokenizer = await AutoTokenizer.from_pretrained('Xenova/siglip-base-patch16-224');\n * const processor = await AutoProcessor.from_pretrained('Xenova/siglip-base-patch16-224');\n * const model = await SiglipModel.from_pretrained('Xenova/siglip-base-patch16-224');\n *\n * // Run tokenization\n * const texts = ['a photo of 2 cats', 'a photo of 2 dogs'];\n * const text_inputs = tokenizer(texts, { padding: 'max_length', truncation: true });\n *\n * // Read image and run processor\n * const image = await RawImage.read('http://images.cocodataset.org/val2017/000000039769.jpg');\n * const image_inputs = await processor(image);\n *\n * // Run model with both text and pixel inputs\n * const output = await model({ ...text_inputs, ...image_inputs });\n * // {\n * //   logits_per_image: Tensor {\n * //     dims: [ 1, 2 ],\n * //     data: Float32Array(2) [ -1.6019744873046875, -10.720091819763184 ],\n * //   },\n * //   logits_per_text: Tensor {\n * //     dims: [ 2, 1 ],\n * //     data: Float32Array(2) [ -1.6019744873046875, -10.720091819763184 ],\n * //   },\n * //   text_embeds: Tensor {\n * //     dims: [ 2, 768 ],\n * //     data: Float32Array(1536) [ ... ],\n * //   },\n * //   image_embeds: Tensor {\n * //     dims: [ 1, 768 ],\n * //     data: Float32Array(768) [ ... ],\n * //   }\n * // }\n * ```\n */\nexport class SiglipModel extends SiglipPreTrainedModel { }\n\n/**\n * The text model from SigLIP without any head or projection on top.\n *\n * **Example:** Compute text embeddings with `SiglipTextModel`.\n *\n * ```javascript\n * import { AutoTokenizer, SiglipTextModel } from '@huggingface/transformers';\n *\n * // Load tokenizer and text model\n * const tokenizer = await AutoTokenizer.from_pretrained('Xenova/siglip-base-patch16-224');\n * const text_model = await SiglipTextModel.from_pretrained('Xenova/siglip-base-patch16-224');\n *\n * // Run tokenization\n * const texts = ['a photo of 2 cats', 'a photo of 2 dogs'];\n * const text_inputs = tokenizer(texts, { padding: 'max_length', truncation: true });\n *\n * // Compute embeddings\n * const { pooler_output } = await text_model(text_inputs);\n * // Tensor {\n * //   dims: [ 2, 768 ],\n * //   type: 'float32',\n * //   data: Float32Array(1536) [ ... ],\n * //   size: 1536\n * // }\n * ```\n */\nexport class SiglipTextModel extends SiglipPreTrainedModel {\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any = {}) {\n    return super.from_pretrained(pretrained_model_name_or_path, {\n      ...options,\n      // Update default model file name if not provided\n      model_file_name: options.model_file_name ?? 'text_model',\n    });\n  }\n}\n\n/**\n * The vision model from SigLIP without any head or projection on top.\n *\n * **Example:** Compute vision embeddings with `SiglipVisionModel`.\n *\n * ```javascript\n * import { AutoProcessor, SiglipVisionModel, RawImage} from '@huggingface/transformers';\n *\n * // Load processor and vision model\n * const processor = await AutoProcessor.from_pretrained('Xenova/siglip-base-patch16-224');\n * const vision_model = await SiglipVisionModel.from_pretrained('Xenova/siglip-base-patch16-224');\n *\n * // Read image and run processor\n * const image = await RawImage.read('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/football-match.jpg');\n * const image_inputs = await processor(image);\n *\n * // Compute embeddings\n * const { pooler_output } = await vision_model(image_inputs);\n * // Tensor {\n * //   dims: [ 1, 768 ],\n * //   type: 'float32',\n * //   data: Float32Array(768) [ ... ],\n * //   size: 768\n * // }\n * ```\n */\nexport class SiglipVisionModel extends CLIPPreTrainedModel {\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any = {}) {\n    return super.from_pretrained(pretrained_model_name_or_path, {\n      ...options,\n      // Update default model file name if not provided\n      model_file_name: options.model_file_name ?? 'vision_model',\n    });\n  }\n}\n//////////////////////////////////////////////////\n// ChineseCLIP models\nexport class ChineseCLIPPreTrainedModel extends PreTrainedModel { }\n\nexport class ChineseCLIPModel extends ChineseCLIPPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// JinaCLIP models\nexport class JinaCLIPPreTrainedModel extends PreTrainedModel { }\n\nexport class JinaCLIPModel extends JinaCLIPPreTrainedModel {\n  async forward(model_inputs: any) {\n    const missing_text_inputs = !model_inputs.input_ids;\n    const missing_image_inputs = !model_inputs.pixel_values;\n\n    if (missing_text_inputs && missing_image_inputs) {\n      throw new Error('Either `input_ids` or `pixel_values` should be provided.');\n    }\n\n    // If either `input_ids` or `pixel_values` aren't passed, we need to create dummy input since the model requires a value to be specified.\n    if (missing_text_inputs) {\n      // NOTE: We cannot pass zero-dimension tensor as input for input_ids.\n      // Fortunately, the majority of time is spent in the vision encoder, so this shouldn't significantly impact performance.\n      model_inputs.input_ids = ones([model_inputs.pixel_values.dims[0], 1]);\n    }\n\n    if (missing_image_inputs) {\n      // NOTE: Since we create a zero-sized tensor, this does not increase computation time.\n      // @ts-ignore\n      const { image_size } = this.config.vision_config;\n      model_inputs.pixel_values = full([0, 3, image_size, image_size], 0.0); // (pass zero-dimension tensor)\n    }\n\n    const { text_embeddings, image_embeddings, l2norm_text_embeddings, l2norm_image_embeddings } = await super.forward(\n      model_inputs,\n    );\n\n    const result: any = {};\n    if (!missing_text_inputs) {\n      result.text_embeddings = text_embeddings;\n      result.l2norm_text_embeddings = l2norm_text_embeddings;\n    }\n    if (!missing_image_inputs) {\n      result.image_embeddings = image_embeddings;\n      result.l2norm_image_embeddings = l2norm_image_embeddings;\n    }\n    return result;\n  }\n}\n\nexport class JinaCLIPTextModel extends JinaCLIPPreTrainedModel {\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any = {}) {\n    return super.from_pretrained(pretrained_model_name_or_path, {\n      ...options,\n      // Update default model file name if not provided\n      model_file_name: options.model_file_name ?? 'text_model',\n    });\n  }\n}\n\nexport class JinaCLIPVisionModel extends JinaCLIPPreTrainedModel {\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any = {}) {\n    return super.from_pretrained(pretrained_model_name_or_path, {\n      ...options,\n      // Update default model file name if not provided\n      model_file_name: options.model_file_name ?? 'vision_model',\n    });\n  }\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// GPT2 models\nexport class GPT2PreTrainedModel extends PreTrainedModel { }\n\nexport class GPT2Model extends GPT2PreTrainedModel { }\n\n/**\n * GPT-2 language model head on top of the GPT-2 base model. This model is suitable for text generation tasks.\n */\nexport class GPT2LMHeadModel extends GPT2PreTrainedModel { }\n// export class GPT2ForSequenceClassification extends GPT2PreTrainedModel {\n// TODO\n// }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// JAIS models\nexport class JAISPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare JAIS Model transformer outputting raw hidden-states without any specific head on top.\n */\nexport class JAISModel extends JAISPreTrainedModel { }\n\n/**\n * The JAIS Model transformer with a language modeling head on top (linear layer with weights tied to the input embeddings).\n */\nexport class JAISLMHeadModel extends JAISPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// GPTNeo models\nexport class GPTNeoPreTrainedModel extends PreTrainedModel { }\nexport class GPTNeoModel extends GPTNeoPreTrainedModel { }\n\nexport class GPTNeoForCausalLM extends GPTNeoPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// GPTNeoX models\nexport class GPTNeoXPreTrainedModel extends PreTrainedModel { }\nexport class GPTNeoXModel extends GPTNeoXPreTrainedModel { }\n\nexport class GPTNeoXForCausalLM extends GPTNeoXPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// GPT-J models\nexport class GPTJPreTrainedModel extends PreTrainedModel { }\n\nexport class GPTJModel extends GPTJPreTrainedModel { }\n\nexport class GPTJForCausalLM extends GPTJPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// GPTBigCode models\nexport class GPTBigCodePreTrainedModel extends PreTrainedModel { }\n\nexport class GPTBigCodeModel extends GPTBigCodePreTrainedModel { }\n\nexport class GPTBigCodeForCausalLM extends GPTBigCodePreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// CodeGen models\nexport class CodeGenPreTrainedModel extends PreTrainedModel { }\n/**\n * CodeGenModel is a class representing a code generation model without a language model head.\n */\nexport class CodeGenModel extends CodeGenPreTrainedModel { }\n\n/**\n * CodeGenForCausalLM is a class that represents a code generation model based on the GPT-2 architecture. It extends the `CodeGenPreTrainedModel` class.\n */\nexport class CodeGenForCausalLM extends CodeGenPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// LLama models\n\n/**\n * The bare LLama Model outputting raw hidden-states without any specific head on top.\n */\nexport class LlamaPreTrainedModel extends PreTrainedModel { }\n/**\n * The bare LLaMA Model outputting raw hidden-states without any specific head on top.\n */\nexport class LlamaModel extends LlamaPreTrainedModel { }\n\nexport class LlamaForCausalLM extends LlamaPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// EXAONE models\nexport class ExaonePreTrainedModel extends PreTrainedModel { }\nexport class ExaoneModel extends ExaonePreTrainedModel { }\nexport class ExaoneForCausalLM extends ExaonePreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// MobileLLM models\nexport class MobileLLMPreTrainedModel extends PreTrainedModel { }\nexport class MobileLLMModel extends MobileLLMPreTrainedModel { }\nexport class MobileLLMForCausalLM extends MobileLLMPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// OLMo models\nexport class OlmoPreTrainedModel extends PreTrainedModel { }\nexport class OlmoModel extends OlmoPreTrainedModel { }\nexport class OlmoForCausalLM extends OlmoPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// OLMo2 models\nexport class Olmo2PreTrainedModel extends PreTrainedModel { }\nexport class Olmo2Model extends Olmo2PreTrainedModel { }\nexport class Olmo2ForCausalLM extends Olmo2PreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Granite models\nexport class GranitePreTrainedModel extends PreTrainedModel { }\nexport class GraniteModel extends GranitePreTrainedModel { }\nexport class GraniteForCausalLM extends GranitePreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Cohere models\n\n/**\n * The bare Cohere Model outputting raw hidden-states without any specific head on top.\n */\nexport class CoherePreTrainedModel extends PreTrainedModel { }\nexport class CohereModel extends CoherePreTrainedModel { }\n\nexport class CohereForCausalLM extends CoherePreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Gemma models\n\n/**\n * The bare Gemma Model outputting raw hidden-states without any specific head on top.\n */\nexport class GemmaPreTrainedModel extends PreTrainedModel { }\n/**\n * The bare Gemma Model outputting raw hidden-states without any specific head on top.\n */\nexport class GemmaModel extends GemmaPreTrainedModel { }\n\nexport class GemmaForCausalLM extends GemmaPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Gemma2 models\n\n/**\n * The bare Gemma2 Model outputting raw hidden-states without any specific head on top.\n */\nexport class Gemma2PreTrainedModel extends PreTrainedModel { }\n/**\n * The bare Gemma2 Model outputting raw hidden-states without any specific head on top.\n */\nexport class Gemma2Model extends Gemma2PreTrainedModel { }\n\nexport class Gemma2ForCausalLM extends Gemma2PreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\nexport class OpenELMPreTrainedModel extends PreTrainedModel { }\nexport class OpenELMModel extends OpenELMPreTrainedModel { }\n\nexport class OpenELMForCausalLM extends OpenELMPreTrainedModel { }\n\n//////////////////////////////////////////////////\n// Qwen2 models\n\n/**\n * The bare Qwen2 Model outputting raw hidden-states without any specific head on top.\n */\nexport class Qwen2PreTrainedModel extends PreTrainedModel { }\n/**\n * The bare Qwen2 Model outputting raw hidden-states without any specific head on top.\n */\nexport class Qwen2Model extends Qwen2PreTrainedModel { }\n\nexport class Qwen2ForCausalLM extends Qwen2PreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Phi models\nexport class PhiPreTrainedModel extends PreTrainedModel { }\n/**\n * The bare Phi Model outputting raw hidden-states without any specific head on top.\n */\nexport class PhiModel extends PhiPreTrainedModel { }\n\nexport class PhiForCausalLM extends PhiPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Phi3 models\nexport class Phi3PreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare Phi3 Model outputting raw hidden-states without any specific head on top.\n */\nexport class Phi3Model extends Phi3PreTrainedModel { }\n\nexport class Phi3ForCausalLM extends Phi3PreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Bloom models\n/**\n * The Bloom Model transformer with a language modeling head on top (linear layer with weights tied to the input embeddings).\n */\nexport class BloomPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare Bloom Model transformer outputting raw hidden-states without any specific head on top.\n */\nexport class BloomModel extends BloomPreTrainedModel { }\n\n/**\n * The Bloom Model transformer with a language modeling head on top (linear layer with weights tied to the input embeddings).\n */\nexport class BloomForCausalLM extends BloomPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// MPT models\nexport class MptPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare Mpt Model transformer outputting raw hidden-states without any specific head on top.\n */\nexport class MptModel extends MptPreTrainedModel { }\n\n/**\n * The MPT Model transformer with a language modeling head on top (linear layer with weights tied to the input embeddings).\n */\nexport class MptForCausalLM extends MptPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// OPT models\nexport class OPTPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare OPT Model outputting raw hidden-states without any specific head on top.\n */\nexport class OPTModel extends OPTPreTrainedModel { }\n\n/**\n * The OPT Model transformer with a language modeling head on top (linear layer with weights tied to the input embeddings).\n */\nexport class OPTForCausalLM extends OPTPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\nexport class VitPosePreTrainedModel extends PreTrainedModel { }\n\n/**\n * The VitPose model with a pose estimation head on top.\n */\nexport class VitPoseForPoseEstimation extends VitPosePreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\nexport class ViTMAEPreTrainedModel extends PreTrainedModel { }\nexport class ViTMAEModel extends ViTMAEPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\nexport class GroupViTPreTrainedModel extends PreTrainedModel { }\nexport class GroupViTModel extends GroupViTPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\nexport class VitMattePreTrainedModel extends PreTrainedModel { }\n\n/**\n * ViTMatte framework leveraging any vision backbone e.g. for ADE20k, CityScapes.\n *\n * **Example:** Perform image matting with a `VitMatteForImageMatting` model.\n * ```javascript\n * import { AutoProcessor, VitMatteForImageMatting, RawImage } from '@huggingface/transformers';\n *\n * // Load processor and model\n * const processor = await AutoProcessor.from_pretrained('Xenova/vitmatte-small-distinctions-646');\n * const model = await VitMatteForImageMatting.from_pretrained('Xenova/vitmatte-small-distinctions-646');\n *\n * // Load image and trimap\n * const image = await RawImage.fromURL('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/vitmatte_image.png');\n * const trimap = await RawImage.fromURL('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/vitmatte_trimap.png');\n *\n * // Prepare image + trimap for the model\n * const inputs = await processor(image, trimap);\n *\n * // Predict alpha matte\n * const { alphas } = await model(inputs);\n * // Tensor {\n * //   dims: [ 1, 1, 640, 960 ],\n * //   type: 'float32',\n * //   size: 614400,\n * //   data: Float32Array(614400) [ 0.9894027709960938, 0.9970508813858032, ... ]\n * // }\n * ```\n *\n * You can visualize the alpha matte as follows:\n * ```javascript\n * import { Tensor, cat } from '@huggingface/transformers';\n *\n * // Visualize predicted alpha matte\n * const imageTensor = image.toTensor();\n *\n * // Convert float (0-1) alpha matte to uint8 (0-255)\n * const alphaChannel = alphas\n *   .squeeze(0)\n *   .mul_(255)\n *   .clamp_(0, 255)\n *   .round_()\n *   .to('uint8');\n *\n * // Concatenate original image with predicted alpha\n * const imageData = cat([imageTensor, alphaChannel], 0);\n *\n * // Save output image\n * const outputImage = RawImage.fromTensor(imageData);\n * outputImage.save('output.png');\n * ```\n */\nexport class VitMatteForImageMatting extends VitMattePreTrainedModel {\n  /**\n   * @param {any} model_inputs\n   */\n  async _call(model_inputs: any) {\n    return new ImageMattingOutput(await super._call(model_inputs));\n  }\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\nexport class Swin2SRPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare Swin2SR Model transformer outputting raw hidden-states without any specific head on top.\n */\nexport class Swin2SRModel extends Swin2SRPreTrainedModel { }\n\n/**\n * Swin2SR Model transformer with an upsampler head on top for image super resolution and restoration.\n *\n * **Example:** Super-resolution w/ `Xenova/swin2SR-classical-sr-x2-64`.\n *\n * ```javascript\n * import { AutoProcessor, Swin2SRForImageSuperResolution, RawImage } from '@huggingface/transformers';\n *\n * // Load processor and model\n * const model_id = 'Xenova/swin2SR-classical-sr-x2-64';\n * const processor = await AutoProcessor.from_pretrained(model_id);\n * const model = await Swin2SRForImageSuperResolution.from_pretrained(model_id);\n *\n * // Prepare model inputs\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/butterfly.jpg';\n * const image = await RawImage.fromURL(url);\n * const inputs = await processor(image);\n *\n * // Run model\n * const outputs = await model(inputs);\n *\n * // Convert Tensor to RawImage\n * const output = outputs.reconstruction.squeeze().clamp_(0, 1).mul_(255).round_().to('uint8');\n * const outputImage = RawImage.fromTensor(output);\n * // RawImage {\n * //   data: Uint8Array(786432) [ 41, 31, 24, ... ],\n * //   width: 512,\n * //   height: 512,\n * //   channels: 3\n * // }\n * ```\n */\nexport class Swin2SRForImageSuperResolution extends Swin2SRPreTrainedModel { }\n//////////////////////////////////////////////////\n\n\n//////////////////////////////////////////////////\nexport class SamPreTrainedModel extends PreTrainedModel { }\n\n/**\n * Segment Anything Model (SAM) for generating segmentation masks, given an input image\n * and optional 2D location and bounding boxes.\n *\n * **Example:** Perform mask generation w/ `Xenova/sam-vit-base`.\n * ```javascript\n * import { SamModel, AutoProcessor, RawImage } from '@huggingface/transformers';\n *\n * const model = await SamModel.from_pretrained('Xenova/sam-vit-base');\n * const processor = await AutoProcessor.from_pretrained('Xenova/sam-vit-base');\n *\n * const img_url = 'https://huggingface.co/ybelkada/segment-anything/resolve/main/assets/car.png';\n * const raw_image = await RawImage.read(img_url);\n * const input_points = [[[450, 600]]] // 2D localization of a window\n *\n * const inputs = await processor(raw_image, { input_points });\n * const outputs = await model(inputs);\n *\n * const masks = await processor.post_process_masks(outputs.pred_masks, inputs.original_sizes, inputs.reshaped_input_sizes);\n * // [\n * //   Tensor {\n * //     dims: [ 1, 3, 1764, 2646 ],\n * //     type: 'bool',\n * //     data: Uint8Array(14002632) [ ... ],\n * //     size: 14002632\n * //   }\n * // ]\n * const scores = outputs.iou_scores;\n * // Tensor {\n * //   dims: [ 1, 1, 3 ],\n * //   type: 'float32',\n * //   data: Float32Array(3) [\n * //     0.8892380595207214,\n * //     0.9311248064041138,\n * //     0.983696699142456\n * //   ],\n * //   size: 3\n * // }\n * ```\n */\nexport class SamModel extends SamPreTrainedModel {\n  /**\n   * Compute image embeddings and positional image embeddings, given the pixel values of an image.\n   * @param {Object} model_inputs Object containing the model inputs.\n   * @param {Tensor} model_inputs.pixel_values Pixel values obtained using a `SamProcessor`.\n   * @returns {Promise<{ image_embeddings: Tensor, image_positional_embeddings: Tensor }>} The image embeddings and positional image embeddings.\n   */\n  async get_image_embeddings({ pixel_values }: { pixel_values: Tensor }) {\n    // in:\n    //  - pixel_values: tensor.float32[batch_size,3,1024,1024]\n    //\n    // out:\n    //  - image_embeddings: tensor.float32[batch_size,256,64,64]\n    //  - image_positional_embeddings: tensor.float32[batch_size,256,64,64]\n    return await encoderForward(this, { pixel_values });\n  }\n\n  /**\n   * @typedef {Object} SamModelInputs Object containing the model inputs.\n   * @property {Tensor} pixel_values Pixel values as a Tensor with shape `(batch_size, num_channels, height, width)`.\n   * These can be obtained using a `SamProcessor`.\n   * @property {Tensor} [input_points] Input 2D spatial points with shape `(batch_size, num_points, 2)`.\n   * This is used by the prompt encoder to encode the prompt.\n   * @property {Tensor} [input_labels] Input labels for the points, as a Tensor of shape `(batch_size, point_batch_size, num_points)`.\n   * This is used by the prompt encoder to encode the prompt. There are 4 types of labels:\n   *  - `1`: the point is a point that contains the object of interest\n   *  - `0`: the point is a point that does not contain the object of interest\n   *  - `-1`: the point corresponds to the background\n   *  - `-10`: the point is a padding point, thus should be ignored by the prompt encoder\n   * @property {Tensor} [input_boxes] Input bounding boxes with shape `(batch_size, num_boxes, 4)`.\n   * @property {Tensor} [image_embeddings] Image embeddings used by the mask decoder.\n   * @property {Tensor} [image_positional_embeddings] Image positional embeddings used by the mask decoder.\n   */\n\n  /**\n   * @param {SamModelInputs} model_inputs Object containing the model inputs.\n   * @returns {Promise<Object>} The output of the model.\n   */\n  async forward(model_inputs: any) {\n    if (!model_inputs.image_embeddings || !model_inputs.image_positional_embeddings) {\n      // Compute the image embeddings if they are missing\n      model_inputs = {\n        ...model_inputs,\n        ...(await this.get_image_embeddings(model_inputs)),\n      };\n    }\n\n    if (!model_inputs.input_labels && model_inputs.input_points) {\n      // Set default input labels if they are missing\n      const shape = (model_inputs.input_points as any).dims.slice(0, -1);\n      const numElements = shape.reduce((a: number, b: number) => a * b, 1);\n      model_inputs.input_labels = new Tensor('int64', new BigInt64Array(numElements).fill(1n), shape);\n    }\n\n    const decoder_inputs = {\n      image_embeddings: model_inputs.image_embeddings,\n      image_positional_embeddings: model_inputs.image_positional_embeddings,\n      input_points: null,\n      input_labels: null,\n      input_boxes: null,\n    };\n    if (model_inputs.input_points) {\n      decoder_inputs.input_points = model_inputs.input_points;\n    }\n    if (model_inputs.input_labels) {\n      decoder_inputs.input_labels = model_inputs.input_labels;\n    }\n    if (model_inputs.input_boxes) {\n      decoder_inputs.input_boxes = model_inputs.input_boxes;\n    }\n\n    // Returns:\n    //  - iou_scores: tensor.float32[batch_size,point_batch_size,3]\n    //  - pred_masks: tensor.float32[batch_size,point_batch_size,3,256,256]\n    return await sessionRun(this.sessions['prompt_encoder_mask_decoder'], decoder_inputs);\n  }\n\n  /**\n   * Runs the model with the provided inputs\n   * @param {Object} model_inputs Model inputs\n   * @returns {Promise<SamImageSegmentationOutput>} Object containing segmentation outputs\n   */\n  async _call(model_inputs: any) {\n    return new SamImageSegmentationOutput(await super._call(model_inputs));\n  }\n}\n\n/**\n * Base class for Segment-Anything model's output.\n */\nexport class SamImageSegmentationOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.iou_scores The output logits of the model.\n   * @param {Tensor} output.pred_masks Predicted boxes.\n   */\n  iou_scores: Tensor;\n  pred_masks: Tensor;\n  constructor({ iou_scores, pred_masks }: { iou_scores: Tensor; pred_masks: Tensor }) {\n    super();\n    this.iou_scores = iou_scores;\n    this.pred_masks = pred_masks;\n  }\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Wav2Vec2 models\nexport class Wav2Vec2PreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare Wav2Vec2 Model transformer outputting raw hidden-states without any specific head on top.\n *\n * **Example:** Load and run a `Wav2Vec2Model` for feature extraction.\n *\n * ```javascript\n * import { AutoProcessor, AutoModel, read_audio } from '@huggingface/transformers';\n *\n * // Read and preprocess audio\n * const processor = await AutoProcessor.from_pretrained('Xenova/mms-300m');\n * const audio = await read_audio('https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac', 16000);\n * const inputs = await processor(audio);\n *\n * // Run model with inputs\n * const model = await AutoModel.from_pretrained('Xenova/mms-300m');\n * const output = await model(inputs);\n * // {\n * //   last_hidden_state: Tensor {\n * //     dims: [ 1, 1144, 1024 ],\n * //     type: 'float32',\n * //     data: Float32Array(1171456) [ ... ],\n * //     size: 1171456\n * //   }\n * // }\n * ```\n */\nexport class Wav2Vec2Model extends Wav2Vec2PreTrainedModel { }\n\nexport class Wav2Vec2ForCTC extends Wav2Vec2PreTrainedModel {\n  /**\n   * @param {Object} model_inputs\n   * @param {Tensor} model_inputs.input_values Float values of input raw speech waveform.\n   * @param {Tensor} model_inputs.attention_mask Mask to avoid performing convolution and attention on padding token indices. Mask values selected in [0, 1]\n   */\n  async _call(model_inputs: any) {\n    return new CausalLMOutput(await super._call(model_inputs) as { logits: Tensor });\n  }\n}\n\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// PyAnnote models\nexport class PyAnnotePreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare PyAnnote Model transformer outputting raw hidden-states without any specific head on top.\n */\nexport class PyAnnoteModel extends PyAnnotePreTrainedModel { }\n\n/**\n * PyAnnote Model with a frame classification head on top for tasks like Speaker Diarization.\n *\n * **Example:** Load and run a `PyAnnoteForAudioFrameClassification` for speaker diarization.\n *\n * ```javascript\n * import { AutoProcessor, AutoModelForAudioFrameClassification, read_audio } from '@huggingface/transformers';\n *\n * // Load model and processor\n * const model_id = 'onnx-community/pyannote-segmentation-3.0';\n * const model = await AutoModelForAudioFrameClassification.from_pretrained(model_id);\n * const processor = await AutoProcessor.from_pretrained(model_id);\n *\n * // Read and preprocess audio\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/mlk.wav';\n * const audio = await read_audio(url, processor.feature_extractor.config.sampling_rate);\n * const inputs = await processor(audio);\n *\n * // Run model with inputs\n * const { logits } = await model(inputs);\n * // {\n * //   logits: Tensor {\n * //     dims: [ 1, 767, 7 ],  // [batch_size, num_frames, num_classes]\n * //     type: 'float32',\n * //     data: Float32Array(5369) [ ... ],\n * //     size: 5369\n * //   }\n * // }\n *\n * const result = processor.post_process_speaker_diarization(logits, audio.length);\n * // [\n * //   [\n * //     { id: 0, start: 0, end: 1.0512535626298245, confidence: 0.8220156481664611 },\n * //     { id: 2, start: 1.0512535626298245, end: 2.3398869619825127, confidence: 0.9008811707860472 },\n * //     ...\n * //   ]\n * // ]\n *\n * // Display result\n * console.table(result[0], ['start', 'end', 'id', 'confidence']);\n * // ┌─────────┬────────────────────┬────────────────────┬────┬─────────────────────┐\n * // │ (index) │ start              │ end                │ id │ confidence          │\n * // ├─────────┼────────────────────┼────────────────────┼────┼─────────────────────┤\n * // │ 0       │ 0                  │ 1.0512535626298245 │ 0  │ 0.8220156481664611  │\n * // │ 1       │ 1.0512535626298245 │ 2.3398869619825127 │ 2  │ 0.9008811707860472  │\n * // │ 2       │ 2.3398869619825127 │ 3.5946089560890773 │ 0  │ 0.7521651315796233  │\n * // │ 3       │ 3.5946089560890773 │ 4.578039708226655  │ 2  │ 0.8491978128022479  │\n * // │ 4       │ 4.578039708226655  │ 4.594995410849717  │ 0  │ 0.2935352600416393  │\n * // │ 5       │ 4.594995410849717  │ 6.121008646925269  │ 3  │ 0.6788051309866024  │\n * // │ 6       │ 6.121008646925269  │ 6.256654267909762  │ 0  │ 0.37125512393851134 │\n * // │ 7       │ 6.256654267909762  │ 8.630452635138397  │ 2  │ 0.7467035186353542  │\n * // │ 8       │ 8.630452635138397  │ 10.088643060721703 │ 0  │ 0.7689364814666032  │\n * // │ 9       │ 10.088643060721703 │ 12.58113134631177  │ 2  │ 0.9123324509131324  │\n * // │ 10      │ 12.58113134631177  │ 13.005023911888312 │ 0  │ 0.4828358177572041  │\n * // └─────────┴────────────────────┴────────────────────┴────┴─────────────────────┘\n * ```\n */\nexport class PyAnnoteForAudioFrameClassification extends PyAnnotePreTrainedModel {\n  /**\n   * Calls the model on new inputs.\n   * @param {Object} model_inputs The inputs to the model.\n   * @returns {Promise<TokenClassifierOutput>} An object containing the model's output logits for sequence classification.\n   */\n  async _call(model_inputs: any) {\n    return new TokenClassifierOutput(await super._call(model_inputs) as { logits: Tensor });\n  }\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// WeSpeakerResNet models\nexport class WeSpeakerResNetPreTrainedModel extends PreTrainedModel { }\nexport class WeSpeakerResNetModel extends WeSpeakerResNetPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// UniSpeech models\nexport class UniSpeechPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare UniSpeech Model transformer outputting raw hidden-states without any specific head on top.\n */\nexport class UniSpeechModel extends UniSpeechPreTrainedModel { }\n\n/**\n * UniSpeech Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).\n */\nexport class UniSpeechForCTC extends UniSpeechPreTrainedModel {\n  /**\n   * @param {Object} model_inputs\n   * @param {Tensor} model_inputs.input_values Float values of input raw speech waveform.\n   * @param {Tensor} model_inputs.attention_mask Mask to avoid performing convolution and attention on padding token indices. Mask values selected in [0, 1]\n   */\n  async _call(model_inputs: any) {\n    return new CausalLMOutput(await super._call(model_inputs) as { logits: Tensor });\n  }\n}\n\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// UniSpeechSat models\nexport class UniSpeechSatPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare UniSpeechSat Model transformer outputting raw hidden-states without any specific head on top.\n */\nexport class UniSpeechSatModel extends UniSpeechSatPreTrainedModel { }\n\n/**\n * UniSpeechSat Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).\n */\nexport class UniSpeechSatForCTC extends UniSpeechSatPreTrainedModel {\n  /**\n   * @param {Object} model_inputs\n   * @param {Tensor} model_inputs.input_values Float values of input raw speech waveform.\n   * @param {Tensor} model_inputs.attention_mask Mask to avoid performing convolution and attention on padding token indices. Mask values selected in [0, 1]\n   */\n  async _call(model_inputs: any) {\n    return new CausalLMOutput(await super._call(model_inputs) as { logits: Tensor });\n  }\n}\n\n/**\n * UniSpeechSat Model with a frame classification head on top for tasks like Speaker Diarization.\n */\nexport class UniSpeechSatForAudioFrameClassification extends UniSpeechSatPreTrainedModel {\n  /**\n   * Calls the model on new inputs.\n   * @param {Object} model_inputs The inputs to the model.\n   * @returns {Promise<TokenClassifierOutput>} An object containing the model's output logits for sequence classification.\n   */\n  async _call(model_inputs: any) {\n    return new TokenClassifierOutput(await super._call(model_inputs) as { logits: Tensor });\n  }\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Wav2Vec2Bert models\nexport class Wav2Vec2BertPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare Wav2Vec2Bert Model transformer outputting raw hidden-states without any specific head on top.\n */\nexport class Wav2Vec2BertModel extends Wav2Vec2BertPreTrainedModel { }\n\n/**\n * Wav2Vec2Bert Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).\n */\nexport class Wav2Vec2BertForCTC extends Wav2Vec2BertPreTrainedModel {\n  /**\n   * @param {Object} model_inputs\n   * @param {Tensor} model_inputs.input_features Float values of input mel-spectrogram.\n   * @param {Tensor} model_inputs.attention_mask Mask to avoid performing convolution and attention on padding token indices. Mask values selected in [0, 1]\n   */\n  async _call(model_inputs: any) {\n    return new CausalLMOutput(await super._call(model_inputs) as { logits: Tensor });\n  }\n}\n\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Hubert models\nexport class HubertPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare Hubert Model transformer outputting raw hidden-states without any specific head on top.\n *\n * **Example:** Load and run a `HubertModel` for feature extraction.\n *\n * ```javascript\n * import { AutoProcessor, AutoModel, read_audio } from '@huggingface/transformers';\n *\n * // Read and preprocess audio\n * const processor = await AutoProcessor.from_pretrained('Xenova/hubert-base-ls960');\n * const audio = await read_audio('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/jfk.wav', 16000);\n * const inputs = await processor(audio);\n *\n * // Load and run model with inputs\n * const model = await AutoModel.from_pretrained('Xenova/hubert-base-ls960');\n * const output = await model(inputs);\n * // {\n * //   last_hidden_state: Tensor {\n * //     dims: [ 1, 549, 768 ],\n * //     type: 'float32',\n * //     data: Float32Array(421632) [0.0682469978928566, 0.08104046434164047, -0.4975186586380005, ...],\n * //     size: 421632\n * //   }\n * // }\n * ```\n */\nexport class HubertModel extends Wav2Vec2PreTrainedModel { }\n\n/**\n * Hubert Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).\n */\nexport class HubertForCTC extends Wav2Vec2PreTrainedModel {\n  /**\n   * @param {Object} model_inputs\n   * @param {Tensor} model_inputs.input_values Float values of input raw speech waveform.\n   * @param {Tensor} model_inputs.attention_mask Mask to avoid performing convolution and attention on padding token indices. Mask values selected in [0, 1]\n   */\n  async _call(model_inputs: any) {\n    return new CausalLMOutput(await super._call(model_inputs) as { logits: Tensor });\n  }\n}\n\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// WavLM models\n/**\n * An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained models.\n */\nexport class WavLMPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare WavLM Model transformer outputting raw hidden-states without any specific head on top.\n *\n * **Example:** Load and run a `WavLMModel` for feature extraction.\n *\n * ```javascript\n * import { AutoProcessor, AutoModel, read_audio } from '@huggingface/transformers';\n *\n * // Read and preprocess audio\n * const processor = await AutoProcessor.from_pretrained('Xenova/wavlm-base');\n * const audio = await read_audio('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/jfk.wav', 16000);\n * const inputs = await processor(audio);\n *\n * // Run model with inputs\n * const model = await AutoModel.from_pretrained('Xenova/wavlm-base');\n * const output = await model(inputs);\n * // {\n * //   last_hidden_state: Tensor {\n * //     dims: [ 1, 549, 768 ],\n * //     type: 'float32',\n * //     data: Float32Array(421632) [-0.349443256855011, -0.39341306686401367,  0.022836603224277496, ...],\n * //     size: 421632\n * //   }\n * // }\n * ```\n */\nexport class WavLMModel extends WavLMPreTrainedModel { }\n\n/**\n * WavLM Model with a `language modeling` head on top for Connectionist Temporal Classification (CTC).\n */\nexport class WavLMForCTC extends WavLMPreTrainedModel {\n  /**\n   * @param {Object} model_inputs\n   * @param {Tensor} model_inputs.input_values Float values of input raw speech waveform.\n   * @param {Tensor} model_inputs.attention_mask Mask to avoid performing convolution and attention on padding token indices. Mask values selected in [0, 1]\n   */\n  async _call(model_inputs: any) {\n    return new CausalLMOutput(await super._call(model_inputs) as { logits: Tensor });\n  }\n}\n\n/**\n * WavLM Model with an XVector feature extraction head on top for tasks like Speaker Verification.\n *\n * **Example:** Extract speaker embeddings with `WavLMForXVector`.\n * ```javascript\n * import { AutoProcessor, AutoModel, read_audio } from '@huggingface/transformers';\n *\n * // Read and preprocess audio\n * const processor = await AutoProcessor.from_pretrained('Xenova/wavlm-base-plus-sv');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/jfk.wav';\n * const audio = await read_audio(url, 16000);\n * const inputs = await processor(audio);\n *\n * // Run model with inputs\n * const model = await AutoModel.from_pretrained('Xenova/wavlm-base-plus-sv');\n * const outputs = await model(inputs);\n * // {\n * //   logits: Tensor {\n * //     dims: [ 1, 512 ],\n * //     type: 'float32',\n * //     data: Float32Array(512) [0.5847219228744507, ...],\n * //     size: 512\n * //   },\n * //   embeddings: Tensor {\n * //     dims: [ 1, 512 ],\n * //     type: 'float32',\n * //     data: Float32Array(512) [-0.09079201519489288, ...],\n * //     size: 512\n * //   }\n * // }\n * ```\n */\nexport class WavLMForXVector extends WavLMPreTrainedModel {\n  /**\n   * Calls the model on new inputs.\n   * @param {Object} model_inputs The inputs to the model.\n   * @returns {Promise<XVectorOutput>} An object containing the model's output logits and speaker embeddings.\n   */\n  async _call(model_inputs: any) {\n    return new XVectorOutput(await super._call(model_inputs) as { logits: Tensor, embeddings: Tensor });\n  }\n}\n\n/**\n * WavLM Model with a frame classification head on top for tasks like Speaker Diarization.\n *\n * **Example:** Perform speaker diarization with `WavLMForAudioFrameClassification`.\n * ```javascript\n * import { AutoProcessor, AutoModelForAudioFrameClassification, read_audio } from '@huggingface/transformers';\n *\n * // Read and preprocess audio\n * const processor = await AutoProcessor.from_pretrained('Xenova/wavlm-base-plus-sd');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/jfk.wav';\n * const audio = await read_audio(url, 16000);\n * const inputs = await processor(audio);\n *\n * // Run model with inputs\n * const model = await AutoModelForAudioFrameClassification.from_pretrained('Xenova/wavlm-base-plus-sd');\n * const { logits } = await model(inputs);\n * // {\n * //   logits: Tensor {\n * //     dims: [ 1, 549, 2 ],  // [batch_size, num_frames, num_speakers]\n * //     type: 'float32',\n * //     data: Float32Array(1098) [-3.5301010608673096, ...],\n * //     size: 1098\n * //   }\n * // }\n *\n * const labels = logits[0].sigmoid().tolist().map(\n *     frames => frames.map(speaker => speaker > 0.5 ? 1 : 0)\n * );\n * console.log(labels); // labels is a one-hot array of shape (num_frames, num_speakers)\n * // [\n * //     [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],\n * //     [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],\n * //     [0, 0], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1],\n * //     ...\n * // ]\n * ```\n */\nexport class WavLMForAudioFrameClassification extends WavLMPreTrainedModel {\n  /**\n   * Calls the model on new inputs.\n   * @param {Object} model_inputs The inputs to the model.\n   * @returns {Promise<TokenClassifierOutput>} An object containing the model's output logits for sequence classification.\n   */\n  async _call(model_inputs: any) {\n    return new TokenClassifierOutput(await super._call(model_inputs) as { logits: Tensor });\n  }\n}\n\n//////////////////////////////////////////////////\n// SpeechT5 models\n/**\n * An abstract class to handle weights initialization and a simple interface for downloading and loading pretrained models.\n */\nexport class SpeechT5PreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare SpeechT5 Encoder-Decoder Model outputting raw hidden-states without any specific pre- or post-nets.\n */\nexport class SpeechT5Model extends SpeechT5PreTrainedModel { }\n\n/**\n * SpeechT5 Model with a speech encoder and a text decoder.\n *\n * **Example:** Generate speech from text with `SpeechT5ForSpeechToText`.\n * ```javascript\n * import { AutoTokenizer, AutoProcessor, SpeechT5ForTextToSpeech, SpeechT5HifiGan, Tensor } from '@huggingface/transformers';\n *\n * // Load the tokenizer and processor\n * const tokenizer = await AutoTokenizer.from_pretrained('Xenova/speecht5_tts');\n * const processor = await AutoProcessor.from_pretrained('Xenova/speecht5_tts');\n *\n * // Load the models\n * // NOTE: We use the full-precision versions as they are more accurate\n * const model = await SpeechT5ForTextToSpeech.from_pretrained('Xenova/speecht5_tts', { dtype: 'fp32' });\n * const vocoder = await SpeechT5HifiGan.from_pretrained('Xenova/speecht5_hifigan', { dtype: 'fp32' });\n *\n * // Load speaker embeddings from URL\n * const speaker_embeddings_data = new Float32Array(\n *     await (await fetch('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/speaker_embeddings.bin')).arrayBuffer()\n * );\n * const speaker_embeddings = new Tensor(\n *     'float32',\n *     speaker_embeddings_data,\n *     [1, speaker_embeddings_data.length]\n * )\n *\n * // Run tokenization\n * const { input_ids } = tokenizer('Hello, my dog is cute');\n *\n * // Generate waveform\n * const { waveform } = await model.generate_speech(input_ids, speaker_embeddings, { vocoder });\n * console.log(waveform)\n * // Tensor {\n * //   dims: [ 26112 ],\n * //   type: 'float32',\n * //   size: 26112,\n * //   data: Float32Array(26112) [ -0.00043630177970044315, -0.00018082228780258447, ... ],\n * // }\n * ```\n */\nexport class SpeechT5ForSpeechToText extends SpeechT5PreTrainedModel { }\n\n/**\n * SpeechT5 Model with a text encoder and a speech decoder.\n */\nexport class SpeechT5ForTextToSpeech extends SpeechT5PreTrainedModel {\n  /**\n   * @typedef {Object} SpeechOutput\n   * @property {Tensor} [spectrogram] The predicted log-mel spectrogram of shape\n   * `(output_sequence_length, config.num_mel_bins)`. Returned when no `vocoder` is provided\n   * @property {Tensor} [waveform] The predicted waveform of shape `(num_frames,)`. Returned when a `vocoder` is provided.\n   * @property {Tensor} [cross_attentions] The outputs of the decoder's cross-attention layers of shape\n   * `(config.decoder_layers, config.decoder_attention_heads, output_sequence_length, input_sequence_length)`. returned when `output_cross_attentions` is `true`.\n   */\n\n  /**\n   * Converts a sequence of input tokens into a sequence of mel spectrograms, which are subsequently turned into a speech waveform using a vocoder.\n   * @param {Tensor} input_values Indices of input sequence tokens in the vocabulary.\n   * @param {Tensor} speaker_embeddings Tensor containing the speaker embeddings.\n   * @param {Object} options Optional parameters for generating speech.\n   * @param {number} [options.threshold=0.5] The generated sequence ends when the predicted stop token probability exceeds this value.\n   * @param {number} [options.minlenratio=0.0] Used to calculate the minimum required length for the output sequence.\n   * @param {number} [options.maxlenratio=20.0] Used to calculate the maximum allowed length for the output sequence.\n   * @param {Object} [options.vocoder=null] The vocoder that converts the mel spectrogram into a speech waveform. If `null`, the output is the mel spectrogram.\n   * @param {boolean} [options.output_cross_attentions=false] Whether or not to return the attentions tensors of the decoder's cross-attention layers.\n   * @returns {Promise<SpeechOutput>} A promise which resolves to an object containing the spectrogram, waveform, and cross-attention tensors.\n   */\n  async generate_speech(\n    input_values: Tensor,\n    speaker_embeddings: Tensor,\n    {\n      threshold = 0.5,\n      minlenratio = 0.0,\n      maxlenratio = 20.0,\n      vocoder = null,\n      // output_cross_attentions = false, // TODO add\n    } = {},\n  ) {\n    const model_inputs = {\n      input_ids: input_values,\n    };\n\n    const { encoder_outputs, encoder_attention_mask } = await encoderForward(this, model_inputs);\n\n    // @ts-expect-error TS2339\n    const r = encoder_outputs.dims[1] / this.config.reduction_factor;\n    const maxlen = Math.floor(r * maxlenratio);\n    const minlen = Math.floor(r * minlenratio);\n\n    // @ts-expect-error TS2339\n    const num_mel_bins = this.config.num_mel_bins;\n\n    let spectrogramParts = [];\n    let past_key_values = null;\n    let decoder_outputs = null;\n    let idx = 0;\n\n    while (true) {\n      ++idx;\n\n      const use_cache_branch = boolTensor(!!decoder_outputs);\n      let output_sequence;\n      if (decoder_outputs) {\n        output_sequence = decoder_outputs.output_sequence_out;\n      } else {\n        output_sequence = new Tensor('float32', new Float32Array(num_mel_bins), [1, 1, num_mel_bins]);\n      }\n      let decoderFeeds = {\n        use_cache_branch,\n        output_sequence,\n        encoder_attention_mask: encoder_attention_mask,\n        speaker_embeddings: speaker_embeddings,\n        encoder_hidden_states: encoder_outputs,\n      };\n\n      this.addPastKeyValues(decoderFeeds, past_key_values);\n      decoder_outputs = await sessionRun(this.sessions['decoder_model_merged'], decoderFeeds);\n      past_key_values = this.getPastKeyValues(decoder_outputs, past_key_values);\n\n      const { prob, spectrum } = decoder_outputs;\n      spectrogramParts.push(spectrum);\n\n      if (\n        idx >= minlen &&\n        // Finished when stop token or maximum length is reached.\n        (Array.from(prob.data as Float32Array).filter((p) => p >= threshold).length > 0 || idx >= maxlen)\n      ) {\n        break;\n      }\n    }\n\n    const spectrogram = cat(spectrogramParts);\n    const { waveform } = await sessionRun((vocoder as any).sessions['model'], { spectrogram: spectrogram as any });\n\n    return {\n      spectrogram,\n      waveform,\n      // cross_attentions: null, // TODO add\n    };\n  }\n}\n\n/**\n * HiFi-GAN vocoder.\n *\n * See [SpeechT5ForSpeechToText](./models#module_models.SpeechT5ForSpeechToText) for example usage.\n */\nexport class SpeechT5HifiGan extends PreTrainedModel {\n  main_input_name = 'spectrogram';\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// TrOCR models\nexport class TrOCRPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The TrOCR Decoder with a language modeling head.\n */\nexport class TrOCRForCausalLM extends TrOCRPreTrainedModel { }\n\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Mistral models\n/**\n * The bare Mistral Model outputting raw hidden-states without any specific head on top.\n */\nexport class MistralPreTrainedModel extends PreTrainedModel { }\n\nexport class MistralModel extends MistralPreTrainedModel { }\n\nexport class MistralForCausalLM extends MistralPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Starcoder2 models\n/**\n * The bare Starcoder2 Model outputting raw hidden-states without any specific head on top.\n */\nexport class Starcoder2PreTrainedModel extends PreTrainedModel { }\n\nexport class Starcoder2Model extends Starcoder2PreTrainedModel { }\n\nexport class Starcoder2ForCausalLM extends Starcoder2PreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Falcon models\n/**\n * The bare Falcon Model outputting raw hidden-states without any specific head on top.\n */\nexport class FalconPreTrainedModel extends PreTrainedModel { }\n\nexport class FalconModel extends FalconPreTrainedModel { }\n\nexport class FalconForCausalLM extends FalconPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// CLAP models\nexport class ClapPreTrainedModel extends PreTrainedModel { }\n\nexport class ClapModel extends ClapPreTrainedModel { }\n\n/**\n * CLAP Text Model with a projection layer on top (a linear layer on top of the pooled output).\n *\n * **Example:** Compute text embeddings with `ClapTextModelWithProjection`.\n *\n * ```javascript\n * import { AutoTokenizer, ClapTextModelWithProjection } from '@huggingface/transformers';\n *\n * // Load tokenizer and text model\n * const tokenizer = await AutoTokenizer.from_pretrained('Xenova/clap-htsat-unfused');\n * const text_model = await ClapTextModelWithProjection.from_pretrained('Xenova/clap-htsat-unfused');\n *\n * // Run tokenization\n * const texts = ['a sound of a cat', 'a sound of a dog'];\n * const text_inputs = tokenizer(texts, { padding: true, truncation: true });\n *\n * // Compute embeddings\n * const { text_embeds } = await text_model(text_inputs);\n * // Tensor {\n * //   dims: [ 2, 512 ],\n * //   type: 'float32',\n * //   data: Float32Array(1024) [ ... ],\n * //   size: 1024\n * // }\n * ```\n */\nexport class ClapTextModelWithProjection extends ClapPreTrainedModel {\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any = {}) {\n    return super.from_pretrained(pretrained_model_name_or_path, {\n      ...options,\n      // Update default model file name if not provided\n      model_file_name: options.model_file_name ?? 'text_model',\n    });\n  }\n}\n\n/**\n * CLAP Audio Model with a projection layer on top (a linear layer on top of the pooled output).\n *\n * **Example:** Compute audio embeddings with `ClapAudioModelWithProjection`.\n *\n * ```javascript\n * import { AutoProcessor, ClapAudioModelWithProjection, read_audio } from '@huggingface/transformers';\n *\n * // Load processor and audio model\n * const processor = await AutoProcessor.from_pretrained('Xenova/clap-htsat-unfused');\n * const audio_model = await ClapAudioModelWithProjection.from_pretrained('Xenova/clap-htsat-unfused');\n *\n * // Read audio and run processor\n * const audio = await read_audio('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/cat_meow.wav');\n * const audio_inputs = await processor(audio);\n *\n * // Compute embeddings\n * const { audio_embeds } = await audio_model(audio_inputs);\n * // Tensor {\n * //   dims: [ 1, 512 ],\n * //   type: 'float32',\n * //   data: Float32Array(512) [ ... ],\n * //   size: 512\n * // }\n * ```\n */\nexport class ClapAudioModelWithProjection extends ClapPreTrainedModel {\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any = {}) {\n    return super.from_pretrained(pretrained_model_name_or_path, {\n      ...options,\n      // Update default model file name if not provided\n      model_file_name: options.model_file_name ?? 'audio_model',\n    });\n  }\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// VITS models\nexport class VitsPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The complete VITS model, for text-to-speech synthesis.\n *\n * **Example:** Generate speech from text with `VitsModel`.\n * ```javascript\n * import { AutoTokenizer, VitsModel } from '@huggingface/transformers';\n *\n * // Load the tokenizer and model\n * const tokenizer = await AutoTokenizer.from_pretrained('Xenova/mms-tts-eng');\n * const model = await VitsModel.from_pretrained('Xenova/mms-tts-eng');\n *\n * // Run tokenization\n * const inputs = tokenizer('I love transformers');\n *\n * // Generate waveform\n * const { waveform } = await model(inputs);\n * // Tensor {\n * //   dims: [ 1, 35328 ],\n * //   type: 'float32',\n * //   data: Float32Array(35328) [ ... ],\n * //   size: 35328,\n * // }\n * ```\n */\nexport class VitsModel extends VitsPreTrainedModel {\n  /**\n   * Calls the model on new inputs.\n   * @param {Object} model_inputs The inputs to the model.\n   * @returns {Promise<VitsModelOutput>} The outputs for the VITS model.\n   */\n  async _call(model_inputs: any) {\n    return new VitsModelOutput(await super._call(model_inputs) as VitsModelOutput);\n  }\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// StableLm models\nexport class StableLmPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare StableLm Model transformer outputting raw hidden-states without any specific head on top.\n */\nexport class StableLmModel extends StableLmPreTrainedModel { }\n\n/**\n * StableLm Model with a `language modeling` head on top for Causal Language Modeling (with past).\n */\nexport class StableLmForCausalLM extends StableLmPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Musicgen models\nexport class MusicgenPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare Musicgen decoder model outputting raw hidden-states without any specific head on top.\n */\nexport class MusicgenModel extends MusicgenPreTrainedModel { }\n\n/**\n * The MusicGen decoder model with a language modelling head on top.\n */\nexport class MusicgenForCausalLM extends MusicgenPreTrainedModel { }\n\n/**\n * The composite MusicGen model with a text encoder, audio encoder and Musicgen decoder,\n * for music generation tasks with one or both of text and audio prompts.\n *\n * **Example:** Generate music from text with `Xenova/musicgen-small`.\n * ```javascript\n * import { AutoTokenizer, MusicgenForConditionalGeneration } from '@huggingface/transformers';\n *\n * // Load tokenizer and model\n * const tokenizer = await AutoTokenizer.from_pretrained('Xenova/musicgen-small');\n * const model = await MusicgenForConditionalGeneration.from_pretrained(\n *   'Xenova/musicgen-small', { dtype: 'fp32' }\n * );\n *\n * // Prepare text input\n * const prompt = '80s pop track with bassy drums and synth';\n * const inputs = tokenizer(prompt);\n *\n * // Generate audio\n * const audio_values = await model.generate({\n *   ...inputs,\n *   max_new_tokens: 512,\n *   do_sample: true,\n *   guidance_scale: 3,\n * });\n *\n * // (Optional) Write the output to a WAV file\n * import wavefile from 'wavefile';\n * import fs from 'fs';\n *\n * const wav = new wavefile.WaveFile();\n * wav.fromScratch(1, model.config.audio_encoder.sampling_rate, '32f', audio_values.data);\n * fs.writeFileSync('musicgen_out.wav', wav.toBuffer());\n * ```\n */\nexport class MusicgenForConditionalGeneration extends PreTrainedModel {\n  // NOTE: not MusicgenPreTrainedModel\n  forward_params = [\n    'input_ids',\n    'attention_mask',\n    'encoder_outputs',\n    'decoder_input_ids',\n    'decoder_attention_mask',\n    'past_key_values',\n  ];\n\n  /**\n   * Apply the pattern mask to the final ids,\n   * then revert the pattern delay mask by filtering the pad token id in a single step.\n   * @param {Tensor} outputs The output tensor from the model.\n   * @returns {Tensor} The filtered output tensor.\n   */\n  _apply_and_filter_by_delay_pattern_mask(outputs: any) {\n    const [bs_x_codebooks, seqLength] = outputs.dims;\n    // @ts-expect-error TS2339\n    const num_codebooks = this.config.decoder.num_codebooks;\n    const upperBound = seqLength - num_codebooks;\n\n    let newDataSize = 0;\n    for (let i = 0; i < outputs.size; ++i) {\n      // @ts-expect-error TS2339\n      if (outputs.data[i] === this.config.decoder.pad_token_id) {\n        continue;\n      }\n\n      const row = i % seqLength;\n      const col = Math.floor(i / seqLength) % num_codebooks;\n\n      const diff = row - col;\n      if (diff > 0 && diff <= upperBound) {\n        outputs.data[newDataSize++] = outputs.data[i];\n      }\n    }\n\n    const batch_size = Math.floor(bs_x_codebooks / num_codebooks);\n    const inferred = newDataSize / (batch_size * num_codebooks);\n    // TODO: assert `inferred` is an integer\n    return new Tensor(outputs.type, outputs.data.slice(0, newDataSize), [batch_size, num_codebooks, inferred]);\n  }\n\n  prepare_inputs_for_generation(input_ids: any, model_inputs: any, generation_config: any) {\n    // apply the delay pattern mask\n    let clonedInputIds = structuredClone(input_ids);\n    for (let i = 0; i < clonedInputIds.length; ++i) {\n      for (let j = 0; j < clonedInputIds[i].length; ++j) {\n        // @ts-expect-error TS2339\n        if (i % this.config.decoder.num_codebooks >= j) {\n          // @ts-expect-error TS2339\n          clonedInputIds[i][j] = BigInt(this.config.decoder.pad_token_id);\n        }\n      }\n    }\n    // for classifier free guidance we need to replicate the decoder args across the batch dim\n    // (we'll split these before sampling)\n    if (generation_config.guidance_scale !== null && generation_config.guidance_scale > 1) {\n      // [batch, seqLength] -> [2 * batch, seqLength]\n      clonedInputIds = clonedInputIds.concat(clonedInputIds);\n    }\n\n    const prepped = super.prepare_inputs_for_generation(clonedInputIds, model_inputs, generation_config);\n    return prepped;\n  }\n\n  /**\n   * Generates sequences of token ids for models with a language modeling head.\n   * @param {import('./generation/parameters.js').GenerationFunctionParameters} options\n   * @returns {Promise<ModelOutput|Tensor>} The output of the model, which can contain the generated token ids, attentions, and scores.\n   */\n  async generate(options: any) {\n    const output_ids = await super.generate(options);\n\n    // apply the pattern mask to the final ids\n    // tensor: int64[1,batch_size,4,chunk_length]\n    const audio_codes = this._apply_and_filter_by_delay_pattern_mask(/** @type {Tensor} */ output_ids).unsqueeze_(0); // append the frame dimension back to the audio codes\n\n    const { audio_values } = await sessionRun(this.sessions['encodec_decode'], { audio_codes });\n\n    return audio_values;\n  }\n}\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// Decision Transformer models\nexport class DecisionTransformerPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The model builds upon the GPT2 architecture to perform autoregressive prediction of actions in an offline RL setting.\n * Refer to the paper for more details: https://arxiv.org/abs/2106.01345\n */\nexport class DecisionTransformerModel extends DecisionTransformerPreTrainedModel { }\n\n//////////////////////////////////////////////////\n\nexport class MultiModalityPreTrainedModel extends PreTrainedModel { }\nexport class MultiModalityCausalLM extends MultiModalityPreTrainedModel {\n  forward_params = [\n    // prepare_inputs_embeds\n    'input_ids',\n    'pixel_values',\n    'images_seq_mask',\n    'images_emb_mask',\n\n    // language_model\n    'attention_mask',\n    'position_ids',\n    'past_key_values',\n  ];\n\n  /**\n   * @param {ConstructorParameters<typeof MultiModalityPreTrainedModel>} args\n   */\n\n  _generation_mode: string;\n  sessions: any;\n  constructor(args: ConstructorParameters<typeof MultiModalityPreTrainedModel>[0]) {\n    super(args, {}, {});\n\n    // State-based approach to switch out which heads to use during generation\n    this._generation_mode = 'text';\n  }\n\n  async forward(model_inputs: any) {\n    const mode = this._generation_mode ?? 'text';\n\n    // TODO support re-using PKVs for input_ids.dims[1] !== 1\n    // if (model_inputs.past_key_values) {\n    //     //  && model_inputs.input_ids.dims[1] === 1\n    // }\n\n    let output_1;\n    if (mode === 'text' || !model_inputs.past_key_values) {\n      const session = this.sessions['prepare_inputs_embeds'];\n      const prep_inputs = pick(model_inputs, session.inputNames);\n      output_1 = await sessionRun(session, prep_inputs);\n    } else {\n      const session = this.sessions['gen_img_embeds'];\n      const prep_inputs = pick(\n        {\n          image_ids: model_inputs.input_ids,\n        },\n        session.inputNames,\n      );\n      output_1 = await sessionRun(session, prep_inputs);\n    }\n\n    const input_2 = { ...model_inputs, ...output_1 };\n    const output_2 = await decoderForward(this, input_2);\n\n    const head = this.sessions[mode === 'text' ? 'lm_head' : 'gen_head'];\n    if (!head) {\n      throw new Error(`Unable to find \"${head}\" generation head`);\n    }\n\n    const output_3 = await sessionRun(head, pick(output_2, head.inputNames));\n\n    return {\n      ...output_1,\n      ...output_2,\n      ...output_3,\n    };\n  }\n\n  /**\n   * @param {import('./generation/parameters.js').GenerationFunctionParameters} options\n   */\n  async generate(options: any) {\n    this._generation_mode = 'text';\n    return super.generate(options);\n  }\n\n  /**\n   * @param {import('./generation/parameters.js').GenerationFunctionParameters} options\n   */\n  async generate_images(options: any) {\n    this._generation_mode = 'image';\n\n    const start_num_tokens = (options.inputs ?? options[this.main_input_name]).dims[1];\n    const all_tokens = await super.generate(options);\n\n    const generated_tokens = /** @type {Tensor} */ ((all_tokens as Tensor).slice(null, [start_num_tokens, null]));\n\n    const image_decode = this.sessions['image_decode'];\n    const { decoded_image } = await sessionRun(image_decode, {\n      generated_tokens,\n    });\n\n    // Equivalent to `np.clip((dec + 1) / 2 * 255, 0, 255)`\n    const clamped = decoded_image\n      .add_(1)\n      .mul_(255 / 2)\n      .clamp_(0, 255)\n      .to('uint8');\n\n    // Return as a list of images\n    const images = [];\n    for (const tensor of clamped) {\n      const img = RawImage.fromTensor(tensor);\n      images.push(img);\n    }\n    return images;\n  }\n}\n\nexport class MgpstrModelOutput extends ModelOutput {\n  char_logits: Tensor;\n  bpe_logits: Tensor;\n  wp_logits: Tensor;\n  constructor({ char_logits, bpe_logits, wp_logits }: any) {\n    super();\n    this.char_logits = char_logits;\n    this.bpe_logits = bpe_logits;\n    this.wp_logits = wp_logits;\n  }\n\n  get logits() {\n    return [this.char_logits, this.bpe_logits, this.wp_logits];\n  }\n}\n\nexport class MgpstrPreTrainedModel extends PreTrainedModel { }\n\n/**\n * MGP-STR Model transformer with three classification heads on top\n * (three A^3 modules and three linear layer on top of the transformer encoder output) for scene text recognition (STR).\n */\nexport class MgpstrForSceneTextRecognition extends MgpstrPreTrainedModel {\n  /**\n   * @param {any} model_inputs\n   */\n  async _call(model_inputs: any) {\n    return new MgpstrModelOutput(await super._call(model_inputs) as { char_logits: Tensor, bpe_logits: Tensor, wp_logits: Tensor });\n  }\n}\n\n//////////////////////////////////////////////////\n// PatchTST Transformer models\nexport class PatchTSTPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare PatchTST Model outputting raw hidden-states without any specific head.\n */\nexport class PatchTSTModel extends PatchTSTPreTrainedModel { }\n\n/**\n * The PatchTST for prediction model.\n */\nexport class PatchTSTForPrediction extends PatchTSTPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// StyleTextToSpeech2 Transformer models\nexport class StyleTextToSpeech2PreTrainedModel extends PreTrainedModel { }\nexport class StyleTextToSpeech2Model extends StyleTextToSpeech2PreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// PatchTSMixer Transformer models\nexport class PatchTSMixerPreTrainedModel extends PreTrainedModel { }\n\n/**\n * The bare PatchTSMixer Model outputting raw hidden-states without any specific head.\n */\nexport class PatchTSMixerModel extends PatchTSMixerPreTrainedModel { }\n\n/**\n * The PatchTSMixer for prediction model.\n */\nexport class PatchTSMixerForPrediction extends PatchTSMixerPreTrainedModel { }\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\n// AutoModels, used to simplify construction of PreTrainedModels\n// (uses config to instantiate correct class)\n\n/**\n * Base class of all AutoModels. Contains the `from_pretrained` function\n * which is used to instantiate pretrained models.\n */\ninterface ModelOptions {\n  config?: PretrainedConfig | null;\n  cache_dir?: string | null;\n  local_files_only?: boolean;\n  revision?: string;\n  model_file_name?: string | null;\n  subfolder?: string;\n  device?: string | null;\n  dtype?: string | null;\n  use_external_data_format?: boolean | null;\n  session_options?: any;\n  progress_callback?: ProgressCallback | null;\n}\nexport class PretrainedMixin {\n  /**\n   * Mapping from model type to model class.\n   * @type {Map<string, any>[] | null}\n   */\n  static MODEL_CLASS_MAPPINGS: Map<string, any>[] | null = null;\n\n  /**\n   * Whether to attempt to instantiate the base class (`PretrainedModel`) if\n   * the model type is not found in the mapping.\n   */\n  static BASE_IF_FAIL = false;\n\n  /** @type {typeof PreTrainedModel.from_pretrained} */\n  static async from_pretrained(\n    pretrained_model_name_or_path: string,\n    {\n      progress_callback = null,\n      config = null,\n      cache_dir = null,\n      local_files_only = false,\n      revision = 'main',\n      model_file_name = null,\n      subfolder = 'onnx',\n      device = null,\n      dtype = null,\n      use_external_data_format = null,\n      session_options = {},\n    } = {},\n  ) {\n    const options: ModelOptions = {\n      progress_callback,\n      config,\n      cache_dir,\n      local_files_only,\n      revision,\n      model_file_name,\n      subfolder,\n      device,\n      dtype,\n      use_external_data_format,\n      session_options,\n    };\n    options.config = await AutoConfig.from_pretrained(pretrained_model_name_or_path, options);\n\n    if (!this.MODEL_CLASS_MAPPINGS) {\n      throw new Error('`MODEL_CLASS_MAPPINGS` not implemented for this type of `AutoClass`: ' + this.name);\n    }\n\n    for (const MODEL_CLASS_MAPPING of this.MODEL_CLASS_MAPPINGS) {\n      const modelInfo = MODEL_CLASS_MAPPING.get((options.config as any)?.model_type);\n      if (!modelInfo) {\n        continue; // Item not found in this mapping\n      }\n      return await modelInfo[1].from_pretrained(pretrained_model_name_or_path, options);\n    }\n\n    if (this.BASE_IF_FAIL) {\n      console.warn(`Unknown model class \"${(options.config as any)?.model_type}\", attempting to construct from base class.`);\n      return await PreTrainedModel.from_pretrained(pretrained_model_name_or_path, options);\n    } else {\n      throw Error(`Unsupported model type: ${(options.config as any)?.model_type}`);\n    }\n  }\n}\n\nconst MODEL_MAPPING_NAMES_ENCODER_ONLY = new Map([\n  ['clap', ['ClapModel', ClapModel]],\n  ['clip', ['CLIPModel', CLIPModel]],\n  ['chinese_clip', ['ChineseCLIPModel', ChineseCLIPModel]],\n  ['siglip', ['SiglipModel', SiglipModel]],\n  ['jina_clip', ['JinaCLIPModel', JinaCLIPModel]],\n  ['wav2vec2', ['Wav2Vec2Model', Wav2Vec2Model]],\n  ['wav2vec2-bert', ['Wav2Vec2BertModel', Wav2Vec2BertModel]],\n  ['unispeech', ['UniSpeechModel', UniSpeechModel]],\n  ['unispeech-sat', ['UniSpeechSatModel', UniSpeechSatModel]],\n  ['hubert', ['HubertModel', HubertModel]],\n  ['wavlm', ['WavLMModel', WavLMModel]],\n  ['audio-spectrogram-transformer', ['ASTModel', ASTModel]],\n  ['vits', ['VitsModel', VitsModel]],\n  ['pyannote', ['PyAnnoteModel', PyAnnoteModel]],\n  ['wespeaker-resnet', ['WeSpeakerResNetModel', WeSpeakerResNetModel]],\n\n  ['vit_mae', ['ViTMAEModel', ViTMAEModel]],\n  ['groupvit', ['GroupViTModel', GroupViTModel]],\n  ['swin2sr', ['Swin2SRModel', Swin2SRModel]],\n\n  ['hifigan', ['SpeechT5HifiGan', SpeechT5HifiGan]],\n\n  ['decision_transformer', ['DecisionTransformerModel', DecisionTransformerModel]],\n  ['patchtst', ['PatchTSTForPrediction', PatchTSTModel]],\n  ['patchtsmixer', ['PatchTSMixerForPrediction', PatchTSMixerModel]],\n\n  ['mgp-str', ['MgpstrForSceneTextRecognition', MgpstrForSceneTextRecognition]],\n  ['style_text_to_speech_2', ['StyleTextToSpeech2Model', StyleTextToSpeech2Model]],\n]);\n\nconst MODEL_MAPPING_NAMES_DECODER_ONLY = new Map([\n  ['bloom', ['BloomModel', BloomModel]],\n  ['jais', ['JAISModel', JAISModel]],\n  ['gpt2', ['GPT2Model', GPT2Model]],\n  ['gptj', ['GPTJModel', GPTJModel]],\n  ['gpt_bigcode', ['GPTBigCodeModel', GPTBigCodeModel]],\n  ['gpt_neo', ['GPTNeoModel', GPTNeoModel]],\n  ['gpt_neox', ['GPTNeoXModel', GPTNeoXModel]],\n  ['codegen', ['CodeGenModel', CodeGenModel]],\n  ['llama', ['LlamaModel', LlamaModel]],\n  ['exaone', ['ExaoneModel', ExaoneModel]],\n  ['olmo', ['OlmoModel', OlmoModel]],\n  ['olmo2', ['Olmo2Model', Olmo2Model]],\n  ['mobilellm', ['MobileLLMModel', MobileLLMModel]],\n  ['granite', ['GraniteModel', GraniteModel]],\n  ['cohere', ['CohereModel', CohereModel]],\n  ['gemma', ['GemmaModel', GemmaModel]],\n  ['gemma2', ['Gemma2Model', Gemma2Model]],\n  ['openelm', ['OpenELMModel', OpenELMModel]],\n  ['qwen2', ['Qwen2Model', Qwen2Model]],\n  ['phi', ['PhiModel', PhiModel]],\n  ['phi3', ['Phi3Model', Phi3Model]],\n  ['mpt', ['MptModel', MptModel]],\n  ['opt', ['OPTModel', OPTModel]],\n  ['mistral', ['MistralModel', MistralModel]],\n  ['starcoder2', ['Starcoder2Model', Starcoder2Model]],\n  ['falcon', ['FalconModel', FalconModel]],\n  ['stablelm', ['StableLmModel', StableLmModel]],\n]);\n\nconst MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES = new Map([\n  ['speecht5', ['SpeechT5ForSpeechToText', SpeechT5ForSpeechToText]],\n  ['whisper', ['WhisperForConditionalGeneration', WhisperForConditionalGeneration]],\n  ['moonshine', ['MoonshineForConditionalGeneration', MoonshineForConditionalGeneration]],\n]);\n\nconst MODEL_FOR_TEXT_TO_SPECTROGRAM_MAPPING_NAMES = new Map([\n  ['speecht5', ['SpeechT5ForTextToSpeech', SpeechT5ForTextToSpeech]],\n]);\n\nconst MODEL_FOR_TEXT_TO_WAVEFORM_MAPPING_NAMES = new Map([\n  ['vits', ['VitsModel', VitsModel]],\n  ['musicgen', ['MusicgenForConditionalGeneration', MusicgenForConditionalGeneration]],\n]);\n\nconst MODEL_FOR_CAUSAL_LM_MAPPING_NAMES = new Map([\n  ['bloom', ['BloomForCausalLM', BloomForCausalLM]],\n  ['gpt2', ['GPT2LMHeadModel', GPT2LMHeadModel]],\n  ['jais', ['JAISLMHeadModel', JAISLMHeadModel]],\n  ['gptj', ['GPTJForCausalLM', GPTJForCausalLM]],\n  ['gpt_bigcode', ['GPTBigCodeForCausalLM', GPTBigCodeForCausalLM]],\n  ['gpt_neo', ['GPTNeoForCausalLM', GPTNeoForCausalLM]],\n  ['gpt_neox', ['GPTNeoXForCausalLM', GPTNeoXForCausalLM]],\n  ['codegen', ['CodeGenForCausalLM', CodeGenForCausalLM]],\n  ['llama', ['LlamaForCausalLM', LlamaForCausalLM]],\n  ['exaone', ['ExaoneForCausalLM', ExaoneForCausalLM]],\n  ['olmo', ['OlmoForCausalLM', OlmoForCausalLM]],\n  ['olmo2', ['Olmo2ForCausalLM', Olmo2ForCausalLM]],\n  ['mobilellm', ['MobileLLMForCausalLM', MobileLLMForCausalLM]],\n  ['granite', ['GraniteForCausalLM', GraniteForCausalLM]],\n  ['cohere', ['CohereForCausalLM', CohereForCausalLM]],\n  ['gemma', ['GemmaForCausalLM', GemmaForCausalLM]],\n  ['gemma2', ['Gemma2ForCausalLM', Gemma2ForCausalLM]],\n  ['openelm', ['OpenELMForCausalLM', OpenELMForCausalLM]],\n  ['qwen2', ['Qwen2ForCausalLM', Qwen2ForCausalLM]],\n  ['phi', ['PhiForCausalLM', PhiForCausalLM]],\n  ['phi3', ['Phi3ForCausalLM', Phi3ForCausalLM]],\n  ['mpt', ['MptForCausalLM', MptForCausalLM]],\n  ['opt', ['OPTForCausalLM', OPTForCausalLM]],\n  ['mistral', ['MistralForCausalLM', MistralForCausalLM]],\n  ['starcoder2', ['Starcoder2ForCausalLM', Starcoder2ForCausalLM]],\n  ['falcon', ['FalconForCausalLM', FalconForCausalLM]],\n  ['trocr', ['TrOCRForCausalLM', TrOCRForCausalLM]],\n  ['stablelm', ['StableLmForCausalLM', StableLmForCausalLM]],\n\n  // Also image-text-to-text\n  ['phi3_v', ['Phi3VForCausalLM', Phi3VForCausalLM]],\n]);\n\nconst MODEL_FOR_MULTIMODALITY_MAPPING_NAMES = new Map([\n  ['multi_modality', ['MultiModalityCausalLM', MultiModalityCausalLM]],\n]);\n\nconst MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES = new Map([\n  ['idefics3', ['Idefics3ForConditionalGeneration', Idefics3ForConditionalGeneration]],\n]);\n\nconst MODEL_FOR_IMAGE_TEXT_TO_TEXT_MAPPING_NAMES = new Map([\n  ['llava', ['LlavaForConditionalGeneration', LlavaForConditionalGeneration]],\n  ['llava_onevision', ['LlavaOnevisionForConditionalGeneration', LlavaOnevisionForConditionalGeneration]],\n  ['moondream1', ['Moondream1ForConditionalGeneration', Moondream1ForConditionalGeneration]],\n  ['florence2', ['Florence2ForConditionalGeneration', Florence2ForConditionalGeneration]],\n  //   ['qwen2-vl', ['Qwen2VLForConditionalGeneration', Qwen2VLForConditionalGeneration]],\n  ['idefics3', ['Idefics3ForConditionalGeneration', Idefics3ForConditionalGeneration]],\n  ['paligemma', ['PaliGemmaForConditionalGeneration', PaliGemmaForConditionalGeneration]],\n]);\n\nconst MODEL_FOR_MASK_GENERATION_MAPPING_NAMES = new Map([['sam', ['SamModel', SamModel]]]);\n\nconst MODEL_FOR_CTC_MAPPING_NAMES = new Map([\n  ['wav2vec2', ['Wav2Vec2ForCTC', Wav2Vec2ForCTC]],\n  ['wav2vec2-bert', ['Wav2Vec2BertForCTC', Wav2Vec2BertForCTC]],\n  ['unispeech', ['UniSpeechForCTC', UniSpeechForCTC]],\n  ['unispeech-sat', ['UniSpeechSatForCTC', UniSpeechSatForCTC]],\n  ['wavlm', ['WavLMForCTC', WavLMForCTC]],\n  ['hubert', ['HubertForCTC', HubertForCTC]],\n]);\n\nconst MODEL_FOR_AUDIO_XVECTOR_MAPPING_NAMES = new Map([['wavlm', ['WavLMForXVector', WavLMForXVector]]]);\n\nconst MODEL_FOR_IMAGE_MATTING_MAPPING_NAMES = new Map([\n  ['vitmatte', ['VitMatteForImageMatting', VitMatteForImageMatting]],\n]);\n\nconst MODEL_FOR_TIME_SERIES_PREDICTION_MAPPING_NAMES = new Map([\n  ['patchtst', ['PatchTSTForPrediction', PatchTSTModel]],\n  ['patchtsmixer', ['PatchTSMixerForPrediction', PatchTSMixerModel]],\n]);\n\nconst MODEL_FOR_IMAGE_TO_IMAGE_MAPPING_NAMES = new Map([\n  ['swin2sr', ['Swin2SRForImageSuperResolution', Swin2SRForImageSuperResolution]],\n]);\n\nconst MODEL_FOR_POSE_ESTIMATION_MAPPING_NAMES = new Map([\n  ['vitpose', ['VitPoseForPoseEstimation', VitPoseForPoseEstimation]],\n]);\n\n// NOTE: This is custom to Transformers.js, and is necessary because certain models\n// (e.g., CLIP) are split into vision and text components\nconst MODEL_FOR_IMAGE_FEATURE_EXTRACTION_MAPPING_NAMES = new Map([\n  ['clip', ['CLIPVisionModelWithProjection', CLIPVisionModelWithProjection]],\n  ['siglip', ['SiglipVisionModel', SiglipVisionModel]],\n  ['jina_clip', ['JinaCLIPVisionModel', JinaCLIPVisionModel]],\n]);\n\nconst MODEL_CLASS_TYPE_MAPPING = [\n  [MODEL_MAPPING_NAMES_ENCODER_ONLY, MODEL_TYPES.EncoderOnly],\n  [MODEL_MAPPING_NAMES_DECODER_ONLY, MODEL_TYPES.DecoderOnly],\n  [MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES, MODEL_TYPES.Seq2Seq],\n  [MODEL_FOR_CAUSAL_LM_MAPPING_NAMES, MODEL_TYPES.DecoderOnly],\n  [MODEL_FOR_MULTIMODALITY_MAPPING_NAMES, MODEL_TYPES.MultiModality],\n  [MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES, MODEL_TYPES.Vision2Seq],\n  [MODEL_FOR_IMAGE_TEXT_TO_TEXT_MAPPING_NAMES, MODEL_TYPES.ImageTextToText],\n  [MODEL_FOR_IMAGE_MATTING_MAPPING_NAMES, MODEL_TYPES.EncoderOnly],\n  [MODEL_FOR_TIME_SERIES_PREDICTION_MAPPING_NAMES, MODEL_TYPES.EncoderOnly],\n  [MODEL_FOR_IMAGE_TO_IMAGE_MAPPING_NAMES, MODEL_TYPES.EncoderOnly],\n  [MODEL_FOR_POSE_ESTIMATION_MAPPING_NAMES, MODEL_TYPES.EncoderOnly],\n  [MODEL_FOR_MASK_GENERATION_MAPPING_NAMES, MODEL_TYPES.MaskGeneration],\n  [MODEL_FOR_CTC_MAPPING_NAMES, MODEL_TYPES.EncoderOnly],\n  [MODEL_FOR_TEXT_TO_SPECTROGRAM_MAPPING_NAMES, MODEL_TYPES.Seq2Seq],\n  [MODEL_FOR_TEXT_TO_WAVEFORM_MAPPING_NAMES, MODEL_TYPES.EncoderOnly],\n  [MODEL_FOR_AUDIO_XVECTOR_MAPPING_NAMES, MODEL_TYPES.EncoderOnly],\n\n  // Custom:\n  [MODEL_FOR_IMAGE_FEATURE_EXTRACTION_MAPPING_NAMES, MODEL_TYPES.EncoderOnly],\n];\n\nfor (const [mappings, type] of MODEL_CLASS_TYPE_MAPPING) {\n  // @ts-ignore\n  for (const [name, model] of mappings.values()) {\n    MODEL_TYPE_MAPPING.set(name, type);\n    MODEL_CLASS_TO_NAME_MAPPING.set(model, name);\n    MODEL_NAME_TO_CLASS_MAPPING.set(name, model);\n  }\n}\n\nconst CUSTOM_MAPPING = [\n  // OVERRIDE:\n  // TODO: Refactor to allow class to specify model\n  ['MusicgenForConditionalGeneration', MusicgenForConditionalGeneration, MODEL_TYPES.Musicgen],\n  ['Phi3VForCausalLM', Phi3VForCausalLM, MODEL_TYPES.Phi3V],\n\n  ['CLIPTextModelWithProjection', CLIPTextModelWithProjection, MODEL_TYPES.EncoderOnly],\n  ['SiglipTextModel', SiglipTextModel, MODEL_TYPES.EncoderOnly],\n  ['JinaCLIPTextModel', JinaCLIPTextModel, MODEL_TYPES.EncoderOnly],\n  ['ClapTextModelWithProjection', ClapTextModelWithProjection, MODEL_TYPES.EncoderOnly],\n  ['ClapAudioModelWithProjection', ClapAudioModelWithProjection, MODEL_TYPES.EncoderOnly],\n];\nfor (const [name, model, type] of CUSTOM_MAPPING) {\n  MODEL_TYPE_MAPPING.set(name, type);\n  MODEL_CLASS_TO_NAME_MAPPING.set(model, name);\n  MODEL_NAME_TO_CLASS_MAPPING.set(name, model);\n}\n\n/**\n * Helper class which is used to instantiate pretrained models with the `from_pretrained` function.\n * The chosen model class is determined by the type specified in the model config.\n *\n * @example\n * let model = await AutoModel.from_pretrained('Xenova/bert-base-uncased');\n */\nexport class AutoModel extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = MODEL_CLASS_TYPE_MAPPING.map((x) => x[0]) as Map<string, any>[];\n  static BASE_IF_FAIL = true;\n}\n\n/**\n * Helper class which is used to instantiate pretrained sequence-to-sequence speech-to-text models with the `from_pretrained` function.\n * The chosen model class is determined by the type specified in the model config.\n *\n * @example\n * let model = await AutoModelForSpeechSeq2Seq.from_pretrained('openai/whisper-tiny.en');\n */\nexport class AutoModelForSpeechSeq2Seq extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_SPEECH_SEQ_2_SEQ_MAPPING_NAMES];\n}\n\n/**\n * Helper class which is used to instantiate pretrained sequence-to-sequence text-to-spectrogram models with the `from_pretrained` function.\n * The chosen model class is determined by the type specified in the model config.\n *\n * @example\n * let model = await AutoModelForTextToSpectrogram.from_pretrained('microsoft/speecht5_tts');\n */\nexport class AutoModelForTextToSpectrogram extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_TEXT_TO_SPECTROGRAM_MAPPING_NAMES];\n}\n\n/**\n * Helper class which is used to instantiate pretrained text-to-waveform models with the `from_pretrained` function.\n * The chosen model class is determined by the type specified in the model config.\n *\n * @example\n * let model = await AutoModelForTextToSpectrogram.from_pretrained('facebook/mms-tts-eng');\n */\nexport class AutoModelForTextToWaveform extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_TEXT_TO_WAVEFORM_MAPPING_NAMES];\n}\n\n/**\n * Helper class which is used to instantiate pretrained causal language models with the `from_pretrained` function.\n * The chosen model class is determined by the type specified in the model config.\n *\n * @example\n * let model = await AutoModelForCausalLM.from_pretrained('Xenova/gpt2');\n */\nexport class AutoModelForCausalLM extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_CAUSAL_LM_MAPPING_NAMES];\n}\n\n/**\n * Helper class which is used to instantiate pretrained vision-to-sequence models with the `from_pretrained` function.\n * The chosen model class is determined by the type specified in the model config.\n *\n * @example\n * let model = await AutoModelForVision2Seq.from_pretrained('Xenova/vit-gpt2-image-captioning');\n */\nexport class AutoModelForVision2Seq extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_VISION_2_SEQ_MAPPING_NAMES];\n}\n\n/**\n * Helper class which is used to instantiate pretrained mask generation models with the `from_pretrained` function.\n * The chosen model class is determined by the type specified in the model config.\n *\n * @example\n * let model = await AutoModelForMaskGeneration.from_pretrained('Xenova/sam-vit-base');\n */\nexport class AutoModelForMaskGeneration extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_MASK_GENERATION_MAPPING_NAMES];\n}\n\nexport class AutoModelForCTC extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_CTC_MAPPING_NAMES];\n}\n\nexport class AutoModelForXVector extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_AUDIO_XVECTOR_MAPPING_NAMES];\n}\n\nexport class AutoModelForImageMatting extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_IMAGE_MATTING_MAPPING_NAMES];\n}\n\nexport class AutoModelForImageToImage extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_IMAGE_TO_IMAGE_MAPPING_NAMES];\n}\n\nexport class AutoModelForPoseEstimation extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_POSE_ESTIMATION_MAPPING_NAMES];\n}\n\nexport class AutoModelForImageFeatureExtraction extends PretrainedMixin {\n  static MODEL_CLASS_MAPPINGS = [MODEL_FOR_IMAGE_FEATURE_EXTRACTION_MAPPING_NAMES];\n}\n\n//////////////////////////////////////////////////\n\n//////////////////////////////////////////////////\nexport class Seq2SeqLMOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.logits The output logits of the model.\n   * @param {Tensor} output.past_key_values An tensor of key/value pairs that represent the previous state of the model.\n   * @param {Tensor} output.encoder_outputs The output of the encoder in a sequence-to-sequence model.\n   * @param {Tensor} [output.decoder_attentions] Attentions weights of the decoder, after the attention softmax, used to compute the weighted average in the self-attention heads.\n   * @param {Tensor} [output.cross_attentions] Attentions weights of the decoder's cross-attention layer, after the attention softmax, used to compute the weighted average in the cross-attention heads.\n   */\n  logits: Tensor;\n  past_key_values: Tensor;\n  encoder_outputs: Tensor;\n  decoder_attentions: Tensor | null;\n  cross_attentions: Tensor | null;\n  constructor({\n    logits,\n    past_key_values,\n    encoder_outputs,\n    decoder_attentions = null,\n    cross_attentions = null,\n  }: {\n    logits: Tensor;\n    past_key_values: Tensor;\n    encoder_outputs: Tensor;\n    decoder_attentions: Tensor | null;\n    cross_attentions: Tensor | null;\n  }) {\n    super();\n    this.logits = logits;\n    this.past_key_values = past_key_values;\n    this.encoder_outputs = encoder_outputs;\n    this.decoder_attentions = decoder_attentions;\n    this.cross_attentions = cross_attentions;\n  }\n}\n\n/**\n * Base class for outputs of sentence classification models.\n */\nexport class SequenceClassifierOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.logits classification (or regression if config.num_labels==1) scores (before SoftMax).\n   * @param {Record<string, Tensor>} [output.attentions] Object of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length, sequence_length)`.\n   * Attentions weights after the attention softmax, used to compute the weighted average in the self-attention heads.\n   */\n  logits: Tensor;\n  attentions: Record<string, Tensor>;\n  constructor({ logits, ...attentions }: { logits: Tensor;[key: string]: Tensor }) {\n    super();\n    this.logits = logits;\n    this.attentions = attentions;\n  }\n}\n\n/**\n * Base class for outputs of XVector models.\n */\nexport class XVectorOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.logits Classification hidden states before AMSoftmax, of shape `(batch_size, config.xvector_output_dim)`.\n   * @param {Tensor} output.embeddings Utterance embeddings used for vector similarity-based retrieval, of shape `(batch_size, config.xvector_output_dim)`.\n   */\n  logits: Tensor;\n  embeddings: Tensor;\n  constructor({ logits, embeddings }: { logits: Tensor; embeddings: Tensor }) {\n    super();\n    this.logits = logits;\n    this.embeddings = embeddings;\n  }\n}\n\n/**\n * Base class for outputs of token classification models.\n */\nexport class TokenClassifierOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.logits Classification scores (before SoftMax).\n   */\n  logits: Tensor;\n  constructor({ logits }: { logits: Tensor }) {\n    super();\n    this.logits = logits;\n  }\n}\n\n/**\n * Base class for masked language models outputs.\n */\nexport class MaskedLMOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.logits Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).\n   */\n  logits: Tensor;\n  constructor({ logits }: { logits: Tensor }) {\n    super();\n    this.logits = logits;\n  }\n}\n\n/**\n * Base class for outputs of question answering models.\n */\nexport class QuestionAnsweringModelOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.start_logits Span-start scores (before SoftMax).\n   * @param {Tensor} output.end_logits Span-end scores (before SoftMax).\n   */\n  start_logits: Tensor;\n  end_logits: Tensor;\n  constructor({ start_logits, end_logits }: { start_logits: Tensor; end_logits: Tensor }) {\n    super();\n    this.start_logits = start_logits;\n    this.end_logits = end_logits;\n  }\n}\n\n/**\n * Base class for causal language model (or autoregressive) outputs.\n */\nexport class CausalLMOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.logits Prediction scores of the language modeling head (scores for each vocabulary token before softmax).\n   */\n  logits: Tensor;\n  constructor({ logits }: { logits: Tensor }) {\n    super();\n    this.logits = logits;\n  }\n}\n\n/**\n * Base class for causal language model (or autoregressive) outputs.\n */\nexport class CausalLMOutputWithPast extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.logits Prediction scores of the language modeling head (scores for each vocabulary token before softmax).\n   * @param {Tensor} output.past_key_values Contains pre-computed hidden-states (key and values in the self-attention blocks)\n   * that can be used (see `past_key_values` input) to speed up sequential decoding.\n   */\n  logits: Tensor;\n  past_key_values: Tensor;\n  constructor({ logits, past_key_values }: { logits: Tensor; past_key_values: Tensor }) {\n    super();\n    this.logits = logits;\n    this.past_key_values = past_key_values;\n  }\n}\n\nexport class ImageMattingOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.alphas Estimated alpha values, of shape `(batch_size, num_channels, height, width)`.\n   */\n  alphas: Tensor;\n  constructor({ alphas }: { alphas: Tensor }) {\n    super();\n    this.alphas = alphas;\n  }\n}\n\n/**\n * Describes the outputs for the VITS model.\n */\nexport class VitsModelOutput extends ModelOutput {\n  /**\n   * @param {Object} output The output of the model.\n   * @param {Tensor} output.waveform The final audio waveform predicted by the model, of shape `(batch_size, sequence_length)`.\n   * @param {Tensor} output.spectrogram The log-mel spectrogram predicted at the output of the flow model.\n   * This spectrogram is passed to the Hi-Fi GAN decoder model to obtain the final audio waveform.\n   */\n  waveform: Tensor;\n  spectrogram: Tensor;\n  constructor({ waveform, spectrogram }: { waveform: Tensor; spectrogram: Tensor }) {\n    super();\n    this.waveform = waveform;\n    this.spectrogram = spectrogram;\n  }\n}\n","/**\n * @file Processors are used to prepare inputs (e.g., text, image or audio) for a model.\n *\n * **Example:** Using a `WhisperProcessor` to prepare an audio input for a model.\n * ```javascript\n * import { AutoProcessor, read_audio } from '@huggingface/transformers';\n *\n * const processor = await AutoProcessor.from_pretrained('openai/whisper-tiny.en');\n * const audio = await read_audio('https://huggingface.co/datasets/Narsil/asr_dummy/resolve/main/mlk.flac', 16000);\n * const { input_features } = await processor(audio);\n * // Tensor {\n * //   data: Float32Array(240000) [0.4752984642982483, 0.5597258806228638, 0.56434166431427, ...],\n * //   dims: [1, 80, 3000],\n * //   type: 'float32',\n * //   size: 240000,\n * // }\n * ```\n *\n * @module processors\n */\nimport { PROCESSOR_NAME } from '../utils/constants';\nimport { Callable } from '../utils/generic';\nimport { getModelJSON } from '../utils/hub';\n\n/**\n * @typedef {Object} ProcessorProperties Additional processor-specific properties.\n * @typedef {import('../utils/hub.js').PretrainedOptions & ProcessorProperties} PretrainedProcessorOptions\n * @typedef {import('../tokenizers.js').PreTrainedTokenizer} PreTrainedTokenizer\n */\n\n/**\n * Represents a Processor that extracts features from an input.\n */\nexport class Processor extends Callable {\n  static classes = ['image_processor_class', 'tokenizer_class', 'feature_extractor_class'] as const;\n  static uses_processor_config = false;\n\n  static image_processor_class: any;\n  static tokenizer_class: any;\n  static feature_extractor_class: any;\n\n  /**\n   * Creates a new Processor with the given components\n   * @param {Object} config\n   * @param {Record<string, Object>} components\n   */\n  config: Record<string, any>;\n  components: Record<string, any>;\n  constructor(config: Record<string, any>, components: Record<string, any>) {\n    super();\n    this.config = config;\n    this.components = components;\n  }\n\n  /**\n   * @returns {import('./image_processors_utils.js').ImageProcessor|undefined} The image processor of the processor, if it exists.\n   */\n  get image_processor() {\n    return this.components.image_processor;\n  }\n\n  /**\n   * @returns {PreTrainedTokenizer|undefined} The tokenizer of the processor, if it exists.\n   */\n  get tokenizer() {\n    return this.components.tokenizer;\n  }\n\n  /**\n   * @returns {import('./feature_extraction_utils.js').FeatureExtractor|undefined} The feature extractor of the processor, if it exists.\n   */\n  get feature_extractor() {\n    return this.components.feature_extractor;\n  }\n\n  /**\n   * @param {Parameters<PreTrainedTokenizer['apply_chat_template']>[0]} messages\n   * @param {Parameters<PreTrainedTokenizer['apply_chat_template']>[1]} options\n   * @returns {ReturnType<PreTrainedTokenizer['apply_chat_template']>}\n   */\n  apply_chat_template(messages: any, options: any = {}) {\n    if (!this.tokenizer) {\n      throw new Error('Unable to apply chat template without a tokenizer.');\n    }\n    return this.tokenizer.apply_chat_template(messages, {\n      tokenize: false, // default to false\n      ...options,\n    });\n  }\n\n  /**\n   * @param {Parameters<PreTrainedTokenizer['batch_decode']>} args\n   * @returns {ReturnType<PreTrainedTokenizer['batch_decode']>}\n   */\n  batch_decode(...args: any[]) {\n    if (!this.tokenizer) {\n      throw new Error('Unable to decode without a tokenizer.');\n    }\n    return this.tokenizer.batch_decode(...args);\n  }\n\n  /**\n   * @param {Parameters<PreTrainedTokenizer['decode']>} args\n   * @returns {ReturnType<PreTrainedTokenizer['decode']>}\n   */\n  decode(...args: any[]) {\n    if (!this.tokenizer) {\n      throw new Error('Unable to decode without a tokenizer.');\n    }\n    return this.tokenizer.decode(...args);\n  }\n\n  /**\n   * Calls the feature_extractor function with the given input.\n   * @param {any} input The input to extract features from.\n   * @param {...any} args Additional arguments.\n   * @returns {Promise<any>} A Promise that resolves with the extracted features.\n   */\n  async _call(input: any, ...args: any[]) {\n    for (const item of [this.image_processor, this.feature_extractor, this.tokenizer]) {\n      if (item) {\n        return item(input, ...args);\n      }\n    }\n    throw new Error('No image processor, feature extractor, or tokenizer found.');\n  }\n\n  /**\n   * Instantiate one of the processor classes of the library from a pretrained model.\n   *\n   * The processor class to instantiate is selected based on the `image_processor_type` (or `feature_extractor_type`; legacy)\n   * property of the config object (either passed as an argument or loaded from `pretrained_model_name_or_path` if possible)\n   *\n   * @param {string} pretrained_model_name_or_path The name or path of the pretrained model. Can be either:\n   * - A string, the *model id* of a pretrained processor hosted inside a model repo on huggingface.co.\n   *   Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a\n   *   user or organization name, like `dbmdz/bert-base-german-cased`.\n   * - A path to a *directory* containing processor files, e.g., `./my_model_directory/`.\n   * @param {PretrainedProcessorOptions} options Additional options for loading the processor.\n   *\n   * @returns {Promise<Processor>} A new instance of the Processor class.\n   */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: any) {\n    const [config, components] = await Promise.all([\n      // TODO:\n      this.uses_processor_config ? getModelJSON(pretrained_model_name_or_path, PROCESSOR_NAME, true, options) : {},\n      Promise.all(\n        this.classes\n          .filter((cls) => cls in this)\n          .map(async (cls) => {\n            const component = await this[cls].from_pretrained(pretrained_model_name_or_path, options);\n            return [cls.replace(/_class$/, ''), component];\n          }),\n      ).then(Object.fromEntries),\n    ]);\n\n    return new this(config, components);\n  }\n}\n","export * from './florence2/processing_florence2';\nexport * from './idefics3/processing_idefics3';\nexport * from './mgp_str/processing_mgp_str';\nexport * from './moonshine/processing_moonshine';\nexport * from './janus/processing_janus';\nexport * from './jina_clip/processing_jina_clip';\nexport * from './phi3_v/processing_phi3_v';\nexport * from './paligemma/processing_paligemma';\nexport * from './pyannote/processing_pyannote';\nexport * from './qwen2_vl/processing_qwen2_vl';\nexport * from './sam/processing_sam';\nexport * from './speecht5/processing_speecht5';\nexport * from './wav2vec2/processing_wav2vec2';\nexport * from './whisper/processing_whisper';\n","import { Callable } from '../utils/generic';\nimport { Tensor, interpolate, stack } from '../utils/tensor';\nimport { bankers_round, max, min, softmax } from '../utils/maths';\nimport { RawImage } from '../utils/image';\nimport { calculateReflectOffset, ProgressCallback } from '../utils/core.js';\nimport { getModelJSON, PretrainedOptions } from '../utils/hub.js';\nimport { IMAGE_PROCESSOR_NAME } from '../utils/constants.js';\n\n/**\n * Named tuple to indicate the order we are using is (height x width),\n * even though the Graphics' industry standard is (width x height).\n * @typedef {[height: number, width: number]} HeightWidth\n */\n\n/**\n * @typedef {object} ImageProcessorResult\n * @property {Tensor} pixel_values The pixel values of the batched preprocessed images.\n * @property {HeightWidth[]} original_sizes Array of two-dimensional tuples like [[480, 640]].\n * @property {HeightWidth[]} reshaped_input_sizes Array of two-dimensional tuples like [[1000, 1330]].\n */\n\n/**\n * Helper function to constrain a value to be a multiple of a number.\n * @param {number} val The value to constrain.\n * @param {number} multiple The number to constrain to.\n * @param {number} [minVal=0] The minimum value to constrain to.\n * @param {number} [maxVal=null] The maximum value to constrain to.\n * @returns {number} The constrained value.\n * @private\n */\nfunction constraint_to_multiple_of(val: number, multiple: number, minVal = 0, maxVal = null) {\n  const a = val / multiple;\n  let x = bankers_round(a) * multiple;\n\n  if (maxVal !== null && x > maxVal) {\n    x = Math.floor(a) * multiple;\n  }\n\n  if (x < minVal) {\n    x = Math.ceil(a) * multiple;\n  }\n\n  return x;\n}\n\n/**\n * Rounds the height and width down to the closest multiple of size_divisibility\n * @param {[number, number]} size The size of the image\n * @param {number} divisor The divisor to use.\n * @returns {[number, number]} The rounded size.\n */\nfunction enforce_size_divisibility(size: [number, number], divisor: number) {\n  return [Math.max(Math.floor(size[0] / divisor), 1) * divisor, Math.max(Math.floor(size[1] / divisor), 1) * divisor];\n}\n\n// Helper functions\n\n/**\n * Converts bounding boxes from center format to corners format.\n *\n * @param {number[]} arr The coordinate for the center of the box and its width, height dimensions (center_x, center_y, width, height)\n * @returns {number[]} The coodinates for the top-left and bottom-right corners of the box (top_left_x, top_left_y, bottom_right_x, bottom_right_y)\n */\nexport function center_to_corners_format(centerX: number, centerY: number, width: number, height: number) {\n  return [centerX - width / 2, centerY - height / 2, centerX + width / 2, centerY + height / 2];\n}\n\n/**\n * Post-processes the outputs of the model (for object detection).\n * @param {Object} outputs The outputs of the model that must be post-processed\n * @param {Tensor} outputs.logits The logits\n * @param {Tensor} outputs.pred_boxes The predicted boxes.\n * @param {number} [threshold=0.5] The threshold to use for the scores.\n * @param {[number, number][]} [target_sizes=null] The sizes of the original images.\n * @param {boolean} [is_zero_shot=false] Whether zero-shot object detection was performed.\n * @return {Object[]} An array of objects containing the post-processed outputs.\n */\nexport function post_process_object_detection(\n  outputs: any,\n  threshold = 0.5,\n  target_sizes: [number, number][] | null = null,\n  is_zero_shot = false,\n) {\n  const out_logits = outputs.logits;\n  const out_bbox = outputs.pred_boxes;\n  const [batch_size, num_boxes, num_classes] = out_logits.dims;\n\n  if (target_sizes !== null && target_sizes.length !== batch_size) {\n    throw Error('Make sure that you pass in as many target sizes as the batch dimension of the logits');\n  }\n  let toReturn = [];\n  for (let i = 0; i < batch_size; ++i) {\n    let target_size = target_sizes !== null ? target_sizes[i] : null;\n    let info: {\n      boxes: number[][];\n      classes: number[];\n      scores: number[];\n    } = {\n      boxes: [],\n      classes: [],\n      scores: [],\n    };\n    let logits = out_logits[i];\n    let bbox = out_bbox[i];\n\n    for (let j = 0; j < num_boxes; ++j) {\n      let logit = logits[j];\n\n      let indices = [];\n      let probs;\n      if (is_zero_shot) {\n        // Get indices of classes with high enough probability\n        probs = logit.sigmoid().data;\n        for (let k = 0; k < probs.length; ++k) {\n          if (probs[k] > threshold) {\n            indices.push(k);\n          }\n        }\n      } else {\n        // Get most probable class\n        let maxIndex = max(logit.data as Float32Array)[1];\n\n        if (maxIndex === num_classes - 1) {\n          // This is the background class, skip it\n          continue;\n        }\n        // Compute softmax over classes\n        probs = softmax(logit.data);\n\n        if (probs[Number(maxIndex)] < threshold) {\n          continue;\n        }\n        indices.push(maxIndex);\n      }\n\n      for (const index of indices) {\n        // Some class has a high enough probability\n        /** @type {number[]} */\n        let box = bbox[j].data;\n\n        // convert to [x0, y0, x1, y1] format\n        box = center_to_corners_format(box[0], box[1], box[2], box[3]);\n        if (target_size !== null) {\n          box = box.map((x: number, i: number) => x * target_size[(i + 1) % 2]);\n        }\n\n        info.boxes.push(box);\n        info.classes.push(Number(index));\n        info.scores.push(probs[Number(index)]);\n      }\n    }\n    toReturn.push(info);\n  }\n  return toReturn;\n}\n\n/**\n * Post-processes the outputs of the model (for semantic segmentation).\n * @param {*} outputs Raw outputs of the model.\n * @param {[number, number][]} [target_sizes=null] List of tuples corresponding to the requested final size\n * (height, width) of each prediction. If unset, predictions will not be resized.\n * @returns {{segmentation: Tensor; labels: number[]}[]} The semantic segmentation maps.\n */\nexport function post_process_semantic_segmentation(outputs: any, target_sizes: [number, number][] | null = null) {\n  const logits = outputs.logits;\n  const batch_size = logits.dims[0];\n\n  if (target_sizes !== null && target_sizes.length !== batch_size) {\n    throw Error('Make sure that you pass in as many target sizes as the batch dimension of the logits');\n  }\n\n  const toReturn = [];\n  for (let i = 0; i < batch_size; ++i) {\n    const target_size = target_sizes !== null ? target_sizes[i] : null;\n\n    let data = logits[i];\n\n    // 1. If target_size is not null, we need to resize the masks to the target size\n    if (target_size !== null) {\n      // resize the masks to the target size\n      data = interpolate(data, target_size, 'bilinear', false);\n    }\n    const [height, width] = target_size ?? data.dims.slice(-2);\n\n    const segmentation = new Tensor('int32', new Int32Array(height * width), [height, width]);\n\n    // Buffer to store current largest value\n    const buffer = data[0].data;\n    const segmentation_data = segmentation.data;\n    for (let j = 1; j < data.dims[0]; ++j) {\n      const row = data[j].data;\n      for (let k = 0; k < row.length; ++k) {\n        if (row[k] > buffer[k]) {\n          buffer[k] = row[k];\n          segmentation_data[k] = j;\n        }\n      }\n    }\n\n    // Store which objects have labels\n    // This is much more efficient that creating a set of the final values\n    const hasLabel = new Array(data.dims[0]);\n    for (let j = 0; j < segmentation_data.length; ++j) {\n      const index = segmentation_data[j];\n      hasLabel[index] = index;\n    }\n    /** @type {number[]} The unique list of labels that were detected */\n    const labels = hasLabel.filter((x) => x !== undefined);\n\n    toReturn.push({ segmentation, labels });\n  }\n  return toReturn;\n}\n\n/**\n * Binarize the given masks using `object_mask_threshold`, it returns the associated values of `masks`, `scores` and `labels`.\n * @param {Tensor} class_logits The class logits.\n * @param {Tensor} mask_logits The mask logits.\n * @param {number} object_mask_threshold A number between 0 and 1 used to binarize the masks.\n * @param {number} num_labels The number of labels.\n * @returns {[Tensor[], number[], number[]]} The binarized masks, the scores, and the labels.\n * @private\n */\nfunction remove_low_and_no_objects(\n  class_logits: Tensor,\n  mask_logits: Tensor,\n  object_mask_threshold: number,\n  num_labels: number,\n) {\n  const mask_probs_item = [];\n  const pred_scores_item = [];\n  const pred_labels_item = [];\n\n  for (let j = 0; j < class_logits.dims[0]; ++j) {\n    const cls = class_logits[j];\n    const mask = mask_logits[j];\n\n    const pred_label = max(cls.data as Float32Array)[1];\n    if (pred_label === num_labels) {\n      // Is the background, so we ignore it\n      continue;\n    }\n\n    const scores = softmax(cls.data as Float32Array);\n    const pred_score = scores[Number(pred_label)];\n    if (pred_score > object_mask_threshold) {\n      mask_probs_item.push(mask);\n      pred_scores_item.push(pred_score);\n      pred_labels_item.push(pred_label);\n    }\n  }\n\n  return [mask_probs_item, pred_scores_item, pred_labels_item];\n}\n\n/**\n * Checks whether the segment is valid or not.\n * @param {Int32Array} mask_labels Labels for each pixel in the mask.\n * @param {Tensor[]} mask_probs Probabilities for each pixel in the masks.\n * @param {number} k The class id of the segment.\n * @param {number} mask_threshold The mask threshold.\n * @param {number} overlap_mask_area_threshold The overlap mask area threshold.\n * @returns {[boolean, number[]]} Whether the segment is valid or not, and the indices of the valid labels.\n * @private\n */\nfunction check_segment_validity(\n  mask_labels: Int32Array,\n  mask_probs: Tensor[],\n  k: number,\n  mask_threshold = 0.5,\n  overlap_mask_area_threshold = 0.8,\n) {\n  // mask_k is a 1D array of indices, indicating where the mask is equal to k\n  const mask_k = [];\n  let mask_k_area = 0;\n  let original_area = 0;\n\n  const mask_probs_k_data = mask_probs[k].data;\n\n  // Compute the area of all the stuff in query k\n  for (let i = 0; i < mask_labels.length; ++i) {\n    if (mask_labels[i] === k) {\n      mask_k.push(i);\n      ++mask_k_area;\n    }\n\n    if (mask_probs_k_data[i] >= mask_threshold) {\n      ++original_area;\n    }\n  }\n  let mask_exists = mask_k_area > 0 && original_area > 0;\n\n  // Eliminate disconnected tiny segments\n  if (mask_exists) {\n    // Perform additional check\n    let area_ratio = mask_k_area / original_area;\n    mask_exists = area_ratio > overlap_mask_area_threshold;\n  }\n\n  return [mask_exists, mask_k];\n}\n\n/**\n * Computes the segments.\n * @param {Tensor[]} mask_probs The mask probabilities.\n * @param {number[]} pred_scores The predicted scores.\n * @param {number[]} pred_labels The predicted labels.\n * @param {number} mask_threshold The mask threshold.\n * @param {number} overlap_mask_area_threshold The overlap mask area threshold.\n * @param {Set<number>} label_ids_to_fuse The label ids to fuse.\n * @param {number[]} target_size The target size of the image.\n * @returns {[Tensor, Array<{id: number, label_id: number, score: number}>]} The computed segments.\n * @private\n */\nfunction compute_segments(\n  mask_probs: Tensor[],\n  pred_scores: number[],\n  pred_labels: number[],\n  mask_threshold: number,\n  overlap_mask_area_threshold: number,\n  label_ids_to_fuse: Set<number>,\n  target_size: [number, number] | null = null,\n) {\n  const [height, width] = target_size ?? mask_probs[0].dims;\n\n  const segmentation = new Tensor('int32', new Int32Array(height * width), [height, width]);\n  const segments = [];\n\n  // 1. If target_size is not null, we need to resize the masks to the target size\n  if (target_size !== null) {\n    // resize the masks to the target size\n    for (let i = 0; i < mask_probs.length; ++i) {\n      mask_probs[i] = interpolate(mask_probs[i], target_size, 'bilinear', false);\n    }\n  }\n\n  // 2. Weigh each mask by its prediction score\n  // NOTE: `mask_probs` is updated in-place\n  //\n  // Temporary storage for the best label/scores for each pixel ([height, width]):\n  const mask_labels = new Int32Array(mask_probs[0].data.length);\n  const bestScores = new Float32Array(mask_probs[0].data.length);\n\n  for (let i = 0; i < mask_probs.length; ++i) {\n    let score = pred_scores[i];\n\n    const mask_probs_i_data = mask_probs[i].data;\n\n    for (let j = 0; j < mask_probs_i_data.length; ++j) {\n      mask_probs_i_data[j] *= score;\n      if (mask_probs_i_data[j] > bestScores[j]) {\n        mask_labels[j] = i;\n        bestScores[j] = mask_probs_i_data[j];\n      }\n    }\n  }\n\n  let current_segment_id = 0;\n\n  // let stuff_memory_list = {}\n  const segmentation_data = segmentation.data;\n  for (let k = 0; k < pred_labels.length; ++k) {\n    const pred_class = pred_labels[k];\n\n    // TODO add `should_fuse`\n    // let should_fuse = pred_class in label_ids_to_fuse\n\n    // Check if mask exists and large enough to be a segment\n    const [mask_exists, mask_k] = check_segment_validity(\n      mask_labels,\n      mask_probs,\n      k,\n      mask_threshold,\n      overlap_mask_area_threshold,\n    );\n\n    if (!mask_exists) {\n      // Nothing to see here\n      continue;\n    }\n\n    // TODO\n    // if (pred_class in stuff_memory_list) {\n    //     current_segment_id = stuff_memory_list[pred_class]\n    // } else {\n    //     current_segment_id += 1;\n    // }\n    ++current_segment_id;\n\n    // Add current object segment to final segmentation map\n    for (const index of mask_k as number[]) {\n      segmentation_data[index] = current_segment_id;\n    }\n\n    segments.push({\n      id: current_segment_id,\n      label_id: pred_class,\n      // was_fused: should_fuse, TODO\n      score: pred_scores[k],\n    });\n\n    // TODO\n    // if(should_fuse){\n    //     stuff_memory_list[pred_class] = current_segment_id\n    // }\n  }\n\n  return [segmentation, segments];\n}\n\n/**\n * Rescales the image so that the following conditions are met:\n *\n * 1. Both dimensions (height and width) are divisible by 'factor'.\n * 2. The total number of pixels is within the range ['min_pixels', 'max_pixels'].\n * 3. The aspect ratio of the image is maintained as closely as possible.\n *\n * @param {number} height The height of the image.\n * @param {number} width The width of the image.\n * @param {number} [factor=28] The factor to use for resizing.\n * @param {number} [min_pixels=56*56] The minimum number of pixels.\n * @param {number} [max_pixels=14*14*4*1280] The maximum number of pixels.\n * @returns {[number, number]} The new height and width of the image.\n * @throws {Error} If the height or width is smaller than the factor.\n */\nfunction smart_resize(\n  height: number,\n  width: number,\n  factor = 28,\n  min_pixels = 56 * 56,\n  max_pixels = 14 * 14 * 4 * 1280,\n) {\n  if (height < factor || width < factor) {\n    throw new Error(`height:${height} or width:${width} must be larger than factor:${factor}`);\n  } else if (Math.max(height, width) / Math.min(height, width) > 200) {\n    throw new Error(\n      `absolute aspect ratio must be smaller than 200, got ${Math.max(height, width) / Math.min(height, width)}`,\n    );\n  }\n\n  let h_bar = Math.round(height / factor) * factor;\n  let w_bar = Math.round(width / factor) * factor;\n\n  if (h_bar * w_bar > max_pixels) {\n    const beta = Math.sqrt((height * width) / max_pixels);\n    h_bar = Math.floor(height / beta / factor) * factor;\n    w_bar = Math.floor(width / beta / factor) * factor;\n  } else if (h_bar * w_bar < min_pixels) {\n    const beta = Math.sqrt(min_pixels / (height * width));\n    h_bar = Math.ceil((height * beta) / factor) * factor;\n    w_bar = Math.ceil((width * beta) / factor) * factor;\n  }\n\n  return [h_bar, w_bar];\n}\n\n/**\n * Post-process the model output to generate the final panoptic segmentation.\n * @param {*} outputs The model output to post process\n * @param {number} [threshold=0.5] The probability score threshold to keep predicted instance masks.\n * @param {number} [mask_threshold=0.5] Threshold to use when turning the predicted masks into binary values.\n * @param {number} [overlap_mask_area_threshold=0.8] The overlap mask area threshold to merge or discard small disconnected parts within each binary instance mask.\n * @param {Set<number>} [label_ids_to_fuse=null] The labels in this state will have all their instances be fused together.\n * @param {[number, number][]} [target_sizes=null] The target sizes to resize the masks to.\n * @returns {Array<{ segmentation: Tensor, segments_info: Array<{id: number, label_id: number, score: number}>}>}\n */\nexport function post_process_panoptic_segmentation(\n  outputs: any,\n  threshold = 0.5,\n  mask_threshold = 0.5,\n  overlap_mask_area_threshold = 0.8,\n  label_ids_to_fuse: Set<number> | null = null,\n  target_sizes: [number, number][] | null = null,\n) {\n  if (label_ids_to_fuse === null) {\n    console.warn('`label_ids_to_fuse` unset. No instance will be fused.');\n    label_ids_to_fuse = new Set();\n  }\n\n  const class_queries_logits = outputs.class_queries_logits ?? outputs.logits; // [batch_size, num_queries, num_classes+1]\n  const masks_queries_logits = outputs.masks_queries_logits ?? outputs.pred_masks; // [batch_size, num_queries, height, width]\n\n  const mask_probs = masks_queries_logits.sigmoid(); // [batch_size, num_queries, height, width]\n\n  let [batch_size, num_queries, num_labels] = class_queries_logits.dims;\n  num_labels -= 1; // Remove last class (background)\n\n  if (target_sizes !== null && target_sizes.length !== batch_size) {\n    throw Error('Make sure that you pass in as many target sizes as the batch dimension of the logits');\n  }\n\n  let toReturn = [];\n  for (let i = 0; i < batch_size; ++i) {\n    let target_size = target_sizes !== null ? target_sizes[i] : null;\n\n    let class_logits = class_queries_logits[i];\n    let mask_logits = mask_probs[i];\n\n    let [mask_probs_item, pred_scores_item, pred_labels_item] = remove_low_and_no_objects(\n      class_logits,\n      mask_logits,\n      threshold,\n      num_labels,\n    );\n\n    if (pred_labels_item.length === 0) {\n      // No mask found\n      let [height, width] = target_size ?? mask_logits.dims.slice(-2);\n\n      let segmentation = new Tensor('int32', new Int32Array(height * width).fill(-1), [height, width]);\n      toReturn.push({\n        segmentation: segmentation,\n        segments_info: [],\n      });\n      continue;\n    }\n\n    // Get segmentation map and segment information of batch item\n    let [segmentation, segments] = compute_segments(\n      mask_probs_item as Tensor[],\n      pred_scores_item as number[],\n      pred_labels_item as number[],\n      mask_threshold,\n      overlap_mask_area_threshold,\n      label_ids_to_fuse,\n      target_size,\n    );\n\n    toReturn.push({\n      segmentation: segmentation,\n      segments_info: segments,\n    });\n  }\n\n  return toReturn;\n}\n\n/**\n * Post-processes the outputs of the model (for instance segmentation).\n * @param {*} outputs Raw outputs of the model.\n * @param {number} [threshold=0.5] The probability score threshold to keep predicted instance masks.\n * @param {[number, number][]} [target_sizes=null] List of tuples corresponding to the requested final size\n * (height, width) of each prediction. If unset, predictions will not be resized.\n * @returns {Array<{ segmentation: Tensor, segments_info: Array<{id: number, label_id: number, score: number}>}>}\n */\nexport function post_process_instance_segmentation(\n  outputs: any,\n  threshold = 0.5,\n  target_sizes: [number, number][] | null = null,\n) {\n  throw new Error('`post_process_instance_segmentation` is not yet implemented.');\n}\n\n/**\n * @typedef {Object} ImageProcessorConfig A configuration object used to create an image processor.\n * @property {function} [progress_callback=null] If specified, this function will be called during model construction, to provide the user with progress updates.\n * @property {number[]} [image_mean] The mean values for image normalization.\n * @property {number[]} [image_std] The standard deviation values for image normalization.\n * @property {boolean} [do_rescale] Whether to rescale the image pixel values to the [0,1] range.\n * @property {number} [rescale_factor] The factor to use for rescaling the image pixel values.\n * @property {boolean} [do_normalize] Whether to normalize the image pixel values.\n * @property {boolean} [do_resize] Whether to resize the image.\n * @property {number} [resample] What method to use for resampling.\n * @property {number|Object} [size] The size to resize the image to.\n * @property {number|Object} [image_size] The size to resize the image to (same as `size`).\n * @property {boolean} [do_flip_channel_order=false] Whether to flip the color channels from RGB to BGR.\n * Can be overridden by the `do_flip_channel_order` parameter in the `preprocess` method.\n * @property {boolean} [do_center_crop] Whether to center crop the image to the specified `crop_size`.\n * Can be overridden by `do_center_crop` in the `preprocess` method.\n * @property {boolean} [do_thumbnail] Whether to resize the image using thumbnail method.\n * @property {boolean} [keep_aspect_ratio] If `true`, the image is resized to the largest possible size such that the aspect ratio is preserved.\n * Can be overidden by `keep_aspect_ratio` in `preprocess`.\n * @property {number} [ensure_multiple_of] If `do_resize` is `true`, the image is resized to a size that is a multiple of this value.\n * Can be overidden by `ensure_multiple_of` in `preprocess`.\n *\n * @property {number[]} [mean] The mean values for image normalization (same as `image_mean`).\n * @property {number[]} [std] The standard deviation values for image normalization (same as `image_std`).\n */\n\ninterface ImageProcessorConfig {\n  progress_callback?: ProgressCallback;\n  image_mean?: number[];\n  image_std?: number[];\n  do_rescale?: boolean;\n  rescale_factor?: number;\n  do_normalize?: boolean;\n  do_resize?: boolean;\n  resample?: number;\n  size?: number | { height: number; width: number };\n  image_size?: number | { height: number; width: number };\n  do_flip_channel_order?: boolean;\n  do_center_crop?: boolean;\n  do_thumbnail?: boolean;\n  keep_aspect_ratio?: boolean;\n  ensure_multiple_of?: number;\n  mean?: number[];\n  std?: number[];\n  crop_size?: number | { height: number; width: number };\n  do_crop_margin?: boolean;\n  do_convert_rgb?: boolean;\n}\n\nexport class ImageProcessor extends Callable {\n  protected image_mean?: number[];\n  protected image_std?: number[];\n  protected resample: number;\n  protected do_rescale: boolean;\n  protected rescale_factor: number;\n  protected do_normalize?: boolean;\n  protected do_thumbnail?: boolean;\n  protected size?: number | { height: number; width: number };\n  protected do_resize: boolean;\n  protected size_divisibility?: number;\n  protected do_center_crop?: boolean;\n  protected crop_size?: number | { height: number; width: number };\n  protected do_flip_channel_order: boolean;\n  protected config: ImageProcessorConfig;\n  protected pad_size?: { width: number; height: number };\n  protected do_pad?: boolean;\n  protected do_crop_margin?: boolean;\n  protected do_convert_rgb?: boolean;\n\n  /**\n   * Constructs a new `ImageProcessor`.\n   * @param {ImageProcessorConfig} config The configuration object.\n   */\n  constructor(config: ImageProcessorConfig) {\n    super();\n\n    this.image_mean = config.image_mean ?? config.mean;\n    this.image_std = config.image_std ?? config.std;\n\n    this.resample = config.resample ?? 2; // 2 => bilinear\n    this.do_rescale = config.do_rescale ?? true;\n    this.rescale_factor = config.rescale_factor ?? 1 / 255;\n    this.do_normalize = config.do_normalize;\n\n    this.do_thumbnail = config.do_thumbnail;\n    this.size = config.size ?? config.image_size;\n    this.do_resize = config.do_resize ?? this.size !== undefined;\n    // @ts-expect-error TS2339\n    this.size_divisibility = config.size_divisibility ?? config.size_divisor;\n\n    this.do_center_crop = config.do_center_crop;\n    this.crop_size = config.crop_size;\n    this.do_convert_rgb = config.do_convert_rgb ?? true;\n    this.do_crop_margin = config.do_crop_margin;\n\n    // @ts-expect-error TS2339\n    this.pad_size = config.pad_size;\n    // @ts-expect-error TS2339\n    this.do_pad = config.do_pad;\n\n    if (\n      this.do_pad &&\n      !this.pad_size &&\n      this.size &&\n      typeof this.size === 'object' &&\n      'width' in this.size &&\n      'height' in this.size\n    ) {\n      // Should pad, but no pad size specified\n      // We infer the pad size from the resize size\n      this.pad_size = this.size;\n    }\n\n    this.do_flip_channel_order = config.do_flip_channel_order ?? false;\n\n    this.config = config;\n  }\n\n  /**\n   * Resize the image to make a thumbnail. The image is resized so that no dimension is larger than any\n   * corresponding dimension of the specified size.\n   * @param {RawImage} image The image to be resized.\n   * @param {{height:number, width:number}} size The size `{\"height\": h, \"width\": w}` to resize the image to.\n   * @param {string | 0 | 1 | 2 | 3 | 4 | 5} [resample=2] The resampling filter to use.\n   * @returns {Promise<RawImage>} The resized image.\n   */\n  async thumbnail(image: RawImage, size: { height: number; width: number }, resample = 2) {\n    const input_height = image.height;\n    const input_width = image.width;\n\n    const output_height = size.height;\n    const output_width = size.width;\n\n    // We always resize to the smallest of either the input or output size.\n    let height = Math.min(input_height, output_height);\n    let width = Math.min(input_width, output_width);\n\n    if (height === input_height && width === input_width) {\n      return image;\n    }\n    if (input_height > input_width) {\n      width = Math.floor((input_width * height) / input_height);\n    } else if (input_width > input_height) {\n      height = Math.floor((input_height * width) / input_width);\n    }\n    return await image.resize(width, height, { resample });\n  }\n\n  /**\n   * Crops the margin of the image. Gray pixels are considered margin (i.e., pixels with a value below the threshold).\n   * @param {RawImage} image The image to be cropped.\n   * @param {number} gray_threshold Value below which pixels are considered to be gray.\n   * @returns {Promise<RawImage>} The cropped image.\n   */\n  async crop_margin(image: RawImage, gray_threshold = 200) {\n    const gray_image = image.clone().grayscale();\n\n    const minValue = min(gray_image.data)[0];\n    const maxValue = max(gray_image.data)[0];\n    const diff = BigInt(maxValue) - BigInt(minValue);\n\n    if (Number(diff) === 0) {\n      return image;\n    }\n\n    const threshold = gray_threshold / 255;\n\n    let x_min = gray_image.width,\n      y_min = gray_image.height,\n      x_max = 0,\n      y_max = 0;\n    const gray_image_data = gray_image.data;\n    for (let j = 0; j < gray_image.height; ++j) {\n      const row = j * gray_image.width;\n      for (let i = 0; i < gray_image.width; ++i) {\n        if ((Number(gray_image_data[row + i]) - Number(minValue)) / Number(diff) < threshold) {\n          // We have a non-zero pixel, so we update the min/max values accordingly\n          x_min = Math.min(x_min, i);\n          y_min = Math.min(y_min, j);\n          x_max = Math.max(x_max, i);\n          y_max = Math.max(y_max, j);\n        }\n      }\n    }\n\n    image = await image.crop([x_min, y_min, x_max, y_max]);\n    return image;\n  }\n\n  /**\n   * Pad the image by a certain amount.\n   * @param {Float32Array} pixelData The pixel data to pad.\n   * @param {number[]} imgDims The dimensions of the image (height, width, channels).\n   * @param {{width:number; height:number}|number|'square'} padSize The dimensions of the padded image.\n   * @param {Object} options The options for padding.\n   * @param {'constant'|'symmetric'} [options.mode='constant'] The type of padding to add.\n   * @param {boolean} [options.center=false] Whether to center the image.\n   * @param {number|number[]} [options.constant_values=0] The constant value to use for padding.\n   * @returns {[Float32Array, number[]]} The padded pixel data and image dimensions.\n   */\n  pad_image(\n    pixelData: Float32Array,\n    imgDims: number[],\n    padSize: number | { height: number; width: number } | 'square',\n    constant_values: number | number[] = 0,\n    mode: 'constant' | 'symmetric' = 'constant',\n    center: boolean = false,\n  ): [Float32Array, number[]] {\n    const [imageHeight, imageWidth, imageChannels] = imgDims;\n\n    let paddedImageWidth, paddedImageHeight;\n    if (typeof padSize === 'number') {\n      paddedImageWidth = padSize;\n      paddedImageHeight = padSize;\n    } else if (padSize === 'square') {\n      paddedImageWidth = paddedImageHeight = Math.max(imageHeight, imageWidth);\n    } else {\n      paddedImageWidth = padSize.width;\n      paddedImageHeight = padSize.height;\n    }\n\n    // Only add padding if there is a difference in size\n    if (paddedImageWidth !== imageWidth || paddedImageHeight !== imageHeight) {\n      const paddedPixelData = new Float32Array(paddedImageWidth * paddedImageHeight * imageChannels);\n      if (Array.isArray(constant_values)) {\n        // Fill with constant values, cycling through the array\n        for (let i = 0; i < paddedPixelData.length; ++i) {\n          paddedPixelData[i] = constant_values[i % imageChannels];\n        }\n      } else if (constant_values !== 0) {\n        paddedPixelData.fill(constant_values);\n      }\n\n      const [left, top] = center\n        ? [Math.floor((paddedImageWidth - imageWidth) / 2), Math.floor((paddedImageHeight - imageHeight) / 2)]\n        : [0, 0];\n\n      // Copy the original image into the padded image\n      for (let i = 0; i < imageHeight; ++i) {\n        const a = (i + top) * paddedImageWidth;\n        const b = i * imageWidth;\n        for (let j = 0; j < imageWidth; ++j) {\n          const c = (a + j + left) * imageChannels;\n          const d = (b + j) * imageChannels;\n          for (let k = 0; k < imageChannels; ++k) {\n            paddedPixelData[c + k] = pixelData[d + k];\n          }\n        }\n      }\n\n      if (mode === 'symmetric') {\n        if (center) {\n          throw new Error('`center` padding is not supported when `mode` is set to `symmetric`.');\n          // TODO: Implement this\n        }\n        const h1 = imageHeight - 1;\n        const w1 = imageWidth - 1;\n        for (let i = 0; i < paddedImageHeight; ++i) {\n          const a = i * paddedImageWidth;\n          const b = calculateReflectOffset(i, h1) * imageWidth;\n\n          for (let j = 0; j < paddedImageWidth; ++j) {\n            if (i < imageHeight && j < imageWidth) continue; // Do not overwrite original image\n            const c = (a + j) * imageChannels;\n            const d = (b + calculateReflectOffset(j, w1)) * imageChannels;\n\n            // Copy channel-wise\n            for (let k = 0; k < imageChannels; ++k) {\n              paddedPixelData[c + k] = pixelData[d + k];\n            }\n          }\n        }\n      }\n\n      // Update pixel data and image dimensions\n      pixelData = paddedPixelData;\n      imgDims = [paddedImageHeight, paddedImageWidth, imageChannels];\n    }\n    return [pixelData, imgDims];\n  }\n\n  /**\n   * Rescale the image' pixel values by `this.rescale_factor`.\n   * @param {Float32Array} pixelData The pixel data to rescale.\n   * @returns {void}\n   */\n  rescale(pixelData: Float32Array) {\n    for (let i = 0; i < pixelData.length; ++i) {\n      pixelData[i] = this.rescale_factor * pixelData[i];\n    }\n  }\n\n  /**\n   * Find the target (width, height) dimension of the output image after\n   * resizing given the input image and the desired size.\n   * @param {RawImage} image The image to resize.\n   * @param {any} size The size to use for resizing the image.\n   * @returns {[number, number]} The target (width, height) dimension of the output image after resizing.\n   */\n  get_resize_output_image_size(image: RawImage, size: any) {\n    // `size` comes in many forms, so we need to handle them all here:\n    // 1. `size` is an integer, in which case we resize the image to be a square\n\n    const [srcWidth, srcHeight] = image.size;\n\n    let shortest_edge;\n    let longest_edge;\n\n    if (this.do_thumbnail) {\n      // NOTE: custom logic for `Donut` models\n      const { height, width } = size;\n      shortest_edge = Math.min(height, width);\n    }\n    // Support both formats for backwards compatibility\n    else if (Number.isInteger(size)) {\n      shortest_edge = size;\n      // @ts-expect-error TS2339\n      longest_edge = this.config.max_size ?? shortest_edge;\n    } else if (size !== undefined) {\n      // Extract known properties from `size`\n      shortest_edge = size.shortest_edge;\n      longest_edge = size.longest_edge;\n    }\n\n    // If `longest_edge` and `shortest_edge` are set, maintain aspect ratio and resize to `shortest_edge`\n    // while keeping the largest dimension <= `longest_edge`\n    if (shortest_edge !== undefined || longest_edge !== undefined) {\n      // http://opensourcehacker.com/2011/12/01/calculate-aspect-ratio-conserving-resize-for-images-in-javascript/\n      // Try resize so that shortest edge is `shortest_edge` (target)\n      const shortResizeFactor =\n        shortest_edge === undefined\n          ? 1 // If `shortest_edge` is not set, don't upscale\n          : Math.max(shortest_edge / srcWidth, shortest_edge / srcHeight);\n\n      const newWidth = srcWidth * shortResizeFactor;\n      const newHeight = srcHeight * shortResizeFactor;\n\n      // The new width and height might be greater than `longest_edge`, so\n      // we downscale again to ensure the largest dimension is `longest_edge`\n      const longResizeFactor =\n        longest_edge === undefined\n          ? 1 // If `longest_edge` is not set, don't downscale\n          : Math.min(longest_edge / newWidth, longest_edge / newHeight);\n\n      // To avoid certain floating point precision issues, we round to 2 decimal places\n      let finalWidth = Math.floor(Number((newWidth * longResizeFactor).toFixed(2)));\n      let finalHeight = Math.floor(Number((newHeight * longResizeFactor).toFixed(2)));\n\n      if (this.size_divisibility !== undefined) {\n        [finalWidth, finalHeight] = enforce_size_divisibility([finalWidth, finalHeight], this.size_divisibility);\n      }\n      return [finalWidth, finalHeight];\n    } else if (size !== undefined && size.width !== undefined && size.height !== undefined) {\n      // If `width` and `height` are set, resize to those dimensions\n\n      let newWidth = size.width;\n      let newHeight = size.height;\n\n      // Custom for DPT models\n      if (this.config.keep_aspect_ratio && this.config.ensure_multiple_of) {\n        // determine new height and width\n        let scale_height = newHeight / srcHeight;\n        let scale_width = newWidth / srcWidth;\n\n        // scale as little as possible\n        if (Math.abs(1 - scale_width) < Math.abs(1 - scale_height)) {\n          // fit width\n          scale_height = scale_width;\n        } else {\n          // fit height\n          scale_width = scale_height;\n        }\n\n        newHeight = constraint_to_multiple_of(scale_height * srcHeight, this.config.ensure_multiple_of);\n        newWidth = constraint_to_multiple_of(scale_width * srcWidth, this.config.ensure_multiple_of);\n      }\n\n      return [newWidth, newHeight];\n    } else if (this.size_divisibility !== undefined) {\n      return enforce_size_divisibility([srcWidth, srcHeight], this.size_divisibility);\n    } else if (size.min_pixels !== undefined && size.max_pixels !== undefined) {\n      // Custom resize logic for Qwen2-VL models\n      const { min_pixels, max_pixels } = size;\n      // @ts-expect-error TS2339\n      const factor = this.config.patch_size * this.config.merge_size;\n      return smart_resize(srcHeight, srcWidth, factor, min_pixels, max_pixels);\n    } else {\n      throw new Error(\n        `Could not resize image due to unsupported \\`this.size\\` option in config: ${JSON.stringify(size)}`,\n      );\n    }\n  }\n\n  /**\n   * Resizes the image.\n   * @param {RawImage} image The image to resize.\n   * @returns {Promise<RawImage>} The resized image.\n   */\n  async resize(image: RawImage) {\n    const [newWidth, newHeight] = this.get_resize_output_image_size(image, this.size);\n    return await image.resize(newWidth, newHeight, {\n      resample: this.resample,\n    });\n  }\n\n  /**\n   * @typedef {object} PreprocessedImage\n   * @property {HeightWidth} original_size The original size of the image.\n   * @property {HeightWidth} reshaped_input_size The reshaped input size of the image.\n   * @property {Tensor} pixel_values The pixel values of the preprocessed image.\n   */\n\n  /**\n   * Preprocesses the given image.\n   *\n   * @param {RawImage} image The image to preprocess.\n   * @param {Object} overrides The overrides for the preprocessing options.\n   * @returns {Promise<PreprocessedImage>} The preprocessed image.\n   */\n  async preprocess(\n    image: RawImage,\n    {\n      do_normalize = null,\n      do_pad = null,\n      do_convert_rgb = null,\n      do_convert_grayscale = null,\n      do_flip_channel_order = null,\n    } = {},\n  ) {\n    if (this.do_crop_margin) {\n      // NOTE: Specific to nougat processors. This is done before resizing,\n      // and can be interpreted as a pre-preprocessing step.\n      image = await this.crop_margin(image);\n    }\n\n    const [srcWidth, srcHeight] = image.size; // original image size\n\n    // Convert image to RGB if specified in config.\n    if (do_convert_rgb ?? this.do_convert_rgb) {\n      image = image.rgb();\n    } else if (do_convert_grayscale) {\n      image = image.grayscale();\n    }\n\n    // TODO:\n    // For efficiency reasons, it might be best to merge the resize and center crop operations into one.\n\n    // Resize all images\n    if (this.do_resize) {\n      image = await this.resize(image);\n    }\n\n    // Resize the image using thumbnail method.\n    if (this.do_thumbnail) {\n      // @ts-expect-error TS2345\n      image = await this.thumbnail(image, this.size, this.resample);\n    }\n\n    if (this.do_center_crop) {\n      let crop_width;\n      let crop_height;\n      if (Number.isInteger(this.crop_size)) {\n        crop_width = this.crop_size;\n        crop_height = this.crop_size;\n      } else if (typeof this.crop_size === 'object' && this.crop_size !== null) {\n        crop_width = this.crop_size.width;\n        crop_height = this.crop_size.height;\n      }\n\n      image = await image.center_crop(crop_width as number, crop_height as number);\n    }\n\n    /** @type {HeightWidth} */\n    const reshaped_input_size = [image.height, image.width];\n\n    // NOTE: All pixel-level manipulation (i.e., modifying `pixelData`)\n    // occurs with data in the hwc format (height, width, channels),\n    // to emulate the behavior of the original Python code (w/ numpy).\n    /** @type {Float32Array} */\n    let pixelData = Float32Array.from(image.data);\n    let imgDims = [image.height, image.width, image.channels];\n\n    if (this.do_rescale) {\n      this.rescale(pixelData);\n    }\n\n    if (do_normalize ?? this.do_normalize) {\n      let image_mean = this.image_mean;\n      if (!Array.isArray(this.image_mean)) {\n        image_mean = new Array(image.channels).fill(image_mean);\n      }\n\n      let image_std = this.image_std;\n      if (!Array.isArray(this.image_std)) {\n        image_std = new Array(image.channels).fill(image_mean);\n      }\n\n      if (!image_mean || !image_std) {\n        throw new Error('image_mean and image_std must be defined when normalizing');\n      }\n\n      if (image_mean.length !== image.channels || image_std.length !== image.channels) {\n        throw new Error(\n          `When set to arrays, the length of \\`image_mean\\` (${image_mean.length}) and \\`image_std\\` (${image_std.length}) must match the number of channels in the image (${image.channels}).`,\n        );\n      }\n\n      for (let i = 0; i < pixelData.length; i += image.channels) {\n        for (let j = 0; j < image.channels; ++j) {\n          pixelData[i + j] = (pixelData[i + j] - image_mean[j]) / image_std[j];\n        }\n      }\n    }\n\n    // do padding after rescaling/normalizing\n    if (do_pad ?? this.do_pad) {\n      if (this.pad_size) {\n        const padded = this.pad_image(pixelData, [image.height, image.width, image.channels], this.pad_size);\n        [pixelData, imgDims] = padded as [Float32Array, number[]];\n      } else if (this.size_divisibility) {\n        const [paddedWidth, paddedHeight] = enforce_size_divisibility([imgDims[1], imgDims[0]], this.size_divisibility);\n        [pixelData, imgDims] = this.pad_image(pixelData, imgDims, { width: paddedWidth, height: paddedHeight });\n      }\n    }\n\n    if (do_flip_channel_order ?? this.do_flip_channel_order) {\n      if (imgDims[2] !== 3) {\n        throw new Error('Flipping channel order is only supported for RGB images.');\n      }\n      // Convert RGB to BGR\n      for (let i = 0; i < pixelData.length; i += 3) {\n        const temp = pixelData[i];\n        pixelData[i] = pixelData[i + 2];\n        pixelData[i + 2] = temp;\n      }\n    }\n\n    const pixel_values = new Tensor('float32', pixelData, imgDims).permute(2, 0, 1); // convert to channel dimension format (hwc -> chw)\n\n    return {\n      original_size: [srcHeight, srcWidth],\n      reshaped_input_size: reshaped_input_size,\n      pixel_values,\n    };\n  }\n\n  /**\n   * Calls the feature extraction process on an array of images,\n   * preprocesses each image, and concatenates the resulting\n   * features into a single Tensor.\n   * @param {RawImage[]} images The image(s) to extract features from.\n   * @param {...any} args Additional arguments.\n   * @returns {Promise<ImageProcessorResult>} An object containing the concatenated pixel values (and other metadata) of the preprocessed images.\n   */\n  async _call(images: RawImage[], ...args: any[]) {\n    if (!Array.isArray(images)) {\n      images = [images];\n    }\n    /** @type {PreprocessedImage[]} */\n    const imageData = await Promise.all(images.map((x) => this.preprocess(x)));\n\n    // Stack pixel values\n    const pixel_values = stack(\n      imageData.map((x) => x.pixel_values),\n      0,\n    );\n\n    return {\n      pixel_values,\n\n      // Original sizes of images\n      original_sizes: imageData.map((x) => x.original_size),\n\n      // Reshaped sizes of images, before padding or cropping\n      reshaped_input_sizes: imageData.map((x) => x.reshaped_input_size),\n    };\n  }\n\n  /**\n   * Instantiate one of the processor classes of the library from a pretrained model.\n   *\n   * The processor class to instantiate is selected based on the `image_processor_type` (or `feature_extractor_type`; legacy)\n   * property of the config object (either passed as an argument or loaded from `pretrained_model_name_or_path` if possible)\n   *\n   * @param {string} pretrained_model_name_or_path The name or path of the pretrained model. Can be either:\n   * - A string, the *model id* of a pretrained processor hosted inside a model repo on huggingface.co.\n   *   Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a\n   *   user or organization name, like `dbmdz/bert-base-german-cased`.\n   * - A path to a *directory* containing processor files, e.g., `./my_model_directory/`.\n   * @param {import('../utils/hub.js').PretrainedOptions} options Additional options for loading the processor.\n   *\n   * @returns {Promise<ImageProcessor>} A new instance of the Processor class.\n   */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: PretrainedOptions) {\n    const preprocessorConfig = await getModelJSON(pretrained_model_name_or_path, IMAGE_PROCESSOR_NAME, true, options);\n    return new this(preprocessorConfig);\n  }\n}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\n\nexport class VLMImageProcessor extends ImageProcessor {\n  constructor(config) {\n    super({\n      do_pad: true,\n      pad_size: {\n        width: config.image_size,\n        height: config.image_size,\n      },\n      ...config,\n    });\n    // @ts-expect-error TS2339\n    this.constant_values = this.config.background_color.map((x) => x * this.rescale_factor);\n  }\n\n  pad_image(pixelData, imgDims, padSize, options) {\n    return super.pad_image(pixelData, imgDims, padSize, {\n      constant_values: this.constant_values,\n      center: true,\n      ...options,\n    });\n  }\n}\n","import { GITHUB_ISSUE_URL, IMAGE_PROCESSOR_NAME } from '../../utils/constants';\nimport { getModelJSON } from '../../utils/hub';\nimport { ImageProcessor } from '../../base/image_processors_utils';\nimport { VLMImageProcessor } from '../janus/image_processing_janus';\n\n// Map of processor types to their implementations\nconst PROCESSOR_MAPPING = {\n  'VLMImageProcessor': VLMImageProcessor,\n  'ImageProcessor': ImageProcessor,\n};\n\nexport class AutoImageProcessor {\n  /** @type {typeof ImageProcessor.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: Record<string, unknown> = {}) {\n    const preprocessorConfig = await getModelJSON(pretrained_model_name_or_path, IMAGE_PROCESSOR_NAME, true, options);\n\n    // Determine image processor class\n    const key = preprocessorConfig.image_processor_type ?? preprocessorConfig.feature_extractor_type;\n    let image_processor_class = ImageProcessor;\n\n    if (key && key in PROCESSOR_MAPPING) {\n      image_processor_class = PROCESSOR_MAPPING[key as keyof typeof PROCESSOR_MAPPING];\n    } else if (key !== undefined) {\n      console.warn(\n        `Image processor type '${key}' not found, assuming base ImageProcessor. Please report this at ${GITHUB_ISSUE_URL}.`\n      );\n    }\n\n    // Instantiate image processor\n    return new image_processor_class(preprocessorConfig);\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { AutoImageProcessor } from '../auto/image_processing_auto.js';\nimport { AutoTokenizer } from '../../tokenizers.js';\n\nexport class Florence2Processor extends Processor {\n  static tokenizer_class = AutoTokenizer;\n  static image_processor_class = AutoImageProcessor;\n\n  tasks_answer_post_processing_type: Map<string, string>;\n  task_prompts_without_inputs: Map<string, string>;\n  task_prompts_with_input: Map<string, string>;\n  regexes: Record<string, RegExp>;\n  size_per_bin: number;\n\n  constructor(config: any, components: any) {\n    super(config, components);\n\n    const { tasks_answer_post_processing_type, task_prompts_without_inputs, task_prompts_with_input } =\n      this.image_processor.config;\n\n    /** @type {Map<string, string>} */\n    this.tasks_answer_post_processing_type = new Map(Object.entries(tasks_answer_post_processing_type ?? {}));\n\n    /** @type {Map<string, string>} */\n    this.task_prompts_without_inputs = new Map(Object.entries(task_prompts_without_inputs ?? {}));\n\n    /** @type {Map<string, string>} */\n    this.task_prompts_with_input = new Map(Object.entries(task_prompts_with_input ?? {}));\n\n    this.regexes = {\n      quad_boxes: /(.+?)<loc_(\\d+)><loc_(\\d+)><loc_(\\d+)><loc_(\\d+)><loc_(\\d+)><loc_(\\d+)><loc_(\\d+)><loc_(\\d+)>/gm,\n      bboxes: /([^<]+)?<loc_(\\d+)><loc_(\\d+)><loc_(\\d+)><loc_(\\d+)>/gm,\n    };\n    this.size_per_bin = 1000;\n  }\n\n  /**\n   * Helper function to construct prompts from input texts\n   * @param {string|string[]} text\n   * @returns {string[]}\n   */\n  construct_prompts(text: string | string[]) {\n    if (typeof text === 'string') {\n      text = [text];\n    }\n\n    const prompts = [];\n    for (const t of text) {\n      // 1. fixed task prompts without additional inputs\n      if (this.task_prompts_without_inputs.has(t)) {\n        prompts.push(this.task_prompts_without_inputs.get(t));\n      }\n      // 2. task prompts with additional inputs\n      else {\n        for (const [task, prompt] of this.task_prompts_with_input) {\n          if (t.includes(task)) {\n            prompts.push(prompt.replaceAll('{input}', t).replaceAll(task, ''));\n            break;\n          }\n        }\n\n        // 3. default prompt\n        if (prompts.length !== text.length) {\n          prompts.push(t);\n        }\n      }\n    }\n    return prompts;\n  }\n\n  /**\n   * Post-process the output of the model to each of the task outputs.\n   * @param {string} text The text to post-process.\n   * @param {string} task The task to post-process the text for.\n   * @param {[number, number]} image_size The size of the image. height x width.\n   */\n  post_process_generation(text: string, task: string, image_size: [number, number]) {\n    const task_answer_post_processing_type = this.tasks_answer_post_processing_type.get(task) ?? 'pure_text';\n\n    // remove the special tokens\n    text = text.replaceAll('<s>', '').replaceAll('</s>', '');\n\n    let final_answer;\n    switch (task_answer_post_processing_type) {\n      case 'pure_text':\n        final_answer = text;\n        break;\n\n      case 'description_with_bboxes':\n      case 'bboxes':\n      case 'phrase_grounding':\n      case 'ocr':\n        const key = task_answer_post_processing_type === 'ocr' ? 'quad_boxes' : 'bboxes';\n        const matches = text.matchAll(this.regexes[key]);\n        const labels: string[] = [];\n        const items: number[][] = [];\n        for (const [_, label, ...locations] of matches) {\n          // Push new label, or duplicate the last label\n          labels.push(label ? label.trim() : (labels.at(-1) ?? ''));\n          items.push(\n            locations.map(\n              (x, i) =>\n                // NOTE: Add 0.5 to use the center position of the bin as the coordinate.\n                ((Number(x) + 0.5) / this.size_per_bin) * image_size[i % 2],\n            ),\n          );\n        }\n        final_answer = { labels, [key]: items };\n        break;\n\n      default:\n        throw new Error(`Task \"${task}\" (of type \"${task_answer_post_processing_type}\") not yet implemented.`);\n    }\n\n    return { [task]: final_answer };\n  }\n\n  // NOTE: images and text are switched from the python version\n  // `images` is required, `text` is optional\n  async _call(images: any, text = null, kwargs = {}) {\n    if (!images && !text) {\n      throw new Error('Either text or images must be provided');\n    }\n\n    const image_inputs = await this.image_processor(images, kwargs);\n    const text_inputs = text ? this.tokenizer(text, kwargs) : {};\n\n    return {\n      ...image_inputs,\n      ...text_inputs,\n    };\n  }\n}\n","import { Processor } from '../../base/processing_utils';\nimport { AutoImageProcessor } from '../auto/image_processing_auto';\nimport { AutoTokenizer } from '../../tokenizers';\nimport { RawImage } from '../../utils/image';\nimport { count } from '../../utils/core';\n\n/**\n * Prompt with expanded image tokens for when the image is split into patches.\n * @private\n */\nfunction _prompt_split_image(\n  image_seq_len: number,\n  image_rows: number,\n  image_cols: number,\n  fake_token_around_image: string,\n  image_token: string,\n  global_img_token: string,\n) {\n  let text_split_images = '';\n  for (let n_h = 0; n_h < image_rows; ++n_h) {\n    for (let n_w = 0; n_w < image_cols; ++n_w) {\n      text_split_images +=\n        fake_token_around_image + `<row_${n_h + 1}_col_${n_w + 1}>` + image_token.repeat(image_seq_len);\n    }\n    text_split_images += '\\n';\n  }\n\n  text_split_images +=\n    `\\n${fake_token_around_image}` +\n    `${global_img_token}` +\n    image_token.repeat(image_seq_len) +\n    `${fake_token_around_image}`;\n  return text_split_images;\n}\n\n/**\n * Prompt with expanded image tokens for a single image.\n * @private\n */\nfunction _prompt_single_image(\n  image_seq_len: number,\n  fake_token_around_image: string,\n  image_token: string,\n  global_img_token: string,\n) {\n  return (\n    `${fake_token_around_image}` +\n    `${global_img_token}` +\n    image_token.repeat(image_seq_len) +\n    `${fake_token_around_image}`\n  );\n}\n\nfunction get_image_prompt_string(\n  image_rows: number,\n  image_cols: number,\n  image_seq_len: number,\n  fake_token_around_image: string,\n  image_token: string,\n  global_img_token: string,\n) {\n  if (image_rows === 0 && image_cols === 0) {\n    return _prompt_single_image(image_seq_len, fake_token_around_image, image_token, global_img_token);\n  }\n  return _prompt_split_image(\n    image_seq_len,\n    image_rows,\n    image_cols,\n    fake_token_around_image,\n    image_token,\n    global_img_token,\n  );\n}\n\nexport class Idefics3Processor extends Processor {\n  static image_processor_class = AutoImageProcessor;\n  static tokenizer_class = AutoTokenizer;\n  static uses_processor_config = true;\n\n  fake_image_token = '<fake_token_around_image>';\n  image_token = '<image>';\n  global_img_token = '<global-img>';\n\n  /**\n   *\n   * @param {string|string[]} text\n   * @param {RawImage|RawImage[]|RawImage[][]} images\n   * @returns {Promise<any>}\n   */\n  async _call(text: string | string[], images: RawImage | RawImage[] | RawImage[][], options: any = {}) {\n    options.return_row_col_info ??= true;\n\n    let image_inputs;\n\n    if (images) {\n      image_inputs = await this.image_processor(images, options);\n    }\n\n    // NOTE: We assume text is present\n    if (!Array.isArray(text)) {\n      text = [text];\n    }\n\n    const image_rows = image_inputs.rows ?? [new Array(text.length).fill(0)];\n    const image_cols = image_inputs.cols ?? [new Array(text.length).fill(0)];\n\n    const image_seq_len = this.config.image_seq_len;\n    const n_images_in_text = [];\n    const prompt_strings = [];\n    for (let i = 0; i < text.length; ++i) {\n      const sample = text[i];\n      const sample_rows = image_rows[i];\n      const sample_cols = image_cols[i];\n\n      n_images_in_text.push(count(sample, this.image_token));\n\n      // Replace the image token with fake tokens around the expanded image token sequence of length `image_seq_len`\n      const image_prompt_strings = sample_rows.map((n_rows: number, j: number) =>\n        get_image_prompt_string(\n          n_rows,\n          sample_cols[j],\n          image_seq_len,\n          this.fake_image_token,\n          this.image_token,\n          this.global_img_token,\n        ),\n      );\n\n      const split_sample = sample.split(this.image_token);\n      if (split_sample.length === 0) {\n        throw new Error('The image token should be present in the text.');\n      }\n\n      // Place in the image prompt strings where the image tokens are\n      let new_sample = split_sample[0];\n      for (let j = 0; j < image_prompt_strings.length; ++j) {\n        new_sample += image_prompt_strings[j] + split_sample[j + 1];\n      }\n      prompt_strings.push(new_sample);\n    }\n\n    const text_inputs = this.tokenizer(prompt_strings);\n\n    return {\n      ...text_inputs,\n      ...image_inputs,\n    };\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { AutoImageProcessor } from '../auto/image_processing_auto.js';\nimport { AutoTokenizer } from '../../tokenizers.js';\nimport { max, softmax } from '../../utils/maths.js';\n\nconst DECODE_TYPE_MAPPING = {\n  char: ['char_decode', 1],\n  bpe: ['bpe_decode', 2],\n  wp: ['wp_decode', 102],\n};\nexport class MgpstrProcessor extends Processor {\n  static tokenizer_class = AutoTokenizer;\n  static image_processor_class = AutoImageProcessor;\n\n  /**\n   * @returns {import('../../tokenizers.js').MgpstrTokenizer} The character tokenizer.\n   */\n  get char_tokenizer() {\n    return this.components.char_tokenizer;\n  }\n\n  /**\n   * @returns {import('../../tokenizers.js').GPT2Tokenizer} The BPE tokenizer.\n   */\n  get bpe_tokenizer() {\n    return this.components.bpe_tokenizer;\n  }\n\n  /**\n   * @returns {import('../../tokenizers.js').BertTokenizer} The WordPiece tokenizer.\n   */\n  get wp_tokenizer() {\n    return this.components.wp_tokenizer;\n  }\n\n  /**\n   * Helper function to decode the model prediction logits.\n   * @param {import('../../utils/tensor.js').Tensor} pred_logits Model prediction logits.\n   * @param {string} format Type of model prediction. Must be one of ['char', 'bpe', 'wp'].\n   * @returns {[string[], number[]]} The decoded sentences and their confidence scores.\n   */\n  _decode_helper(pred_logits, format) {\n    if (!DECODE_TYPE_MAPPING.hasOwnProperty(format)) {\n      throw new Error(`Format ${format} is not supported.`);\n    }\n\n    const [decoder_name, eos_token] = DECODE_TYPE_MAPPING[format];\n    const decoder = this[decoder_name].bind(this);\n\n    const [batch_size, batch_max_length] = pred_logits.dims;\n    const conf_scores = [];\n    const all_ids = [];\n\n    /** @type {number[][][]} */\n    const pred_logits_list = pred_logits.tolist();\n    for (let i = 0; i < batch_size; ++i) {\n      const logits = pred_logits_list[i];\n      const ids = [];\n      const scores = [];\n\n      // Start and index=1 to skip the first token\n      for (let j = 1; j < batch_max_length; ++j) {\n        // NOTE: == to match bigint and number\n        const [max_prob, max_prob_index] = max(softmax(logits[j]));\n        scores.push(max_prob);\n        if (max_prob_index == eos_token) {\n          break;\n        }\n        ids.push(max_prob_index);\n      }\n\n      const confidence_score = scores.length > 0 ? scores.reduce((a, b) => a * b, 1) : 0;\n\n      all_ids.push(ids);\n      conf_scores.push(confidence_score);\n    }\n\n    const decoded = decoder(all_ids);\n    return [decoded, conf_scores];\n  }\n\n  /**\n   * Convert a list of lists of char token ids into a list of strings by calling char tokenizer.\n   * @param {number[][]} sequences List of tokenized input ids.\n   * @returns {string[]} The list of char decoded sentences.\n   */\n  char_decode(sequences) {\n    return this.char_tokenizer.batch_decode(sequences).map((str) => str.replaceAll(' ', ''));\n  }\n\n  /**\n   * Convert a list of lists of BPE token ids into a list of strings by calling BPE tokenizer.\n   * @param {number[][]} sequences List of tokenized input ids.\n   * @returns {string[]} The list of BPE decoded sentences.\n   */\n  bpe_decode(sequences) {\n    return this.bpe_tokenizer.batch_decode(sequences);\n  }\n\n  /**\n   * Convert a list of lists of word piece token ids into a list of strings by calling word piece tokenizer.\n   * @param {number[][]} sequences List of tokenized input ids.\n   * @returns {string[]} The list of wp decoded sentences.\n   */\n  wp_decode(sequences) {\n    return this.wp_tokenizer.batch_decode(sequences).map((str) => str.replaceAll(' ', ''));\n  }\n\n  /**\n   * Convert a list of lists of token ids into a list of strings by calling decode.\n   * @param {import('../../utils/tensor.js').Tensor[]} sequences List of tokenized input ids.\n   * @returns {{generated_text: string[], scores: number[], char_preds: string[], bpe_preds: string[], wp_preds: string[]}}\n   * Dictionary of all the outputs of the decoded results.\n   * - generated_text: The final results after fusion of char, bpe, and wp.\n   * - scores: The final scores after fusion of char, bpe, and wp.\n   * - char_preds: The list of character decoded sentences.\n   * - bpe_preds: The list of BPE decoded sentences.\n   * - wp_preds: The list of wp decoded sentences.\n   */\n  // @ts-expect-error The type of this method is not compatible with the one\n  // in the base class. It might be a good idea to fix this.\n  batch_decode([char_logits, bpe_logits, wp_logits]) {\n    const [char_preds, char_scores] = this._decode_helper(char_logits, 'char');\n    const [bpe_preds, bpe_scores] = this._decode_helper(bpe_logits, 'bpe');\n    const [wp_preds, wp_scores] = this._decode_helper(wp_logits, 'wp');\n\n    const generated_text = [];\n    const scores = [];\n    for (let i = 0; i < char_preds.length; ++i) {\n      const [max_score, max_score_index] = max([char_scores[i], bpe_scores[i], wp_scores[i]]);\n      generated_text.push([char_preds[i], bpe_preds[i], wp_preds[i]][max_score_index]);\n      scores.push(max_score);\n    }\n\n    return {\n      generated_text,\n      scores,\n      char_preds,\n      bpe_preds,\n      wp_preds,\n    };\n  }\n  /** @type {typeof Processor.from_pretrained} */\n  static async from_pretrained(...args) {\n    const base = await super.from_pretrained(...args);\n\n    // Load Transformers.js-compatible versions of the BPE and WordPiece tokenizers\n    const bpe_tokenizer = await AutoTokenizer.from_pretrained('Xenova/gpt2'); // openai-community/gpt2\n    const wp_tokenizer = await AutoTokenizer.from_pretrained('Xenova/bert-base-uncased'); // google-bert/bert-base-uncased\n\n    // Update components\n    base.components = {\n      image_processor: base.image_processor,\n      char_tokenizer: base.tokenizer,\n      bpe_tokenizer: bpe_tokenizer,\n      wp_tokenizer: wp_tokenizer,\n    };\n    return base;\n  }\n\n  async _call(images, text = null) {\n    const result = await this.image_processor(images);\n\n    if (text) {\n      result.labels = this.tokenizer(text).input_ids;\n    }\n\n    return result;\n  }\n}\n","export * from './audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer';\nexport * from './clap/feature_extraction_clap';\nexport * from './moonshine/feature_extraction_moonshine';\nexport * from './pyannote/feature_extraction_pyannote';\nexport * from './seamless_m4t/feature_extraction_seamless_m4t';\nexport * from './speecht5/feature_extraction_speecht5';\nexport * from './wav2vec2/feature_extraction_wav2vec2';\nexport * from './wespeaker/feature_extraction_wespeaker';\nexport * from './whisper/feature_extraction_whisper';\n\n// For legacy support, ImageFeatureExtractor is an alias for ImageProcessor\nexport { ImageProcessor as ImageFeatureExtractor } from '../base/image_processors_utils';\n","import { FEATURE_EXTRACTOR_NAME } from '../utils/constants';\nimport { Callable } from '../utils/generic';\nimport { getModelJSON } from '../utils/hub';\nimport { PretrainedOptions } from '../utils/hub';\ninterface FeatureExtractorConfig {\n  feature_extractor_type: string;\n  [key: string]: any; // Allow for additional properties\n}\n\n/**\n * Base class for feature extractors.\n */\nexport class FeatureExtractor extends Callable {\n  protected config: FeatureExtractorConfig;\n\n  /**\n   * Constructs a new FeatureExtractor instance.\n   *\n   * @param {Object} config The configuration for the feature extractor.\n   */\n  constructor(config: FeatureExtractorConfig) {\n    super();\n    this.config = config;\n  }\n\n  /**\n   * Instantiate one of the feature extractor classes of the library from a pretrained model.\n   *\n   * The feature extractor class to instantiate is selected based on the `feature_extractor_type` property of\n   * the config object (either passed as an argument or loaded from `pretrained_model_name_or_path` if possible)\n   *\n   * @param {string} pretrained_model_name_or_path The name or path of the pretrained model. Can be either:\n   * - A string, the *model id* of a pretrained feature_extractor hosted inside a model repo on huggingface.co.\n   *   Valid model ids can be located at the root-level, like `bert-base-uncased`, or namespaced under a\n   *   user or organization name, like `dbmdz/bert-base-german-cased`.\n   * - A path to a *directory* containing feature_extractor files, e.g., `./my_model_directory/`.\n   * @param {import('../utils/hub.js').PretrainedOptions} options Additional options for loading the feature_extractor.\n   *\n   * @returns {Promise<FeatureExtractor>} A new instance of the Feature Extractor class.\n   */\n  static async from_pretrained(pretrained_model_name_or_path: string, options: PretrainedOptions) {\n    const config = await getModelJSON(pretrained_model_name_or_path, FEATURE_EXTRACTOR_NAME, true, options);\n    return new this(config);\n  }\n}\n\n/**\n * Helper function to validate audio inputs.\n * @param {any} audio The audio data.\n * @param {string} feature_extractor The name of the feature extractor.\n * @private\n */\nexport function validate_audio_inputs(audio: any, feature_extractor: string) {\n  if (!(audio instanceof Float32Array || audio instanceof Float64Array)) {\n    throw new Error(\n      `${feature_extractor} expects input to be a Float32Array or a Float64Array, but got ${audio?.constructor?.name ?? typeof audio} instead. ` +\n        `If using the feature extractor directly, remember to use \\`read_audio(url, sampling_rate)\\` to obtain the raw audio data of the file/url.`,\n    );\n  }\n}\n","/**\n * @file Helper module for audio processing.\n *\n * These functions and classes are only used internally,\n * meaning an end-user shouldn't need to access anything here.\n *\n * @module utils/audio\n */\n\nimport { getFile } from './hub';\nimport { FFT, max } from './maths';\nimport { calculateReflectOffset, saveBlob } from './core';\nimport { Tensor, matmul } from './tensor';\nimport { apis } from '../env';\n\n/**\n * Helper function to read audio from a path/URL.\n * @param {string|URL} url The path/URL to load the audio from.\n * @param {number} sampling_rate The sampling rate to use when decoding the audio.\n * @returns {Promise<Float32Array>} The decoded audio as a `Float32Array`.\n */\nexport async function read_audio(url: string | URL, sampling_rate: number) {\n  if (typeof AudioContext === 'undefined') {\n    // Running in node or an environment without AudioContext\n    throw Error(\n      'Unable to load audio from path/URL since `AudioContext` is not available in your environment. ' +\n        'Instead, audio data should be passed directly to the pipeline/processor. ' +\n        'For more information and some example code, see https://huggingface.co/docs/transformers.js/guides/node-audio-processing.',\n    );\n  }\n\n  const response = await (await getFile(url)).arrayBuffer();\n  const audioCTX = new AudioContext({ sampleRate: sampling_rate });\n  if (typeof sampling_rate === 'undefined') {\n    console.warn(`No sampling rate provided, using default of ${audioCTX.sampleRate}Hz.`);\n  }\n  const decoded = await audioCTX.decodeAudioData(response);\n\n  /** @type {Float32Array} */\n  let audio;\n\n  // We now replicate HuggingFace's `ffmpeg_read` method:\n  if (decoded.numberOfChannels === 2) {\n    // When downmixing a stereo audio file to mono using the -ac 1 option in FFmpeg,\n    // the audio signal is summed across both channels to create a single mono channel.\n    // However, if the audio is at full scale (i.e. the highest possible volume level),\n    // the summing of the two channels can cause the audio signal to clip or distort.\n\n    // To prevent this clipping, FFmpeg applies a scaling factor of 1/sqrt(2) (~ 0.707)\n    // to the audio signal before summing the two channels. This scaling factor ensures\n    // that the combined audio signal will not exceed the maximum possible level, even\n    // if both channels are at full scale.\n\n    // After applying this scaling factor, the audio signal from both channels is summed\n    // to create a single mono channel. It's worth noting that this scaling factor is\n    // only applied when downmixing stereo audio to mono using the -ac 1 option in FFmpeg.\n    // If you're using a different downmixing method, or if you're not downmixing the\n    // audio at all, this scaling factor may not be needed.\n    const SCALING_FACTOR = Math.sqrt(2);\n\n    const left = decoded.getChannelData(0);\n    const right = decoded.getChannelData(1);\n\n    audio = new Float32Array(left.length);\n    for (let i = 0; i < decoded.length; ++i) {\n      audio[i] = (SCALING_FACTOR * (left[i] + right[i])) / 2;\n    }\n  } else {\n    // If the audio is not stereo, we can just use the first channel:\n    audio = decoded.getChannelData(0);\n  }\n\n  return audio;\n}\n\n/**\n * Helper function to generate windows that are special cases of the generalized cosine window.\n * See https://www.mathworks.com/help/signal/ug/generalized-cosine-windows.html for more information.\n * @param {number} M Number of points in the output window. If zero or less, an empty array is returned.\n * @param {number} a_0 Offset for the generalized cosine window.\n * @returns {Float64Array} The generated window.\n */\nfunction generalized_cosine_window(M: number, a_0: number) {\n  if (M < 1) {\n    return new Float64Array();\n  }\n  if (M === 1) {\n    return new Float64Array([1]);\n  }\n\n  const a_1 = 1 - a_0;\n  const factor = (2 * Math.PI) / (M - 1);\n\n  const cos_vals = new Float64Array(M);\n  for (let i = 0; i < M; ++i) {\n    cos_vals[i] = a_0 - a_1 * Math.cos(i * factor);\n  }\n  return cos_vals;\n}\n\n/**\n * Generates a Hanning window of length M.\n * See https://numpy.org/doc/stable/reference/generated/numpy.hanning.html for more information.\n *\n * @param {number} M The length of the Hanning window to generate.\n * @returns {Float64Array} The generated Hanning window.\n */\nexport function hanning(M: number) {\n  return generalized_cosine_window(M, 0.5);\n}\n\n/**\n * Generates a Hamming window of length M.\n * See https://numpy.org/doc/stable/reference/generated/numpy.hamming.html for more information.\n *\n * @param {number} M The length of the Hamming window to generate.\n * @returns {Float64Array} The generated Hamming window.\n */\nexport function hamming(M: number) {\n  return generalized_cosine_window(M, 0.54);\n}\n\nconst HERTZ_TO_MEL_MAPPING: { [key: string]: (freq: number) => number } = {\n  htk: (freq: number) => 2595.0 * Math.log10(1.0 + freq / 700.0),\n  kaldi: (freq: number) => 1127.0 * Math.log(1.0 + freq / 700.0),\n  slaney: (freq: number, min_log_hertz = 1000.0, min_log_mel = 15.0, logstep = 27.0 / Math.log(6.4)) =>\n    freq >= min_log_hertz ? min_log_mel + Math.log(freq / min_log_hertz) * logstep : (3.0 * freq) / 200.0,\n};\n\n/**\n * @template {Float32Array|Float64Array|number} T\n * @param {T} freq\n * @param {string} [mel_scale]\n * @returns {T}\n */\nfunction hertz_to_mel<T extends Float32Array | Float64Array | number>(freq: T, mel_scale = 'htk') {\n  const fn = HERTZ_TO_MEL_MAPPING[mel_scale];\n  if (!fn) {\n    throw new Error('mel_scale should be one of \"htk\", \"slaney\" or \"kaldi\".');\n  }\n\n  return typeof freq === 'number' ? fn(freq) : freq.map((x: number) => fn(x));\n}\n\nconst MEL_TO_HERTZ_MAPPING: { [key: string]: (mels: number) => number } = {\n  htk: (mels: number) => 700.0 * (10.0 ** (mels / 2595.0) - 1.0),\n  kaldi: (mels: number) => 700.0 * (Math.exp(mels / 1127.0) - 1.0),\n  slaney: (mels: number, min_log_hertz = 1000.0, min_log_mel = 15.0, logstep = Math.log(6.4) / 27.0) =>\n    mels >= min_log_mel ? min_log_hertz * Math.exp(logstep * (mels - min_log_mel)) : (200.0 * mels) / 3.0,\n};\n\n/**\n * @template {Float32Array|Float64Array|number} T\n * @param {T} mels\n * @param {string} [mel_scale]\n * @returns {T}\n */\nfunction mel_to_hertz<T extends Float32Array | Float64Array | number>(mels: T, mel_scale = 'htk') {\n  const fn = MEL_TO_HERTZ_MAPPING[mel_scale];\n  if (!fn) {\n    throw new Error('mel_scale should be one of \"htk\", \"slaney\" or \"kaldi\".');\n  }\n\n  return typeof mels === 'number' ? fn(mels) : mels.map((x) => fn(x));\n}\n\n/**\n * Creates a triangular filter bank.\n *\n * Adapted from torchaudio and librosa.\n *\n * @param {Float64Array} fft_freqs Discrete frequencies of the FFT bins in Hz, of shape `(num_frequency_bins,)`.\n * @param {Float64Array} filter_freqs Center frequencies of the triangular filters to create, in Hz, of shape `(num_mel_filters,)`.\n * @returns {number[][]} of shape `(num_frequency_bins, num_mel_filters)`.\n */\nfunction _create_triangular_filter_bank(fft_freqs: Float64Array, filter_freqs: Float64Array) {\n  const filter_diff = Float64Array.from(\n    { length: filter_freqs.length - 1 },\n    (_, i) => filter_freqs[i + 1] - filter_freqs[i],\n  );\n\n  const slopes = Array.from(\n    {\n      length: fft_freqs.length,\n    },\n    () => new Array(filter_freqs.length),\n  );\n\n  for (let j = 0; j < fft_freqs.length; ++j) {\n    const slope = slopes[j];\n    for (let i = 0; i < filter_freqs.length; ++i) {\n      slope[i] = filter_freqs[i] - fft_freqs[j];\n    }\n  }\n\n  const numFreqs = filter_freqs.length - 2;\n  const ret = Array.from({ length: numFreqs }, () => new Array(fft_freqs.length));\n\n  for (let j = 0; j < fft_freqs.length; ++j) {\n    // 201\n    const slope = slopes[j];\n    for (let i = 0; i < numFreqs; ++i) {\n      // 80\n      const down = -slope[i] / filter_diff[i];\n      const up = slope[i + 2] / filter_diff[i + 1];\n      ret[i][j] = Math.max(0, Math.min(down, up));\n    }\n  }\n  return ret;\n}\n\n/**\n * Return evenly spaced numbers over a specified interval.\n * @param {number} start The starting value of the sequence.\n * @param {number} end The end value of the sequence.\n * @param {number} num Number of samples to generate.\n * @returns `num` evenly spaced samples, calculated over the interval `[start, stop]`.\n */\nfunction linspace(start: number, end: number, num: number) {\n  const step = (end - start) / (num - 1);\n  return Float64Array.from({ length: num }, (_, i) => start + step * i);\n}\n\n/**\n * Creates a frequency bin conversion matrix used to obtain a mel spectrogram. This is called a *mel filter bank*, and\n * various implementation exist, which differ in the number of filters, the shape of the filters, the way the filters\n * are spaced, the bandwidth of the filters, and the manner in which the spectrum is warped. The goal of these\n * features is to approximate the non-linear human perception of the variation in pitch with respect to the frequency.\n * @param {number} num_frequency_bins Number of frequencies used to compute the spectrogram (should be the same as in `stft`).\n * @param {number} num_mel_filters Number of mel filters to generate.\n * @param {number} min_frequency Lowest frequency of interest in Hz.\n * @param {number} max_frequency Highest frequency of interest in Hz. This should not exceed `sampling_rate / 2`.\n * @param {number} sampling_rate Sample rate of the audio waveform.\n * @param {string} [norm] If `\"slaney\"`, divide the triangular mel weights by the width of the mel band (area normalization).\n * @param {string} [mel_scale] The mel frequency scale to use, `\"htk\"` or `\"slaney\"`.\n * @param {boolean} [triangularize_in_mel_space] If this option is enabled, the triangular filter is applied in mel space rather than frequency space.\n * This should be set to `true` in order to get the same results as `torchaudio` when computing mel filters.\n * @returns {number[][]} Triangular filter bank matrix, which is a 2D array of shape (`num_frequency_bins`, `num_mel_filters`).\n * This is a projection matrix to go from a spectrogram to a mel spectrogram.\n */\nexport function mel_filter_bank(\n  num_frequency_bins: number,\n  num_mel_filters: number,\n  min_frequency: number,\n  max_frequency: number,\n  sampling_rate: number,\n  norm: string | null = null,\n  mel_scale = 'htk',\n  triangularize_in_mel_space = false,\n) {\n  if (norm !== null && norm !== 'slaney') {\n    throw new Error('norm must be one of null or \"slaney\"');\n  }\n\n  const mel_min: any = hertz_to_mel(min_frequency, mel_scale);\n  const mel_max: any = hertz_to_mel(max_frequency, mel_scale);\n  const mel_freqs: any = linspace(mel_min, mel_max, num_mel_filters + 2);\n\n  let filter_freqs: any = mel_to_hertz(mel_freqs, mel_scale);\n  let fft_freqs: any; // frequencies of FFT bins in Hz\n\n  if (triangularize_in_mel_space) {\n    const fft_bin_width = sampling_rate / (num_frequency_bins * 2);\n    fft_freqs = hertz_to_mel(\n      Float64Array.from({ length: num_frequency_bins }, (_, i) => i * fft_bin_width),\n      mel_scale,\n    );\n    filter_freqs = mel_freqs;\n  } else {\n    fft_freqs = linspace(0, Math.floor(sampling_rate / 2), num_frequency_bins);\n  }\n\n  const mel_filters = _create_triangular_filter_bank(fft_freqs, filter_freqs);\n\n  if (norm !== null && norm === 'slaney') {\n    // Slaney-style mel is scaled to be approx constant energy per channel\n    for (let i = 0; i < num_mel_filters; ++i) {\n      const filter = mel_filters[i];\n      const enorm = 2.0 / (filter_freqs[i + 2] - filter_freqs[i]);\n      for (let j = 0; j < num_frequency_bins; ++j) {\n        // Apply this enorm to all frequency bins\n        filter[j] *= enorm;\n      }\n    }\n  }\n\n  // TODO warn if there is a zero row\n\n  return mel_filters;\n}\n\n/**\n * @template {Float32Array|Float64Array} T\n * Pads an array with a reflected version of itself on both ends.\n * @param {T} array The array to pad.\n * @param {number} left The amount of padding to add to the left.\n * @param {number} right The amount of padding to add to the right.\n * @returns {T} The padded array.\n */\nfunction padReflect<T extends Float32Array | Float64Array>(array: T, left: number, right: number) {\n  // @ts-ignore\n  const padded = new array.constructor(array.length + left + right);\n  const w = array.length - 1;\n\n  for (let i = 0; i < array.length; ++i) {\n    padded[left + i] = array[i];\n  }\n\n  for (let i = 1; i <= left; ++i) {\n    padded[left - i] = array[calculateReflectOffset(i, w)];\n  }\n\n  for (let i = 1; i <= right; ++i) {\n    padded[w + left + i] = array[calculateReflectOffset(w - i, w)];\n  }\n\n  return padded;\n}\n\n/**\n * Helper function to compute `amplitude_to_db` and `power_to_db`.\n * @template {Float32Array|Float64Array} T\n * @param {T} spectrogram\n * @param {number} factor\n * @param {number} reference\n * @param {number} min_value\n * @param {number} db_range\n * @returns {T}\n */\nfunction _db_conversion_helper<T extends Float32Array | Float64Array>(\n  spectrogram: T,\n  factor: number,\n  reference: number,\n  min_value: number,\n  db_range: number | null,\n) {\n  if (reference <= 0) {\n    throw new Error('reference must be greater than zero');\n  }\n\n  if (min_value <= 0) {\n    throw new Error('min_value must be greater than zero');\n  }\n\n  reference = Math.max(min_value, reference);\n\n  const logReference = Math.log10(reference);\n  for (let i = 0; i < spectrogram.length; ++i) {\n    spectrogram[i] = factor * Math.log10(Math.max(min_value, spectrogram[i]) - logReference);\n  }\n\n  if (db_range !== null) {\n    if (db_range <= 0) {\n      throw new Error('db_range must be greater than zero');\n    }\n    const maxValue = Number(max(spectrogram)[0]) - db_range;\n    for (let i = 0; i < spectrogram.length; ++i) {\n      spectrogram[i] = Math.max(spectrogram[i], maxValue);\n    }\n  }\n\n  return spectrogram;\n}\n\n/**\n * Converts an amplitude spectrogram to the decibel scale. This computes `20 * log10(spectrogram / reference)`,\n * using basic logarithm properties for numerical stability. NOTE: Operates in-place.\n *\n * The motivation behind applying the log function on the (mel) spectrogram is that humans do not hear loudness on a\n * linear scale. Generally to double the perceived volume of a sound we need to put 8 times as much energy into it.\n * This means that large variations in energy may not sound all that different if the sound is loud to begin with.\n * This compression operation makes the (mel) spectrogram features match more closely what humans actually hear.\n *\n * @template {Float32Array|Float64Array} T\n * @param {T} spectrogram The input amplitude (mel) spectrogram.\n * @param {number} [reference=1.0] Sets the input spectrogram value that corresponds to 0 dB.\n * For example, use `np.max(spectrogram)` to set the loudest part to 0 dB. Must be greater than zero.\n * @param {number} [min_value=1e-5] The spectrogram will be clipped to this minimum value before conversion to decibels,\n * to avoid taking `log(0)`. The default of `1e-5` corresponds to a minimum of -100 dB. Must be greater than zero.\n * @param {number} [db_range=null] Sets the maximum dynamic range in decibels. For example, if `db_range = 80`, the\n * difference between the peak value and the smallest value will never be more than 80 dB. Must be greater than zero.\n * @returns {T} The modified spectrogram in decibels.\n */\nfunction amplitude_to_db(spectrogram: Float32Array | Float64Array, reference = 1.0, min_value = 1e-5, db_range = null) {\n  return _db_conversion_helper(spectrogram, 20.0, reference, min_value, db_range);\n}\n\n/**\n * Converts a power spectrogram to the decibel scale. This computes `10 * log10(spectrogram / reference)`,\n * using basic logarithm properties for numerical stability. NOTE: Operates in-place.\n *\n * The motivation behind applying the log function on the (mel) spectrogram is that humans do not hear loudness on a\n * linear scale. Generally to double the perceived volume of a sound we need to put 8 times as much energy into it.\n * This means that large variations in energy may not sound all that different if the sound is loud to begin with.\n * This compression operation makes the (mel) spectrogram features match more closely what humans actually hear.\n *\n * Based on the implementation of `librosa.power_to_db`.\n *\n * @template {Float32Array|Float64Array} T\n * @param {T} spectrogram The input power (mel) spectrogram. Note that a power spectrogram has the amplitudes squared!\n * @param {number} [reference=1.0] Sets the input spectrogram value that corresponds to 0 dB.\n * For example, use `np.max(spectrogram)` to set the loudest part to 0 dB. Must be greater than zero.\n * @param {number} [min_value=1e-10] The spectrogram will be clipped to this minimum value before conversion to decibels,\n * to avoid taking `log(0)`. The default of `1e-10` corresponds to a minimum of -100 dB. Must be greater than zero.\n * @param {number} [db_range=null] Sets the maximum dynamic range in decibels. For example, if `db_range = 80`, the\n * difference between the peak value and the smallest value will never be more than 80 dB. Must be greater than zero.\n * @returns {T} The modified spectrogram in decibels.\n */\nfunction power_to_db(\n  spectrogram: Float32Array | Float64Array,\n  reference = 1.0,\n  min_value = 1e-10,\n  db_range: number | null = null,\n) {\n  return _db_conversion_helper(spectrogram, 10.0, reference, min_value, db_range);\n}\n\n/**\n * Calculates a spectrogram over one waveform using the Short-Time Fourier Transform.\n *\n * This function can create the following kinds of spectrograms:\n *   - amplitude spectrogram (`power = 1.0`)\n *   - power spectrogram (`power = 2.0`)\n *   - complex-valued spectrogram (`power = None`)\n *   - log spectrogram (use `log_mel` argument)\n *   - mel spectrogram (provide `mel_filters`)\n *   - log-mel spectrogram (provide `mel_filters` and `log_mel`)\n *\n * In this implementation, the window is assumed to be zero-padded to have the same size as the analysis frame.\n * A padded window can be obtained from `window_function()`. The FFT input buffer may be larger than the analysis frame,\n * typically the next power of two.\n *\n * @param {Float32Array|Float64Array} waveform The input waveform of shape `(length,)`. This must be a single real-valued, mono waveform.\n * @param {Float32Array|Float64Array} window The windowing function to apply of shape `(frame_length,)`, including zero-padding if necessary. The actual window length may be\n * shorter than `frame_length`, but we're assuming the array has already been zero-padded.\n * @param {number} frame_length The length of the analysis frames in samples (a.k.a., `fft_length`).\n * @param {number} hop_length The stride between successive analysis frames in samples.\n * @param {Object} options\n * @param {number} [options.fft_length=null] The size of the FFT buffer in samples. This determines how many frequency bins the spectrogram will have.\n * For optimal speed, this should be a power of two. If `null`, uses `frame_length`.\n * @param {number} [options.power=1.0] If 1.0, returns the amplitude spectrogram. If 2.0, returns the power spectrogram. If `null`, returns complex numbers.\n * @param {boolean} [options.center=true] Whether to pad the waveform so that frame `t` is centered around time `t * hop_length`. If `false`, frame\n * `t` will start at time `t * hop_length`.\n * @param {string} [options.pad_mode=\"reflect\"] Padding mode used when `center` is `true`. Possible values are: `\"constant\"` (pad with zeros),\n * `\"edge\"` (pad with edge values), `\"reflect\"` (pads with mirrored values).\n * @param {boolean} [options.onesided=true] If `true`, only computes the positive frequencies and returns a spectrogram containing `fft_length // 2 + 1`\n * frequency bins. If `false`, also computes the negative frequencies and returns `fft_length` frequency bins.\n * @param {number} [options.preemphasis=null] Coefficient for a low-pass filter that applies pre-emphasis before the DFT.\n * @param {number[][]} [options.mel_filters=null] The mel filter bank of shape `(num_freq_bins, num_mel_filters)`.\n * If supplied, applies this filter bank to create a mel spectrogram.\n * @param {number} [options.mel_floor=1e-10] Minimum value of mel frequency banks.\n * @param {string} [options.log_mel=null] How to convert the spectrogram to log scale. Possible options are:\n * `null` (don't convert), `\"log\"` (take the natural logarithm) `\"log10\"` (take the base-10 logarithm), `\"dB\"` (convert to decibels).\n * Can only be used when `power` is not `null`.\n * @param {number} [options.reference=1.0] Sets the input spectrogram value that corresponds to 0 dB. For example, use `max(spectrogram)[0]` to set\n * the loudest part to 0 dB. Must be greater than zero.\n * @param {number} [options.min_value=1e-10] The spectrogram will be clipped to this minimum value before conversion to decibels, to avoid taking `log(0)`.\n * For a power spectrogram, the default of `1e-10` corresponds to a minimum of -100 dB. For an amplitude spectrogram, the value `1e-5` corresponds to -100 dB.\n * Must be greater than zero.\n * @param {number} [options.db_range=null] Sets the maximum dynamic range in decibels. For example, if `db_range = 80`, the difference between the\n * peak value and the smallest value will never be more than 80 dB. Must be greater than zero.\n * @param {boolean} [options.remove_dc_offset=null] Subtract mean from waveform on each frame, applied before pre-emphasis. This should be set to `true` in\n * order to get the same results as `torchaudio.compliance.kaldi.fbank` when computing mel filters.\n * @param {number} [options.max_num_frames=null] If provided, limits the number of frames to compute to this value.\n * @param {number} [options.min_num_frames=null] If provided, ensures the number of frames to compute is at least this value.\n * @param {boolean} [options.do_pad=true] If `true`, pads the output spectrogram to have `max_num_frames` frames.\n * @param {boolean} [options.transpose=false] If `true`, the returned spectrogram will have shape `(num_frames, num_frequency_bins/num_mel_filters)`. If `false`, the returned spectrogram will have shape `(num_frequency_bins/num_mel_filters, num_frames)`.\n * @returns {Promise<Tensor>} Spectrogram of shape `(num_frequency_bins, length)` (regular spectrogram) or shape `(num_mel_filters, length)` (mel spectrogram).\n */\nexport async function spectrogram(\n  waveform: Float32Array | Float64Array,\n  window: Float32Array | Float64Array,\n  frame_length: number,\n  hop_length: number,\n  {\n    fft_length = null as number | null,\n    power = 1.0,\n    center = true,\n    pad_mode = 'reflect',\n    onesided = true,\n    preemphasis = null,\n    mel_filters = null as number[][] | null,\n    mel_floor = 1e-10,\n    log_mel = null,\n    reference = 1.0,\n    min_value = 1e-10,\n    db_range = null,\n    remove_dc_offset = null,\n\n    // Custom parameters for efficiency reasons\n    min_num_frames = null,\n    max_num_frames = null,\n    do_pad = true,\n    transpose = false,\n  } = {},\n) {\n  const window_length = window.length;\n  if (fft_length === null) {\n    fft_length = frame_length;\n  }\n  if (frame_length > fft_length) {\n    throw Error(`frame_length (${frame_length}) may not be larger than fft_length (${fft_length})`);\n  }\n\n  if (window_length !== frame_length) {\n    throw new Error(`Length of the window (${window_length}) must equal frame_length (${frame_length})`);\n  }\n\n  if (hop_length <= 0) {\n    throw new Error('hop_length must be greater than zero');\n  }\n\n  if (power === null && mel_filters !== null) {\n    throw new Error(\n      'You have provided `mel_filters` but `power` is `None`. Mel spectrogram computation is not yet supported for complex-valued spectrogram. ' +\n        'Specify `power` to fix this issue.',\n    );\n  }\n\n  if (center) {\n    if (pad_mode !== 'reflect') {\n      throw new Error(`pad_mode=\"${pad_mode}\" not implemented yet.`);\n    }\n    const half_window = Math.floor((fft_length - 1) / 2) + 1;\n    waveform = padReflect(waveform, half_window, half_window);\n  }\n\n  // split waveform into frames of frame_length size\n  let num_frames = Math.floor(1 + Math.floor((waveform.length - frame_length) / hop_length));\n  if (min_num_frames !== null && num_frames < min_num_frames) {\n    num_frames = min_num_frames;\n  }\n  const num_frequency_bins = onesided ? Math.floor(fft_length / 2) + 1 : fft_length;\n\n  let d1 = num_frames;\n  let d1Max = num_frames;\n\n  // If maximum number of frames is provided, we must either pad or truncate\n  if (max_num_frames !== null) {\n    if (max_num_frames > num_frames) {\n      // input is too short, so we pad\n      if (do_pad) {\n        d1Max = max_num_frames;\n      }\n    } else {\n      // input is too long, so we truncate\n      d1Max = d1 = max_num_frames;\n    }\n  }\n\n  // Preallocate arrays to store output.\n  const fft = new FFT(fft_length);\n  const inputBuffer = new Float64Array(fft_length);\n  const outputBuffer = new Float64Array(fft.outputBufferSize);\n  const transposedMagnitudeData = new Float32Array(num_frequency_bins * d1Max);\n\n  for (let i = 0; i < d1; ++i) {\n    // Populate buffer with waveform data\n    const offset = i * hop_length;\n    const buffer_size = Math.min(waveform.length - offset, frame_length);\n    if (buffer_size !== frame_length) {\n      // The full buffer is not needed, so we need to reset it (avoid overflow from previous iterations)\n      // NOTE: We don't need to reset the buffer if it's full since we overwrite the first\n      // `frame_length` values and the rest (`fft_length - frame_length`) remains zero.\n      inputBuffer.fill(0, 0, frame_length);\n    }\n\n    for (let j = 0; j < buffer_size; ++j) {\n      inputBuffer[j] = waveform[offset + j];\n    }\n\n    if (remove_dc_offset) {\n      let sum = 0;\n      for (let j = 0; j < buffer_size; ++j) {\n        sum += inputBuffer[j];\n      }\n      const mean = sum / buffer_size;\n      for (let j = 0; j < buffer_size; ++j) {\n        inputBuffer[j] -= mean;\n      }\n    }\n\n    if (preemphasis !== null) {\n      // Done in reverse to avoid copies and distructive modification\n      for (let j = buffer_size - 1; j >= 1; --j) {\n        inputBuffer[j] -= preemphasis * inputBuffer[j - 1];\n      }\n      inputBuffer[0] *= 1 - preemphasis;\n    }\n\n    // Apply window function\n    for (let j = 0; j < window.length; ++j) {\n      inputBuffer[j] *= window[j];\n    }\n\n    fft.realTransform(outputBuffer, inputBuffer);\n\n    // compute magnitudes\n    for (let j = 0; j < num_frequency_bins; ++j) {\n      const j2 = j << 1;\n\n      // NOTE: We transpose the data here to avoid doing it later\n      transposedMagnitudeData[j * d1Max + i] = outputBuffer[j2] ** 2 + outputBuffer[j2 + 1] ** 2;\n    }\n  }\n\n  if (power !== null && power !== 2) {\n    // slight optimization to not sqrt\n    const pow = 2 / power; // we use 2 since we already squared\n    for (let i = 0; i < transposedMagnitudeData.length; ++i) {\n      transposedMagnitudeData[i] **= pow;\n    }\n  }\n\n  if (!mel_filters) {\n    throw new Error('mel_filters must be provided');\n  }\n  const num_mel_filters = mel_filters.length;\n\n  // Perform matrix multiplication:\n  // mel_spec = mel_filters @ magnitudes.T\n  //  - mel_filters.shape=(80, 201)\n  //  - magnitudes.shape=(3000, 201) => magnitudes.T.shape=(201, 3000)\n  //  - mel_spec.shape=(80, 3000)\n  let mel_spec = await matmul(\n    // TODO: Make `mel_filters` a Tensor during initialization\n    new Tensor('float32', mel_filters.flat(), [num_mel_filters, num_frequency_bins] as [number, number]),\n    new Tensor('float32', transposedMagnitudeData, [num_frequency_bins, d1Max] as [number, number]),\n  );\n  if (transpose) {\n    mel_spec = mel_spec.transpose(1, 0);\n  }\n\n  const mel_spec_data = /** @type {Float32Array} */ mel_spec.data;\n  for (let i = 0; i < mel_spec_data.length; ++i) {\n    mel_spec_data[i] = Math.max(mel_floor, mel_spec_data[i]);\n  }\n\n  if (power !== null && log_mel !== null) {\n    const o = Math.min(mel_spec_data.length, d1 * num_mel_filters);\n    // NOTE: operates in-place\n    switch (log_mel) {\n      case 'log':\n        for (let i = 0; i < o; ++i) {\n          mel_spec_data[i] = Math.log(mel_spec_data[i]);\n        }\n        break;\n      case 'log10':\n        for (let i = 0; i < o; ++i) {\n          mel_spec_data[i] = Math.log10(mel_spec_data[i]);\n        }\n        break;\n      case 'dB':\n        if (power === 1.0) {\n          amplitude_to_db(mel_spec_data, reference, min_value, db_range);\n        } else if (power === 2.0) {\n          power_to_db(mel_spec_data, reference, min_value, db_range);\n        } else {\n          throw new Error(`Cannot use log_mel option '${log_mel}' with power ${power}`);\n        }\n        break;\n      default:\n        throw new Error(`log_mel must be one of null, 'log', 'log10' or 'dB'. Got '${log_mel}'`);\n    }\n  }\n\n  return mel_spec;\n}\n\n/**\n * Returns an array containing the specified window.\n * @param {number} window_length The length of the window in samples.\n * @param {string} name The name of the window function.\n * @param {Object} options Additional options.\n * @param {boolean} [options.periodic=true] Whether the window is periodic or symmetric.\n * @param {number} [options.frame_length=null] The length of the analysis frames in samples.\n * Provide a value for `frame_length` if the window is smaller than the frame length, so that it will be zero-padded.\n * @param {boolean} [options.center=true] Whether to center the window inside the FFT buffer. Only used when `frame_length` is provided.\n * @returns {Float64Array} The window of shape `(window_length,)` or `(frame_length,)`.\n */\nexport function window_function(\n  window_length: number,\n  name: string,\n  { periodic = true, frame_length = null, center = true } = {},\n) {\n  const length = periodic ? window_length + 1 : window_length;\n  let window;\n  switch (name) {\n    case 'boxcar':\n      window = new Float64Array(length).fill(1.0);\n      break;\n    case 'hann':\n    case 'hann_window':\n      window = hanning(length);\n      break;\n    case 'hamming':\n      window = hamming(length);\n      break;\n    case 'povey':\n      window = hanning(length).map((x) => Math.pow(x, 0.85));\n      break;\n    default:\n      throw new Error(`Unknown window type ${name}.`);\n  }\n  if (periodic) {\n    window = window.subarray(0, window_length);\n  }\n  if (frame_length === null) {\n    return window;\n  }\n  if (window_length > frame_length) {\n    throw new Error(`Length of the window (${window_length}) may not be larger than frame_length (${frame_length})`);\n  }\n\n  return window;\n}\n\n/**\n * Encode audio data to a WAV file.\n * WAV file specs : https://en.wikipedia.org/wiki/WAV#WAV_File_header\n * \n * Adapted from https://www.npmjs.com/package/audiobuffer-to-wav\n * @param {Float32Array} samples The audio samples.\n * @param {number} rate The sample rate.\n * @returns {ArrayBuffer} The WAV audio buffer.\n */\nfunction encodeWAV(samples: Float32Array, rate: number) {\n  let offset = 44;\n  const buffer = new ArrayBuffer(offset + samples.length * 4);\n  const view = new DataView(buffer);\n\n  /* RIFF identifier */\n  writeString(view, 0, \"RIFF\");\n  /* RIFF chunk length */\n  view.setUint32(4, 36 + samples.length * 4, true);\n  /* RIFF type */\n  writeString(view, 8, \"WAVE\");\n  /* format chunk identifier */\n  writeString(view, 12, \"fmt \");\n  /* format chunk length */\n  view.setUint32(16, 16, true);\n  /* sample format (raw) */\n  view.setUint16(20, 3, true);\n  /* channel count */\n  view.setUint16(22, 1, true);\n  /* sample rate */\n  view.setUint32(24, rate, true);\n  /* byte rate (sample rate * block align) */\n  view.setUint32(28, rate * 4, true);\n  /* block align (channel count * bytes per sample) */\n  view.setUint16(32, 4, true);\n  /* bits per sample */\n  view.setUint16(34, 32, true);\n  /* data chunk identifier */\n  writeString(view, 36, \"data\");\n  /* data chunk length */\n  view.setUint32(40, samples.length * 4, true);\n\n  for (let i = 0; i < samples.length; ++i, offset += 4) {\n      view.setFloat32(offset, samples[i], true);\n  }\n\n  return buffer;\n}\n\nfunction writeString(view: DataView, offset: number, string: string) {\n  for (let i = 0; i < string.length; ++i) {\n      view.setUint8(offset + i, string.charCodeAt(i));\n  }\n}\n\n\nexport class RawAudio {\n\n  /**\n   * Create a new `RawAudio` object.\n   * @param {Float32Array} audio Audio data\n   * @param {number} sampling_rate Sampling rate of the audio data\n   */\n  audio: Float32Array;\n  sampling_rate: number;\n\n  constructor(audio: Float32Array, sampling_rate: number) {\n      this.audio = audio\n      this.sampling_rate = sampling_rate\n  }\n\n  /**\n   * Convert the audio to a wav file buffer.\n   * @returns {ArrayBuffer} The WAV file.\n   */\n  toWav() {\n      return encodeWAV(this.audio, this.sampling_rate)\n  }\n\n  /**\n   * Convert the audio to a blob.\n   * @returns {Blob}\n   */\n  toBlob() {\n      const wav = this.toWav();\n      const blob = new Blob([wav], { type: 'audio/wav' });\n      return blob;\n  }\n\n  toArray() {\n    return this.audio;\n  }\n\n  /**\n   * Save the audio to a wav file.\n   * @param {string} path\n   */\n  async save(path: string) {\n      let fn;\n\n      if (apis.IS_BROWSER_ENV) {\n          if (apis.IS_WEBWORKER_ENV) {\n              throw new Error('Unable to save a file from a Web Worker.')\n          }\n          fn = saveBlob;\n      } else if (apis.IS_FS_AVAILABLE) {\n         throw new Error('Unable to save because filesystem is disabled in this environment.')\n      } else {\n          throw new Error('Unable to save because filesystem is disabled in this environment.')\n      }\n\n      await fn(path, this.toBlob())\n  }\n} ","import { FeatureExtractor, validate_audio_inputs } from '../../base/feature_extraction_utils';\nimport { Tensor } from '../../utils/tensor';\nimport { mel_filter_bank, spectrogram, window_function } from '../../utils/audio';\n\nexport class ASTFeatureExtractor extends FeatureExtractor {\n  mel_filters: any;\n  window: any;\n  mean: any;\n  std: any;\n\n  constructor(config: any) {\n    super(config);\n\n    const sampling_rate = this.config.sampling_rate;\n    const mel_filters = mel_filter_bank(\n      256, // num_frequency_bins\n      this.config.num_mel_bins, // num_mel_filters\n      20, // min_frequency\n      Math.floor(sampling_rate / 2), // max_frequency\n      sampling_rate, // sampling_rate\n      null, // norm\n      'kaldi', // mel_scale\n      true, // triangularize_in_mel_space\n    );\n\n    // Do padding:\n    for (let i = 0; i < mel_filters.length; ++i) {\n      mel_filters[i].push(0);\n    }\n    this.mel_filters = mel_filters;\n\n    this.window = window_function(400, 'hann', {\n      periodic: false,\n    });\n\n    this.mean = this.config.mean;\n    this.std = this.config.std;\n  }\n\n  /**\n   * Computes the log-Mel spectrogram of the provided audio waveform.\n   * @param {Float32Array|Float64Array} waveform The audio waveform to process.\n   * @param {number} max_length The maximum number of frames to return.\n   * @returns {Promise<Tensor>} An object containing the log-Mel spectrogram data as a Float32Array and its dimensions as an array of numbers.\n   */\n  async _extract_fbank_features(waveform: Float32Array | Float64Array, max_length: number) {\n    // NOTE: We don't pad/truncate since that is passed in as `max_num_frames`\n    return spectrogram(\n      waveform,\n      this.window, // window\n      400, // frame_length\n      160, // hop_length\n      {\n        fft_length: 512,\n        power: 2.0,\n        center: false,\n        preemphasis: 0.97,\n        mel_filters: this.mel_filters,\n        log_mel: 'log',\n        mel_floor: 1.192092955078125e-7,\n        remove_dc_offset: true,\n\n        // Custom\n        max_num_frames: max_length,\n        transpose: true,\n      },\n    );\n  }\n\n  /**\n   * Asynchronously extracts features from a given audio using the provided configuration.\n   * @param {Float32Array|Float64Array} audio The audio data as a Float32Array/Float64Array.\n   * @returns {Promise<{ input_values: Tensor }>} A Promise resolving to an object containing the extracted input features as a Tensor.\n   */\n  async _call(audio: Float32Array | Float64Array) {\n    validate_audio_inputs(audio, 'ASTFeatureExtractor');\n\n    const features = await this._extract_fbank_features(audio, this.config.max_length);\n    if (this.config.do_normalize) {\n      // Normalize the input audio spectrogram to have mean=0, std=0.5\n      const denom = this.std * 2;\n      const features_data = features.data;\n      for (let i = 0; i < features_data.length; ++i) {\n        features_data[i] = (features_data[i] - this.mean) / denom;\n      }\n    }\n\n    return {\n      input_values: features.unsqueeze_(0),\n    };\n  }\n}\n","import { FeatureExtractor, validate_audio_inputs } from '../../base/feature_extraction_utils.js';\nimport { Tensor } from '../../utils/tensor.js';\nimport { mel_filter_bank, spectrogram, window_function } from '../../utils/audio.js';\n\nexport class ClapFeatureExtractor extends FeatureExtractor {\n  mel_filters: any;\n  mel_filters_slaney: any;\n  window: any;\n\n  constructor(config: any) {\n    super(config);\n\n    this.mel_filters = mel_filter_bank(\n      this.config.nb_frequency_bins, // num_frequency_bins\n      this.config.feature_size, // num_mel_filters\n      this.config.frequency_min, // min_frequency\n      this.config.frequency_max, // max_frequency\n      this.config.sampling_rate, // sampling_rate\n      null, // norm\n      'htk', // mel_scale\n    );\n\n    this.mel_filters_slaney = mel_filter_bank(\n      this.config.nb_frequency_bins, // num_frequency_bins\n      this.config.feature_size, // num_mel_filters\n      this.config.frequency_min, // min_frequency\n      this.config.frequency_max, // max_frequency\n      this.config.sampling_rate, // sampling_rate\n      'slaney', // norm\n      'slaney', // mel_scale\n    );\n\n    this.window = window_function(this.config.fft_window_size, 'hann');\n  }\n\n  /**\n   * Extracts the mel spectrogram and prepares it for the mode based on the `truncation` and `padding` arguments.\n   *\n   * Four different path are possible:\n   *   - `truncation=\"fusion\"` and the length of the waveform is greater than the max length: the mel spectrogram\n   *     will be computed on the entire audio. 3 random crops and a dowsampled version of the full mel spectrogram\n   *     are then stacked together. They will later be used for `feature_fusion`.\n   *   - `truncation=\"rand_trunc\"` and the length of the waveform is smaller than the max length: the audio is\n   *     padded based on `padding`.\n   *   - `truncation=\"fusion\"` and the length of the waveform is smaller than the max length: the audio is padded\n   *     based on `padding`, and is repeated `4` times.\n   *   - `truncation=\"rand_trunc\"` and the length of the waveform is greater than the max length: the mel\n   *     spectrogram will be computed on a random crop of the waveform.\n   *\n   * @param {Float32Array|Float64Array} waveform The input waveform.\n   * @param {number} max_length The maximum length of the waveform.\n   * @param {string} truncation The truncation strategy to use.\n   * @param {string} padding The padding strategy to use.\n   * @returns {Promise<Tensor>} An object containing the mel spectrogram data as a Float32Array, its dimensions as an array of numbers, and a boolean indicating whether the waveform was longer than the max length.\n   * @private\n   */\n  async _get_input_mel(waveform: Float32Array | Float64Array, max_length: number, truncation: string, padding: string) {\n    /** @type {Tensor} */\n    let input_mel;\n    let longer = false;\n    const diff = waveform.length - max_length;\n    if (diff > 0) {\n      if (truncation === 'rand_trunc') {\n        longer = true;\n        const idx = Math.floor(Math.random() * (diff + 1));\n        waveform = waveform.subarray(idx, idx + max_length);\n\n        input_mel = await this._extract_fbank_features(waveform, this.mel_filters_slaney, this.config.nb_max_samples);\n      } else {\n        // TODO implement fusion strategy\n        throw new Error(`Truncation strategy \"${truncation}\" not implemented`);\n      }\n    } else {\n      if (diff < 0) {\n        let padded = new Float64Array(max_length); // already padded with zeros\n        padded.set(waveform);\n\n        if (padding === 'repeat') {\n          for (let i = waveform.length; i < max_length; i += waveform.length) {\n            padded.set(waveform.subarray(0, Math.min(waveform.length, max_length - i)), i);\n          }\n        } else if (padding === 'repeatpad') {\n          for (let i = waveform.length; i < -diff; i += waveform.length) {\n            padded.set(waveform, i);\n          }\n        }\n        waveform = padded;\n      }\n\n      if (truncation === 'fusion') {\n        throw new Error(`Truncation strategy \"${truncation}\" not implemented`);\n      }\n\n      input_mel = await this._extract_fbank_features(waveform, this.mel_filters_slaney, this.config.nb_max_samples);\n    }\n\n    return input_mel.unsqueeze_(0);\n  }\n\n  /**\n   * Compute the log-mel spectrogram of the provided `waveform` using the Hann window.\n   * In CLAP, two different filter banks are used depending on the truncation pattern:\n   *  - `self.mel_filters`: they correspond to the default parameters of `torchaudio` which can be obtained from\n   *    calling `torchaudio.transforms.MelSpectrogram().mel_scale.fb`. These filters are used when `truncation`\n   *    is set to `\"fusion\"`.\n   *  - `self.mel_filteres_slaney` : they correspond to the default parameters of `librosa` which used\n   *    `librosa.filters.mel` when computing the mel spectrogram. These filters were only used in the original\n   *    implementation when the truncation mode is not `\"fusion\"`.\n   *\n   * @param {Float32Array|Float64Array} waveform The audio waveform to process.\n   * @param {number[][]} mel_filters The mel filters to use.\n   * @param {number} [max_length=null] The maximum number of frames to return.\n   * @returns {Promise<Tensor>} An object containing the log-Mel spectrogram data as a Float32Array and its dimensions as an array of numbers.\n   */\n  async _extract_fbank_features(waveform: Float32Array | Float64Array, mel_filters: any, max_length = null) {\n    // NOTE: We don't pad/truncate since that is passed in as `max_num_frames`\n    return spectrogram(\n      waveform,\n      this.window, // window\n      this.config.fft_window_size, // frame_length\n      this.config.hop_length, // hop_length\n      {\n        power: 2.0,\n        mel_filters,\n        log_mel: 'dB',\n\n        // Custom\n        max_num_frames: max_length,\n        do_pad: false,\n        transpose: true,\n      },\n    );\n  }\n\n  /**\n   * Asynchronously extracts features from a given audio using the provided configuration.\n   * @param {Float32Array|Float64Array} audio The audio data as a Float32Array/Float64Array.\n   * @returns {Promise<{ input_features: Tensor }>} A Promise resolving to an object containing the extracted input features as a Tensor.\n   */\n  async _call(audio: Float32Array | Float64Array, { max_length = null } = {}) {\n    validate_audio_inputs(audio, 'ClapFeatureExtractor');\n\n    // convert to mel spectrogram, truncate and pad if needed.\n    const padded_inputs = await this._get_input_mel(\n      audio,\n      max_length ?? this.config.nb_max_samples,\n      this.config.truncation,\n      this.config.padding,\n    );\n\n    return {\n      input_features: padded_inputs.unsqueeze_(0),\n    };\n  }\n}\n","import { FeatureExtractor, validate_audio_inputs } from '../../base/feature_extraction_utils.js';\nimport { Tensor } from '../../utils/tensor.js';\n\nexport class MoonshineFeatureExtractor extends FeatureExtractor {\n  /**\n   * Asynchronously extracts input values from a given audio using the provided configuration.\n   * @param {Float32Array|Float64Array} audio The audio data as a Float32Array/Float64Array.\n   * @returns {Promise<{ input_values: Tensor; }>} The extracted input values.\n   */\n  async _call(audio) {\n    validate_audio_inputs(audio, 'MoonshineFeatureExtractor');\n\n    if (audio instanceof Float64Array) {\n      audio = new Float32Array(audio);\n    }\n\n    const shape = [1 /* batch_size */, audio.length /* num_samples */];\n    return {\n      input_values: new Tensor('float32', audio, shape),\n    };\n  }\n}\n","import { FeatureExtractor, validate_audio_inputs } from '../../base/feature_extraction_utils.js';\nimport { Tensor } from '../../utils/tensor.js';\nimport { max, softmax } from '../../utils/maths.js';\n\nexport class PyAnnoteFeatureExtractor extends FeatureExtractor {\n  /**\n   * Asynchronously extracts features from a given audio using the provided configuration.\n   * @param {Float32Array|Float64Array} audio The audio data as a Float32Array/Float64Array.\n   * @returns {Promise<{ input_values: Tensor; }>} The extracted input features.\n   */\n  async _call(audio) {\n    validate_audio_inputs(audio, 'PyAnnoteFeatureExtractor');\n\n    if (audio instanceof Float64Array) {\n      audio = new Float32Array(audio);\n    }\n\n    const shape = [1 /* batch_size */, 1 /* num_channels */, audio.length /* num_samples */];\n    return {\n      input_values: new Tensor('float32', audio, shape),\n    };\n  }\n\n  /**\n   * NOTE: Can return fractional values. `Math.ceil` will ensure correct value.\n   * @param {number} samples The number of frames in the audio.\n   * @returns {number} The number of frames in the audio.\n   */\n  samples_to_frames(samples) {\n    return (samples - this.config.offset) / this.config.step;\n  }\n\n  /**\n   * Post-processes the speaker diarization logits output by the model.\n   * @param {import('../../utils/tensor.js').Tensor} logits The speaker diarization logits output by the model.\n   * @param {number} num_samples Number of samples in the input audio.\n   * @returns {Array<Array<{ id: number, start: number, end: number, confidence: number }>>} The post-processed speaker diarization results.\n   */\n  post_process_speaker_diarization(logits, num_samples) {\n    const ratio = num_samples / this.samples_to_frames(num_samples) / this.config.sampling_rate;\n\n    const results = [];\n    for (const scores of logits.tolist()) {\n      const accumulated_segments = [];\n\n      let current_speaker = -1;\n      for (let i = 0; i < scores.length; ++i) {\n        /** @type {number[]} */\n        const probabilities = softmax(scores[i]);\n        const [score, id] = max(probabilities);\n        const [start, end] = [i, i + 1];\n\n        if (id !== current_speaker) {\n          // Speaker has changed\n          current_speaker = id;\n          accumulated_segments.push({ id, start, end, score });\n        } else {\n          // Continue the current segment\n          accumulated_segments.at(-1).end = end;\n          accumulated_segments.at(-1).score += score;\n        }\n      }\n\n      results.push(\n        accumulated_segments.map(\n          // Convert frame-space to time-space\n          // and compute the confidence\n          ({ id, start, end, score }) => ({\n            id,\n            start: start * ratio,\n            end: end * ratio,\n            confidence: score / (end - start),\n          }),\n        ),\n      );\n    }\n    return results;\n  }\n}\n","import { FeatureExtractor, validate_audio_inputs } from '../../base/feature_extraction_utils.js';\nimport { Tensor } from '../../utils/tensor.js';\nimport { mel_filter_bank, spectrogram, window_function } from '../../utils/audio.js';\n\nexport class SeamlessM4TFeatureExtractor extends FeatureExtractor {\n  constructor(config) {\n    super(config);\n\n    const sampling_rate = this.config.sampling_rate;\n    const mel_filters = mel_filter_bank(\n      256, // num_frequency_bins\n      this.config.num_mel_bins, // num_mel_filters\n      20, // min_frequency\n      Math.floor(sampling_rate / 2), // max_frequency\n      sampling_rate, // sampling_rate\n      null, // norm\n      'kaldi', // mel_scale\n      true, // triangularize_in_mel_space\n    );\n\n    // Do padding:\n    for (let i = 0; i < mel_filters.length; ++i) {\n      mel_filters[i].push(0);\n    }\n    this.mel_filters = mel_filters;\n\n    this.window = window_function(400, 'povey', {\n      periodic: false,\n    });\n  }\n\n  /**\n   * Computes the log-Mel spectrogram of the provided audio waveform.\n   * @param {Float32Array|Float64Array} waveform The audio waveform to process.\n   * @param {number} max_length The maximum number of frames to return.\n   * @returns {Promise<Tensor>} An object containing the log-Mel spectrogram data as a Float32Array and its dimensions as an array of numbers.\n   */\n  async _extract_fbank_features(waveform, max_length) {\n    // NOTE: We don't pad/truncate since that is passed in as `max_num_frames`\n\n    // Kaldi compliance: 16-bit signed integers\n    // 32768 == 2 ** 15\n    waveform = waveform.map((/** @type {number} */ x) => x * 32768);\n\n    return spectrogram(\n      waveform,\n      this.window, // window\n      400, // frame_length\n      160, // hop_length\n      {\n        fft_length: 512,\n        power: 2.0,\n        center: false,\n        preemphasis: 0.97,\n        mel_filters: this.mel_filters,\n        log_mel: 'log',\n        mel_floor: 1.192092955078125e-7,\n        remove_dc_offset: true,\n\n        // Custom\n        max_num_frames: max_length,\n        transpose: true,\n      },\n    );\n  }\n\n  /**\n   * Asynchronously extracts features from a given audio using the provided configuration.\n   * @param {Float32Array|Float64Array} audio The audio data as a Float32Array/Float64Array.\n   * @param {Object} options Optional parameters for feature extraction.\n   * @param {boolean} [options.padding=true] Whether to pad the sequence to a multiple of `pad_to_multiple_of`.\n   * @param {number} [options.pad_to_multiple_of=2] The number to pad the sequence to a multiple of.\n   * @param {boolean} [options.do_normalize_per_mel_bins=true] Whether or not to zero-mean unit-variance normalize the input per mel-channel.\n   * @param {boolean} [options.return_attention_mask=true] Whether to return the attention mask.\n   * @returns {Promise<{ input_features: Tensor, attention_mask?: Tensor }>} A Promise resolving to an object containing the extracted input features and attention masks as Tensors.\n   */\n  async _call(\n    audio,\n    { padding = true, pad_to_multiple_of = 2, do_normalize_per_mel_bins = true, return_attention_mask = true } = {},\n  ) {\n    validate_audio_inputs(audio, 'SeamlessM4TFeatureExtractor');\n\n    let features = await this._extract_fbank_features(audio, this.config.max_length);\n\n    if (do_normalize_per_mel_bins) {\n      const [num_features, feature_size] = features.dims;\n      const data = features.data;\n      for (let i = 0; i < feature_size; ++i) {\n        let sum = 0;\n        for (let j = 0; j < num_features; ++j) {\n          sum += data[j * feature_size + i];\n        }\n\n        const mean = sum / num_features;\n\n        let variance = 0;\n        for (let j = 0; j < num_features; ++j) {\n          variance += (data[j * feature_size + i] - mean) ** 2;\n        }\n        variance /= num_features - 1; // NOTE: We use ddof=1\n\n        const std = Math.sqrt(variance + 1e-7);\n        for (let j = 0; j < num_features; ++j) {\n          const index = j * feature_size + i;\n          data[index] = (data[index] - mean) / std;\n        }\n      }\n    }\n\n    let padded_attention_mask;\n    if (padding) {\n      const [num_frames, num_channels] = features.dims;\n      const data = /** @type {Float32Array} */ features.data;\n\n      const pad_size = num_frames % pad_to_multiple_of;\n      if (pad_size > 0) {\n        const padded_data = new Float32Array(num_channels * (num_frames + pad_size));\n        padded_data.set(data);\n        padded_data.fill(this.config.padding_value, data.length);\n\n        const numPaddedFrames = num_frames + pad_size;\n        features = new Tensor(features.type, padded_data, [numPaddedFrames, num_channels]);\n\n        if (return_attention_mask) {\n          padded_attention_mask = new Tensor('int64', new BigInt64Array(numPaddedFrames), [1, numPaddedFrames]);\n          /** @type {BigInt64Array} */ padded_attention_mask.data.fill(1n, 0, num_frames);\n        }\n      }\n    }\n\n    const [num_frames, num_channels] = features.dims;\n\n    const stride = this.config.stride;\n    const remainder = num_frames % stride;\n    if (remainder !== 0) {\n      throw new Error(`The number of frames (${num_frames}) must be a multiple of the stride (${stride}).`);\n    }\n\n    const input_features = features.view(1, Math.floor(num_frames / stride), num_channels * stride);\n\n    const result = { input_features };\n\n    if (return_attention_mask) {\n      const reshapedNumFrames = input_features.dims[1];\n\n      const attention_mask_data = new BigInt64Array(reshapedNumFrames);\n\n      if (padded_attention_mask) {\n        const padded_attention_mask_data = padded_attention_mask.data;\n        for (let i = 1, j = 0; i < num_frames; i += stride, ++j) {\n          attention_mask_data[j] = padded_attention_mask_data[i];\n        }\n      } else {\n        attention_mask_data.fill(1n);\n      }\n      result.attention_mask = new Tensor('int64', attention_mask_data, [1, reshapedNumFrames]);\n    }\n\n    return result;\n  }\n}\n","import { FeatureExtractor } from '../../base/feature_extraction_utils.js';\n\nexport class SpeechT5FeatureExtractor extends FeatureExtractor {}\n","import { FeatureExtractor, validate_audio_inputs } from '../../base/feature_extraction_utils.js';\nimport { Tensor } from '../../utils/tensor.js';\n\nexport class Wav2Vec2FeatureExtractor extends FeatureExtractor {\n  /**\n   * @param {Float32Array} input_values\n   * @returns {Float32Array}\n   */\n  _zero_mean_unit_var_norm(input_values) {\n    // TODO support batch?\n    const sum = input_values.reduce((a, b) => a + b, 0);\n    const mean = sum / input_values.length;\n    const variance = input_values.reduce((a, b) => a + (b - mean) ** 2, 0) / input_values.length;\n    return input_values.map((x) => (x - mean) / Math.sqrt(variance + 1e-7));\n  }\n\n  /**\n   * Asynchronously extracts features from a given audio using the provided configuration.\n   * @param {Float32Array|Float64Array} audio The audio data as a Float32Array/Float64Array.\n   * @returns {Promise<{ input_values: Tensor; attention_mask: Tensor }>} A Promise resolving to an object containing the extracted input features and attention mask as Tensors.\n   */\n  async _call(audio) {\n    validate_audio_inputs(audio, 'Wav2Vec2FeatureExtractor');\n\n    if (audio instanceof Float64Array) {\n      audio = new Float32Array(audio);\n    }\n\n    let input_values = audio;\n\n    // zero-mean and unit-variance normalization\n    if (this.config.do_normalize) {\n      input_values = this._zero_mean_unit_var_norm(input_values);\n    }\n\n    // TODO: allow user to pass in attention mask\n    const shape = [1, input_values.length];\n    return {\n      input_values: new Tensor('float32', input_values, shape),\n      attention_mask: new Tensor('int64', new BigInt64Array(input_values.length).fill(1n), shape),\n    };\n  }\n}\n","import { FeatureExtractor, validate_audio_inputs } from '../../base/feature_extraction_utils.js';\nimport { Tensor } from '../../utils/tensor.js';\nimport { mel_filter_bank, spectrogram, window_function } from '../../utils/audio.js';\n\nexport class WeSpeakerFeatureExtractor extends FeatureExtractor {\n  constructor(config) {\n    super(config);\n\n    const sampling_rate = this.config.sampling_rate;\n    const mel_filters = mel_filter_bank(\n      256, // num_frequency_bins\n      this.config.num_mel_bins, // num_mel_filters\n      20, // min_frequency\n      Math.floor(sampling_rate / 2), // max_frequency\n      sampling_rate, // sampling_rate\n      null, // norm\n      'kaldi', // mel_scale\n      true, // triangularize_in_mel_space\n    );\n\n    // Do padding:\n    for (let i = 0; i < mel_filters.length; ++i) {\n      mel_filters[i].push(0);\n    }\n    this.mel_filters = mel_filters;\n\n    this.window = window_function(400, 'hamming', {\n      periodic: false,\n    });\n    this.min_num_frames = this.config.min_num_frames;\n  }\n\n  /**\n   * Computes the log-Mel spectrogram of the provided audio waveform.\n   * @param {Float32Array|Float64Array} waveform The audio waveform to process.\n   * @returns {Promise<Tensor>} An object containing the log-Mel spectrogram data as a Float32Array and its dimensions as an array of numbers.\n   */\n  async _extract_fbank_features(waveform) {\n    // Kaldi compliance: 16-bit signed integers\n    // 32768 == 2 ** 15\n    waveform = waveform.map((/** @type {number} */ x) => x * 32768);\n\n    return spectrogram(\n      waveform,\n      this.window, // window\n      400, // frame_length\n      160, // hop_length\n      {\n        fft_length: 512,\n        power: 2.0,\n        center: false,\n        preemphasis: 0.97,\n        mel_filters: this.mel_filters,\n        log_mel: 'log',\n        mel_floor: 1.192092955078125e-7,\n        remove_dc_offset: true,\n\n        // Custom\n        transpose: true,\n        min_num_frames: this.min_num_frames,\n      },\n    );\n  }\n\n  /**\n   * Asynchronously extracts features from a given audio using the provided configuration.\n   * @param {Float32Array|Float64Array} audio The audio data as a Float32Array/Float64Array.\n   * @returns {Promise<{ input_features: Tensor }>} A Promise resolving to an object containing the extracted input features as a Tensor.\n   */\n  async _call(audio) {\n    validate_audio_inputs(audio, 'WeSpeakerFeatureExtractor');\n\n    const features = (await this._extract_fbank_features(audio)).unsqueeze_(0);\n\n    if (this.config.fbank_centering_span === null) {\n      // center features with global average\n      const meanData = /** @type {Float32Array} */ features.mean(1).data;\n      const featuresData = /** @type {Float32Array} */ features.data;\n      const [batch_size, num_frames, feature_size] = features.dims;\n\n      for (let i = 0; i < batch_size; ++i) {\n        const offset1 = i * num_frames * feature_size;\n        const offset2 = i * feature_size;\n        for (let j = 0; j < num_frames; ++j) {\n          const offset3 = offset1 + j * feature_size;\n          for (let k = 0; k < feature_size; ++k) {\n            featuresData[offset3 + k] -= meanData[offset2 + k];\n          }\n        }\n      }\n    }\n\n    return {\n      input_features: features,\n    };\n  }\n}\n","import { FeatureExtractor, validate_audio_inputs } from '../../base/feature_extraction_utils';\nimport { Tensor } from '../../utils/tensor';\nimport { mel_filter_bank, spectrogram, window_function } from '../../utils/audio';\nimport { max } from '../../utils/maths';\nimport { AutomaticSpeechRecognitionConfig } from '../../pipelines';\nexport class WhisperFeatureExtractor extends FeatureExtractor {\n  constructor(config: Partial<AutomaticSpeechRecognitionConfig>) {\n    super(config);\n\n    // Prefer given `mel_filters` from preprocessor_configon, or calculate them if they don't exist.\n    this.config.mel_filters ??= mel_filter_bank(\n      Math.floor(1 + this.config.n_fft / 2), // num_frequency_bins\n      this.config.feature_size, // num_mel_filters\n      0.0, // min_frequency\n      8000.0, // max_frequency\n      this.config.sampling_rate, // sampling_rate\n      'slaney', // norm\n      'slaney', // mel_scale\n    );\n\n    this.window = window_function(this.config.n_fft, 'hann');\n  }\n\n  /**\n   * Computes the log-Mel spectrogram of the provided audio waveform.\n   * @param {Float32Array|Float64Array} waveform The audio waveform to process.\n   * @returns {Promise<Tensor>} An object containing the log-Mel spectrogram data as a Float32Array and its dimensions as an array of numbers.\n   */\n  async _extract_fbank_features(waveform: Float32Array | Float64Array) {\n    const features = await spectrogram(\n      waveform,\n      this.window, // window\n      this.config.n_fft, // frame_length\n      this.config.hop_length, // hop_length\n      {\n        power: 2.0,\n        mel_filters: this.config.mel_filters,\n        log_mel: 'log10',\n\n        // Custom\n        max_num_frames: this.config.nb_max_frames, // 3000\n      },\n    );\n\n    const data = features.data;\n    const maxValue = max(/** @type {Float32Array} */ data)[0];\n\n    for (let i = 0; i < data.length; ++i) {\n      data[i] = (Math.max(data[i], maxValue - 8.0) + 4.0) / 4.0;\n    }\n\n    return features;\n  }\n\n  /**\n   * Asynchronously extracts features from a given audio using the provided configuration.\n   * @param {Float32Array|Float64Array} audio The audio data as a Float32Array/Float64Array.\n   * @returns {Promise<{ input_features: Tensor }>} A Promise resolving to an object containing the extracted input features as a Tensor.\n   */\n  async _call(audio: AudioPipelineInputs) {\n    validate_audio_inputs(audio, 'WhisperFeatureExtractor');\n\n    let waveform;\n    if (audio.length > this.config.n_samples) {\n      console.warn(\n        'Attempting to extract features for audio longer than 30 seconds. ' +\n          'If using a pipeline to extract transcript from a long audio clip, ' +\n          'remember to specify `chunk_length_s` and/or `stride_length_s`.',\n      );\n      waveform = audio.slice(0, this.config.n_samples);\n    } else {\n      // pad with zeros\n      waveform = new Float32Array(this.config.n_samples);\n      waveform.set(audio);\n    }\n\n    const features = await this._extract_fbank_features(waveform);\n\n    return {\n      input_features: features.unsqueeze_(0),\n    };\n  }\n}\n","import { FEATURE_EXTRACTOR_NAME, GITHUB_ISSUE_URL } from '../../utils/constants.js';\nimport { getModelJSON } from '../../utils/hub.js';\nimport { FeatureExtractor } from '../../base/feature_extraction_utils.js';\nimport * as AllFeatureExtractors from '../feature_extractors.js';\n\nexport class AutoFeatureExtractor {\n  /** @type {typeof FeatureExtractor.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options = {}) {\n    const preprocessorConfig = await getModelJSON(pretrained_model_name_or_path, FEATURE_EXTRACTOR_NAME, true, options);\n\n    // Determine feature extractor class\n    const key = preprocessorConfig.feature_extractor_type;\n    const feature_extractor_class = AllFeatureExtractors[key as keyof typeof AllFeatureExtractors];\n\n    if (!feature_extractor_class) {\n      throw new Error(`Unknown feature_extractor_type: '${key}'. Please report this at ${GITHUB_ISSUE_URL}.`);\n    }\n\n    // Instantiate feature extractor\n    return new feature_extractor_class(preprocessorConfig);\n  }\n}\n","import { AutoFeatureExtractor } from '../auto/feature_extraction_auto.js';\nimport { AutoTokenizer } from '../../tokenizers.js';\nimport { Processor } from '../../base/processing_utils.js';\n\n/**\n * Represents a MoonshineProcessor that extracts features from an audio input.\n */\nexport class MoonshineProcessor extends Processor {\n  static tokenizer_class = AutoTokenizer;\n  static feature_extractor_class = AutoFeatureExtractor;\n\n  /**\n   * Calls the feature_extractor function with the given audio input.\n   * @param {any} audio The audio input to extract features from.\n   * @returns {Promise<any>} A Promise that resolves with the extracted features.\n   */\n  async _call(audio) {\n    return await this.feature_extractor(audio);\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { AutoImageProcessor } from '../auto/image_processing_auto.js';\nimport { AutoTokenizer } from '../../tokenizers.js';\nimport { mergeArrays } from '../../utils/core.js';\nimport { Tensor } from '../../utils/tensor.js';\nimport { RawImage } from '../../utils/image.js';\n\nexport class VLChatProcessor extends Processor {\n  static image_processor_class = AutoImageProcessor;\n  static tokenizer_class = AutoTokenizer;\n  static uses_processor_config = true;\n\n  constructor(config, components) {\n    super(config, components);\n\n    this.image_tag = this.config.image_tag;\n    this.image_start_tag = this.config.image_start_tag;\n    this.image_end_tag = this.config.image_end_tag;\n    this.num_image_tokens = this.config.num_image_tokens;\n  }\n\n  /**\n   * @typedef {Object} MultimodalMessageProperties Additional properties for multimodal messages.\n   * @property {(RawImage | string | URL)[]} [images] The images in the message.\n   * @typedef {(import('../../tokenizers.js').Message & MultimodalMessageProperties)[]} MultimodalConversation The conversation possibly containing multimodal inputs.\n   */\n\n  /**\n   * @typedef {Object} VLCChatProcessorResult The processed input.\n   * @property {Tensor} input_ids The input IDs.\n   * @property {Tensor} attention_mask The attention mask.\n   * @property {Tensor} images_seq_mask The image sequence mask.\n   * @property {Tensor} images_emb_mask The image embedding mask.\n   */\n\n  /**\n   * @param {MultimodalConversation} conversation The chat messages to process.\n   * @param {Object} options Additional options for processing.\n   * @param {RawImage|RawImage[]} [options.images] The images to process, if not set in the conversation.\n   * @param {string} [options.chat_template=\"default\"] The chat template to use.\n   * @returns {Promise<VLCChatProcessorResult | VLCChatProcessorResult & import('../../base/image_processors_utils.js').ImageProcessorResult>} The processed input.\n   */\n  async _call(conversation, { images = null, chat_template = 'default' } = {}) {\n    if (!images) {\n      images = await Promise.all(\n        conversation\n          .filter((msg) => msg.images)\n          .flatMap((msg) => msg.images)\n          .map((img) => RawImage.read(img)),\n      );\n    } else if (!Array.isArray(images)) {\n      images = [images];\n    }\n\n    const tokenizer = this.tokenizer;\n    const result = tokenizer.apply_chat_template(conversation, {\n      tokenize: false,\n      add_generation_prompt: true,\n      chat_template,\n    });\n\n    const encode = (text) => tokenizer.encode(text, { add_special_tokens: false });\n    const parts = /** @type {string} */ result.split(this.image_tag);\n    const num_images = parts.length - 1;\n    if (images.length !== num_images) {\n      throw new Error(\n        `Number of images provided (${images.length}) does not match number of \"${this.image_tag}\" image tags (${num_images})`,\n      );\n    }\n\n    const [image_placeholder_tag_id, image_start_tag_id, image_end_tag_id] = tokenizer.model.convert_tokens_to_ids([\n      this.image_tag,\n      this.image_start_tag,\n      this.image_end_tag,\n    ]);\n\n    let input_ids = encode(parts[0]);\n    let images_seq_mask = new Array(input_ids.length).fill(false);\n    for (let i = 1; i < parts.length; ++i) {\n      const placeholder_image_tokens = new Array(this.num_image_tokens).fill(image_placeholder_tag_id);\n      const tokens = encode(parts[i]);\n      input_ids = mergeArrays(input_ids, [image_start_tag_id], placeholder_image_tokens, [image_end_tag_id], tokens);\n      const image_mask = new Array(this.num_image_tokens).fill(true);\n      images_seq_mask = mergeArrays(\n        images_seq_mask,\n        [false],\n        image_mask,\n        [false],\n        new Array(tokens.length).fill(false),\n      );\n    }\n\n    const dims = [1, input_ids.length];\n    const final = {\n      input_ids: new Tensor('int64', input_ids, dims),\n      attention_mask: new Tensor('int64', new Array(input_ids.length).fill(1), dims),\n      images_seq_mask: new Tensor('bool', images_seq_mask, dims),\n      images_emb_mask: new Tensor('bool', new Array(num_images * this.num_image_tokens).fill(true), [\n        1,\n        num_images,\n        this.num_image_tokens,\n      ]),\n    };\n\n    if (images && images.length > 0) {\n      const image_inputs = await this.image_processor(images);\n      // Set the batch_size dimension to 1\n      image_inputs.pixel_values.unsqueeze_(0);\n      return { ...final, ...image_inputs };\n    }\n\n    return final;\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { AutoImageProcessor } from '../auto/image_processing_auto.js';\nimport { AutoTokenizer } from '../../tokenizers.js';\n\nexport class JinaCLIPProcessor extends Processor {\n  static tokenizer_class = AutoTokenizer;\n  static image_processor_class = AutoImageProcessor;\n\n  async _call(text = null, images = null, kwargs = {}) {\n    if (!text && !images) {\n      throw new Error('Either text or images must be provided');\n    }\n\n    const text_inputs = text ? this.tokenizer(text, kwargs) : {};\n    const image_inputs = images ? await this.image_processor(images, kwargs) : {};\n\n    return {\n      ...text_inputs,\n      ...image_inputs,\n    };\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { AutoImageProcessor } from '../auto/image_processing_auto.js';\nimport { AutoTokenizer } from '../../tokenizers.js';\nimport { RawImage } from '../../utils/image.js';\n\nconst IMAGE_TOKEN = '<|image|>';\nconst IMAGE_TOKEN_PATTERN = /<\\|image_\\d+\\|>/g;\n\nexport class Phi3VProcessor extends Processor {\n  static image_processor_class = AutoImageProcessor;\n  static tokenizer_class = AutoTokenizer;\n\n  /**\n   *\n   * @param {string|string[]} text\n   * @param {RawImage|RawImage[]} images\n   * @param  { { padding?: boolean, truncation?: boolean, num_crops?: number } | undefined } options\n   * @returns {Promise<any>}\n   */\n  async _call(text, images = null, { padding = true, truncation = true, num_crops = null } = {}) {\n    if (!Array.isArray(text)) {\n      text = [text];\n    }\n\n    let text_inputs, image_inputs;\n    if (images) {\n      image_inputs = await this.image_processor(images, { num_crops });\n      const { num_img_tokens } = image_inputs;\n\n      // The original implementation adds a bos_token before the image tokens\n      // TODO: Check if this affects performance, since it looks like a bug in the original implementation\n      const prompt_chunks = text.map((t, i) =>\n        t.split(IMAGE_TOKEN_PATTERN).join(IMAGE_TOKEN.repeat(num_img_tokens[i])),\n      );\n\n      text_inputs = this.tokenizer(prompt_chunks, { padding, truncation });\n\n      // The model expects image tokens to be negative, so we negate the image token ids\n      const image_token_id = this.tokenizer.model.convert_tokens_to_ids([IMAGE_TOKEN])[0];\n      text_inputs.input_ids.map_((id) => (id == image_token_id ? -id : id));\n    } else {\n      text_inputs = this.tokenizer(text);\n    }\n\n    return {\n      ...text_inputs,\n      ...image_inputs,\n    };\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { AutoImageProcessor } from '../auto/image_processing_auto.js';\nimport { AutoTokenizer } from '../../tokenizers.js';\n\nconst IMAGE_TOKEN = '<image>';\n\nfunction build_string_from_input(prompt, bos_token, image_seq_len, image_token, num_images) {\n  return `${image_token.repeat(image_seq_len * num_images)}${bos_token}${prompt}\\n`;\n}\n\nexport class PaliGemmaProcessor extends Processor {\n  static tokenizer_class = AutoTokenizer;\n  static image_processor_class = AutoImageProcessor;\n  static uses_processor_config = false;\n\n  /**\n   * @typedef {import('../../utils/image.js').RawImage} RawImage\n   */\n\n  // `images` is required, `text` is optional\n  async _call(/** @type {RawImage|RawImage[]} */ images, text = null, kwargs = {}) {\n    if (!text) {\n      console.warn('You are using PaliGemma without a text prefix. It will perform as a picture-captioning model.');\n      text = '';\n    }\n\n    if (!Array.isArray(images)) {\n      images = [images];\n    }\n\n    if (!Array.isArray(text)) {\n      text = [text];\n    }\n\n    const bos_token = this.tokenizer.bos_token;\n    // @ts-expect-error TS2339\n    const image_seq_length = this.image_processor.config.image_seq_length;\n    let input_strings;\n    if (text.some((t) => t.includes(IMAGE_TOKEN))) {\n      input_strings = text.map((sample) => {\n        const expanded_sample = sample.replaceAll(IMAGE_TOKEN, IMAGE_TOKEN.repeat(image_seq_length));\n        const bos_rfind_index = expanded_sample.lastIndexOf(IMAGE_TOKEN);\n        const bos_index = bos_rfind_index === -1 ? 0 : bos_rfind_index + IMAGE_TOKEN.length;\n        return expanded_sample.slice(0, bos_index) + bos_token + expanded_sample.slice(bos_index) + '\\n';\n      });\n    } else {\n      console.warn(\n        'You are passing both `text` and `images` to `PaliGemmaProcessor`. The processor expects special ' +\n          'image tokens in the text, as many tokens as there are images per each text. It is recommended to ' +\n          'add `<image>` tokens in the very beginning of your text. For this call, we will infer how many images ' +\n          'each text has and add special tokens.',\n      );\n\n      input_strings = text.map((sample) =>\n        build_string_from_input(sample, bos_token, image_seq_length, IMAGE_TOKEN, images.length),\n      );\n    }\n\n    const text_inputs = this.tokenizer(input_strings, kwargs);\n    const image_inputs = await this.image_processor(images, kwargs);\n\n    return {\n      ...image_inputs,\n      ...text_inputs,\n    };\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { PyAnnoteFeatureExtractor } from './feature_extraction_pyannote.js';\n\nexport class PyAnnoteProcessor extends Processor {\n  static feature_extractor_class = PyAnnoteFeatureExtractor;\n\n  /**\n   * Calls the feature_extractor function with the given audio input.\n   * @param {any} audio The audio input to extract features from.\n   * @returns {Promise<any>} A Promise that resolves with the extracted features.\n   */\n  async _call(audio) {\n    return await this.feature_extractor(audio);\n  }\n\n  /** @type {PyAnnoteFeatureExtractor['post_process_speaker_diarization']} */\n  post_process_speaker_diarization(...args) {\n    return /** @type {PyAnnoteFeatureExtractor} */ this.feature_extractor.post_process_speaker_diarization(...args);\n  }\n\n  get sampling_rate() {\n    return this.feature_extractor.config.sampling_rate;\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { AutoImageProcessor } from '../auto/image_processing_auto.js';\nimport { AutoTokenizer } from '../../tokenizers.js';\nimport { RawImage } from '../../utils/image.js';\n\nexport class Qwen2VLProcessor extends Processor {\n  static image_processor_class = AutoImageProcessor;\n  static tokenizer_class = AutoTokenizer;\n\n  /**\n   *\n   * @param {string|string[]} text\n   * @param {RawImage|RawImage[]} images\n   * @param  {...any} args\n   * @returns {Promise<any>}\n   */\n  async _call(text, images = null, ...args) {\n    if (!Array.isArray(text)) {\n      text = [text];\n    }\n\n    let image_inputs, image_grid_thw;\n\n    if (images) {\n      image_inputs = await this.image_processor(images);\n      image_grid_thw = image_inputs.image_grid_thw;\n    }\n\n    if (image_grid_thw) {\n      // @ts-expect-error TS2551\n      let merge_length = this.image_processor.config.merge_size ** 2;\n      let index = 0;\n\n      const image_grid_thw_list = image_grid_thw.tolist();\n      text = text.map((t) => {\n        while (t.includes('<|image_pad|>')) {\n          const prod = Number(image_grid_thw_list[index++].reduce((a, b) => a * b, 1n));\n          t = t.replace('<|image_pad|>', '<|placeholder|>'.repeat(Math.floor(prod / merge_length)));\n        }\n        return t.replaceAll('<|placeholder|>', '<|image_pad|>');\n      });\n    }\n\n    const text_inputs = this.tokenizer(text);\n\n    return {\n      ...text_inputs,\n      ...image_inputs,\n      // TODO: ...videos_inputs,\n    };\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { AutoImageProcessor } from '../auto/image_processing_auto.js';\n\nexport class SamProcessor extends Processor {\n  static image_processor_class = AutoImageProcessor;\n\n  async _call(...args) {\n    return await this.image_processor(...args);\n  }\n\n  post_process_masks(...args) {\n    // @ts-ignore\n    return this.image_processor.post_process_masks(...args);\n  }\n\n  reshape_input_points(...args) {\n    // @ts-ignore\n    return this.image_processor.reshape_input_points(...args);\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { AutoTokenizer } from '../../tokenizers.js';\nimport { AutoFeatureExtractor } from '../auto/feature_extraction_auto.js';\n\nexport class SpeechT5Processor extends Processor {\n  static tokenizer_class = AutoTokenizer;\n  static feature_extractor_class = AutoFeatureExtractor;\n\n  /**\n   * Calls the feature_extractor function with the given input.\n   * @param {any} input The input to extract features from.\n   * @returns {Promise<any>} A Promise that resolves with the extracted features.\n   */\n  async _call(input) {\n    return await this.feature_extractor(input);\n  }\n}\n","import { Processor } from '../../base/processing_utils.js';\nimport { AutoFeatureExtractor } from '../auto/feature_extraction_auto.js';\n\nexport class Wav2Vec2ProcessorWithLM extends Processor {\n  static feature_extractor_class = AutoFeatureExtractor;\n\n  /**\n   * Calls the feature_extractor function with the given audio input.\n   * @param {any} audio The audio input to extract features from.\n   * @returns {Promise<any>} A Promise that resolves with the extracted features.\n   */\n  async _call(audio) {\n    return await this.feature_extractor(audio);\n  }\n}\n","import { AutoFeatureExtractor } from '../auto/feature_extraction_auto';\nimport { AutoTokenizer } from '../../tokenizers';\nimport { Processor } from '../../base/processing_utils';\n\n/**\n * Represents a WhisperProcessor that extracts features from an audio input.\n */\nexport class WhisperProcessor extends Processor {\n  static tokenizer_class = AutoTokenizer;\n  static feature_extractor_class = AutoFeatureExtractor;\n\n  /**\n   * Calls the feature_extractor function with the given audio input.\n   * @param {any} audio The audio input to extract features from.\n   * @returns {Promise<any>} A Promise that resolves with the extracted features.\n   */\n  async _call(audio) {\n    return await this.feature_extractor(audio);\n  }\n}\n","export * from './bit/image_processing_bit';\nexport * from './chinese_clip/image_processing_chinese_clip';\nexport * from './clip/image_processing_clip';\nexport * from './convnext/image_processing_convnext';\nexport * from './deit/image_processing_deit';\nexport * from './idefics3/image_processing_idefics3';\nexport * from './janus/image_processing_janus';\nexport * from './jina_clip/image_processing_jina_clip';\nexport * from './llava_onevision/image_processing_llava_onevision';\nexport * from './phi3_v/image_processing_phi3_v';\nexport * from './qwen2_vl/image_processing_qwen2_vl';\nexport * from './sam/image_processing_sam';\nexport * from './siglip/image_processing_siglip';\nexport * from './swin2sr/image_processing_swin2sr';\nexport * from './vitmatte/image_processing_vitmatte';\nexport * from './vitpose/image_processing_vitpose';\n","import { ImageProcessor } from '../../base/image_processors_utils';\n\nexport class BitImageProcessor extends ImageProcessor {}\n","import { ImageProcessor } from '../../base/image_processors_utils';\n\nexport class ChineseCLIPFeatureExtractor extends ImageProcessor {}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\n\nexport class CLIPImageProcessor extends ImageProcessor {}\nexport class CLIPFeatureExtractor extends CLIPImageProcessor {}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\n\nexport class ConvNextImageProcessor extends ImageProcessor {\n  constructor(config: any) {\n    super(config);\n\n    /**\n     * Percentage of the image to crop. Only has an effect if this.size < 384.\n     */\n    // @ts-expect-error TS2339\n    this.crop_pct = this.config.crop_pct ?? 224 / 256;\n  }\n\n  async resize(image: any) {\n    const shortest_edge = this.size?.shortest_edge;\n    if (shortest_edge === undefined) {\n      throw new Error(`Size dictionary must contain 'shortest_edge' key.`);\n    }\n\n    if (shortest_edge < 384) {\n      // maintain same ratio, resizing shortest edge to shortest_edge/crop_pct\n      const resize_shortest_edge = Math.floor(shortest_edge / this.crop_pct);\n\n      const [newWidth, newHeight] = this.get_resize_output_image_size(image, {\n        shortest_edge: resize_shortest_edge,\n      });\n\n      image = await image.resize(newWidth, newHeight, {\n        resample: this.resample,\n      });\n\n      // then crop to (shortest_edge, shortest_edge)\n      image = await image.center_crop(shortest_edge, shortest_edge);\n    } else {\n      // warping (no cropping) when evaluated at 384 or larger\n      image = await image.resize(shortest_edge, shortest_edge, {\n        resample: this.resample,\n      });\n    }\n\n    return image;\n  }\n}\nexport class ConvNextFeatureExtractor extends ConvNextImageProcessor {}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\n\nexport class DeiTImageProcessor extends ImageProcessor {}\nexport class DeiTFeatureExtractor extends DeiTImageProcessor {}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\nimport { RawImage } from '../../utils/image.js';\nimport { cat, full, interpolate_4d, slice, stack, Tensor } from '../../utils/tensor.js';\n\nexport class Idefics3ImageProcessor extends ImageProcessor {\n  do_image_splitting: boolean;\n  max_image_size: [number, number];\n\n  constructor(config: any) {\n    super(config);\n\n    this.do_image_splitting = config.do_image_splitting ?? true;\n    this.max_image_size = config.max_image_size;\n  }\n\n  /**\n   * @typedef {import('../../utils/image.js').RawImage} RawImage\n   * @typedef {import('../../utils/tensor.js').Tensor} Tensor\n   */\n\n  /**\n   * Calculate size to resize images to, to be multiples of `vision_encoder_max_size` while preserving the aspect ratio.\n   * @param {Tensor} pixel_values Tensor of the image to resize.\n   * @param {number} vision_encoder_max_size Maximum size of the output image. If the image is larger than this size,\n   * it will be split into patches of this size, and the original image will be concatenated with the patches, resized to max_size.\n   */\n  get_resize_for_vision_encoder(pixel_values: Tensor, vision_encoder_max_size: number) {\n    let [height, width] = pixel_values.dims.slice(-2);\n\n    const aspect_ratio = width / height;\n    if (width >= height) {\n      width = Math.ceil(width / vision_encoder_max_size) * vision_encoder_max_size;\n      height = Math.floor(width / aspect_ratio);\n      height = Math.ceil(height / vision_encoder_max_size) * vision_encoder_max_size;\n    } else {\n      height = Math.ceil(height / vision_encoder_max_size) * vision_encoder_max_size;\n      width = Math.floor(height * aspect_ratio);\n      width = Math.ceil(width / vision_encoder_max_size) * vision_encoder_max_size;\n    }\n    return { height, width };\n  }\n\n  /** @param {RawImage|RawImage[]|RawImage[][]} images */\n  async _call(\n    images: RawImage | RawImage[] | RawImage[][],\n    { do_image_splitting = null, return_row_col_info = false } = {},\n  ) {\n    /** @type {RawImage[][]} */\n    let batched_2d_images;\n    if (!Array.isArray(images)) {\n      batched_2d_images = [[images]];\n    } else {\n      if (images.length === 0 || !images[0]) {\n        throw new Error('No images provided.');\n      }\n      if (!Array.isArray(images[0])) {\n        batched_2d_images = [/** @type {RawImage[]} */ images];\n      } else {\n        batched_2d_images = /** @type {RawImage[][]} */ images;\n      }\n    }\n\n    // List of tensors, each with shape [patches, channels, height, width]\n    let all_pixel_values = [];\n    let images_list_rows = [];\n    let images_list_cols = [];\n\n    const original_sizes = [];\n    const reshaped_input_sizes = [];\n    for (const image_batch of batched_2d_images) {\n      let images_list = await Promise.all((image_batch as RawImage[]).map((x) => this.preprocess(x)));\n\n      // Original sizes of images\n      original_sizes.push(...images_list.map((x: any) => x.original_size));\n\n      // Reshaped sizes of images, before padding or cropping\n      reshaped_input_sizes.push(...images_list.map((x: any) => x.reshaped_input_size));\n\n      // Convert images to 4D tensors for easier processing\n      images_list.forEach((x: any) => x.pixel_values.unsqueeze_(0));\n\n      const longest_edge = this.max_image_size[0];\n\n      /** @type {Tensor[]} */\n      let images_tensor;\n      if (do_image_splitting ?? this.do_image_splitting) {\n        let image_rows = new Array(images_list.length);\n        let image_cols = new Array(images_list.length);\n\n        // We first resize both height and width of each image to the nearest max_image_size multiple, disregarding the aspect ratio\n        images_tensor = await Promise.all(\n          images_list.map(async (x: any, i: number) => {\n            const new_size = this.get_resize_for_vision_encoder(x.pixel_values, longest_edge);\n\n            const resized = await interpolate_4d(x.pixel_values, {\n              size: [new_size.height, new_size.width],\n            });\n\n            const { frames, num_splits_h, num_splits_w } = await this.split_image(resized, {\n              longest_edge: this.max_image_size[0],\n            });\n            image_rows[i] = num_splits_h;\n            image_cols[i] = num_splits_w;\n            return cat(frames, 0);\n          }),\n        );\n\n        images_list_rows.push(image_rows);\n        images_list_cols.push(image_cols);\n      } else {\n        /** @type {[number, number]} */\n        const size = [longest_edge, longest_edge];\n        images_tensor = await Promise.all(images_list.map((x: any) => interpolate_4d(x.pixel_values, { size })));\n\n        images_list_rows.push(new Array(images_list.length).fill(0));\n        images_list_cols.push(new Array(images_list.length).fill(0));\n      }\n\n      all_pixel_values.push(cat(images_tensor, 0));\n    }\n\n    const batch_size = all_pixel_values.length;\n    const [n, c, h, w] = all_pixel_values[0].dims;\n\n    // Stack pixel values\n    let pixel_values;\n    let pixel_attention_mask;\n    if (batch_size === 1) {\n      pixel_values = all_pixel_values[0].unsqueeze_(0);\n      pixel_attention_mask = full([batch_size, n, h, w], true);\n    } else {\n      // Add padding (if necessary) to images with less patches than the maximum number of patches\n      const max_num_patches = Math.max(...all_pixel_values.map((x) => x.dims.at(0)));\n\n      pixel_attention_mask = full([batch_size, max_num_patches, h, w], true);\n      const pixel_attention_mask_data = pixel_attention_mask.data as any;\n      const pixel_attention_mask_stride = max_num_patches * h * w;\n      for (let i = 0; i < batch_size; ++i) {\n        const num_patches: number = all_pixel_values[i].dims[0];\n        if (num_patches < max_num_patches) {\n          all_pixel_values[i] = cat([all_pixel_values[i], full([max_num_patches - num_patches, c, h, w], 0)], 0);\n\n          const start_offset = i * pixel_attention_mask_stride + num_patches * h * w;\n          const end_offset = (i + 1) * pixel_attention_mask_stride;\n\n          pixel_attention_mask_data.fill(false, start_offset, end_offset);\n        }\n      }\n      pixel_values = stack(all_pixel_values, 0);\n    }\n\n    return {\n      pixel_values,\n      pixel_attention_mask,\n\n      original_sizes,\n      reshaped_input_sizes,\n      ...(return_row_col_info ? { rows: images_list_rows, cols: images_list_cols } : {}),\n    };\n  }\n\n  async split_image(pixel_values: Tensor, { longest_edge }: { longest_edge: number }) {\n    const max_height = longest_edge;\n    const max_width = longest_edge;\n\n    const frames = [];\n\n    const [height, width] = pixel_values.dims.slice(-2);\n\n    let num_splits_h = 0,\n      num_splits_w = 0;\n\n    if (height > max_height || width > max_width) {\n      // Calculate the number of splits\n      num_splits_h = Math.ceil(height / max_height);\n      num_splits_w = Math.ceil(width / max_width);\n\n      // Calculate the optimal width and height for the sub-images\n      const optimal_height = Math.ceil(height / num_splits_h);\n      const optimal_width = Math.ceil(width / num_splits_w);\n\n      // Iterate through each row and column\n      for (let r = 0; r < num_splits_h; ++r) {\n        for (let c = 0; c < num_splits_w; ++c) {\n          let start_x, start_y, end_x, end_y;\n          if (r === num_splits_h - 1) {\n            // At bottom\n            start_y = height - optimal_height;\n            end_y = height;\n          } else {\n            start_y = r * optimal_height;\n            end_y = (r + 1) * optimal_height;\n          }\n          if (c === num_splits_w - 1) {\n            // At right\n            start_x = width - optimal_width;\n            end_x = width;\n          } else {\n            start_x = c * optimal_width;\n            end_x = (c + 1) * optimal_width;\n          }\n\n          const starts = [start_y, start_x];\n          const ends = [end_y, end_x];\n\n          const patch = await slice(pixel_values, starts, ends, [2, 3]);\n          frames.push(patch);\n        }\n      }\n\n      // Resize the global image to match max dimensions for memory efficiency\n      const global_image_height = max_height;\n      const global_image_width = max_width;\n\n      if (height !== global_image_height || width !== global_image_width) {\n        pixel_values = await interpolate_4d(pixel_values, {\n          size: [global_image_height, global_image_width],\n        });\n      }\n    }\n\n    frames.push(pixel_values);\n\n    return { frames, num_splits_h, num_splits_w };\n  }\n}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\n\nexport class JinaCLIPImageProcessor extends ImageProcessor {\n  constructor(config) {\n    // JinaCLIPImageProcessor uses a custom preprocessor_config.json, so we configure it here\n    const { resize_mode, fill_color, interpolation, size, ...other } = config;\n\n    const new_size =\n      resize_mode === 'squash'\n        ? { width: size, height: size }\n        : resize_mode === 'shortest'\n          ? { shortest_edge: size }\n          : { longest_edge: size };\n\n    const resample = interpolation === 'bicubic' ? 3 : 2;\n    super({\n      ...other,\n      size: new_size,\n      resample,\n      do_center_crop: true,\n      crop_size: size,\n      do_normalize: true,\n    });\n  }\n}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\n\nexport class LlavaOnevisionImageProcessor extends ImageProcessor {}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\nimport { cat, interpolate_4d, slice, stack, Tensor } from '../../utils/tensor.js';\n\nconst IMAGE_SIZE = 336;\nconst SLICE_AXES = [2, 3]; // axes to slice on\nconst { ceil, floor, sqrt } = Math;\n\nexport class Phi3VImageProcessor extends ImageProcessor {\n  constructor(config) {\n    super({\n      ...config,\n      do_normalize: true,\n      do_pad: true,\n      pad_size: 'custom',\n      do_convert_rgb: true,\n      do_resize: true, // Smart resizing \"hd_transform\"\n    });\n\n    this._num_crops = config.num_crops;\n  }\n  calc_num_image_tokens_from_image_size(width, height) {\n    // @ts-expect-error\n    const { num_img_tokens } = this.config;\n    return floor(\n      (floor(height / IMAGE_SIZE) * floor(width / IMAGE_SIZE) + 1) * num_img_tokens +\n        1 +\n        (floor(height / IMAGE_SIZE) + 1) * sqrt(num_img_tokens),\n    );\n  }\n\n  /** @type {ImageProcessor['get_resize_output_image_size']} */\n  get_resize_output_image_size(image, size) {\n    const hd_num = this._num_crops;\n    const [width, height] = image.size;\n\n    let ratio = width / height;\n    let scale = 1;\n\n    // Calculate the scaling factor\n    while (scale * Math.ceil(scale / ratio) <= hd_num) {\n      scale += 1;\n    }\n    scale -= 1;\n\n    // Compute the new dimensions\n    const new_w = Math.floor(scale * 336);\n    const new_h = Math.floor(new_w / ratio);\n\n    return [new_w, new_h];\n  }\n\n  /** @type {ImageProcessor['pad_image']} */\n  pad_image(pixelData, imgDims, padSize, options = {}) {\n    // Phi3V uses a custom padding strategy:\n    // - Pad to a multiple of 336\n    // - Pad with white pixels\n    const [imageHeight, imageWidth] = imgDims;\n    const height = IMAGE_SIZE * ceil(imageHeight / IMAGE_SIZE);\n    const width = IMAGE_SIZE * ceil(imageWidth / IMAGE_SIZE);\n\n    // NOTE: Since padding is done after normalization, we need to fill with the normalized values\n    const constant_values = [1, 1, 1].map((x, i) => (x - this.image_mean[i]) / this.image_std[i]);\n    return super.pad_image(\n      pixelData,\n      imgDims,\n      { width, height },\n      {\n        center: true,\n        constant_values,\n        ...options,\n      },\n    );\n  }\n\n  async _call(images, { num_crops = null } = {}) {\n    // @ts-expect-error\n    this._num_crops = num_crops ??= this.config.num_crops;\n    if (num_crops < 4 || sqrt(num_crops) % 1 !== 0) {\n      throw new Error('num_crops must be a square number >= 4');\n    }\n\n    if (!Array.isArray(images)) {\n      images = [images];\n    }\n\n    const num_images = images.length;\n    const imageData = await Promise.all(images.map((x) => this.preprocess(x)));\n\n    const original_sizes = imageData.map((x) => x.original_size);\n    const reshaped_input_sizes = imageData.map((x) => x.reshaped_input_size);\n\n    // Process each image in batch\n    const all_pixel_values = [];\n    for (const { pixel_values } of imageData) {\n      pixel_values.unsqueeze_(0); // Easier processing as 4D tensor\n\n      const [height, width] = pixel_values.dims.slice(-2);\n\n      // Global image (Tensor of shape [num_channels, height, width])\n      const batch_pixel_values = await interpolate_4d(pixel_values, {\n        size: [IMAGE_SIZE, IMAGE_SIZE],\n        mode: 'bicubic',\n      });\n\n      if (num_crops > 0) {\n        const patches = [];\n        const sqrt_patches = sqrt(num_crops);\n        const patch_width = floor(width / sqrt_patches);\n        const patch_height = floor(height / sqrt_patches);\n        for (let y = 0; y < sqrt_patches; ++y) {\n          for (let x = 0; x < sqrt_patches; ++x) {\n            let start_x, start_y, end_x, end_y;\n            if (y === sqrt_patches - 1) {\n              // At bottom\n              start_y = height - patch_height;\n              end_y = height;\n            } else {\n              start_y = y * patch_height;\n              end_y = (y + 1) * patch_height;\n            }\n            if (x === sqrt_patches - 1) {\n              // At right\n              start_x = width - patch_width;\n              end_x = width;\n            } else {\n              start_x = x * patch_width;\n              end_x = (x + 1) * patch_width;\n            }\n\n            const starts = [start_y, start_x];\n            const ends = [end_y, end_x];\n            const patch = await slice(pixel_values, starts, ends, SLICE_AXES);\n            patches.push(patch);\n          }\n        }\n\n        const resized_tensors = await interpolate_4d(cat(patches, 0), {\n          size: [IMAGE_SIZE, IMAGE_SIZE],\n          mode: 'bicubic',\n        }); // [num_crops, 3, 336, 336]\n\n        // Concatenate the global image with the patches\n        all_pixel_values.push(cat([batch_pixel_values, resized_tensors], 0));\n      } else {\n        // Only use the global image\n        // NOTE: Not currently supported in modelling code\n        all_pixel_values.push(batch_pixel_values);\n      }\n    }\n\n    // [num_images, 1 + num_crops, num_channels=3, height, width]\n    const pixel_values = stack(all_pixel_values, 0);\n\n    // Calculate padded image sizes\n    const sizes = reshaped_input_sizes.map((x) => x.map((y) => IMAGE_SIZE * ceil(y / IMAGE_SIZE)));\n\n    const image_sizes = new Tensor('int64', sizes.flat(), [num_images, 2]);\n\n    const num_img_tokens = sizes.map(([height, width]) => this.calc_num_image_tokens_from_image_size(width, height));\n\n    return { pixel_values, original_sizes, reshaped_input_sizes, image_sizes, num_img_tokens };\n  }\n}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\nimport { cat, Tensor } from '../../utils/tensor.js';\n\nexport class Qwen2VLImageProcessor extends ImageProcessor {\n  async _call(images, ...args) {\n    const { pixel_values, original_sizes, reshaped_input_sizes } = await super._call(images, ...args);\n\n    let patches = pixel_values;\n\n    // @ts-ignore\n    const { temporal_patch_size, merge_size, patch_size } = this.config;\n    if (patches.dims[0] === 1) {\n      // Equivalent to np.tile(patches, (self.temporal_patch_size, 1, 1, 1))\n      patches = cat(\n        Array.from({ length: temporal_patch_size }, () => patches),\n        0,\n      );\n    }\n\n    const grid_t = patches.dims[0] / temporal_patch_size;\n    const channel = patches.dims[1];\n    const grid_h = Math.floor(patches.dims[2] / patch_size);\n    const grid_w = Math.floor(patches.dims[3] / patch_size);\n\n    const flatten_patches = patches\n      .view(\n        grid_t,\n        temporal_patch_size,\n        channel,\n        Math.floor(grid_h / merge_size),\n        merge_size,\n        patch_size,\n        Math.floor(grid_w / merge_size),\n        merge_size,\n        patch_size,\n      )\n      .permute(0, 3, 6, 4, 7, 2, 1, 5, 8)\n      .view(grid_t * grid_h * grid_w, channel * temporal_patch_size * patch_size * patch_size);\n\n    const image_grid_thw = new Tensor('int64', [grid_t, grid_h, grid_w], [1, 3]);\n\n    return {\n      pixel_values: flatten_patches,\n      image_grid_thw,\n      original_sizes,\n      reshaped_input_sizes,\n    };\n  }\n}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\nimport { calculateDimensions } from '../../utils/core.js';\n\nimport { interpolate_4d, Tensor } from '../../utils/tensor.js';\n\n/**\n * @typedef {object} SamImageProcessorResult\n * @property {Tensor} pixel_values\n * @property {import(\"../../base/image_processors_utils.js\").HeightWidth[]} original_sizes\n * @property {import(\"../../base/image_processors_utils.js\").HeightWidth[]} reshaped_input_sizes\n * @property {Tensor} [input_points]\n * @property {Tensor} [input_labels]\n * @property {Tensor} [input_boxes]\n */\n\nexport class SamImageProcessor extends ImageProcessor {\n  /**\n   *\n   * @param {any} input_points\n   * @param {import(\"../../base/image_processors_utils.js\").HeightWidth[]} original_sizes\n   * @param {import(\"../../base/image_processors_utils.js\").HeightWidth[]} reshaped_input_sizes\n   * @returns {Tensor}\n   */\n  reshape_input_points(input_points, original_sizes, reshaped_input_sizes, is_bounding_box = false) {\n    // Make deep copy to avoid altering user's input\n    input_points = structuredClone(input_points);\n    let shape = calculateDimensions(input_points);\n\n    // TODO: add support for 2D input_points\n    if (shape.length === 3) {\n      // Correct user's input\n      if (!is_bounding_box) {\n        shape = [1, ...shape];\n      }\n      input_points = [input_points];\n    } else if (shape.length !== 4) {\n      throw Error(\n        'The input_points must be a 4D tensor of shape `batch_size`, `point_batch_size`, `nb_points_per_image`, `2`.',\n      );\n    }\n\n    // Reshape input points\n    for (let i = 0; i < input_points.length; ++i) {\n      // batch_size\n      let originalImageSize = original_sizes[i];\n      let reshapedImageSize = reshaped_input_sizes[i];\n\n      let resizeFactors = [reshapedImageSize[0] / originalImageSize[0], reshapedImageSize[1] / originalImageSize[1]];\n\n      for (let j = 0; j < input_points[i].length; ++j) {\n        // point_batch_size\n        for (let k = 0; k < input_points[i][j].length; ++k) {\n          // nb_points_per_image\n          for (let w = 0; w < input_points[i][j][k].length; ++w) {\n            // 2 or 4\n            input_points[i][j][k][w] *= resizeFactors[w % 2];\n          }\n        }\n      }\n    }\n\n    return new Tensor('float32', Float32Array.from(input_points.flat(Infinity)), shape);\n  }\n\n  /**\n   *\n   * @param {any} input_labels\n   * @param {Tensor} input_points\n   * @returns {Tensor}\n   */\n  add_input_labels(input_labels, input_points) {\n    let shape = calculateDimensions(input_labels);\n    if (shape.length === 2) {\n      // Correct user's input\n      shape = [1, ...shape];\n      input_labels = [input_labels];\n    } else if (shape.length !== 3) {\n      throw Error(\n        'The input_points must be a 4D tensor of shape `batch_size`, `point_batch_size`, `nb_points_per_image`, `2`.',\n      );\n    }\n\n    if (shape.some((x, i) => x !== input_points.dims[i])) {\n      throw Error(`The first ${shape.length} dimensions of 'input_points' and 'input_labels' must be the same.`);\n    }\n    return new Tensor('int64', input_labels.flat(Infinity).map(BigInt), shape);\n  }\n  /**\n   * @param {any[]} images The URL(s) of the image(s) to extract features from.\n   * @param {Object} [options] Additional options for the processor.\n   * @param {any} [options.input_points=null] A 3D or 4D array, representing the input points provided by the user.\n   * - 3D: `[point_batch_size, nb_points_per_image, 2]`. In this case, `batch_size` is assumed to be 1.\n   * - 4D: `[batch_size, point_batch_size, nb_points_per_image, 2]`.\n   * @param {any} [options.input_labels=null] A 2D or 3D array, representing the input labels for the points, used by the prompt encoder to encode the prompt.\n   * - 2D: `[point_batch_size, nb_points_per_image]`. In this case, `batch_size` is assumed to be 1.\n   * - 3D: `[batch_size, point_batch_size, nb_points_per_image]`.\n   * @param {number[][][]} [options.input_boxes=null] A 3D array of shape `(batch_size, num_boxes, 4)`, representing the input boxes provided by the user.\n   * This is used by the prompt encoder to encode the prompt. Generally yields to much better generated masks.\n   * The processor will generate a tensor, with each dimension corresponding respectively to the image batch size,\n   * the number of boxes per image and the coordinates of the top left and botton right point of the box.\n   * In the order (`x1`, `y1`, `x2`, `y2`):\n   * - `x1`: the x coordinate of the top left point of the input box\n   * - `y1`: the y coordinate of the top left point of the input box\n   * - `x2`: the x coordinate of the bottom right point of the input box\n   * - `y2`: the y coordinate of the bottom right point of the input box\n   * @returns {Promise<SamImageProcessorResult>}\n   */\n  async _call(images, { input_points = null, input_labels = null, input_boxes = null } = {}) {\n    // TODO allow user to use preprocessed images\n    /** @type {SamImageProcessorResult} */\n    const processed = await super._call(images);\n\n    if (input_points) {\n      processed.input_points = this.reshape_input_points(\n        input_points,\n        processed.original_sizes,\n        processed.reshaped_input_sizes,\n      );\n    }\n\n    if (input_labels) {\n      if (!processed.input_points) {\n        throw Error('`input_points` must be provided if `input_labels` are provided.');\n      }\n      processed.input_labels = this.add_input_labels(input_labels, processed.input_points);\n    }\n\n    if (input_boxes) {\n      processed.input_boxes = this.reshape_input_points(\n        input_boxes,\n        processed.original_sizes,\n        processed.reshaped_input_sizes,\n        true,\n      );\n    }\n\n    return processed;\n  }\n\n  /**\n   * Remove padding and upscale masks to the original image size.\n   * @param {Tensor} masks Batched masks from the mask_decoder in (batch_size, num_channels, height, width) format.\n   * @param {[number, number][]} original_sizes The original sizes of each image before it was resized to the model's expected input shape, in (height, width) format.\n   * @param {[number, number][]} reshaped_input_sizes The size of each image as it is fed to the model, in (height, width) format. Used to remove padding.\n   * @param {Object} options Optional parameters for post-processing.\n   * @param {number} [options.mask_threshold] The threshold to use for binarizing the masks.\n   * @param {boolean} [options.binarize] Whether to binarize the masks.\n   * @param {Object} [options.pad_size] The target size the images were padded to before being passed to the model. If `null`, the target size is assumed to be the processor's `pad_size`.\n   * @param {number} [options.pad_size.height] The height the images were padded to.\n   * @param {number} [options.pad_size.width] The width the images were padded to.\n   * @returns {Promise<Tensor[]>} Batched masks in batch_size, num_channels, height, width) format, where (height, width) is given by original_size.\n   */\n  async post_process_masks(\n    masks,\n    original_sizes,\n    reshaped_input_sizes,\n    { mask_threshold = 0.0, binarize = true, pad_size = null } = {},\n  ) {\n    // masks: [1, 1, 3, 256, 256]\n\n    const output_masks = [];\n\n    pad_size = pad_size ?? this.pad_size;\n\n    /** @type {[number, number]} */\n    const target_image_size = [pad_size.height, pad_size.width];\n\n    for (let i = 0; i < original_sizes.length; ++i) {\n      const original_size = original_sizes[i];\n      const reshaped_input_size = reshaped_input_sizes[i];\n\n      // Upscale mask to padded size\n      let interpolated_mask = await interpolate_4d(masks[i], { mode: 'bilinear', size: target_image_size });\n\n      // Crop mask\n      interpolated_mask = interpolated_mask.slice(null, null, [0, reshaped_input_size[0]], [0, reshaped_input_size[1]]);\n\n      // Downscale mask\n      interpolated_mask = await interpolate_4d(interpolated_mask, { mode: 'bilinear', size: original_size });\n\n      if (binarize) {\n        const data = interpolated_mask.data;\n        const binarizedMaskData = new Uint8Array(data.length);\n        for (let i = 0; i < data.length; ++i) {\n          if (data[i] > mask_threshold) {\n            binarizedMaskData[i] = 1;\n          }\n        }\n        interpolated_mask = new Tensor('bool', binarizedMaskData, interpolated_mask.dims);\n      }\n\n      output_masks.push(interpolated_mask);\n    }\n\n    return output_masks;\n  }\n\n  /**\n   * Generates a list of crop boxes of different sizes. Each layer has (2**i)**2 boxes for the ith layer.\n   * @param {import(\"../../utils/image.js\").RawImage} image Input original image\n   * @param {number} target_size Target size of the resized image\n   * @param {Object} options Options for generating crop boxes\n   * @param {number} [options.crop_n_layers] If >0, mask prediction will be run again on crops of the image.\n   * Sets the number of layers to run, where each layer has 2**i_layer number of image crops.\n   * @param {number} [options.overlap_ratio] Sets the degree to which crops overlap. In the first crop layer,\n   * crops will overlap by this fraction of the image length. Later layers with more crops scale down this overlap.\n   * @param {number} [options.points_per_crop] Number of points to sample from each crop.\n   * @param {number} [options.crop_n_points_downscale_factor] The number of points-per-side sampled in layer n is\n   * scaled down by crop_n_points_downscale_factor**n.\n   * @returns {Object} An object containing the crop boxes, number of points per crop, cropped images, and input labels.\n   */\n  generate_crop_boxes(\n    image,\n    target_size,\n    { crop_n_layers = 0, overlap_ratio = 512 / 1500, points_per_crop = 32, crop_n_points_downscale_factor = 1 } = {},\n  ) {\n    // TODO: Implement\n    // return { crop_boxes, points_per_crop, cropped_images, input_labels }\n  }\n}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\n\nexport class SiglipImageProcessor extends ImageProcessor {}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\n\nexport class Swin2SRImageProcessor extends ImageProcessor {\n  pad_image(pixelData, imgDims, padSize, options = {}) {\n    // NOTE: In this case, `padSize` represents the size of the sliding window for the local attention.\n    // In other words, the image is padded so that its width and height are multiples of `padSize`.\n    const [imageHeight, imageWidth, imageChannels] = imgDims;\n\n    return super.pad_image(\n      pixelData,\n      imgDims,\n      {\n        // NOTE: For Swin2SR models, the original python implementation adds padding even when the image's width/height is already\n        // a multiple of `pad_size`. However, this is most likely a bug (PR: https://github.com/mv-lab/swin2sr/pull/19).\n        // For this reason, we only add padding when the image's width/height is not a multiple of `pad_size`.\n        width: imageWidth + ((padSize - (imageWidth % padSize)) % padSize),\n        height: imageHeight + ((padSize - (imageHeight % padSize)) % padSize),\n      },\n      {\n        mode: 'symmetric',\n        center: false,\n        constant_values: -1,\n        ...options,\n      },\n    );\n  }\n}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\n\nimport { stack, cat } from '../../utils/tensor.js';\n\nexport class VitMatteImageProcessor extends ImageProcessor {\n  /**\n   * Calls the feature extraction process on an array of images, preprocesses\n   * each image, and concatenates the resulting features into a single Tensor.\n   * @param {import(\"../../utils/image.js\").RawImage[]} images The image(s) to extract features from.\n   * @param {import(\"../../utils/image.js\").RawImage[]} trimaps The trimaps(s) to extract features from.\n   * @returns {Promise<import(\"../../base/image_processors_utils.js\").ImageProcessorResult>} An object containing the concatenated pixel values of the preprocessed images.\n   */\n  async _call(images, trimaps) {\n    if (!Array.isArray(images)) {\n      images = [images];\n    }\n    if (!Array.isArray(trimaps)) {\n      trimaps = [trimaps];\n    }\n\n    const imageData = await Promise.all(images.map((x) => this.preprocess(x)));\n    const trimapData = await Promise.all(\n      trimaps.map((x) =>\n        this.preprocess(x, {\n          do_normalize: false,\n          do_convert_rgb: false,\n          do_convert_grayscale: true,\n        }),\n      ),\n    );\n\n    // Stack pixel values\n    const pixel_values = stack(\n      imageData.map(\n        // Concatenate images and trimaps\n        (x, i) => cat([x.pixel_values, trimapData[i].pixel_values], 0),\n      ),\n      0,\n    );\n\n    return {\n      pixel_values,\n\n      // Original sizes of images\n      original_sizes: imageData.map((x) => x.original_size),\n\n      // Reshaped sizes of images, before padding or cropping\n      reshaped_input_sizes: imageData.map((x) => x.reshaped_input_size),\n    };\n  }\n}\n","import { ImageProcessor } from '../../base/image_processors_utils.js';\n\nexport class VitPoseImageProcessor extends ImageProcessor {\n  /**\n   * Transform the heatmaps into keypoint predictions and transform them back to the image.\n   * NOTE: This is a naive implementation and does not include advanced post-processing techniques,\n   * so the results may not be as accurate as the original implementation.\n   * @param {import('../../utils/tensor.js').Tensor} outputs The model outputs.\n   * @param {[number, number, number, number][][]} boxes List or array of bounding boxes for each image.\n   * Each box should be a list of 4 floats representing the bounding box coordinates in COCO format (top_left_x, top_left_y, width, height).\n   * @returns {{\n   *   bbox: [number, number, number, number],\n   *   scores: number[],\n   *   labels: number[],\n   *   keypoints: [number, number][]\n   * }[][]} List of keypoints predictions for each image.\n   */\n  post_process_pose_estimation(\n    outputs,\n    boxes,\n    {\n      threshold = null,\n      // TODO:\n      // kernel_size = 11,\n      // target_sizes = null,\n    } = {},\n  ) {\n    // NOTE: boxes are 3D (batch_size, num_boxes, 4)\n    const heatmaps = outputs.tolist();\n    const [batch_size, num_classes, height, width] = outputs.dims;\n\n    const results = [];\n    for (let b = 0; b < batch_size; ++b) {\n      const heatmap = heatmaps[b];\n      const bboxes = boxes[b];\n\n      const batch_results = [];\n      for (let n = 0; n < bboxes.length; ++n) {\n        const bbox = bboxes[n];\n\n        const keypoints = [];\n        const scores = [];\n        const labels = [];\n\n        const xScale = bbox.at(-2) / width;\n        const yScale = bbox.at(-1) / height;\n        for (let c = 0; c < heatmap.length; ++c) {\n          let [xWeightedSum, yWeightedSum] = [0, 0];\n          let sum = 0;\n          let score = -Infinity;\n          const row = heatmap[c];\n          for (let y = 0; y < row.length; ++y) {\n            const col = row[y];\n            for (let x = 0; x < col.length; ++x) {\n              const value = col[x];\n              sum += value;\n\n              score = Math.max(score, value);\n\n              // Get weighted sum of positions\n              // TODO: Determine best offsets\n              xWeightedSum += (x + 0.5) * value;\n              yWeightedSum += y * value;\n            }\n          }\n\n          // Ignore low scores, if threshold is set\n          if (threshold != null && score < threshold) continue;\n\n          /** @type {[number, number]} */\n          const keypoint = [(xScale * xWeightedSum) / sum, (yScale * yWeightedSum) / sum];\n          keypoints.push(keypoint);\n          labels.push(c);\n          scores.push(score);\n        }\n        batch_results.push({\n          bbox,\n          scores,\n          labels,\n          keypoints,\n        });\n      }\n      results.push(batch_results);\n    }\n    return results;\n  }\n}\n","import { IMAGE_PROCESSOR_NAME } from '../../utils/constants.js';\nimport { getModelJSON } from '../../utils/hub.js';\nimport { Processor } from '../../base/processing_utils.js';\n\nimport * as AllProcessors from '../processors.js';\nimport * as AllImageProcessors from '../image_processors.js';\nimport * as AllFeatureExtractors from '../feature_extractors.js';\n\n/**\n * Helper class which is used to instantiate pretrained processors with the `from_pretrained` function.\n * The chosen processor class is determined by the type specified in the processor config.\n *\n * **Example:** Load a processor using `from_pretrained`.\n * ```javascript\n * let processor = await AutoProcessor.from_pretrained('openai/whisper-tiny.en');\n * ```\n *\n * **Example:** Run an image through a processor.\n * ```javascript\n * let processor = await AutoProcessor.from_pretrained('Xenova/clip-vit-base-patch16');\n * let image = await RawImage.read('https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/football-match.jpg');\n * let image_inputs = await processor(image);\n * // {\n * //   \"pixel_values\": {\n * //     \"dims\": [ 1, 3, 224, 224 ],\n * //     \"type\": \"float32\",\n * //     \"data\": Float32Array [ -1.558687686920166, -1.558687686920166, -1.5440893173217773, ... ],\n * //     \"size\": 150528\n * //   },\n * //   \"original_sizes\": [\n * //     [ 533, 800 ]\n * //   ],\n * //   \"reshaped_input_sizes\": [\n * //     [ 224, 224 ]\n * //   ]\n * // }\n * ```\n */\nexport class AutoProcessor extends Processor {\n  /** @type {typeof Processor.from_pretrained} */\n  static async from_pretrained(pretrained_model_name_or_path: string, options = {}): Promise<Processor> {\n    // TODO: first check for processor.json\n    const preprocessorConfig = await getModelJSON(pretrained_model_name_or_path, IMAGE_PROCESSOR_NAME, true, options);\n\n    const { image_processor_type, feature_extractor_type, processor_class } = preprocessorConfig;\n    if (processor_class && AllProcessors[processor_class as keyof typeof AllProcessors]) {\n      return AllProcessors[processor_class as keyof typeof AllProcessors].from_pretrained(\n        pretrained_model_name_or_path,\n        options,\n      );\n    }\n\n    if (!image_processor_type && !feature_extractor_type) {\n      throw new Error('No `image_processor_type` or `feature_extractor_type` found in the config.');\n    }\n\n    const components: Record<string, any> = {};\n    if (image_processor_type) {\n      const image_processor_class = AllImageProcessors[image_processor_type as keyof typeof AllImageProcessors];\n      if (!image_processor_class) {\n        throw new Error(`Unknown image_processor_type: '${image_processor_type}'.`);\n      }\n      components.image_processor = new image_processor_class(preprocessorConfig);\n    }\n\n    if (feature_extractor_type) {\n      const image_processor_class = AllImageProcessors[feature_extractor_type as keyof typeof AllImageProcessors];\n      if (image_processor_class) {\n        // Handle legacy case where image processors were specified as feature extractors\n        components.image_processor = new image_processor_class(preprocessorConfig);\n      } else {\n        const feature_extractor_class =\n          AllFeatureExtractors[feature_extractor_type as keyof typeof AllFeatureExtractors];\n        if (!feature_extractor_class) {\n          throw new Error(`Unknown feature_extractor_type: '${feature_extractor_type}'.`);\n        }\n        components.feature_extractor = new feature_extractor_class(preprocessorConfig);\n      }\n    }\n\n    const config = {};\n    return new Processor(config, components);\n  }\n}\n","/**\n * @file Pipelines provide a high-level, easy to use, API for running machine learning models.\n *\n * **Example:** Instantiate pipeline using the `pipeline` function.\n * ```javascript\n * import { pipeline } from '@huggingface/transformers';\n *\n * const classifier = await pipeline('sentiment-analysis');\n * const output = await classifier('I love transformers!');\n * // [{'label': 'POSITIVE', 'score': 0.999817686}]\n * ```\n *\n * @module pipelines\n */\n\nimport { AutoTokenizer, PreTrainedTokenizer } from './tokenizers';\nimport {\n  AutoModel,\n  AutoModelForSpeechSeq2Seq,\n  AutoModelForTextToWaveform,\n  AutoModelForTextToSpectrogram,\n  AutoModelForCTC,\n  AutoModelForCausalLM,\n  AutoModelForVision2Seq,\n  AutoModelForImageToImage,\n  AutoModelForImageFeatureExtraction,\n  PreTrainedModel,\n} from './models';\nimport { AutoProcessor } from './models/auto/processing_auto';\nimport { Processor } from './base/processing_utils';\n\nimport { Callable } from './utils/generic.js';\n\nimport { dispatchCallback, product } from './utils/core';\nimport { softmax, max, round } from './utils/maths';\nimport { read_audio, RawAudio } from './utils/audio';\nimport { Tensor, mean_pooling, interpolate_4d, quantize_embeddings, topk } from './utils/tensor';\nimport { RawImage } from './utils/image';\nimport { PretrainedOptions } from './utils/hub';\nimport { ImagePipelineConstructorArgs, Message, TextGenerationOutput, TextImagePipelineConstructorArgs } from './types';\nimport {\n  ImageFeatureExtractionPipelineOptions,\n  ImagePipelineInputs,\n  AudioPipelineInputs,\n  TextPipelineConstructorArgs,\n  PipelineType,\n  TextAudioPipelineConstructorArgs,\n} from './types';\n/**\n * @typedef {string | RawImage | URL} ImageInput\n * @typedef {ImageInput|ImageInput[]} ImagePipelineInputs\n */\n\n/**\n * Prepare images for further tasks.\n * @param {ImagePipelineInputs} images images to prepare.\n * @returns {Promise<RawImage[]>} returns processed images.\n * @private\n */\n\nasync function prepareImages(images: ImagePipelineInputs) {\n  if (!Array.isArray(images)) {\n    images = [images];\n  }\n\n  // Possibly convert any non-images to images\n  return await Promise.all(images.map((x) => RawImage.read(x)));\n}\n\n/**\n * @typedef {string | URL | Float32Array | Float64Array} AudioInput\n * @typedef {AudioInput|AudioInput[]} AudioPipelineInputs\n */\n\ntype AudioInput = string | URL | Float32Array | Float64Array;\n\n/**\n * Prepare audios for further tasks.\n * @param {AudioPipelineInputs} audios audios to prepare.\n * @param {number} sampling_rate sampling rate of the audios.\n * @returns {Promise<Float32Array[]>} The preprocessed audio data.\n * @private\n */\nasync function prepareAudios(audios: AudioPipelineInputs, sampling_rate: number) {\n  if (!Array.isArray(audios)) {\n    audios = [audios];\n  }\n\n  return await Promise.all(\n    audios.map((x) => {\n      if (typeof x === 'string' || x instanceof URL) {\n        return read_audio(x, sampling_rate);\n      } else if (x instanceof Float64Array) {\n        return new Float32Array(x);\n      }\n      return x;\n    }),\n  );\n}\n\n/**\n * @typedef {Object} BoundingBox\n * @property {number} xmin The minimum x coordinate of the bounding box.\n * @property {number} ymin The minimum y coordinate of the bounding box.\n * @property {number} xmax The maximum x coordinate of the bounding box.\n * @property {number} ymax The maximum y coordinate of the bounding box.\n */\n\n/**\n * Helper function to convert list [xmin, xmax, ymin, ymax] into object { \"xmin\": xmin, ... }\n * @param {number[]} box The bounding box as a list.\n * @param {boolean} asInteger Whether to cast to integers.\n * @returns {BoundingBox} The bounding box as an object.\n * @private\n */\nfunction get_bounding_box(box: number[], asInteger: boolean) {\n  if (asInteger) {\n    box = box.map((x) => x | 0);\n  }\n  const [xmin, ymin, xmax, ymax] = box;\n\n  return { xmin, ymin, xmax, ymax };\n}\n\n/**\n * @callback DisposeType Disposes the item.\n * @returns {Promise<void>} A promise that resolves when the item has been disposed.\n *\n * @typedef {Object} Disposable\n * @property {DisposeType} dispose A promise that resolves when the pipeline has been disposed.\n */\n\n/**\n * The Pipeline class is the class from which all pipelines inherit.\n * Refer to this class for methods shared across different pipelines.\n */\nexport abstract class Pipeline extends Callable {\n  /**\n   * Create a new Pipeline.\n   * @param {Object} options An object containing the following properties:\n   * @param {string} [options.task] The task of the pipeline. Useful for specifying subtasks.\n   * @param {PreTrainedModel} [options.model] The model used by the pipeline.\n   * @param {PreTrainedTokenizer} [options.tokenizer=null] The tokenizer used by the pipeline (if any).\n   * @param {Processor} [options.processor=null] The processor used by the pipeline (if any).\n   */\n  task: string;\n  model: PreTrainedModel;\n  tokenizer: PreTrainedTokenizer | null;\n  processor: Processor | null;\n\n  constructor({\n    task,\n    model,\n    tokenizer = null,\n    processor = null,\n  }: {\n    task: string;\n    model: PreTrainedModel;\n    tokenizer?: PreTrainedTokenizer | null;\n    processor?: Processor | null;\n  }) {\n    super();\n    this.task = task;\n    this.model = model;\n    this.tokenizer = tokenizer;\n    this.processor = processor;\n  }\n\n  async dispose(): Promise<void> {\n    await this.model.dispose();\n  }\n\n  public abstract _call(...args: any[]): Promise<any>;\n}\n\n/**\n * @typedef {Object} ModelTokenizerConstructorArgs\n * @property {string} task The task of the pipeline. Useful for specifying subtasks.\n * @property {PreTrainedModel} model The model used by the pipeline.\n * @property {PreTrainedTokenizer} tokenizer The tokenizer used by the pipeline.\n *\n * @typedef {ModelTokenizerConstructorArgs} TextPipelineConstructorArgs An object used to instantiate a text-based pipeline.\n */\n\n/**\n * @typedef {Object} ModelProcessorConstructorArgs\n * @property {string} task The task of the pipeline. Useful for specifying subtasks.\n * @property {PreTrainedModel} model The model used by the pipeline.\n * @property {Processor} processor The processor used by the pipeline.\n *\n * @typedef {ModelProcessorConstructorArgs} AudioPipelineConstructorArgs An object used to instantiate an audio-based pipeline.\n * @typedef {ModelProcessorConstructorArgs} ImagePipelineConstructorArgs An object used to instantiate an image-based pipeline.\n */\n\n/**\n * @typedef {Object} ModelTokenizerProcessorConstructorArgs\n * @property {string} task The task of the pipeline. Useful for specifying subtasks.\n * @property {PreTrainedModel} model The model used by the pipeline.\n * @property {PreTrainedTokenizer} tokenizer The tokenizer used by the pipeline.\n * @property {Processor} processor The processor used by the pipeline.\n *\n * @typedef {ModelTokenizerProcessorConstructorArgs} TextAudioPipelineConstructorArgs An object used to instantiate a text- and audio-based pipeline.\n * @typedef {ModelTokenizerProcessorConstructorArgs} TextImagePipelineConstructorArgs An object used to instantiate a text- and image-based pipeline.\n */\n\n/**\n * @typedef {import('./tokenizers.js').Message[]} Chat\n *\n * @typedef {Object} TextGenerationSingle\n * @property {string|Chat} generated_text The generated text.\n * @typedef {TextGenerationSingle[]} TextGenerationOutput\n *\n * @typedef {Object} TextGenerationSpecificParams Parameters specific to text-generation pipelines.\n * @property {boolean} [add_special_tokens] Whether or not to add special tokens when tokenizing the sequences.\n * @property {boolean} [return_full_text=true] If set to `false` only added text is returned, otherwise the full text is returned.\n * @typedef {import('./generation/configuration_utils.js').GenerationConfig & TextGenerationSpecificParams} TextGenerationConfig\n *\n * @callback TextGenerationPipelineCallback Complete the prompt(s) given as inputs.\n * @param {string|string[]|Chat|Chat[]} texts One or several prompts (or one list of prompts) to complete.\n * @param {Partial<TextGenerationConfig>} [options] Additional keyword arguments to pass along to the generate method of the model.\n * @returns {Promise<TextGenerationOutput|TextGenerationOutput[]>} An array or object containing the generated texts.\n *\n * @typedef {TextPipelineConstructorArgs & TextGenerationPipelineCallback & Disposable} TextGenerationPipelineType\n */\n\n/**\n * Language generation pipeline using any `ModelWithLMHead` or `ModelForCausalLM`.\n * This pipeline predicts the words that will follow a specified text prompt.\n * NOTE: For the full list of generation parameters, see [`GenerationConfig`](./utils/generation#module_utils/generation.GenerationConfig).\n *\n * **Example:** Text generation with `Xenova/distilgpt2` (default settings).\n * ```javascript\n * const generator = await pipeline('text-generation', 'Xenova/distilgpt2');\n * const text = 'I enjoy walking with my cute dog,';\n * const output = await generator(text);\n * // [{ generated_text: \"I enjoy walking with my cute dog, and I love to play with the other dogs.\" }]\n * ```\n *\n * **Example:** Text generation with `Xenova/distilgpt2` (custom settings).\n * ```javascript\n * const generator = await pipeline('text-generation', 'Xenova/distilgpt2');\n * const text = 'Once upon a time, there was';\n * const output = await generator(text, {\n *   temperature: 2,\n *   max_new_tokens: 10,\n *   repetition_penalty: 1.5,\n *   no_repeat_ngram_size: 2,\n *   num_beams: 2,\n *   num_return_sequences: 2,\n * });\n * // [{\n * //   \"generated_text\": \"Once upon a time, there was an abundance of information about the history and activities that\"\n * // }, {\n * //   \"generated_text\": \"Once upon a time, there was an abundance of information about the most important and influential\"\n * // }]\n * ```\n *\n * **Example:** Run code generation with `Xenova/codegen-350M-mono`.\n * ```javascript\n * const generator = await pipeline('text-generation', 'Xenova/codegen-350M-mono');\n * const text = 'def fib(n):';\n * const output = await generator(text, {\n *   max_new_tokens: 44,\n * });\n * // [{\n * //   generated_text: 'def fib(n):\\n' +\n * //     '    if n == 0:\\n' +\n * //     '        return 0\\n' +\n * //     '    elif n == 1:\\n' +\n * //     '        return 1\\n' +\n * //     '    else:\\n' +\n * //     '        return fib(n-1) + fib(n-2)\\n'\n * // }]\n * ```\n */\ntype Chat = Message[];\nexport class TextGenerationPipeline\n  extends /** @type {new (options: TextPipelineConstructorArgs) => TextGenerationPipelineType} */ Pipeline\n{\n  /**\n   * Create a new TextGenerationPipeline.\n   * @param {TextPipelineConstructorArgs} options An object used to instantiate the pipeline.\n   */\n  constructor(options: TextPipelineConstructorArgs) {\n    super(options);\n  }\n\n  /** @type {TextGenerationPipelineCallback} */\n  async _call(texts: string | string[] | Chat | Chat[], generate_kwargs = {}) {\n    let isBatched = false;\n    let isChatInput = false;\n\n    // Normalize inputs\n    /** @type {string[]} */\n    let inputs;\n    if (typeof texts === 'string') {\n      inputs = texts = [texts];\n    } else if (Array.isArray(texts) && texts.every((x) => typeof x === 'string')) {\n      isBatched = true;\n      inputs = /** @type {string[]} */ texts;\n    } else {\n      if (isChat(texts)) {\n        texts = [texts as Chat];\n      } else if (Array.isArray(texts) && texts.every(isChat)) {\n        isBatched = true;\n      } else {\n        throw new Error('Input must be a string, an array of strings, a Chat, or an array of Chats');\n      }\n      isChatInput = true;\n\n      // If the input is a chat, we need to apply the chat template\n      inputs = /** @type {string[]} */ /** @type {Chat[]} */ texts.map((x: any) =>\n        this.tokenizer!.apply_chat_template(x, {\n          tokenize: false,\n          add_generation_prompt: true,\n        }),\n      );\n    }\n\n    // By default, do not add special tokens\n    const add_special_tokens = (generate_kwargs as any).add_special_tokens ?? false;\n\n    // By default, return full text\n    const return_full_text = isChatInput ? false : ((generate_kwargs as any).return_full_text ?? true);\n\n    this.tokenizer!.padding_side = 'left';\n    const model_inputs = (this.tokenizer as any)(texts, {\n      add_special_tokens,\n      padding: true,\n      truncation: true,\n    } as any);\n\n    const outputTokenIds = /** @type {Tensor} */ await this.model.generate({\n      ...model_inputs,\n      ...generate_kwargs,\n    });\n\n    const decoded = (this.tokenizer as any).batch_decode(outputTokenIds, {\n      skip_special_tokens: true,\n    });\n\n    let promptLengths;\n    if (!return_full_text && (model_inputs as any).input_ids.dims.at(-1) > 0) {\n      promptLengths = (this.tokenizer as any)\n        .batch_decode((model_inputs as any).input_ids, {\n          skip_special_tokens: true,\n        })\n        .map((x: any) => x.length);\n    }\n\n    /** @type {TextGenerationOutput[]} */\n    const toReturn: TextGenerationOutput[] = Array.from({ length: texts.length }, (_) => []);\n    for (let i = 0; i < (decoded as any).length; ++i) {\n      const textIndex = Math.floor((i / (outputTokenIds as any).dims[0]) * texts.length);\n\n      if (promptLengths) {\n        // Trim the decoded text to only include the generated part\n        decoded[i] = (decoded as any)[i].slice(promptLengths[textIndex]);\n      }\n      toReturn[textIndex].push({\n        generated_text: isChatInput\n          ? [.../** @type {Chat[]} */ texts[textIndex], { role: 'assistant', content: decoded[i] }]\n          : decoded[i],\n      });\n    }\n    return !isBatched && toReturn.length === 1 ? toReturn[0] : toReturn;\n  }\n}\n\n/**\n * @typedef {Object} FeatureExtractionPipelineOptions Parameters specific to feature extraction pipelines.\n * @property {'none'|'mean'|'cls'} [pooling=\"none\"] The pooling method to use.\n * @property {boolean} [normalize=false] Whether or not to normalize the embeddings in the last dimension.\n * @property {boolean} [quantize=false] Whether or not to quantize the embeddings.\n * @property {'binary'|'ubinary'} [precision='binary'] The precision to use for quantization.\n *\n * @callback FeatureExtractionPipelineCallback Extract the features of the input(s).\n * @param {string|string[]} texts One or several texts (or one list of texts) to get the features of.\n * @param {FeatureExtractionPipelineOptions} [options] The options to use for feature extraction.\n * @returns {Promise<Tensor>} The features computed by the model.\n *\n * @typedef {TextPipelineConstructorArgs & FeatureExtractionPipelineCallback & Disposable} FeatureExtractionPipelineType\n */\n\n/**\n * Feature extraction pipeline using no model head. This pipeline extracts the hidden\n * states from the base transformer, which can be used as features in downstream tasks.\n *\n * **Example:** Run feature extraction with `bert-base-uncased` (without pooling/normalization).\n * ```javascript\n * const extractor = await pipeline('feature-extraction', 'Xenova/bert-base-uncased', { revision: 'default' });\n * const output = await extractor('This is a simple test.');\n * // Tensor {\n * //   type: 'float32',\n * //   data: Float32Array [0.05939924716949463, 0.021655935794115067, ...],\n * //   dims: [1, 8, 768]\n * // }\n * ```\n *\n * **Example:** Run feature extraction with `bert-base-uncased` (with pooling/normalization).\n * ```javascript\n * const extractor = await pipeline('feature-extraction', 'Xenova/bert-base-uncased', { revision: 'default' });\n * const output = await extractor('This is a simple test.', { pooling: 'mean', normalize: true });\n * // Tensor {\n * //   type: 'float32',\n * //   data: Float32Array [0.03373778983950615, -0.010106077417731285, ...],\n * //   dims: [1, 768]\n * // }\n * ```\n *\n * **Example:** Calculating embeddings with `sentence-transformers` models.\n * ```javascript\n * const extractor = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');\n * const output = await extractor('This is a simple test.', { pooling: 'mean', normalize: true });\n * // Tensor {\n * //   type: 'float32',\n * //   data: Float32Array [0.09094982594251633, -0.014774246141314507, ...],\n * //   dims: [1, 384]\n * // }\n * ```\n * **Example:** Calculating binary embeddings with `sentence-transformers` models.\n * ```javascript\n * const extractor = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');\n * const output = await extractor('This is a simple test.', { pooling: 'mean', quantize: true, precision: 'binary' });\n * // Tensor {\n * //   type: 'int8',\n * //   data: Int8Array [49, 108, 24, ...],\n * //   dims: [1, 48]\n * // }\n * ```\n */\nexport class FeatureExtractionPipeline\n  extends /** @type {new (options: TextPipelineConstructorArgs) => FeatureExtractionPipelineType} */ Pipeline\n{\n  /**\n   * Create a new FeatureExtractionPipeline.\n   * @param {TextPipelineConstructorArgs} options An object used to instantiate the pipeline.\n   */\n  constructor(options: TextPipelineConstructorArgs) {\n    super(options);\n  }\n\n  /** @type {FeatureExtractionPipelineCallback} */\n  async _call(\n    texts: string | string[],\n    {\n      pooling = /** @type {'none'} */ 'none',\n      normalize = false,\n      quantize = false,\n      precision = /** @type {'binary'} */ 'binary',\n    } = {},\n  ) {\n    // Run tokenization\n    const model_inputs = (this.tokenizer as any)(texts, {\n      padding: true,\n      truncation: true,\n    });\n\n    // Run model\n    const outputs = await (this.model as any)(model_inputs);\n\n    // TODO: Provide warning to the user that they might be using model which was not exported\n    // specifically for feature extraction\n    // console.log(this.model.config)\n    // console.log(outputs)\n\n    /** @type {Tensor} */\n    let result = outputs.last_hidden_state ?? outputs.logits ?? outputs.token_embeddings;\n    if (pooling === 'none') {\n      // Skip pooling\n    } else if (pooling === 'mean') {\n      result = mean_pooling(result, model_inputs.attention_mask);\n    } else if (pooling === 'cls') {\n      result = result.slice(null, 0);\n    } else {\n      throw Error(`Pooling method '${pooling}' not supported.`);\n    }\n\n    if (normalize) {\n      result = result.normalize(2, -1);\n    }\n\n    if (quantize) {\n      result = quantize_embeddings(result, precision as any);\n    }\n\n    return result;\n  }\n}\n\n/**\n * @typedef {Object} ImageFeatureExtractionPipelineOptions Parameters specific to image feature extraction pipelines.\n * @property {boolean} [pool=null] Whether or not to return the pooled output. If set to `false`, the model will return the raw hidden states.\n *\n * @callback ImageFeatureExtractionPipelineCallback Extract the features of the input(s).\n * @param {ImagePipelineInputs} images One or several images (or one list of images) to get the features of.\n * @param {ImageFeatureExtractionPipelineOptions} [options] The options to use for image feature extraction.\n * @returns {Promise<Tensor>} The image features computed by the model.\n *\n * @typedef {ImagePipelineConstructorArgs & ImageFeatureExtractionPipelineCallback & Disposable} ImageFeatureExtractionPipelineType\n */\n\n/**\n * Image feature extraction pipeline using no model head. This pipeline extracts the hidden\n * states from the base transformer, which can be used as features in downstream tasks.\n *\n * **Example:** Perform image feature extraction with `Xenova/vit-base-patch16-224-in21k`.\n * ```javascript\n * const image_feature_extractor = await pipeline('image-feature-extraction', 'Xenova/vit-base-patch16-224-in21k');\n * const url = 'https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats.png';\n * const features = await image_feature_extractor(url);\n * // Tensor {\n * //   dims: [ 1, 197, 768 ],\n * //   type: 'float32',\n * //   data: Float32Array(151296) [ ... ],\n * //   size: 151296\n * // }\n * ```\n *\n * **Example:** Compute image embeddings with `Xenova/clip-vit-base-patch32`.\n * ```javascript\n * const image_feature_extractor = await pipeline('image-feature-extraction', 'Xenova/clip-vit-base-patch32');\n * const url = 'https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats.png';\n * const features = await image_feature_extractor(url);\n * // Tensor {\n * //   dims: [ 1, 512 ],\n * //   type: 'float32',\n * //   data: Float32Array(512) [ ... ],\n * //   size: 512\n * // }\n * ```\n */\nexport class ImageFeatureExtractionPipeline\n  extends /** @type {new (options: ImagePipelineConstructorArgs) => ImageFeatureExtractionPipelineType} */ Pipeline\n{\n  /**\n   * Create a new ImageFeatureExtractionPipeline.\n   * @param {ImagePipelineConstructorArgs} options An object used to instantiate the pipeline.\n   */\n  constructor(options: ImagePipelineConstructorArgs) {\n    super(options);\n  }\n\n  /** @type {ImageFeatureExtractionPipelineCallback} */\n  async _call(images: ImagePipelineInputs, { pool = null } = {}) {\n    const preparedImages = await prepareImages(images);\n    const { pixel_values } = await (this.processor as any)(preparedImages);\n    const outputs = await (this.model as any)({ pixel_values });\n\n    /** @type {Tensor} */\n    let result;\n    if (pool) {\n      if (!('pooler_output' in outputs)) {\n        throw Error(\n          `No pooled output was returned. Make sure the model has a 'pooler' layer when using the 'pool' option.`,\n        );\n      }\n      result = outputs.pooler_output;\n    } else {\n      result = outputs.last_hidden_state ?? outputs.logits ?? outputs.image_embeds;\n    }\n    return result;\n  }\n}\n\n/**\n * @typedef {Object} Chunk\n * @property {[number, number]} timestamp The start and end timestamp of the chunk in seconds.\n * @property {string} text The recognized text.\n */\n\n/**\n * @typedef {Object} AutomaticSpeechRecognitionOutput\n * @property {string} text The recognized text.\n * @property {Chunk[]} [chunks] When using `return_timestamps`, the `chunks` will become a list\n * containing all the various text chunks identified by the model.\n *\n * @typedef {Object} AutomaticSpeechRecognitionSpecificParams Parameters specific to automatic-speech-recognition pipelines.\n * @property {boolean|'word'} [return_timestamps] Whether to return timestamps or not. Default is `false`.\n * @property {number} [chunk_length_s] The length of audio chunks to process in seconds. Default is 0 (no chunking).\n * @property {number} [stride_length_s] The length of overlap between consecutive audio chunks in seconds. If not provided, defaults to `chunk_length_s / 6`.\n * @property {boolean} [force_full_sequences] Whether to force outputting full sequences or not. Default is `false`.\n * @property {string} [language] The source language. Default is `null`, meaning it should be auto-detected. Use this to potentially improve performance if the source language is known.\n * @property {string} [task] The task to perform. Default is `null`, meaning it should be auto-detected.\n * @property {number} [num_frames] The number of frames in the input audio.\n * @typedef {import('./generation/configuration_utils.js').GenerationConfig & AutomaticSpeechRecognitionSpecificParams} AutomaticSpeechRecognitionConfig\n *\n * @callback AutomaticSpeechRecognitionPipelineCallback Transcribe the audio sequence(s) given as inputs to text.\n * @param {AudioPipelineInputs} audio The input audio file(s) to be transcribed. The input is either:\n * - `string` or `URL` that is the filename/URL of the audio file, the file will be read at the processor's sampling rate\n * to get the waveform using the [`AudioContext`](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext) API.\n * If `AudioContext` is not available, you should pass the raw waveform in as a Float32Array of shape `(n, )`.\n * - `Float32Array` or `Float64Array` of shape `(n, )`, representing the raw audio at the correct sampling rate (no further check will be done).\n * @param {Partial<AutomaticSpeechRecognitionConfig>} [options] Additional keyword arguments to pass along to the generate method of the model.\n * @returns {Promise<AutomaticSpeechRecognitionOutput|AutomaticSpeechRecognitionOutput[]>} An object containing the transcription text and optionally timestamps if `return_timestamps` is `true`.\n *\n * @typedef {TextAudioPipelineConstructorArgs & AutomaticSpeechRecognitionPipelineCallback & Disposable} AutomaticSpeechRecognitionPipelineType\n */\n\ninterface Chunk {\n  timestamp: [number, number];\n  text: string;\n}\n\ninterface AutomaticSpeechRecognitionOutput {\n  text: string;\n  chunks?: Chunk[];\n}\n\ninterface AutomaticSpeechRecognitionSpecificParams {\n  return_timestamps?: boolean | 'word';\n  chunk_length_s?: number;\n  stride_length_s?: number;\n  force_full_sequences?: boolean;\n  language?: string;\n  task?: string;\n  num_frames?: number;\n}\n\ntype AutomaticSpeechRecognitionConfig = import('./generation/configuration_utils.js').GenerationConfig &\n  AutomaticSpeechRecognitionSpecificParams;\n\ntype AutomaticSpeechRecognitionPipelineCallback = (\n  audio: AudioPipelineInputs,\n  options?: Partial<AutomaticSpeechRecognitionConfig>,\n) => Promise<AutomaticSpeechRecognitionOutput | AutomaticSpeechRecognitionOutput[]>;\n\ntype AutomaticSpeechRecognitionPipelineType = TextAudioPipelineConstructorArgs &\n  AutomaticSpeechRecognitionPipelineCallback &\n  Disposable;\n\n/**\n * Pipeline that aims at extracting spoken text contained within some audio.\n *\n * **Example:** Transcribe English.\n * ```javascript\n * const transcriber = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny.en');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/jfk.wav';\n * const output = await transcriber(url);\n * // { text: \" And so my fellow Americans ask not what your country can do for you, ask what you can do for your country.\" }\n * ```\n *\n * **Example:** Transcribe English w/ timestamps.\n * ```javascript\n * const transcriber = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny.en');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/jfk.wav';\n * const output = await transcriber(url, { return_timestamps: true });\n * // {\n * //   text: \" And so my fellow Americans ask not what your country can do for you, ask what you can do for your country.\"\n * //   chunks: [\n * //     { timestamp: [0, 8],  text: \" And so my fellow Americans ask not what your country can do for you\" }\n * //     { timestamp: [8, 11], text: \" ask what you can do for your country.\" }\n * //   ]\n * // }\n * ```\n *\n * **Example:** Transcribe English w/ word-level timestamps.\n * ```javascript\n * const transcriber = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny.en');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/jfk.wav';\n * const output = await transcriber(url, { return_timestamps: 'word' });\n * // {\n * //   \"text\": \" And so my fellow Americans ask not what your country can do for you ask what you can do for your country.\",\n * //   \"chunks\": [\n * //     { \"text\": \" And\", \"timestamp\": [0, 0.78] },\n * //     { \"text\": \" so\", \"timestamp\": [0.78, 1.06] },\n * //     { \"text\": \" my\", \"timestamp\": [1.06, 1.46] },\n * //     ...\n * //     { \"text\": \" for\", \"timestamp\": [9.72, 9.92] },\n * //     { \"text\": \" your\", \"timestamp\": [9.92, 10.22] },\n * //     { \"text\": \" country.\", \"timestamp\": [10.22, 13.5] }\n * //   ]\n * // }\n * ```\n *\n * **Example:** Transcribe French.\n * ```javascript\n * const transcriber = await pipeline('automatic-speech-recognition', 'Xenova/whisper-small');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/french-audio.mp3';\n * const output = await transcriber(url, { language: 'french', task: 'transcribe' });\n * // { text: \" J'adore, j'aime, je n'aime pas, je déteste.\" }\n * ```\n *\n * **Example:** Translate French to English.\n * ```javascript\n * const transcriber = await pipeline('automatic-speech-recognition', 'Xenova/whisper-small');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/french-audio.mp3';\n * const output = await transcriber(url, { language: 'french', task: 'translate' });\n * // { text: \" I love, I like, I don't like, I hate.\" }\n * ```\n *\n * **Example:** Transcribe/translate audio longer than 30 seconds.\n * ```javascript\n * const transcriber = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny.en');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/ted_60.wav';\n * const output = await transcriber(url, { chunk_length_s: 30, stride_length_s: 5 });\n * // { text: \" So in college, I was a government major, which means [...] So I'd start off light and I'd bump it up\" }\n * ```\n */\nexport class AutomaticSpeechRecognitionPipeline\n  extends /** @type {new (options: TextAudioPipelineConstructorArgs) => AutomaticSpeechRecognitionPipelineType} */ Pipeline\n{\n  /**\n   * Create a new AutomaticSpeechRecognitionPipeline.\n   * @param {TextAudioPipelineConstructorArgs} options An object used to instantiate the pipeline.\n   */\n  constructor(options: TextAudioPipelineConstructorArgs) {\n    super(options);\n  }\n\n  /** @type {AutomaticSpeechRecognitionPipelineCallback} */\n  async _call(audio: AudioPipelineInputs, kwargs = {}) {\n    switch ((this.model as any).config.model_type) {\n      case 'whisper':\n        return this._call_whisper(audio, kwargs);\n      case 'wav2vec2':\n      case 'wav2vec2-bert':\n      case 'unispeech':\n      case 'unispeech-sat':\n      case 'hubert':\n        return this._call_wav2vec2(audio, kwargs);\n      case 'moonshine':\n        return this._call_moonshine(audio, kwargs);\n      default:\n        throw new Error(\n          `AutomaticSpeechRecognitionPipeline does not support model type '${this.model.config.model_type}'.`,\n        );\n    }\n  }\n\n  /**\n   * @type {AutomaticSpeechRecognitionPipelineCallback}\n   * @private\n   */\n  async _call_wav2vec2(audio: AudioPipelineInputs, kwargs: Partial<AutomaticSpeechRecognitionConfig>) {\n    // TODO use kwargs\n\n    if (kwargs.language) {\n      console.warn('`language` parameter is not yet supported for `wav2vec2` models, defaulting to \"English\".');\n    }\n    if (kwargs.task) {\n      console.warn('`task` parameter is not yet supported for `wav2vec2` models, defaulting to \"transcribe\".');\n    }\n\n    const single = !Array.isArray(audio);\n    if (single) {\n      audio = [audio as AudioInput];\n    }\n\n    const sampling_rate = (this.processor as any).feature_extractor.config.sampling_rate;\n    const preparedAudios = await prepareAudios(audio, sampling_rate);\n\n    const toReturn = [];\n    for (const aud of preparedAudios) {\n      const inputs = await (this.processor as any)(aud);\n      const output = await (this.model as any)(inputs);\n      const logits = output.logits[0];\n\n      const predicted_ids = [];\n      for (const item of logits) {\n        predicted_ids.push(max(item.data)[1]);\n      }\n      const predicted_sentences = (this.tokenizer as any).decode(predicted_ids);\n      toReturn.push({ text: predicted_sentences });\n    }\n    return single ? toReturn[0] : toReturn;\n  }\n\n  /**\n   * @type {AutomaticSpeechRecognitionPipelineCallback}\n   * @private\n   */\n  async _call_whisper(audio: AudioPipelineInputs, kwargs: Partial<AutomaticSpeechRecognitionConfig>) {\n    const return_timestamps = kwargs.return_timestamps ?? false;\n    const chunk_length_s = kwargs.chunk_length_s ?? 0;\n    const force_full_sequences = kwargs.force_full_sequences ?? false;\n    let stride_length_s = kwargs.stride_length_s ?? null;\n\n    const generation_config = { ...kwargs };\n\n    if (return_timestamps === 'word') {\n      (generation_config as any)['return_token_timestamps'] = true;\n      generation_config['return_timestamps'] = false; // Do not predict timestamp tokens\n    }\n\n    const single = !Array.isArray(audio);\n    if (single) {\n      audio = [audio as AudioInput];\n    }\n\n    const time_precision =\n      (this.processor as any).feature_extractor.config.chunk_length / (this.model as any).config.max_source_positions;\n    const hop_length = (this.processor as any).feature_extractor.config.hop_length;\n\n    const sampling_rate = (this.processor as any).feature_extractor.config.sampling_rate;\n    const preparedAudios = await prepareAudios(audio, sampling_rate);\n\n    const toReturn = [];\n    for (const aud of preparedAudios) {\n      /** @type {{stride: number[], input_features: Tensor, is_last: boolean, tokens?: bigint[], token_timestamps?: number[]}[]} */\n      let chunks = [];\n      if (chunk_length_s > 0) {\n        if (stride_length_s === null) {\n          stride_length_s = chunk_length_s / 6;\n        } else if (chunk_length_s <= stride_length_s) {\n          throw Error('`chunk_length_s` must be larger than `stride_length_s`.');\n        }\n\n        // TODO support different stride_length_s (for left and right)\n\n        const window = sampling_rate * chunk_length_s;\n        const stride = sampling_rate * stride_length_s;\n        const jump = window - 2 * stride;\n        let offset = 0;\n\n        // Create subarrays of audio with overlaps\n        while (true) {\n          const offset_end = offset + window;\n          const subarr = aud.subarray(offset, offset_end);\n          const feature = await (this.processor as any)(subarr);\n\n          const is_first = offset === 0;\n          const is_last = offset_end >= aud.length;\n          chunks.push({\n            stride: [subarr.length, is_first ? 0 : stride, is_last ? 0 : stride],\n            input_features: feature.input_features,\n            is_last,\n          });\n          if (is_last) break;\n          offset += jump;\n        }\n      } else {\n        chunks = [\n          {\n            stride: [aud.length, 0, 0],\n            input_features: (await (this.processor as any)(aud)).input_features,\n            is_last: true,\n            tokens: [],\n          },\n        ];\n      }\n\n      // Generate for each set of input features\n      for (const chunk of chunks) {\n        generation_config.num_frames = Math.floor(chunk.stride[0] / hop_length);\n        // console.log(generation_config, chunk);\n        // NOTE: doing sequentially for now\n        const data = await this.model.generate({\n          inputs: chunk.input_features,\n          ...generation_config,\n        });\n\n        // TODO: Right now we only get top beam\n        if (return_timestamps === 'word') {\n          // @ts-expect-error TS2339\n          chunk.tokens = data.sequences.tolist()[0];\n          // @ts-expect-error TS2339\n          chunk.token_timestamps = data.token_timestamps.tolist()[0].map((x: number) => round(x, 2));\n        } else {\n          chunk.tokens = (data as Tensor)[0].tolist();\n        }\n\n        // convert stride to seconds\n        chunk.stride = chunk.stride.map((x) => x / sampling_rate);\n      }\n\n      // Merge text chunks\n      // @ts-ignore\n      const [full_text, optional] = this.tokenizer._decode_asr(chunks, {\n        time_precision,\n        return_timestamps,\n        force_full_sequences,\n      });\n\n      toReturn.push({ text: full_text, ...optional });\n    }\n    return single ? toReturn[0] : toReturn;\n  }\n\n  /**\n   * @type {AutomaticSpeechRecognitionPipelineCallback}\n   * @private\n   */\n  async _call_moonshine(audio: AudioPipelineInputs, kwargs: Partial<AutomaticSpeechRecognitionConfig>) {\n    const single = !Array.isArray(audio);\n    if (single) {\n      audio = [audio as AudioInput];\n    }\n    const sampling_rate = (this.processor as any).feature_extractor.config.sampling_rate;\n    const preparedAudios = await prepareAudios(audio, sampling_rate);\n    const toReturn = [];\n    for (const aud of preparedAudios) {\n      const inputs = await (this.processor as any)(aud);\n\n      // According to the [paper](https://arxiv.org/pdf/2410.15608):\n      // \"We use greedy decoding, with a heuristic limit of 6 output tokens\n      // per second of audio to avoid repeated output sequences.\"\n      const max_new_tokens = Math.floor(aud.length / sampling_rate) * 6;\n      const outputs = await this.model.generate({ max_new_tokens, ...kwargs, ...inputs });\n\n      const text = (this.processor as any).batch_decode(/** @type {Tensor} */ outputs, {\n        skip_special_tokens: true,\n      })[0];\n      toReturn.push({ text });\n    }\n    return single ? toReturn[0] : toReturn;\n  }\n}\n\n/**\n * @typedef {Object} ImageToTextSingle\n * @property {string} generated_text The generated text.\n * @typedef {ImageToTextSingle[]} ImageToTextOutput\n *\n * @callback ImageToTextPipelineCallback Assign labels to the image(s) passed as inputs.\n * @param {ImagePipelineInputs} texts The images to be captioned.\n * @param {Partial<import('./generation/configuration_utils.js').GenerationConfig>} [options] Additional keyword arguments to pass along to the generate method of the model.\n * @returns {Promise<ImageToTextOutput|ImageToTextOutput[]>} An object (or array of objects) containing the generated text(s).\n *\n * @typedef {TextImagePipelineConstructorArgs & ImageToTextPipelineCallback & Disposable} ImageToTextPipelineType\n */\n\n/**\n * Image To Text pipeline using a `AutoModelForVision2Seq`. This pipeline predicts a caption for a given image.\n *\n * **Example:** Generate a caption for an image w/ `Xenova/vit-gpt2-image-captioning`.\n * ```javascript\n * const captioner = await pipeline('image-to-text', 'Xenova/vit-gpt2-image-captioning');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/cats.jpg';\n * const output = await captioner(url);\n * // [{ generated_text: 'a cat laying on a couch with another cat' }]\n * ```\n *\n * **Example:** Optical Character Recognition (OCR) w/ `Xenova/trocr-small-handwritten`.\n * ```javascript\n * const captioner = await pipeline('image-to-text', 'Xenova/trocr-small-handwritten');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/handwriting.jpg';\n * const output = await captioner(url);\n * // [{ generated_text: 'Mr. Brown commented icily.' }]\n * ```\n */\nexport class ImageToTextPipeline\n  extends /** @type {new (options: TextImagePipelineConstructorArgs) => ImageToTextPipelineType} */ Pipeline\n{\n  /**\n   * Create a new ImageToTextPipeline.\n   * @param {TextImagePipelineConstructorArgs} options An object used to instantiate the pipeline.\n   */\n  constructor(options: TextImagePipelineConstructorArgs) {\n    super(options);\n  }\n\n  /** @type {ImageToTextPipelineCallback} */\n  async _call(images: ImagePipelineInputs, generate_kwargs = {}) {\n    const isBatched = Array.isArray(images);\n    const preparedImages = await prepareImages(images);\n\n    const { pixel_values } = await (this.processor as any)(preparedImages);\n\n    const toReturn = [];\n    for (const batch of pixel_values) {\n      batch.dims = [1, ...batch.dims];\n      const output = await (this.model as any).generate({ inputs: batch, ...generate_kwargs });\n      const decoded = (this.tokenizer as any)\n        .batch_decode(/** @type {Tensor} */ output, {\n          skip_special_tokens: true,\n        })\n        .map((x: any) => ({ generated_text: x.trim() }));\n      toReturn.push(decoded);\n    }\n\n    return isBatched ? toReturn : toReturn[0];\n  }\n}\n\n/**\n * @typedef {Object} VocoderOptions\n * @property {PreTrainedModel} [vocoder] The vocoder used by the pipeline (if the model uses one). If not provided, use the default HifiGan vocoder.\n * @typedef {TextAudioPipelineConstructorArgs & VocoderOptions} TextToAudioPipelineConstructorArgs\n */\ntype VocoderOptions = {\n  vocoder: PreTrainedModel | null;\n};\n\n/**\n * @typedef {Object} TextToAudioOutput\n * @property {Float32Array} audio The generated audio waveform.\n * @property {number} sampling_rate The sampling rate of the generated audio waveform.\n *\n * @typedef {Object} TextToAudioPipelineOptions Parameters specific to text-to-audio pipelines.\n * @property {Tensor|Float32Array|string|URL} [speaker_embeddings=null] The speaker embeddings (if the model requires it).\n *\n * @callback TextToAudioPipelineCallback Generates speech/audio from the inputs.\n * @param {string|string[]} texts The text(s) to generate.\n * @param {TextToAudioPipelineOptions} options Parameters passed to the model generation/forward method.\n * @returns {Promise<TextToAudioOutput>} An object containing the generated audio and sampling rate.\n *\n * @typedef {TextToAudioPipelineConstructorArgs & TextToAudioPipelineCallback & Disposable} TextToAudioPipelineType\n */\n\ntype TextToAudioPipelineConstructorArgs = TextAudioPipelineConstructorArgs & VocoderOptions;\n\n/**\n * Text-to-audio generation pipeline using any `AutoModelForTextToWaveform` or `AutoModelForTextToSpectrogram`.\n * This pipeline generates an audio file from an input text and optional other conditional inputs.\n *\n * **Example:** Generate audio from text with `Xenova/speecht5_tts`.\n * ```javascript\n * const synthesizer = await pipeline('text-to-speech', 'Xenova/speecht5_tts', { quantized: false });\n * const speaker_embeddings = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/speaker_embeddings.bin';\n * const out = await synthesizer('Hello, my dog is cute', { speaker_embeddings });\n * // {\n * //   audio: Float32Array(26112) [-0.00005657337896991521, 0.00020583874720614403, ...],\n * //   sampling_rate: 16000\n * // }\n * ```\n *\n * You can then save the audio to a .wav file with the `wavefile` package:\n * ```javascript\n * import wavefile from 'wavefile';\n * import fs from 'fs';\n *\n * const wav = new wavefile.WaveFile();\n * wav.fromScratch(1, out.sampling_rate, '32f', out.audio);\n * fs.writeFileSync('out.wav', wav.toBuffer());\n * ```\n *\n * **Example:** Multilingual speech generation with `Xenova/mms-tts-fra`. See [here](https://huggingface.co/models?pipeline_tag=text-to-speech&other=vits&sort=trending) for the full list of available languages (1107).\n * ```javascript\n * const synthesizer = await pipeline('text-to-speech', 'Xenova/mms-tts-fra');\n * const out = await synthesizer('Bonjour');\n * // {\n * //   audio: Float32Array(23808) [-0.00037693005288019776, 0.0003325853613205254, ...],\n * //   sampling_rate: 16000\n * // }\n * ```\n */\nexport class TextToAudioPipeline\n  extends /** @type {new (options: TextToAudioPipelineConstructorArgs) => TextToAudioPipelineType} */ Pipeline\n{\n  DEFAULT_VOCODER_ID = 'Xenova/speecht5_hifigan';\n\n  /**\n   * Create a new TextToAudioPipeline.\n   * @param {TextToAudioPipelineConstructorArgs} options An object used to instantiate the pipeline.\n   */\n  vocoder: PreTrainedModel | null;\n  constructor(options: TextToAudioPipelineConstructorArgs) {\n    super(options);\n\n    // TODO: Find a better way for `pipeline` to set the default vocoder\n    this.vocoder = options.vocoder ?? null;\n  }\n\n  /** @type {TextToAudioPipelineCallback} */\n  async _call(\n    text_inputs: string | string[],\n    { speaker_embeddings = null }: { speaker_embeddings: Tensor | Float32Array | string | URL | null },\n  ) {\n    // console.log(\"inside call\", this.model.config);\n    // If this.processor is not set, we are using a `AutoModelForTextToWaveform` model\n    if (this.processor) {\n      // console.log(\"Found processor:\", this.processor)\n      return this._call_text_to_spectrogram(text_inputs, { speaker_embeddings });\n    } else {\n      console.log(\"No Processor found, running waveform\")\n      return this._call_text_to_waveform(text_inputs);\n    }\n  }\n\n  async _call_text_to_waveform(text_inputs: string | string[]) {\n    // Run tokenization\n    const inputs = (this.tokenizer as any)(text_inputs, {\n      padding: true,\n      truncation: true,\n    });\n\n    // Generate waveform\n    const { waveform } = await (this.model as any)(inputs);\n\n    // @ts-expect-error TS2339\n    const sampling_rate = this.model.config.sampling_rate;\n    return new RawAudio(\n      waveform.data,\n      sampling_rate,\n    );\n  }\n\n  async _call_text_to_spectrogram(\n    text_inputs: string | string[],\n    { speaker_embeddings = null as Tensor | Float32Array | string | URL | null },\n  ) {\n    // Load vocoder, if not provided\n    if (!this.vocoder) {\n      console.log('No vocoder specified, using default HifiGan vocoder.');\n      this.vocoder = await (AutoModel as any).from_pretrained(this.DEFAULT_VOCODER_ID, { dtype: 'fp32' });\n    }\n\n    // Load speaker embeddings as Float32Array from path/URL\n    if (typeof speaker_embeddings === 'string' || speaker_embeddings instanceof URL) {\n      // Load from URL with fetch\n      speaker_embeddings = new Float32Array(await (await fetch(speaker_embeddings)).arrayBuffer());\n    }\n\n    if (speaker_embeddings instanceof Float32Array) {\n      speaker_embeddings = new Tensor('float32', speaker_embeddings, [1, speaker_embeddings.length]);\n    } else if (!(speaker_embeddings instanceof Tensor)) {\n      throw new Error('Speaker embeddings must be a `Tensor`, `Float32Array`, `string`, or `URL`.');\n    }\n\n    // Run tokenization\n    const { input_ids } = (this.tokenizer as any)(text_inputs, {\n      padding: true,\n      truncation: true,\n    });\n\n    // NOTE: At this point, we are guaranteed that `speaker_embeddings` is a `Tensor`\n    // @ts-ignore\n    const { waveform } = await (this.model as any).generate_speech(input_ids, speaker_embeddings, {\n      vocoder: this.vocoder,\n    });\n\n    const sampling_rate = (this.processor as any).feature_extractor.config.sampling_rate;\n    return new RawAudio(\n        waveform.data,\n        sampling_rate,\n    );\n  }\n}\n\n/**\n * @callback ImageToImagePipelineCallback Transform the image(s) passed as inputs.\n * @param {ImagePipelineInputs} images The images to transform.\n * @returns {Promise<RawImage|RawImage[]>} The transformed image or list of images.\n *\n * @typedef {ImagePipelineConstructorArgs & ImageToImagePipelineCallback & Disposable} ImageToImagePipelineType\n */\n\n/**\n * Image to Image pipeline using any `AutoModelForImageToImage`. This pipeline generates an image based on a previous image input.\n *\n * **Example:** Super-resolution w/ `Xenova/swin2SR-classical-sr-x2-64`\n * ```javascript\n * const upscaler = await pipeline('image-to-image', 'Xenova/swin2SR-classical-sr-x2-64');\n * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/butterfly.jpg';\n * const output = await upscaler(url);\n * // RawImage {\n * //   data: Uint8Array(786432) [ 41, 31, 24,  43, ... ],\n * //   width: 512,\n * //   height: 512,\n * //   channels: 3\n * // }\n * ```\n */\nexport class ImageToImagePipeline\n  extends /** @type {new (options: ImagePipelineConstructorArgs) => ImageToImagePipelineType} */ Pipeline\n{\n  /**\n   * Create a new ImageToImagePipeline.\n   * @param {ImagePipelineConstructorArgs} options An object used to instantiate the pipeline.\n   */\n  processor: any;\n\n  constructor(options: ImagePipelineConstructorArgs) {\n    super(options);\n    this.processor = options.processor;\n  }\n\n  /** @type {ImageToImagePipelineCallback} */\n  async _call(images: ImagePipelineInputs) {\n    const preparedImages = await prepareImages(images);\n    const inputs = await this.processor(preparedImages);\n    const outputs = await (this.model as any)(inputs);\n\n    /** @type {RawImage[]} */\n    const toReturn = [];\n    for (const batch of outputs.reconstruction) {\n      const output = batch.squeeze().clamp_(0, 1).mul_(255).round_().to('uint8');\n      toReturn.push(RawImage.fromTensor(output));\n    }\n\n    return toReturn.length > 1 ? toReturn : toReturn[0];\n  }\n}\n\nexport const SUPPORTED_TASKS = {\n  'text-generation': {\n    tokenizer: AutoTokenizer,\n    pipeline: TextGenerationPipeline,\n    model: AutoModelForCausalLM,\n    default: {\n      // TODO: replace with original\n      // \"model\": \"gpt2\",\n      model: 'Xenova/gpt2',\n    },\n    type: 'text',\n  },\n  'automatic-speech-recognition': {\n    tokenizer: AutoTokenizer,\n    pipeline: AutomaticSpeechRecognitionPipeline,\n    model: [AutoModelForSpeechSeq2Seq, AutoModelForCTC],\n    processor: AutoProcessor,\n    default: {\n      // TODO: replace with original\n      // \"model\": \"openai/whisper-tiny.en\",\n      model: 'Xenova/whisper-tiny.en',\n    },\n    type: 'multimodal',\n  },\n  'text-to-audio': {\n    tokenizer: AutoTokenizer,\n    pipeline: TextToAudioPipeline,\n    model: [AutoModelForTextToWaveform, AutoModelForTextToSpectrogram],\n    processor: [AutoProcessor, /* Some don't use a processor */ null],\n    default: {\n      // TODO: replace with original\n      // \"model\": \"microsoft/speecht5_tts\",\n      model: 'Xenova/speecht5_tts',\n    },\n    type: 'text',\n  },\n  'image-to-text': {\n    tokenizer: AutoTokenizer,\n    pipeline: ImageToTextPipeline,\n    model: AutoModelForVision2Seq,\n    processor: AutoProcessor,\n    default: {\n      // TODO: replace with original\n      // \"model\": \"nlpconnect/vit-gpt2-image-captioning\",\n      model: 'Xenova/vit-gpt2-image-captioning',\n    },\n    type: 'multimodal',\n  },\n  'image-to-image': {\n    // no tokenizer\n    pipeline: ImageToImagePipeline,\n    model: AutoModelForImageToImage,\n    processor: AutoProcessor,\n    default: {\n      // TODO: replace with original\n      // \"model\": \"caidas/swin2SR-classical-sr-x2-64\",\n      model: 'Xenova/swin2SR-classical-sr-x2-64',\n    },\n    type: 'image',\n  },\n\n  // This task serves as a useful interface for dealing with sentence-transformers (https://huggingface.co/sentence-transformers).\n  'feature-extraction': {\n    tokenizer: AutoTokenizer,\n    pipeline: FeatureExtractionPipeline,\n    model: AutoModel,\n    default: {\n      // TODO: replace with original\n      // \"model\": \"sentence-transformers/all-MiniLM-L6-v2\",\n      model: 'Xenova/all-MiniLM-L6-v2',\n    },\n    type: 'text',\n  },\n  'image-feature-extraction': {\n    processor: AutoProcessor,\n    pipeline: ImageFeatureExtractionPipeline,\n    model: [AutoModelForImageFeatureExtraction, AutoModel],\n    default: {\n      // TODO: replace with original\n      // \"model\": \"google/vit-base-patch16-224\",\n      model: 'Xenova/vit-base-patch16-224-in21k',\n    },\n    type: 'image',\n  },\n} as const;\n\n// TODO: Add types for TASK_ALIASES\nexport const TASK_ALIASES = {\n  asr: 'automatic-speech-recognition',\n  'text-to-speech': 'text-to-audio',\n\n  // Add for backwards compatibility\n  embeddings: 'feature-extraction',\n} as const;\n\n/**\n * @typedef {keyof typeof SUPPORTED_TASKS} TaskType\n * @typedef {keyof typeof TASK_ALIASES} AliasType\n * @typedef {TaskType | AliasType} PipelineType All possible pipeline types.\n * @typedef {{[K in TaskType]: InstanceType<typeof SUPPORTED_TASKS[K][\"pipeline\"]>}} SupportedTasks A mapping of pipeline names to their corresponding pipeline classes.\n * @typedef {{[K in AliasType]: InstanceType<typeof SUPPORTED_TASKS[TASK_ALIASES[K]][\"pipeline\"]>}} AliasTasks A mapping from pipeline aliases to their corresponding pipeline classes.\n * @typedef {SupportedTasks & AliasTasks} AllTasks A mapping from all pipeline names and aliases to their corresponding pipeline classes.\n */\n\n/**\n * Utility factory method to build a `Pipeline` object.\n *\n * @template {PipelineType} T The type of pipeline to return.\n * @param {T} task The task defining which pipeline will be returned. Currently accepted tasks are:\n *  - `\"automatic-speech-recognition\"`: will return a `AutomaticSpeechRecognitionPipeline`.\n *  - `\"feature-extraction\"`: will return a `FeatureExtractionPipeline`.\n *  - `\"image-to-text\"`: will return a `ImageToTextPipeline`.\n *  - `\"text-generation\"`: will return a `TextGenerationPipeline`.\n * @param {string} [model=null] The name of the pre-trained model to use. If not specified, the default model for the task will be used.\n * @param {import('./utils/hub.js').PretrainedModelOptions} [options] Optional parameters for the pipeline.\n * @returns {Promise<AllTasks[T]>} A Pipeline object for the specified task.\n * @throws {Error} If an unsupported pipeline is requested.\n */\nexport async function pipeline(\n  task: PipelineType,\n  model: string | null = null,\n  {\n    progress_callback = null,\n    config = null,\n    cache_dir = null,\n    local_files_only = false,\n    revision = 'main',\n    device = null,\n    dtype = null,\n    model_file_name = null,\n    session_options = {},\n  } = {},\n) {\n  // Helper method to construct pipeline\n\n  // Apply aliases\n  // @ts-ignore\n  task = TASK_ALIASES[task] ?? task;\n\n  // Get pipeline info\n  const pipelineInfo = SUPPORTED_TASKS[task.split('_', 1)[0] as keyof typeof SUPPORTED_TASKS];\n  if (!pipelineInfo) {\n    throw Error(`Unsupported pipeline: ${task}. Must be one of [${Object.keys(SUPPORTED_TASKS)}]`);\n  }\n\n  // Use model if specified, otherwise, use default\n  if (!model) {\n    model = pipelineInfo.default.model;\n    console.log(`No model specified. Using default model: \"${model}\".`);\n  }\n\n  const pretrainedOptions = {\n    progress_callback,\n    config,\n    cache_dir,\n    local_files_only,\n    revision,\n    device,\n    dtype,\n    model_file_name,\n    session_options,\n  };\n\n  const classes = new Map([\n    ['tokenizer', (pipelineInfo as any).tokenizer],\n    ['model', (pipelineInfo as any).model],\n    ['processor', (pipelineInfo as any).processor],\n  ]);\n\n  // Load model, tokenizer, and processor (if they exist)\n  const results = await loadItems(classes, model, pretrainedOptions);\n  results.task = task;\n\n  dispatchCallback(progress_callback, {\n    status: 'ready',\n    task: task,\n    model: model,\n  });\n\n  const pipelineClass = pipelineInfo.pipeline;\n  return new pipelineClass(results);\n}\n\n/**\n * Helper function to get applicable model, tokenizer, or processor classes for a given model.\n * @param {Map<string, any>} mapping The mapping of names to classes, arrays of classes, or null.\n * @param {string} model The name of the model to load.\n * @param {import('./utils/hub.js').PretrainedOptions} pretrainedOptions The options to pass to the `from_pretrained` method.\n * @private\n */\nasync function loadItems(mapping: Map<string, any>, model: string, pretrainedOptions: PretrainedOptions) {\n  const result = Object.create(null);\n\n  /**@type {Promise[]} */\n  const promises = [];\n  for (const [name, cls] of mapping.entries()) {\n    if (!cls) continue;\n\n    /**@type {Promise} */\n    let promise;\n    if (Array.isArray(cls)) {\n      promise = new Promise(async (resolve, reject) => {\n        let e;\n        for (const c of cls) {\n          if (c === null) {\n            // If null, we resolve it immediately, meaning the relevant\n            // class was not found, but it is optional.\n            resolve(null);\n            return;\n          }\n          try {\n            resolve(await c.from_pretrained(model, pretrainedOptions));\n            return;\n          } catch (err) {\n            if ((err as Error).message?.includes('Unsupported model type')) {\n              // If the error is due to an unsupported model type, we\n              // save the error and try the next class.\n              e = err as Error;\n            } else if ((err as Error).message?.includes('Could not locate file')) {\n              e = err as Error;\n            } else {\n              reject(err);\n              return;\n            }\n          }\n        }\n        reject(e);\n      });\n    } else {\n      promise = cls.from_pretrained(model, pretrainedOptions);\n    }\n\n    result[name] = promise;\n    promises.push(promise);\n  }\n\n  // Wait for all promises to resolve (in parallel)\n  await Promise.all(promises);\n\n  // Then assign to result\n  for (const [name, promise] of Object.entries(result)) {\n    result[name] = await promise;\n  }\n\n  return result;\n}\n\nfunction isChat(obj: any): obj is Chat {\n  return Array.isArray(obj) && obj.every((x) => typeof x === 'object' && 'role' in x && 'content' in x);\n}\n","/**\n * @module generation/streamers\n */\n\nimport { mergeArrays } from '../utils/core.js';\nimport { is_chinese_char, PreTrainedTokenizer } from '../tokenizers.js';\nimport { apis } from '../env.js';\n\nexport class BaseStreamer {\n  /**\n   * Function that is called by `.generate()` to push new tokens\n   * @param {bigint[][]} value\n   */\n  put(value: bigint[][]) {\n    throw Error('Not implemented');\n  }\n\n  /**\n   * Function that is called by `.generate()` to signal the end of generation\n   */\n  end() {\n    throw Error('Not implemented');\n  }\n}\n\nconst stdout_write = apis.IS_PROCESS_AVAILABLE ? (x: string) => process.stdout.write(x) : (x: string) => console.log(x);\n\n/**\n * Simple text streamer that prints the token(s) to stdout as soon as entire words are formed.\n */\nexport class TextStreamer extends BaseStreamer {\n  /**\n   *\n   * @param {import('../tokenizers.js').PreTrainedTokenizer} tokenizer\n   * @param {Object} options\n   * @param {boolean} [options.skip_prompt=false] Whether to skip the prompt tokens\n   * @param {function(string): void} [options.callback_function=null] Function to call when a piece of text is ready to display\n   * @param {function(bigint[]): void} [options.token_callback_function=null] Function to call when a new token is generated\n   * @param {Object} [options.decode_kwargs={}] Additional keyword arguments to pass to the tokenizer's decode method\n   */\n\n  tokenizer: PreTrainedTokenizer;\n  skip_prompt: boolean;\n  callback_function: (x: string) => void;\n  token_callback_function: any;\n  decode_kwargs: any;\n  print_len: number;\n  next_tokens_are_prompt: boolean;\n  token_cache: bigint[];\n\n  constructor(\n    tokenizer: PreTrainedTokenizer,\n    {\n      skip_prompt = false,\n      callback_function = null,\n      token_callback_function = null,\n      skip_special_tokens = true,\n      decode_kwargs = {},\n      ...kwargs\n    } = {},\n  ) {\n    super();\n    this.tokenizer = tokenizer;\n    this.skip_prompt = skip_prompt;\n    this.callback_function = callback_function ?? stdout_write;\n    this.token_callback_function = token_callback_function;\n    this.decode_kwargs = { skip_special_tokens, ...decode_kwargs, ...kwargs };\n\n\n    // variables used in the streaming process\n    this.token_cache = [];\n    this.print_len = 0;\n    this.next_tokens_are_prompt = true;\n  }\n\n  /**\n   * Receives tokens, decodes them, and prints them to stdout as soon as they form entire words.\n   * @param {bigint[][]} value\n   */\n  put(value: bigint[][]) {\n    if (value.length > 1) {\n      throw Error('TextStreamer only supports batch size of 1');\n    }\n\n    if (this.skip_prompt && this.next_tokens_are_prompt) {\n      this.next_tokens_are_prompt = false;\n      return;\n    }\n\n    const tokens = value[0];\n    this.token_callback_function?.(tokens);\n\n    // Add the new token to the cache and decodes the entire thing.\n    this.token_cache = mergeArrays(this.token_cache, tokens);\n    const text = this.tokenizer.decode(this.token_cache, this.decode_kwargs);\n\n    let printable_text;\n    if (text.endsWith('\\n')) {\n      // After the symbol for a new line, we flush the cache.\n      printable_text = text.slice(this.print_len);\n      this.token_cache = [];\n      this.print_len = 0;\n    } else if (text.length > 0 && is_chinese_char(text.charCodeAt(text.length - 1))) {\n      // If the last token is a CJK character, we print the characters.\n      printable_text = text.slice(this.print_len);\n      this.print_len += printable_text.length;\n    } else {\n      // Otherwise, prints until the last space char (simple heuristic to avoid printing incomplete words,\n      // which may change with the subsequent token -- there are probably smarter ways to do this!)\n      printable_text = text.slice(this.print_len, text.lastIndexOf(' ') + 1);\n      this.print_len += printable_text.length;\n    }\n\n    this.on_finalized_text(printable_text, false);\n  }\n\n  /**\n   * Flushes any remaining cache and prints a newline to stdout.\n   */\n  end() {\n    let printable_text;\n    if (this.token_cache.length > 0) {\n      const text = this.tokenizer.decode(this.token_cache, this.decode_kwargs);\n      printable_text = text.slice(this.print_len);\n      this.token_cache = [];\n      this.print_len = 0;\n    } else {\n      printable_text = '';\n    }\n    this.next_tokens_are_prompt = true;\n    this.on_finalized_text(printable_text, true);\n  }\n\n  /**\n   * Prints the new text to stdout. If the stream is ending, also prints a newline.\n   * @param {string} text\n   * @param {boolean} stream_end\n   */\n  on_finalized_text(text: string, stream_end: boolean) {\n    if (text.length > 0) {\n      this.callback_function?.(text);\n    }\n    if (stream_end && this.callback_function === stdout_write && apis.IS_PROCESS_AVAILABLE) {\n      this.callback_function?.('\\n');\n    }\n  }\n}\n\n/**\n * Utility class to handle streaming of tokens generated by whisper speech-to-text models.\n * Callback functions are invoked when each of the following events occur:\n *  - A new chunk starts (on_chunk_start)\n *  - A new token is generated (callback_function)\n *  - A chunk ends (on_chunk_end)\n *  - The stream is finalized (on_finalize)\n */\nexport class WhisperTextStreamer extends TextStreamer {\n  /**\n   * @param {import('../tokenizers.js').WhisperTokenizer} tokenizer\n   * @param {Object} options\n   * @param {boolean} [options.skip_prompt=false] Whether to skip the prompt tokens\n   * @param {function(string): void} [options.callback_function=null] Function to call when a piece of text is ready to display\n   * @param {function(bigint[]): void} [options.token_callback_function=null] Function to call when a new token is generated\n   * @param {function(number): void} [options.on_chunk_start=null] Function to call when a new chunk starts\n   * @param {function(number): void} [options.on_chunk_end=null] Function to call when a chunk ends\n   * @param {function(): void} [options.on_finalize=null] Function to call when the stream is finalized\n   * @param {number} [options.time_precision=0.02] Precision of the timestamps\n   * @param {boolean} [options.skip_special_tokens=true] Whether to skip special tokens when decoding\n   * @param {Object} [options.decode_kwargs={}] Additional keyword arguments to pass to the tokenizer's decode method\n   */\n  timestamp_begin: number;\n  time_precision: number;\n  waiting_for_timestamp: boolean;\n\n  constructor(\n    tokenizer: PreTrainedTokenizer,\n    {\n      skip_prompt = false,\n      callback_function = null,\n      token_callback_function = null,\n      on_chunk_start = null,\n      on_chunk_end = null,\n      on_finalize = null,\n      time_precision = 0.02,\n      skip_special_tokens = true,\n      decode_kwargs = {},\n    } = {},\n  ) {\n    super(tokenizer, {\n      skip_prompt,\n      skip_special_tokens,\n      callback_function,\n      token_callback_function,\n      decode_kwargs,\n    });\n    this.timestamp_begin = tokenizer.timestamp_begin;\n\n    this.on_chunk_start = on_chunk_start;\n    this.on_chunk_end = on_chunk_end;\n    this.on_finalize = on_finalize;\n\n    this.time_precision = time_precision;\n\n    this.waiting_for_timestamp = false;\n  }\n\n  /**\n   * @param {bigint[][]} value\n   */\n  put(value: bigint[][]) {\n    if (value.length > 1) {\n      throw Error('WhisperTextStreamer only supports batch size of 1');\n    }\n    const tokens = value[0];\n\n    // Check if the token is a timestamp\n    if (tokens.length === 1) {\n      const offset = Number(tokens[0]) - this.timestamp_begin;\n      if (offset >= 0) {\n        const time = offset * this.time_precision;\n        if (this.waiting_for_timestamp) {\n          this.on_chunk_end?.(time);\n        } else {\n          this.on_chunk_start?.(time);\n        }\n        this.waiting_for_timestamp = !this.waiting_for_timestamp; // Toggle\n        value = [[]]; // Skip timestamp\n      }\n    }\n    return super.put(value);\n  }\n\n  end() {\n    super.end();\n    this.on_finalize?.();\n  }\n}\n","// Some of this code is from https://github.com/hexgrad/kokoro/\nimport { phonemize as espeakng } from \"phonemizer\";\n\n  /**\n   * Helper function to split a string on a regex, but keep the delimiters.\n   * This is required, because the JavaScript `.split()` method does not keep the delimiters,\n   * and wrapping in a capturing group causes issues with existing capturing groups (due to nesting).\n   * @param {string} text The text to split.\n   * @param {RegExp} regex The regex to split on.\n   * @returns {{match: boolean; text: string}[]} The split string.\n   */\n  function split(text: string, regex: RegExp) {\n    const result = [];\n    let prev = 0;\n    for (const match of text.matchAll(regex)) {\n      const fullMatch = match[0];\n      if (prev < match.index) {\n        result.push({ match: false, text: text.slice(prev, match.index) });\n      }\n      if (fullMatch.length > 0) {\n        result.push({ match: true, text: fullMatch });\n      }\n      prev = match.index + fullMatch.length;\n    }\n    if (prev < text.length) {\n      result.push({ match: false, text: text.slice(prev) });\n    }\n    return result;\n  }\n\n  /**\n   * Helper function to split numbers into phonetic equivalents\n   * @param {string} match The matched number\n   * @returns {string} The phonetic equivalent\n   */\n  function split_num(match: string) {\n    if (match.includes(\".\")) {\n      return match;\n    } else if (match.includes(\":\")) {\n      let [h, m] = match.split(\":\").map(Number);\n      if (m === 0) {\n        return `${h} o'clock`;\n      } else if (m < 10) {\n        return `${h} oh ${m}`;\n      }\n      return `${h} ${m}`;\n    }\n    let year = parseInt(match.slice(0, 4), 10);\n    if (year < 1100 || year % 1000 < 10) {\n      return match;\n    }\n    let left = match.slice(0, 2);\n    let right = parseInt(match.slice(2, 4), 10);\n    let suffix = match.endsWith(\"s\") ? \"s\" : \"\";\n    if (year % 1000 >= 100 && year % 1000 <= 999) {\n      if (right === 0) {\n        return `${left} hundred${suffix}`;\n      } else if (right < 10) {\n        return `${left} oh ${right}${suffix}`;\n      }\n    }\n    return `${left} ${right}${suffix}`;\n  }\n\n  /**\n   * Helper function to format monetary values\n   * @param {string} match The matched currency\n   * @returns {string} The formatted currency\n   */\n  function flip_money(match: string) {\n    const bill = match[0] === \"$\" ? \"dollar\" : \"pound\";\n    if (isNaN(Number(match.slice(1)))) {\n      return `${match.slice(1)} ${bill}s`;\n    } else if (!match.includes(\".\")) {\n      let suffix = match.slice(1) === \"1\" ? \"\" : \"s\";\n      return `${match.slice(1)} ${bill}${suffix}`;\n    }\n    const [b, c] = match.slice(1).split(\".\");\n    const d = parseInt(c.padEnd(2, \"0\"), 10);\n    let coins = match[0] === \"$\" ? (d === 1 ? \"cent\" : \"cents\") : d === 1 ? \"penny\" : \"pence\";\n    return `${b} ${bill}${b === \"1\" ? \"\" : \"s\"} and ${d} ${coins}`;\n  }\n\n  /**\n   * Helper function to process decimal numbers\n   * @param {string} match The matched number\n   * @returns {string} The formatted number\n   */\n  function point_num(match: string) {\n    let [a, b] = match.split(\".\");\n    return `${a} point ${b.split(\"\").join(\" \")}`;\n  }\n\n  /**\n   * Normalize text for phonemization\n   * @param {string} text The text to normalize\n   * @returns {string} The normalized text\n   */\n  function normalize_text(text: string) {\n    return (\n      text\n        // 1. Handle quotes and brackets\n        .replace(/[‘’]/g, \"'\")\n        .replace(/«/g, \"“\")\n        .replace(/»/g, \"”\")\n        .replace(/[“”]/g, '\"')\n        .replace(/\\(/g, \"«\")\n        .replace(/\\)/g, \"»\")\n\n        // 2. Replace uncommon punctuation marks\n        .replace(/、/g, \", \")\n        .replace(/。/g, \". \")\n        .replace(/！/g, \"! \")\n        .replace(/，/g, \", \")\n        .replace(/：/g, \": \")\n        .replace(/；/g, \"; \")\n        .replace(/？/g, \"? \")\n\n        // 3. Whitespace normalization\n        .replace(/[^\\S \\n]/g, \" \")\n        .replace(/  +/, \" \")\n        .replace(/(?<=\\n) +(?=\\n)/g, \"\")\n\n        // 4. Abbreviations\n        .replace(/\\bD[Rr]\\.(?= [A-Z])/g, \"Doctor\")\n        .replace(/\\b(?:Mr\\.|MR\\.(?= [A-Z]))/g, \"Mister\")\n        .replace(/\\b(?:Ms\\.|MS\\.(?= [A-Z]))/g, \"Miss\")\n        .replace(/\\b(?:Mrs\\.|MRS\\.(?= [A-Z]))/g, \"Mrs\")\n        .replace(/\\betc\\.(?! [A-Z])/gi, \"etc\")\n\n        // 5. Normalize casual words\n        .replace(/\\b(y)eah?\\b/gi, \"$1e'a\")\n\n        // 5. Handle numbers and currencies\n        .replace(/\\d*\\.\\d+|\\b\\d{4}s?\\b|(?<!:)\\b(?:[1-9]|1[0-2]):[0-5]\\d\\b(?!:)/g, split_num)\n        .replace(/(?<=\\d),(?=\\d)/g, \"\")\n        .replace(/[$£]\\d+(?:\\.\\d+)?(?: hundred| thousand| (?:[bm]|tr)illion)*\\b|[$£]\\d+\\.\\d\\d?\\b/gi, flip_money)\n        .replace(/\\d*\\.\\d+/g, point_num)\n        .replace(/(?<=\\d)-(?=\\d)/g, \" to \")\n        .replace(/(?<=\\d)S/g, \" S\")\n\n        // 6. Handle possessives\n        .replace(/(?<=[BCDFGHJ-NP-TV-Z])'?s\\b/g, \"'S\")\n        .replace(/(?<=X')S\\b/g, \"s\")\n\n        // 7. Handle hyphenated words/letters\n        .replace(/(?:[A-Za-z]\\.){2,} [a-z]/g, (m) => m.replace(/\\./g, \"-\"))\n        .replace(/(?<=[A-Z])\\.(?=[A-Z])/gi, \"-\")\n\n        // 8. Strip leading and trailing whitespace\n        .trim()\n    );\n  }\n\n  /**\n   * Escapes regular expression special characters from a string by replacing them with their escaped counterparts.\n   *\n   * @param {string} string The string to escape.\n   * @returns {string} The escaped string.\n   */\n  function escapeRegExp(string: string) {\n    return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"); // $& means the whole matched string\n  }\n\n  const PUNCTUATION = ';:,.!?¡¿—…\"«»“”(){}[]';\n  const PUNCTUATION_PATTERN = new RegExp(`(\\\\s*[${escapeRegExp(PUNCTUATION)}]+\\\\s*)+`, \"g\");\n\n  const HINDI_PHONEME_MAP: { [key: string]: string } = {\n    // Vowels - Updated to be more accurate and broadly understood\n    'अ': 'a',      // a\n    'आ': 'aː',     // Long 'a'\n    'इ': 'e',      // Lax 'i'\n    'ई': 'eː',     // Long 'i'\n    'उ': 'ʊ',      // Lax 'u'\n    'ऊ': 'uː',     // Long 'u'\n    'ऋ': 'ri',    // 'ri' sound (often pronounced like this) -  Could also be ɾɪ\n    'ए': 'eː',     // Long 'e'\n    'ऐ': 'ɛ',      // Diphthong/Monophthong 'ai' - More accurately [ɛ] or [æ] in many dialects\n    'ओ': 'oː',     // Long 'o'\n    'औ': 'ɔ',      // Diphthong/Monophthong 'au' - More accurately [ɔ] or [ɒ] in many dialects\n    'ऍ': 'æ',      // Open 'e' sound (like in 'cat') - Borrowed sound\n    'ऑ': 'ɒ',      // Open 'o' sound (like in 'caught') - Borrowed sound\n\n    // Consonants - Updated for broader IPA understanding (using alveolar series where applicable)\n    'क': 'k',      // Voiceless velar stop\n    'ख': 'kʰ',     // Aspirated voiceless velar stop\n    'ग': 'g',      // Voiced velar stop\n    'घ': 'gʰ',     // Aspirated voiced velar stop\n    'ङ': 'ŋ',      // Velar nasal\n    'च': 'tʃ',     // Voiceless postalveolar affricate\n    'छ': 'tʃʰ',    // Aspirated voiceless postalveolar affricate\n    'ज': 'dʒ',     // Voiced postalveolar affricate\n    'झ': 'dʒʰ',    // Aspirated voiced postalveolar affricate\n    'ञ': 'ɲ',      // Palatal nasal\n    'ट': 'ʈ',      // Voiceless retroflex stop\n    'ठ': 'ʈʰ',     // Aspirated voiceless retroflex stop\n    'ड': 'ɖ',      // Voiced retroflex stop\n    'ढ': 'ɖʰ',     // Aspirated voiced retroflex stop\n    'ण': 'ɳ',      // Retroflex nasal\n    'त': 't',      // Voiceless alveolar stop (Technically dental [t̪])\n    'थ': 'tʰ',     // Aspirated voiceless alveolar stop (Technically dental [t̪ʰ])\n    'द': 'd',      // Voiced alveolar stop (Technically dental [d̪])\n    'ध': 'dʰ',     // Aspirated voiced alveolar stop (Technically dental [d̪ʰ])\n    'न': 'n',      // Alveolar nasal (Technically dental [n̪])\n    'प': 'p',      // Voiceless bilabial stop\n    'फ': 'pʰ',     // Aspirated voiceless bilabial stop\n    'ब': 'b',      // Voiced bilabial stop\n    'भ': 'bʰ',     // Aspirated voiced bilabial stop\n    'म': 'm',      // Bilabial nasal\n    'य': 'j',      // Palatal approximant\n    'र': 'r',      // Alveolar trill or flap\n    'ल': 'l',      // Alveolar lateral approximant\n    'व': 'w',      // Bilabial approximant (More common pronunciation, technically could be labiodental [ʋ])\n    'श': 'ʃ',      // Postalveolar voiceless fricative (Often used, but 'ष' is retroflex [ʂ])\n    'ष': 'ʂ',      // Retroflex voiceless fricative (More accurate for 'ष')\n    'स': 's',      // Alveolar voiceless fricative (Technically dental [s̪])\n    'ह': 'h',      // Voiceless glottal fricative (Simpler and common, could be breathy voiced [ɦ])\n\n    // Matras (Vowel Marks) - Updated to match vowel changes\n    'ा': 'aː',     // aa matra\n    'ि': 'ɪ',      // i matra\n    'ी': 'iː',     // ee matra\n    'ु': 'ʊ',      // u matra\n    'ू': 'uː',     // oo matra\n    'ृ': 'ri',    // ri matra - Could also be ɾɪ\n    'े': 'eː',     // e matra\n    'ै': 'ɛ',      // ai matra\n    'ो': 'oː',     // o matra\n    'ौ': 'ɔ',      // au matra\n    'ं': 'n',      // Anusvara - Simplified to 'n' for general nasal consonant (See notes below)\n    'ः': 'h',      // Visarga\n    '्': '',       // Halant/Virama - Removes inherent vowel\n\n    // Nukta variations - Generally correct\n    'क़': 'q',      // Uvular stop\n    'ख़': 'x',      // Voiceless velar fricative\n    'ग़': 'ɣ',      // Voiced velar fricative\n    'ज़': 'z',      // Voiced alveolar fricative\n    'ड़': 'ɽ',      // Retroflex flap\n    'ढ़': 'ɽʰ',     // Aspirated retroflex flap\n    'फ़': 'f',      // Labiodental fricative\n  };\n\n  // Add function to detect script\n  // function isDevanagari(text: string): boolean {\n  //   return /[\\u0900-\\u097F]/.test(text);\n  // }\n\n  // Add Spanish phoneme detection\n  // function isSpanish(text: string): boolean {\n  //   return /[áéíóúñ¿¡]|ll|ñ/i.test(text);\n  // }\n\n  // Add Spanish phoneme mappings\n  const SPANISH_PHONEME_MAP: { [key: string]: string } = {\n    // Vowels\n    'a': 'a',\n    'á': 'ˈa',\n    'e': 'e',\n    'é': 'ˈe',\n    'i': 'i',\n    'í': 'ˈi',\n    'o': 'o',\n    'ó': 'ˈo',\n    'u': 'u',\n    'ú': 'ˈu',\n    'ü': 'u',\n\n    // Consonants\n    'b': 'b',\n    'v': 'β',\n    'c': 'k',\n    'ch': 'tʃ',\n    'd': 'ð',\n    'f': 'f',\n    'g': 'ɡ',\n    'h': '',  // silent in Spanish\n    'j': 'x',\n    'k': 'k',\n    'l': 'l',\n    'll': 'j',\n    'm': 'm',\n    'n': 'n',\n    'ñ': 'ɲ',\n    'p': 'p',\n    'q': 'k',\n    'r': 'ɾ',\n    'rr': 'r',\n    's': 's',\n    't': 't',\n    'w': 'w',\n    'x': 'ks',\n    'y': 'ʝ',\n    'z': 'θ'  // for European Spanish\n  };\n\n  function isHinglish(text: string): boolean {\n    // Common Hinglish words and patterns\n    const hinglishPatterns = [\n      /\\b(aap|tum|hum|main|mein|ham|yeh|woh|kya|kaun|kaise|kyun|kab|kahan|yahan|wahan)\\b/i,\n      /\\b(hai|hain|ho|hoga|tha|the|thi|thin|raha|rahe|rahi|rahin)\\b/i, // Common verb forms\n      /\\b(ka|ke|ki|ko|se|par|me|mein|pe)\\b/i, // Common postpositions\n      /\\b(accha|theek|bahut|bohot|thoda|zyada|kam|jyada)\\b/i, // Common adjectives and adverbs\n      /\\b(karo|karta|karti|karta|karo|karna|kar|karenge|karega|karegi)\\b/i, // Forms of करना (to do)\n      /\\b(bolo|bolta|bolti|bolte|bola|boli|bole|bolna|bol)\\b/i, // Forms of बोलना (to speak)\n      /\\b(jao|jata|jati|jate|gaya|gayi|gaye|jana|ja)\\b/i, // Forms of जाना (to go)\n      /\\b(khao|khata|khati|khate|khaya|khayi|khaye|khana|kha)\\b/i, // Forms of खाना (to eat)\n      /\\b(suno|sunta|sunti|sunte|suna|suni|sune|sunna|sun)\\b/i // Forms of सुनना (to listen)\n    ];\n    \n    // Check for patterns that are strong indicators of Hinglish\n    for (const pattern of hinglishPatterns) {\n      if (pattern.test(text)) {\n        return true;\n      }\n    }\n    \n    // Look for common Hindi word endings\n    const hindiEndingPattern = /\\b\\w+(iye|ogi|ega|enge|engi|ogi|oga|egi|enga|engi)\\b/i;\n    if (hindiEndingPattern.test(text)) {\n      return true;\n    }\n    \n    // Check for sentences that are likely to be Hinglish\n    // Common Hindi sentence structures\n    const commonSentences = [\n      /aap k(ya|i|e) (kar|ho|hai)/i,\n      /kya (ho raha|chal raha|hua)/i,\n      /\\b(theek|accha) hai\\b/i,\n      /kaise ho/i,\n      /\\b(namaste|namaskar)\\b/i\n    ];\n    \n    for (const pattern of commonSentences) {\n      if (pattern.test(text)) {\n        return true;\n      }\n    }\n    \n    return false;\n  }\n\n  const HINGLISH_PHONEME_MAP: { [key: string]: string } = {\n    // Vowels\n    'a': 'ə',      // Short 'a' (schwa), inherent in Hindi consonants\n    'aa': 'aː',    // Long 'a' (आ), as in \"naam\"\n    'i': 'ɪ',      // Short 'i' (इ), as in \"kitna\"\n    'ee': 'iː',    // Long 'i' (ई), as in \"Vaishnavi\" ending\n    'u': 'ʊ',      // Short 'u' (उ), as in \"tum\"\n    'oo': 'uː',    // Long 'u' (ऊ), as in \"soona\"\n    'e': 'eː',     // Long 'e' (ए), as in \"ek\"\n    'ai': 'ɛː',    // 'ai' (ऐ), as in \"kaise\"\n    'o': 'oː',     // Long 'o' (ओ), as in \"bolo\"\n    'au': 'ɔː',    // 'au' (औ), as in \"mausam\"\n  \n    // Common consonant patterns\n    'kh': 'kʰ',    // Aspirated 'k' (ख), as in \"khaana\"\n    'gh': 'gʰ',    // Aspirated 'g' (घ), as in \"ghar\"\n    'ch': 'tʃ',    // 'ch' (च), as in \"chalo\"\n    'jh': 'dʒʰ',   // Aspirated 'j' (झ), as in \"jheel\"\n    'th': 't̪ʰ',   // Aspirated dental 't' (थ), as in \"tha\"\n    'dh': 'd̪ʰ',   // Aspirated dental 'd' (ध), as in \"dhan\"\n    'ph': 'pʰ',    // Aspirated 'p' (फ), as in \"phool\"\n    'bh': 'bʰ',    // Aspirated 'b' (भ), as in \"bhai\"\n    'sh': 'ʃ',     // 'sh' (श), as in \"shaadi\"\n    'ng': 'ŋ',     // Nasal 'ng' (ङ्ग), as in \"rang\"\n    'tt': 'ʈ',     // Retroflex 't' (ट), as in \"theek\"\n    'dd': 'ɖ',     // Retroflex 'd' (ड), as in \"ladka\"\n    'tth': 'ʈʰ',   // Aspirated retroflex 't' (ठ)\n    'ddh': 'ɖʰ',   // Aspirated retroflex 'd' (ढ)\n  \n    // Special consonants\n    'r': 'ɾ',      // Flapped 'r' (र), as in \"raasta\"\n    'n': 'n̪',     // Dental 'n' (न), as in \"naam\"\n    't': 't̪',     // Dental 't' (त), as in \"tum\"\n    'd': 'd̪',     // Dental 'd' (द), as in \"dena\"\n    'k': 'k',      // 'k' (क), as in \"kar\"\n    'g': 'g',      // 'g' (ग), as in \"gaya\"\n    'p': 'p',      // 'p' (प), as in \"paani\"\n    'b': 'b',      // 'b' (ब), as in \"bolo\"\n    'm': 'm',      // 'm' (म), as in \"main\"\n    'y': 'j',      // 'y' (य), as in \"yaad\"\n    'v': 'v',      // 'v' (व), as in \"Vaishnavi\"\n    'w': 'v',      // 'w' mapped to 'v' (व), common in Hinglish\n    'l': 'l',      // 'l' (ल), as in \"ladka\"\n    's': 's',      // 's' (स), as in \"suno\"\n    'h': 'h',      // 'h' (ह), as in \"hai\"\n    'z': 'z',      // 'z' (ज़), as in \"zindagi\"\n    'f': 'f',      // 'f' (फ़), as in \"fark\"\n  };\n\n\nfunction processHinglishText(text: string): string {\n  // Expanded list of common Hinglish words with phonetic mappings\n  const commonHinglishWords: { [key: string]: string } = {\n    'aap': 'aːp',           // आप (you, formal)\n    'tum': 't̪ʊm',         // तुम (you, informal)\n    'main': 'mɛ̃',         // मैं (I)\n    'mein': 'mẽ',          // में (in)\n    'hum': 'hʊm',          // हम (we)\n    'bolo': 'boːloː',      // बोलो (speak)\n    'suno': 'sʊnoː',       // सुनो (listen)\n    'ham': 'həm',          // Alternative spelling for हम\n    'kya': 'kjɑː',         // क्या (what)\n    'kaun': 'kɔːn',        // कौन (who)\n    'kaise': 'kɛːse',      // कैसे (how)\n    'kyun': 'kjũː',        // क्यों (why)\n    'kab': 'kəb',          // कब (when)\n    'kahan': 'kəhãː',      // कहाँ (where)\n    'yahan': 'jəhãː',      // यहाँ (here)\n    'wahan': 'vəhãː',      // वहाँ (there)\n    'hai': 'hɛː',          // है (is)\n    'hain': 'hɛ̃ː',        // हैं (are)\n    'ho': 'hoː',           // हो (are/be)\n    'kar': 'kər',          // कर (do)\n    'rahe': 'rəhe',        // रहे (continuous action)\n    'raha': 'rəhaː',       // रहा (was, masculine)\n    'gaya': 'gəjaː',       // गया (went, masculine)\n    'gayi': 'gəjiː',       // गई (went, feminine)\n    'accha': 'ətʃʰaː',    // अच्छा (good)\n    'theek': 'ʈʰiːk',     // ठीक (fine)\n    'bahut': 'bəhʊt̪',    // बहुत (a lot)\n    'namaste': 'nəməst̪e', // नमस्ते (hello)\n    'namaskar': 'nəməskaːr', // नमस्कार (greetings)\n    'dhanyavaad': 'd̪ʰənjəvaːd̪', // धन्यवाद (thank you)\n    'ghar': 'gʰər',        // घर (house)\n    'ladka': 'ləɖkaː',     // लड़का (boy)\n    'kaam': 'kaːm',        // काम (work)\n    'nahi': 'nəhiː',       // नहीं (no)\n    'tha': 'tʰaː',         // था (was, masculine)\n    'thi': 'tʰiː',         // थी (was, feminine)\n    'the': 'tʰeː',         // थे (were)\n    'jaan': 'dʒaːn',       // जान (life/soul)\n    'pyaar': 'pjaːr',      // प्यार (love)\n    'dost': 'doːst',       // दोस्त (friend)\n    'khana': 'kʰaːnaː',    // खाना (food/to eat)\n    'paani': 'paːniː',     // पानी (water)\n    'bachcha': 'bətʃʰaː', // बच्चा (child)\n    'raasta': 'raːstaː',   // रास्ता (path)\n    'sapna': 'səpnaː',     // सपना (dream)\n    'dil': 'dɪl',          // दिल (heart)\n    'zindagi': 'zɪndəgiː', // ज़िंदगी (life)\n    'samajh': 'səmədʒʰ',  // समझ (understanding)\n    'baat': 'baːt',        // बात (talk)\n    'waqt': 'vəqt',        // वक्त (time)\n    'yaad': 'jaːd',        // याद (memory)\n    'shaadi': 'ʃaːdiː',    // शादी (marriage)\n    'khush': 'kʰʊʃ',      // खुश (happy)\n    'milna': 'mɪlnaː',     // मिलना (to meet)\n    'dekhna': 'deːkʰnaː', // देखना (to see)\n    'sochna': 'soːtʃnaː',  // सोचना (to think)\n    'jaanna': 'dʒaːnnaː', // जानना (to know)\n    'lena': 'leːnaː',      // लेना (to take)\n    'dena': 'deːnaː',      // देना (to give)\n    'chalna': 'tʃəlnaː',   // चलना (to walk)\n    'aana': 'aːnaː',       // आना (to come)\n    'jaana': 'dʒaːnaː',   // जाना (to go)\n    'peena': 'piːnaː',     // पीना (to drink)\n    'sona': 'soːnaː',      // सोना (to sleep)\n    'aaj': 'aːdʒ',         // आज (today)\n    'kal': 'kəl',          // कल (yesterday/tomorrow)\n    'abhi': 'əbʰiː',       // अभी (now)\n    'sab': 'səb',          // सब (all)\n    'kuch': 'kʊtʃ',       // कुछ (some)\n    'thoda': 'tʰoːdaː',    // थोड़ा (little)\n    'zyada': 'zjaːdaː'     // ज़्यादा (more)\n  };\n\n  const words = text.toLowerCase().split(/\\s+/);\n  return words.map(word => {\n    if (commonHinglishWords[word]) {\n      return commonHinglishWords[word];\n    }\n\n    let result = '';\n    let i = 0;\n    while (i < word.length) {\n      // Check two-character patterns first\n      if (i < word.length - 1) {\n        const twoChars = word.substring(i, i + 2);\n        if (HINGLISH_PHONEME_MAP[twoChars]) {\n          result += HINGLISH_PHONEME_MAP[twoChars];\n          i += 2;\n          continue;\n        }\n      }\n\n      // Handle single characters\n      const char = word[i];\n      result += HINGLISH_PHONEME_MAP[char] || char;\n      i++;\n    }\n\n    // Post-process word for Hindi-specific rules\n    // Lengthen final 'i' or 'e' to match Hindi pronunciation\n    result = result.replace(/ɪ$/g, 'iː').replace(/e$/g, 'eː');\n    // Remove schwa before final consonant if unintended\n    result = result.replace(/ə([kgtɖd̪pbɾmn̪lsʃʈ])$/g, '$1');\n    // Add nasalization for 'n' or 'm' at end if applicable\n    result = result.replace(/[nm]$/, '̃');\n\n    return result;\n  }).join(' ');\n} \n\n  // Add function to handle Hindi syllable structure\n  function processHindiSyllable(text: string): string {\n    return text\n      // Handle consonant clusters with virama\n      .replace(/([क-ह])्([क-ह])/g, (_, c1, c2) => {\n        const p1 = HINDI_PHONEME_MAP[c1] || c1;\n        const p2 = HINDI_PHONEME_MAP[c2] || c2;\n        return p1 + p2;\n      })\n      // Handle inherent 'a' sound after consonants, but not at word end\n      .replace(/([क-ह])(?![ािीुूृेैोौ्ंँः]|$)/g, (_, c) => {\n        const phoneme = HINDI_PHONEME_MAP[c] || c;\n        return phoneme + 'ə';\n      })\n      // Handle word-final consonants without schwa\n      .replace(/([क-ह])$/g, (_, c) => HINDI_PHONEME_MAP[c] || c)\n      // Handle nasalization\n      .replace(/([aeiouəɛɔ])ं/g, '$1̃')\n      .replace(/([aeiouəɛɔ])ँ/g, '$1̃');\n  }\n\n  // Define supported language codes explicitly\n  type SupportedLanguage = 'en-us' | 'en-gb' | 'hi' | 'es' | 'fr' | 'zh';\n  \n  export async function phonemize(text: string, language: SupportedLanguage = \"en-us\", norm = true) {\n    // 1. Normalize text\n    if (norm) {\n      text = normalize_text(text);\n    }\n\n    // Directly use the provided language code\n    let targetLanguage = language;\n    \n    // For backward compatibility - map any legacy single-letter codes\n    if (language === 'a' as any) targetLanguage = 'en-us';\n    if (language === 'b' as any) targetLanguage = 'en-gb';\n    if (language === 'h' as any) targetLanguage = 'hi';\n    if (language === 'e' as any) targetLanguage = 'es';\n    if (language === 'f' as any) targetLanguage = 'fr';\n    if (language === 'z' as any) targetLanguage = 'zh';\n    \n    console.log(`Processing text (${text.length} chars) as: ${targetLanguage}`);\n\n    // Check if text is too long - handle with max char limits\n    const MAX_PHONEME_INPUT_LENGTH = 300; // Safe maximum for phonemization\n    \n    if (text.length > MAX_PHONEME_INPUT_LENGTH) {\n      console.warn(`Text too long (${text.length} chars), processing only the first ${MAX_PHONEME_INPUT_LENGTH} characters`);\n      // Truncate at word boundary closest to the limit\n      const truncatedText = text.substring(0, MAX_PHONEME_INPUT_LENGTH).split(' ').slice(0, -1).join(' ');\n      console.log(`Truncated to: \"${truncatedText}\"`);\n      text = truncatedText;\n    }\n\n    // 3. Split into chunks, to ensure we preserve punctuation\n    const sections = split(text, PUNCTUATION_PATTERN);\n\n    // 4. Convert each section to phonemes\n    const ps = (await Promise.all(\n      sections.map(async ({ match, text }) => {\n        if (match) return text;\n        \n        switch (targetLanguage) {\n          case 'hi': // Handles both Devanagari and Romanized Hindi (Hinglish)\n            // Check for Devanagari script\n            const isDevanagari = /[\\u0900-\\u097F]/.test(text);\n            \n            if (isDevanagari) {\n              // For Devanagari script\n              return Array.from(text)\n                .map(char => HINDI_PHONEME_MAP[char] || char)\n                .join('');\n            } else {\n              // For Hinglish (Romanized Hindi)\n              let processed = processHinglishText(text);\n              return processed;\n            }\n          \n          case 'es':\n            let result = text.toLowerCase();\n            result = result\n              .replace(/ch/g, 'tʃ')\n              .replace(/ll/g, 'j')\n              .replace(/rr/g, 'r')\n              .replace(/c([ie])/g, 's$1');\n            \n            return Array.from(result)\n              .map(char => SPANISH_PHONEME_MAP[char] || char)\n              .join('');\n          \n          case 'en-us':\n          case 'en-gb':\n          default: // Default to English using espeakng\n            try {\n              // Pass the correct language code directly to espeakng\n              // Handle potential errors in espeakng more gracefully\n              try {\n                return (await espeakng(text, targetLanguage)).join(\" \");\n              } catch (espeakError) {\n                console.error(`Error with espeakng phonemization for ${targetLanguage}:`, espeakError);\n                // Fallback to character-by-character phoneme mapping for English\n                return text\n                  .replace(/ch/g, 'tʃ')\n                  .replace(/th/g, 'θ')\n                  .replace(/sh/g, 'ʃ')\n                  .replace(/ph/g, 'f');\n              }\n            } catch (error) {\n              console.error(`Unexpected error in phonemization for ${targetLanguage}:`, error);\n              return text; // Ultimate fallback\n            }\n        }\n      })\n    )).join(\"\");\n\n    // 5. Post-process phonemes\n    let processed = ps\n      // General post-processing\n      .replace(/kəkˈoːɹoʊ/g, \"kˈoʊkəɹoʊ\")\n      .replace(/kəkˈɔːɹəʊ/g, \"kˈəʊkəɹəʊ\")\n      .replace(/ʲ/g, \"j\")\n      .replace(/r/g, \"ɹ\")\n      .replace(/x/g, \"k\")\n      .replace(/ɬ/g, \"l\")\n      .replace(/(?<=[a-zɹː])(?=hˈʌndɹɪd)/g, \" \")\n      .replace(/ z(?=[;:,.!?¡¿—…\"«»\"\"(){}[] ]|$)/g, \"z\");\n      \n    // 6. Language-specific post-processing\n    if (targetLanguage === 'en-us') {\n      processed = processed.replace(/(?<=nˈaɪn)ti(?!ː)/g, \"di\");\n    } else if (targetLanguage === 'hi') {\n      // Hindi-specific post-processing\n      processed = processed\n        // Handle aspirated sounds\n        .replace(/(?<=[aeiou])h/g, 'ɦ')\n        // Add space after long vowels for better rhythm\n        .replace(/(?<=\\w)ː/g, 'ː ')\n        // Fix common pronunciation issues\n        .replace(/kəʊn/g, \"kɔːn\") // Fix \"kaun\" pronunciation\n        .replace(/həʊ/g, \"hoː\")   // Fix \"ho\" pronunciation \n        .replace(/([kKgGtTdDpPbB])ə([ɾr])/g, \"$1$2\") // Remove schwa between consonant and 'r'\n        .replace(/([aeiouy])([ɾr])([aeiouy])/g, \"$1$2$3\") // Strengthen 'r' between vowels\n        // Add spacing between syllables for better rhythm\n        .replace(/([kKgGtTdDpPbB][ɦh])/g, \"$1 \")\n        // Ensure proper stress patterns for Hindi\n        .replace(/([aeiou])([^aeiou\\s]+)$/g, \"$1ː$2\"); // Lengthen final vowels before consonant endings\n    } \n    \n    // Ensure the output isn't too long\n    const trimmedResult = processed.trim();\n    \n    // Debug log the phonemization result\n    console.log(`Phonemized ${text.length} chars into ${trimmedResult.length} phoneme chars`);\n    \n    return trimmedResult;\n  }","// Some of this code is from https://github.com/hexgrad/kokoro/\n\nexport const VOICES = Object.freeze({\n  af: {\n    // Default voice is a 50-50 mix of Bella & Sarah\n    name: \"Default\",\n    language: \"en-us\",\n    gender: \"Female\",\n  },\n  af_bella: {\n    name: \"Bella\",\n    language: \"en-us\",\n    gender: \"Female\",\n  },\n  af_nicole: {\n    name: \"Nicole\",\n    language: \"en-us\",\n    gender: \"Female\",\n  },\n  af_sarah: {\n    name: \"Sarah\",\n    language: \"en-us\",\n    gender: \"Female\",\n  },\n  af_sky: {\n    name: \"Sky\",\n    language: \"en-us\",\n    gender: \"Female\",\n  },\n  am_adam: {\n    name: \"Adam\",\n    language: \"en-us\",\n    gender: \"Male\",\n  },\n  am_michael: {\n    name: \"Michael\",\n    language: \"en-us\",\n    gender: \"Male\",\n  },\n\n  bf_emma: {\n    name: \"Emma\",\n    language: \"en-gb\",\n    gender: \"Female\",\n  },\n  bf_isabella: {\n    name: \"Isabella\",\n    language: \"en-gb\",\n    gender: \"Female\",\n  },\n  bm_george: {\n    name: \"George\",\n    language: \"en-gb\",\n    gender: \"Male\",\n  },\n  bm_lewis: {\n    name: \"Lewis\",\n    language: \"en-gb\",\n    gender: \"Male\",\n  },\n  hf_alpha: {\n    name: \"alpha\",\n    language: \"hi\",\n    gender: \"Female\",\n  },\n  hf_beta: {\n    name: \"beta\",\n    language: \"hi\",\n    gender: \"Female\",\n  },\n  hm_omega: {\n    name: \"omega\",\n    language: \"hi\",\n    gender: \"Male\",\n  },\n  hm_psi: {\n    name: \"psi\",\n    language: \"hi\",\n    gender: \"Male\",\n  },\n  ef_dora: {\n    name: \"dora\",\n    language: \"es\",\n    gender: \"Female\",\n  },\n  em_alex: {\n    name: \"alex\",\n    language: \"es\",\n    gender: \"Male\",\n  },\n  em_santa: {\n    name: \"santa\",\n    language: \"es\",\n    gender: \"Male\",\n  },\n  ff_siwis: {\n    name: \"siwis\",\n    language: \"es\",\n    gender: \"Female\",\n  },\n  jf_alpha: {\n    name: \"alpha\",\n    language: \"ja\",\n    gender: \"Female\",\n  },\n  jf_gongitsune: {\n    name: \"gongitsune\",\n    language: \"ja\",\n    gender: \"Female\",\n  },\n  jf_nezumi: {\n    name: \"nezumi\",\n    language: \"ja\",\n    gender: \"Female\",\n  },\n  jf_tebukuro: {\n    name: \"tebukuro\",\n    language: \"ja\",\n    gender: \"Female\",\n  },\n  jm_kumo: {\n    name: \"kumo\",\n    language: \"ja\",\n    gender: \"Male\",\n  },\n  zf_xiaobei: {\n    name: \"xiaobei\",\n    language: \"zh\",\n    gender: \"Female\",\n  },\n  zf_xiaoni: {\n    name: \"xiaoni\",\n    language: \"zh\",\n    gender: \"Female\",\n  },\n  zf_xiaoxiao: {\n    name: \"xiaoxiao\",\n    language: \"zh\",\n    gender: \"Female\",\n  },\n  zf_xiaoyi: {\n    name: \"xiaoyi\",\n    language: \"zh\",\n    gender: \"Female\",\n  },\n  zm_yunjian: {\n    name: \"yunjian\",\n    language: \"zh\",\n    gender: \"Male\",\n  },\n  zm_yunxi: {\n    name: \"yunxi\",\n    language: \"zh\",\n    gender: \"Male\",\n  },\n  zm_yunxia: {\n    name: \"yunxia\",\n    language: \"zh\",\n    gender: \"Male\",\n  },\n  zm_yunyang: {\n    name: \"yunyang\",\n    language: \"zh\",\n    gender: \"Male\",\n  },\n});\n\nconst VOICE_DATA_URL = \"https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/main/voices\";\n\n/**\n *\n * @param {keyof typeof VOICES} id\n * @returns {Promise<ArrayBufferLike>}\n */\nasync function getVoiceFile(id: string) {\n  const url = `${VOICE_DATA_URL}/${id}.bin`;\n\n  let cache;\n  try {\n    cache = await caches.open(\"kokoro-voices\");\n    const cachedResponse = await cache.match(url);\n    if (cachedResponse) {\n      return await cachedResponse.arrayBuffer();\n    }\n  } catch (e) {\n    console.warn(\"Unable to open cache\", e);\n  }\n\n  // No cache, or cache failed to open. Fetch the file.\n  const response = await fetch(url);\n  const buffer = await response.arrayBuffer();\n\n  if (cache) {\n    try {\n      // NOTE: We use `new Response(buffer, ...)` instead of `response.clone()` to handle LFS files\n      await cache.put(\n        url,\n        new Response(buffer, {\n          headers: response.headers,\n        }),\n      );\n    } catch (e) {\n      console.warn(\"Unable to cache file\", e);\n    }\n  }\n\n  return buffer;\n}\n\nconst VOICE_CACHE = new Map();\nexport async function getVoiceData(voice: any) {\n  if (VOICE_CACHE.has(voice)) {\n    return VOICE_CACHE.get(voice);\n  }\n\n  const buffer = new Float32Array(await getVoiceFile(voice));\n  VOICE_CACHE.set(voice, buffer);\n  return buffer;\n}","import { StyleTextToSpeech2Model, AutoTokenizer, Tensor } from \"../libs/transformers/transformers\";\nimport { ModelConfig } from '../config/models/types';\nimport { phonemize } from \"../libs/transformers/utils/phonemize\";\nimport { getVoiceData, VOICES } from \"../libs/transformers/utils/voices\";\n\n\nconst STYLE_DIM = 256;\nconst SAMPLE_RATE = 24000;\n\nexport class TTSEngine {\n  private model: StyleTextToSpeech2Model | null = null;\n  private tokenizer: any = null;\n\n  constructor() {\n    this.model = null;\n    this.tokenizer = null;\n  }\n\n  async loadModel(modelConfig: ModelConfig, options: any = {}) {\n    // console.log('Loading TTS model... ', modelConfig.repo, options);\n    try {\n      this.model = await StyleTextToSpeech2Model.from_pretrained(modelConfig.repo, {\n        progress_callback: options.onProgress,\n        dtype: options.dtype || \"fp32\",\n        device:  \"webgpu\",\n      });\n      \n      this.tokenizer = await AutoTokenizer.from_pretrained(modelConfig.repo, {\n        progress_callback: options.onProgress\n      });\n    } catch (error) {\n      console.error('Error loading TTS model:', error);\n      throw error;\n    }\n  }\n\n  async *generateSpeechStream(text: string, options: any = {}): AsyncGenerator<Float32Array> {\n    console.log(\"Streaming flow triggered\"); // Log to confirm streaming is used\n    \n    if (!this.model || !this.tokenizer) {\n      throw new Error('TTS model not initialized');\n    }\n\n    const { voice = \"af_bella\", speed = 1, language = \"en-us\" } = options;\n\n    if (!VOICES.hasOwnProperty(voice)) {\n      console.error(`Voice \"${voice}\" not found. Available voices:`);\n      console.table(VOICES);\n      throw new Error(`Voice \"${voice}\" not found. Should be one of: ${Object.keys(VOICES).join(\", \")}.`);\n    }\n\n    try {\n      // Split long text into manageable chunks\n      // Maximum character limit per chunk (based on testing)\n      const MAX_CHUNK_LENGTH = 250;\n      const textChunks = this.splitTextIntoChunks(text, MAX_CHUNK_LENGTH);\n      console.log(`Text split into ${textChunks.length} chunks for processing`);\n\n      // Process each chunk and collect audio data\n      for (const chunk of textChunks) {\n        // Pass explicit language code directly to phonemize\n        const phonemes = await phonemize(chunk, language);\n        console.log(`Phonemized chunk: ${chunk.length} chars into ${phonemes.length} phoneme chars`);\n\n        const { input_ids } = this.tokenizer(phonemes, {\n          truncation: true,\n        });\n\n        // Select voice style based on number of input tokens\n        const num_tokens = Math.min(Math.max(\n          input_ids.dims.at(-1) - 2, // Without padding\n          0,\n        ), 509);\n\n        // Load voice style\n        const data = await getVoiceData(voice);\n        const offset = num_tokens * STYLE_DIM;\n        const voiceData = data.slice(offset, offset + STYLE_DIM);\n\n        // Prepare model inputs\n        const inputs = {\n          input_ids: input_ids,\n          style: new Tensor(\"float32\", voiceData, [1, STYLE_DIM]),\n          speed: new Tensor(\"float32\", [speed], [1]),\n        };\n\n        // Generate audio for this chunk\n        const output = await this.model._call(inputs);\n        \n        if (!output || !output.waveform) {\n          console.warn('Model returned null or undefined waveform for a chunk, skipping');\n          continue;\n        }\n        \n        // Convert Tensor to Float32Array\n        const chunkAudioData = new Float32Array(output.waveform.data);\n        \n        if (chunkAudioData.length === 0) {\n          console.warn('Generated audio data is empty for a chunk, skipping');\n          continue;\n        }\n\n        // Normalize audio data\n        const maxValue = chunkAudioData.reduce((max, val) => Math.max(max, Math.abs(val)), 0);\n        const normalizedData = maxValue > 0 ? \n          new Float32Array(chunkAudioData.length) : \n          chunkAudioData;\n        \n        if (maxValue > 0) {\n          for (let i = 0; i < chunkAudioData.length; i++) {\n            normalizedData[i] = chunkAudioData[i] / maxValue;\n          }\n        }\n\n        // Yield smaller chunks of the normalized audio data for streaming\n        const streamChunkSize = 4096; // Can be adjusted for performance\n        for (let i = 0; i < normalizedData.length; i += streamChunkSize) {\n          const streamChunk = normalizedData.slice(i, i + streamChunkSize);\n          if (streamChunk.length > 0) {\n            yield streamChunk;\n          }\n        }\n        \n        // Small pause between chunks for natural-sounding speech\n        const pauseSamples = Math.floor(0.2 * SAMPLE_RATE); // 200ms pause\n        const pauseChunk = new Float32Array(pauseSamples).fill(0);\n        yield pauseChunk;\n      }\n    } catch (error) {\n      console.error('Detailed error in generateSpeechStream:', error);\n      throw error;\n    }\n  }\n  \n  // Helper method to split text into manageable chunks\n  private splitTextIntoChunks(text: string, maxChunkLength: number): string[] {\n    // Find natural break points (sentences, clauses) to split text\n    const chunks: string[] = [];\n    \n    // Use regex to split by sentence boundaries but keep punctuation\n    const sentences = text.match(/[^.!?]+[.!?]+/g) || [text];\n    \n    let currentChunk = '';\n    for (const sentence of sentences) {\n      // If adding this sentence would exceed max length and we already have content\n      if (currentChunk.length + sentence.length > maxChunkLength && currentChunk.length > 0) {\n        chunks.push(currentChunk);\n        currentChunk = sentence;\n      } else {\n        // Otherwise add to current chunk\n        currentChunk += sentence;\n      }\n      \n      // If current chunk is already too long, split it at clause boundaries\n      if (currentChunk.length > maxChunkLength) {\n        const clauses = currentChunk.split(/[,;:]/);\n        currentChunk = '';\n        \n        for (const clause of clauses) {\n          if (currentChunk.length + clause.length > maxChunkLength && currentChunk.length > 0) {\n            chunks.push(currentChunk);\n            currentChunk = clause;\n          } else {\n            currentChunk += clause;\n          }\n        }\n      }\n    }\n    \n    // Add any remaining text\n    if (currentChunk.length > 0) {\n      chunks.push(currentChunk);\n    }\n    \n    // If any chunk is still too long, use hard splitting as a fallback\n    return chunks.flatMap(chunk => {\n      if (chunk.length <= maxChunkLength) {\n        return [chunk];\n      } else {\n        // Hard split by character count, trying to break at word boundaries\n        const words = chunk.split(' ');\n        const hardChunks: string[] = [];\n        let currentHardChunk = '';\n        \n        for (const word of words) {\n          if (currentHardChunk.length + word.length + 1 > maxChunkLength) {\n            hardChunks.push(currentHardChunk);\n            currentHardChunk = word;\n          } else {\n            currentHardChunk += (currentHardChunk ? ' ' : '') + word;\n          }\n        }\n        \n        if (currentHardChunk) {\n          hardChunks.push(currentHardChunk);\n        }\n        \n        return hardChunks;\n      }\n    });\n  }\n}\n\n","import {\n  pipeline,\n  TextGenerationPipeline,\n  FeatureExtractionPipeline,\n  AutomaticSpeechRecognitionPipeline,\n  TextToAudioPipeline,\n  ImageToTextPipeline,\n  ImageToImagePipeline,\n  ImageFeatureExtractionPipeline,\n  PipelineType\n} from '../libs/transformers/transformers';\nimport { ModelConfig } from '../config/models/types';\nimport { TTSEngine } from './tts-engine';\nimport { AutoProcessor, MultiModalityCausalLM } from '../libs/transformers/transformers';\n\nexport class TransformersEngineWrapper {\n  private transformersPipeline:\n    | TextGenerationPipeline\n    | FeatureExtractionPipeline\n    | AutomaticSpeechRecognitionPipeline\n    | TextToAudioPipeline\n    | ImageToTextPipeline\n    | ImageToImagePipeline\n    | ImageFeatureExtractionPipeline\n    | null = null;\n  private modelType: string | null = null;\n  private ttsEngine: TTSEngine | null = null;\n  private imageProcessor: any | null = null;\n  private multimodalModel: any | null = null;\n\n  constructor() {\n    this.transformersPipeline = null;\n    this.modelType = null;\n  }\n\n  async loadModel(modelConfig: ModelConfig, options: any = {}) {\n    try {\n      // Validate required model config properties\n      if (!modelConfig.modelType) {\n        throw new Error('Model configuration missing required \"modelType\" property');\n      }\n      if (!modelConfig.repo) {\n        throw new Error('Model configuration missing required \"repo\" property');\n      }\n\n      this.modelType = modelConfig.modelType;\n      \n      options.device = 'webgpu';\n\n      // Configure pipeline options with proper worker settings\n      const pipelineOptions = {\n        progress_callback: options.onProgress || (() => {}),\n        ...options\n      };\n\n      // Handle TTS models first, before attempting to create other pipelines\n      if (modelConfig.modelType === 'text-to-speech') {\n        this.ttsEngine = new TTSEngine();\n        console.log('Loading TTS model...');\n        await this.ttsEngine.loadModel(modelConfig, options);\n        console.log('TTS model loaded');\n        return; // Exit early for TTS models\n      }\n\n      // Initialize image processor for multimodal models\n      if (modelConfig.modelType === 'multimodal') {\n        options.device = \"webgpu\";\n        // console.log('Loading multimodal model...');\n        this.imageProcessor = await AutoProcessor.from_pretrained(modelConfig.repo, pipelineOptions);\n        // console.log('Image processor loaded');\n        this.multimodalModel = await MultiModalityCausalLM.from_pretrained(modelConfig.repo, pipelineOptions);\n        // console.log('Multimodal model loaded');\n        return;\n      }\n\n      // For non-TTS models, create the appropriate pipeline\n      const pipelineType = modelConfig.pipeline as PipelineType;\n      this.transformersPipeline = await pipeline(pipelineType, modelConfig.repo, pipelineOptions);\n\n    } catch (error) {\n      console.error('Error loading Transformers model:', error);\n      const message = error instanceof Error ? error.message : String(error);\n      throw new Error(`Failed to load Transformers model \"${modelConfig.modelName}\": ${message}`);\n    }\n  }\n\n  // Text generation specific method\n  async generateText(input: string | Array<{ role: string; content: string }>, options: any = {}) {\n    if (!this.transformersPipeline || this.modelType !== 'text-generation') {\n      throw new Error('Text generation pipeline not initialized.');\n    }\n\n    let messages = Array.isArray(input) ? input : [];\n\n    // If input is a string, construct messages array\n    if (typeof input === 'string') {\n      if (options.system_prompt) {\n        messages.push({ role: 'system', content: options.system_prompt });\n      }\n      messages.push({ role: 'user', content: input });\n    }\n\n    // Convert messages array to text format\n    const prompt = messages.map((m) => `${m.role}: ${m.content}`).join('\\n');\n\n    const result = await (this.transformersPipeline as any)(prompt, {\n      temperature: options.temperature ?? 0.1,\n      max_new_tokens: options.max_new_tokens ?? 300,\n      repetition_penalty: options.repetition_penalty,\n      no_repeat_ngram_size: options.no_repeat_ngram_size,\n      num_beams: options.num_beams,\n      num_return_sequences: options.num_return_sequences,\n      ...options,\n    });\n    return result;\n  }\n\n  // Feature extraction specific method\n  async extractFeatures(text: string, options: any = {}) {\n    if (!this.transformersPipeline || this.modelType !== 'feature-extraction') {\n      throw new Error('Feature extraction pipeline not initialized.');\n    }\n    return await (this.transformersPipeline as any)(text, {\n      pooling: options.pooling ?? 'mean',\n      normalize: options.normalize ?? true,\n      ...options,\n    });\n  }\n\n  // Speech recognition specific method\n  async transcribe(audioInput: Float32Array | Float64Array | string | Blob, options: any = {}) {\n    if (!this.transformersPipeline || this.modelType !== 'automatic-speech-recognition') {\n      throw new Error('Speech recognition pipeline not initialized.');\n    }\n\n    const input = audioInput instanceof Blob ? new Float32Array(await audioInput.arrayBuffer()) : (audioInput as any);\n\n    const result = await (this.transformersPipeline as any)(input, {\n      language: options.language,\n      task: options.task,\n      return_timestamps: options.return_timestamps,\n      chunk_length_s: options.chunk_length_s,\n      stride_length_s: options.stride_length_s,\n      ...options,\n    });\n    return result;\n  }\n\n  // Streaming text-to-speech method\n  async textToSpeechStream(text: string, options: any = {}) {\n    if (!this.ttsEngine) {\n      throw new Error('Text-to-speech engine not initialized.');\n    }\n    \n    try {\n      // Find the selected voice's language from options or fallback\n      const stream = this.ttsEngine.generateSpeechStream(text, options);\n      \n      // Return both the stream and the sample rate needed for playback\n      return {\n        stream: stream,\n        sampleRate: 24000 // Hardcoded based on kokoro-tts's known sample rate\n      };\n    } catch (error) {\n      console.error('Error in text-to-speech stream:', error);\n      throw error;\n    }\n  }\n\n  // Generic method for backward compatibility\n  async generate(prompt: string, options: any = {}) {\n    switch (this.modelType) {\n      case 'text-generation':\n        return this.generateText(prompt, options);\n      case 'feature-extraction':\n        return this.extractFeatures(prompt, options);\n      case 'automatic-speech-recognition':\n        return this.transcribe(prompt, options);\n      case 'text-to-speech':\n        throw new Error('Direct text-to-speech is no longer supported. Use textToSpeechStream instead.');\n      default:\n        throw new Error(`Unsupported model type: ${this.modelType}`);\n    }\n  }\n\n  async embed(input: string, options: any = {}) {\n    if (!this.transformersPipeline || this.modelType !== 'feature-extraction') {\n      console.debug(`Feature extraction pipeline not initialized. ${input}, ${options}`);\n      throw new Error('Feature extraction pipeline not initialized.');\n    }\n  }\n\n  async generateImage(input: { text: string }, options: any = {}) {\n    if (this.modelType !== 'multimodal') {\n      throw new Error('Multimodal model not initialized.');\n    }\n\n    if (!this.imageProcessor || !this.multimodalModel) {\n      throw new Error('Image processor or multimodal model not initialized.');\n    }\n\n    try {\n      const conversation = [{ 'role': 'user', 'content': input.text }];\n      \n      // Process the input text with the image processor\n      const inputs = await this.imageProcessor(conversation, {\n        chat_template: \"text_to_image\",\n        ...options\n      });\n\n      // Generate the image\n      const num_image_tokens = this.imageProcessor.num_image_tokens;\n\n      const outputs = await this.multimodalModel.generate({\n        ...inputs,\n        min_new_tokens: num_image_tokens,\n        max_new_tokens: num_image_tokens,\n        do_sample: true,\n      });\n\n      return outputs;\n    } catch (error) {\n      console.error('Error generating image:', error);\n      throw error;\n    }\n  }\n}\n","{\n    \"llama-3.2-1b-instruct\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"Llama-3.2-1B-Instruct\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Llama-3.2-1B-Instruct-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\",\n            \"q0f32\",\n            \"q0f16\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"defaultParams\": {\n            \"temperature\": 0.7,\n            \"maxTokens\": 2048\n        },\n        \"pipeline\": \"text-generation\"\n    },\n    \"llama-3.2-3b-instruct\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"Llama-3.2-3B-Instruct\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Llama-3.2-3B-Instruct-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"defaultParams\": {\n            \"temperature\": 0.7,\n            \"maxTokens\": 2048\n        },\n        \"pipeline\": \"text-generation\",\n        \"metadata\": {\n            \"context_window_size\": 4096,\n            \"download_size_in_mb\": {\n                \"q4f16_1\": 1797,\n                \"q4f32_1\": 1797\n            },\n            \"estimated_vram_in_mb\": {\n                \"q4f16_1\": 1797,\n                \"q4f32_1\": 1797\n            }\n        }\n    },\n    \"hermes-llama-3.2-3b\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"hermes-llama-3.2-3b\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Hermes-3-Llama-3.2-3B-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"defaultParams\": {\n            \"temperature\": 0.7,\n            \"maxTokens\": 2048\n        },\n        \"pipeline\": \"text-generation\",\n        \"metadata\": {\n            \"context_window_size\": 4096,\n            \"download_size_in_mb\": {\n                \"q4f16_1\": 1797,\n                \"q4f32_1\": 1797\n            },\n            \"estimated_vram_in_mb\": {\n                \"q4f16_1\": 1797,\n                \"q4f32_1\": 1797\n            }\n        }\n    },\n    \"qwen2.5-3b-instruct\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"Qwen2.5-3B-Instruct\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Qwen2.5-3B-Instruct-{quantization}-MLC\",\n        \"quantizations\": [\"q4f32_1\"],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"defaultParams\": {\n            \"temperature\": 0.7,\n            \"maxTokens\": 4096\n        },\n        \"pipeline\": \"text-generation\"\n    },  \n    \"smollm2-135m-instruct\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"SmolLM2-135M-Instruct\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/SmolLM2-135M-Instruct-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q0f32\",\n            \"q0f16\"\n        ],\n        \"defaultQuantization\": \"q0f32\",\n        \"defaultParams\": {\n            \"temperature\": 0.7,\n            \"maxTokens\": 2048\n        },\n        \"required_features\": [\n            \"shader-f16\"\n        ],\n        \"overrides\": {\n            \"context_window_size\": 4096\n        },\n        \"pipeline\": \"text-generation\"\n    },\n    \"smollm2-360m-instruct\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"SmolLM2-360M-Instruct\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/SmolLM2-360M-Instruct-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\",\n            \"q0f32\",\n            \"q0f16\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"required_features\": [\n            \"shader-f16\"\n        ],\n        \"defaultParams\": {\n            \"temperature\": 0.1,\n            \"maxTokens\": 2048\n        },\n        \"pipeline\": \"text-generation\"\n    },\n    \"smollm2-1.7b-instruct\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"SmolLM2-1.7B-Instruct\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/SmolLM2-1.7B-Instruct-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"pipeline\": \"text-generation\",\n        \"defaultParams\": {\n            \"temperature\": 0.1,\n            \"maxTokens\": 2048\n        }\n    },\n    \"qwen2.5-0.5b-instruct\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"Qwen2.5-0.5B-Instruct\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Qwen2.5-0.5B-Instruct-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\",\n            \"q0f32\",\n            \"q0f16\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"pipeline\": \"text-generation\"\n    },\n    \"gemma-2b-it\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"gemma-2b-it\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/gemma-2b-it-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"pipeline\": \"text-generation\",\n        \"required_features\": [\n            \"shader-f16\"\n        ]\n    },\n    \"tinyllama-1.1b-chat-v0.4\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"TinyLlama-1.1B-Chat-v0.4\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/TinyLlama-1.1B-Chat-v0.4-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"pipeline\": \"text-generation\"\n    },\n    \"phi-3.5-mini-instruct\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"Phi-3.5-mini-instruct\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Phi-3.5-mini-instruct-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"pipeline\": \"text-generation\"\n    },\n    \"qwen2.5-1.5b-instruct\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"Qwen2.5-1.5B-Instruct\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Qwen2.5-1.5B-Instruct-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"pipeline\": \"text-generation\"\n    },\n    \"deepseek-r1-distill-qwen-1.5b\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"DeepSeek-R1-Distill-Qwen-1.5B-MLC\",\n        \"modelType\": \"text-generation\",\n        \"modelLibrary\": \"Qwen2-1.5B-Instruct-q4f32_1-ctx4k_cs1k-webgpu.wasm\",\n        \"repo\": \"sauravpanda/DeepSeek-R1-Distill-Qwen-1.5B-MLC\",\n        \"quantizations\": [\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"pipeline\": \"text-generation\"\n    },\n    \"deepseek-r1-distill-qwen-7b\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"DeepSeek-R1-Distill-Qwen-7B\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/DeepSeek-R1-Distill-Qwen-7B-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"pipeline\": \"text-generation\"\n    },\n    \"deepseek-r1-distill-llama-8b\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"DeepSeek-R1-Distill-Llama-8B\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/DeepSeek-R1-Distill-Llama-8B-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"pipeline\": \"text-generation\"\n    },\n    \"snowflake-arctic-embed-m-b4\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"snowflake-arctic-embed-m-b4\",\n        \"modelType\": \"embedding\",\n        \"repo\": \"mlc-ai/snowflake-arctic-embed-m-{quantization}-MLC-b4\",\n        \"quantizations\": [\n            \"q0f32\"\n        ],\n        \"defaultQuantization\": \"q0f32\",\n        \"pipeline\": \"embedding\",\n        \"metadata\": {\n            \"context_window_size\": 512,\n            \"download_size_in_mb\": {\n                \"q0f32\": 218\n            },\n            \"estimated_vram_in_mb\": {\n                \"q0f32\": 218\n            }\n        }\n    },\n    \"snowflake-arctic-embed-s-b4\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"snowflake-arctic-embed-s-b4\",\n        \"modelType\": \"embedding\",\n        \"repo\": \"mlc-ai/snowflake-arctic-embed-s-{quantization}-MLC-b4\",\n        \"quantizations\": [\n            \"q0f32\"\n        ],\n        \"defaultQuantization\": \"q0f32\",\n        \"pipeline\": \"embedding\",\n        \"metadata\": {\n            \"context_window_size\": 512,\n            \"download_size_in_mb\": {\n                \"q0f32\": 66.4\n            },\n            \"estimated_vram_in_mb\": {\n                \"q0f32\": 66.4\n            }\n        }\n    },\n    \"snowflake-arctic-embed-m-b32\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"snowflake-arctic-embed-m-b32\",\n        \"modelType\": \"embedding\",\n        \"repo\": \"mlc-ai/snowflake-arctic-embed-m-{quantization}-MLC-b32\",\n        \"quantizations\": [\n            \"q0f32\"\n        ],\n        \"defaultQuantization\": \"q0f32\",\n        \"pipeline\": \"embedding\",\n        \"metadata\": {\n            \"context_window_size\": 512,\n            \"download_size_in_mb\": {\n                \"q0f32\": 218\n            },\n            \"estimated_vram_in_mb\": {\n                \"q0f32\": 218\n            }\n        }\n    },\n    \"snowflake-arctic-embed-s-b32\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"snowflake-arctic-embed-s-b32\",\n        \"modelType\": \"embedding\",\n        \"repo\": \"mlc-ai/snowflake-arctic-embed-s-{quantization}-MLC-b32\",\n        \"quantizations\": [\n            \"q0f32\"\n        ],\n        \"defaultQuantization\": \"q0f32\",\n        \"pipeline\": \"embedding\",\n        \"metadata\": {\n            \"context_window_size\": 512,\n            \"download_size_in_mb\": {\n                \"q0f32\": 66.4\n            },\n            \"estimated_vram_in_mb\": {\n                \"q0f32\": 66.4\n            }\n        }\n    },\n    \"qwen3-0.6b\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"Qwen3-0.6B\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Qwen3-0.6B-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\",\n            \"q0f16\",\n            \"q0f32\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"defaultParams\": {\n            \"temperature\": 0.7,\n            \"maxTokens\": 4096\n        },\n        \"pipeline\": \"text-generation\",\n        \"metadata\": {\n            \"context_window_size\": 4096,\n            \"estimated_vram_in_mb\": {\n                \"q4f16_1\": 1403.34,\n                \"q4f32_1\": 1924.98,\n                \"q0f16\": 2220.38,\n                \"q0f32\": 3843.25\n            }\n        }\n    },\n    \"qwen3-1.7b\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"Qwen3-1.7B\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Qwen3-1.7B-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"defaultParams\": {\n            \"temperature\": 0.7,\n            \"maxTokens\": 4096\n        },\n        \"pipeline\": \"text-generation\",\n        \"metadata\": {\n            \"context_window_size\": 4096,\n            \"estimated_vram_in_mb\": {\n                \"q4f16_1\": 2036.66,\n                \"q4f32_1\": 2635.44\n            }\n        }\n    },\n    \"qwen3-4b\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"Qwen3-4B\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Qwen3-4B-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"defaultParams\": {\n            \"temperature\": 0.7,\n            \"maxTokens\": 4096\n        },\n        \"pipeline\": \"text-generation\",\n        \"metadata\": {\n            \"context_window_size\": 4096,\n            \"estimated_vram_in_mb\": {\n                \"q4f16_1\": 3431.59,\n                \"q4f32_1\": 4327.71\n            }\n        }\n    },\n    \"qwen3-8b\": {\n        \"engine\": \"mlc\",\n        \"modelName\": \"Qwen3-8B\",\n        \"modelType\": \"text-generation\",\n        \"repo\": \"mlc-ai/Qwen3-8B-{quantization}-MLC\",\n        \"quantizations\": [\n            \"q4f16_1\",\n            \"q4f32_1\"\n        ],\n        \"defaultQuantization\": \"q4f32_1\",\n        \"defaultParams\": {\n            \"temperature\": 0.7,\n            \"maxTokens\": 4096\n        },\n        \"pipeline\": \"text-generation\",\n        \"metadata\": {\n            \"context_window_size\": 4096,\n            \"estimated_vram_in_mb\": {\n                \"q4f16_1\": 5695.78,\n                \"q4f32_1\": 6852.55\n            }\n        }\n    }\n}","{\n  \"llama-3.2-1b-instruct\": {\n    \"engine\": \"transformers\",\n    \"modelName\": \"Llama-3.2-1b-Instruct\",\n    \"modelType\": \"text-generation\",\n    \"repo\": \"Xenova/llama-3.2-1b-instruct\",\n    \"pipeline\": \"text-generation\",\n    \"defaultParams\": {\n      \"temperature\": 0.7,\n      \"maxLength\": 2048\n    },\n    \"defaultQuantization\": \"q4\"\n  },\n  \"whisper-tiny-en\": {\n    \"engine\": \"transformers\",\n    \"modelName\": \"whisper-tiny-en\",\n    \"modelType\": \"automatic-speech-recognition\",\n    \"repo\": \"onnx-community/whisper-tiny.en\",\n    \"pipeline\": \"automatic-speech-recognition\",\n    \"defaultQuantization\": \"q4\",\n    \"quantizations\": [\"q4\", \"fp16\", \"int4\"]\n  },\n  \"whisper-base-all\": {\n    \"engine\": \"transformers\",\n    \"modelName\": \"whisper-base-all\",\n    \"modelType\": \"automatic-speech-recognition\",\n    \"repo\": \"onnx-community/whisper-base_timestamped\",\n    \"pipeline\": \"automatic-speech-recognition\",\n    \"defaultQuantization\": \"q4\",\n    \"quantizations\": [\"q4\", \"fp16\", \"int4\"]\n  },\n  \"whisper-small-all\": {\n    \"engine\": \"transformers\",\n    \"modelName\": \"whisper-small-all\",\n    \"modelType\": \"automatic-speech-recognition\",\n    \"repo\": \"onnx-community/whisper-small_timestamped\",\n    \"pipeline\": \"automatic-speech-recognition\",\n    \"defaultQuantization\": \"q4\",\n    \"quantizations\": [\"q4\", \"fp16\", \"int4\"]\n  },\n  \"kokoro-tts\": {\n    \"engine\": \"transformers\",\n    \"modelName\": \"kokoro-tts\",\n    \"modelType\": \"text-to-speech\",\n    \"repo\": \"onnx-community/Kokoro-82M-v1.0-ONNX\",\n    \"pipeline\": \"text-to-speech\",\n    \"defaultQuantization\": \"fp32\",\n    \"quantizations\": [\"q4\", \"q8\", \"fp32\", \"fp16\", \"q4f16\"],\n    \"defaultParams\": {\n      \"language\": \"en\"\n    }\n  },\n  \"janus-1.3b\": {\n    \"engine\": \"transformers\",\n    \"modelName\": \"Janus-1.3B-ONNX\",\n    \"modelType\": \"multimodal\",\n    \"repo\": \"onnx-community/Janus-1.3B-ONNX\",\n    \"pipeline\": \"multimodal\",\n    \"defaultQuantization\": \"q4f16\",\n    \"quantizations\": [\"q4\", \"q8\", \"fp32\", \"fp16\", \"q4f16\"],\n    \"defaultParams\": {\n    }\n  }\n} ","// src/index.js (Main entry point)\n\nimport { MLCEngineWrapper } from '../../engines/mlc-engine-wrapper';\nimport { TransformersEngineWrapper } from '../../engines/transformer-engine-wrapper';\nimport { ModelConfig, MLCConfig, TransformersConfig } from '../../config/models/types';\nimport mlcModels from '../../config/models/mlc-models.json';\nimport transformersModels from '../../config/models/transformers-models.json';\n\n// Combine model configurations\nconst MODEL_CONFIG: Record<string, ModelConfig> = {\n  ...(mlcModels as Record<string, MLCConfig>),\n  ...(transformersModels as Record<string, TransformersConfig>),\n};\n\nexport class BrowserAI {\n  private engine: MLCEngineWrapper | TransformersEngineWrapper | null;\n  public currentModel: ModelConfig | null;\n  private mediaRecorder: MediaRecorder | null = null;\n  private audioChunks: Blob[] = [];\n  private modelIdentifier: string | null = null;\n  private customModels: Record<string, ModelConfig> = {};\n\n  constructor() {\n    this.engine = null;\n    this.currentModel = null;\n  }\n\n  registerCustomModel(modelIdentifier: string, modelConfig: ModelConfig): void {\n    if (MODEL_CONFIG[modelIdentifier]) {\n      console.warn(`Overriding existing model with identifier \"${modelIdentifier}\"`);\n    }\n    this.customModels[modelIdentifier] = modelConfig;\n  }\n\n  async loadModel(modelIdentifier: string, options: Record<string, unknown> = {}): Promise<void> {\n    this.modelIdentifier = modelIdentifier;\n    // Check custom models first, then fall back to built-in models\n    const modelConfig = this.customModels[this.modelIdentifier] || MODEL_CONFIG[this.modelIdentifier];\n    if (!modelConfig) {\n      throw new Error(`Model identifier \"${this.modelIdentifier}\" not recognized.`);\n    }\n\n    // Check if model exists in both MLC and Transformers configs\n    const mlcVersion = (mlcModels as Record<string, MLCConfig>)[this.modelIdentifier];\n    // const transformersVersion = (transformersModels as Record<string, TransformersConfig>)[modelIdentifier];\n\n    // For text-generation models, prefer MLC if available\n    let engineToUse = modelConfig.engine;\n    if (modelConfig.modelType === 'text-generation' && mlcVersion) {\n      engineToUse = 'mlc';\n    }\n\n    switch (engineToUse) {\n      case 'mlc':\n        this.engine = new MLCEngineWrapper();\n        await this.engine.loadModel(mlcVersion || modelConfig, options);\n        break;\n      case 'transformers':\n        this.engine = new TransformersEngineWrapper();\n        await this.engine.loadModel(modelConfig, options);\n        break;\n      default:\n        throw new Error(`Engine \"${engineToUse}\" not supported.`);\n    }\n\n    this.currentModel = modelConfig;\n  }\n\n  async generateText(prompt: string, options: Record<string, unknown> = {}): Promise<unknown> {\n    if (!this.engine) {\n      throw new Error('No model loaded. Please call loadModel first.');\n    }\n\n    try {\n      const result = await this.engine.generateText(prompt, options);\n      return result;\n    } catch (error) {\n      console.error('Error generating text:', error);\n      throw error;\n    }\n  }\n\n  async embed(input: string, options: Record<string, unknown> = {}): Promise<unknown> {\n    if (!this.engine) {\n      throw new Error('No model loaded. Please call loadModel first.');\n    }\n    return await this.engine.embed(input, options);\n  }\n\n  async transcribeAudio(audio: Blob | Float32Array, options: Record<string, unknown> = {}): Promise<unknown> {\n    if (!this.engine) {\n      throw new Error('No model loaded. Please call loadModel first.');\n    }\n\n    try {\n      if (this.engine instanceof TransformersEngineWrapper) {\n        if (audio instanceof Blob) {\n          const audioContext = new AudioContext({\n            sampleRate: 16000, // Force 16kHz sample rate\n          });\n\n          const arrayBuffer = await audio.arrayBuffer();\n          const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n\n          // Ensure we get the correct number of samples\n          const float32Data = new Float32Array(Math.floor(audioBuffer.length));\n          audioBuffer.copyFromChannel(float32Data, 0);\n\n          // Clean up\n          audioContext.close();\n\n          return await this.engine.transcribe(float32Data, options);\n        }\n        return await this.engine.transcribe(audio, options);\n      } else {\n        throw new Error('Engine does not support transcribe method.');\n      }\n    } catch (error) {\n      console.error('Transcription error:', error);\n      throw error;\n    }\n  }\n\n  async startRecording(): Promise<void> {\n    if (this.mediaRecorder) {\n      throw new Error('Recording already in progress');\n    }\n\n    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n    this.mediaRecorder = new MediaRecorder(stream);\n    this.audioChunks = [];\n\n    this.mediaRecorder.ondataavailable = (event) => {\n      if (event.data.size > 0) {\n        this.audioChunks.push(event.data);\n      }\n    };\n\n    this.mediaRecorder.start();\n  }\n\n  async stopRecording(): Promise<Blob> {\n    return new Promise((resolve, reject) => {\n      if (!this.mediaRecorder || this.mediaRecorder.state === 'inactive') {\n        reject(new Error('No recording in progress'));\n        return;\n      }\n\n      this.mediaRecorder.onstop = () => {\n        const audioBlob = new Blob(this.audioChunks, { type: 'audio/webm' });\n        this.audioChunks = [];\n        this.mediaRecorder = null;\n        resolve(audioBlob);\n      };\n\n      this.mediaRecorder.stop();\n    });\n  }\n\n  async generateResponse(text: string): Promise<string> {\n    if (!this.modelIdentifier) {\n      throw new Error('No model loaded. Please call loadModel first.');\n    }\n    if (this.currentModel?.modelName !== this.modelIdentifier) {\n      await this.loadModel(this.modelIdentifier);\n    }\n    const response = await this.generateText(text);\n    return response as string;\n  }\n\n  async textToSpeech(text: string, options: Record<string, unknown> = {}): Promise<any> {\n    // Check if engine is already loaded\n    if (!this.engine) {\n      // Load the transformers engine if not already loaded\n      this.engine = new TransformersEngineWrapper();\n      await this.engine.loadModel(MODEL_CONFIG['kokoro-tts'], {\n        quantized: true,\n        device: 'webgpu',\n        ...options,\n      });\n    }\n\n    try {\n      if (this.engine instanceof TransformersEngineWrapper) {\n        // Use the streaming method\n        return await this.engine.textToSpeechStream(text, options);\n      } else {\n        throw new Error('Current engine does not support text-to-speech streaming');\n      }\n    } catch (error) {\n      console.error('Error generating speech stream:', error);\n      throw error;\n    }\n  }\n\n  async generateImage(text: string, options: Record<string, unknown> = {}): Promise<string> {\n    if (!this.modelIdentifier) {\n      throw new Error('No model loaded. Please call loadModel first.');\n    }\n\n    if (this.currentModel?.modelType !== 'multimodal') {\n      throw new Error('Current model does not support multimodal inputs.');\n    }\n\n    if (this.engine instanceof TransformersEngineWrapper) {\n      const response = await this.engine.generateImage({\n        text: text as string,\n      }, options);\n      return response;\n    }\n\n    throw new Error('Current engine does not support multimodal generation');\n  }\n\n  async clearModelCache(): Promise<void> {\n    return new Promise<void>(async (resolve, reject) => {\n      try {\n        // MLC models are stored in Cache Storage with specific prefixes\n        const cacheNames = ['webllm/config', 'webllm/wasm', 'webllm/model'];\n        \n        // Get all cache names\n        const existingCacheNames = await caches.keys();\n        \n        // Filter caches that match our MLC prefixes\n        const mlcCaches = existingCacheNames.filter(name => \n          cacheNames.some(prefix => name.includes(prefix))\n        );\n        \n        // Delete all matching caches\n        await Promise.all(mlcCaches.map(name => caches.delete(name)));\n        \n        console.log('Successfully cleared MLC model cache');\n        resolve();\n      } catch (error) {\n        console.error('Error clearing model cache:', error);\n        reject(error);\n      }\n    });\n  }\n\n  async clearSpecificModelCache(modelIdentifier: string): Promise<void> {\n    if (!this.engine || !(this.engine instanceof MLCEngineWrapper)) {\n      throw new Error('MLC Engine not initialized.');\n    }\n    \n    try {\n      await this.engine.clearSpecificModel(modelIdentifier);\n      console.log(`Successfully cleared cache for model: ${modelIdentifier}`);\n    } catch (error) {\n      console.error(`Error clearing model cache for ${modelIdentifier}:`, error);\n      throw error;\n    }\n  }\n\n  dispose() {\n    if (this.engine instanceof MLCEngineWrapper) {\n      this.engine.dispose();\n    }\n    this.engine = null;\n    this.currentModel = null;\n  }\n}\n","import { Storable, Database, DatabaseConfig } from '../types';\nimport { Storage, StorageFactory } from '../storage';\n\n\nclass IndexedDBStorage<T extends Storable> implements Storage<T> {\n    private dbName: string;\n    private version: number;\n    private storeName: string;\n    private db: IDBDatabase | null = null;\n\n    constructor(config: DatabaseConfig) {\n      this.dbName = config.databaseName;\n      this.version = config.version || 1;\n      this.storeName = config.storeName || 'BrowserAIStore';\n\n    }\n\n\n    private async openDatabase(): Promise<IDBDatabase> {\n        return new Promise((resolve, reject) => {\n            if(this.db){\n                resolve(this.db)\n                return;\n            }\n\n          const request = indexedDB.open(this.dbName, this.version);\n\n          request.onerror = (event) => {\n            reject(`Database error: ${(event.target as IDBRequest).error}`);\n          };\n\n          request.onsuccess = (event) => {\n            this.db = (event.target as IDBRequest).result;\n            resolve(this.db);\n          };\n\n           request.onupgradeneeded = (event) => {\n            const db = (event.target as IDBRequest).result;\n\n            if (!db.objectStoreNames.contains(this.storeName)) {\n              db.createObjectStore(this.storeName, { keyPath: 'id' });\n            }\n          };\n        });\n      }\n\n\n    async store(data: T): Promise<void> {\n         const db = await this.openDatabase();\n        return new Promise((resolve, reject) => {\n          const transaction = db.transaction([this.storeName], 'readwrite');\n          const store = transaction.objectStore(this.storeName);\n          const request = store.add(data);\n\n          request.onsuccess = () => resolve();\n          request.onerror = (event) => reject(`Error storing data: ${(event.target as IDBRequest).error}`);\n        });\n      }\n\n      async get(id: string): Promise<T | undefined> {\n        const db = await this.openDatabase();\n        return new Promise((resolve, reject) => {\n          const transaction = db.transaction([this.storeName], 'readonly');\n          const store = transaction.objectStore(this.storeName);\n          const request = store.get(id);\n\n          request.onsuccess = (event) => resolve((event.target as IDBRequest).result as T);\n          request.onerror = (event) => reject(`Error getting data: ${(event.target as IDBRequest).error}`);\n        });\n      }\n\n     async getAll(): Promise<T[]> {\n         const db = await this.openDatabase();\n        return new Promise((resolve, reject) => {\n          const transaction = db.transaction([this.storeName], 'readonly');\n          const store = transaction.objectStore(this.storeName);\n          const request = store.getAll();\n\n          request.onsuccess = (event) => resolve((event.target as IDBRequest).result as T[]);\n          request.onerror = (event) => reject(`Error getting data: ${(event.target as IDBRequest).error}`);\n        });\n      }\n\n\n    async update(data: T): Promise<void> {\n        const db = await this.openDatabase();\n        return new Promise((resolve, reject) => {\n          const transaction = db.transaction([this.storeName], 'readwrite');\n          const store = transaction.objectStore(this.storeName);\n          const request = store.put(data);\n\n          request.onsuccess = () => resolve();\n          request.onerror = (event) => reject(`Error updating data: ${(event.target as IDBRequest).error}`);\n        });\n      }\n\n    async delete(id: string): Promise<void> {\n        const db = await this.openDatabase();\n        return new Promise((resolve, reject) => {\n          const transaction = db.transaction([this.storeName], 'readwrite');\n          const store = transaction.objectStore(this.storeName);\n          const request = store.delete(id);\n\n          request.onsuccess = () => resolve();\n          request.onerror = (event) => reject(`Error deleting data: ${(event.target as IDBRequest).error}`);\n        });\n      }\n\n     async clear(): Promise<void> {\n        const db = await this.openDatabase();\n         return new Promise((resolve, reject) => {\n          const transaction = db.transaction([this.storeName], 'readwrite');\n          const store = transaction.objectStore(this.storeName);\n          const request = store.clear();\n\n          request.onsuccess = () => resolve();\n          request.onerror = (event) => reject(`Error clearing data: ${(event.target as IDBRequest).error}`);\n        });\n    }\n\n\n    close(): void {\n        if(this.db){\n            this.db.close()\n            this.db = null\n        }\n      }\n  }\n\n\n export class IndexedDBStorageFactory<T extends Storable> implements StorageFactory<T>{\n   async createStorage(type: string, config: DatabaseConfig): Promise<Storage<T>> {\n       if(type !== 'indexeddb'){\n           throw new Error(`invalid type ${type}`);\n       }\n       return new IndexedDBStorage<T>(config);\n   }\n}","import { Storable, DatabaseConfig } from '../types';\nimport { Storage, StorageFactory } from '../storage';\n\nexport class SqliteStorage<T extends Storable> implements Storage<T> {\n    private db: IDBDatabase | null = null;\n    private readonly storeName: string;\n\n    constructor(config: DatabaseConfig) {\n        this.storeName = config.databaseName || 'defaultStore';\n        this.initDatabase();\n    }\n\n    private async initDatabase(): Promise<void> {\n        return new Promise((resolve, reject) => {\n            const request = indexedDB.open(this.storeName, 1);\n\n            request.onerror = () => reject(request.error);\n            request.onsuccess = () => {\n                this.db = request.result;\n                resolve();\n            };\n\n            request.onupgradeneeded = (event) => {\n                const db = (event.target as IDBOpenDBRequest).result;\n                if (!db.objectStoreNames.contains(this.storeName)) {\n                    db.createObjectStore(this.storeName, { keyPath: 'id' });\n                }\n            };\n        });\n    }\n\n    async store(data: T): Promise<void> {\n        await this.ensureDbReady();\n        return new Promise((resolve, reject) => {\n            const transaction = this.db!.transaction([this.storeName], 'readwrite');\n            const store = transaction.objectStore(this.storeName);\n            const request = store.add(data);\n\n            request.onerror = () => reject(request.error);\n            request.onsuccess = () => resolve();\n        });\n    }\n\n    async get(id: string): Promise<T | undefined> {\n        await this.ensureDbReady();\n        return new Promise((resolve, reject) => {\n            const transaction = this.db!.transaction([this.storeName], 'readonly');\n            const store = transaction.objectStore(this.storeName);\n            const request = store.get(id);\n\n            request.onerror = () => reject(request.error);\n            request.onsuccess = () => resolve(request.result || undefined);\n        });\n    }\n\n    async getAll(): Promise<T[]> {\n        await this.ensureDbReady();\n        return new Promise((resolve, reject) => {\n            const transaction = this.db!.transaction([this.storeName], 'readonly');\n            const store = transaction.objectStore(this.storeName);\n            const request = store.getAll();\n\n            request.onerror = () => reject(request.error);\n            request.onsuccess = () => resolve(request.result);\n        });\n    }\n\n    async update(data: T): Promise<void> {\n        await this.ensureDbReady();\n        return new Promise((resolve, reject) => {\n            const transaction = this.db!.transaction([this.storeName], 'readwrite');\n            const store = transaction.objectStore(this.storeName);\n            const request = store.put(data);\n\n            request.onerror = () => reject(request.error);\n            request.onsuccess = () => resolve();\n        });\n    }\n\n    async delete(id: string): Promise<void> {\n        await this.ensureDbReady();\n        return new Promise((resolve, reject) => {\n            const transaction = this.db!.transaction([this.storeName], 'readwrite');\n            const store = transaction.objectStore(this.storeName);\n            const request = store.delete(id);\n\n            request.onerror = () => reject(request.error);\n            request.onsuccess = () => resolve();\n        });\n    }\n\n    async clear(): Promise<void> {\n        await this.ensureDbReady();\n        return new Promise((resolve, reject) => {\n            const transaction = this.db!.transaction([this.storeName], 'readwrite');\n            const store = transaction.objectStore(this.storeName);\n            const request = store.clear();\n\n            request.onerror = () => reject(request.error);\n            request.onsuccess = () => resolve();\n        });\n    }\n\n    private async ensureDbReady(): Promise<void> {\n        if (!this.db) {\n            await this.initDatabase();\n        }\n    }\n\n    close(): void {\n        if (this.db) {\n            this.db.close();\n            this.db = null;\n        }\n    }\n}\n\nexport class SqliteStorageFactory<T extends Storable> implements StorageFactory<T> {\n    async createStorage(type: string, config: DatabaseConfig): Promise<Storage<T>> {\n        if(type !== 'sqlite'){\n           throw new Error(`invalid type ${type}`);\n       }\n      return new SqliteStorage<T>(config);\n    }\n}","import { Storable, Database, DatabaseOptions, VectorStore } from './types';\nimport { Storage, StorageFactory } from './storage';\nimport { VectorStoreFactory } from './vectorstore';\nimport { IndexedDBStorageFactory } from './implementation/indexeddb';\nimport { SqliteStorageFactory } from './implementation/sqlite';\n\n// placeholder for vectorstore factories\nconst vectorStoreFactories: Record<string, VectorStoreFactory> = {\n\n}\n\n// register storage factories here\nconst storageFactories: Record<string, StorageFactory<any>> = {\n    'indexeddb': new IndexedDBStorageFactory(),\n    'sqlite': new SqliteStorageFactory()\n};\n\n\n\nexport class DatabaseImpl<T extends Storable> implements Database<T> {\n\n  private storage!: Storage<T>;\n  private vectorStore?: VectorStore;\n\n  constructor() {\n  }\n\n  async initialize(options: DatabaseOptions) {\n    if (!storageFactories[options.type]) {\n      throw new Error(`storage type not supported ${options.type}`);\n    }\n    this.storage = await storageFactories[options.type].createStorage(options.type, options.config);\n  }\n\n  async store(data: T): Promise<void> {\n    return this.storage.store(data);\n  }\n\n  async get(id: string): Promise<T | undefined> {\n    return this.storage.get(id);\n  }\n\n  async getAll(): Promise<T[]> {\n    return this.storage.getAll();\n  }\n\n  async update(data: T): Promise<void> {\n    return this.storage.update(data);\n  }\n\n  async delete(id: string): Promise<void> {\n    return this.storage.delete(id);\n  }\n\n  async clear(): Promise<void> {\n    return this.storage.clear();\n  }\n\n  close(): void {\n    if (this.storage) {\n      this.storage.close();\n    }\n  }\n\n  setVectorStore(type: string) : void {\n    if(!vectorStoreFactories[type]){\n        throw new Error(`Vector store type not supported ${type}`);\n    }\n\n    this.vectorStore = vectorStoreFactories[type].createVectorStore(type);\n  }\n\n  async addVector(id: string, vector: number[]) : Promise<void> {\n    if(!this.vectorStore){\n       throw new Error(\"Vector store not initialized\")\n    }\n    await this.vectorStore.add(id, vector);\n  }\n\n\n async searchVector(vector: number[], topK: number): Promise<string[]> {\n     if(!this.vectorStore){\n        throw new Error(\"Vector store not initialized\")\n     }\n    return await this.vectorStore.search(vector, topK);\n  }\n}","export class HTMLCleaner {\n    private tagsToRemove: string[];\n    private attributesToRemove: string[];\n\n    /**\n     * Creates an instance of HTMLCleaner.\n     * @param {string[]} [tagsToRemove] - Array of HTML tags to remove from the content\n     * @param {string[]} [attributesToRemove] - Array of HTML attributes to remove from remaining elements\n     */\n    constructor(tagsToRemove?: string[], attributesToRemove?: string[]) {\n        this.tagsToRemove = tagsToRemove || ['script', 'style', 'noscript', 'svg', 'canvas', 'iframe', 'video', 'audio', 'img', 'nav', 'aside', 'footer', 'header'];\n        this.attributesToRemove = attributesToRemove || ['onclick', 'onload', 'onerror', 'onmouseover', 'onmouseout'];\n        \n        // Apply deduplication to all methods\n        this.applyDeduplicationToAllMethods();\n    }\n\n    /**\n     * Cleans HTML content by removing specified tags and attributes, returning only text content.\n     * @param {string} html - The HTML content to clean\n     * @returns {string} Cleaned text content with excess whitespace removed\n     */\n    clean(html: string): string {\n        let tempElement = document.createElement('div');\n        tempElement.innerHTML = html;\n\n        this.tagsToRemove.forEach(tag => {\n            let elements = tempElement.querySelectorAll(tag);\n            elements.forEach(el => el.remove());\n        });\n\n        const allElements = tempElement.querySelectorAll('*');\n        allElements.forEach(el => {\n            this.attributesToRemove.forEach(attr => el.removeAttribute(attr));\n        });\n\n        let textContent = tempElement.textContent || \"\";\n        textContent = textContent.replace(/\\s+/g, ' ').trim();\n        return this.deduplicateFinalOutput(textContent);\n    }\n\n    /**\n     * Extracts text content from semantically important HTML elements.\n     * @param {string} html - The HTML content to process\n     * @returns {string} Concatenated text content from semantic elements with line breaks\n     */\n    cleanSemantic(html: string): string {\n        let tempElement = document.createElement('div');\n        tempElement.innerHTML = html;\n        let importantText = \"\";\n        const importantTags = ['article', 'main', 'section', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'blockquote', 'code', 'pre', 'em', 'strong', 'a'];\n        importantTags.forEach(tag => {\n            let elements = tempElement.querySelectorAll(tag);\n            elements.forEach(el => {\n                importantText += (el.textContent || \"\") + \"\\n\\n\";\n            });\n        });\n        importantText = importantText.replace(/\\s+/g, ' ').trim();\n        return this.deduplicateFinalOutput(importantText);\n    }\n\n    /**\n     * Extracts information about interactive elements from HTML content.\n     * @param {string} html - The HTML content to process\n     * @returns {string} Formatted string containing information about interactive elements\n     */\n    cleanForInteractive(html: string): string {\n        let tempElement = document.createElement('div');\n        tempElement.innerHTML = html;\n        \n        const interactiveElements = new Set([\n            'a', 'button', 'input', 'select', 'textarea',\n            'details', 'menu', 'menuitem'\n        ]);\n\n        const interactiveRoles = new Set([\n            'button', 'link', 'checkbox', 'radio',\n            'tab', 'menuitem', 'option', 'switch'\n        ]);\n\n        let interactiveContent = \"\";\n        \n        const processElement = (element: Element) => {\n            const tagName = element.tagName.toLowerCase();\n            const role = element.getAttribute('role');\n            \n            if (interactiveElements.has(tagName) || \n                (role && interactiveRoles.has(role))) {\n                // Special handling for input elements\n                if (tagName === 'input') {\n                    const value = (element as HTMLInputElement).value;\n                    interactiveContent += `[${tagName}] ${value}\\n`;\n                } else {\n                    interactiveContent += `[${tagName}] ${element.textContent}\\n`;\n                }\n            }\n        };\n\n        tempElement.querySelectorAll('*').forEach(processElement);\n        return this.deduplicateFinalOutput(interactiveContent.trim());\n    }\n\n    /**\n     * Preserves the hierarchical structure of HTML content, focusing on headings and paragraphs.\n     * @param {string} html - The HTML content to process\n     * @returns {string} Indented text representation of the document's semantic structure\n     */\n    preserveSemanticHierarchy(html: string): string {\n        let tempElement = document.createElement('div');\n        tempElement.innerHTML = html;\n\n        const headingLevels = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];\n        let structuredContent = \"\";\n        \n        const processNode = (element: Element, depth: number = 0) => {\n            const tagName = element.tagName.toLowerCase();\n            const indent = '  '.repeat(depth);\n            \n            if (headingLevels.includes(tagName)) {\n                structuredContent += `${indent}${tagName}: ${element.textContent}\\n`;\n            } else if (tagName === 'p' || tagName === 'article') {\n                structuredContent += `${indent}${element.textContent}\\n`;\n            }\n            \n            Array.from(element.children).forEach(child => processNode(child, depth + 1));\n        };\n\n        processNode(tempElement);\n        return this.deduplicateFinalOutput(structuredContent.trim());\n    }\n\n    /**\n     * Deduplicates the final output to remove repeated paragraphs and sections\n     * @param {string} text - The text to deduplicate\n     * @returns {string} Deduplicated text\n     */\n    private deduplicateFinalOutput(text: string): string {\n        // Split text into paragraphs\n        const paragraphs = text.split(/\\n{2,}|\\r\\n{2,}/);\n        const uniqueParagraphs: string[] = [];\n        const seenParagraphs = new Set<string>();\n        \n        // Process each paragraph\n        for (const paragraph of paragraphs) {\n            const trimmed = paragraph.trim();\n            \n            // Skip empty paragraphs\n            if (!trimmed) continue;\n            \n            // Skip if we've seen this exact paragraph before\n            if (seenParagraphs.has(trimmed)) continue;\n            \n            // Check for near-duplicate paragraphs (>80% similarity)\n            let isDuplicate = false;\n            for (const existing of seenParagraphs) {\n                if (this.calculateSimilarity(trimmed, existing) > 0.8) {\n                    isDuplicate = true;\n                    break;\n                }\n            }\n            \n            if (!isDuplicate) {\n                uniqueParagraphs.push(trimmed);\n                seenParagraphs.add(trimmed);\n            }\n        }\n        \n        // Join unique paragraphs back together\n        return uniqueParagraphs.join('\\n\\n');\n    }\n\n    /**\n     * Calculates similarity between two strings (0-1 scale)\n     * @private\n     * @param {string} str1 - First string to compare\n     * @param {string} str2 - Second string to compare\n     * @returns {number} Similarity score between 0 and 1\n     */\n    private calculateSimilarity(str1: string, str2: string): number {\n        // If either string is empty, return 0\n        if (!str1.length || !str2.length) return 0;\n        \n        // If strings are identical, return 1\n        if (str1 === str2) return 1;\n        \n        // If one string contains the other, return a high similarity\n        if (str1.includes(str2) || str2.includes(str1)) {\n            return 0.9;\n        }\n        \n        // Calculate Levenshtein distance\n        const len1 = str1.length;\n        const len2 = str2.length;\n        \n        // Use a simplified approach for long strings to avoid performance issues\n        if (len1 > 100 || len2 > 100) {\n            // Compare first 50 chars, middle 50 chars, and last 50 chars\n            const compareStart = this.calculateLevenshteinSimilarity(\n                str1.substring(0, 50), \n                str2.substring(0, 50)\n            );\n            \n            const mid1Start = Math.max(0, Math.floor(len1 / 2) - 25);\n            const mid2Start = Math.max(0, Math.floor(len2 / 2) - 25);\n            const compareMiddle = this.calculateLevenshteinSimilarity(\n                str1.substring(mid1Start, mid1Start + 50), \n                str2.substring(mid2Start, mid2Start + 50)\n            );\n            \n            const compareEnd = this.calculateLevenshteinSimilarity(\n                str1.substring(Math.max(0, len1 - 50)), \n                str2.substring(Math.max(0, len2 - 50))\n            );\n            \n            // Average the three similarity scores\n            return (compareStart + compareMiddle + compareEnd) / 3;\n        }\n        \n        // For shorter strings, calculate full Levenshtein similarity\n        return this.calculateLevenshteinSimilarity(str1, str2);\n    }\n\n    /**\n     * Calculates Levenshtein similarity between two strings\n     * @private\n     * @param {string} str1 - First string to compare\n     * @param {string} str2 - Second string to compare\n     * @returns {number} Similarity score between 0 and 1\n     */\n    private calculateLevenshteinSimilarity(str1: string, str2: string): number {\n        const len1 = str1.length;\n        const len2 = str2.length;\n        \n        // Create a matrix of size (len1+1) x (len2+1)\n        const matrix: number[][] = Array(len1 + 1).fill(null).map(() => Array(len2 + 1).fill(0));\n        \n        // Initialize the first row and column\n        for (let i = 0; i <= len1; i++) {\n            matrix[i][0] = i;\n        }\n        \n        for (let j = 0; j <= len2; j++) {\n            matrix[0][j] = j;\n        }\n        \n        // Fill the matrix\n        for (let i = 1; i <= len1; i++) {\n            for (let j = 1; j <= len2; j++) {\n                const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;\n                matrix[i][j] = Math.min(\n                    matrix[i - 1][j] + 1,      // deletion\n                    matrix[i][j - 1] + 1,      // insertion\n                    matrix[i - 1][j - 1] + cost // substitution\n                );\n            }\n        }\n        \n        // Calculate similarity as 1 - (distance / max length)\n        const distance = matrix[len1][len2];\n        const maxLength = Math.max(len1, len2);\n        return 1 - (distance / maxLength);\n    }\n\n    /**\n     * Applies deduplication to all cleaning methods\n     */\n    private applyDeduplicationToAllMethods(): void {\n        // Store original methods\n        const originalClean = this.clean;\n        const originalCleanSemantic = this.cleanSemantic;\n        const originalCleanForInteractive = this.cleanForInteractive;\n        const originalPreserveSemanticHierarchy = this.preserveSemanticHierarchy;\n        \n        // Override methods to apply deduplication\n        this.clean = (html: string): string => {\n            return this.deduplicateFinalOutput(originalClean.call(this, html));\n        };\n        \n        this.cleanSemantic = (html: string): string => {\n            return this.deduplicateFinalOutput(originalCleanSemantic.call(this, html));\n        };\n        \n        this.cleanForInteractive = (html: string): string => {\n            return this.deduplicateFinalOutput(originalCleanForInteractive.call(this, html));\n        };\n        \n        this.preserveSemanticHierarchy = (html: string): string => {\n            return this.deduplicateFinalOutput(originalPreserveSemanticHierarchy.call(this, html));\n        };\n\n    }\n\n    /**\n     * Creates a structured representation of HTML with element IDs for easy reference,\n     * optimized to reduce noise and focus on meaningful content.\n     * @param {string} html - The HTML content to process\n     * @param {Object} options - Configuration options\n     * @param {boolean} [options.includeCodeBlocks=false] - Whether to include code blocks in the output\n     * @param {boolean} [options.includeScripts=false] - Whether to include script content in the output\n     * @returns {Object} Object containing the structured content, element mapping, and reference mapping\n     */\n    cleanWithElementIDs(html: string, options: {\n        includeCodeBlocks?: boolean,\n        includeScripts?: boolean // Note: script tags are removed by default unless includeScripts=true\n    } = {}): {\n        content: string,\n        elements: Record<string, { type: string, text: string, attributes?: Record<string, string> }>,\n        references: Record<string, string | { href?: string, class?: string, selector?: string }>\n    } {\n        const includeCodeBlocks = options.includeCodeBlocks || false;\n        const includeScripts = options.includeScripts || false;\n\n        let tempElement = document.createElement('div');\n        // Use DOMParser for potentially more robust parsing, though innerHTML is often fine\n        // const parser = new DOMParser();\n        // const doc = parser.parseFromString(html, 'text/html');\n        // tempElement = doc.body; // Or work directly with doc.body\n        tempElement.innerHTML = html; // Sticking with innerHTML for simplicity matching original code\n\n        // --- Initial Cleaning ---\n\n        // 1. Remove unwanted elements BEFORE processing\n        this.tagsToRemove.forEach(tag => {\n            // Only remove if not explicitly included (like scripts)\n            if (tag === 'script' && includeScripts) return;\n            // Don't remove interactive elements we want to process\n            if (['a', 'button', 'input', 'select', 'textarea'].includes(tag)) return;\n\n            let elements = tempElement.querySelectorAll(tag);\n            elements.forEach(el => el.remove());\n        });\n\n        // 2. Clean attributes except important ones\n        const allowedAttributes = ['href', 'type', 'value', 'placeholder', 'name', 'checked', 'selected', 'class', 'id', 'for', 'alt', 'title']; // Added for, alt, title\n        const allElements = tempElement.querySelectorAll('*');\n        allElements.forEach(el => {\n            Array.from(el.attributes).forEach(attr => {\n                // Allow all data-* attributes? Maybe not needed for LLM.\n                // if (!allowedAttributes.includes(attr.name) && !attr.name.startsWith('data-')) {\n                if (!allowedAttributes.includes(attr.name)) {\n                    el.removeAttribute(attr.name);\n                }\n            });\n        });\n\n        // --- Processing ---\n\n        const elements: Record<string, { type: string, text: string, attributes?: Record<string, string> }> = {};\n        const references: Record<string, string | { href?: string, class?: string, selector?: string }> = {};\n        let elementCounter = 1;\n\n        // Set to track processed text content to avoid duplicates (mainly for paragraphs/headings)\n        const processedTextContent = new Set<string>();\n\n        // Helper function to create a selector for an element\n        const createSelector = (element: Element): string => {\n            console.log(element);\n            if (!element || !element.tagName) return ''; // Guard against null/undefined elements\n            const tagName = element.tagName.toLowerCase();\n            let selector = tagName;\n\n            // Add ID if available and valid\n            if (element.id && !/\\s/.test(element.id)) { // Ensure ID doesn't contain spaces\n                selector += `#${CSS.escape(element.id)}`; // Use CSS.escape for robustness\n            }\n\n            // Add name attribute for inputs/textareas/selects if no ID/class? (optional enhancement)\n            if (['input', 'select'].includes(tagName) && element.hasAttribute('name') && !element.id && !element.className) {\n                selector += `[name=\"${CSS.escape(element.getAttribute('name') || '')}\"]`;\n            }\n\n            if (['textarea'].includes(tagName) && element.hasAttribute('name')) {\n                selector += `[name=\"${CSS.escape(element.getAttribute('name') || '')}\"]`;\n            }\n\n            // Add classes if available\n            if (element.className && typeof element.className === 'string') {\n                const classes = element.className.split(/\\s+/).filter(Boolean);\n                classes.forEach(cls => {\n                    // Check if class is reasonably valid (optional, but good practice)\n                    if (/^[a-zA-Z0-9_-]+$/.test(cls)) {\n                       selector += `.${CSS.escape(cls)}`;\n                    }\n                });\n            }\n\n            return selector;\n        };\n\n        // Recursive function to process the document\n        const processNode = (node: Node): string => {\n            // 1. Handle Text Nodes\n            if (node.nodeType === Node.TEXT_NODE) {\n                const text = node.textContent?.replace(/\\s+/g, ' ').trim(); // Normalize whitespace\n                return text ? text + ' ' : ''; // Add trailing space for concatenation\n            }\n\n            // 2. Handle Non-Element Nodes (like comments)\n            if (node.nodeType !== Node.ELEMENT_NODE) return '';\n\n            const element = node as Element;\n            const tagName = element.tagName.toLowerCase();\n\n            // 3. Skip elements completely if they are not meant for LLM context\n            // (This check might be redundant if tagsToRemove already handled it, but good safety)\n            const skipElements = ['script', 'style', 'noscript', 'svg', 'canvas', 'iframe']; // Ensure consistency\n             if (skipElements.includes(tagName) && !(tagName === 'script' && includeScripts)) {\n                 return '';\n             }\n\n            let elementId = '';\n            let elementOutputPrefix = '';\n            let elementOutputSuffix = '';\n            let elementContent = '';\n            let processChildren = true; // Flag to control whether to process child nodes\n\n            // --- Handle Specific Element Types ---\n\n            // Headings\n             if (/^h[1-6]$/.test(tagName)) {\n                const level = parseInt(tagName.substring(1));\n                const prefix = '#'.repeat(level);\n                const text = element.textContent?.trim();\n                if (text && !processedTextContent.has(text)) {\n                    elementId = `${tagName}_${elementCounter++}`;\n                    elements[elementId] = { type: tagName, text: text };\n                    references[elementId] = { selector: createSelector(element), class: element.getAttribute('class') || undefined };\n                    processedTextContent.add(text);\n\n                    // Output format: ## Heading Text [h2_1]\n                    elementOutputPrefix = `${prefix} ${text} `;\n                    elementOutputSuffix = `[${elementId}]\\n\\n`; // Add ID and block spacing\n                    processChildren = false; // Don't process children again, textContent was enough\n                } else {\n                     return ''; // Skip duplicate or empty heading\n                 }\n            }\n            // Links\n            else if (tagName === 'a' && element.hasAttribute('href')) {\n                const text = element.textContent?.trim();\n                const href = element.getAttribute('href') || '';\n\n                // Avoid processing mailto: or javascript: links unless text is significant?\n                // if (href.startsWith('mailto:') || href.startsWith('javascript:')) return '';\n\n                // Process if text is meaningful\n                if (text && text.length > 1) {\n                    // Use combined text+href for uniqueness check if needed, but often text is enough\n                    const uniqueKey = `link:${text}|${href}`;\n                    if (!processedTextContent.has(uniqueKey)) {\n                         elementId = `link_${elementCounter++}`;\n                         const attributes: Record<string, string> = { href: href };\n                         elements[elementId] = { type: 'link', text: text, attributes: attributes };\n                         references[elementId] = { href: href, selector: createSelector(element), class: element.getAttribute('class') || undefined };\n                         processedTextContent.add(uniqueKey);\n\n                         // Output format: Link Text [link_1]\n                         elementOutputPrefix = text; // Get text from children processing instead? Better for nested tags in links.\n                         elementOutputSuffix = ` [${elementId}] `;\n                         // Let children be processed to capture nested formatting (like strong tags)\n                    } else {\n                        // If duplicate link text/href, maybe just output text without ID?\n                        elementOutputPrefix = text + ' ';\n                        processChildren = false; // Avoid reprocessing children if skipping ID\n                    }\n\n                } else {\n                    // Link without meaningful text, maybe skip or just process children?\n                    // return ''; // Option 1: Skip entirely\n                    processChildren = true; // Option 2: Process children within the link tag\n                }\n            }\n            // Buttons\n            else if (tagName === 'button') {\n                const text = element.textContent?.trim() || element.getAttribute('aria-label') || element.getAttribute('title');\n\n                if (text && text.length > 0) {\n                    const uniqueKey = `button:${text}`;\n                    // Allow duplicate button text if needed, maybe use selector for uniqueness?\n                    // const uniqueKey = createSelector(element);\n                    if (!processedTextContent.has(uniqueKey)) {\n                         elementId = `btn_${elementCounter++}`;\n                         const attributes: Record<string, string> = {};\n                         const type = element.getAttribute('type');\n                         const name = element.getAttribute('name');\n                         const value = element.getAttribute('value');\n                         const class_val = element.getAttribute('class'); // Use consistent naming\n\n                         if (type) attributes.type = type;\n                         if (name) attributes.name = name;\n                         if (value) attributes.value = value;\n                         if (class_val) attributes.class = class_val;\n\n                         elements[elementId] = {\n                            type: 'button',\n                            text: text,\n                            attributes: Object.keys(attributes).length > 0 ? attributes : undefined\n                        };\n                         references[elementId] = { selector: createSelector(element), class: element.getAttribute('class') || undefined };\n                         // processedTextContent.add(uniqueKey); // Add if strict button deduplication is needed\n\n                         // Output format: [Button: Button Text] [btn_1]\n                         elementOutputPrefix = `[Button: ${text}]`;\n                         elementOutputSuffix = ` [${elementId}] `;\n                         processChildren = false; // Button textContent is usually sufficient\n                    } else {\n                        return ''; // Skip duplicate button\n                    }\n                } else {\n                    return ''; // Skip button without text\n                }\n            }\n            // Inputs\n            else if (tagName === 'input') {\n                const type = element.getAttribute('type') || 'text';\n                // Skip hidden inputs unless specifically needed\n                if (type === 'hidden') return '';\n\n                const value = (element as HTMLInputElement).value;\n                const placeholder = element.getAttribute('placeholder');\n                const name = element.getAttribute('name');\n                const checked = (element as HTMLInputElement).checked;\n                const labelText = findLabelText(element); // Helper to find associated label\n\n                const idText = labelText || placeholder || name || type; // Best text descriptor\n\n                elementId = `input_${elementCounter++}`;\n                const attributes: Record<string, string> = { type };\n                if (value && type !== 'password') attributes.value = value; // Don't expose password values\n                if (placeholder) attributes.placeholder = placeholder;\n                if (name) attributes.name = name;\n                if (checked) attributes.checked = 'true';\n                if (labelText) attributes.label = labelText; // Add associated label text\n                 if (element.getAttribute('class')) attributes.class = element.getAttribute('class')!;\n\n                elements[elementId] = {\n                    type: 'input',\n                    text: idText,\n                    attributes\n                };\n                references[elementId] = { selector: createSelector(element), class: element.getAttribute('class') || undefined };\n\n                // Output format: [text input label=\"Label\" placeholder=\"Placeholder\"] [input_1]\n                let displayText = `[${type} input`;\n                 if (labelText) displayText += ` label=\"${labelText}\"`;\n                 else if (placeholder) displayText += ` placeholder=\"${placeholder}\"`;\n                 else if (name) displayText += ` name=\"${name}\"`;\n                 // Only show value for specific types maybe? (e.g., not password)\n                 // if (value && type !== 'password') displayText += ` value=\"${value}\"`;\n                 if (checked) displayText += ` (checked)`;\n                displayText += `]`;\n\n                elementOutputPrefix = displayText;\n                elementOutputSuffix = ` [${elementId}] `;\n                processChildren = false; // Inputs don't have meaningful children for content\n            }\n            // Select (Dropdowns)\n            else if (tagName === 'select') {\n                const name = element.getAttribute('name');\n                const labelText = findLabelText(element);\n                const idText = labelText || name || 'dropdown';\n\n                interface OptionData {\n                    value: string;\n                    text: string;\n                    selected?: boolean;\n                }\n\n                const options: OptionData[] = Array.from(element.querySelectorAll('option')).map(opt => {\n                    const optData: OptionData = {\n                        value: opt.getAttribute('value') || opt.textContent || '',\n                        text: opt.textContent || ''\n                    };\n                    if ((opt as HTMLOptionElement).selected) {\n                        optData.selected = true;\n                    }\n                    return optData;\n                });\n                const selectedOption = options.find(opt => opt.selected);\n\n                elementId = `select_${elementCounter++}`;\n                elements[elementId] = {\n                    type: 'select',\n                    text: idText,\n                    attributes: {\n                        name: name || '',\n                        options: JSON.stringify(options), // Store all options for context\n                        ...(selectedOption && {selectedValue: selectedOption.value}), // Add current value if selected\n                        ...(labelText && {label: labelText}),\n                        ...(element.getAttribute('class') && {class: element.getAttribute('class')!})\n                    }\n                };\n                references[elementId] = { selector: createSelector(element), class: element.getAttribute('class') || undefined };\n\n                // Output format: [Dropdown label=\"Label\" name=\"Name\" selected=\"Value\"] [select_1]\n                let displayText = `[Dropdown`;\n                if (labelText) displayText += ` label=\"${labelText}\"`;\n                else if (name) displayText += ` name=\"${name}\"`;\n                if (selectedOption) displayText += ` selected=\"${selectedOption.text || selectedOption.value}\"`; // Show selected text or value\n                displayText += `]`;\n\n                elementOutputPrefix = displayText;\n                elementOutputSuffix = ` [${elementId}] `;\n                processChildren = false; // Options are handled above\n            }\n            // ** Textareas **\n            else if (tagName === 'textarea') {\n                // const value = (element as HTMLTextAreaElement)?.value; // Current value\n                const placeholder = element.getAttribute('placeholder');\n                const name = element.getAttribute('name');\n                 const labelText = findLabelText(element);\n                 const idText = labelText || placeholder || name || 'text area';\n\n                elementId = `textarea_${elementCounter++}`;\n                const attributes: Record<string, string> = {};\n                // Include value? Might be too verbose for LLM, depends on use case.\n                // if (value) attributes.value = value;\n                if (placeholder) attributes.placeholder = placeholder;\n                if (name) attributes.name = name;\n                if (labelText) attributes.label = labelText;\n                 if (element.getAttribute('class')) attributes.class = element.getAttribute('class')!;\n\n                elements[elementId] = {\n                    type: 'textarea',\n                    text: idText, // Use label/placeholder/name for identification text\n                    attributes\n                };\n                references[elementId] = { selector: createSelector(element), class: element.getAttribute('class') || undefined };\n\n                // Output format: [Textarea label=\"Label\" placeholder=\"Placeholder\"] [textarea_1]\n                let displayText = `[Textarea`; // Changed from \"Text area\" for consistency\n                 if (labelText) displayText += ` label=\"${labelText}\"`;\n                 else if (placeholder) displayText += ` placeholder=\"${placeholder}\"`;\n                 else if (name) displayText += ` name=\"${name}\"`;\n                // if (value) displayText += ` value=\"${value}\"`; // Optional: include current value\n                displayText += `]`;\n\n                elementOutputPrefix = displayText;\n                elementOutputSuffix = ` [${elementId}] `;\n                processChildren = false; // textContent/value is the primary info\n            }\n            // Paragraphs\n             else if (tagName === 'p') {\n                // Process children, add paragraph breaks\n                elementContent = Array.from(element.childNodes).map(processNode).join('');\n                const trimmedContent = elementContent.trim();\n                if (trimmedContent && trimmedContent.length > 10 && !processedTextContent.has(trimmedContent)) { // Add length check and deduplication\n                     // Optionally add ID for long/unique paragraphs\n                     // elementId = `p_${elementCounter++}`;\n                     // elements[elementId] = { type: 'paragraph', text: element.textContent?.trim() || '' };\n                     // references[elementId] = { selector: createSelector(element), class: element.getAttribute('class') || undefined };\n                     // elementOutputSuffix = ` [${elementId}]`;\n                     processedTextContent.add(trimmedContent);\n                     return `${trimmedContent}\\n\\n`; // Add paragraph break\n                 } else if (trimmedContent) {\n                     return `${trimmedContent}\\n\\n`; // Still add breaks for shorter paragraphs if not empty\n                 } else {\n                     return ''; // Skip empty paragraphs\n                 }\n            }\n            // List Items\n             else if (tagName === 'li') {\n                // Process children, add list marker\n                elementContent = Array.from(element.childNodes).map(processNode).join('');\n                 const trimmedContent = elementContent.trim();\n                 if (trimmedContent) {\n                     // Optionally add ID\n                     // elementId = `li_${elementCounter++}`;\n                     // elements[elementId] = { type: 'list-item', text: element.textContent?.trim() || '' };\n                     // references[elementId] = { selector: createSelector(element), class: element.getAttribute('class') || undefined };\n                     // elementOutputSuffix = ` [${elementId}]`;\n                     return `• ${trimmedContent}\\n`; // Add bullet and newline\n                 } else {\n                     return ''; // Skip empty list items\n                 }\n            }\n             // Unordered/Ordered Lists\n             else if (tagName === 'ul' || tagName === 'ol') {\n                 elementContent = Array.from(element.childNodes).map(processNode).join('');\n                 // Add extra newline after the list for spacing\n                 return elementContent.trim() ? `${elementContent.trim()}\\n\\n` : '';\n             }\n            // Code Blocks (PRE/CODE)\n             else if (tagName === 'pre' || tagName === 'code') {\n                if (includeCodeBlocks) {\n                     elementId = `${tagName}_${elementCounter++}`;\n                     const text = element.textContent || ''; // Get raw text content\n                     elements[elementId] = { type: tagName, text: text.trim() };\n                     references[elementId] = { selector: createSelector(element), class: element.getAttribute('class') || undefined };\n\n                     // Output format: ```language\\n code \\n``` [code_1]\n                     const langClass = element.className.match(/language-(\\w+)/);\n                     const lang = langClass ? langClass[1] : '';\n                     elementOutputPrefix = `\\`\\`\\`${lang}\\n${text.trim()}\\n\\`\\`\\``;\n                     elementOutputSuffix = ` [${elementId}]\\n\\n`;\n                     processChildren = false; // Don't process children of code blocks\n                 } else {\n                     return '[Code Block]\\n\\n'; // Placeholder if not including content\n                 }\n            }\n             // Labels (often contain text for inputs) - process their content\n             else if (tagName === 'label') {\n                 // Process children normally, the text will be picked up by findLabelText if needed\n                 processChildren = true;\n             }\n            // Images\n             else if (tagName === 'img') {\n                 const alt = element.getAttribute('alt')?.trim();\n                 const src = element.getAttribute('src');\n                 if (alt) {\n                     elementId = `img_${elementCounter++}`;\n                     elements[elementId] = { type: 'image', text: alt, attributes: { alt: alt, ...(src && {src: src}) } };\n                     references[elementId] = { selector: createSelector(element), class: element.getAttribute('class') || undefined };\n                     elementOutputPrefix = `[Image: ${alt}]`;\n                     elementOutputSuffix = ` [${elementId}] `;\n                 }\n                 // Maybe return empty string if no alt text? Or a placeholder?\n                 // else { return '[Image] '; }\n                 processChildren = false; // Images don't have children\n             }\n\n            // --- Default Handling for Other Elements (div, span, etc.) ---\n            if (processChildren) {\n                elementContent = Array.from(element.childNodes).map(processNode).join('');\n            }\n\n            // Add prefix/suffix if an ID was generated for this element\n            return `${elementOutputPrefix}${elementContent}${elementOutputSuffix}`;\n        };\n\n        // Helper function to find text associated with an input/textarea/select\n        const findLabelText = (element: Element): string | null => {\n            // 1. Check for aria-label or aria-labelledby\n             const ariaLabel = element.getAttribute('aria-label');\n             if (ariaLabel) return ariaLabel;\n             const ariaLabelledBy = element.getAttribute('aria-labelledby');\n             if (ariaLabelledBy) {\n                 const labelElement = tempElement.querySelector(`#${CSS.escape(ariaLabelledBy)}`);\n                 if (labelElement) return labelElement.textContent?.trim() || null;\n             }\n\n            // 2. Look for a <label> element pointing to this element's ID\n            if (element.id) {\n                const label = tempElement.querySelector(`label[for=\"${CSS.escape(element.id)}\"]`);\n                if (label) {\n                    return label.textContent?.trim() || null;\n                }\n            }\n\n            // 3. Look for a <label> element wrapping this element\n            const parentLabel = element.closest('label');\n            if (parentLabel) {\n                // Get text content of the label, excluding the input/select/textarea itself\n                let labelText = '';\n                 Array.from(parentLabel.childNodes).forEach(child => {\n                     if (child !== element) {\n                         labelText += child.textContent || '';\n                     }\n                 });\n                 return labelText.trim() || null;\n             }\n\n             // 4. Check for a sibling label immediately before (common pattern without 'for')\n             let prevSibling = element.previousElementSibling;\n             while(prevSibling && prevSibling.nodeType !== Node.ELEMENT_NODE) {\n                 prevSibling = prevSibling.previousElementSibling;\n             }\n             if (prevSibling && prevSibling.tagName.toLowerCase() === 'label') {\n                 return prevSibling.textContent?.trim() || null;\n             }\n\n             // 5. Look within common parent structure like <div class=\"q\"> <label>...</label> <input/> </div>\n             const commonParent = element.closest('.q, .form-group, .input-group'); // Add common form group classes\n             if (commonParent) {\n                 const label = commonParent.querySelector('label');\n                 if (label && !label.hasAttribute('for')) { // If label doesn't have 'for', assume it's for this input\n                     return label.textContent?.trim() || null;\n                 }\n             }\n\n\n            return null; // No label found\n        };\n\n\n        // Start processing from the body or the root temp element\n        const body = tempElement.querySelector('body') || tempElement;\n        let content = processNode(body);\n\n        // --- Final Cleanup ---\n        content = content\n            .replace(/\\s+\\n/g, '\\n')      // Remove spaces before newlines\n            .replace(/\\n\\s+/g, '\\n')      // Remove spaces after newlines (start of line)\n            .replace(/\\n{3,}/g, '\\n\\n')   // Normalize multiple newlines to max two\n            .replace(/[ \\t]{2,}/g, ' ')     // Replace multiple spaces/tabs with a single space\n            .replace(/^ +/gm, '')        // Remove leading spaces on each line\n            .trim();                       // Trim leading/trailing whitespace from the whole string\n\n        // Optional: Apply final deduplication if needed (can be aggressive)\n        // content = this.deduplicateFinalOutput(content);\n\n        // Optional: Further clean up potentially redundant/nested IDs if they cause issues\n        // This might remove valid nested IDs, use with caution\n        // content = content.replace(/(\\[[a-z]+_\\d+\\])\\s*(\\[[a-z]+_\\d+\\])/g, '$2'); // Keep only the inner ID if nested\n        // content = content.replace(/\\n\\s*\\[\\w+_\\d+\\]\\s*\\n/g, '\\n');   // Remove element IDs on their own lines\n\n        return { content, elements, references };\n    }\n}","export function identifyMainContent(cleanedText: string): string {\n    // Split text into paragraphs\n    const paragraphs = cleanedText.split('\\n\\n').filter(p => p.trim());\n    \n    if (paragraphs.length === 0) return cleanedText;\n\n    // Use heuristics to identify main content\n    const mainParagraphs = paragraphs.filter(p => {\n        const words = p.split(/\\s+/).length;\n        return words > 20 && words < 1000; // Reasonable paragraph length\n    });\n\n    return mainParagraphs.length > 0 ? mainParagraphs.join('\\n\\n') : cleanedText;\n}\n\n// TODO: Implement these additional content identification functions\n/*\n- Add semantic structure analysis\n- Add relevance scoring\n- Add content classification\n- Add language detection\n- Add summary generation\n*/\n\nexport interface ContentClassification {\n    type: 'article' | 'product' | 'form' | 'navigation' | 'other';\n    confidence: number;\n    keywords: string[];\n    entities: string[];\n}\n\nexport function classifyContent(content: string): ContentClassification {\n    const words = content.toLowerCase().split(/\\s+/);\n    const wordFreq = new Map<string, number>();\n    \n    // Calculate word frequencies\n    words.forEach(word => {\n        if (word.length > 3) { // Skip short words\n            wordFreq.set(word, (wordFreq.get(word) || 0) + 1);\n        }\n    });\n\n    // Extract keywords (words with high frequency)\n    const keywords = Array.from(wordFreq.entries())\n        .sort((a, b) => b[1] - a[1])\n        .slice(0, 10)\n        .map(([word]) => word);\n\n    // Simple classification based on content patterns\n    const classification = determineContentType(keywords);\n\n    return {\n        ...classification,\n        keywords,\n        entities: extractEntities(content)\n    };\n}\n\nfunction determineContentType(keywords: string[]): Pick<ContentClassification, 'type' | 'confidence'> {\n    const patterns = {\n        article: ['article', 'post', 'blog', 'news', 'story'],\n        product: ['price', 'buy', 'cart', 'shop', 'product'],\n        form: ['submit', 'input', 'form', 'select', 'checkbox'],\n        navigation: ['menu', 'nav', 'link', 'home', 'page']\n    };\n\n    const scores = Object.entries(patterns).map(([type, patterns]) => {\n        const score = patterns.reduce((acc, pattern) => {\n            return acc + (keywords.includes(pattern) ? 1 : 0);\n        }, 0) / patterns.length;\n        return { type, score };\n    });\n\n    const bestMatch = scores.reduce((a, b) => a.score > b.score ? a : b);\n    \n    return {\n        type: bestMatch.score > 0.3 ? bestMatch.type as ContentClassification['type'] : 'other',\n        confidence: bestMatch.score\n    };\n}\n\nfunction extractEntities(content: string): string[] {\n    // Simple named entity recognition\n    const entities: string[] = [];\n    \n    // Find potential proper nouns (words starting with capital letters)\n    const words = content.split(/\\s+/);\n    let currentEntity = '';\n    \n    words.forEach(word => {\n        if (/^[A-Z][a-zA-Z]*$/.test(word)) {\n            currentEntity += currentEntity ? ` ${word}` : word;\n        } else {\n            if (currentEntity) {\n                entities.push(currentEntity);\n                currentEntity = '';\n            }\n        }\n    });\n\n    // Remove duplicates and return\n    return [...new Set(entities)];\n}\n\nexport interface ContentSection {\n    type: 'header' | 'profile' | 'main' | 'navigation' | 'interaction' | 'metadata' | 'other';\n    elements: Element[];\n    content: string;\n    relevanceScore?: number;\n    confidence: number;\n}\n\nexport interface SectionAnalysis {\n    sections: ContentSection[];\n    summary: string;\n    recommendedSections: ContentSection[];\n}\n\n// Add new platform-specific patterns\nexport interface PlatformPatterns {\n    selectors: string[];\n    classPatterns: RegExp[];\n    contentRules: {\n        type: ContentSection['type'];\n        patterns: string[];\n    }[];\n}\n\nconst PLATFORM_PATTERNS: Record<string, PlatformPatterns> = {\n    linkedin: {\n        selectors: [\n            '[data-test-id]',\n            '.profile-section',\n            '.feed-shared-update-v2',\n            '.scaffold-layout__main'\n        ],\n        classPatterns: [\n            /artdeco-card/,\n            /profile-/,\n            /feed-shared/,\n            /scaffold-layout/\n        ],\n        contentRules: [\n            {\n                type: 'profile',\n                patterns: ['connections', 'followers', 'experience', 'education', 'skills']\n            },\n            {\n                type: 'interaction',\n                patterns: ['connect', 'follow', 'message', 'react', 'comment', 'share']\n            }\n        ]\n    },\n    twitter: {\n        selectors: [\n            '[data-testid]',\n            '.tweet',\n            '.profile-timeline',\n            '[role=\"article\"]'\n        ],\n        classPatterns: [\n            /css-\\d+/,\n            /tweet-/,\n            /timeline-/\n        ],\n        contentRules: [\n            {\n                type: 'profile',\n                patterns: ['followers', 'following', 'joined', 'tweets']\n            },\n            {\n                type: 'interaction',\n                patterns: ['reply', 'retweet', 'like', 'share', 'bookmark']\n            }\n        ]\n    },\n    // Generic patterns for any website\n    generic: {\n        selectors: [\n            'main',\n            'header',\n            'nav',\n            'article',\n            'aside',\n            'section',\n            '[role=\"main\"]',\n            '[role=\"navigation\"]',\n            '[role=\"complementary\"]'\n        ],\n        classPatterns: [\n            /main/i,\n            /header/i,\n            /content/i,\n            /navigation/i\n        ],\n        contentRules: [\n            {\n                type: 'main',\n                patterns: ['article', 'post', 'content', 'story']\n            },\n            {\n                type: 'navigation',\n                patterns: ['menu', 'nav', 'links', 'sidebar']\n            }\n        ]\n    }\n};\n\nexport class ContentSectionAnalyzer {\n    private platform: string = 'generic';\n    private patterns: PlatformPatterns;\n\n    constructor() {\n        // Start with generic patterns\n        this.patterns = PLATFORM_PATTERNS.generic;\n    }\n\n    /**\n     * Detect the platform and set appropriate patterns\n     */\n    private detectPlatform(): void {\n        const url = window.location.hostname;\n        \n        if (url.includes('linkedin')) {\n            this.platform = 'linkedin';\n        } else if (url.includes('twitter')) {\n            this.platform = 'twitter';\n        } else {\n            this.platform = 'generic';\n        }\n        \n        this.patterns = {\n            ...PLATFORM_PATTERNS.generic,\n            ...PLATFORM_PATTERNS[this.platform]\n        };\n    }\n\n    analyzeSections(rootElement: Element, task?: string): SectionAnalysis {\n        // Detect platform first\n        this.detectPlatform();\n        \n        // Step 1: Initial section grouping\n        const sections = this.groupIntoSections(rootElement);\n        \n        // Step 2: Analyze and score sections\n        const analyzedSections = this.analyzeSectionRelevance(sections, task);\n        \n        // Step 3: Generate summary and recommendations\n        return {\n            sections: analyzedSections,\n            summary: this.generateSectionSummary(analyzedSections),\n            recommendedSections: this.getRecommendedSections(analyzedSections)\n        };\n    }\n\n    private groupIntoSections(rootElement: Element): ContentSection[] {\n        const sections: ContentSection[] = [];\n        \n        // Helper to determine if elements are related\n        const areElementsRelated = (el1: Element, el2: Element): boolean => {\n            // Check proximity in DOM\n            const distance = this.calculateDOMDistance(el1, el2);\n            if (distance > 3) return false;\n            \n            // Check visual proximity (if elements have position data)\n            const visuallyClose = this.areElementsVisuallyClose(el1, el2);\n            if (!visuallyClose) return false;\n            \n            // Check semantic relationship\n            return this.areElementsSemanticallyRelated(el1, el2);\n        };\n\n        // Start with landmark elements\n        const landmarks = rootElement.querySelectorAll('main, header, nav, article, aside, section');\n        landmarks.forEach(landmark => {\n            const type = this.determineSectionType(landmark);\n            sections.push({\n                type,\n                elements: [landmark],\n                content: landmark.textContent || '',\n                confidence: 0.9\n            });\n        });\n\n        // Group remaining elements\n        const ungroupedElements = Array.from(rootElement.querySelectorAll('*'))\n            .filter(el => !this.isElementInSections(el, sections));\n\n        let currentGroup: Element[] = [];\n        let currentType: ContentSection['type'] = 'other';\n\n        ungroupedElements.forEach(element => {\n            if (currentGroup.length === 0) {\n                currentGroup.push(element);\n                currentType = this.determineSectionType(element);\n            } else {\n                const lastElement = currentGroup[currentGroup.length - 1];\n                if (areElementsRelated(lastElement, element)) {\n                    currentGroup.push(element);\n                } else {\n                    // Create new section from current group\n                    sections.push({\n                        type: currentType,\n                        elements: [...currentGroup],\n                        content: currentGroup.map(el => el.textContent).join(' '),\n                        confidence: 0.7\n                    });\n                    currentGroup = [element];\n                    currentType = this.determineSectionType(element);\n                }\n            }\n        });\n\n        // Add any remaining elements\n        if (currentGroup.length > 0) {\n            sections.push({\n                type: currentType,\n                elements: currentGroup,\n                content: currentGroup.map(el => el.textContent).join(' '),\n                confidence: 0.7\n            });\n        }\n\n        return sections;\n    }\n\n    private analyzeSectionRelevance(sections: ContentSection[], task?: string): ContentSection[] {\n        return sections.map(section => {\n            const relevanceScore = this.calculateRelevanceScore(section, task);\n            return {\n                ...section,\n                relevanceScore\n            };\n        });\n    }\n\n    private calculateRelevanceScore(section: ContentSection, task?: string): number {\n        let score = 0;\n\n        // Base score from content quality\n        score += this.evaluateContentQuality(section.content);\n\n        // Adjust based on section type\n        score += this.getTypeRelevanceScore(section.type);\n\n        // If task is provided, evaluate relevance to task\n        if (task) {\n            score += this.evaluateTaskRelevance(section.content, task);\n        }\n\n        // Normalize score to 0-1 range\n        return Math.min(Math.max(score / 3, 0), 1);\n    }\n\n    private evaluateContentQuality(content: string): number {\n        let score = 0;\n        \n        // Check content length\n        const words = content.split(/\\s+/).length;\n        if (words > 10 && words < 1000) score += 0.3;\n        \n        // Check for meaningful content\n        if (!/^\\s*$/.test(content)) score += 0.2;\n        \n        // Check for structured content\n        if (content.includes('\\n')) score += 0.2;\n        \n        // Check for interactive elements\n        if (/button|link|input/i.test(content)) score += 0.3;\n        \n        return score;\n    }\n\n    private getTypeRelevanceScore(type: ContentSection['type']): number {\n        const typeScores: Record<ContentSection['type'], number> = {\n            header: 0.7,\n            profile: 0.8,\n            main: 1.0,\n            navigation: 0.4,\n            interaction: 0.6,\n            metadata: 0.3,\n            other: 0.2\n        };\n        \n        return typeScores[type];\n    }\n\n    private evaluateTaskRelevance(content: string, task: string): number {\n        // Convert content and task to lowercase for comparison\n        const normalizedContent = content.toLowerCase();\n        const normalizedTask = task.toLowerCase();\n\n        // Extract keywords from task\n        const taskKeywords = normalizedTask\n            .split(/\\s+/)\n            .filter(word => word.length > 3);\n\n        // Calculate keyword matches\n        const matchingKeywords = taskKeywords.filter(keyword => \n            normalizedContent.includes(keyword)\n        );\n\n        return matchingKeywords.length / taskKeywords.length;\n    }\n\n    private determineSectionType(element: Element): ContentSection['type'] {\n        const tagName = element.tagName.toLowerCase();\n        const role = element.getAttribute('role');\n        const className = element.className;\n        const textContent = element.textContent?.toLowerCase() || '';\n\n        // Check platform-specific patterns first\n        for (const rule of this.patterns.contentRules) {\n            if (rule.patterns.some(pattern => \n                textContent.includes(pattern) || \n                className.toLowerCase().includes(pattern)\n            )) {\n                return rule.type;\n            }\n        }\n\n        // Check for platform-specific selectors\n        if (this.patterns.selectors.some(selector => element.matches(selector))) {\n            // Determine type based on context and content\n            return this.inferTypeFromContext(element);\n        }\n\n        // Fall back to generic type detection\n        if (tagName === 'header' || /header|banner/i.test(className)) {\n            return 'header';\n        }\n        if (/profile|user-info/i.test(className)) {\n            return 'profile';\n        }\n        if (tagName === 'main' || role === 'main' || /main-content/i.test(className)) {\n            return 'main';\n        }\n        if (tagName === 'nav' || role === 'navigation') {\n            return 'navigation';\n        }\n        if (/button|form|input/i.test(tagName)) {\n            return 'interaction';\n        }\n        if (/metadata|info|details/i.test(className)) {\n            return 'metadata';\n        }\n        \n        return 'other';\n    }\n\n    private inferTypeFromContext(element: Element): ContentSection['type'] {\n        const context = {\n            hasInteractiveElements: element.querySelectorAll('button, a, input, textarea').length > 0,\n            hasImages: element.querySelectorAll('img').length > 0,\n            textLength: element.textContent?.length || 0,\n            isNearHeader: this.isNearElementType(element, 'header'),\n            isNearNav: this.isNearElementType(element, 'nav'),\n            hasStructuredData: element.querySelectorAll('ul, ol, table').length > 0\n        };\n\n        // Use context to infer section type\n        if (context.hasInteractiveElements && context.textLength < 200) {\n            return 'interaction';\n        }\n        if (context.hasImages && context.textLength > 500) {\n            return 'main';\n        }\n        if (context.hasStructuredData && context.isNearNav) {\n            return 'navigation';\n        }\n        if (context.isNearHeader && context.textLength < 300) {\n            return 'metadata';\n        }\n\n        return 'other';\n    }\n\n    private isNearElementType(element: Element, type: string): boolean {\n        const distance = 3; // Check 3 elements up and down\n        let current = element;\n        \n        // Check previous siblings\n        for (let i = 0; i < distance && current.previousElementSibling; i++) {\n            current = current.previousElementSibling;\n            if (current.tagName.toLowerCase() === type) return true;\n        }\n        \n        // Check next siblings\n        current = element;\n        for (let i = 0; i < distance && current.nextElementSibling; i++) {\n            current = current.nextElementSibling;\n            if (current.tagName.toLowerCase() === type) return true;\n        }\n        \n        return false;\n    }\n\n    private calculateDOMDistance(el1: Element, el2: Element): number {\n        const path1 = this.getPathToRoot(el1);\n        const path2 = this.getPathToRoot(el2);\n        \n        // Find common ancestor\n        let commonAncestorIndex = 0;\n        const maxLength = Math.min(path1.length, path2.length);\n        \n        while (commonAncestorIndex < maxLength && \n               path1[commonAncestorIndex] === path2[commonAncestorIndex]) {\n            commonAncestorIndex++;\n        }\n        \n        return (path1.length - commonAncestorIndex) + \n               (path2.length - commonAncestorIndex);\n    }\n\n    private getPathToRoot(element: Element): Element[] {\n        const path: Element[] = [];\n        let current: Element | null = element;\n        \n        while (current) {\n            path.unshift(current);\n            current = current.parentElement;\n        }\n        \n        return path;\n    }\n\n    private areElementsVisuallyClose(el1: Element, el2: Element): boolean {\n        const rect1 = el1.getBoundingClientRect();\n        const rect2 = el2.getBoundingClientRect();\n        \n        // Calculate distance between elements\n        const horizontalDistance = Math.abs(rect1.left - rect2.left);\n        const verticalDistance = Math.abs(rect1.top - rect2.top);\n        \n        // Consider elements close if they're within 100px of each other\n        return horizontalDistance < 100 && verticalDistance < 100;\n    }\n\n    private areElementsSemanticallyRelated(el1: Element, el2: Element): boolean {\n        // Add platform-specific class pattern checking\n        const matchesPatterns = this.patterns.classPatterns.some(pattern => {\n            const el1Match = Array.from(el1.classList).some(c => pattern.test(c));\n            const el2Match = Array.from(el2.classList).some(c => pattern.test(c));\n            return el1Match && el2Match;\n        });\n\n        if (matchesPatterns) return true;\n\n        // Fallback to existing semantic relationship checks\n        return this.areElementsSemanticallyRelated(el1, el2);\n    }\n\n    private isElementInSections(element: Element, sections: ContentSection[]): boolean {\n        return sections.some(section => \n            section.elements.some(el => el.contains(element))\n        );\n    }\n\n    private generateSectionSummary(sections: ContentSection[]): string {\n        const relevantSections = sections\n            .filter(s => (s.relevanceScore || 0) > 0.5)\n            .sort((a, b) => (b.relevanceScore || 0) - (a.relevanceScore || 0));\n\n        return relevantSections\n            .map(section => `${section.type.toUpperCase()}: ${\n                section.content.substring(0, 100)}${\n                section.content.length > 100 ? '...' : ''\n            } (Relevance: ${(section.relevanceScore || 0).toFixed(2)})`)\n            .join('\\n\\n');\n    }\n\n    private getRecommendedSections(sections: ContentSection[]): ContentSection[] {\n        return sections\n            .filter(s => (s.relevanceScore || 0) > 0.7)\n            .sort((a, b) => (b.relevanceScore || 0) - (a.relevanceScore || 0));\n    }\n}","export interface BrowserAgentAction {\n    type: 'click' | 'scroll' | 'navigate' | 'extract' | 'read' | 'wait' | \n          'think' | 'analyze' | 'classify' | 'summarize';\n    target?: string;\n    value?: any;\n    taskType?: AgentModelConfig['taskType'];\n}\n\nexport interface PageMetadata {\n    title: string;\n    url: string;\n    description: string;\n    keywords: string;\n    timestamp: string;\n}\n\nexport interface RetryConfig {\n    maxRetries: number;\n    delay: number;\n    backoffFactor: number;\n}\n\nexport class ActionError extends Error {\n    constructor(\n        public action: BrowserAgentAction,\n        message: string\n    ) {\n        super(`Failed to execute ${action.type}: ${message}`);\n        this.name = 'ActionError';\n    }\n}\n\nexport interface AgentState {\n    currentUrl: string;\n    lastAction: BrowserAgentAction | null;\n    actionHistory: BrowserAgentAction[];\n    errors: ActionError[];\n}\n\nexport interface AgentModelConfig {\n    taskType: 'navigation' | 'analysis' | 'extraction' | 'decision' | 'conversation';\n    modelId: string;\n    options?: Record<string, unknown>;\n}\n\nexport interface AgentConfig {\n    models: {\n        [key in AgentModelConfig['taskType']]?: AgentModelConfig;\n    };\n    defaultModel?: string;\n}\n","import { HTMLCleaner } from './html-cleaner';\nimport { identifyMainContent } from './content-identifier';\nimport { PageMetadata, ActionError, RetryConfig, BrowserAgentAction, AgentConfig, AgentModelConfig } from '@/core/agent/types';\nimport { BrowserAI } from '@/core/llm';\n\n// CURRENTLY WIP\n\nexport class BrowserAgent {\n    private currentUrl: string;\n    private htmlCleaner: HTMLCleaner;\n    private actionHistory: BrowserAgentAction[] = [];\n    private retryConfig: RetryConfig = {\n        maxRetries: 3,\n        delay: 1000,\n        backoffFactor: 1.5\n    };\n    private browserAI: BrowserAI;\n    private config: AgentConfig;\n\n    constructor(config: AgentConfig) {\n        this.currentUrl = window.location.href;\n        this.htmlCleaner = new HTMLCleaner();\n        this.browserAI = new BrowserAI();\n        this.config = config;\n        this.initializeModels();\n    }\n\n    private async initializeModels() {\n        // Load default model if specified\n        if (this.config.defaultModel) {\n            await this.browserAI.loadModel(this.config.defaultModel);\n        }\n    }\n\n    private async getModelForTask(taskType: AgentModelConfig['taskType']): Promise<void> {\n        const modelConfig = this.config.models[taskType];\n        if (!modelConfig) {\n            if (!this.config.defaultModel) {\n                throw new Error(`No model configured for task type ${taskType}`);\n            }\n            return;\n        }\n\n        // Load the specific model for this task if it's different from current\n        if (this.browserAI.currentModel?.modelName !== modelConfig.modelId) {\n            await this.browserAI.loadModel(modelConfig.modelId, modelConfig.options);\n        }\n    }\n\n    async executeAction(action: BrowserAgentAction): Promise<any> {\n        try {\n            this.actionHistory.push(action);\n            return await this.executeWithRetry(() => this.performAction(action));\n        } catch (error: unknown) {\n            if (error instanceof Error) {\n                throw new ActionError(action, error.message);\n            }\n            throw new ActionError(action, String(error));\n        }\n    }\n\n    private async executeWithRetry(fn: () => Promise<any>, attempt = 1): Promise<any> {\n        try {\n            return await fn();\n        } catch (error) {\n            if (attempt >= this.retryConfig.maxRetries) {\n                throw error;\n            }\n            \n            const delay = this.retryConfig.delay * Math.pow(this.retryConfig.backoffFactor, attempt - 1);\n            await this.wait(delay);\n            return this.executeWithRetry(fn, attempt + 1);\n        }\n    }\n\n    private async performAction(action: BrowserAgentAction): Promise<any> {\n        this.validateAction(action);\n        \n        // If action requires AI, ensure correct model is loaded\n        if (action.taskType) {\n            await this.getModelForTask(action.taskType);\n        }\n        \n        switch (action.type) {\n            case 'click':\n                return this.clickElement(action.target as string);\n            case 'scroll':\n                return this.scroll(action.value);\n            case 'navigate':\n                return this.navigate(action.target as string);\n            case 'extract':\n                return this.extractContent(action.target as string);\n            case 'read':\n                return this.readPageContent();\n            case 'wait':\n                return this.wait(action.value);\n            case 'think':\n                return this.makeDecision(action.value);\n            case 'analyze':\n                return this.analyzeContent(action.value);\n            case 'classify':\n                return this.classifyContent(action.value);\n            case 'summarize':\n                return this.summarizeContent(action.value);\n        }\n    }\n\n    private validateAction(action: BrowserAgentAction): void {\n        switch (action.type) {\n            case 'click':\n            case 'extract':\n                if (!action.target) {\n                    throw new Error(`${action.type} action requires a target selector`);\n                }\n                break;\n            case 'scroll':\n                if (!action.value?.direction || !action.value?.amount) {\n                    throw new Error('Scroll action requires direction and amount');\n                }\n                break;\n            case 'navigate':\n                if (!action.target || !action.target.startsWith('http')) {\n                    throw new Error('Navigate action requires a valid URL');\n                }\n                break;\n        }\n    }\n\n    private async clickElement(selector: string): Promise<boolean> {\n        const element = document.querySelector(selector);\n        if (element && element instanceof HTMLElement) {\n            element.click();\n            return true;\n        }\n        return false;\n    }\n\n    private async scroll(options: { direction: 'up' | 'down', amount: number }): Promise<void> {\n        window.scrollBy({\n            top: options.direction === 'down' ? options.amount : -options.amount,\n            behavior: 'smooth'\n        });\n    }\n\n    private async navigate(url: string): Promise<void> {\n        window.location.href = url;\n    }\n\n    private async extractContent(selector: string): Promise<string> {\n        const element = document.querySelector(selector);\n        return element ? this.htmlCleaner.clean(element.innerHTML) : '';\n    }\n\n    private async readPageContent(): Promise<{\n        mainContent: string;\n        semanticContent: string;\n        metadata: PageMetadata;\n    }> {\n        const html = document.documentElement.innerHTML;\n        return {\n            mainContent: await this.getMainContent(html),\n            semanticContent: this.htmlCleaner.cleanSemantic(html),\n            metadata: this.extractMetadata()\n        };\n    }\n\n    private async wait(ms: number): Promise<void> {\n        return new Promise(resolve => setTimeout(resolve, ms));\n    }\n\n    private async getMainContent(html: string): Promise<string> {\n        const cleanedText = this.htmlCleaner.clean(html);\n        return identifyMainContent(cleanedText);\n    }\n\n    private extractMetadata(): PageMetadata {\n        return {\n            title: document.title,\n            url: this.currentUrl,\n            description: this.getMetaContent('description'),\n            keywords: this.getMetaContent('keywords'),\n            timestamp: new Date().toISOString()\n        };\n    }\n\n    private getMetaContent(name: string): string {\n        const meta = document.querySelector(`meta[name=\"${name}\"]`);\n        return meta ? meta.getAttribute('content') || '' : '';\n    }\n\n    private async makeDecision(context: string): Promise<{\n        nextAction: BrowserAgentAction;\n        reasoning: string;\n    }> {\n        await this.getModelForTask('decision');\n        \n        const prompt = `\n        Context: ${context}\n        Current URL: ${this.currentUrl}\n        \n        Analyze the context and decide the next action. \n        Respond in JSON format with:\n        {\n            \"nextAction\": {\n                \"type\": \"...\",\n                \"target\": \"...\",\n                \"value\": \"...\"\n            },\n            \"reasoning\": \"...\"\n        }\n        `;\n\n        const response = await this.browserAI.generateText(prompt);\n        return JSON.parse(response as string);\n    }\n\n    private async analyzeContent(content: string): Promise<{\n        summary: string;\n        entities: string[];\n        sentiment: string;\n        topics: string[];\n    }> {\n        await this.getModelForTask('analysis');\n        \n        const prompt = `\n        Analyze this content:\n        ${content}\n        \n        Provide a detailed analysis including summary, entities, sentiment, and topics.\n        Respond in JSON format.\n        `;\n\n        const response = await this.browserAI.generateText(prompt);\n        return JSON.parse(response as string);\n    }\n\n    private async classifyContent(content: string): Promise<{\n        type: string;\n        confidence: number;\n        categories: string[];\n    }> {\n        await this.getModelForTask('analysis');\n        const response = await this.browserAI.generateText(`\n            Classify this content: ${content}\n            Respond in JSON format with type, confidence, and categories.\n        `);\n        return JSON.parse(response as string);\n    }\n\n    private async summarizeContent(content: string): Promise<{\n        summary: string;\n        keyPoints: string[];\n    }> {\n        await this.getModelForTask('analysis');\n        const response = await this.browserAI.generateText(`\n            Summarize this content: ${content}\n            Respond in JSON format with summary and key points.\n        `);\n        return JSON.parse(response as string);\n    }\n\n    // Example usage with different models\n    async performTask(goal: string): Promise<void> {\n        // Read the page\n        const content = await this.executeAction({ \n            type: 'read' \n        });\n\n        // Analyze content using analysis model\n        const analysis = await this.executeAction({ \n            type: 'analyze',\n            value: content.mainContent,\n            taskType: 'analysis'\n        });\n\n        // Make decision using decision model\n        const decision = await this.executeAction({\n            type: 'think',\n            value: `Goal: ${goal}\\nAnalysis: ${JSON.stringify(analysis)}`,\n            taskType: 'decision'\n        });\n\n        // Execute the decided action\n        await this.executeAction(decision.nextAction);\n    }\n\n    getActionHistory(): BrowserAgentAction[] {\n        return [...this.actionHistory];\n    }\n}","/**\n * DOM Structure Analyzer\n * A TypeScript library for identifying semantic sections of webpages\n */\n\n// Types for our library\nexport type SectionType = \n  | 'navigation' \n  | 'header' \n  | 'footer' \n  | 'sidebar' \n  | 'main-content' \n  | 'article'\n  | 'comments'\n  | 'search'\n  | 'social-links'\n  | 'advertisement'\n  | 'form'\n  | 'unknown';\n\nexport interface AnalysisResult {\n  element: HTMLElement;\n  type: SectionType;\n  confidence: number;\n  highlightColor?: string;\n}\n\nexport interface AnalyzerOptions {\n  highlightColors?: Record<SectionType, string>;\n  minimumConfidence?: number;\n  enabledAnalyzers?: Array<keyof typeof analyzers>;\n}\n\n// Default options\nconst DEFAULT_OPTIONS: AnalyzerOptions = {\n  highlightColors: {\n    'navigation': 'rgba(255, 0, 0, 0.2)',\n    'header': 'rgba(0, 255, 0, 0.2)',\n    'footer': 'rgba(0, 0, 255, 0.2)',\n    'sidebar': 'rgba(255, 255, 0, 0.2)',\n    'main-content': 'rgba(255, 0, 255, 0.2)',\n    'article': 'rgba(0, 255, 255, 0.2)',\n    'comments': 'rgba(128, 0, 128, 0.2)',\n    'search': 'rgba(255, 165, 0, 0.2)',\n    'social-links': 'rgba(0, 128, 128, 0.2)',\n    'advertisement': 'rgba(128, 128, 0, 0.2)',\n    'form': 'rgba(128, 0, 0, 0.2)',\n    'unknown': 'rgba(128, 128, 128, 0.2)'\n  },\n  minimumConfidence: 0.6,\n  enabledAnalyzers: ['semantic', 'classId', 'position', 'content', 'aria']\n};\n\n/**\n * Main class for DOM Structure Analysis\n */\nexport class DOMStructureAnalyzer {\n  private options: AnalyzerOptions;\n  private results: AnalysisResult[] = [];\n  private highlightElements: HTMLElement[] = [];\n\n  constructor(options: Partial<AnalyzerOptions> = {}) {\n    this.options = { ...DEFAULT_OPTIONS, ...options };\n  }\n\n  /**\n   * Analyze the DOM to identify sections\n   */\n  public analyze(root: HTMLElement = document.body): AnalysisResult[] {\n    this.results = [];\n    this.removeHighlights();\n\n    // Get all elements that might be structural sections\n    const potentialSections = this.getPotentialSections(root);\n    \n    // Analyze each potential section\n    potentialSections.forEach(element => {\n      const elementResults: Record<SectionType, number> = {\n        'navigation': 0,\n        'header': 0,\n        'footer': 0,\n        'sidebar': 0,\n        'main-content': 0,\n        'article': 0,\n        'comments': 0,\n        'search': 0,\n        'social-links': 0,\n        'advertisement': 0,\n        'form': 0,\n        'unknown': 0\n      };\n\n      // Run enabled analyzers\n      this.options.enabledAnalyzers?.forEach(analyzerName => {\n        const analyzerResults = analyzers[analyzerName](element);\n        \n        // Combine results\n        Object.keys(analyzerResults).forEach(type => {\n          elementResults[type as SectionType] += analyzerResults[type as SectionType];\n        });\n      });\n\n      // Normalize scores to get confidence levels\n      let totalScore = Object.values(elementResults).reduce((sum, score) => sum + score, 0);\n      if (totalScore === 0) {\n        elementResults.unknown = 1;\n        totalScore = 1;\n      }\n\n      // Find the section type with highest confidence\n      let highestType: SectionType = 'unknown';\n      let highestConfidence = 0;\n\n      (Object.keys(elementResults) as SectionType[]).forEach(type => {\n        const confidence = elementResults[type] / totalScore;\n        if (confidence > highestConfidence) {\n          highestConfidence = confidence;\n          highestType = type;\n        }\n      });\n\n      // Add to results if confidence meets minimum threshold\n      if (highestConfidence >= (this.options.minimumConfidence || 0.6)) {\n        this.results.push({\n          element,\n          type: highestType,\n          confidence: highestConfidence,\n          highlightColor: this.options.highlightColors?.[highestType]\n        });\n      }\n    });\n\n    return this.results;\n  }\n\n  /**\n   * Highlight identified sections on the page\n   */\n  public highlight(): void {\n    this.removeHighlights();\n\n    this.results.forEach(result => {\n      const highlightEl = document.createElement('div');\n      highlightEl.classList.add('dom-analyzer-highlight');\n      \n      // Set position and dimensions\n      const rect = result.element.getBoundingClientRect();\n      const scrollX = window.scrollX || document.documentElement.scrollLeft;\n      const scrollY = window.scrollY || document.documentElement.scrollTop;\n      \n      Object.assign(highlightEl.style, {\n        position: 'absolute',\n        top: `${rect.top + scrollY}px`,\n        left: `${rect.left + scrollX}px`,\n        width: `${rect.width}px`,\n        height: `${rect.height}px`,\n        backgroundColor: result.highlightColor || 'rgba(128, 128, 128, 0.2)',\n        zIndex: '10000',\n        pointerEvents: 'none',\n        border: '2px solid rgba(0, 0, 0, 0.5)',\n        borderRadius: '4px',\n        boxSizing: 'border-box'\n      });\n\n      // Add a label\n      const label = document.createElement('div');\n      Object.assign(label.style, {\n        position: 'absolute',\n        top: '0',\n        left: '0',\n        backgroundColor: 'rgba(0, 0, 0, 0.7)',\n        color: 'white',\n        padding: '2px 6px',\n        fontSize: '12px',\n        borderRadius: '2px',\n        pointerEvents: 'none'\n      });\n      label.textContent = `${result.type} (${Math.round(result.confidence * 100)}%)`;\n      highlightEl.appendChild(label);\n\n      document.body.appendChild(highlightEl);\n      this.highlightElements.push(highlightEl);\n    });\n  }\n\n  /**\n   * Remove all highlights\n   */\n  public removeHighlights(): void {\n    this.highlightElements.forEach(el => {\n      if (el.parentNode) {\n        el.parentNode.removeChild(el);\n      }\n    });\n    this.highlightElements = [];\n  }\n\n  /**\n   * Get section mapping (for use in other applications)\n   */\n  public getSectionMap(): Record<SectionType, HTMLElement[]> {\n    const map: Record<SectionType, HTMLElement[]> = {\n      'navigation': [],\n      'header': [],\n      'footer': [],\n      'sidebar': [],\n      'main-content': [],\n      'article': [],\n      'comments': [],\n      'search': [],\n      'social-links': [],\n      'advertisement': [],\n      'form': [],\n      'unknown': []\n    };\n\n    this.results.forEach(result => {\n      map[result.type].push(result.element);\n    });\n\n    return map;\n  }\n\n  /**\n   * Get potential DOM sections for analysis\n   */\n  private getPotentialSections(root: HTMLElement): HTMLElement[] {\n    // First look for semantic elements\n    const semanticSelectors = [\n      'nav', 'header', 'footer', 'aside', 'main', 'article', \n      'section', 'form', 'div.sidebar', 'div.main', 'div.content',\n      'div.navigation', 'div.menu', 'div.header', 'div.footer',\n      '[role=\"navigation\"]', '[role=\"banner\"]', '[role=\"contentinfo\"]',\n      '[role=\"complementary\"]', '[role=\"main\"]', '[role=\"search\"]'\n    ];\n\n    // Get all matching elements\n    const elements = Array.from(\n      root.querySelectorAll(semanticSelectors.join(', '))\n    ) as HTMLElement[];\n\n    // Include the root if it's a potential section itself\n    if (semanticSelectors.some(selector => \n      root.matches(selector) || \n      (root.id && root.id.match(/(nav|header|footer|sidebar|content|main)/i)) ||\n      (root.className && root.className.match(/(nav|header|footer|sidebar|content|main)/i))\n    )) {\n      elements.unshift(root);\n    }\n\n    // Filter out elements that are too small or are nested within already detected elements\n    return this.filterNestedElements(elements);\n  }\n\n  /**\n   * Filter out nested elements to prevent duplicate highlighting\n   */\n  private filterNestedElements(elements: HTMLElement[]): HTMLElement[] {\n    // Sort by DOM depth (shallowest first)\n    elements.sort((a, b) => {\n      let depthA = 0, depthB = 0;\n      let node: Node | null = a;\n      while (node) { depthA++; node = node.parentNode; }\n      node = b;\n      while (node) { depthB++; node = node.parentNode; }\n      return depthA - depthB;\n    });\n\n    // Keep track of which elements to include\n    const filtered: HTMLElement[] = [];\n    \n    elements.forEach(element => {\n      // Check if this element is contained within an already included element\n      const isNested = filtered.some(parent => parent.contains(element) && parent !== element);\n      \n      // Only include if not nested and has minimum size\n      if (!isNested && this.hasMinimumSize(element)) {\n        filtered.push(element);\n      }\n    });\n\n    return filtered;\n  }\n\n  /**\n   * Check if an element has minimum size to be considered a section\n   */\n  private hasMinimumSize(element: HTMLElement): boolean {\n    const rect = element.getBoundingClientRect();\n    return rect.width > 50 && rect.height > 50;\n  }\n}\n\n/**\n * Individual analyzers that assign scores to different section types\n */\nconst analyzers = {\n  /**\n   * Analyzes semantic HTML tags\n   */\n  semantic(element: HTMLElement): Record<SectionType, number> {\n    const scores: Record<SectionType, number> = { } as Record<SectionType, number>;\n    Object.keys(DEFAULT_OPTIONS.highlightColors || {}).forEach(key => {\n      scores[key as SectionType] = 0;\n    });\n\n    const tagName = element.tagName.toLowerCase();\n    \n    switch (tagName) {\n      case 'nav':\n        scores.navigation = 10;\n        break;\n      case 'header':\n        scores.header = 10;\n        break;\n      case 'footer':\n        scores.footer = 10;\n        break;\n      case 'aside':\n        scores.sidebar = 10;\n        break;\n      case 'main':\n        scores['main-content'] = 10;\n        break;\n      case 'article':\n        scores.article = 10;\n        break;\n      case 'form':\n        scores.form = 8;\n        break;\n      case 'section':\n        // Need more info to categorize sections\n        const sectionHeading = element.querySelector('h1, h2, h3, h4, h5, h6');\n        if (sectionHeading) {\n          const headingText = sectionHeading.textContent?.toLowerCase() || '';\n          if (headingText.includes('comment')) scores.comments = 5;\n          else if (headingText.includes('related')) scores['main-content'] = 3;\n          else scores.article = 3;\n        }\n        break;\n    }\n\n    return scores;\n  },\n\n  /**\n   * Analyzes class and ID attributes\n   */\n  classId(element: HTMLElement): Record<SectionType, number> {\n    const scores: Record<SectionType, number> = { } as Record<SectionType, number>;\n    Object.keys(DEFAULT_OPTIONS.highlightColors || {}).forEach(key => {\n      scores[key as SectionType] = 0;\n    });\n\n    const className = element.className.toLowerCase();\n    const id = element.id.toLowerCase();\n    \n    // Navigation indicators\n    if (className.match(/nav|menu|navbar|navigation/) || id.match(/nav|menu|navbar|navigation/)) {\n      scores.navigation += 5;\n    }\n    \n    // Header indicators\n    if (className.match(/header|banner|top/) || id.match(/header|banner|top/)) {\n      scores.header += 5;\n    }\n    \n    // Footer indicators\n    if (className.match(/footer|bottom/) || id.match(/footer|bottom/)) {\n      scores.footer += 5;\n    }\n    \n    // Sidebar indicators\n    if (className.match(/sidebar|side|rail|widget-area/) || id.match(/sidebar|side|rail|widget-area/)) {\n      scores.sidebar += 5;\n    }\n    \n    // Main content indicators\n    if (className.match(/content|main|body|page/) || id.match(/content|main|body|page/)) {\n      scores['main-content'] += 5;\n    }\n    \n    // Article indicators\n    if (className.match(/article|post|entry/) || id.match(/article|post|entry/)) {\n      scores.article += 5;\n    }\n    \n    // Comments indicators\n    if (className.match(/comments|discussion|responses/) || id.match(/comments|discussion|responses/)) {\n      scores.comments += 5;\n    }\n    \n    // Search indicators\n    if (className.match(/search/) || id.match(/search/)) {\n      scores.search += 5;\n    }\n    \n    // Social links indicators\n    if (className.match(/social|share|follow/) || id.match(/social|share|follow/)) {\n      scores['social-links'] += 5;\n    }\n    \n    // Ads indicators\n    if (className.match(/ad|ads|advert|banner/) || id.match(/ad|ads|advert|banner/)) {\n      scores.advertisement += 5;\n    }\n\n    return scores;\n  },\n\n  /**\n   * Analyzes element position on the page\n   */\n  position(element: HTMLElement): Record<SectionType, number> {\n    const scores: Record<SectionType, number> = { } as Record<SectionType, number>;\n    Object.keys(DEFAULT_OPTIONS.highlightColors || {}).forEach(key => {\n      scores[key as SectionType] = 0;\n    });\n\n    const rect = element.getBoundingClientRect();\n    const windowHeight = window.innerHeight;\n    const windowWidth = window.innerWidth;\n    \n    // Top position suggests header or navigation\n    if (rect.top < windowHeight * 0.2) {\n      scores.header += 3;\n      scores.navigation += 2;\n    }\n    \n    // Bottom position suggests footer\n    if (rect.bottom > windowHeight * 0.8) {\n      scores.footer += 3;\n    }\n    \n    // Left side suggests sidebar\n    if (rect.left < windowWidth * 0.2 && rect.width < windowWidth * 0.3) {\n      scores.sidebar += 3;\n      scores.navigation += 1;\n    }\n    \n    // Right side suggests sidebar\n    if (rect.right > windowWidth * 0.8 && rect.width < windowWidth * 0.3) {\n      scores.sidebar += 3;\n    }\n    \n    // Central position suggests main content\n    if (rect.left > windowWidth * 0.2 && rect.right < windowWidth * 0.8) {\n      scores['main-content'] += 3;\n      scores.article += 2;\n    }\n\n    // Full width at top often indicates navigation or header\n    if (rect.width > windowWidth * 0.9 && rect.top < windowHeight * 0.2) {\n      scores.navigation += 2;\n      scores.header += 2;\n    }\n\n    return scores;\n  },\n\n  /**\n   * Analyzes content characteristics\n   */\n  content(element: HTMLElement): Record<SectionType, number> {\n    const scores: Record<SectionType, number> = { } as Record<SectionType, number>;\n    Object.keys(DEFAULT_OPTIONS.highlightColors || {}).forEach(key => {\n      scores[key as SectionType] = 0;\n    });\n\n    // Count different types of elements\n    const links = element.querySelectorAll('a');\n    const paragraphs = element.querySelectorAll('p');\n    const headings = element.querySelectorAll('h1, h2, h3, h4, h5, h6');\n    const images = element.querySelectorAll('img');\n    const forms = element.querySelectorAll('form');\n    const inputs = element.querySelectorAll('input');\n    // const buttons = element.querySelectorAll('button');\n    // const lists = element.querySelectorAll('ul, ol');\n    \n    // Navigation usually has many links, often in lists\n    if (links.length > 5 && links.length / element.textContent!.length > 0.1) {\n      scores.navigation += 3;\n    }\n    \n    // Main content usually has paragraphs and headings\n    if (paragraphs.length > 2 && headings.length >= 1) {\n      scores['main-content'] += 3;\n      scores.article += 2;\n    }\n    \n    // Articles often have paragraphs, headings, and images\n    if (paragraphs.length > 3 && headings.length >= 1 && images.length >= 1) {\n      scores.article += 3;\n    }\n    \n    // Search usually has a form with inputs\n    if (forms.length >= 1 && inputs.length >= 1) {\n      // Specifically look for search input types or placeholder text\n      const searchInputs = Array.from(inputs).filter(input => \n        input.getAttribute('type') === 'search' || \n        input.getAttribute('placeholder')?.toLowerCase().includes('search')\n      );\n      \n      if (searchInputs.length > 0) {\n        scores.search += 4;\n      } else {\n        scores.form += 3;\n      }\n    }\n    \n    // Comments sections often have repeated similar structures\n    const commentPatterns = element.querySelectorAll('.comment, .response, [id^=\"comment-\"]');\n    if (commentPatterns.length > 1) {\n      scores.comments += 4;\n    }\n    \n    // Social links often have recognizable icons or text\n    const socialPatterns = Array.from(links).filter(link => {\n      const href = link.getAttribute('href') || '';\n      const text = link.textContent?.toLowerCase() || '';\n      return href.match(/facebook|twitter|instagram|linkedin|youtube/) || \n             text.match(/facebook|twitter|instagram|linkedin|youtube|share|follow/);\n    });\n    \n    if (socialPatterns.length > 1) {\n      scores['social-links'] += 4;\n    }\n    \n    // Sidebar often has widgets and less text\n    if (element.querySelectorAll('.widget, aside, [class*=\"widget\"]').length > 0) {\n      scores.sidebar += 3;\n    }\n\n    return scores;\n  },\n\n  /**\n   * Analyzes ARIA roles and landmarks\n   */\n  aria(element: HTMLElement): Record<SectionType, number> {\n    const scores: Record<SectionType, number> = { } as Record<SectionType, number>;\n    Object.keys(DEFAULT_OPTIONS.highlightColors || {}).forEach(key => {\n      scores[key as SectionType] = 0;\n    });\n\n    const role = element.getAttribute('role');\n    \n    if (role) {\n      switch (role) {\n        case 'navigation':\n          scores.navigation = 10;\n          break;\n        case 'banner':\n          scores.header = 10;\n          break;\n        case 'contentinfo':\n          scores.footer = 10;\n          break;\n        case 'complementary':\n          scores.sidebar = 10;\n          break;\n        case 'main':\n          scores['main-content'] = 10;\n          break;\n        case 'article':\n          scores.article = 10;\n          break;\n        case 'search':\n          scores.search = 10;\n          break;\n        case 'form':\n          scores.form = 8;\n          break;\n      }\n    }\n\n    return scores;\n  }\n};\n\n/**\n * Usage example\n */\nexport function analyzeAndHighlightPage(): void {\n  const analyzer = new DOMStructureAnalyzer();\n  analyzer.analyze();\n  analyzer.highlight();\n  \n  console.log('DOM analysis complete');\n  console.log('Detected sections:', analyzer.getSectionMap());\n} ","/**\n * Browser action helper functions for AI agent interactions\n * These standalone functions can be used in agent workflows to interact with web pages\n */\n\n/**\n * Click on an element matching the provided selector\n * @param selector CSS selector for the target element\n * @returns Promise resolving to true if click was successful, false otherwise\n */\nexport async function clickElement(selector: string): Promise<boolean> {\n  try {\n    const element = document.querySelector(selector);\n    if (element && element instanceof HTMLElement) {\n      element.click();\n      return true;\n    }\n    return false;\n  } catch (error) {\n    console.error(`Error clicking element ${selector}:`, error);\n    return false;\n  }\n}\n\n/**\n * Fill a form input with the provided value\n * @param selector CSS selector for the input element\n * @param value Value to enter into the input\n * @returns Promise resolving to true if input was filled successfully, false otherwise\n */\nexport async function fillInput(selector: string, value: string): Promise<boolean> {\n  try {\n    const element = document.querySelector(selector);\n    if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n      element.value = value;\n      \n      // Trigger input and change events to simulate user typing\n      element.dispatchEvent(new Event('input', { bubbles: true }));\n      element.dispatchEvent(new Event('change', { bubbles: true }));\n      return true;\n    }\n    return false;\n  } catch (error) {\n    console.error(`Error filling input ${selector}:`, error);\n    return false;\n  }\n}\n\n/**\n * Select an option from a dropdown\n * @param selector CSS selector for the select element\n * @param value Value to select\n * @returns Promise resolving to true if selection was successful, false otherwise\n */\nexport async function selectOption(selector: string, value: string): Promise<boolean> {\n  try {\n    const element = document.querySelector(selector);\n    if (element instanceof HTMLSelectElement) {\n      element.value = value;\n      element.dispatchEvent(new Event('change', { bubbles: true }));\n      return true;\n    }\n    return false;\n  } catch (error) {\n    console.error(`Error selecting option in ${selector}:`, error);\n    return false;\n  }\n}\n\n/**\n * Scroll the page in the specified direction and amount\n * @param options Scroll options including direction and amount\n * @returns Promise resolving to void\n */\nexport async function scrollPage(options: { direction: 'up' | 'down', amount: number }): Promise<void> {\n  try {\n    window.scrollBy({\n      top: options.direction === 'down' ? options.amount : -options.amount,\n      behavior: 'smooth'\n    });\n    \n    // Wait for scroll to complete\n    return new Promise(resolve => setTimeout(resolve, 300));\n  } catch (error) {\n    console.error('Error scrolling page:', error);\n  }\n}\n\n/**\n * Navigate to a specified URL\n * @param url URL to navigate to\n * @returns Promise resolving to void\n */\nexport async function navigateTo(url: string): Promise<void> {\n  try {\n    window.location.href = url;\n  } catch (error) {\n    console.error(`Error navigating to ${url}:`, error);\n  }\n}\n\n/**\n * Wait for an element to appear in the DOM\n * @param selector CSS selector for the element to wait for\n * @param timeout Maximum time to wait in milliseconds\n * @returns Promise resolving to the element if found, null if timeout\n */\nexport async function waitForElement(selector: string, timeout = 5000): Promise<Element | null> {\n  return new Promise(resolve => {\n    const element = document.querySelector(selector);\n    if (element) {\n      resolve(element);\n      return;\n    }\n\n    const startTime = Date.now();\n    const checkInterval = setInterval(() => {\n      const element = document.querySelector(selector);\n      if (element) {\n        clearInterval(checkInterval);\n        resolve(element);\n      } else if (Date.now() - startTime > timeout) {\n        clearInterval(checkInterval);\n        resolve(null);\n      }\n    }, 100);\n  });\n}\n\n/**\n * Extract text content from an element\n * @param selector CSS selector for the target element\n * @returns Promise resolving to the text content or empty string if element not found\n */\nexport async function extractText(selector: string): Promise<string> {\n  try {\n    const element = document.querySelector(selector);\n    return element ? element.textContent?.trim() || '' : '';\n  } catch (error) {\n    console.error(`Error extracting text from ${selector}:`, error);\n    return '';\n  }\n}\n\n/**\n * Check if an element exists in the DOM\n * @param selector CSS selector for the element to check\n * @returns Promise resolving to true if element exists, false otherwise\n */\nexport async function elementExists(selector: string): Promise<boolean> {\n  try {\n    return document.querySelector(selector) !== null;\n  } catch (error) {\n    console.error(`Error checking if element exists ${selector}:`, error);\n    return false;\n  }\n}\n\n/**\n * Find all elements matching a selector and return their text content\n * @param selector CSS selector for the elements to find\n * @returns Promise resolving to array of text content from matching elements\n */\nexport async function findAllElements(selector: string): Promise<string[]> {\n  try {\n    const elements = document.querySelectorAll(selector);\n    return Array.from(elements).map(el => el.textContent?.trim() || '');\n  } catch (error) {\n    console.error(`Error finding elements ${selector}:`, error);\n    return [];\n  }\n}\n\n/**\n * Submit a form\n * @param selector CSS selector for the form element\n * @returns Promise resolving to true if submission was successful, false otherwise\n */\nexport async function submitForm(selector: string): Promise<boolean> {\n  try {\n    const form = document.querySelector(selector);\n    if (form instanceof HTMLFormElement) {\n      form.submit();\n      return true;\n    }\n    return false;\n  } catch (error) {\n    console.error(`Error submitting form ${selector}:`, error);\n    return false;\n  }\n}\n\n/**\n * Focus on an element\n * @param selector CSS selector for the element to focus\n * @returns Promise resolving to true if focus was successful, false otherwise\n */\nexport async function focusElement(selector: string): Promise<boolean> {\n  try {\n    const element = document.querySelector(selector);\n    if (element instanceof HTMLElement) {\n      element.focus();\n      return true;\n    }\n    return false;\n  } catch (error) {\n    console.error(`Error focusing element ${selector}:`, error);\n    return false;\n  }\n}\n\n/**\n * Get attributes of an element\n * @param selector CSS selector for the target element\n * @param attributeNames Array of attribute names to retrieve\n * @returns Promise resolving to object with attribute name-value pairs\n */\nexport async function getElementAttributes(\n  selector: string, \n  attributeNames: string[]\n): Promise<Record<string, string>> {\n  try {\n    const element = document.querySelector(selector);\n    if (!element) return {};\n    \n    const attributes: Record<string, string> = {};\n    attributeNames.forEach(attr => {\n      const value = element.getAttribute(attr);\n      if (value !== null) {\n        attributes[attr] = value;\n      }\n    });\n    \n    return attributes;\n  } catch (error) {\n    console.error(`Error getting attributes from ${selector}:`, error);\n    return {};\n  }\n} ","/**\n * PDF Parser for extracting text from PDF files\n * Uses PDF.js library for parsing PDF documents in the browser\n */\n\n/* eslint-disable no-console */\n\n// We'll use the PDF.js library which needs to be included in the project\n// This interface represents the PDF.js library types we'll use\ninterface PDFJSStatic {\n  getDocument: (source: Uint8Array | { url: string }) => PDFDocumentLoadingTask;\n  GlobalWorkerOptions?: {\n    workerSrc: string;\n  };\n  version?: string;\n}\n\ninterface PDFDocumentLoadingTask {\n  promise: Promise<PDFDocumentProxy>;\n}\n\ninterface PDFDocumentProxy {\n  numPages: number;\n  getPage: (pageNumber: number) => Promise<PDFPageProxy>;\n}\n\ninterface PDFPageProxy {\n  getTextContent: () => Promise<PDFTextContent>;\n}\n\ninterface PDFTextContent {\n  items: Array<{ str: string }>;\n}\n\n// Helper function to get the PDF.js library\nfunction getPdfLib(): PDFJSStatic {\n  if (typeof window === 'undefined') {\n    throw new Error('PDF.js can only be used in browser environments');\n  }\n  \n  const pdfjsLib = (window as any).pdfjsLib;\n  \n  if (!pdfjsLib) {\n    throw new Error('PDF.js library not found. Make sure to include it in your project.');\n  }\n  \n  console.log('PDF.js library found:', pdfjsLib);\n  \n  // Ensure worker is set - check if workerSrc can be set directly\n  if (pdfjsLib.GlobalWorkerOptions) {\n    try {\n      // Only try to set the workerSrc property if it's not already set\n      if (!pdfjsLib.GlobalWorkerOptions.workerSrc) {\n        pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.11.174/build/pdf.worker.min.js';\n      }\n    } catch (e) {\n      console.warn('Could not set PDF.js worker source:', e);\n      // You might need an alternative approach here depending on the PDF.js version\n    }\n  }\n  \n  return pdfjsLib;\n}\n\n// Declare PDF.js as a global variable that will be loaded externally\ndeclare const pdfjsLib: PDFJSStatic;\n\n/**\n * Options for PDF parsing\n */\nexport interface PDFParseOptions {\n  /**\n   * Maximum number of pages to parse (default: all pages)\n   */\n  maxPages?: number;\n  \n  /**\n   * Whether to include page numbers in the output (default: false)\n   */\n  includePageNumbers?: boolean;\n  \n  /**\n   * Custom page separator (default: \"\\n\\n\")\n   */\n  pageSeparator?: string;\n  \n  /**\n   * Debug mode (default: false)\n   */\n  debug?: boolean;\n}\n\n/**\n * Result of PDF parsing\n */\nexport interface PDFParseResult {\n  /**\n   * The extracted text content\n   */\n  text: string;\n  \n  /**\n   * Number of pages in the document\n   */\n  numPages: number;\n  \n  /**\n   * Text content by page\n   */\n  pages: string[];\n  \n  /**\n   * Any errors encountered during parsing\n   */\n  errors?: string[];\n  \n  /**\n   * Debug information about the parsing process\n   */\n  debugInfo?: string[];\n}\n\n/**\n * PDF Parser class for extracting text from PDF files\n */\nexport class PDFParser {\n  /**\n   * Parse a PDF file from a URL\n   * \n   * @param url URL of the PDF file to parse\n   * @param options Parsing options\n   * @returns Promise resolving to the parsed PDF content\n   */\n  static async parseFromUrl(url: string, options: PDFParseOptions = {}): Promise<PDFParseResult> {\n    const debugInfo: string[] = [];\n    if (options.debug) debugInfo.push(`Starting URL parsing: ${url}`);\n    console.log(`Starting URL parsing: ${url}`);\n    \n    try {\n      // Get PDF.js library\n      const pdfjsLib = getPdfLib();\n      if (options.debug) debugInfo.push('PDF.js library found');\n      \n      // Load the PDF document\n      if (options.debug) debugInfo.push('Loading PDF document from URL...');\n      console.log('Loading PDF document from URL...');\n      \n      const loadingTask = pdfjsLib.getDocument({ url });\n      const pdf = await loadingTask.promise;\n      \n      if (options.debug) debugInfo.push(`PDF loaded successfully. Pages: ${pdf.numPages}`);\n      console.log(`PDF loaded successfully. Pages: ${pdf.numPages}`);\n      \n      return this.extractTextFromPdf(pdf, options, debugInfo);\n    } catch (error) {\n      const errorMessage = (error as Error).message;\n      if (options.debug) debugInfo.push(`Error: ${errorMessage}`);\n      console.error('PDF parsing error:', error);\n      \n      return {\n        text: '',\n        numPages: 0,\n        pages: [],\n        errors: [errorMessage],\n        debugInfo: options.debug ? debugInfo : undefined\n      };\n    }\n  }\n  \n  /**\n   * Parse a PDF file from an ArrayBuffer\n   * \n   * @param data ArrayBuffer containing the PDF data\n   * @param options Parsing options\n   * @returns Promise resolving to the parsed PDF content\n   */\n  static async parseFromData(data: ArrayBuffer, options: PDFParseOptions = {}): Promise<PDFParseResult> {\n    const debugInfo: string[] = [];\n    if (options.debug) debugInfo.push(`Starting ArrayBuffer parsing. Size: ${data.byteLength} bytes`);\n    console.log(`Starting ArrayBuffer parsing. Size: ${data.byteLength} bytes`);\n    \n    try {\n      // Get PDF.js library\n      const pdfjsLib = getPdfLib();\n      if (options.debug) debugInfo.push('PDF.js library found');\n      \n      // Convert ArrayBuffer to Uint8Array\n      const uint8Array = new Uint8Array(data);\n      if (options.debug) debugInfo.push(`Converted to Uint8Array. Length: ${uint8Array.length}`);\n      console.log(`Converted to Uint8Array. Length: ${uint8Array.length}`);\n      \n      // Load the PDF document\n      if (options.debug) debugInfo.push('Loading PDF document from data...');\n      console.log('Loading PDF document from data...');\n      \n      try {\n        const loadingTask = pdfjsLib.getDocument(uint8Array);\n        console.log('Loading task created:', loadingTask);\n        \n        const pdf = await loadingTask.promise;\n        console.log('PDF loaded successfully:', pdf);\n        console.log('Number of pages:', pdf.numPages);\n        \n        if (options.debug) debugInfo.push(`PDF loaded successfully. Pages: ${pdf.numPages}`);\n        \n        return this.extractTextFromPdf(pdf, options, debugInfo);\n      } catch (loadError) {\n        console.error('Error loading PDF:', loadError);\n        throw loadError;\n      }\n    } catch (error) {\n      const errorMessage = (error as Error).message;\n      if (options.debug) debugInfo.push(`Error: ${errorMessage}`);\n      console.error('PDF parsing error:', error);\n      \n      return {\n        text: '',\n        numPages: 0,\n        pages: [],\n        errors: [errorMessage],\n        debugInfo: options.debug ? debugInfo : undefined\n      };\n    }\n  }\n  \n  /**\n   * Extract text content from a PDF document\n   * \n   * @param pdf PDF document proxy\n   * @param options Parsing options\n   * @returns Promise resolving to the parsed PDF content\n   */\n  private static async extractTextFromPdf(\n    pdf: PDFDocumentProxy, \n    options: PDFParseOptions,\n    debugInfo: string[]\n  ): Promise<PDFParseResult> {\n    const { \n      maxPages = pdf.numPages,\n      includePageNumbers = false,\n      pageSeparator = '\\n\\n'\n    } = options;\n    \n    const pageTexts: string[] = [];\n    const errors: string[] = [];\n    \n    // Determine how many pages to process\n    const pagesToProcess = Math.min(maxPages, pdf.numPages);\n    \n    // Process each page\n    for (let i = 1; i <= pagesToProcess; i++) {\n      try {\n        const page = await pdf.getPage(i);\n        const textContent = await page.getTextContent();\n        \n        let pageText = textContent.items.map(item => item.str).join(' ');\n        \n        // Add page number if requested\n        if (includePageNumbers) {\n          pageText = `[Page ${i}]\\n${pageText}`;\n        }\n        \n        pageTexts.push(pageText);\n      } catch (error) {\n        errors.push(`Error extracting text from page ${i}: ${(error as Error).message}`);\n      }\n    }\n    \n    // Combine all page texts\n    const fullText = pageTexts.join(pageSeparator);\n    \n    return {\n      text: fullText,\n      numPages: pdf.numPages,\n      pages: pageTexts,\n      errors: errors.length > 0 ? errors : undefined,\n      debugInfo: options.debug ? debugInfo : undefined\n    };\n  }\n  \n  /**\n   * Loads the PDF.js library from a CDN if not already available\n   * @param pdfJsPath Path to the PDF.js library\n   * @param workerPath Path to the PDF.js worker\n   */\n  static async loadPdfJsLibrary(\n    pdfJsPath: string = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.11.174/build/pdf.min.js',\n    workerPath: string = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.11.174/build/pdf.worker.min.js'\n  ): Promise<void> {\n    // Check if PDF.js is already available\n    if ((window as any).pdfjsLib) {\n      return;\n    }\n\n    // Check if we're in a browser extension environment\n    const isExtension = typeof window !== 'undefined' && \n                       typeof (window as any).chrome !== 'undefined' && \n                       (window as any).chrome.runtime && \n                       (window as any).chrome.runtime.id;\n    \n    if (isExtension) {\n      try {\n        // For extensions, use dynamic import with a fallback\n        let pdfjs;\n        try {\n          // Try to use bundled version first\n          pdfjs = await import('pdfjs-dist');\n        } catch (e) {\n          // Fallback to window global if import fails\n          if (!(window as any).pdfjsLib) {\n            throw new Error('PDF.js not available');\n          }\n          pdfjs = (window as any).pdfjsLib;\n        }\n        \n        // Set up worker\n        if (pdfjs.GlobalWorkerOptions && !pdfjs.GlobalWorkerOptions.workerSrc) {\n          const chrome = (window as any).chrome;\n          if (chrome && chrome.runtime && chrome.runtime.getURL) {\n            pdfjs.GlobalWorkerOptions.workerSrc = chrome.runtime.getURL('pdf.worker.min.js');\n          } else {\n            pdfjs.GlobalWorkerOptions.workerSrc = workerPath;\n          }\n        }\n        \n        // Assign to window\n        (window as any).pdfjsLib = pdfjs;\n      } catch (error) {\n        console.error('Error loading PDF.js:', error);\n        throw error;\n      }\n    } else {\n      // For non-extension environments, load from CDN\n      return new Promise((resolve, reject) => {\n        const script = document.createElement('script');\n        script.src = pdfJsPath;\n        script.onload = () => {\n          (window as any).pdfjsLib.GlobalWorkerOptions.workerSrc = workerPath;\n          resolve();\n        };\n        script.onerror = () => reject(new Error('Failed to load PDF.js'));\n        document.head.appendChild(script);\n      });\n    }\n  }\n\n  /**\n   * Checks if PDF.js is available in the current environment\n   */\n  static isPdfJsAvailable(): boolean {\n    return typeof window !== 'undefined' && !!(window as any).pdfjsLib;\n  }\n}\n\n/**\n * Utility function to extract text from a PDF file\n * \n * @param source URL or ArrayBuffer of the PDF file\n * @param options Parsing options\n * @returns Promise resolving to the parsed PDF content\n */\nexport async function extractTextFromPdf(\n  source: string | ArrayBuffer,\n  options: PDFParseOptions = {}\n): Promise<string> {\n  let result: PDFParseResult;\n  \n  if (typeof source === 'string') {\n    result = await PDFParser.parseFromUrl(source, options);\n  } else {\n    result = await PDFParser.parseFromData(source, options);\n  }\n  \n  return result.text;\n}\n\n/**\n * Utility function to extract structured text from a PDF file with page information\n * \n * @param source URL or ArrayBuffer of the PDF file\n * @param options Parsing options\n * @returns Promise resolving to the parsed PDF content with page information\n */\nexport async function extractStructuredTextFromPdf(\n  source: string | ArrayBuffer,\n  options: PDFParseOptions = {}\n): Promise<PDFParseResult> {\n  if (typeof source === 'string') {\n    return await PDFParser.parseFromUrl(source, options);\n  } else {\n    return await PDFParser.parseFromData(source, options);\n  }\n}\n\n// Instead, initialize PDF.js when needed in a function\nfunction initializePdfJs() {\n  // Only run this in browser environments\n  if (typeof window !== 'undefined') {\n    // Check if PDF.js is already loaded\n    if (!(window as any).pdfjsLib) {\n      console.log('PDF.js not loaded, will load on demand when needed');\n    }\n  }\n}\n\n// Call this function instead of using top-level await\ninitializePdfJs();\n\n/**\n * Formats PDF text with page numbers and additional metadata\n * @param result The parsed PDF result\n * @param options Formatting options\n * @returns Formatted text representation of the PDF\n */\nexport function pdfToText(\n  result: PDFParseResult,\n  options: {\n    includePageNumbers?: boolean;\n    includeSummary?: boolean;\n    pagePrefix?: string;\n    pageSuffix?: string;\n  } = {}\n): string {\n  // Default options\n  const includePageNumbers = options.includePageNumbers !== false;\n  const includeSummary = options.includeSummary !== false;\n  const pagePrefix = options.pagePrefix || '--- Page ';\n  const pageSuffix = options.pageSuffix || ' ---';\n  \n  const lines: string[] = [];\n  \n  // Add each page with optional page numbers\n  if (includePageNumbers) {\n    for (let i = 0; i < result.pages.length; i++) {\n      const pageNum = i + 1;\n      lines.push(`${pagePrefix}${pageNum}${pageSuffix}`);\n      lines.push(result.pages[i]);\n      lines.push(''); // Empty line between pages\n    }\n  } else {\n    // Just concatenate all pages\n    lines.push(result.text);\n  }\n  \n  // Add summary information\n  if (includeSummary) {\n    lines.push('');\n    lines.push(`PDF Summary: ${result.numPages} pages`);\n    \n    if (result.errors && result.errors.length > 0) {\n      lines.push('Errors encountered during parsing:');\n      result.errors.forEach(error => {\n        lines.push(`- ${error}`);\n      });\n    }\n  }\n  \n  return lines.join('\\n');\n}\n\n/**\n * Processes a PDF file and returns both text and structured data\n * This is a convenience function that handles buffer copying and multiple extractions\n * \n * @param file The PDF file to process\n * @param options Parsing options\n * @returns An object containing text, structured data, and debug information\n */\nexport async function processPdfFile(\n  file: File,\n  options: PDFParseOptions & {\n    textFormatting?: {\n      includePageNumbers?: boolean;\n      includeSummary?: boolean;\n      pagePrefix?: string;\n      pageSuffix?: string;\n    }\n  } = {}\n): Promise<{\n  text: string;\n  structured: PDFParseResult;\n  formattedText: string; // New property for AI-friendly text\n  debugInfo: string[];\n}> {\n  const debugInfo: string[] = [];\n  \n  // Validate file\n  if (!file || file.type !== 'application/pdf') {\n    throw new Error('Invalid file: Must be a PDF');\n  }\n  \n  debugInfo.push(`Processing PDF: ${file.name} (${(file.size / 1024).toFixed(2)} KB)`);\n  \n  try {\n    // Read the file as ArrayBuffer\n    const fileBuffer = await file.arrayBuffer();\n    debugInfo.push('File loaded as ArrayBuffer');\n    \n    // Create copies to prevent detachment issues\n    const textBuffer = fileBuffer.slice(0);\n    const structuredBuffer = fileBuffer.slice(0);\n    \n    // Ensure PDF.js is available\n    if (!PDFParser.isPdfJsAvailable()) {\n      debugInfo.push('PDF.js not available, loading from CDN...');\n      await PDFParser.loadPdfJsLibrary();\n      debugInfo.push('PDF.js loaded successfully');\n    }\n    \n    // Extract text\n    debugInfo.push('Extracting text from PDF...');\n    const text = await extractTextFromPdf(textBuffer, options);\n    debugInfo.push(`Text extracted successfully (${text.length} characters)`);\n    \n    // Extract structured data\n    debugInfo.push('Extracting structured data...');\n    const structured = await extractStructuredTextFromPdf(structuredBuffer, options);\n    debugInfo.push(`Structured data extracted (${structured.numPages} pages)`);\n    \n    // Create AI-friendly formatted text\n    debugInfo.push('Creating formatted text for AI...');\n    const formattedText = pdfToText(structured, options.textFormatting);\n    debugInfo.push(`Formatted text created (${formattedText.length} characters)`);\n    \n    return {\n      text,\n      structured,\n      formattedText,\n      debugInfo\n    };\n  } catch (error) {\n    debugInfo.push(`Error: ${error instanceof Error ? error.message : String(error)}`);\n    throw error;\n  }\n}\n","/**\n * CSV Parser for BrowserAI\n * Provides functionality to parse CSV files in browser environments\n */\n\n/**\n * Options for CSV parsing\n */\nexport interface CSVParseOptions {\n  /**\n   * Whether to include headers in the output (default: true)\n   */\n  includeHeaders?: boolean;\n  \n  /**\n   * Custom delimiter (default: \",\")\n   */\n  delimiter?: string;\n  \n  /**\n   * Whether to trim whitespace from values (default: true)\n   */\n  trimValues?: boolean;\n  \n  /**\n   * Whether to skip empty lines (default: true)\n   */\n  skipEmptyLines?: boolean;\n  \n  /**\n   * Custom quote character (default: '\"')\n   */\n  quoteChar?: string;\n  \n  /**\n   * Debug mode (default: false)\n   */\n  debug?: boolean;\n}\n\n/**\n * Result of CSV parsing\n */\nexport interface CSVParseResult {\n  /**\n   * Headers from the CSV file\n   */\n  headers: string[];\n  \n  /**\n   * Data rows as arrays of values\n   */\n  rows: string[][];\n  \n  /**\n   * Data as an array of objects (using headers as keys)\n   */\n  data: Record<string, string>[];\n  \n  /**\n   * Total number of rows (excluding headers if present)\n   */\n  rowCount: number;\n  \n  /**\n   * Total number of columns\n   */\n  columnCount: number;\n  \n  /**\n   * Any errors encountered during parsing\n   */\n  errors?: string[];\n  \n  /**\n   * Debug information\n   */\n  debugInfo?: string[];\n}\n\n/**\n * CSV Parser class\n */\nexport class CSVParser {\n  /**\n   * Parse CSV content from a string\n   * @param content CSV content as string\n   * @param options Parsing options\n   * @returns Parsed CSV data\n   */\n  static parseFromString(content: string, options: CSVParseOptions = {}): CSVParseResult {\n    const debugInfo: string[] = options.debug ? ['Parsing CSV from string'] : [];\n    const errors: string[] = [];\n    \n    // Set default options\n    const delimiter = options.delimiter || ',';\n    const quoteChar = options.quoteChar || '\"';\n    const includeHeaders = options.includeHeaders !== false;\n    const trimValues = options.trimValues !== false;\n    const skipEmptyLines = options.skipEmptyLines !== false;\n    \n    if (options.debug) {\n      debugInfo.push(`Options: delimiter=\"${delimiter}\", quoteChar=\"${quoteChar}\", includeHeaders=${includeHeaders}, trimValues=${trimValues}, skipEmptyLines=${skipEmptyLines}`);\n    }\n    \n    try {\n      // Split content into lines\n      let lines = content.split(/\\r?\\n/);\n      \n      if (skipEmptyLines) {\n        lines = lines.filter(line => line.trim() !== '');\n      }\n      \n      if (options.debug) {\n        debugInfo.push(`Found ${lines.length} lines in CSV`);\n      }\n      \n      if (lines.length === 0) {\n        errors.push('CSV content is empty');\n        return {\n          headers: [],\n          rows: [],\n          data: [],\n          rowCount: 0,\n          columnCount: 0,\n          errors,\n          debugInfo\n        };\n      }\n      \n      // Parse lines into rows\n      const rows: string[][] = [];\n      for (let i = 0; i < lines.length; i++) {\n        const line = lines[i];\n        const row = this.parseLine(line, delimiter, quoteChar, trimValues);\n        rows.push(row);\n      }\n      \n      // Extract headers and data\n      let headers: string[] = [];\n      let data: Record<string, string>[] = [];\n      \n      if (includeHeaders && rows.length > 0) {\n        headers = rows[0];\n        const dataRows = rows.slice(1);\n        \n        // Convert to array of objects\n        data = dataRows.map(row => {\n          const obj: Record<string, string> = {};\n          headers.forEach((header, index) => {\n            obj[header] = index < row.length ? row[index] : '';\n          });\n          return obj;\n        });\n      } else {\n        // No headers, use indices as keys\n        data = rows.map(row => {\n          const obj: Record<string, string> = {};\n          row.forEach((value, index) => {\n            obj[`column${index + 1}`] = value;\n          });\n          return obj;\n        });\n      }\n      \n      const columnCount = rows.length > 0 ? rows[0].length : 0;\n      const rowCount = includeHeaders && rows.length > 0 ? rows.length - 1 : rows.length;\n      \n      if (options.debug) {\n        debugInfo.push(`Parsed ${rowCount} data rows with ${columnCount} columns`);\n      }\n      \n      return {\n        headers,\n        rows: includeHeaders && rows.length > 0 ? rows.slice(1) : rows,\n        data,\n        rowCount,\n        columnCount,\n        errors: errors.length > 0 ? errors : undefined,\n        debugInfo: options.debug ? debugInfo : undefined\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n      errors.push(`Error parsing CSV: ${errorMessage}`);\n      \n      if (options.debug) {\n        debugInfo.push(`Error: ${errorMessage}`);\n      }\n      \n      return {\n        headers: [],\n        rows: [],\n        data: [],\n        rowCount: 0,\n        columnCount: 0,\n        errors,\n        debugInfo: options.debug ? debugInfo : undefined\n      };\n    }\n  }\n  \n  /**\n   * Parse a single CSV line into an array of values\n   */\n  private static parseLine(line: string, delimiter: string, quoteChar: string, trimValues: boolean): string[] {\n    const values: string[] = [];\n    let currentValue = '';\n    let inQuotes = false;\n    \n    for (let i = 0; i < line.length; i++) {\n      const char = line[i];\n      const nextChar = i < line.length - 1 ? line[i + 1] : '';\n      \n      if (char === quoteChar) {\n        if (inQuotes && nextChar === quoteChar) {\n          // Escaped quote\n          currentValue += quoteChar;\n          i++; // Skip the next quote\n        } else {\n          // Toggle quote mode\n          inQuotes = !inQuotes;\n        }\n      } else if (char === delimiter && !inQuotes) {\n        // End of value\n        values.push(trimValues ? currentValue.trim() : currentValue);\n        currentValue = '';\n      } else {\n        // Add character to current value\n        currentValue += char;\n      }\n    }\n    \n    // Add the last value\n    values.push(trimValues ? currentValue.trim() : currentValue);\n    \n    return values;\n  }\n  \n  /**\n   * Parse CSV from a File object\n   * @param file CSV file\n   * @param options Parsing options\n   * @returns Promise resolving to parsed CSV data\n   */\n  static async parseFromFile(file: File, options: CSVParseOptions = {}): Promise<CSVParseResult> {\n    const debugInfo: string[] = options.debug ? [`Parsing CSV file: ${file.name} (${(file.size / 1024).toFixed(2)} KB)`] : [];\n    \n    try {\n      const text = await file.text();\n      \n      if (options.debug) {\n        debugInfo.push(`File loaded as text, length: ${text.length} characters`);\n      }\n      \n      const result = this.parseFromString(text, options);\n      \n      if (options.debug && debugInfo.length > 0) {\n        result.debugInfo = [...debugInfo, ...(result.debugInfo || [])];\n      }\n      \n      return result;\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n      \n      if (options.debug) {\n        debugInfo.push(`Error reading file: ${errorMessage}`);\n      }\n      \n      return {\n        headers: [],\n        rows: [],\n        data: [],\n        rowCount: 0,\n        columnCount: 0,\n        errors: [`Error reading CSV file: ${errorMessage}`],\n        debugInfo: options.debug ? debugInfo : undefined\n      };\n    }\n  }\n}\n\n/**\n * Converts parsed CSV data to a formatted text string\n * @param csvData The parsed CSV data\n * @param options Formatting options\n * @returns Formatted text representation of the CSV data\n */\nexport function csvToText(\n  csvData: CSVParseResult,\n  options: {\n    includeHeaders?: boolean;\n    columnSeparator?: string;\n    rowSeparator?: string;\n    maxRows?: number;\n    maxColumnWidth?: number;\n  } = {}\n): string {\n  // Default options\n  const includeHeaders = options.includeHeaders !== false;\n  const columnSeparator = options.columnSeparator || ' | ';\n  const rowSeparator = options.rowSeparator || '\\n';\n  const maxRows = options.maxRows || Infinity;\n  const maxColumnWidth = options.maxColumnWidth || 50;\n  \n  // Function to truncate long values\n  const truncate = (value: string): string => {\n    if (value.length <= maxColumnWidth) return value;\n    return value.substring(0, maxColumnWidth - 3) + '...';\n  };\n  \n  const lines: string[] = [];\n  \n  // Add headers if requested\n  if (includeHeaders && csvData.headers.length > 0) {\n    lines.push(csvData.headers.map(h => truncate(h)).join(columnSeparator));\n    \n    // Add separator line\n    if (csvData.headers.length > 0) {\n      const separatorLine = csvData.headers.map(() => '-'.repeat(10)).join(columnSeparator);\n      lines.push(separatorLine);\n    }\n  }\n  \n  // Add data rows\n  const rowsToInclude = Math.min(csvData.rows.length, maxRows);\n  for (let i = 0; i < rowsToInclude; i++) {\n    const row = csvData.rows[i];\n    lines.push(row.map(cell => truncate(cell)).join(columnSeparator));\n  }\n  \n  // Add indication if rows were truncated\n  if (csvData.rows.length > maxRows) {\n    lines.push(`... (${csvData.rows.length - maxRows} more rows)`);\n  }\n  \n  // Add summary\n  lines.push('');\n  lines.push(`CSV Summary: ${csvData.rowCount} rows, ${csvData.columnCount} columns`);\n  \n  return lines.join(rowSeparator);\n}\n\n/**\n * Extract text representation from a CSV file\n * @param source CSV content as string or File\n * @param options Parsing and formatting options\n * @returns Promise resolving to text representation of the CSV\n */\nexport async function extractTextFromCSV(\n  source: string | File,\n  options: CSVParseOptions & {\n    textFormatting?: {\n      includeHeaders?: boolean;\n      columnSeparator?: string;\n      rowSeparator?: string;\n      maxRows?: number;\n      maxColumnWidth?: number;\n    }\n  } = {}\n): Promise<string> {\n  try {\n    let result: CSVParseResult;\n    \n    if (typeof source === 'string') {\n      result = CSVParser.parseFromString(source, options);\n    } else {\n      result = await CSVParser.parseFromFile(source, options);\n    }\n    \n    // Convert to text\n    return csvToText(result, options.textFormatting);\n  } catch (error) {\n    console.error('Error extracting text from CSV:', error);\n    return `Error extracting text from CSV: ${error instanceof Error ? error.message : String(error)}`;\n  }\n}\n\n/**\n * Processes a CSV file and returns both structured data and text representation\n * @param file The CSV file to process\n * @param options Parsing and formatting options\n * @returns Promise resolving to processed CSV data\n */\nexport async function processCSVFile(\n  file: File,\n  options: CSVParseOptions & {\n    textFormatting?: {\n      includeHeaders?: boolean;\n      columnSeparator?: string;\n      rowSeparator?: string;\n      maxRows?: number;\n      maxColumnWidth?: number;\n    }\n  } = {}\n): Promise<{\n  parsed: CSVParseResult;\n  text: string;\n  debugInfo: string[];\n}> {\n  const debugInfo: string[] = [];\n  \n  // Validate file\n  if (!file || (!file.name.toLowerCase().endsWith('.csv') && file.type !== 'text/csv')) {\n    throw new Error('Invalid file: Must be a CSV file');\n  }\n  \n  debugInfo.push(`Processing CSV: ${file.name} (${(file.size / 1024).toFixed(2)} KB)`);\n  \n  try {\n    // Parse the CSV file\n    debugInfo.push('Parsing CSV file...');\n    const parsed = await CSVParser.parseFromFile(file, {\n      ...options,\n      debug: true // Force debug for internal use\n    });\n    \n    debugInfo.push(`CSV parsed successfully: ${parsed.rowCount} rows, ${parsed.columnCount} columns`);\n    \n    if (parsed.debugInfo) {\n      debugInfo.push(...parsed.debugInfo);\n    }\n    \n    // Convert to text\n    debugInfo.push('Converting CSV to text format...');\n    const text = csvToText(parsed, options.textFormatting);\n    debugInfo.push(`Text conversion complete: ${text.length} characters`);\n    \n    return {\n      parsed,\n      text,\n      debugInfo\n    };\n  } catch (error) {\n    debugInfo.push(`Error: ${error instanceof Error ? error.message : String(error)}`);\n    throw error;\n  }\n}\n\n/**\n * Extract data from a CSV file as an array of objects\n * @param source CSV content as string or File\n * @param options Parsing options\n * @returns Promise resolving to array of objects\n */\nexport async function extractDataFromCSV(\n  source: string | File,\n  options: CSVParseOptions = {}\n): Promise<Record<string, string>[]> {\n  try {\n    let result: CSVParseResult;\n    \n    if (typeof source === 'string') {\n      result = CSVParser.parseFromString(source, options);\n    } else {\n      result = await CSVParser.parseFromFile(source, options);\n    }\n    \n    return result.data;\n  } catch (error) {\n    console.error('Error extracting data from CSV:', error);\n    return [];\n  }\n} ","/**\n * DOCX Parser for BrowserAI\n * Provides functionality to parse DOCX files in browser environments\n */\n\nimport mammoth from 'mammoth';\n\n/**\n * Options for DOCX parsing\n */\nexport interface DOCXParseOptions {\n  /**\n   * Whether to extract images (default: false)\n   */\n  extractImages?: boolean;\n  \n  /**\n   * Whether to preserve styles (default: false)\n   */\n  preserveStyles?: boolean;\n  \n  /**\n   * Whether to include headers and footers (default: true)\n   */\n  includeHeadersFooters?: boolean;\n  \n  /**\n   * Whether to extract document properties (default: false)\n   */\n  extractProperties?: boolean;\n  \n  /**\n   * Debug mode (default: false)\n   */\n  debug?: boolean;\n}\n\n/**\n * Result of DOCX parsing\n */\nexport interface DOCXParseResult {\n  /**\n   * The extracted text content\n   */\n  text: string;\n  \n  /**\n   * HTML representation of the document\n   */\n  html: string;\n  \n  /**\n   * Document properties (if extracted)\n   */\n  properties?: Record<string, string>;\n  \n  /**\n   * Document structure information\n   */\n  structure?: {\n    paragraphs: number;\n    tables: number;\n    images: number;\n    sections: number;\n  };\n  \n  /**\n   * Any errors encountered during parsing\n   */\n  errors?: string[];\n  \n  /**\n   * Debug information\n   */\n  debugInfo?: string[];\n}\n\n/**\n * DOCX Parser class\n */\nexport class DOCXParser {\n  /**\n   * Parse DOCX from a File object\n   * @param file DOCX file\n   * @param options Parsing options\n   * @returns Promise resolving to parsed DOCX data\n   */\n  static async parseFromFile(file: File, options: DOCXParseOptions = {}): Promise<DOCXParseResult> {\n    const debugInfo: string[] = options.debug ? [`Parsing DOCX file: ${file.name} (${(file.size / 1024).toFixed(2)} KB)`] : [];\n    const errors: string[] = [];\n    \n    try {\n      // Read the file as ArrayBuffer\n      const arrayBuffer = await file.arrayBuffer();\n      \n      if (options.debug) {\n        debugInfo.push(`File loaded as ArrayBuffer, size: ${arrayBuffer.byteLength} bytes`);\n      }\n      \n      // Configure mammoth options\n      const mammothOptions: any = {\n        includeDefaultStyleMap: options.preserveStyles !== false,\n        includeEmbeddedStyleMap: options.preserveStyles !== false,\n        convertImage: options.extractImages ? mammoth.images.imgElement : undefined,\n        includeHeader: options.includeHeadersFooters !== false,\n        includeFooter: options.includeHeadersFooters !== false\n      };\n      \n      if (options.debug) {\n        debugInfo.push(`Mammoth options: ${JSON.stringify(mammothOptions)}`);\n      }\n      \n      // Convert DOCX to HTML\n      const result = await mammoth.convertToHtml({ arrayBuffer }, mammothOptions);\n      \n      if (options.debug) {\n        debugInfo.push(`Conversion to HTML complete, HTML length: ${result.value.length} characters`);\n        if (result.messages.length > 0) {\n          debugInfo.push(`Conversion messages: ${JSON.stringify(result.messages)}`);\n        }\n      }\n      \n      // Add any warnings to errors\n      result.messages.forEach(message => {\n        if (message.type === 'warning') {\n          errors.push(message.message);\n        }\n      });\n      \n      // Extract text from HTML\n      const text = this.extractTextFromHtml(result.value);\n      \n      if (options.debug) {\n        debugInfo.push(`Text extracted from HTML, length: ${text.length} characters`);\n      }\n      \n      // Extract document structure information\n      const structure = this.extractStructure(result.value);\n      \n      if (options.debug) {\n        debugInfo.push(`Document structure extracted: ${JSON.stringify(structure)}`);\n      }\n      \n      // Extract document properties if requested\n      let properties: Record<string, string> | undefined;\n      if (options.extractProperties) {\n        try {\n          properties = await this.extractProperties(arrayBuffer);\n          if (options.debug) {\n            debugInfo.push(`Document properties extracted: ${JSON.stringify(properties)}`);\n          }\n        } catch (error) {\n          const errorMessage = error instanceof Error ? error.message : String(error);\n          errors.push(`Failed to extract document properties: ${errorMessage}`);\n          if (options.debug) {\n            debugInfo.push(`Error extracting properties: ${errorMessage}`);\n          }\n        }\n      }\n      \n      return {\n        text,\n        html: result.value,\n        properties,\n        structure,\n        errors: errors.length > 0 ? errors : undefined,\n        debugInfo: options.debug ? debugInfo : undefined\n      };\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n      errors.push(`Error parsing DOCX: ${errorMessage}`);\n      \n      if (options.debug) {\n        debugInfo.push(`Error: ${errorMessage}`);\n      }\n      \n      return {\n        text: '',\n        html: '',\n        structure: { paragraphs: 0, tables: 0, images: 0, sections: 0 },\n        errors,\n        debugInfo: options.debug ? debugInfo : undefined\n      };\n    }\n  }\n  \n  /**\n   * Extract text from HTML\n   * @param html HTML content\n   * @returns Plain text\n   */\n  private static extractTextFromHtml(html: string): string {\n    // Create a DOM parser\n    const parser = new DOMParser();\n    const doc = parser.parseFromString(html, 'text/html');\n    \n    // Extract text\n    return doc.body.textContent || '';\n  }\n  \n  /**\n   * Extract document structure information\n   * @param html HTML content\n   * @returns Structure information\n   */\n  private static extractStructure(html: string): DOCXParseResult['structure'] {\n    // Create a DOM parser\n    const parser = new DOMParser();\n    const doc = parser.parseFromString(html, 'text/html');\n    \n    return {\n      paragraphs: doc.querySelectorAll('p').length,\n      tables: doc.querySelectorAll('table').length,\n      images: doc.querySelectorAll('img').length,\n      sections: doc.querySelectorAll('section, div.section').length\n    };\n  }\n  \n  /**\n   * Extract document properties\n   * @param arrayBuffer Document as ArrayBuffer\n   * @returns Document properties\n   */\n  private static async extractProperties(arrayBuffer: ArrayBuffer): Promise<Record<string, string>> {\n    // This is a simplified version - mammoth doesn't directly expose properties\n    // For a full implementation, you might need to use another library or parse the DOCX XML\n    \n    // Use the arrayBuffer parameter to avoid the TS6133 error\n    const size = arrayBuffer.byteLength;\n    \n    return {\n      note: 'Document properties extraction is limited in this version',\n      fileSize: `${(size / 1024).toFixed(2)} KB`\n    };\n  }\n  \n  /**\n   * Check if the file is a valid DOCX file\n   * @param file File to check\n   * @returns True if the file is a valid DOCX file\n   */\n  static isValidDocxFile(file: File): boolean {\n    return (\n      file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||\n      file.name.toLowerCase().endsWith('.docx')\n    );\n  }\n  \n  /**\n   * Check if the file is a valid DOC file\n   * @param file File to check\n   * @returns True if the file is a valid DOC file\n   */\n  static isValidDocFile(file: File): boolean {\n    return (\n      file.type === 'application/msword' ||\n      file.name.toLowerCase().endsWith('.doc')\n    );\n  }\n}\n\n/**\n * Formats DOCX content for AI consumption\n * @param result The parsed DOCX result\n * @param options Formatting options\n * @returns Formatted text representation of the DOCX\n */\nexport function docxToText(\n  result: DOCXParseResult,\n  options: {\n    includeSummary?: boolean;\n    includeStructure?: boolean;\n    includeProperties?: boolean;\n  } = {}\n): string {\n  // Default options\n  const includeSummary = options.includeSummary !== false;\n  // Make these false by default\n  const includeStructure = options.includeStructure === true;\n  const includeProperties = options.includeProperties === true;\n  \n  const lines: string[] = [];\n  \n  // Add the main text content\n  lines.push(result.text);\n  \n  // Add a brief summary if requested\n  if (includeSummary) {\n    lines.push('');\n    lines.push('--- Document Summary ---');\n    if (result.structure) {\n      lines.push(`Document contains approximately ${result.structure.paragraphs} paragraphs of text.`);\n      if (result.structure.tables > 0) {\n        lines.push(`Document includes ${result.structure.tables} tables.`);\n      }\n      if (result.structure.images > 0) {\n        lines.push(`Document contains ${result.structure.images} images (not included in text).`);\n      }\n    }\n  }\n  \n  // Add document structure information only if explicitly requested\n  if (includeStructure && result.structure) {\n    lines.push('');\n    lines.push('--- Document Structure ---');\n    lines.push(`Paragraphs: ${result.structure.paragraphs}`);\n    lines.push(`Tables: ${result.structure.tables}`);\n    lines.push(`Images: ${result.structure.images}`);\n    lines.push(`Sections: ${result.structure.sections}`);\n  }\n  \n  // Add document properties only if explicitly requested\n  if (includeProperties && result.properties) {\n    lines.push('');\n    lines.push('--- Document Properties ---');\n    for (const [key, value] of Object.entries(result.properties)) {\n      lines.push(`${key}: ${value}`);\n    }\n  }\n  \n  return lines.join('\\n');\n}\n\n/**\n * Extract text from a DOCX file\n * @param file DOCX file\n * @param options Parsing options\n * @returns Promise resolving to extracted text\n */\nexport async function extractTextFromDOCX(\n  file: File,\n  options: DOCXParseOptions = {}\n): Promise<string> {\n  try {\n    const result = await DOCXParser.parseFromFile(file, options);\n    return result.text;\n  } catch (error) {\n    console.error('Error extracting text from DOCX:', error);\n    return `Error extracting text from DOCX: ${error instanceof Error ? error.message : String(error)}`;\n  }\n}\n\n/**\n * Processes a DOCX file and returns both structured data and text representation\n * @param file The DOCX file to process\n * @param options Parsing and formatting options\n * @returns Promise resolving to processed DOCX data\n */\nexport async function processDOCXFile(\n  file: File,\n  options: DOCXParseOptions & {\n    textFormatting?: {\n      includeSummary?: boolean;\n      includeStructure?: boolean;\n      includeProperties?: boolean;\n    }\n  } = {}\n): Promise<{\n  parsed: DOCXParseResult;\n  text: string;\n  formattedText: string;\n  debugInfo: string[];\n}> {\n  const debugInfo: string[] = [];\n  \n  // Validate file\n  if (!file || (!DOCXParser.isValidDocxFile(file) && !DOCXParser.isValidDocFile(file))) {\n    throw new Error('Invalid file: Must be a DOC or DOCX file');\n  }\n  \n  debugInfo.push(`Processing document: ${file.name} (${(file.size / 1024).toFixed(2)} KB)`);\n  \n  try {\n    // Parse the DOCX file\n    debugInfo.push('Parsing document file...');\n    const parsed = await DOCXParser.parseFromFile(file, {\n      ...options,\n      debug: true // Force debug for internal use\n    });\n    \n    debugInfo.push(`Document parsed successfully: ${parsed.text.length} characters of text`);\n    \n    if (parsed.debugInfo) {\n      debugInfo.push(...parsed.debugInfo);\n    }\n    \n    // Get the raw text\n    const text = parsed.text;\n    \n    // Create formatted text for AI with minimal metadata by default\n    debugInfo.push('Creating formatted text for AI...');\n    const formattedText = docxToText(parsed, {\n      includeSummary: options.textFormatting?.includeSummary !== false,\n      includeStructure: options.textFormatting?.includeStructure === true,\n      includeProperties: options.textFormatting?.includeProperties === true\n    });\n    debugInfo.push(`Formatted text created: ${formattedText.length} characters`);\n    \n    return {\n      parsed,\n      text,\n      formattedText,\n      debugInfo\n    };\n  } catch (error) {\n    debugInfo.push(`Error: ${error instanceof Error ? error.message : String(error)}`);\n    throw error;\n  }\n} ","import * as Tesseract from 'tesseract.js';\n\n/**\n * Options for image parsing\n */\nexport interface ImageParseOptions {\n  /**\n   * Language for OCR (default: 'eng')\n   */\n  language?: string;\n  \n  /**\n   * Whether to include confidence scores (default: false)\n   */\n  includeConfidence?: boolean;\n  \n  /**\n   * Debug mode (default: false)\n   */\n  debug?: boolean;\n}\n\n/**\n * Result of image parsing\n */\nexport interface ImageParseResult {\n  /**\n   * The extracted text content\n   */\n  text: string;\n  \n  /**\n   * Image properties\n   */\n  properties?: {\n    width: number;\n    height: number;\n    format: string;\n    size: number;\n  };\n  \n  /**\n   * OCR confidence score (0-100)\n   */\n  confidence?: number;\n  \n  /**\n   * Any errors encountered during parsing\n   */\n  errors?: string[];\n  \n  /**\n   * Debug information\n   */\n  debugInfo?: string[];\n  \n  /**\n   * Whether the image contains meaningful text\n   */\n  hasText?: boolean;\n}\n\n/**\n * Parser for image files (JPEG, PNG)\n */\nexport class ImageParser {\n  /**\n   * Parse text from an image file\n   */\n  static async parseFromFile(file: File, options: ImageParseOptions = {}): Promise<ImageParseResult> {\n    const debugInfo: string[] = [];\n    if (options.debug) debugInfo.push(`Starting image parsing: ${file.name}`);\n    \n    try {\n      // Check if we're in a Chrome extension environment\n      const isExtension = typeof window !== 'undefined' && \n                         typeof (window as any).chrome !== 'undefined' && \n                         (window as any).chrome.runtime && \n                         (window as any).chrome.runtime.id;\n      \n      let text = '';\n      let confidence = 0;\n      \n      if (isExtension) {\n        // For extensions, use a simpler approach without OCR\n        // You could implement a basic image description here\n        text = `[Image: ${file.name} (${file.type}, ${Math.round(file.size/1024)} KB)]`;\n        confidence = 100; // Not real OCR confidence\n      } else {\n        // Create a blob URL from the file\n        const imageUrl = URL.createObjectURL(file);\n        \n        try {\n          // Use the simpler scheduler API instead of worker API\n          const result = await Tesseract.recognize(\n            imageUrl,\n            options.language || 'eng',\n            {\n              logger: options.debug ? m => {\n                if (typeof m === 'object') {\n                  debugInfo.push(`Tesseract: status=${m.status}, progress=${m.progress || 0}`);\n                } else {\n                  debugInfo.push(`Tesseract: ${String(m)}`);\n                }\n              } : undefined\n            }\n          );\n          \n          text = result.data.text;\n          confidence = result.data.confidence;\n        } finally {\n          // Always clean up the URL\n          URL.revokeObjectURL(imageUrl);\n        }\n      }\n      \n      // Get image properties\n      const properties = await this.extractImageProperties(file);\n      \n      // Clean the text\n      const cleanedText = this.cleanOcrText(text);\n      \n      // Determine if the image has meaningful text\n      const hasText = this.hasActualText(cleanedText, confidence);\n      \n      return {\n        text: cleanedText,\n        properties,\n        confidence,\n        hasText,\n        debugInfo: options.debug ? debugInfo : undefined\n      };\n    } catch (error) {\n      const errorMessage = (error as Error).message;\n      if (options.debug) debugInfo.push(`Error: ${errorMessage}`);\n      \n      return {\n        text: `[Error processing image: ${errorMessage}]`,\n        hasText: false,\n        errors: [errorMessage],\n        debugInfo: options.debug ? debugInfo : undefined\n      };\n    }\n  }\n  \n  /**\n   * Extract properties from an image file\n   */\n  private static async extractImageProperties(file: File): Promise<ImageParseResult['properties']> {\n    return new Promise((resolve) => {\n      const img = new Image();\n      const objectUrl = URL.createObjectURL(file);\n      \n      img.onload = () => {\n        URL.revokeObjectURL(objectUrl);\n        resolve({\n          width: img.width,\n          height: img.height,\n          format: file.type.split('/')[1].toUpperCase(),\n          size: file.size\n        });\n      };\n      \n      img.onerror = () => {\n        URL.revokeObjectURL(objectUrl);\n        resolve({\n          width: 0,\n          height: 0,\n          format: file.type.split('/')[1].toUpperCase(),\n          size: file.size\n        });\n      };\n      \n      img.src = objectUrl;\n    });\n  }\n  \n  /**\n   * Check if a file is a valid image file\n   */\n  static isValidImageFile(file: File): boolean {\n    return file.type === 'image/jpeg' || \n           file.type === 'image/png' || \n           file.type === 'image/jpg';\n  }\n  \n  /**\n   * Clean OCR text by removing non-text symbols and noise\n   * @param text Raw OCR text\n   * @returns Cleaned text\n   */\n  private static cleanOcrText(text: string): string {\n    if (!text || text.trim().length === 0) {\n      return '';\n    }\n    \n    // Remove common OCR noise patterns\n    let cleaned = text\n      // Remove strings of special characters\n      .replace(/[^\\w\\s.,;:!?'\"()[\\]{}#@%&*+-=/<>|]{2,}/g, ' ')\n      // Remove isolated special characters\n      .replace(/\\s[^\\w\\s.,;:!?'\"()[\\]{}#@%&*+-=/<>|]\\s/g, ' ')\n      // Normalize whitespace\n      .replace(/\\s+/g, ' ')\n      .trim();\n    \n    return cleaned;\n  }\n  \n  /**\n   * Determines if extracted text is meaningful or just OCR noise\n   * @param text The extracted text\n   * @param confidence OCR confidence score\n   * @returns Whether the text is meaningful\n   */\n  private static hasActualText(text: string, confidence?: number): boolean {\n    // If text is empty after cleaning, it has no meaningful content\n    const cleaned = this.cleanOcrText(text);\n    if (!cleaned) {\n      return false;\n    }\n    \n    // Count actual words (3+ letters) vs. total tokens\n    const tokens = cleaned.split(/\\s+/);\n    const actualWords = tokens.filter(token => /^[a-zA-Z]{3,}$/.test(token));\n    \n    // Calculate the ratio of actual words to total tokens\n    const wordRatio = tokens.length > 0 ? actualWords.length / tokens.length : 0;\n    \n    // Check for random character distribution (a sign of noise)\n    const letters = cleaned.replace(/[^a-zA-Z]/g, '');\n    const singleLetterCount = (cleaned.match(/\\s[a-zA-Z]\\s/g) || []).length;\n    const singleLetterRatio = letters.length > 0 ? singleLetterCount / letters.length : 0;\n    \n    // If confidence is very low, it's likely noise\n    if (confidence !== undefined && confidence < 40) {\n      return false;\n    }\n    \n    // Check for common OCR noise patterns\n    const hasRandomSymbols = /[^\\w\\s.,;:!?'\"()[\\]{}#@%&*+-=/<>|]{2,}/.test(text);\n    const hasTooManySpecialChars = (text.match(/[^\\w\\s]/g) || []).length > text.length * 0.3;\n    const hasTooManySingleChars = singleLetterRatio > 0.2;\n    const hasLowWordRatio = wordRatio < 0.3;\n    \n    // Your example had lots of single letters and special characters\n    if (hasRandomSymbols && hasTooManySpecialChars && (hasTooManySingleChars || hasLowWordRatio)) {\n      return false;\n    }\n    \n    // Require a minimum number of actual words\n    return actualWords.length >= 3;\n  }\n}\n\n/**\n * Formats image OCR results for AI consumption\n */\nexport function imageToText(\n  result: ImageParseResult,\n  options: {\n    includeSummary?: boolean;\n  } = {}\n): string {\n  // Default options\n  const includeSummary = options.includeSummary !== false;\n  \n  const lines: string[] = [];\n  \n  // If no text was found, return a simple message\n  if (!result.text || result.text.trim().length === 0) {\n    if (includeSummary) {\n      return 'This image does not contain any readable text.';\n    }\n    return '';\n  }\n  \n  // Add the main text content\n  lines.push(result.text);\n  \n  // Add a brief summary if requested\n  if (includeSummary && result.properties) {\n    lines.push('');\n    lines.push('--- Image Summary ---');\n    lines.push(`Image dimensions: ${result.properties.width}x${result.properties.height} pixels`);\n    lines.push(`Image format: ${result.properties.format}`);\n    lines.push(`Image size: ${Math.round(result.properties.size / 1024)} KB`);\n    \n    if (result.confidence !== undefined) {\n      lines.push(`OCR confidence: ${result.confidence.toFixed(2)}%`);\n    }\n  }\n  \n  return lines.join('\\n');\n}\n\n/**\n * Extract text from an image file\n */\nexport async function extractTextFromImage(\n  file: File,\n  options: ImageParseOptions = {}\n): Promise<string> {\n  const result = await ImageParser.parseFromFile(file, options);\n  return result.text;\n}\n\n/**\n * Process an image file and return various representations\n */\nexport async function processImageFile(\n  file: File,\n  options: ImageParseOptions & {\n    textFormatting?: {\n      includeSummary?: boolean;\n    }\n  } = {}\n): Promise<{\n  parsed: ImageParseResult;\n  text: string;\n  formattedText: string;\n  debugInfo: string[];\n}> {\n  const debugInfo: string[] = [];\n  \n  if (options.debug) {\n    debugInfo.push(`Processing image file: ${file.name}`);\n  }\n  \n  // Parse the image file\n  debugInfo.push('Parsing image file...');\n  const parsed = await ImageParser.parseFromFile(file, options);\n  \n  if (parsed.debugInfo) {\n    debugInfo.push(...parsed.debugInfo);\n  }\n  \n  // Extract raw text\n  debugInfo.push('Extracting raw text...');\n  const text = parsed.text;\n  \n  // Create formatted text for AI\n  debugInfo.push('Creating formatted text for AI...');\n  const formattedText = imageToText(parsed, {\n    includeSummary: options.textFormatting?.includeSummary !== false\n  });\n  \n  return {\n    parsed,\n    text,\n    formattedText,\n    debugInfo\n  };\n}"],"mappings":"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AK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAK;AAAA,UAAK;AAAA,UAAK;AAAA,UAC1G;AAAA,UAAK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAK;AAAA,UAAK;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAK;AAAA,UAAI;AAAA,UAAK;AAAA,UAAI;AAAA,UAAK;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UACxG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UACxG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAC3G;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,QACvF;AAAA,QACA,KAAK;AAAA,QACL;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAW,SAAS;AAClB,QAAI,CAAC,KAAK,SAAS;AACjB,WAAK,UAAU;AAAA,QACb;AAAA,UACE;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAK;AAAA,UAAI;AAAA,UAAK;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UACvG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAC5G;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,QAChB;AAAA,QACA,KAAK;AAAA,QACL;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAW,OAAO;AAChB,QAAI,CAAC,KAAK,OAAO;AACf,WAAK,QAAQ;AAAA,QACX;AAAA,UACE;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAK;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UACxG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAK;AAAA,UAAK;AAAA,UAAK;AAAA,UAAK;AAAA,UAAK;AAAA,UAAK;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UACzG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UACzG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAC1G;AAAA,UAAK;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAG;AAAA,UAAG;AAAA,UAAI;AAAA,UAAG;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AAAA,UAAK;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAI;AAAA,UAAG;AA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","names":["url","count","path","path","self","url","path","min","max","len","j","i","Tensor","InferenceSession","Tensor","Tensor","slice","product","min","max","Tensor","Tensor","count","Tensor","mean","meanTensor","stdTensor","Tensor","len","n","Tensor","tokens","self","chunk","max","leftStart","leftStop","rightStart","rightStop","text","bannedTokens","CONTENT_TYPE_MAP","url","Tensor","data","path","path","Tensor","self","input_ids","Tensor","x","Tensor","Tensor","Tensor","spectrogram","Tensor","spectrogram","Tensor","url","spectrogram","window","mean","Tensor","path","Tensor","Tensor","mean","num_frames","num_channels","Tensor","mean","Tensor","Tensor","IMAGE_TOKEN","pixel_values","Tensor","Tensor","Tensor","i","window","Tensor","escapeRegExp","text","processed","url","Tensor","max","elements","options","patterns","url","path2","path","url","url","element","url"]}