{"version":3,"sources":["../src/files.ts","../src/auth.ts","../src/provider.ts","../src/config.ts","../src/transport-http.ts","../src/transport-ws.ts","../src/token-updates.ts"],"sourcesContent":["import type { TranscriptResult } from '@saraudio/core';\nimport { AuthenticationError, ProviderError, RateLimitError } from '@saraudio/core';\nimport type { Logger } from '@saraudio/utils';\nimport { mergeHeaders, normalizeHeaders, toArrayBuffer } from '@saraudio/utils';\n\nimport { resolveApiKey } from './auth';\nimport type { SonioxResolvedConfig } from './config';\nimport type {\n  SonioxHttpCreateTranscriptionRequest,\n  SonioxHttpTranscriptionResource,\n  SonioxHttpTranscriptResponse,\n  SonioxHttpUploadFileResponse,\n} from './SonioxHttpTranscriptionModel';\n\n/** Build Soniox REST base URL for a given path (uses resolved.httpBase). */\nfunction buildBase(resolved: SonioxResolvedConfig, path: string): string {\n  const base = resolved.httpBase.replace(/\\/?$/, '');\n  return `${base}${path.startsWith('/') ? '' : '/'}${path}`;\n}\n\n/** Upload raw audio bytes as a file to Soniox Files API. Returns file id. */\nexport async function sonioxUploadFile(\n  resolved: SonioxResolvedConfig,\n  audio: Blob | ArrayBuffer | Uint8Array,\n  opts?: { filename?: string; headers?: HeadersInit },\n  logger?: Logger,\n): Promise<SonioxHttpUploadFileResponse> {\n  const url = buildBase(resolved, '/files');\n  const token = await resolveApiKey(resolved.raw);\n\n  // When sending FormData, do NOT set content-type manually — let the browser/runtime set boundary.\n  const form = new FormData();\n  const filename = opts?.filename ?? 'audio.wav';\n  const body =\n    audio instanceof Blob ? audio : new Blob([await toArrayBuffer(audio)], { type: 'application/octet-stream' });\n  form.append('file', body, filename);\n\n  let headers: Record<string, string> = {};\n  const provided = opts?.headers;\n  if (provided) headers = mergeHeaders(headers, normalizeHeaders(provided));\n  headers.authorization = `Bearer ${token}`;\n\n  const res = await fetch(url, { method: 'POST', body: form, headers });\n  if (!res.ok) {\n    if (res.status === 401 || res.status === 403) throw new AuthenticationError('Unauthorized');\n    if (res.status === 429) {\n      const ra = res.headers.get('retry-after');\n      const ms = ra ? Number(ra) * 1000 : undefined;\n      throw new RateLimitError('Rate limited', ms);\n    }\n    const text = await res.text().catch(() => '');\n    logger?.error('soniox upload failed', { module: 'provider-soniox', status: res.status, text });\n    throw new ProviderError('Soniox upload error', 'soniox', undefined, res.status);\n  }\n  return (await res.json()) as SonioxHttpUploadFileResponse;\n}\n\n/** Create a transcription job for a given file id or audio URL. */\nexport async function sonioxCreateTranscription(\n  resolved: SonioxResolvedConfig,\n  request: SonioxHttpCreateTranscriptionRequest,\n  headersInit?: HeadersInit,\n): Promise<SonioxHttpTranscriptionResource> {\n  const url = buildBase(resolved, '/transcriptions');\n  const token = await resolveApiKey(resolved.raw);\n  let headers: Record<string, string> = { 'content-type': 'application/json' };\n  if (headersInit) headers = mergeHeaders(headers, normalizeHeaders(headersInit));\n  headers.authorization = `Bearer ${token}`;\n  const res = await fetch(url, { method: 'POST', headers, body: JSON.stringify(request) });\n  if (!res.ok) {\n    if (res.status === 401 || res.status === 403) throw new AuthenticationError('Unauthorized');\n    if (res.status === 429) {\n      const ra = res.headers.get('retry-after');\n      const ms = ra ? Number(ra) * 1000 : undefined;\n      throw new RateLimitError('Rate limited', ms);\n    }\n    throw new ProviderError('Soniox create transcription error', 'soniox', undefined, res.status);\n  }\n  return (await res.json()) as SonioxHttpTranscriptionResource;\n}\n\n/** Get transcription job resource by id. */\nexport async function sonioxGetTranscription(\n  resolved: SonioxResolvedConfig,\n  id: string,\n  headersInit?: HeadersInit,\n): Promise<SonioxHttpTranscriptionResource> {\n  const url = buildBase(resolved, `/transcriptions/${encodeURIComponent(id)}`);\n  const token = await resolveApiKey(resolved.raw);\n  let headers: Record<string, string> = {};\n  if (headersInit) headers = mergeHeaders(headers, normalizeHeaders(headersInit));\n  headers.authorization = `Bearer ${token}`;\n  const res = await fetch(url, { method: 'GET', headers });\n  if (!res.ok) throw new ProviderError('Soniox get transcription error', 'soniox', undefined, res.status);\n  return (await res.json()) as SonioxHttpTranscriptionResource;\n}\n\n/** Retrieve finalized transcript (text/tokens) for a job id. */\nexport async function sonioxGetTranscript(\n  resolved: SonioxResolvedConfig,\n  id: string,\n  headersInit?: HeadersInit,\n): Promise<SonioxHttpTranscriptResponse> {\n  const url = buildBase(resolved, `/transcriptions/${encodeURIComponent(id)}/transcript`);\n  const token = await resolveApiKey(resolved.raw);\n  let headers: Record<string, string> = {};\n  if (headersInit) headers = mergeHeaders(headers, normalizeHeaders(headersInit));\n  headers.authorization = `Bearer ${token}`;\n  const res = await fetch(url, { method: 'GET', headers });\n  if (!res.ok) throw new ProviderError('Soniox get transcript error', 'soniox', undefined, res.status);\n  return (await res.json()) as SonioxHttpTranscriptResponse;\n}\n\n/**\n * Convenience: upload → create job → poll until completed → fetch transcript → map to TranscriptResult.\n * Not used by live path; suitable for batch flows.\n */\nexport async function sonioxTranscribeFile(\n  resolved: SonioxResolvedConfig,\n  audio: Blob | ArrayBuffer | Uint8Array,\n  request: Omit<SonioxHttpCreateTranscriptionRequest, 'file_id' | 'audio_url'> & { filename?: string },\n  headersInit?: HeadersInit,\n  logger?: Logger,\n): Promise<TranscriptResult> {\n  const { filename, ...createRequest } = request;\n\n  const upload = await sonioxUploadFile(resolved, audio, { filename, headers: headersInit }, logger);\n  const job = await sonioxCreateTranscription(resolved, { ...createRequest, file_id: upload.id }, headersInit);\n  // Simple polling; in real apps consider webhooks.\n  let current = job;\n  const start = Date.now();\n  while (current.status !== 'completed' && current.status !== 'error') {\n    // basic backoff\n    const waited = Date.now() - start;\n    const sleep = Math.min(1000 + Math.floor(waited / 10), 5000);\n    await new Promise((r) => setTimeout(r, sleep));\n    current = await sonioxGetTranscription(resolved, job.id, headersInit);\n  }\n  if (current.status !== 'completed') {\n    throw new ProviderError(`Soniox job failed: ${current.error_message ?? 'unknown'}`, 'soniox');\n  }\n  const tr = await sonioxGetTranscript(resolved, job.id, headersInit);\n  const tokens = tr.tokens ?? [];\n  return {\n    text: tr.text ?? '',\n    words: tokens.map((t) => ({ word: t.text, startMs: t.start_ms, endMs: t.end_ms, confidence: t.confidence })),\n    metadata: { id: tr.id },\n  } satisfies TranscriptResult;\n}\n","import { AuthenticationError } from '@saraudio/core';\nimport type { SonioxOptions } from './types';\n\n/**\n * Resolve credential for Soniox.\n * Priority (to match Deepgram and encourage secure flows):\n * 1) getToken() → short‑lived token / temp API key\n * 2) token      → explicit bearer/token string\n * 3) apiKey     → long‑lived API key (server‑side)\n */\nexport async function resolveApiKey(options: SonioxOptions): Promise<string> {\n  const auth = options.auth;\n  if (auth?.getToken) {\n    const token = await auth.getToken();\n    if (typeof token === 'string' && token.length > 0) return token;\n  }\n  if (auth?.token && auth.token.length > 0) return auth.token;\n  if (auth?.apiKey && auth.apiKey.length > 0) return auth.apiKey;\n  throw new AuthenticationError('Soniox requires a tokenProvider, token, or apiKey');\n}\n","import { defineProvider } from '@saraudio/core';\nimport type { Logger } from '@saraudio/utils';\nimport { resolveConfig } from './config';\nimport { SonioxOptionsSchema } from './schema';\nimport { transcribeHTTP } from './transport-http';\nimport { createWsStream } from './transport-ws';\nimport type { SonioxOptions, SonioxProvider } from './types';\n\nexport function soniox(options: SonioxOptions): SonioxProvider {\n  const validated = SonioxOptionsSchema.parse(options);\n  const logger: Logger | undefined = validated.logger ? validated.logger.child('provider-soniox') : undefined;\n  let resolved = resolveConfig(validated);\n  const listeners = new Set<(opts: SonioxOptions) => void>();\n\n  return defineProvider({\n    id: 'soniox',\n    capabilities: {\n      partials: 'mutable',\n      words: true,\n      diarization: 'word',\n      language: 'final',\n      segments: false,\n      forceEndpoint: true,\n      multichannel: true,\n      translation: 'two_way',\n      transports: { http: true, websocket: true },\n    },\n    getPreferredFormat() {\n      return { encoding: 'pcm16', sampleRate: resolved.sampleRate, channels: resolved.channels } as const;\n    },\n    getSupportedFormats() {\n      return [\n        { encoding: 'pcm16', sampleRate: 16000, channels: 1 },\n        { encoding: 'pcm16', sampleRate: 16000, channels: 2 },\n        { encoding: 'pcm16', sampleRate: 8000, channels: 1 },\n      ] as const;\n    },\n    negotiateFormat(candidate) {\n      const sampleRate = candidate.sampleRate ?? resolved.sampleRate;\n      const channels = (candidate.channels ?? resolved.channels) as 1 | 2;\n      return { encoding: 'pcm16', sampleRate, channels } as const;\n    },\n    async update(next) {\n      const validatedNext = SonioxOptionsSchema.parse(next);\n      resolved = resolveConfig(validatedNext);\n      listeners.forEach((l) => l(validatedNext));\n    },\n    onUpdate(listener) {\n      listeners.add(listener);\n      return () => listeners.delete(listener);\n    },\n    stream() {\n      return createWsStream(resolved, logger);\n    },\n    async transcribe(audio, batchOptions, signal) {\n      return transcribeHTTP(resolved, audio, batchOptions, signal, logger);\n    },\n  });\n}\n","import { clamp, normalizeChannels } from '@saraudio/utils';\nimport type { SonioxOptions } from './types';\n\nexport const DEFAULT_WS_URL = 'wss://stt-rt.soniox.com/transcribe-websocket';\nexport const DEFAULT_HTTP_BASE = 'https://api.soniox.com/v1';\nexport const DEFAULT_SAMPLE_RATE = 16_000;\nexport const DEFAULT_CHANNELS: 1 | 2 = 1;\nexport const DEFAULT_QUEUE_BUDGET_MS = 200;\nexport const QUEUE_MIN_MS = 100;\nexport const QUEUE_MAX_MS = 500;\n// Soniox requires a keepalive message at least once every 20s when idle.\nexport const DEFAULT_WS_KEEPALIVE_MS = 15_000;\nexport const KEEPALIVE_MIN_MS = 1_000;\nexport const KEEPALIVE_MAX_MS = 18_000;\n\nexport interface SonioxResolvedConfig {\n  raw: SonioxOptions;\n  wsUrl: string;\n  httpBase: string;\n  sampleRate: number;\n  channels: 1 | 2;\n  audioFormat: string;\n  queueBudgetMs: number;\n  wsKeepaliveMs: number;\n}\n\n// clamp/normalizeChannels из @saraudio/utils\n\nexport function resolveConfig(options: SonioxOptions): SonioxResolvedConfig {\n  const sampleRate = options.sampleRate ?? DEFAULT_SAMPLE_RATE;\n  const channels = normalizeChannels(options.channels ?? DEFAULT_CHANNELS);\n  const audioFormat = options.audioFormat ?? 'pcm_s16le';\n  const queueBudgetMs = clamp(options.queueBudgetMs ?? DEFAULT_QUEUE_BUDGET_MS, QUEUE_MIN_MS, QUEUE_MAX_MS);\n  const wsKeepaliveMs = clamp(options.wsKeepaliveMs ?? DEFAULT_WS_KEEPALIVE_MS, KEEPALIVE_MIN_MS, KEEPALIVE_MAX_MS);\n  // Если задан baseUrl строкой, позволим ей переопределить дефолты транспорта, иначе оставим дефолты.\n  const base = options.baseUrl;\n  const wsUrl = typeof base === 'string' && base.startsWith('ws') ? base : DEFAULT_WS_URL;\n  const httpBase =\n    typeof base === 'string' && base.startsWith('http') && !base.startsWith('ws') ? base : DEFAULT_HTTP_BASE;\n  return {\n    raw: options,\n    wsUrl,\n    httpBase,\n    sampleRate,\n    channels,\n    audioFormat,\n    queueBudgetMs,\n    wsKeepaliveMs,\n  } satisfies SonioxResolvedConfig;\n}\n","import type { TranscriptResult } from '@saraudio/core';\nimport type { Logger } from '@saraudio/utils';\nimport { mergeHeaders, normalizeHeaders } from '@saraudio/utils';\nimport type { SonioxResolvedConfig } from './config';\nimport { sonioxTranscribeFile } from './files';\nimport type { SonioxHttpCreateTranscriptionRequest } from './SonioxHttpTranscriptionModel';\n\n// Minimal batch transcription via Soniox REST API.\n// Strategy: upload chunk → create job → poll → fetch transcript (batch flow).\n\nexport async function transcribeHTTP(\n  resolved: SonioxResolvedConfig,\n  audio: Blob | ArrayBuffer | Uint8Array,\n  _options?: { language?: string; diarization?: boolean },\n  _signal?: AbortSignal,\n  logger?: Logger,\n): Promise<TranscriptResult> {\n  const provided =\n    typeof resolved.raw.headers === 'function'\n      ? await resolved.raw.headers({ transport: 'http' })\n      : resolved.raw.headers;\n  const headers = provided ? mergeHeaders({}, normalizeHeaders(provided)) : undefined;\n\n  const translation: SonioxHttpCreateTranscriptionRequest['translation'] | undefined = resolved.raw.translation\n    ? resolved.raw.translation.type === 'one_way'\n      ? { type: 'one_way', target_language: resolved.raw.translation.targetLanguage }\n      : {\n          type: 'two_way',\n          language_a: resolved.raw.translation.languageA,\n          language_b: resolved.raw.translation.languageB,\n        }\n    : undefined;\n\n  return await sonioxTranscribeFile(\n    resolved,\n    audio,\n    {\n      model: resolved.raw.model,\n      language_hints: resolved.raw.languageHints,\n      language_hints_strict: resolved.raw.languageHintsStrict,\n      enable_speaker_diarization: resolved.raw.diarization,\n      enable_language_identification: resolved.raw.languageIdentification,\n      translation,\n    },\n    headers,\n    logger,\n  );\n}\n","import type { NormalizedFrame, TranscriptionStream, TranscriptToken, TranscriptUpdate } from '@saraudio/core';\nimport { AbortedError, AuthenticationError, NetworkError, ProviderError, RateLimitError } from '@saraudio/core';\nimport type { Logger } from '@saraudio/utils';\nimport { buildTransportUrl, frameDurationMs } from '@saraudio/utils';\nimport { resolveApiKey } from './auth';\nimport type { SonioxResolvedConfig } from './config';\nimport type {\n  SonioxWsErrorResponse,\n  SonioxWsFinishedResponse,\n  SonioxWsInitConfig,\n  SonioxWsStreamResponse,\n  SonioxWsToken,\n} from './SonioxWsRealtimeModel';\n\ntype StreamStatus = TranscriptionStream['status'];\ntype SonioxRawMessage = SonioxWsStreamResponse & Partial<SonioxWsFinishedResponse> & Partial<SonioxWsErrorResponse>;\n\nexport function createWsStream(resolved: SonioxResolvedConfig, logger?: Logger): TranscriptionStream {\n  let status: StreamStatus = 'idle';\n  const updateHandlers = new Set<(u: TranscriptUpdate) => void>();\n  const errorHandlers = new Set<(e: Error) => void>();\n  const statusHandlers = new Set<(s: StreamStatus) => void>();\n\n  let ws: WebSocket | null = null;\n  let connecting: Promise<void> | null = null;\n  let disconnecting: Promise<void> | null = null;\n  let closedByClient = false;\n  let keepaliveTimer: ReturnType<typeof setInterval> | null = null;\n  let lastActivityAtMs = 0;\n\n  const queue: { frame: NormalizedFrame<'pcm16'>; dur: number }[] = [];\n  let queuedMs = 0;\n\n  // logger is parameter\n  // Soniox can emit `speaker` as number or string. Our public contract uses numeric speaker ids.\n  // Map non-numeric labels to stable numeric ids for the lifetime of this stream.\n  const SPEAKER_LABEL_ID_BASE = 100;\n  const speakerLabelToId = new Map<string, number>();\n  const speakerIdToLabel = new Map<number, string>();\n\n  const normalizeSpeaker = (value: unknown): number | undefined => {\n    if (typeof value === 'number' && Number.isFinite(value)) {\n      return value;\n    }\n    if (typeof value === 'string') {\n      const trimmed = value.trim();\n      if (trimmed.length === 0) return undefined;\n      if (/^\\d+$/.test(trimmed)) {\n        const parsed = Number(trimmed);\n        return Number.isFinite(parsed) ? parsed : undefined;\n      }\n      const existing = speakerLabelToId.get(trimmed);\n      if (existing !== undefined) return existing;\n      const id = SPEAKER_LABEL_ID_BASE + speakerLabelToId.size;\n      speakerLabelToId.set(trimmed, id);\n      speakerIdToLabel.set(id, trimmed);\n      return id;\n    }\n    return undefined;\n  };\n\n  const setStatus = (next: StreamStatus): void => {\n    if (status === next) return;\n    status = next;\n    statusHandlers.forEach((h) => h(status));\n  };\n\n  const markActivity = (): void => {\n    lastActivityAtMs = Date.now();\n  };\n\n  const clearKeepalive = (): void => {\n    if (!keepaliveTimer) return;\n    clearInterval(keepaliveTimer);\n    keepaliveTimer = null;\n  };\n\n  const startKeepalive = (): void => {\n    clearKeepalive();\n    keepaliveTimer = setInterval(() => {\n      const socket = ws;\n      if (!socket || socket.readyState !== WebSocket.OPEN) return;\n      const idleMs = Date.now() - lastActivityAtMs;\n      if (idleMs < resolved.wsKeepaliveMs) return;\n      try {\n        socket.send(JSON.stringify({ type: 'keepalive' }));\n        markActivity();\n      } catch (err) {\n        logger?.warn('soniox keepalive send failed', {\n          module: 'provider-soniox',\n          error: err instanceof Error ? err.message : String(err),\n        });\n      }\n    }, resolved.wsKeepaliveMs);\n  };\n\n  const isSonioxRawMessage = (value: unknown): value is SonioxRawMessage => {\n    if (typeof value !== 'object' || value === null) return false;\n    const v = value as Record<string, unknown>;\n    if (v.tokens !== undefined && !Array.isArray(v.tokens)) return false;\n    return true;\n  };\n\n  const isMarker = (value: unknown): boolean => {\n    if (typeof value !== 'string') return false;\n    const s = value.trim();\n    return s.startsWith('<') && s.endsWith('>');\n  };\n\n  const createToken = (t: SonioxWsToken): TranscriptToken | null => {\n    const rawText = t.text;\n    if (isMarker(rawText)) return null;\n    const text = typeof rawText === 'string' ? rawText : '';\n    const token: TranscriptToken = { text, isFinal: t.is_final === true };\n\n    if (typeof t.start_ms === 'number' && Number.isFinite(t.start_ms)) token.startMs = Math.max(0, t.start_ms);\n    if (typeof t.end_ms === 'number' && Number.isFinite(t.end_ms)) token.endMs = Math.max(0, t.end_ms);\n    if (typeof t.confidence === 'number' && Number.isFinite(t.confidence)) token.confidence = t.confidence;\n\n    const speaker = normalizeSpeaker(t.speaker);\n    if (speaker !== undefined) token.speaker = speaker;\n\n    if (typeof t.language === 'string' && t.language.trim().length > 0) token.language = t.language;\n    if (typeof t.source_language === 'string' && t.source_language.trim().length > 0) {\n      token.translationSourceLanguage = t.source_language;\n    }\n    if (t.translation_status === 'translation') token.translationStatus = 'translation';\n\n    const tokenMetadata: Record<string, unknown> = {};\n    if (typeof t.language === 'string') tokenMetadata.language = t.language;\n    if (typeof t.source_language === 'string') tokenMetadata.sourceLanguage = t.source_language;\n    if (typeof t.translation_status === 'string') tokenMetadata.translationStatus = t.translation_status;\n    if (Object.keys(tokenMetadata).length > 0) token.metadata = tokenMetadata;\n\n    return token;\n  };\n\n  const resetQueue = (): void => {\n    queue.length = 0;\n    queuedMs = 0;\n  };\n\n  const flushQueue = (): void => {\n    const socket = ws;\n    if (!socket || socket.readyState !== WebSocket.OPEN) return;\n    while (queue.length > 0) {\n      const item = queue.shift();\n      if (!item) break;\n      const buf = item.frame.pcm.buffer.slice(0);\n      socket.send(buf);\n      markActivity();\n    }\n  };\n\n  const enqueue = (frame: NormalizedFrame<'pcm16'>): void => {\n    if (frame.pcm.length === 0) return;\n    const dur = frameDurationMs(frame.pcm.length, frame.sampleRate, frame.channels);\n    queue.push({ frame, dur });\n    queuedMs += dur;\n    while (queuedMs > resolved.queueBudgetMs && queue.length > 1) {\n      const dropped = queue.shift();\n      if (!dropped) break;\n      queuedMs = Math.max(0, queuedMs - dropped.dur);\n      logger?.warn('soniox send queue dropped oldest frame (backpressure)', { module: 'provider-soniox', queuedMs });\n    }\n    flushQueue();\n  };\n\n  const emitUpdate = (u: TranscriptUpdate): void => {\n    updateHandlers.forEach((h) => h(u));\n  };\n\n  const emitError = (e: Error): void => errorHandlers.forEach((h) => h(e));\n\n  const mapCloseReason = (code: number, reasonRaw: string): Error | null => {\n    // Soniox typically sends JSON with error_code/error_message in reason\n    try {\n      const parsed: unknown = reasonRaw ? JSON.parse(reasonRaw) : undefined;\n      if (typeof parsed !== 'object' || parsed === null) return null;\n      const status = (parsed as Record<string, unknown>).error_code;\n      const message = (parsed as Record<string, unknown>).error_message;\n      if (status === 401) return new AuthenticationError(typeof message === 'string' ? message : 'Unauthorized');\n      if (status === 429) return new RateLimitError(typeof message === 'string' ? message : 'Too Many Requests');\n      if (typeof status === 'number' && status >= 400) {\n        return new ProviderError(\n          typeof message === 'string' ? message : 'Provider error',\n          'soniox',\n          status,\n          status,\n          parsed,\n        );\n      }\n    } catch {\n      // ignore\n    }\n    if (code === 1006) return new NetworkError('Abnormal closure', true);\n    return null;\n  };\n\n  const handleMessage = (data: unknown): void => {\n    if (typeof data !== 'string') return;\n    let msg: SonioxRawMessage | null = null;\n    try {\n      const parsed: unknown = JSON.parse(data);\n      msg = isSonioxRawMessage(parsed) ? parsed : null;\n    } catch (err) {\n      logger?.warn('soniox message parse failed', {\n        module: 'provider-soniox',\n        error: err instanceof Error ? err.message : String(err),\n      });\n      return;\n    }\n    if (!msg) return;\n\n    if (typeof msg.error_code === 'number' && typeof msg.error_message === 'string') {\n      emitError(new ProviderError(msg.error_message, 'soniox', msg.error_code, msg.error_code, msg));\n      setStatus('error');\n      return;\n    }\n\n    const updateMetadata: Record<string, unknown> = {};\n    if (typeof msg.final_audio_proc_ms === 'number' && Number.isFinite(msg.final_audio_proc_ms)) {\n      updateMetadata.finalAudioProcMs = msg.final_audio_proc_ms;\n    }\n    if (typeof msg.total_audio_proc_ms === 'number' && Number.isFinite(msg.total_audio_proc_ms)) {\n      updateMetadata.totalAudioProcMs = msg.total_audio_proc_ms;\n    }\n    if (msg.finished === true) {\n      updateMetadata.finished = true;\n    }\n\n    const tokens: TranscriptToken[] = [];\n    let finalize = false;\n    if (msg.tokens && msg.tokens.length > 0) {\n      for (const t of msg.tokens) {\n        if (isMarker(t.text)) {\n          finalize = true;\n          continue;\n        }\n        const token = createToken(t);\n        if (token) tokens.push(token);\n      }\n    }\n\n    if (speakerIdToLabel.size > 0) {\n      const speakerLabels: Record<string, string> = {};\n      for (const [id, label] of speakerIdToLabel) {\n        speakerLabels[String(id)] = label;\n      }\n      updateMetadata.speakerLabels = speakerLabels;\n    }\n\n    const hasMetadata = Object.keys(updateMetadata).length > 0;\n    if (tokens.length > 0 || finalize || hasMetadata) {\n      const update: TranscriptUpdate = { providerId: 'soniox', tokens, raw: msg };\n      if (finalize) update.finalize = true;\n      if (hasMetadata) update.metadata = updateMetadata;\n      emitUpdate(update);\n    }\n\n    if (msg.finished === true) setStatus('disconnected');\n  };\n\n  const connect = async (signal?: AbortSignal): Promise<void> => {\n    if (connecting) return connecting;\n    if (signal?.aborted) throw new AbortedError('Soniox connect aborted');\n    setStatus('connecting');\n\n    connecting = (async () => {\n      // use resolved from args\n      const apiKey = await resolveApiKey(resolved.raw);\n      if (signal?.aborted) throw new AbortedError('Soniox connect aborted');\n\n      // Build URL: support baseUrl string or builder from BaseProviderOptions\n      const defaultBase = resolved.wsUrl;\n      const params = new URLSearchParams();\n      const rawQuery = resolved.raw.query;\n      if (rawQuery && Object.keys(rawQuery).length > 0) {\n        for (const [k, v] of Object.entries(rawQuery)) {\n          if (v === null || v === undefined) continue;\n          params.set(k, String(v));\n        }\n      }\n      const url = await buildTransportUrl(resolved.raw.baseUrl, defaultBase, params, 'websocket');\n      const wsProtocols = resolved.raw.wsProtocols?.map((protocol) => protocol.trim()).filter((protocol) => protocol);\n      const socket = wsProtocols && wsProtocols.length > 0 ? new WebSocket(url, wsProtocols) : new WebSocket(url);\n      ws = socket;\n      socket.binaryType = 'arraybuffer';\n      closedByClient = false;\n\n      const onOpen = (): void => {\n        // Send initial JSON config per Soniox protocol\n        const init: SonioxWsInitConfig = {\n          api_key: apiKey,\n          model: resolved.raw.model,\n          audio_format: resolved.audioFormat,\n          num_channels: resolved.channels,\n          sample_rate: resolved.sampleRate,\n          language_hints: resolved.raw.languageHints,\n        };\n        if (resolved.raw.languageHintsStrict === true) {\n          init.language_hints_strict = true;\n        }\n        if (resolved.raw.diarization === true) {\n          init.enable_speaker_diarization = true;\n        }\n        if (resolved.raw.endpointDetection === true) {\n          init.enable_endpoint_detection = true;\n        }\n        if (resolved.raw.languageIdentification === true) {\n          init.enable_language_identification = true;\n        }\n        if (resolved.raw.translation) {\n          if (resolved.raw.translation.type === 'one_way') {\n            init.translation = { type: 'one_way', target_language: resolved.raw.translation.targetLanguage };\n          } else {\n            init.translation = {\n              type: 'two_way',\n              language_a: resolved.raw.translation.languageA,\n              language_b: resolved.raw.translation.languageB,\n            };\n          }\n        }\n        try {\n          socket.send(JSON.stringify(init));\n          markActivity();\n        } catch (err) {\n          emitError(new NetworkError('Failed to send init', true, err));\n        }\n        startKeepalive();\n        setStatus('ready');\n        flushQueue();\n      };\n      const onMessage = (ev: MessageEvent): void => handleMessage(ev.data);\n      const onError = (): void => {\n        emitError(new NetworkError('Soniox WebSocket error', true));\n        setStatus('error');\n      };\n      const onClose = (ev: CloseEvent): void => {\n        const err = mapCloseReason(ev.code, String(ev.reason ?? ''));\n        clearKeepalive();\n        ws = null;\n        resetQueue();\n        setStatus('disconnected');\n        if (!closedByClient && err) emitError(err);\n      };\n\n      socket.addEventListener('open', onOpen);\n      socket.addEventListener('message', onMessage);\n      socket.addEventListener('error', onError);\n      socket.addEventListener('close', onClose);\n    })();\n\n    return connecting;\n  };\n\n  const disconnect = async (): Promise<void> => {\n    if (disconnecting) return disconnecting;\n    disconnecting = (async () => {\n      const socket = ws;\n      if (!socket) return;\n      try {\n        closedByClient = true;\n        clearKeepalive();\n        // Signal end of stream by sending zero‑length frame per Soniox docs\n        try {\n          socket.send(new ArrayBuffer(0));\n        } catch {}\n        socket.close(1000, 'client-close');\n      } finally {\n        ws = null;\n        resetQueue();\n      }\n    })();\n    return disconnecting;\n  };\n\n  const send = (frame: NormalizedFrame<'pcm16'>): void => {\n    enqueue(frame);\n  };\n\n  const forceEndpoint = async (): Promise<void> => {\n    const socket = ws;\n    if (!socket || socket.readyState !== WebSocket.OPEN) return;\n    try {\n      socket.send(JSON.stringify({ type: 'finalize' }));\n      markActivity();\n    } catch {}\n  };\n\n  return {\n    get status() {\n      return status;\n    },\n    async connect(signal?: AbortSignal) {\n      return connect(signal);\n    },\n    async disconnect() {\n      return disconnect();\n    },\n    send,\n    forceEndpoint,\n    onUpdate(handler) {\n      updateHandlers.add(handler);\n      return () => updateHandlers.delete(handler);\n    },\n    onError(handler) {\n      errorHandlers.add(handler);\n      return () => errorHandlers.delete(handler);\n    },\n    onStatusChange(handler) {\n      statusHandlers.add(handler);\n      return () => statusHandlers.delete(handler);\n    },\n  };\n}\n","import type { TranscriptToken, TranscriptUpdate } from '@saraudio/core';\nimport type { SonioxWsErrorResponse, SonioxWsFinishedResponse, SonioxWsStreamResponse } from './SonioxWsRealtimeModel';\n\nexport type SonioxRawMessage = SonioxWsStreamResponse | SonioxWsFinishedResponse | SonioxWsErrorResponse;\n\nexport type SonioxTokenMetadata = {\n  language?: string;\n  sourceLanguage?: string;\n  translationStatus?: string;\n};\n\nexport type SonioxUpdateMetadata = {\n  finalAudioProcMs?: number;\n  totalAudioProcMs?: number;\n  finished?: boolean;\n  speakerLabels?: Record<string, string>;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null;\n\nexport const isSonioxUpdate = (\n  update: TranscriptUpdate,\n): update is TranscriptUpdate & { providerId: 'soniox'; metadata?: SonioxUpdateMetadata; raw?: SonioxRawMessage } =>\n  update.providerId === 'soniox';\n\nexport const asSonioxTokenMetadata = (token: TranscriptToken): SonioxTokenMetadata | null => {\n  if (!isRecord(token.metadata)) return null;\n  const language = typeof token.metadata.language === 'string' ? token.metadata.language : undefined;\n  const sourceLanguage = typeof token.metadata.sourceLanguage === 'string' ? token.metadata.sourceLanguage : undefined;\n  const translationStatus =\n    typeof token.metadata.translationStatus === 'string' ? token.metadata.translationStatus : undefined;\n\n  if (!language && !sourceLanguage && !translationStatus) return null;\n  return { language, sourceLanguage, translationStatus };\n};\n\nexport const asSonioxUpdateMetadata = (update: TranscriptUpdate): SonioxUpdateMetadata | null => {\n  if (!isRecord(update.metadata)) return null;\n  const finalAudioProcMs =\n    typeof update.metadata.finalAudioProcMs === 'number' ? update.metadata.finalAudioProcMs : undefined;\n  const totalAudioProcMs =\n    typeof update.metadata.totalAudioProcMs === 'number' ? update.metadata.totalAudioProcMs : undefined;\n  const finished = update.metadata.finished === true ? true : undefined;\n\n  let speakerLabels: Record<string, string> | undefined;\n  if (isRecord(update.metadata.speakerLabels)) {\n    const mapped: Record<string, string> = {};\n    for (const [k, v] of Object.entries(update.metadata.speakerLabels)) {\n      if (typeof v === 'string') mapped[k] = v;\n    }\n    if (Object.keys(mapped).length > 0) speakerLabels = mapped;\n  }\n\n  if (\n    finalAudioProcMs === undefined &&\n    totalAudioProcMs === undefined &&\n    finished === undefined &&\n    speakerLabels === undefined\n  )\n    return null;\n  return { finalAudioProcMs, totalAudioProcMs, finished, speakerLabels };\n};\n"],"mappings":";;;;;;;;AACA,SAAS,uBAAAA,sBAAqB,eAAe,sBAAsB;AAEnE,SAAS,cAAc,kBAAkB,qBAAqB;;;ACH9D,SAAS,2BAA2B;AAUpC,eAAsB,cAAc,SAAyC;AAC3E,QAAM,OAAO,QAAQ;AACrB,MAAI,MAAM,UAAU;AAClB,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,QAAI,OAAO,UAAU,YAAY,MAAM,SAAS,EAAG,QAAO;AAAA,EAC5D;AACA,MAAI,MAAM,SAAS,KAAK,MAAM,SAAS,EAAG,QAAO,KAAK;AACtD,MAAI,MAAM,UAAU,KAAK,OAAO,SAAS,EAAG,QAAO,KAAK;AACxD,QAAM,IAAI,oBAAoB,mDAAmD;AACnF;;;ADJA,SAAS,UAAU,UAAgC,MAAsB;AACvE,QAAM,OAAO,SAAS,SAAS,QAAQ,QAAQ,EAAE;AACjD,SAAO,GAAG,IAAI,GAAG,KAAK,WAAW,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI;AACzD;AAGA,eAAsB,iBACpB,UACA,OACA,MACA,QACuC;AACvC,QAAM,MAAM,UAAU,UAAU,QAAQ;AACxC,QAAM,QAAQ,MAAM,cAAc,SAAS,GAAG;AAG9C,QAAM,OAAO,IAAI,SAAS;AAC1B,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,OACJ,iBAAiB,OAAO,QAAQ,IAAI,KAAK,CAAC,MAAM,cAAc,KAAK,CAAC,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAC7G,OAAK,OAAO,QAAQ,MAAM,QAAQ;AAElC,MAAI,UAAkC,CAAC;AACvC,QAAM,WAAW,MAAM;AACvB,MAAI,SAAU,WAAU,aAAa,SAAS,iBAAiB,QAAQ,CAAC;AACxE,UAAQ,gBAAgB,UAAU,KAAK;AAEvC,QAAM,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,QAAQ,MAAM,MAAM,QAAQ,CAAC;AACpE,MAAI,CAAC,IAAI,IAAI;AACX,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,IAAK,OAAM,IAAIC,qBAAoB,cAAc;AAC1F,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,KAAK,IAAI,QAAQ,IAAI,aAAa;AACxC,YAAM,KAAK,KAAK,OAAO,EAAE,IAAI,MAAO;AACpC,YAAM,IAAI,eAAe,gBAAgB,EAAE;AAAA,IAC7C;AACA,UAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAC5C,YAAQ,MAAM,wBAAwB,EAAE,QAAQ,mBAAmB,QAAQ,IAAI,QAAQ,KAAK,CAAC;AAC7F,UAAM,IAAI,cAAc,uBAAuB,UAAU,QAAW,IAAI,MAAM;AAAA,EAChF;AACA,SAAQ,MAAM,IAAI,KAAK;AACzB;AAGA,eAAsB,0BACpB,UACA,SACA,aAC0C;AAC1C,QAAM,MAAM,UAAU,UAAU,iBAAiB;AACjD,QAAM,QAAQ,MAAM,cAAc,SAAS,GAAG;AAC9C,MAAI,UAAkC,EAAE,gBAAgB,mBAAmB;AAC3E,MAAI,YAAa,WAAU,aAAa,SAAS,iBAAiB,WAAW,CAAC;AAC9E,UAAQ,gBAAgB,UAAU,KAAK;AACvC,QAAM,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,QAAQ,SAAS,MAAM,KAAK,UAAU,OAAO,EAAE,CAAC;AACvF,MAAI,CAAC,IAAI,IAAI;AACX,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,IAAK,OAAM,IAAIA,qBAAoB,cAAc;AAC1F,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,KAAK,IAAI,QAAQ,IAAI,aAAa;AACxC,YAAM,KAAK,KAAK,OAAO,EAAE,IAAI,MAAO;AACpC,YAAM,IAAI,eAAe,gBAAgB,EAAE;AAAA,IAC7C;AACA,UAAM,IAAI,cAAc,qCAAqC,UAAU,QAAW,IAAI,MAAM;AAAA,EAC9F;AACA,SAAQ,MAAM,IAAI,KAAK;AACzB;AAGA,eAAsB,uBACpB,UACA,IACA,aAC0C;AAC1C,QAAM,MAAM,UAAU,UAAU,mBAAmB,mBAAmB,EAAE,CAAC,EAAE;AAC3E,QAAM,QAAQ,MAAM,cAAc,SAAS,GAAG;AAC9C,MAAI,UAAkC,CAAC;AACvC,MAAI,YAAa,WAAU,aAAa,SAAS,iBAAiB,WAAW,CAAC;AAC9E,UAAQ,gBAAgB,UAAU,KAAK;AACvC,QAAM,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,OAAO,QAAQ,CAAC;AACvD,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,cAAc,kCAAkC,UAAU,QAAW,IAAI,MAAM;AACtG,SAAQ,MAAM,IAAI,KAAK;AACzB;AAGA,eAAsB,oBACpB,UACA,IACA,aACuC;AACvC,QAAM,MAAM,UAAU,UAAU,mBAAmB,mBAAmB,EAAE,CAAC,aAAa;AACtF,QAAM,QAAQ,MAAM,cAAc,SAAS,GAAG;AAC9C,MAAI,UAAkC,CAAC;AACvC,MAAI,YAAa,WAAU,aAAa,SAAS,iBAAiB,WAAW,CAAC;AAC9E,UAAQ,gBAAgB,UAAU,KAAK;AACvC,QAAM,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,OAAO,QAAQ,CAAC;AACvD,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,cAAc,+BAA+B,UAAU,QAAW,IAAI,MAAM;AACnG,SAAQ,MAAM,IAAI,KAAK;AACzB;AAMA,eAAsB,qBACpB,UACA,OACA,SACA,aACA,QAC2B;AAC3B,QAAM,EAAE,UAAU,GAAG,cAAc,IAAI;AAEvC,QAAM,SAAS,MAAM,iBAAiB,UAAU,OAAO,EAAE,UAAU,SAAS,YAAY,GAAG,MAAM;AACjG,QAAM,MAAM,MAAM,0BAA0B,UAAU,EAAE,GAAG,eAAe,SAAS,OAAO,GAAG,GAAG,WAAW;AAE3G,MAAI,UAAU;AACd,QAAM,QAAQ,KAAK,IAAI;AACvB,SAAO,QAAQ,WAAW,eAAe,QAAQ,WAAW,SAAS;AAEnE,UAAM,SAAS,KAAK,IAAI,IAAI;AAC5B,UAAM,QAAQ,KAAK,IAAI,MAAO,KAAK,MAAM,SAAS,EAAE,GAAG,GAAI;AAC3D,UAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AAC7C,cAAU,MAAM,uBAAuB,UAAU,IAAI,IAAI,WAAW;AAAA,EACtE;AACA,MAAI,QAAQ,WAAW,aAAa;AAClC,UAAM,IAAI,cAAc,sBAAsB,QAAQ,iBAAiB,SAAS,IAAI,QAAQ;AAAA,EAC9F;AACA,QAAM,KAAK,MAAM,oBAAoB,UAAU,IAAI,IAAI,WAAW;AAClE,QAAM,SAAS,GAAG,UAAU,CAAC;AAC7B,SAAO;AAAA,IACL,MAAM,GAAG,QAAQ;AAAA,IACjB,OAAO,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,UAAU,OAAO,EAAE,QAAQ,YAAY,EAAE,WAAW,EAAE;AAAA,IAC3G,UAAU,EAAE,IAAI,GAAG,GAAG;AAAA,EACxB;AACF;;;AEpJA,SAAS,sBAAsB;;;ACA/B,SAAS,OAAO,yBAAyB;AAGlC,IAAM,iBAAiB;AACvB,IAAM,oBAAoB;AAC1B,IAAM,sBAAsB;AAC5B,IAAM,mBAA0B;AAChC,IAAM,0BAA0B;AAChC,IAAM,eAAe;AACrB,IAAM,eAAe;AAErB,IAAM,0BAA0B;AAChC,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AAezB,SAAS,cAAc,SAA8C;AAC1E,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,WAAW,kBAAkB,QAAQ,YAAY,gBAAgB;AACvE,QAAM,cAAc,QAAQ,eAAe;AAC3C,QAAM,gBAAgB,MAAM,QAAQ,iBAAiB,yBAAyB,cAAc,YAAY;AACxG,QAAM,gBAAgB,MAAM,QAAQ,iBAAiB,yBAAyB,kBAAkB,gBAAgB;AAEhH,QAAM,OAAO,QAAQ;AACrB,QAAM,QAAQ,OAAO,SAAS,YAAY,KAAK,WAAW,IAAI,IAAI,OAAO;AACzE,QAAM,WACJ,OAAO,SAAS,YAAY,KAAK,WAAW,MAAM,KAAK,CAAC,KAAK,WAAW,IAAI,IAAI,OAAO;AACzF,SAAO;AAAA,IACL,KAAK;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC/CA,SAAS,gBAAAC,eAAc,oBAAAC,yBAAwB;AAQ/C,eAAsB,eACpB,UACA,OACA,UACA,SACA,QAC2B;AAC3B,QAAM,WACJ,OAAO,SAAS,IAAI,YAAY,aAC5B,MAAM,SAAS,IAAI,QAAQ,EAAE,WAAW,OAAO,CAAC,IAChD,SAAS,IAAI;AACnB,QAAM,UAAU,WAAWC,cAAa,CAAC,GAAGC,kBAAiB,QAAQ,CAAC,IAAI;AAE1E,QAAM,cAA+E,SAAS,IAAI,cAC9F,SAAS,IAAI,YAAY,SAAS,YAChC,EAAE,MAAM,WAAW,iBAAiB,SAAS,IAAI,YAAY,eAAe,IAC5E;AAAA,IACE,MAAM;AAAA,IACN,YAAY,SAAS,IAAI,YAAY;AAAA,IACrC,YAAY,SAAS,IAAI,YAAY;AAAA,EACvC,IACF;AAEJ,SAAO,MAAM;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO,SAAS,IAAI;AAAA,MACpB,gBAAgB,SAAS,IAAI;AAAA,MAC7B,uBAAuB,SAAS,IAAI;AAAA,MACpC,4BAA4B,SAAS,IAAI;AAAA,MACzC,gCAAgC,SAAS,IAAI;AAAA,MAC7C;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC9CA,SAAS,cAAc,uBAAAC,sBAAqB,cAAc,iBAAAC,gBAAe,kBAAAC,uBAAsB;AAE/F,SAAS,mBAAmB,uBAAuB;AAc5C,SAAS,eAAe,UAAgC,QAAsC;AACnG,MAAI,SAAuB;AAC3B,QAAM,iBAAiB,oBAAI,IAAmC;AAC9D,QAAM,gBAAgB,oBAAI,IAAwB;AAClD,QAAM,iBAAiB,oBAAI,IAA+B;AAE1D,MAAI,KAAuB;AAC3B,MAAI,aAAmC;AACvC,MAAI,gBAAsC;AAC1C,MAAI,iBAAiB;AACrB,MAAI,iBAAwD;AAC5D,MAAI,mBAAmB;AAEvB,QAAM,QAA4D,CAAC;AACnE,MAAI,WAAW;AAKf,QAAM,wBAAwB;AAC9B,QAAM,mBAAmB,oBAAI,IAAoB;AACjD,QAAM,mBAAmB,oBAAI,IAAoB;AAEjD,QAAM,mBAAmB,CAAC,UAAuC;AAC/D,QAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG;AACvD,aAAO;AAAA,IACT;AACA,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,UAAU,MAAM,KAAK;AAC3B,UAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,UAAI,QAAQ,KAAK,OAAO,GAAG;AACzB,cAAM,SAAS,OAAO,OAAO;AAC7B,eAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAAA,MAC5C;AACA,YAAM,WAAW,iBAAiB,IAAI,OAAO;AAC7C,UAAI,aAAa,OAAW,QAAO;AACnC,YAAM,KAAK,wBAAwB,iBAAiB;AACpD,uBAAiB,IAAI,SAAS,EAAE;AAChC,uBAAiB,IAAI,IAAI,OAAO;AAChC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,CAAC,SAA6B;AAC9C,QAAI,WAAW,KAAM;AACrB,aAAS;AACT,mBAAe,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;AAAA,EACzC;AAEA,QAAM,eAAe,MAAY;AAC/B,uBAAmB,KAAK,IAAI;AAAA,EAC9B;AAEA,QAAM,iBAAiB,MAAY;AACjC,QAAI,CAAC,eAAgB;AACrB,kBAAc,cAAc;AAC5B,qBAAiB;AAAA,EACnB;AAEA,QAAM,iBAAiB,MAAY;AACjC,mBAAe;AACf,qBAAiB,YAAY,MAAM;AACjC,YAAM,SAAS;AACf,UAAI,CAAC,UAAU,OAAO,eAAe,UAAU,KAAM;AACrD,YAAM,SAAS,KAAK,IAAI,IAAI;AAC5B,UAAI,SAAS,SAAS,cAAe;AACrC,UAAI;AACF,eAAO,KAAK,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC,CAAC;AACjD,qBAAa;AAAA,MACf,SAAS,KAAK;AACZ,gBAAQ,KAAK,gCAAgC;AAAA,UAC3C,QAAQ;AAAA,UACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACxD,CAAC;AAAA,MACH;AAAA,IACF,GAAG,SAAS,aAAa;AAAA,EAC3B;AAEA,QAAM,qBAAqB,CAAC,UAA8C;AACxE,QAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,UAAM,IAAI;AACV,QAAI,EAAE,WAAW,UAAa,CAAC,MAAM,QAAQ,EAAE,MAAM,EAAG,QAAO;AAC/D,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,CAAC,UAA4B;AAC5C,QAAI,OAAO,UAAU,SAAU,QAAO;AACtC,UAAM,IAAI,MAAM,KAAK;AACrB,WAAO,EAAE,WAAW,GAAG,KAAK,EAAE,SAAS,GAAG;AAAA,EAC5C;AAEA,QAAM,cAAc,CAAC,MAA6C;AAChE,UAAM,UAAU,EAAE;AAClB,QAAI,SAAS,OAAO,EAAG,QAAO;AAC9B,UAAM,OAAO,OAAO,YAAY,WAAW,UAAU;AACrD,UAAM,QAAyB,EAAE,MAAM,SAAS,EAAE,aAAa,KAAK;AAEpE,QAAI,OAAO,EAAE,aAAa,YAAY,OAAO,SAAS,EAAE,QAAQ,EAAG,OAAM,UAAU,KAAK,IAAI,GAAG,EAAE,QAAQ;AACzG,QAAI,OAAO,EAAE,WAAW,YAAY,OAAO,SAAS,EAAE,MAAM,EAAG,OAAM,QAAQ,KAAK,IAAI,GAAG,EAAE,MAAM;AACjG,QAAI,OAAO,EAAE,eAAe,YAAY,OAAO,SAAS,EAAE,UAAU,EAAG,OAAM,aAAa,EAAE;AAE5F,UAAM,UAAU,iBAAiB,EAAE,OAAO;AAC1C,QAAI,YAAY,OAAW,OAAM,UAAU;AAE3C,QAAI,OAAO,EAAE,aAAa,YAAY,EAAE,SAAS,KAAK,EAAE,SAAS,EAAG,OAAM,WAAW,EAAE;AACvF,QAAI,OAAO,EAAE,oBAAoB,YAAY,EAAE,gBAAgB,KAAK,EAAE,SAAS,GAAG;AAChF,YAAM,4BAA4B,EAAE;AAAA,IACtC;AACA,QAAI,EAAE,uBAAuB,cAAe,OAAM,oBAAoB;AAEtE,UAAM,gBAAyC,CAAC;AAChD,QAAI,OAAO,EAAE,aAAa,SAAU,eAAc,WAAW,EAAE;AAC/D,QAAI,OAAO,EAAE,oBAAoB,SAAU,eAAc,iBAAiB,EAAE;AAC5E,QAAI,OAAO,EAAE,uBAAuB,SAAU,eAAc,oBAAoB,EAAE;AAClF,QAAI,OAAO,KAAK,aAAa,EAAE,SAAS,EAAG,OAAM,WAAW;AAE5D,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAY;AAC7B,UAAM,SAAS;AACf,eAAW;AAAA,EACb;AAEA,QAAM,aAAa,MAAY;AAC7B,UAAM,SAAS;AACf,QAAI,CAAC,UAAU,OAAO,eAAe,UAAU,KAAM;AACrD,WAAO,MAAM,SAAS,GAAG;AACvB,YAAM,OAAO,MAAM,MAAM;AACzB,UAAI,CAAC,KAAM;AACX,YAAM,MAAM,KAAK,MAAM,IAAI,OAAO,MAAM,CAAC;AACzC,aAAO,KAAK,GAAG;AACf,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,QAAM,UAAU,CAAC,UAA0C;AACzD,QAAI,MAAM,IAAI,WAAW,EAAG;AAC5B,UAAM,MAAM,gBAAgB,MAAM,IAAI,QAAQ,MAAM,YAAY,MAAM,QAAQ;AAC9E,UAAM,KAAK,EAAE,OAAO,IAAI,CAAC;AACzB,gBAAY;AACZ,WAAO,WAAW,SAAS,iBAAiB,MAAM,SAAS,GAAG;AAC5D,YAAM,UAAU,MAAM,MAAM;AAC5B,UAAI,CAAC,QAAS;AACd,iBAAW,KAAK,IAAI,GAAG,WAAW,QAAQ,GAAG;AAC7C,cAAQ,KAAK,yDAAyD,EAAE,QAAQ,mBAAmB,SAAS,CAAC;AAAA,IAC/G;AACA,eAAW;AAAA,EACb;AAEA,QAAM,aAAa,CAAC,MAA8B;AAChD,mBAAe,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AAAA,EACpC;AAEA,QAAM,YAAY,CAAC,MAAmB,cAAc,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AAEvE,QAAM,iBAAiB,CAAC,MAAc,cAAoC;AAExE,QAAI;AACF,YAAM,SAAkB,YAAY,KAAK,MAAM,SAAS,IAAI;AAC5D,UAAI,OAAO,WAAW,YAAY,WAAW,KAAM,QAAO;AAC1D,YAAMC,UAAU,OAAmC;AACnD,YAAM,UAAW,OAAmC;AACpD,UAAIA,YAAW,IAAK,QAAO,IAAIC,qBAAoB,OAAO,YAAY,WAAW,UAAU,cAAc;AACzG,UAAID,YAAW,IAAK,QAAO,IAAIE,gBAAe,OAAO,YAAY,WAAW,UAAU,mBAAmB;AACzG,UAAI,OAAOF,YAAW,YAAYA,WAAU,KAAK;AAC/C,eAAO,IAAIG;AAAA,UACT,OAAO,YAAY,WAAW,UAAU;AAAA,UACxC;AAAA,UACAH;AAAA,UACAA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AACA,QAAI,SAAS,KAAM,QAAO,IAAI,aAAa,oBAAoB,IAAI;AACnE,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,CAAC,SAAwB;AAC7C,QAAI,OAAO,SAAS,SAAU;AAC9B,QAAI,MAA+B;AACnC,QAAI;AACF,YAAM,SAAkB,KAAK,MAAM,IAAI;AACvC,YAAM,mBAAmB,MAAM,IAAI,SAAS;AAAA,IAC9C,SAAS,KAAK;AACZ,cAAQ,KAAK,+BAA+B;AAAA,QAC1C,QAAQ;AAAA,QACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MACxD,CAAC;AACD;AAAA,IACF;AACA,QAAI,CAAC,IAAK;AAEV,QAAI,OAAO,IAAI,eAAe,YAAY,OAAO,IAAI,kBAAkB,UAAU;AAC/E,gBAAU,IAAIG,eAAc,IAAI,eAAe,UAAU,IAAI,YAAY,IAAI,YAAY,GAAG,CAAC;AAC7F,gBAAU,OAAO;AACjB;AAAA,IACF;AAEA,UAAM,iBAA0C,CAAC;AACjD,QAAI,OAAO,IAAI,wBAAwB,YAAY,OAAO,SAAS,IAAI,mBAAmB,GAAG;AAC3F,qBAAe,mBAAmB,IAAI;AAAA,IACxC;AACA,QAAI,OAAO,IAAI,wBAAwB,YAAY,OAAO,SAAS,IAAI,mBAAmB,GAAG;AAC3F,qBAAe,mBAAmB,IAAI;AAAA,IACxC;AACA,QAAI,IAAI,aAAa,MAAM;AACzB,qBAAe,WAAW;AAAA,IAC5B;AAEA,UAAM,SAA4B,CAAC;AACnC,QAAI,WAAW;AACf,QAAI,IAAI,UAAU,IAAI,OAAO,SAAS,GAAG;AACvC,iBAAW,KAAK,IAAI,QAAQ;AAC1B,YAAI,SAAS,EAAE,IAAI,GAAG;AACpB,qBAAW;AACX;AAAA,QACF;AACA,cAAM,QAAQ,YAAY,CAAC;AAC3B,YAAI,MAAO,QAAO,KAAK,KAAK;AAAA,MAC9B;AAAA,IACF;AAEA,QAAI,iBAAiB,OAAO,GAAG;AAC7B,YAAM,gBAAwC,CAAC;AAC/C,iBAAW,CAAC,IAAI,KAAK,KAAK,kBAAkB;AAC1C,sBAAc,OAAO,EAAE,CAAC,IAAI;AAAA,MAC9B;AACA,qBAAe,gBAAgB;AAAA,IACjC;AAEA,UAAM,cAAc,OAAO,KAAK,cAAc,EAAE,SAAS;AACzD,QAAI,OAAO,SAAS,KAAK,YAAY,aAAa;AAChD,YAAM,SAA2B,EAAE,YAAY,UAAU,QAAQ,KAAK,IAAI;AAC1E,UAAI,SAAU,QAAO,WAAW;AAChC,UAAI,YAAa,QAAO,WAAW;AACnC,iBAAW,MAAM;AAAA,IACnB;AAEA,QAAI,IAAI,aAAa,KAAM,WAAU,cAAc;AAAA,EACrD;AAEA,QAAM,UAAU,OAAO,WAAwC;AAC7D,QAAI,WAAY,QAAO;AACvB,QAAI,QAAQ,QAAS,OAAM,IAAI,aAAa,wBAAwB;AACpE,cAAU,YAAY;AAEtB,kBAAc,YAAY;AAExB,YAAM,SAAS,MAAM,cAAc,SAAS,GAAG;AAC/C,UAAI,QAAQ,QAAS,OAAM,IAAI,aAAa,wBAAwB;AAGpE,YAAM,cAAc,SAAS;AAC7B,YAAM,SAAS,IAAI,gBAAgB;AACnC,YAAM,WAAW,SAAS,IAAI;AAC9B,UAAI,YAAY,OAAO,KAAK,QAAQ,EAAE,SAAS,GAAG;AAChD,mBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC7C,cAAI,MAAM,QAAQ,MAAM,OAAW;AACnC,iBAAO,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,QACzB;AAAA,MACF;AACA,YAAM,MAAM,MAAM,kBAAkB,SAAS,IAAI,SAAS,aAAa,QAAQ,WAAW;AAC1F,YAAM,cAAc,SAAS,IAAI,aAAa,IAAI,CAAC,aAAa,SAAS,KAAK,CAAC,EAAE,OAAO,CAAC,aAAa,QAAQ;AAC9G,YAAM,SAAS,eAAe,YAAY,SAAS,IAAI,IAAI,UAAU,KAAK,WAAW,IAAI,IAAI,UAAU,GAAG;AAC1G,WAAK;AACL,aAAO,aAAa;AACpB,uBAAiB;AAEjB,YAAM,SAAS,MAAY;AAEzB,cAAM,OAA2B;AAAA,UAC/B,SAAS;AAAA,UACT,OAAO,SAAS,IAAI;AAAA,UACpB,cAAc,SAAS;AAAA,UACvB,cAAc,SAAS;AAAA,UACvB,aAAa,SAAS;AAAA,UACtB,gBAAgB,SAAS,IAAI;AAAA,QAC/B;AACA,YAAI,SAAS,IAAI,wBAAwB,MAAM;AAC7C,eAAK,wBAAwB;AAAA,QAC/B;AACA,YAAI,SAAS,IAAI,gBAAgB,MAAM;AACrC,eAAK,6BAA6B;AAAA,QACpC;AACA,YAAI,SAAS,IAAI,sBAAsB,MAAM;AAC3C,eAAK,4BAA4B;AAAA,QACnC;AACA,YAAI,SAAS,IAAI,2BAA2B,MAAM;AAChD,eAAK,iCAAiC;AAAA,QACxC;AACA,YAAI,SAAS,IAAI,aAAa;AAC5B,cAAI,SAAS,IAAI,YAAY,SAAS,WAAW;AAC/C,iBAAK,cAAc,EAAE,MAAM,WAAW,iBAAiB,SAAS,IAAI,YAAY,eAAe;AAAA,UACjG,OAAO;AACL,iBAAK,cAAc;AAAA,cACjB,MAAM;AAAA,cACN,YAAY,SAAS,IAAI,YAAY;AAAA,cACrC,YAAY,SAAS,IAAI,YAAY;AAAA,YACvC;AAAA,UACF;AAAA,QACF;AACA,YAAI;AACF,iBAAO,KAAK,KAAK,UAAU,IAAI,CAAC;AAChC,uBAAa;AAAA,QACf,SAAS,KAAK;AACZ,oBAAU,IAAI,aAAa,uBAAuB,MAAM,GAAG,CAAC;AAAA,QAC9D;AACA,uBAAe;AACf,kBAAU,OAAO;AACjB,mBAAW;AAAA,MACb;AACA,YAAM,YAAY,CAAC,OAA2B,cAAc,GAAG,IAAI;AACnE,YAAM,UAAU,MAAY;AAC1B,kBAAU,IAAI,aAAa,0BAA0B,IAAI,CAAC;AAC1D,kBAAU,OAAO;AAAA,MACnB;AACA,YAAM,UAAU,CAAC,OAAyB;AACxC,cAAM,MAAM,eAAe,GAAG,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;AAC3D,uBAAe;AACf,aAAK;AACL,mBAAW;AACX,kBAAU,cAAc;AACxB,YAAI,CAAC,kBAAkB,IAAK,WAAU,GAAG;AAAA,MAC3C;AAEA,aAAO,iBAAiB,QAAQ,MAAM;AACtC,aAAO,iBAAiB,WAAW,SAAS;AAC5C,aAAO,iBAAiB,SAAS,OAAO;AACxC,aAAO,iBAAiB,SAAS,OAAO;AAAA,IAC1C,GAAG;AAEH,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,YAA2B;AAC5C,QAAI,cAAe,QAAO;AAC1B,qBAAiB,YAAY;AAC3B,YAAM,SAAS;AACf,UAAI,CAAC,OAAQ;AACb,UAAI;AACF,yBAAiB;AACjB,uBAAe;AAEf,YAAI;AACF,iBAAO,KAAK,IAAI,YAAY,CAAC,CAAC;AAAA,QAChC,QAAQ;AAAA,QAAC;AACT,eAAO,MAAM,KAAM,cAAc;AAAA,MACnC,UAAE;AACA,aAAK;AACL,mBAAW;AAAA,MACb;AAAA,IACF,GAAG;AACH,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,CAAC,UAA0C;AACtD,YAAQ,KAAK;AAAA,EACf;AAEA,QAAM,gBAAgB,YAA2B;AAC/C,UAAM,SAAS;AACf,QAAI,CAAC,UAAU,OAAO,eAAe,UAAU,KAAM;AACrD,QAAI;AACF,aAAO,KAAK,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC,CAAC;AAChD,mBAAa;AAAA,IACf,QAAQ;AAAA,IAAC;AAAA,EACX;AAEA,SAAO;AAAA,IACL,IAAI,SAAS;AACX,aAAO;AAAA,IACT;AAAA,IACA,MAAM,QAAQ,QAAsB;AAClC,aAAO,QAAQ,MAAM;AAAA,IACvB;AAAA,IACA,MAAM,aAAa;AACjB,aAAO,WAAW;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,SAAS;AAChB,qBAAe,IAAI,OAAO;AAC1B,aAAO,MAAM,eAAe,OAAO,OAAO;AAAA,IAC5C;AAAA,IACA,QAAQ,SAAS;AACf,oBAAc,IAAI,OAAO;AACzB,aAAO,MAAM,cAAc,OAAO,OAAO;AAAA,IAC3C;AAAA,IACA,eAAe,SAAS;AACtB,qBAAe,IAAI,OAAO;AAC1B,aAAO,MAAM,eAAe,OAAO,OAAO;AAAA,IAC5C;AAAA,EACF;AACF;;;AHvZO,SAAS,OAAO,SAAwC;AAC7D,QAAM,YAAY,oBAAoB,MAAM,OAAO;AACnD,QAAM,SAA6B,UAAU,SAAS,UAAU,OAAO,MAAM,iBAAiB,IAAI;AAClG,MAAI,WAAW,cAAc,SAAS;AACtC,QAAM,YAAY,oBAAI,IAAmC;AAEzD,SAAO,eAAe;AAAA,IACpB,IAAI;AAAA,IACJ,cAAc;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,MACV,eAAe;AAAA,MACf,cAAc;AAAA,MACd,aAAa;AAAA,MACb,YAAY,EAAE,MAAM,MAAM,WAAW,KAAK;AAAA,IAC5C;AAAA,IACA,qBAAqB;AACnB,aAAO,EAAE,UAAU,SAAS,YAAY,SAAS,YAAY,UAAU,SAAS,SAAS;AAAA,IAC3F;AAAA,IACA,sBAAsB;AACpB,aAAO;AAAA,QACL,EAAE,UAAU,SAAS,YAAY,MAAO,UAAU,EAAE;AAAA,QACpD,EAAE,UAAU,SAAS,YAAY,MAAO,UAAU,EAAE;AAAA,QACpD,EAAE,UAAU,SAAS,YAAY,KAAM,UAAU,EAAE;AAAA,MACrD;AAAA,IACF;AAAA,IACA,gBAAgB,WAAW;AACzB,YAAM,aAAa,UAAU,cAAc,SAAS;AACpD,YAAM,WAAY,UAAU,YAAY,SAAS;AACjD,aAAO,EAAE,UAAU,SAAS,YAAY,SAAS;AAAA,IACnD;AAAA,IACA,MAAM,OAAO,MAAM;AACjB,YAAM,gBAAgB,oBAAoB,MAAM,IAAI;AACpD,iBAAW,cAAc,aAAa;AACtC,gBAAU,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;AAAA,IAC3C;AAAA,IACA,SAAS,UAAU;AACjB,gBAAU,IAAI,QAAQ;AACtB,aAAO,MAAM,UAAU,OAAO,QAAQ;AAAA,IACxC;AAAA,IACA,SAAS;AACP,aAAO,eAAe,UAAU,MAAM;AAAA,IACxC;AAAA,IACA,MAAM,WAAW,OAAO,cAAc,QAAQ;AAC5C,aAAO,eAAe,UAAU,OAAO,cAAc,QAAQ,MAAM;AAAA,IACrE;AAAA,EACF,CAAC;AACH;;;AIxCA,IAAM,WAAW,CAAC,UAAqD,OAAO,UAAU,YAAY,UAAU;AAEvG,IAAM,iBAAiB,CAC5B,WAEA,OAAO,eAAe;AAEjB,IAAM,wBAAwB,CAAC,UAAuD;AAC3F,MAAI,CAAC,SAAS,MAAM,QAAQ,EAAG,QAAO;AACtC,QAAM,WAAW,OAAO,MAAM,SAAS,aAAa,WAAW,MAAM,SAAS,WAAW;AACzF,QAAM,iBAAiB,OAAO,MAAM,SAAS,mBAAmB,WAAW,MAAM,SAAS,iBAAiB;AAC3G,QAAM,oBACJ,OAAO,MAAM,SAAS,sBAAsB,WAAW,MAAM,SAAS,oBAAoB;AAE5F,MAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,kBAAmB,QAAO;AAC/D,SAAO,EAAE,UAAU,gBAAgB,kBAAkB;AACvD;AAEO,IAAM,yBAAyB,CAAC,WAA0D;AAC/F,MAAI,CAAC,SAAS,OAAO,QAAQ,EAAG,QAAO;AACvC,QAAM,mBACJ,OAAO,OAAO,SAAS,qBAAqB,WAAW,OAAO,SAAS,mBAAmB;AAC5F,QAAM,mBACJ,OAAO,OAAO,SAAS,qBAAqB,WAAW,OAAO,SAAS,mBAAmB;AAC5F,QAAM,WAAW,OAAO,SAAS,aAAa,OAAO,OAAO;AAE5D,MAAI;AACJ,MAAI,SAAS,OAAO,SAAS,aAAa,GAAG;AAC3C,UAAM,SAAiC,CAAC;AACxC,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,OAAO,SAAS,aAAa,GAAG;AAClE,UAAI,OAAO,MAAM,SAAU,QAAO,CAAC,IAAI;AAAA,IACzC;AACA,QAAI,OAAO,KAAK,MAAM,EAAE,SAAS,EAAG,iBAAgB;AAAA,EACtD;AAEA,MACE,qBAAqB,UACrB,qBAAqB,UACrB,aAAa,UACb,kBAAkB;AAElB,WAAO;AACT,SAAO,EAAE,kBAAkB,kBAAkB,UAAU,cAAc;AACvE;","names":["AuthenticationError","AuthenticationError","mergeHeaders","normalizeHeaders","mergeHeaders","normalizeHeaders","AuthenticationError","ProviderError","RateLimitError","status","AuthenticationError","RateLimitError","ProviderError"]}